[GCP 實戰] LINE 名片 Bot 升級:Gemini 結構化輸出、多名片消歧義清單與二次修改確認機制

升級前情提要 在完成了基於 Vertex AI ADK 的代理人重構後,我們的 LINE 名片助理機器人 (linebot-namecard-python) 進入了實際生產環境進行測試。然而,在真實的使用情境下,我們很快發現了三個影響體驗與安全性的核心痛點: OCR 解析 JSON 不穩定:使用一般的 JSON Mode 配合 Prompt,Gemini 偶爾還是會輸出 Markdown 標記,或者漏掉欄位,造成 parser 報錯。 搜尋結果過多導致 LINE API 400 錯誤:LINE 限制單次只能發送最多 5 個訊息。當搜尋結果包含 5 張卡片加上 Agent 的文字回覆,總數為 6,就會直接被 LINE 拒絕並已讀不回。 AI 誤觸修改:使用者若是提及修改,Agent 在沒有二次確認的情況下會直接寫入 Firebase,容易因為聽錯或幻覺而造成資料被污染。 這篇文章將專注於分享我們如何針對上述痛點進行第二波升級,實作 Structured Outputs、消歧義清單、二次確認機制,以及我們在運維部署時所踩到的環境變數搶救大坑! 優化一:擁抱 Gemini Structured Outputs 結構化輸出 以往在呼叫 gemini-3-flash-preview 進行名片圖片解析時,我們是透過在 Prompt 中命令並手動 parse JSON。為了達到 100% 的格式保障,我們導入了 Vertex AI API 原生的 Structured Outputs (結構化輸出) 功能。 1. 定義名片 Schema 在 app/gemini_utils.py 中,我們定義了名片物件的約束 Schema,強迫 Gemini 嚴格依循此格式輸出: NAMECARD_SCHEMA = { "type": "OBJECT", "properties": { "name": { "type": "STRING", "description": "聯絡人姓名,如果看不出來,請填寫 N/A" }, "title": { "type": "STRING", "description": "職稱或頭銜,如果看不出來,請填寫 N/A" }, "company": { "type": "STRING", "description": "公司名稱,如果看不出來,請填寫 N/A" }, "address": { "type": "STRING", "description": "公司或聯絡地址,如果看不出來,請填寫 N/A" }, "phone": { "type": "STRING", "description": ( "電話號碼,格式為 #886-0123-456-789,1234。" "沒有分機就忽略 ,1234。如果看不出來,請填寫 N/A" ) }, "email": { "type": "STRING", "description": "電子郵件信箱,如果看不出來,請填寫 N/A" } }, "required": ["name", "title", "company", "address", "phone", "email"] } 2. 套用至 Generation Config 我們只需要在實例化...
繼續閱讀

[Gemini][Agent] Google Managed Agents API 全解析:持久化沙箱、Filesystem 跨輪共用、三段式編排,附 LINE 研究 Bot 開源實作

(圖片來源: Google Cloud Docs - Managed Agents on Agent Platform) 前情提要:自己 hand-roll agent loop 的時代要結束了 過去想做一個真正會「做事」的 AI agent,腦袋裡浮現的元件清單大概都長這樣: 一個 LLM 主迴圈(ReAct?自己寫狀態機?) 一個 sandbox 跑 LLM 產的 code(Docker?Firecracker?E2B?) 一個 filesystem 存 agent 產出的中間檔(S3?本機?臨時還是要持久?) 一個 search API(自己接 Google Custom Search?SerpAPI?) 一個 page fetcher(playwright?readability-lxml?) 把上面這些串起來的 tool router 然後才是怎麼讓使用者把 session 接下去 而且 session 一斷,agent 寫到一半的 report.md、sources.json、跑到一半的 venv 全沒了。沒人想再做一次「我幫你開個 Docker、掛個 volume、記得在 7 天後砍掉」這種事。 這幾天 Google 在 Cloud Docs 把這條 pipeline 變成「呼叫一個 managed API」的事 —— Gemini Enterprise Agent Platform 推出 Managed Agents API(內部代號 Antigravity),把 sandbox、filesystem、工具集全部 managed 化,連環境 ID 一傳,agent 上次的中間檔還躺在那裡等你。 本文會做兩件事: 把核心能力拆開講清楚,包含背後的 antigravity-preview-05-2026 模型在做什麼。 用一隻已開源的 LINE 研究規劃師 Bot(kkdai/line-research-bot)當作活生生的示範,看新功能怎麼在實際 production code 裡組合起來 —— 順便把我除錯時撞到的五個典型 Pre-GA 坑分享給大家避雷。 核心能力三大重點 依照官方文件,這次 Managed Agents 的核心就三件事: 1. 持久化沙箱 + Filesystem(Persistent Sandbox) 過去 code interpreter 類的功能,每次呼叫就重開一個容器,上次 pip install 過的套件、寫過的檔案、開到一半的 Python 解釋器全沒了。 “Each agent operates within a sandboxed environment … capable of reasoning, planning, executing code, web searching, and file operations.” 現在你拿著同一個 environment_id 再打第二次 interaction,agent 看到的是上一次的 /workspace/: /workspace/sources.json 還在 /workspace/report.md 寫到一半,這次接著改 上次 pip install...
繼續閱讀

[GCP 實戰] LINE Bot 升級大作戰:擁抱 Vertex AI ADK Tools,實作智慧名片庫與備援搜尋

前情提要 在上一篇中,我們成功地將 LINE 名片助理機器人 (linebot-namecard-python) 從 AI Studio API Key 驗證模式,升級為企業級的 Google Cloud Vertex AI 機制,徹底擺脫了 429 配額焦慮。 然而,原本名片搜尋的做法非常有侷限性:我們必須先從 Firebase 抓出該使用者的所有名片,打包成一個巨大的 JSON 陣列,然後硬塞進 prompt 中,要求 Gemini 從中挑選最相關的名片物件回傳。 這種做法有三大死穴: Token 浪費:名片一多,每次搜尋都是對 Token 餘額無情的打擊。 缺乏彈性:模型只能被動搜尋,沒辦法主動針對細節欄位追問、也沒辦法進行資料更新。 無法連動操作:如果使用者說「幫我把王大明的電話改掉」,我們得在 Webhook 裡寫一堆複雜的 NLP 判斷和分支。 為了解決這些痛點,我們決定將機器人重構,擁抱 Google Cloud 官方最新推出、強大且代碼友善的 Agent Development Kit (ADK)! 這篇文章將與大家分享,我們如何將 Firebase 的存取完全重構為 ADK Tools、實作動態閉包(Closures),以及在 Cloud Run 部署與 Antigravity CLI 工具中所踩到的各種頂級血淚深坑! 架構升級:為什麼選擇 ADK 與 Tools? Agent Development Kit (ADK) 是 Google Cloud 推出的一套 code-first 代理人開發框架。以往我們為了讓大模型能呼叫外部 API,必須手寫落落長的 OpenAPI schema 或複雜的 function-calling 描述;而 ADK 讓這一切簡化成簡單的 Python 函數! 我們為名片 Agent 規劃了五大核心資料操作功能,並以 Python 函數 的形式直接註冊為 Agent 的 Tools: get_all_namecards():讀取當前使用者所有的名片清單(包含 ID)。 get_namecard_by_id(card_id):取得指定名片的詳細內容。 display_namecard(card_id):核心工具!當模型比對到符合條件的名片時呼叫,用來告訴 Python 主程式「該在畫面上呈現這張名片了」。 update_namecard_memo(card_id, memo):更新名片備忘錄。 update_namecard_field(card_id, field, value):直接以自然語言更新名片指定欄位(姓名、電話、Email 等)。 核心程式碼改寫:動態閉包 Tools 實作 在 Webhook 開發中,最重要的一點是安全性。我們絕對不能讓 A 使用者搜尋或修改到 B 使用者的名片。 因此,我們不能實作靜態、全域的 Database Tools。取而代之的是,我們在 handle_smart_query 中,透過閉包 (Closures) 機制為每次對話請求動態建立專屬的 Tools。 這套寫法不僅能完美綁定使用者的 user_id,還能利用閉包中的 found_card_ids 列表,完美收集模型在思考決策過程中「想要呈現給使用者看的所有名片 ID」: def make_adk_tools(user_id: str, found_card_ids: list): """為特定使用者動態建立專屬的 Firebase 資料存取與操作工具""" def get_all_namecards() -> list[dict]: """取得當前使用者在 Firebase 資料庫中所有的名片資料列表。 每張名片資料都包含唯一的 card_id 欄位。""" cards_dict = firebase_utils.get_all_cards(user_id) all_cards_list = [] for...
繼續閱讀

[工具實戰] 擁抱 Google 最新 AI 命令行助手:Antigravity CLI (agy) 與 YOLO 免確認狂飆模式全解密

前情提要 隨著生成式 AI 走入日常開發,終端機裡的 AI 助手也迎來了史詩級的更新!如果你是原先 Gemini CLI 的忠實擁護者,你可能已經知道這款工具將於 2026 年 6 月 18 日正式退役。 接下這個時代火炬的,就是 Google 在 I/O 2026 震撼推出的次世代輕量化、Go 語言驅動之多代理終端 UI 助手 —— Antigravity CLI(在終端機中以 agy 呼叫)! 然而,新工具上線總是伴隨著各種踩坑與驚喜。這篇文章將專注於 Antigravity CLI (agy),為大家解密如何搞定「看不見字的配色地獄」、如何開啟讓人欲罷不能的 YOLO 免確認狂飆模式,以及那些深藏在 settings.json 底下、鮮為人知的終端黑科技與設定秘辛! 🛠️ 填坑第一步:Antigravity CLI (agy) 配色看不見字的救星! 在安裝並首次啟動 agy 時,許多習慣 macOS / Linux 深色背景終端機的開發者,迎面而來的第一個暴擊通常是:「字體黑成一片,完全看不清文字!」 這是因為 agy 預設設定檔可能被配置成了淺色(Light)主題。我們不需要妥協去換掉自己心愛的終端機背景,只需要修改 settings.json 即可一鍵得救! 🛠️ 填坑步驟 找到 Antigravity CLI 的全域設定檔,路徑通常在: ~/.gemini/antigravity-cli/settings.json 將裡面的 "colorScheme" 設定值從 "light" 修改為 "dark": { "allowNonWorkspaceAccess": true, "colorScheme": "dark", "enableTelemetry": false, "permissions": { ... } } 存檔後重啟終端機,所有的輸出就會自動轉換為高對比度的深色模式配色,眼睛瞬間得救! 🔥 重頭戲:YOLO 模式 —— 解鎖無限自動化執行的「免確認」大絕招 大家在用 AI 寫程式時,最煩的莫過於每做一次檔案修改、執行一次 git 指令,CLI 就跳出一次詢問:「您確定要執行此操作嗎?(y/N)」。這在進行大規模重構或批次任務時,簡直是手指與精神的雙重磨難。 為此,agy 提供了兩種層級的 YOLO(You Only Live Once)免確認自動執行模式,讓 AI 能流暢、不間斷地自主執行直到任務完成: 1. ⚡ 極致 YOLO 派:--dangerously-skip-permissions 參數 如果你在一個完全隔離且安全的沙盒環境,或者對 AI 產出的指令有 100% 的信心,可以在啟動時加上這行大絕招: agy --dangerously-skip-permissions 一旦加上這個 Flag,agy 將會把所有工具授權與命令執行的確認提示完全跳過,進入「一路狂飆」的自動執行狀態。適合放著讓它自己跑完複雜的自動化測試或檔案遷移! 2. 🛡️ 溫和控管派:/permissions 精細設定 如果你不想冒著被 AI 執行 rm -rf 的風險,可以在 CLI 內直接輸入 /permissions 或直接修改 settings.json。透過白名單機制,只讓特定的指令或路徑自動批准: { "permissions": { "allow": [ "read_file(/Users/al03034132/Documents)", "command(git)", "command(npm test)" ], "deny": [ "command(rm -rf)" ] } } 這樣既能讓 Git 操作和單元測試進入...
繼續閱讀

[Workshop][Gemini CLI] Build with AI 2026 實戰筆記:用 Gemini CLI + 官方 MCP,從零到上線一隻 Google Drive LINE Bot

(活動:Build with AI 2026 @ Google Taipei 101 / 簡報:SpeakerDeck / 教材:kkdai/BwAI-2026 / 範例:kkdai/bwai2026-sample) 前情提要:當 CLI 變成「會思考的同事」 2026 年 Google I/O 之後,Gemini CLI 已經不只是另一個包了 LLM 的 terminal 玩具,而是一個可以掛 MCP、會自己 plan、會自己跑 gcloud、會在不懂的時候停下來問你的開發工具。 這次在 Build with AI 2026 的工作坊裡,我把這套工具流壓縮成兩個 hands-on session: Workshop 1:環境準備 + 兩個必裝的官方 MCP —— 讓 Gemini CLI 接上 Google 的官方知識與 Maps Platform。 Workshop 2:對 Gemini CLI 講一句話,把 LINE Bot 部署上 Cloud Run —— 不再手敲那串又長又痛苦的 gcloud run deploy ...。 整份教材已開源在 kkdai/BwAI-2026,範例專案在 kkdai/bwai2026-sample,活動投影片放在 SpeakerDeck。這篇是現場 walkthrough 的完整文字版,含我們當天在台上撞到的三個雷。 為什麼是 Gemini CLI + MCP?先看時間軸 過去一年 Gemini API 與其生態的更新節奏非常密: 時間 新東西 對工作流的影響 2025/08 Gemini YouTube Video Understanding 直接 URL 餵影片給模型 2025/11 Gemini File Search Managed RAG,不用自己接 vector DB 2025/12 Google Search Grounding (Vertex) 模型答案能 grounded 到 search 結果 2025/12 Maps Grounding & Maps Platform Assist MCP 地圖場景原生上身 2026/02 Google Developer Knowledge API + MCP Server 官方文件變成可被 LLM 查詢的工具 2026/03 Gemini 3 Flash + Tool Combo 單次 call 串多個 grounding tool 核心觀察:Google 把每個新能力都做成 MCP Server,意思是 Gemini...
繼續閱讀

[Gemini實戰][RAG] Gemini API File Search 多模態大升級全解析:Embedding 2、Metadata 過濾、頁級引用,附 LINE Bot 開源實作

(圖片來源: Google Blog - Gemini API File Search is now multimodal: build efficient, verifiable RAG) 前情提要:RAG 終於不用自己拼樂高了 過去這幾年只要做 RAG(Retrieval-Augmented Generation),開發者腦袋裡浮現的元件清單大概都長這樣: 一個 chunker(langchain?自己寫?) 一個 embedding model(OpenAI text-embedding-3?Cohere?BGE?) 一個向量資料庫(ChromaDB、FAISS、pgvector、Pinecone…挑哪個都要打架) 一個檢索 + rerank 的流程 然後才是 LLM 更別說多模態 RAG 還要再多一層:圖片怎麼 embed?要不要先 OCR?要不要切兩個 store 文字一個圖片一個?文圖混搜怎麼算分?光是這幾題就能耗掉一個 sprint。 這幾天 Google 在開發者部落格丟出 Expanded Gemini API File Search for multimodal RAG,把上面這條冗長的 pipeline 變成「呼叫一個 managed API」的事,而且圖片是原生支援的。 本文會做兩件事: 把新功能拆開講清楚,包含背後的 Gemini Embedding 2 在做什麼。 用一隻已開源的 LINE Bot(kkdai/linebot-multimodal-rag)當作活生生的示範,看新功能怎麼在實際 production code 裡組合起來 — 順便把我除錯時撞到的兩個典型坑分享給大家避雷。 新功能三大重點 依照官方部落格,這次升級的核心就三件事: 1. 真.多模態檔案搜尋(Native Multimodal File Search) 過去的 File Search 是純文字檢索,圖片只能靠 OCR 變成文字才能進 store。 “File Search now processes images and text together. Powered by the Gemini Embedding 2 model, the tool understands native image data.” 現在你可以直接把圖片丟進 File Search Store,跟文字一起被索引。背後的引擎是 Gemini Embedding 2 —— 文字、圖片、影片、音訊、文件共用同一個向量空間,所以你可以「拿圖找文字」、「拿文字找圖」、或者「拿圖找圖」,不用自己對齊空間。 對我們做產品的人來說,這代表: 文圖混搜不再是研究題目,是一個 API call。 不用維護兩個 store(一個給文字 chunks、一個給 CLIP-style image embeddings)。 科學圖表、UI screenshot、報表、相簿…這些以前 OCR 之後損失大半語意的東西,現在能保留原始視覺資訊去檢索。 2. Custom Metadata 與 Server-side 過濾 每一份你丟進 store 的檔案,現在都可以掛上 key-value 標籤: {"key": "user_id", "string_value": "U1234abcd..."} {"key": "department", "string_value": "Legal"} {"key": "status", "string_value":...
繼續閱讀