[I/O Extended Taipei] 在 Gemini API 家族中建構應用程式:從呼叫 API,到架構一個會自己完成工作的系統

(活動:Google I/O Extended 2026 Taipei / 簡報:SpeakerDeck) 前情提要:Gemini API 已經不是「多打一個 prompt」而已 如果你對 Gemini API 的印象還停留在「選一個 model,送一段 prompt,拿回一段文字」,那你看到 2026 年這一輪更新時,很可能會突然意識到一件事: Gemini API 已經從單純的 API 介面,變成一個可以拿來搭應用、搭代理、搭非同步流程的完整平台。 這篇內容整理自我在 Google I/O Extended 2026 Taipei 的分享「在 Gemini API 家族中建構應用程式」。LINE 台灣開發者關係部技術總監 Evan Lin 在現場反覆強調的核心觀察是:開發者現在真正該思考的,不再只是 「我要用 Pro 還是 Flash?」,而是 「我要怎麼把模型、檢索、代理、回呼與成本控制串成一套系統?」。 換句話說,重點正在從 call API,轉向 design system。 先看全景圖:2026 Gemini API 家族到底多了什麼? 如果把 2026 年的 Gemini API 當成一張 capability map 來看,大致可以拆成三層。 第一層:核心模型 Gemini 3.5 Pro:最強推理能力,適合複雜規劃、進階分析與多步驟任務。 Gemini 3.5 Flash:主力模型,速度、成本與能力最平衡,適合多數產品流量。 Flash-Lite:高頻率、低成本場景的意圖判斷器與前置分類器。 Gemini Embedding 2:不只文本,也能支援多模態向量化需求。 第二層:關鍵能力模組 Retrieval:File Search、Google Search Grounding、URL Context。 Agent / Async:Agents API、Webhook、Deep Research agent。 Infrastructure:Context caching、Batch API、Live API。 第三層:系統設計方式 這一層反而最重要。因為當上面那幾個能力被做成平台服務之後,很多以前得自己補的「中間層」突然不見了: 不一定要自己搭一套 RAG pipeline。 不一定要自己養 agent loop。 不一定要用 polling 卡住主伺服器等結果。 核心觀察:Gemini API 的升級不只是「模型變強」,而是 Google 把原本屬於應用層的麻煩事,往平台層往下吃掉了。這會直接改變我們設計 AI 系統的方式。 架構轉折點:三個工具,三次思維切換 這場分享裡最值得反覆消化的,是這三個工具背後代表的架構變化。 1. File Search:從手刻 RAG,轉向 Managed RAG 以前講到企業知識問答,大家直覺就是: 切 chunk。 做 embedding。 存進 vector DB。 寫 retrieval code。 再自己補 citation 與權限控管。 現在 File Search 出現後,開發者可以把更多力氣放在「文件怎麼治理、權限怎麼分、回答怎麼呈現」,而不是一直重複寫那套基礎設施。 更重要的是,它不是只會查文字。 為什麼這次的 File Search 特別值得注意? 圖文同空間:PDF 裡的截圖、圖表、圖文混排,不再只是附件,而是模型可理解的內容。 Metadata 過濾:可以依部門、系統、文件類型做過濾,這對企業內部知識檢索非常重要。 精確引用:能回到具體頁數與 grounding metadata,讓回答更能被信任。 這代表一件很實際的事:很多企業過去花在 LangChain、向量庫與 chunking 策略上的時間,現在可以大幅往 權限設計、UX、內容治理 轉移。...
繼續閱讀

[AI 實戰] 用 AGY CLI (Antigravity) 打造 macOS 應用程式的極速 AI 協同開發體驗

寫在前面:開發者的全新協同模式 想像一下這個場景:你正在開發一個結合 macOS 底層音訊(CoreAudio/ScreenCaptureKit)與 Gemini Live API WebSocket 的即時會議翻譯 App。在測試階段,程式突然報錯閃退,且音訊串流出現全 0 的大靜音。 過去,你的排錯流程可能是: 打開終端機,撈出 log 檔案。 複製整段報錯與相關程式碼。 切換到瀏覽器,打開 AI 聊天視窗,貼上並詢問原因。 得到修改建議後,複製回編輯器,手動測試。 重複以上步驟,直到修復,然後手動寫 README.md、寫部落格、建立 GitHub 倉庫、提交代碼並推送。 而在這一次的開發中,我們採用了 Google DeepMind 設計的 AGY CLI (Antigravity-CLI) 代理人。我們驚訝地發現,上述所有繁瑣的上下文切換,都可以在終端機內透過與智慧代理的對話全自動完成。這篇文章將還原真實的 Prompt 對話流,分享我們如何與 AGY CLI 協作,從零打造出一個 macOS 會議翻譯 App。 階段一:靈感碰撞與架構設計 一切源自於一個開發想法與一份 Google 新釋出的 API 文件。開發者在終端機對 AGY CLI 貼上了網址,並拋出第一個核心問題: User: 跟著這個範例,可能打造出一個 Mac OS App 可以收取電腦裡面的聲音,然後即時翻譯成其他語言? 開始幫我思考該怎麼做,我主要目的是要可以拿來開會 zoom / google meet 直接翻譯其他國家的語言成繁體中文。 這邊有其他文件給你參考:https://ai.google.dev/gemini-api/docs/live-api/live-translate?hl=zh-tw 收到指令後,AGY CLI 發揮了架構師的角色,迅速分析並給出了一套 macOS 原生的解決方案: 不用安裝虛擬音效卡:推薦使用 Apple 在 macOS 13+ 推出的 ScreenCaptureKit 框架,直接以 Sandbox 安全模式擷取選定應用程式(如 Zoom 或 Chrome)的純淨音軌。 即時音訊重採樣:利用 AVAudioConverter 將多聲道/立體聲的 48kHz 音訊,實時重採樣為 Gemini Live 支援的 16kHz 單聲道 PCM 格式。 雙向 WebSocket 通訊:利用 Swift 的 URLSessionWebSocketTask 實作雙向長連接,一邊傳送 PCM 音訊塊,一邊接收繁體中文翻譯結果與播報音訊。 階段二:環境配置與編譯焦慮消除 在開始動手寫 Swift 代碼前,開發者對於 macOS 的編譯環境提出了疑問: User: 我是不是一定要有 xcode 才能 compile? User: 幫我跑 xcode-select –install 面對開發者的環境焦慮,AGY CLI 給出了解答: 雖然建立標準的 macOS SwiftUI GUI 應用程式包最好使用 Xcode,但我們並不一定需要手動開啟 Xcode IDE。 AGY CLI 協助撰寫了一個自動建置腳本 build_app.sh,直接調用終端機的 swiftc 命令列工具來編譯所有 .swift 原始檔,並自動打包成完整的 .app 目錄結構。 同時,對於開發者要求安裝 Command Line Tools 的請求,AGY CLI 主動呼叫了權限工具,直接在本地運行了 xcode-select --install,自動配置好 Swift 編譯環境。 階段三:連線排障與音訊...
繼續閱讀

[Gemini 3.5 Live Translate 實戰] macOS 應用程式音訊擷取與 Gemini Live API 雙向即時翻譯系統開發記

全新 API 亮相:Gemini 3.5 Live Translate 在 2026 年 6 月 9 日,Google 正式釋出了全新的語音即時翻譯模型 —— Gemini 3.5 Live Translate。這是 Google 在 AI 語音翻譯技術上的又一重大突破,目前已在 Google AI Studio、Gemini Live API 提供開發者公開預覽,並同步導入 Google Translate 與 Google Meet 等服務。 Gemini 3.5 Live Translate 的核心特點包括: 流暢自然的雙向語音翻譯:支援高達 70 種以上的語言,能自動偵測輸入語音的語言種類,不需人工設定。 連續串流生成(而非單句輪替):不同於以往必須等說話者完全說完才進行翻譯的 turn-by-turn 系統,Gemini 3.5 Live Translate 會一邊聆聽一邊實時生成翻譯,在上下文理解與即時性之間取得平衡,翻譯僅落後說話者數秒,完全避免了尷尬的停頓。 語調與節奏保留:生成的語音不僅通順,還能保留原說話者的語氣、抑揚頓挫與說話節奏。 強健的抗噪能力:在嘈雜或不穩定的環境下,依舊能準確擷取並辨識語音。 這篇文章將紀錄我們如何使用 Swift 開發一款 native macOS 應用程式 MeetingTranslator,串接這款強大的新 API,實現將特定 App 音訊即時翻譯為繁體中文語音與字幕的實戰經歷。 系統設計與架構 我們的目標是開發一款 Native SwiftUI 應用程式,它無須安裝像 BlackHole 這樣的虛擬音效卡,而是利用 Apple 官方的 ScreenCaptureKit 框架,直接擷取選定應用程式(如 Google Chrome 的 YouTube 或線上會議)的音訊流,並透過 Gemini Live WebSocket API,實現超低延遲的語音對話式翻譯。 系統架構流向 graph TD A[ScreenCaptureKit <br>擷取應用程式音訊] -->|48kHz Stereo Float32| B[AVAudioConverter <br>重採樣與聲道轉換] B -->|16kHz Mono Int16 PCM| C[Gemini Live API <br>WebSocket 連線] C -->|實時辨識字幕| D[SwiftUI Subtitle HUD <br>繁體中文雙語字幕] C -->|24kHz Mono Int16 PCM 翻譯音訊| E[AudioPlaybackManager <br>AVAudioEngine 播放器] 核心實作一:ScreenCaptureKit 擷取與重採樣 macOS 13 推出的 ScreenCaptureKit 讓開發者免去了過去依賴核心音訊虛擬設備的痛苦,能精準過濾並錄製特定應用程式的畫面與音訊。 1. 篩選與過濾目標 App 我們使用 SCShareableContent 獲取系統目前正在運作的應用程式,並篩選掉沒有名稱的背景服務及系統自帶服務: func fetchShareableApps() async -> [SCRunningApplication] { do { let content = try await SCShareableContent.current return content.applications.filter { app in let...
繼續閱讀

[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...
繼續閱讀