不用再一個個拉紅框了!Gemini 3 新功能教學:我如何用Agentic Vision,在LINE裡標註目標?
不用再一個個拉紅框了!Gemini 3 新功能教學:我如何用Agentic Vision,在LINE裡標註目標?
2026.02.03 | AI與大數據

在完成 LINE Bot 的 Multi-Agent Orchestration 架構 之後,原本的圖片分析功能是直接將圖片送到 gemini-2.5-flash 做識別。但 Google 在 2026 年 1 月發布了 Gemini 3 Flash 的 Agentic Vision 功能,讓模型不再只是「看」圖片,而是能主動寫 Python 程式碼來放大、裁切、標註圖片。

這讓我想到一個有趣的使用場景:

使用者傳一張照片,說「幫我把咖啡標記出來」,AI 不只回覆文字描述,還會畫出 bounding box 標註在圖片上,把標註後的圖片傳回 LINE。

本文記錄了實作這個功能的完整過程,包括踩到的坑和解決方案。

Agentic Vision 是什麼?

傳統的圖片分析是靜態的:丟圖片給模型,模型回傳文字描述。

Agentic Vision 把圖片理解變成一個主動的調查過程,使用 Think → Act → Observe 循環:

Agentic Vision 流程                         │
│                                                             │
│  1. Think  - 分析圖片,規劃要怎麼深入調查                     │
│  2. Act    - 寫 Python 程式碼(裁切、放大、標註、計算)         │
│  3. Observe - 觀察程式碼執行結果(包括生成的標註圖片)          │
│  4. 重複以上步驟直到完成分析                                   │
└─────────────────────────────────────────────────────────────┘

技術核心

模型: gemini-3-flash-preview
關鍵功能: code_execution 工具 — 讓模型能寫並執行 Python 程式碼
輸出: 除了文字分析,還能回傳模型生成的標註圖片

# 啟用 Agentic Vision 的 API 呼叫
response = client.models.generate_content(
    model="gemini-3-flash-preview",
    contents=[image_part, "幫我把咖啡標記出來"],
    config=types.GenerateContentConfig(
        tools=[types.Tool(code_execution=types.ToolCodeExecution)],
        thinking_config=types.ThinkingConfig(thinkingBudget=2048),
    )
)

# Response 包含多種 part:文字、程式碼、執行結果、標註圖片
for part in response.candidates[0].content.parts:
    if part.text:           # 文字分析
    if part.executable_code: # 模型寫的 Python 程式碼
    if part.code_execution_result:  # 程式碼執行結果
    if part.as_image():     # 生成的標註圖片!

功能設計

使用者體驗流程

原本收到圖片就直接分析,改成先讓使用者選擇模式:

使用者傳送圖片
     │
     ▼
┌─────────────────────────────────────┐
│  📷 已收到圖片,請選擇分析方式:      │
│                                     │
│  ┌──────────┐  ┌─────────────────┐  │
│  │ 識別圖片  │  │ Agentic Vision │  │
│  └──────────┘  └─────────────────┘  │
│         (Quick Reply Buttons)        │
└─────────────────────────────────────┘
     │                    │
     ▼                    ▼
 gemini-2.5-flash    使用者輸入指令
 直接回傳文字描述    「幫我把咖啡標記出來」
                         │
                         ▼
                  gemini-3-flash-preview
                  + code_execution
                         │
                    ┌────┴────┐
                    ▼         ▼
               文字分析    標註圖片
               (Text)    (Image)
                    │         │
                    ▼         ▼
               LINE TextMsg + ImageSendMessage

為什麼要分兩步?

Agentic Vision 需要使用者提供具體指令(例如「標記出所有人」「數一數有幾隻貓」),不像一般識別只需要「描述圖片」。所以選擇 Agentic Vision 後,會先請使用者輸入想要達成的目標。

實作細節

1. 圖片暫存機制

因為 LINE 的 Quick Reply 是異步的(使用者點按鈕觸發 PostbackEvent),圖片需要暫存:

# main.py
image_temp_store: Dict[str, bytes] = {}        # 暫存圖片(user_id → bytes)
pending_agentic_vision: Dict[str, bool] = {}    # 等待使用者輸入指令

流程:

  1. 收到圖片 → 存入 image_temp_store[user_id]
  2. 使用者點「Agentic Vision」→ 設定 pending_agentic_vision[user_id] = True
  3. 使用者輸入文字 → 偵測到 pending 狀態,取出圖片 + 文字一起送去分析

2. Quick Reply 實作

使用 LINE SDK 的 PostbackAction ,與現有的 YouTube 摘要、地點搜尋 Quick Reply 保持一致的模式:

quick_reply_buttons = QuickReply(
    items=[
        QuickReplyButton(
            action=PostbackAction(
                label="識別圖片",
                data=json.dumps({"action": "image_analyze", "mode": "recognize"}),
                display_text="識別圖片"
            )
        ),
        QuickReplyButton(
            action=PostbackAction(
                label="Agentic Vision",
                data=json.dumps({"action": "image_analyze", "mode": "agentic_vision"}),
                display_text="Agentic Vision"
            )
        ),
    ]
)

3. Agentic Vision 分析核心

# tools/summarizer.py
def analyze_image_agentic(image_data: bytes, prompt: str) -> dict:
    client = _get_vertex_client()

    contents = [
        types.Part.from_text(text=prompt),
        types.Part.from_bytes(data=image_data, mime_type="image/png")
    ]

    response = client.models.generate_content(
        model="gemini-3-flash-preview",
        contents=contents,
        config=types.GenerateContentConfig(
            temperature=0.5,
            max_output_tokens=4096,
            tools=[types.Tool(code_execution=types.ToolCodeExecution)],
            thinking_config=types.ThinkingConfig(thinkingBudget=2048),
        )
    )

    result_parts = []
    generated_images = []

    for part in response.candidates[0].content.parts:
        if hasattr(part, 'thought') and part.thought:
            continue  # 跳過 thinking parts
        if part.text is not None:
            result_parts.append(part.text)
        if part.code_execution_result is not None:
            result_parts.append(f"[Code Output]: {part.code_execution_result.output}")
        # 提取模型生成的標註圖片
        img = part.as_image()
        if img is not None:
            generated_images.append(img.image_bytes)

    return {
        "status": "success",
        "analysis": "\n".join(result_parts),
        "images": generated_images  # 標註後的圖片 bytes
    }

4. 圖片回傳機制

LINE 的 ImageSendMessage 需要公開的 HTTPS URL。因為我們部署在 Cloud Run(本身就是公開 HTTPS),所以直接在 FastAPI 上加一個圖片 serving endpoint:

# 暫存標註圖片(UUID → bytes,5 分鐘 TTL)
annotated_image_store: Dict[str, dict] = {}

@app.get("/images/{image_id}")
def serve_annotated_image(image_id: str):
    """提供暫存的標註圖片給 LINE 下載"""
    entry = annotated_image_store.get(image_id)
    if not entry:
        raise HTTPException(status_code=404)
    if time.time() - entry["created_at"] > 300:  # 5 分鐘過期
        annotated_image_store.pop(image_id, None)
        raise HTTPException(status_code=404)
    return Response(content=entry["data"], media_type="image/png")

自動偵測 App 的 base URL(從 webhook request 的 headers):

@app.post("/")
async def handle_webhook_callback(request: Request):
    global app_base_url
    if not app_base_url:
        forwarded_proto = request.headers.get('x-forwarded-proto', 'https')
        host = request.headers.get('x-forwarded-host') or request.headers.get('host', '')
        if host:
            app_base_url = f"{forwarded_proto}://{host}"

最後組合成 ImageSendMessage

def _create_image_send_message(image_bytes: bytes):
    image_id = store_annotated_image(image_bytes)
    image_url = f"{app_base_url}/images/{image_id}"
    return ImageSendMessage(
        original_content_url=image_url,
        preview_image_url=image_url,
    )

成果展示

 Agentic Vision
圖/ Evan提供
 Agentic Vision
圖/ Evan提供

踩到的坑

坑 1: from_image_bytes 不存在

ERROR: Error analyzing image: from_image_bytes

原因: google-genai SDK 中沒有 types.Part.from_image_bytes() ** 這個方法,正確的是 **types.Part.from_bytes()

# ❌ 錯誤
types.Part.from_image_bytes(data=image_data, mime_type="image/png")

# ✅ 正確
types.Part.from_bytes(data=image_data, mime_type="image/png")

坑 2: ThinkingLevel enum 不存在

ERROR: module 'google.genai.types' has no attribute 'ThinkingLevel'

原因: google-genai==1.49.0ThinkingConfig 只支援 thinkingBudget (整數),不支援 thinking_level enum。Context7 和官方文件的範例是基於更新版本的 SDK。

# ❌ 在 v1.49.0 不存在
types.ThinkingConfig(thinking_level=types.ThinkingLevel.MEDIUM)

# ✅ v1.49.0 支援的寫法
types.ThinkingConfig(thinkingBudget=2048)

教訓 :AI 生成的程式碼範例可能基於較新或較舊的 SDK 版本,永遠要用 python -c "help(types.ThinkingConfig)" 確認實際可用的參數。

坑 3: 識別圖片結果不完整

原因: gemini-2.5-flash 預設啟用 thinking,thinking tokens 會消耗 max_output_tokens 的額度。原本設定 max_output_tokens=2048,thinking 用掉一大半後,實際回覆被截斷。

# ❌ 改前:thinking 消耗了大部分 token 額度
config=types.GenerateContentConfig(
    max_output_tokens=2048,
)

# ✅ 改後:關閉 thinking + 加大 token 額度
config=types.GenerateContentConfig(
    max_output_tokens=8192,
    thinking_config=types.ThinkingConfig(thinkingBudget=0),  # 關閉 thinking
)

重點: 對於簡單的圖片描述,thinking 是多餘的開銷。thinkingBudget=0 可以關閉 thinking,讓全部 token 用在回覆上。

修改的檔案

原本的 VisionAgent 只有一條路徑,現在變成:

LINE Image Message
     │
     ▼
handle_image_message()
     │
     ├── image_temp_store[user_id] = image_bytes
     │
     ▼
Quick Reply: "識別圖片" / "Agentic Vision"
     │                         │
     ▼                         ▼
handle_image_analyze_      pending_agentic_vision[user_id] = True
postback()                     │
     │                         ▼
     │                   使用者輸入文字指令
     │                         │
     │                         ▼
     │                   handle_agentic_vision_with_prompt()
     │                         │
     ▼                         ▼
orchestrator               orchestrator
.process_image()           .process_image_agentic(prompt=使用者指令)
     │                         │
     ▼                         ▼
VisionAgent.analyze()      VisionAgent.analyze_agentic()
     │                         │
     ▼                         ▼
analyze_image()            analyze_image_agentic()
gemini-2.5-flash           gemini-3-flash-preview
thinkingBudget=0           + code_execution
                           + thinkingBudget=2048
     │                         │
     ▼                         ├── 文字分析 → TextSendMessage
TextSendMessage                ├── 標註圖片 → /images/{uuid} → ImageSendMessage
                               └── push_message([text, image])

開發心得

1. SDK 版本差異是最大的坑

這次開發最花時間的不是功能設計,而是 SDK 版本差異。 google-genai 的 API 變動頻繁:

  • from_image_bytesfrom_bytes(方法名稱變更)
  • ThinkingLevel enum 在 v1.49.0 不存在(需要用 thinkingBudget 整數)
  • thinkingmax_output_tokens 的影響沒有文件說明

建議:開發前先跑 pip show google-genai 確認版本,再用 help() 確認實際可用的 API。

2. LINE Bot 回傳圖片的限制

LINE 的 ImageSendMessage 要求圖片必須是公開的 HTTPS URL,不能直接傳 bytes。解決方案:

方案 優點 缺點
GCS 上傳 穩定、持久 需要設定 bucket 和權限
FastAPI endpoint 自行 serve 簡單、不需外部服務 重啟後消失、記憶體佔用
Base64 嵌入文字 最簡單 LINE 不支援

我選擇 FastAPI endpoint 方案,因為:

  • Cloud Run 本身就是公開 HTTPS
  • 標註圖片只需要短暫存在(5 分鐘 TTL)
  • 不需要額外設定 GCS bucket

3. Thinking 是一把雙刃劍

gemini-2.5-flash 預設啟用 thinking,這對複雜推理有幫助,但對簡單的圖片描述反而是負擔:

  • 消耗 max_output_tokens 額度
  • 增加延遲
  • 回覆可能被截斷

原則:簡單任務關閉 thinking(thinkingBudget=0),複雜的 Agentic Vision 才開啟。

4. 狀態管理的取捨

Agentic Vision 需要兩步互動(選模式 → 輸入指令),這引入了狀態管理:

image_temp_store: Dict[str, bytes] = {}       # 圖片暫存
pending_agentic_vision: Dict[str, bool] = {}   # 等待指令

用 in-memory dict 最簡單,但有個風險:Cloud Run 可能在兩次請求之間重啟。對於個人 Bot 這是可接受的,但如果要做成產品級服務,應該改用 Redis 或 Firestore。

本文授權轉載自Evan部落格,原文標題為:[Gemini 3 Flash] 在 LINE Bot 中實現 Agentic Vision:讓 AI 主動標註圖片甚至做更多 AI 處理

往下滑看下一篇文章
從智慧助手到自主代理:博弘雲端如何帶領企業走上 AI 實踐之路
從智慧助手到自主代理:博弘雲端如何帶領企業走上 AI 實踐之路

「代理式 AI 」(Agentic AI)的創新服務正在重新塑造企業對AI的想像:成為內部實際運行的數位員工,提升關鍵工作流程的效率。代理式AI的技術應用清楚指向一個核心趨勢:2025 年是 AI 邁向「代理式 AI」的起點,讓 AI 擁有決策自主權的技術轉型關鍵,2026 年這股浪潮將持續擴大並邁向規模化部署。

面對這股 AI Agent 浪潮,企業如何加速落地成為關鍵,博弘雲端以雲端與數據整合實力,結合零售、金融等產業經驗,提出 AI 系統整合商定位,協助企業從規劃、導入到維運,降低試錯風險,成為企業佈局 AI 的關鍵夥伴。

避開 AI 轉型冤枉路,企業該如何走對第一步?

博弘雲端事業中心副總經理陳亭竹指出,AI 已經從過去被動回答問題、生成內容的智慧助手,正式進化為具備自主執行能力、可跨系統協作的數位員工,應用場景也從單一任務延伸至多代理協作(Multi-Agent)模式。

「儘管 AI 前景看好,但這條導入之路並非一帆風順。」博弘雲端技術維運中心副總經理暨技術長宋青雲綜合多份市場調查報告指出,到了 2028 年,高達 70% 的重複性工作將被 AI 取代,但同時也有約 40% 的生成式 AI 專案面臨失敗風險;關鍵原因在於,企業常常低估了導入 GenAI 的整體難度——挑戰不僅來自 AI 相關技術的快速更迭,更涉及流程變革與人員適應。

2-RD096270.jpg
博弘雲端事業中心副總經理陳亭竹指出,AI 已經從過去被動回答問題的智慧助手,正式進化為具備自主執行能力、可跨系統協作的數位員工。面對這樣的轉變,企業唯有採取「小步快跑、持續驗證」的方式,才能在控制風險的同時加速 AI 落地。
圖/ 數位時代

正因如此,企業在導入 AI 時,其實需要外部專業夥伴的協助,而博弘雲端不僅擁有導入 AI 應用所需的完整技術能力,涵蓋數據、雲端、應用開發、資安防禦與維運,可以一站式滿足企業需求,更能使企業在 AI 轉型過程中少走冤枉路。

宋青雲表示,許多企業在導入 AI 時,往往因過度期待、認知落差或流程改造不全,導致專案停留在測試階段,難以真正落地。這正是博弘雲端存在的關鍵價值——協助企業釐清方向,避免踏上產業內早已被證實「不可行」的方法或技術路徑,縮短從概念驗證到正式上線的過程,讓 AI 真正成為可被信賴、可持續運作的企業戰力。

轉換率提升 50% 的關鍵:HAPPY GO 的 AI 落地實戰路徑

博弘雲端這套導入方法論,並非紙上談兵,而是已在多個實際場域中驗證成效;鼎鼎聯合行銷的 HAPPY GO 會員平台的 AI 轉型歷程,正是其最具代表性的案例之一。陳亭竹說明,HAPPY GO 過去曾面臨AI 落地應用的考驗:會員資料散落在不同部門與系統中,無法整合成完整的會員輪廓,亦難以對會員進行精準貼標與分眾行銷。

為此,博弘雲端先協助 HAPPY GO 進行會員資料的邏輯化與規格化,完成建置數據中台後,再依業務情境評估適合的 AI 模型,並且減少人工貼標的時間,逐步發展精準行銷、零售 MLOps(Machine Learning Operations,模型開發與維運管理)平台等 AI 應用。在穩固的數據基礎下,AI 應用成效也開始一一浮現:首先是 AI 市場調查應用,讓資料彙整與分析效率提升約 80%;透過 AI 個性化推薦機制,廣告點擊轉換率提升 50%。

3-RD096215.jpg
左、右為博弘雲端事業中心副總經理陳亭竹及技術維運中心副總經理暨技術長宋青雲。宋青雲分享企業導入案例,許多企業往往因過度期待、認知落差或流程改造不全,導致專案停留在測試階段,難以真正落地。這正是博弘雲端存在的關鍵價值——協助企業釐清方向,避免踏上產業內早已被證實「不可行」的方法或技術路徑,縮短從概念驗證到正式上線的過程,讓 AI 真正成為可被信賴、可持續運作的企業戰力。
圖/ 數位時代

整合 Databricks 與雲端服務,打造彈性高效的數據平台

在協助鼎鼎聯合行銷與其他客戶的實務經驗中,博弘雲端發現,底層數據架構是真正影響 AI 落地速度的關鍵之一,因與 Databricks 合作協助企業打造更具彈性與擴充性的數據平台,作為 AI 長期發展的基礎。

Databricks 以分散式資料處理框架(Apache Spark)為核心,能同時整合結構化與非結構化資料,並支援分散式資料處理、機器學習與進階分析等多元工作負載,讓企業免於在多個平台間反覆搬移資料,省下大量重複開發與系統整合的時間,從而加速 AI 應用從概念驗證、使用者驗收測試(UAT),一路推進到正式上線(Production)的過程,還能確保資料治理策略的一致性,有助於降低資料外洩與合規風險;此對於金融等高度重視資安與法規遵循的產業而言,更顯關鍵。

陳亭竹認為,Databricks 是企業在擴展 AI 應用時「進可攻、退可守」的重要選項。企業可將數據收納在雲端平台,當需要啟動新型 AI 或 Agent 專案時,再切換至 Databricks 進行開發與部署,待服務趨於穩定後,再轉回雲端平台,不僅兼顧開發效率與成本控管,也讓數據平台真正成為 AI 持續放大價值的關鍵基礎。

企業強化 AI 資安防禦的三個維度

隨著 AI 與 Agent 應用逐步深入企業核心流程,資訊安全與治理的重要性也隨之同步提升。對此,宋青雲提出建立完整 AI 資安防禦體系的 3 個維度。第一是資料治理層,企業在導入 AI 應用初期,就應做好資料分級與建立資料治理政策(Policy),明確定義高風險與隱私資料的使用邊界,並規範 AI Agent「能看什麼、說什麼、做什麼」,防止 AI 因執行錯誤而造成的資安風險。

第二是權限管理層,當 AI Agent 角色升級為數位員工時,企業也須比照人員管理方式為其設定明確的職務角色與權限範圍,包括可存取的資料類型與可執行的操作行為,防止因權限過大,讓 AI 成為新的資安破口。

第三為技術應用層,除了導入多重身份驗證、DLP 防制資料外洩、定期修補應用程式漏洞等既有資安防禦措施外,還需導入專為生成式 AI 設計的防禦機制,對 AI 的輸入指令與輸出內容進行雙向管控,降低指令注入攻擊(Prompt Injection)或惡意內容傳遞的風險。

4-RD096303.jpg
博弘雲端技術維運中心副總經理暨技術長宋青雲進一步說明「AI 應用下的資安考驗」,透過完善治理政策與角色權限,並設立專為生成式 AI 設計的防禦機制,降低 AI 安全隱私外洩的風險。
圖/ 數位時代

此外,博弘雲端也透過 MSSP 資安維運託管服務,從底層的 WAF、防火牆與入侵偵測,到針對 AI 模型特有弱點的持續掃描,提供 7×24 不間斷且即時的監控與防護。不僅能在系統出現漏洞時主動識別並修補漏洞,更可以即時監控活動,快速辨識潛在威脅。不僅如此,也能因應法規對 AI 可解釋性與可稽核性的要求,保留完整操作與決策紀錄,協助企業因應法規審查。

「AI Agent 已成為企業未來發展的必然方向,」陳亭竹強調,面對這樣的轉變,企業唯有採取「小步快跑、持續驗證」的方式,才能在控制風險的同時,加速 AI 落地。在這波變革浪潮中,博弘雲端不只是提供雲端服務技術的領航家,更是企業推動 AI 轉型的策略戰友。透過深厚的雲端與數據技術實力、跨產業的AI導入實務經驗,以及完善的資安維運託管服務,博弘雲端將持續協助企業把數據轉化為行動力,在 AI Agent 時代助企業實踐永續穩健的 AI 落地應用。

>>掌握AI 應用的新契機,立即聯繫博弘雲端專業顧問

登入數位時代會員

開啟專屬自己的主題內容,

每日推播重點文章

閱讀會員專屬文章

請先登入數位時代會員

看更多獨享內容

請先登入數位時代會員

開啟收藏文章功能,

請先登入數位時代會員

開啟訂閱文章分類功能,

請先登入數位時代會員

我還不是會員, 註冊去!
追蹤我們
2026 大重啟
© 2026 Business Next Media Corp. All Rights Reserved. 本網站內容未經允許,不得轉載。
106 台北市大安區光復南路102號9樓