[Gemini] Tool Combo 實戰:在單次 API 呼叫中結合 Maps Grounding 與 Places API 打造 LINE 聚會地點小幫手

參考文章: Gemini API tooling updates: context circulation, tool combos and Maps grounding for Gemini 3 Google Places API (New) - searchNearby GitHub: linebot-spot-finder 完整程式碼 GitHub (聚會小幫手 LINE Bot Spot Finder) 前情提要 LINE Bot + Gemini 的組合已經很常見,不管是用 Google Search Grounding 讓模型查即時資訊,還是用 Function Calling 讓模型呼叫自訂邏輯,單獨使用都很成熟。 但如果你想在同一個問題裡同時做到「地圖定位情境」和「查詢真實評分」呢? 以餐廳搜尋來說,傳統做法通常長這樣: 用戶: "幫我找附近評價4星以上的熱炒店" 方案 A(只用 Maps Grounding): Gemini 有地圖情境,但評分資訊是 AI 自行描述,不保證準確。 方案 B(只用 Places API): 可以拿到真實評分,但沒有地圖情境,Gemini 不知道用戶在哪裡。 要兩者兼得,通常需要分兩次 API 呼叫,或是自己手動串接。 AI 能查地圖、也能呼叫外部 API,但要在一次呼叫裡同時做到這兩件事——在 Gemini API 的舊架構下一直是個尷尬的空白。 直到 2026 年 3 月 17 日,Google 發布了 Gemini API Tooling Updates(作者:Mariano Cocirio),這個問題才有了官方解法。 什麼是 Tool Combinations? Google 在這次更新中宣布了三個核心功能: 1. Tool Combinations(工具組合) 開發者現在可以在單次 Gemini API 呼叫中同時掛上 built-in 工具(如 Google Search、Google Maps)以及自訂 Function Declarations。模型自行決定要呼叫哪個工具、何時呼叫,最後整合結果生成回答。 2. Maps Grounding Gemini 現在可以直接感知地圖資料,不再只是文字描述「位置」,而是真正具備空間情境——知道用戶在哪裡、附近有什麼。 3. Context Circulation 讓多輪工具呼叫之間的情境能自然流通,模型在第二次呼叫時能完整記憶第一次的工具呼叫結果。 這次改動的關鍵在於: # 舊的做法(兩個工具不能並存) types.Tool(google_search=types.GoogleSearch()) types.Tool(function_declarations=[MY_FN]) # 新的做法(同一個 Tool 物件,兩者共存) types.Tool( google_maps=types.GoogleMaps(), function_declarations=[MY_FN], ) 一行改動,打開了全新的組合方式。 專案目標 這次我用 Tool Combinations 改造了既有的 linebot-spot-finder,讓它從「只能 Maps Grounding 粗略回答」升級到「Google Maps 情境 + Places API 真實資料」: 用戶傳送 GPS 位置後輸入:「請找評價 4 顆星以上、適合多人聚餐的熱炒店,列出名稱、地址和評論摘要。」 Bot(舊版 Maps Grounding):「附近有幾間熱炒店,評價都不錯。」(AI 自行描述,可能不準) Bot(新版...
繼續閱讀

[Gemini] Multimodal Function Response 實戰:打造能「看圖說故事」的 LINE 電商客服機器人

參考文章: Gemini API - Function Calling with Multimodal GitHub: linebot-gemini-multimodel-funcal Vertex AI - Multimodal Function Response 完整程式碼 GitHub 前情提要 相信很多人都用過 LINE Bot + Function Calling 的組合。當用戶問「我上個月買了什麼衣服?」時,Bot 呼叫資料庫查詢函式,取回訂單資料,然後 Gemini 根據那份 JSON 回答: 開發者設計的傳統流程: 用戶: "幫我看看我之前買過的那件外套" Bot: [呼叫 get_order_history()] 函式回傳: {"product_name": "棕色飛行員外套", "order_date": "2026-01-15", ...} Gemini: "您在 1 月 15 日購買了棕色飛行員外套,金額 NT$1,890。" 回答完全正確,但總覺得少了什麼——用戶說的是「那件外套」,Gemini 只是轉述 JSON 裡的文字,完全沒有辦法「確認」那件衣服長什麼樣子。如果資料庫裡剛好有三件外套,AI 根本無法判斷哪件才是用戶記憶中的那件。 AI 能讀懂文字,但看不到圖片——這個限制在傳統 Function Calling 架構下一直是死角。 直到 Gemini 推出了 Multimodal Function Response,這個問題才被真正解決。 什麼是 Multimodal Function Response? 傳統的 Function Calling 流程是這樣的: [用戶訊息] → Gemini → [function_call] → [執行函式] → [回傳 JSON] → Gemini → [文字回答] Multimodal Function Response 改變了中間那一步。函式不只能回傳 JSON,還能在同一個回應中夾帶圖片(JPEG/PNG/WebP)或文件(PDF): [用戶訊息] → Gemini → [function_call] → [執行函式] → [回傳 JSON + 圖片 bytes] → Gemini → [看過圖片的文字回答] Gemini 在下一輪生成回答時,能同時「看到」函式回傳的結構化資料和圖片,從而生成更豐富、更精準的回應。 官方目前支援的媒體格式: 類別 支援格式 圖片 image/jpeg, image/png, image/webp 文件 application/pdf, text/plain 這個功能的應用場景非常廣泛:電商客服(辨識商品圖片)、醫療諮詢(分析檢驗報告 PDF)、設計評審(看截圖給建議)……幾乎所有需要「函式回傳視覺資料給 AI 分析」的場景都適用。 專案目標 這次我用 Multimodal Function Response 打造了一個 LINE 電商客服機器人,示範以下場景: 用戶:「幫我看看我之前買過的那件外套」 Bot(傳統):「您購買了棕色飛行員外套。」 Bot(Multimodal):「從照片中可以看到這是一件棕色飛行員外套,輕量尼龍材質,側邊有金屬拉鏈裝飾口袋。這是您 1 月 15 日的訂單 ORD-2026-0115,共 NT$1,890,已送達。」+ 商品照片 差別顯而易見:Gemini 真的「看了」那件衣服,而不只是轉述資料庫裡的文字。 架構設計 為什麼不用 Google ADK?...
繼續閱讀

AI Agent 的安全性宣告:深入探索 A2AS (Agent-to-Agent Security) 憑證機制

參考連結: A2AS.org 官方網站 linebot-adk 專案認證頁面 這篇文章記錄了我在維護 linebot-adk (LINE Bot Agent Development Kit) 時,收到的一個有趣 Pull Request:為專案加上 A2AS 安全憑證。這不只是一個 YAML 檔案,更是 2026 年 AI Agent 邁向「工業級安全」的重要里程碑。 前情提要 當我們在開發像 linebot-adk 這樣具備 Tool Use (Function Calling) 能力的 Agent 時,使用者最擔心的問題往往是:「這個 Agent 會不會背著我亂下指令?」或是「它到底能存取哪些資料?」。 傳統上我們只能在 README.md 寫寫說明,但那是給人看的,不是給系統驗證的。這就是為什麼 A2AS (Agent-to-Agent Security) 出現了——它被譽為「AI 界的 HTTPS」。 🛠️ 第一步:理解 A2AS 的 BASIC 模型 A2AS 不只是個名稱,它背後有一套完整的 BASIC 安全模型,旨在解決 AI Agent 之間的信任問題: (B)ehavior Certificates: 宣告式憑證,明確定義 Agent 的行為邊界。 (A)uthenticated Prompts: 確保提示詞的來源可信且具備追蹤性。 (S)ecurity Boundaries: 利用結構化標籤(如 <a2as:user>)隔離不受信任的輸入。 (I)n-Context Defenses: 在 Prompt 中嵌入防禦邏輯,拒絕惡意注入。 (C)odified Policies: 將業務規則寫成程式碼,在推論時強制執行。 🎨 第二步:解構 a2as.yaml——Agent 的身份證 在 linebot-adk 收到 PR #1 中,最核心的變動就是新增了 a2as.yaml。這個檔案就像是 Agent 的「數位簽名」,將程式碼邏輯顯性化: manifest: subject: name: kkdai/linebot-adk scope: [main.py, multi_tool_agent/agent.py] issued: by: A2AS.org url: https://a2as.org/certified/agents/kkdai/linebot-adk agents: root_agent: type: instance models: [gemini-2.5-flash] tools: [get_weather, get_current_time] 為什麼這很重要? 這份憑證直接與我們的 main.py 內容掛鉤。當憑證宣告了 tools: [get_weather, get_current_time],就代表這是一個有限授權的 Agent。如果它試圖執行 delete_database,安全性監控系統就能立刻發現這超出了憑證範圍。 🌐 第三步:結合程式碼邏輯 在 linebot-adk 中,我們使用了 Google 的 ADK (Agent Development Kit) 來建構 Agent。A2AS 憑證能精準地映射我們的程式架構: 1. 工具宣告與實現 在 multi_tool_agent/agent.py 中,我們定義了兩個工具: def get_weather(city: str) -> dict: # 實現獲取天氣的邏輯 ... def...
繼續閱讀

打造 Agent Skill Hub:從技能開發到 GitHub Pages 多國語言文件自動化部署

參考連結: Agent Skill Hub 儲存庫 GitHub Pages 官方說明文件 這篇文章記錄了我在開發 Agent Skill Hub (2026 技能庫) 時,如何從零開始建構技能描述規範,並參考極簡美學打造出支援中英雙語的 GitHub Pages 文件站。 前情提要 隨著 AI Agent(如 OpenClaw 或 Gemini CLI)的普及,我們發現「如何讓 Agent 快速理解並執行特定任務」成為了關鍵。與其每次都寫長長的 Prompt,不如將常用的操作封裝成標準化的 Skills。 為了方便社群交流與 Agent 讀取,我建立了 agent-skill-hub。但只有程式碼是不夠的,我們還需要一個像樣的「門面」—— 一個既美觀又具備技術細節的文件網站。 🛠️ 第一步:標準化技能描述 (SKILL.md) 在 agent-skill-hub 中,每個技能(如 gcp-helper 或 n8n-executor)都擁有一個 SKILL.md。這個檔案的結構至關重要,因為它不只是給人看的,更是給 LLM 讀取的: Name & Description: 讓 Agent 知道這是什麼。 When to Use: 定義觸發場景。 Core Pattern: 提供標準指令範例。 Common Mistakes: 減少 Agent 幻覺導致的錯誤。 🎨 第二步:設計風格——致敬極簡美學 在設計 docs 目錄下的網頁時,我參考了 whisperASR 的風格。那種深色背景搭配亮眼點綴色(Teal)的設計,非常符合現代開發者的審美: 視覺元素重點: 漸層標題:利用 linear-gradient 營造出高端的質感。 Teal 點綴色:使用 #14b8a6 作為關鍵按鈕與標題的強調色。 卡片式佈局:清楚呈現每個技能的圖示與簡介,具備良好的回應式設計(Responsive Design)。 🌐 第三步:多國語言支援與自動跳轉 為了讓全球開發者都能使用,我採用了目錄結構化的語系管理方式: docs/ ├── index.html (語言偵測與導向) ├── en/ (英文版本) │ └── skills/ └── zh/ (繁體中文版本) └── skills/ 我在根目錄的 index.html 加入了一段簡單的 JavaScript,會根據使用者的瀏覽器設定自動引導至正確的語系: const lang = navigator.language || navigator.userLanguage; if (lang.startsWith('zh')) { window.location.href = './zh/index.html'; } else { window.location.href = './en/index.html'; } 🚀 第四步:GitHub Pages 部署流程 在 2026 年,最推薦的部署方式是將內容放在主分支的 docs/ 目錄下,這樣可以保持 main 分支的整潔,同時讓開發與文件同步更新。 1. 準備目錄結構 透過指令一次建立所有需要的目錄: mkdir -p docs/en/skills docs/zh/skills docs/assets/css 2. Git 提交與 Push 完成 HTML/CSS 開發後,執行標準的 Git...
繼續閱讀

在 Google Cloud VM 部署 OpenClaw:避開 sudo-rs 權限與 NVM 路徑的技術坑

(Image generated by Nano Banana - Gemini Image Generation) 參考文章: OpenClaw 官方網站 OpenClaw 實戰教學:中文整理 FAQ 與建議 Skills OpenClaw 安全指南:資安加強建議 YouTube 教學影片:在 GCP 部署 OpenClaw 這篇文章記錄了在 Google Cloud Platform (GCP) 的 Debian/Ubuntu 環境下,安裝 OpenClaw (2026 最新版) 時遇到的權限、環境變數及進程持久化問題的完整解決流程。 前情提要 最近 AI Agent 領域非常熱門,OpenClaw 作為一個能 24 小時運作的開源 AI 代理,其強大的系統存取與瀏覽能力讓人印象深刻。為了安全起見,將它部署在雲端 VM (如 GCP GCE) 是最理想的作法,既能保證 24/7 在線,又能隔離本機的敏感資料。 但在 GCP 的預設 Debian/Ubuntu 環境中,由於權限機制與一般的 Desktop Linux 略有不同,照著官方腳本安裝往往會踩到不少坑。 🛠️ OpenClaw 在 GCP 的基本安裝流程 在進入故障排除之前,我們先快速跑一遍標準的安裝邏輯: 1. 建立 VM 執行個體 在 GCP Console 建立一個新的 VM: 機型:建議 e2-small 或 e2-medium(視您的 Agent 負載而定)。 作業系統:建議選用 Ubuntu 24.04 LTS 或 Debian 12。 硬碟:建議 20GB 以上。 2. 連線與基礎更新 透過 SSH 進入 VM 後,先執行系統更新: sudo apt update && sudo apt upgrade -y sudo apt install -y git curl build-essential 3. 正式安裝 OpenClaw 官方提供了一鍵安裝腳本: curl -fsSL https://openclaw.ai/install.sh | bash 但是! 如果您直接執行上述腳本,在 GCP 上通常會遇到以下兩個嚴重的權限與路徑問題。 🛠️ 問題一:sudo-rs 的「HAL 9000」式拒絕 現象: 當執行官方安裝腳本時,遇到 sudo-rs 報錯: sudo-rs: I'm sorry evanslin. I'm afraid I can't do that 原因: 互動限制:透過 curl ... |...
繼續閱讀

[Gemini] Multimodal Function Response 實戰:打造能「看圖說故事」的 LINE 電商客服機器人

參考文章: Gemini API - Function Calling with Multimodal GitHub: linebot-gemini-multimodel-funcal Vertex AI - Multimodal Function Response 完整程式碼 GitHub 前情提要 相信很多人都用過 LINE Bot + Function Calling 的組合。當用戶問「我上個月買了什麼衣服?」時,Bot 呼叫資料庫查詢函式,取回訂單資料,然後 Gemini 根據那份 JSON 回答: 開發者設計的傳統流程: 用戶: "幫我看看我之前買過的那件外套" Bot: [呼叫 get_order_history()] 函式回傳: {"product_name": "棕色飛行員外套", "order_date": "2026-01-15", ...} Gemini: "您在 1 月 15 日購買了棕色飛行員外套,金額 NT$1,890。" 回答完全正確,但總覺得少了什麼——用戶說的是「那件外套」,Gemini 只是轉述 JSON 裡的文字,完全沒有辦法「確認」那件衣服長什麼樣子。如果資料庫裡剛好有三件外套,AI 根本無法判斷哪件才是用戶記憶中的那件。 AI 能讀懂文字,但看不到圖片——這個限制在傳統 Function Calling 架構下一直是死角。 直到 Gemini 推出了 Multimodal Function Response,這個問題才被真正解決。 什麼是 Multimodal Function Response? 傳統的 Function Calling 流程是這樣的: [用戶訊息] → Gemini → [function_call] → [執行函式] → [回傳 JSON] → Gemini → [文字回答] Multimodal Function Response 改變了中間那一步。函式不只能回傳 JSON,還能在同一個回應中夾帶圖片(JPEG/PNG/WebP)或文件(PDF): [用戶訊息] → Gemini → [function_call] → [執行函式] → [回傳 JSON + 圖片 bytes] → Gemini → [看過圖片的文字回答] Gemini 在下一輪生成回答時,能同時「看到」函式回傳的結構化資料和圖片,從而生成更豐富、更精準的回應。 官方目前支援的媒體格式: 類別 支援格式 圖片 image/jpeg, image/png, image/webp 文件 application/pdf, text/plain 這個功能的應用場景非常廣泛:電商客服(辨識商品圖片)、醫療諮詢(分析檢驗報告 PDF)、設計評審(看截圖給建議)……幾乎所有需要「函式回傳視覺資料給 AI 分析」的場景都適用。 專案目標 這次我用 Multimodal Function Response 打造了一個 LINE 電商客服機器人,示範以下場景: 用戶:「幫我看看我之前買過的那件外套」 Bot(傳統):「您購買了棕色飛行員外套。」 Bot(Multimodal):「從照片中可以看到這是一件棕色飛行員外套,輕量尼龍材質,側邊有金屬拉鏈裝飾口袋。這是您 1 月 15 日的訂單 ORD-2026-0115,共 NT$1,890,已送達。」+ 商品照片 差別顯而易見:Gemini 真的「看了」那件衣服,而不只是轉述資料庫裡的文字。 架構設計 為什麼不用 Google ADK?...
繼續閱讀