July
22nd,
2026
痛點:一張中文名片,其實是兩張名片 台灣的名片有個很常見的設計:正面印中文,背面印英文(或反過來)。我們的 LINE 名片 Bot 原本的邏輯很單純:收到一張圖片,OCR 一次,存一筆資料。 問題就出在這裡。使用者傳正面,Bot 存了一筆只有中文姓名的資料;如果使用者接著把背面也傳過去,Bot 會把它當成「另一張新名片」,同一個人在資料庫裡就會出現兩筆各缺一半資訊的紀錄。使用者得自己手動比對、刪除重複資料,體驗非常糟。 這篇文章記錄我們如何讓 Bot 學會「這是同一張名片的兩面」,並且把正反面資訊合併成一筆完整資料。 解法:先問一句「還有背面嗎?」 比起自己寫規則去猜兩張圖片是不是同一張名片,我們選了一個更直接的做法:問使用者。 流程設計如下: 使用者傳送名片正面,Bot 照常 OCR。 OCR 完成後,Bot 不馬上存檔,而是回覆一句「📇 已辨識正面資料,這張名片還有背面嗎?」,並附上兩顆 Quick Reply 按鈕。 使用者按「沒有,直接儲存」→ 照原本流程存檔,結束。 使用者按「有背面」→ Bot 記住剛剛那張正面圖片,等待下一張圖片進來。 背面圖片一到,兩張圖片一起送進 Gemini,合併成一筆資料再存檔。 這個等待狀態我們用專案原本就有的 user_states 記憶體字典來管理,並且加上 5 分鐘的逾時:使用者按了「有背面」卻不理它、跑去做別的事,5 分鐘一過就當作放棄,不會卡住整個流程。 user_states[user_id] = { 'action': 'pending_backside_confirm', 'card_obj': card_obj, 'front_image_bytes': image_content, 'expires_at': time.time() + PENDING_BACKSIDE_TIMEOUT_SECONDS } 核心:讓 Gemini 一次看兩張圖,自己做合併 最關鍵的技術決定是:要不要分兩次辨識正面、背面,再自己寫程式合併?我們選擇了另一條路,把正反面圖片包在同一次 generate_content 請求裡,直接交給 Gemini 判斷。 原因很簡單:中英文姓名要合併成「王大明 David Wang」這種格式,靠字串規則去兜很容易兜得又醜又不準;但這種語意層級的整合,靠規則去湊反而更容易出錯,交給 Gemini 直接判斷比較省事。 在 app/gemini_utils.py 中新增了 generate_json_from_two_images,沿用既有的 NAMECARD_SCHEMA 結構化輸出,只是這次 contents 塞了兩個圖片 Part: def generate_json_from_two_images( front_img: PIL.Image.Image, back_img: PIL.Image.Image, prompt: str) -> object: model = GenerativeModel( "gemini-3-flash-preview", generation_config={ "response_mime_type": "application/json", "response_schema": NAMECARD_SCHEMA }, ) front_part = Part.from_data( data=pil_to_bytes(front_img), mime_type="image/jpeg") back_part = Part.from_data( data=pil_to_bytes(back_img), mime_type="image/jpeg") response = model.generate_content( [prompt, front_part, back_part], stream=False, labels={"client_id": "namecard"} ) return response Prompt 也只是在原本的 IMGAGE_PROMPT 後面多加一段合併指示: DOUBLE_SIDED_IMAGE_PROMPT = IMGAGE_PROMPT + """ 這兩張圖片是同一張名片的正面與背面,請整合成一筆完整資料。 若同一欄位中英文都有出現(如姓名、公司),請合併呈現 (例如「王大明 David Wang」); 若某欄位只有一面出現,直接採用該面的值;忽略明顯重複的資訊。 """ 一次 API 呼叫,換來的是完全不用自己寫合併規則、也不用維護那套規則。 容易忽略的兩個小坑 功能上線前的整體 code review,抓到兩個很容易被忽略、但真的會咬人的細節。 坑一:重複檢查的時機點 原本的重複檢查(比對 email 是否已存在)是 OCR 完馬上做。但雙面辨識上線後,如果正面剛好跟舊資料的 email 重複,這時候就提早判定「已存在」並結束流程,那背面圖片裡如果帶有新的 email,就再也沒有機會被看到了。...
繼續閱讀
July
18th,
2026
台灣AI大未來 解析最新的AI趨勢、台灣情勢、企業布局與個人發展 作者: 簡立峰(Chien Lee-feng) 蕭玉品 出版社:商業周刊 買書推薦網址: Readmoo: 由此去購買。 前言: 這是 2026 年第 2 本讀完的書。這大概也是蠻新的一本書,就是 2025 年底才出的一本書,那時候會買這本書因為就是公司在 2024 年有邀請簡立峰來公司演講,後來偶然在電子書櫃上看到他出的書,就想說來看一下。 大綱 當AI改寫世界,台灣下一步怎麼走? Google台灣區前董事總經理、電腦科學暨人工智慧學者──簡立峰 為台灣撰寫第一本AI時代的使用說明書, 讓台灣人看懂AI時代的機會與挑戰! 世界每十年就歷經一次數位革命: ●1990年,個人電腦開啟電腦世代; ●2000年,網際網路造就網路世代; ●2010年,行動裝置與社群媒體引領行動世代; ●2020年,生成式AI如ChatGPT震撼登場…… 如今正是AI世代,遊戲規則全面改寫,差距正在1:99間急遽擴大。 你會落後被淘汰,還是把握機遇、成為1%的贏家? 本書帶你洞悉AI格局,掌握關鍵轉型之鑰! 【地緣政治下的AI發展】 當全球正經歷一場由AI驅動的典範轉移,美國將AI視為其重返霸權的關鍵,這不僅預示著AI產品化將徹底顛覆世界的運行規則,更開啟了未來AI演變的無限可能。從「曼哈頓計畫」到「星際之門」的深遠布局,本書將深入剖析美中關稅戰下的全球局勢,洞察AI如何重塑國際秩序。 ●1:99的挑戰,抓住機會的國家、企業、個人,都有可能會成為獨一無二、遠超他人的「1」,其他人則成了遠遠落後的「99」。 ●DeepSeek的出現,顛覆了美國壟斷的現象,帶來AI世界的「再平衡」,等於發明了窮人的原子彈。 ●如果不加快晶片國產化的腳步,不具生產力的美國就沒有明天,直接在AI戰役中喪失競爭力,台積電因而成了美中對抗的X因子。 【放眼世界的台灣】 AI浪潮席捲全球,這不只是技術革新,更是國家發展的關鍵轉捩點。身處這股巨浪中,台灣不僅擁有得天獨厚的「護國神山」台積電,更在AI挑戰與機會並存之際,看到成為「世界的台灣」的黃金十年。本書帶你一窺台灣製造業的未來潛能,以及新舊企業如何重新定調「台灣製造」。 ●面對地緣政治變局,以製造業為主的台灣企業要順勢而為,透過海外生產,在台研發打造「台灣+N(外國)」模式,協助台灣去除紅色供應鏈、加入美系供應鏈的一環。 ●海島的市場永遠在外面,你飛去日本、飛去美國旅遊、出差幾天不等於國際化,國際化是每天的生活受不同文化衝擊。 【百工百業的AI實踐】 AI時代是企業轉型、人才再造的關鍵時刻,敢於轉向的企業才有競爭機會。本書例舉許多不同業種企業如何因應AI的案例,並提供實用的對策方向,引導台灣企業轉型搶占AI市場,邁向成長與創新。 ●AI的影響可比喻成「大風吹」,從科技巨擘到中小企業,不論是騰籠換鳥,還是為員工賦能,風往哪裡吹,新的機會就在那裡。 ●「老創+新創」從軟體整合轉向軟硬整合,結合二者優勢,AI應用才有可能。 ●發展主權AI並非外包出去就結束了,不論是自建模型、請科技巨頭幫忙,要把策略規畫得清清楚楚,否則恐怕只是白花錢。 【掌握個人學習、職涯的黃金鑰匙】 身為AI世代的一分子,如何利用AI提升學習效率,同時清晰辨識AI的極限,是AI時代的重要課題。本書建議如何善用AI工具的同時,也點出人類的差異化經驗將成為無可取代的稀世珍寶,因此聰明地累積個人獨特價值,才能讓自己在AI時代立於不敗之地。 ●AI喜歡用某些特定句型,究其原因在於AI是機率概念,自然有些規律在裡頭,但反過來說,正因為它資料量夠大,才能試出各種人類沒見過的組合。 ●AI將許多工作的「及格線」從60分一舉提高到80分,迫使各行各業必須重新定義人力的核心職能和價值。 ● AI時代,具備專業基礎的資深人才學AI最快,因為他們長期累積的知識能判斷AI生成內容的正確性,這次AI的典範轉移,反過來將老一世代的優勢給放大了。 這是一本專為台灣量身打造的AI生存指南,幫助你全面掌握AI變革的脈絡,找到國家、企業與個人在變局中的成長之道。 這本書可以說是 Google 台灣前董事總經理簡立峰博士與資深媒體人蕭玉品,聯手為台灣人與企業量身打造的「AI時代生存說明書」。簡博士用非常務實、精準的在地視角,剖析了在這波瘋狂的 AI 浪潮下,台灣該如何重新定位、企業如何打出軟硬整合的國際盃,以及每個人該如何避免陷入「大腦外包」的危機。 我為你將全書的四大核心架構整理出來,先透過這個概覽掌握整體脈絡: 全書四大核心架構概覽 面向分類 核心痛點與趨勢 台灣與個人的突圍戰略 1. 最新AI趨勢 AI 帶來高度的集權與統一,可能演變成 1:99 的能力與資源懸殊;不過 DeepSeek 等新興勢力的崛起,也正為全球帶來「再平衡」的機會。 理解 AI 的「機率與語言架構」本質,從中尋找非美系壟斷的突破點,拉高基本能力下限。 2. 台灣情勢定位 台灣雖是地緣政治與 AI 晶片的關鍵 X 因子,但也面臨島嶼內捲、少子化與五缺的結構性限制。 將「農民心態」徹底轉向「航海家心態」,以出海為唯一生存王道,跨出台灣邊界擴大數位國土。 3. 企業轉型布局 台灣「硬體極強、軟體極弱」,缺乏算力與商業情境的軟體新創很難獨立在國際存活。 推動「老創(硬體大廠)+新創(軟體應用)」攜手,利用 Edge AI(邊緣AI)為強大的硬體裝置裝上大腦。 4. 個人發展鑰匙 面臨「大腦外包」的無形危機,只會照書教、缺乏實戰經驗的平庸專業新鮮人將首當其衝。 從「解題式」慣性轉為「出題式」思維,透過與 AI 進行高頻次的「反覆互動與修正」來創造獨特價值。 一、 最新AI趨勢:1:99 的「超級人類」大挑戰 極端的權力集中:AI 時代帶來了高度的中央集權,全球科技巨頭佔據極大優勢。全球數千種語言中,僅有約百種能在主流 AI 中使用,且英文與簡體中文被深度優化,這代表語言與文化架構是掌握 AI 的第一關鍵。 1:99 的分水嶺:這波海嘯最殘酷的不是消滅底層普通人(AI 反而能拉高普通人的下限),而是消滅「平庸的專業人士」。抓住機會的 1% 人會因為 AI 變身超級人類,拿走 99% 人的能力與機會,其他人則成了落後的 99%。 AI 世界的再平衡:近年非美系低成本高效模型的出現,打破了美國科技巨頭的絕對壟斷,這被形容為發明了「窮人的原子彈」,為資源較少的國家與企業帶來重新洗牌的契機。 二、 台灣情勢:從「海島內捲」轉向「大航海時代」 地緣政治的 X 因子:台積電與台灣硬體供應鏈在美中科技對抗中高居關鍵地位,因為台灣具備「最早知道需求」的特性(例如能率先掌握伺服器電壓變化等系統需求),在全球基礎設施的調整中擁有重要身分。 打破農民心態:多數台灣企業習慣了「海島思維」,日常生活中「看不見海」,容易在舒適的同溫層中陷入內捲。面對未來 20 年少子化、新生兒暴跌的結構性危機,簡博士疾呼必須轉向「航海家心態」,因為「出海」已是台灣各行各業唯一的生存之道。 數位國土的延伸:以台積電為例,AI 能讓台灣在海外複製工廠後,由台灣工程師進行遠距操作;台灣也應將高齡化、勞動力短缺的危機轉為機會,積極發展機器人與屬於自己的主權 AI,避免國家級的數位落差。 三、 企業布局:軟硬整合,讓「老創+新創」攜手共舞 用 Edge AI 幫硬體裝上大腦:Edge AI(邊緣AI,指讓終端裝置具備在地運算能力,不全依賴雲端)是台灣的天下。台灣純做軟體新創很難拼過國際巨頭,但我們可以把 AI 服務直接內建、綑綁在全世界都在用的強大硬體裝置中(如捷安特的自行車或各種終端設備),大幅提升附加價值。 老創加新創打國際盃:現在的 AI 新創如果沒有富爸爸提供的數據、算力和真實的「商業情境」,幾乎不可能成功。因此,硬體大廠(老創)應該攜手軟體新創,結合老創的國際通路與新創的靈活應用,一起組隊出海打國際盃。 主權 AI 的務實規劃:發展主權 AI 不能只是盲目把業務外包給科技巨頭。企業不論是自建模型還是與大廠合作,都必須把自身的策略、場域應用規劃得清清楚楚,否則只是平白燒錢。 四、 個人發展:拒絕「大腦外包」,做高段位的「出題者」 思維從「解題」變「出題」:AI 的能耐都是被「問」出來的,問題越專業,得到的回應就越準確。未來職場不再看重死記硬背,核心能力將轉向問題定義、思辨與方向掌控,能展現主動影響力的「出題者」才能勝出。 利用「反覆迭代」深化學習:如果只是把問題丟給 AI、一次取得答案就直接複製使用,這種行為等同於抄襲;但如果能跟...
繼續閱讀
July
17th,
2026
蔡桑說怪
日本神話與靈界怪談,有時還有臺灣
共 73 人評分
作者: 蔡亦竹 出版社:圓神出版
買書推薦網址:
Readmoo: 由此去購買。
前言:
這是 2026 年第 1 本讀完的書。今年上半年都沒有寫讀書心得,因為許多書籍都只有看一點點。這一本書也讀了蠻久的,是在找書的時候偶爾看到這一本書,結果整本書到了後半段卻是相當的好看,我一口氣最後就看完。
大綱
沒有最ㄎㄧㄤ,只有更ㄎㄧㄤ!蔡亦竹a.k.a.民俗學中二教授的鬼話連篇大解放!
◆日本初代神明家庭是如何天天上演八點檔狗血劇?
◆日本神話是怎麼把各種「性隱喻」藏在故事裡?
◆妖怪不是統統都是害人精,哪些妖怪可以讓你發大財、上天堂?
◆妖怪界裡也有霸凌現象?只是變老變醜就可以是一種妖怪?
◆玉皇大帝其實不是CEO?觀世音菩薩其實是外籍人士?
◆臺灣也可以有「師公手錶」「妖怪寶可夢」?
臺灣人怕鬼,日本人怕鬼,全世界的人都怕鬼……
沒有看過《鬼話連篇》沒關係,來這裡聽蔡桑練肖話、說鬼神,讓你心裡不再「毛毛der」!
大多數人對日本的印象是──參拜不完的寺廟、超萌超宅的coser、AV女優……威!一定還有靈異故事、貞子、妖怪,以及各種都市傳說!
聽蔡桑如何把毛骨悚然的撞鬼經驗結合流傳千古的歷史故事,看蔡桑如何用超接地氣語法,揭露日本神話背後的文化意涵!
日本民俗學博士蔡亦竹集結多年對民俗學的研究,以神話鬼話做媒介,用輕鬆易懂的鄉民語言,帶讀者進入日本的「神鬼傳奇」。其中包括日本神明的家譜、妖怪與文化的關聯以及其中所蘊藏的寓意等,同時也讓臺灣的眾神明可以臺日友好大串聯地活躍於文字中,讓你懂鬼話、迷鬼神!看完保證媽媽還會問你,為什麼要跪著看這本書?
因為《蔡桑說怪》會讓你跪地大喊:「日本神話到底是嗑了什麼?我也想要來一點!」
這本書可不是那種硬梆梆的學術論文,而是筑波大學民俗學博士蔡亦竹(蔡桑),用超接地氣的「鄉民用語」與爆笑風格,把日本神話和靈界怪談扒開給你看的文化解析書!最精妙的是,他不僅講日本,還會時不時拉回臺灣的民俗視角做對比。
以下為你精煉出這本書的三大核心板塊與重點整理:
核心三大板塊重點整理
板塊分類
核心研究焦點
蔡桑的「台味白話解讀」與亮點
1. 日本的神話原型
日本初代神明家庭(伊邪那岐、伊邪那美、天照、須佐之男)的誕生,以及歷史上的怨靈信仰。
用「色情與暴力、獵奇與SOD大集合」來吐槽日本神話極度放飛自我的荒謬劇情。介紹日本古代史的「怨靈同好會」及天狗等特有種。
2. 妖怪與都市怪談
鄉野鬼怪如何隨著時代演變成現代的都市傳說(如裂口女、超高速阿婆)。
妖怪是「都市化的新寵物」,背後折射出的是現代人的集體焦慮、孤單,以及媒體對靈異風潮的推波助瀾。
3. 有時還有臺灣
臺灣與日本之間信仰的跨海交涉與文化對照(如長崎媽祖與台南飛虎將軍)。
展現「臺日友好大串聯」。透過觀看日本的怪談,反思臺灣人自己的文化根源與主體性。
一、 日本神話:比本土劇還超展開的第一家庭
初代家庭的愛恨情仇:日本的創世神明(伊邪那岐與伊邪那美)決裂過程荒謬又驚悚(老婆在黃泉變腐屍、老公嚇到逃跑離婚),後代的太陽神天照大神和弟弟須佐之男也是相愛相殺。蔡桑笑稱這些情節放到現代來看,簡直是種種驚悚與獵奇情節的大集合。
怨靈同好會:日本歷史上許多被膜拜的高階神明(如學問之神菅原道真、崇德天皇),其實生前都是「死得很慘的政治鬥爭受害者」。因為後人害怕他們變成怨靈報復,才趕緊蓋神社把他們當神拜,形成了日本獨特的怨靈信仰文化。
二、 妖怪與都市傳說:現代人的集體焦慮
妖怪是都市的新寵物:以前的妖怪(如河童、山姥)住在深山樹林,代表人類對大自然的敬畏;都市化之後,妖怪也「搬進城裡」,演變成裂口女、超高速阿婆等都市怪談。
反映現實社會的孤獨:這些現代怪談的誕生,表面上是恐怖故事,骨子裡其實折射出都市人的疏離感與集體焦慮。同時書中也回顧了八〇、九〇年代日本大眾媒體(電視靈異節目)為了收視率推波助瀾的「靈異熱潮興衰史」。
三、 有時還有臺灣:臺日神鬼的奇妙連結
講日文的媽祖與日本神明:書中特別提及臺日信仰的交織。例如日本長崎有多間媽祖廟,那裡的媽祖因為在地化而會「說日文」;而臺灣台南則有「飛虎將軍廟」,供奉的是二戰時為了保護臺灣村民而犧牲的日本飛行員杉浦茂峰。
民俗學的本質是「人的研究」:蔡桑強調,無論是研究日本神話還是臺灣的靈異現象,恐怖或荒謬的終究不是鬼怪,而是背後的人類社會。信仰能撫慰人心,是因為它反映了當代人的思考邏輯。
本書核心精神金句:
「了解人就會理解鬼,妖怪、幽靈都是依據現實的想像。」
我們必須去發現每一個現象背後為何形成的主因。當我們透過日本怪談這面鏡子,深刻理解了民俗傳說的運作,才能帶著更清晰的眼光,回頭發現並認同屬於「臺灣自己」的文化形貌。
心得
這一本書是充滿了相當多的鄉間傳奇,並且最後跟著一篇他的研究報告與實際發生過的事情會讓你覺得驚訝萬分。首先整本書會開始分享著日本鬼怪的一些故事,並且去思考著許多日本神話背後鬼怪故事由來。 並且也會根據著日本色情與暴力跟他們許多鬼怪故事的牽連。
第二話就一些台灣相關故事的分享,並且也會講到「膽大黨」裡面的超高速婆婆的由來,裂嘴女的相關故事。這些都會讓你很想要一口氣閱讀完。隨著最近好像鬼月又要到了,似乎這一系列的書又會變得開始熱門。大家也也可以看看。
繼續閱讀
July
8th,
2026
(圖片來源: 數位憑證皮夾官方網站) 前提: 上一篇入門版做了一個 HR 員工卡系統:同仁自己申請一張員工卡,然後拿它去申請「運動補助」跟「育兒補助」。那一篇的重點是「發卡(Issuer)」跟「驗證(Verifier)」兩個角色分開來看。 這一篇想再往前走一步:如果一個場景要同時扮演驗證方跟發行方,串成一條完整的 DID 生態鏈,會長什麼樣子?我挑的場景是「訪客背書發證」——這也是我在腦力激盪五個檢驗方應用時,覺得最能展示「全鏈」的一個。 順便,這篇會很誠實地把開發過程中踩到的三個坑寫下來,因為那些才是 TIL 真正有價值的部分。 程式碼在這裡:https://github.com/kkdai/did-usecase-visitor 線上體驗:https://did-usecase-visitor-660825558664.asia-east1.run.app 場景:員工門禁 + 訪客背書發證 這個大廳證件台有兩個模式: 員工門禁 / 活動報名:員工用數位皮夾出示員工卡,系統只驗證「是不是有效員工」,驗過就開門 / 報名成功。姓名、生日、子女數這些欄位一律不揭露,留在皮夾裡——這就是選擇性揭露。 訪客背書發證(這篇的主角):由一位在職員工出示員工卡「背書」,驗證通過之後,系統當場核發一張帶到期時間的臨時訪客通行證到訪客的皮夾。 第二個模式的價值在於,它把兩個角色接起來了: 先當 Verifier(驗員工卡)→ 驗過才當 Issuer(發訪客卡) 比起傳統的紙本訪客簿(抄身分證、押證件影本、一堆個資堆在櫃台還要人工回收),數位背書只留下「哪位員工背書」這一筆可追責的資訊,訪客資料留在訪客自己的皮夾,通行證還可以設到期時間。 架構決策:為什麼不直接改上一個專案 這次我開了一個全新的專案、部署到獨立的 Cloud Run 服務,而不是在原本的 HR 專案上加頁面。幾個考量: 靜態前端 + JSON API:原專案用 jade 樣板 server-side render,這次改成 public/ 靜態頁 + 幾支 JSON API(/api/access/qrcode、/api/access/status),前後端分得比較乾淨。 把皮夾 API 呼叫抽成 lib/wallet.js:原專案的 issuer / verifier 呼叫是內嵌在路由裡、而且重複。這次抽成三個函式:requestPresentationQRCode()、getPresentationResult()、issueCredential(),好維護也好測。 狀態改用記憶體:原專案把資料寫進單一 record.js 檔案,在 Cloud Run 這種無狀態環境上寫檔會有問題。這次用簡單的記憶體物件(重啟歸零,展示用途足夠)。 權杖沿用同一個沙盒帳號:issuer / verifier 的 access token 跟上一篇是同一組,直接重用。 驗證「持有員工卡」的部分,我先沿用既有的運動補助 verifier ref 當 fallback(VERIFIER_ACCESS_REF 沒設就用 VERIFIER_SPORT_REF),這樣不用等後台設定就能先跑起來。 踩坑紀錄一:出示成功了,畫面卻一直卡住 這是最經典的一個。手機掃碼、皮夾也完成出示了,但桌面的頁面就是不往下走,一直在輪詢。 第一步先看 Cloud Run 的日誌,發現 /api/access/status 每 3 秒回一次、每次都回「未驗證」。我在後端加了一行把驗證方原始回應印出來的 log,重新部署後再測一次,就抓到真相了: { "data": [ { "credentialType": "0028680530_line_school", "claims": [ { "ename": "english_name", "cname": "英文名字", "value": "Lub" }, { "ename": "join_company", "cname": "入職時間", "value": "2018-10-05" } ] } ], "verifyResult": true, "resultDescription": "success", "transactionId": "8cd7f37b-..." } 看到問題了嗎?回應裡的欄位是 verifyResult(camelCase),而且根本沒有 code 這個欄位。但我沿用上一篇的舊寫法,判斷式是: // 舊的(對不上現在的回應) const verified = data.code === 0 && data.verify_result === true; data.code 是 undefined、data.verify_result 也是 undefined(人家叫 verifyResult),所以永遠 false,永遠 pending。其實驗證早就成功了(verifyResult: true、resultDescription: "success"),只是我判斷的欄位名對不上——看起來沙盒...
繼續閱讀
July
7th,
2026
痛點:同一個專案內的 Gemini API 費用如何精準分攤? 在開發企業級 LLM 服務或是經營多租戶 (Multi-tenant) 平台時,最常被財務與維運團隊問到的問題就是: 「我們同一個 GCP 專案內接了許多不同的業務與 LINE Bot,每天的 Gemini Key 費用都會統統出現在 Gemini API 的範圍,我們有辦法根據不同的 Gemini Key 或不同的使用者來拆分費用嗎?」 直接回答你的問題: 在 Google Cloud 帳單(Cloud Billing)報告中,無法直接「根據不同的 API Key 金鑰名稱」來分開顯示費用。 Google Cloud 的帳單報表最小的歸屬維度是到「專案 (Project)」、「服務 (Service)」和「SKU (產品細項)」,系統並不會把個別的 API Key 字串當作獨立的計費項目。對帳單系統來說,同一個專案內不論你建了 10 把還是 100 把 API Key,通通都會被揉在一起算成一筆 Gemini API 的總帳。 山不轉路轉:Vertex AI 的「請求標籤 (Labels)」救星 如果因為架構限制非得塞在同一個專案,最推薦的做法就是:切換至 Vertex AI 呼叫,並使用「請求標籤 (Labels)」。 如果你目前使用的是 Google AI Studio 的 API Key,它在單一專案內是無法傳遞計費標籤的。但如果你將程式碼改為呼叫 Vertex AI 的 Gemini API(一樣在同一個專案內),Vertex AI 支援在每次發送請求時,動態帶入自訂的 labels(標籤)。 原理與流程 在每次發送請求(例如呼叫 generateContent)時,於 API Request 中帶入特定的 Metadata: { "contents": { ... }, "labels": { "client_id": "info_helper", "api_key_group": "marketing_team" } } 這些自訂標籤會直接被傳遞到 GCP 的帳單系統。之後當你到 GCP 帳單報告中,在「分組依據 (Group by)」選擇你設定的標籤鍵(例如 client_id),就能在同一個專案內,把不同標籤(代表不同服務、客戶或使用者)的費用算得一清二楚! 專案實戰改造:全面導入 Labels 機制 為了完成這個需求,我們盤點了目前 LINE Bot 專案的 API 呼叫架構,並進行了以下重構。 1. 專案 API 呼叫盤點 經由掃描,我們發現專案中絕大部分都是使用 Vertex AI 進行呼叫(17 個 Client 中有 14 個使用 vertexai=True),只有少數例外: Vertex AI 呼叫:包括 GitHub 摘要、多個 Google Maps Grounding 工具、文字摘要、圖片分析、語音轉文字等(共 11 個檔案、19 處呼叫點)。 Gemini API Key 呼叫:main.py 的 Live API、batch_service.py 的 Batch 服務,以及 tts_tool.py 的 TTS...
繼續閱讀
July
1st,
2026
寫在前面:第二回合,換一把利器 在上一篇文章中,我們用 AGY CLI (Antigravity) 從零打造了一個 macOS 即時會議翻譯 App:透過 ScreenCaptureKit 擷取 Zoom / Google Meet 的音訊,送入 Gemini Live API 進行即時翻譯,並在 App 視窗中顯示繁體中文雙語字幕。 App 上線後,開發者在實際開會中發現了幾個讓人皺眉的問題,同時也有了更多功能想法。這一次,我們換上了 Anthropic 的 Claude Code,在終端機中展開了第二回合的深度打磨。 以下記錄這場協作的完整對話流程,還原每一個關鍵決策點。 階段一:揭露隱藏危機 — 10 分鐘後自動停住的 WebSocket 謎團 App 看似完美運作,但開發者在一場真實的長會議後帶著疑問回來了: User: 查一下這個程式碼,為什麼大概即時翻譯大概十多分鐘就會停住,幫我查看可能會有的原因。 閱讀了全部五個 Swift 原始檔,並結合內建的 Gemini Live API 技能文件,精準指出問題根源: Gemini Live API 的 WebSocket 連線有約 10 分鐘的 Session 上限。時間一到,伺服器會主動關閉連線並送出 GoAway 信號。然而原始程式碼對這個情境毫無防備,造成三層失效: 斷線後不重連:didCloseWith 回呼只更新了 UI 上的狀態文字,沒有任何重連邏輯。 音訊靜默丟棄:isConnected = false 之後,每一個來自麥克風的音訊 chunk 都被 guard isConnected else { return } 無聲地吃掉,使用者毫無察覺。 isRunning 狀態錯誤:主視窗的「翻譯中」圖示仍在閃爍,但實際上什麼都沒有發生。 隨即重構了 GeminiLiveConnection.swift,在不改變任何外部介面的前提下,引入三道防線: GoAway 信號提前偵測:在 parseServerResponse() 中解析伺服器發出的 goAway JSON 訊息,不等連線真正斷掉,就提前主動重連,實現無縫接續翻譯。 指數退避自動重連:斷線後以 2s → 4s → 6s 的間隔遞增重試,最多 10 次;重連成功後計數歸零,確保下一次斷線同樣有完整的重試機會。全程靜默,使用者無感。 30 秒 Ping 保活:連線成功後啟動 Timer,每 30 秒向伺服器發送 sendPing,防止中間網路設備因閒置而切斷連線。 修改完成後,開發者執行了 bash build_app.sh 並推送至 GitHub: Build 成功,commit 完成,push 上去了。之後即時翻譯應該可以長時間持續運作,Session 到期時自動靜默重連,使用者不會察覺中斷。 階段二:功能訪談 — 五個問題鎖定兩大優先開發方向 穩定性解決之後,開發者開始思考 App 能走得更遠: User: 幫我仔細研究後給我三個新功能推薦 仔細閱讀程式碼後,先提出一個定向問題,而非直接給出清單: 這三個新功能的方向你比較傾向哪一類? A. 實用性 / UX — 讓日常使用更方便(字幕匯出、快捷鍵、會議記錄) B. 翻譯品質 — 更準確、更自然(多語言偵測、說話人辨識) C. 系統整合 — 與其他工具串接(Notion、Zoom overlay) User: A 三個 UX 功能隨即出爐:懸浮字幕視窗、會議記錄自動匯出、全域快捷鍵。開發者的回應很直接: User: 1 跟 2 都要 接下來是一場簡短的需求訪談,一次只問一個最關鍵的問題: 懸浮視窗要顯示幾行?→...
繼續閱讀