從問 AI 到用 Agent · 架構補充

A2A:把既有系統,安全開成一個 Agent 能用的服務

從「我的 Agent」出發:我要嘛去用別人的服務,要嘛把自己的既有系統開放給別的 Agent 用。這頁的重點是三件事——我的 Agent Card、A2A 的 API 設計,以及最容易被忽略的:怎麼在開放的同時,守住既有系統的穩定。

🕰️ 時代感:對外的介面一直在進化

同一個系統,對外開放的「介面」換了三個時代——從給人看,到給程式接,到給 Agent 自己讀。Agent Card 就是這一代的介面。

flowchart LR
  U["🖥️ UI
給「人」用
眼睛看 · 手點"]:::era1 A["🔌 API
給「程式」用
工程師寫 code 呼叫"]:::era2 C(["🪪 Agent Card
給「Agent」用
自己讀卡 · 自己呼叫"]):::era3 U -->|人到程式| A A -->|程式到 Agent| C classDef era1 fill:#e5e9f0,stroke:#64748b,stroke-width:2px,color:#334155 classDef era2 fill:#dbeafe,stroke:#2563eb,stroke-width:2px,color:#17335e classDef era3 fill:#dcfce7,stroke:#16a34a,stroke-width:2.5px,color:#14532d

重點:每一代都沒取代上一代——UI、API 還在。Agent Card 是「多開一個給 Agent 讀的門面」,讓你的系統也能被 AI 直接使用。

🧱 一條垂直的開放堆疊:卡 → API → 隔離層 → 既有系統

呼叫方 Agent 我的 Agent Card A2A API / 服務邏輯 隔離 / 授權層 既有系統(資料庫 / 佇列)
flowchart TB
  CALLER(["🤖 呼叫方 Agent
我的 Agent,或別人的"]):::result CARD["🪪 我的 Agent Card
放 /.well-known/agent-card.json
宣告 skill · 參數 · 回傳 · 驗證方式"]:::data API["🔌 A2A API
GET 讀卡=公開發現 · POST /tasks=要驗證
憑證放 HTTP header,不進 skill 參數"]:::proc ADP{"🛡️ 隔離 / 授權層
驗身分 · 限流
依 token 推導你能看什麼"} subgraph SYS["🏢 既有系統 · 原封不動"] direction TB SVC["服務 / 業務邏輯"]:::proc DB[("資料庫")]:::infra Q["背景任務佇列
長任務丟這裡跑"]:::infra SVC --- DB end CALLER -->|① 讀卡:你會什麼、怎麼呼叫| CARD CARD -->|② 回傳能力與呼叫方式| CALLER CALLER -->|③ POST /tasks · 憑證放 header| API API --> ADP ADP -->|④ 通過才碰,且只碰你該看的| SVC ADP -.->|長任務:立刻回 taskId,不佔線| Q SVC -->|⑤ 回結果 / 多輪| CALLER class ADP decision classDef data fill:#fef3c7,stroke:#d97706,stroke-width:2px,color:#78350f classDef decision fill:#ede9fe,stroke:#7c3aed,stroke-width:2px,color:#4c1d95 classDef proc fill:#dbeafe,stroke:#2563eb,stroke-width:2px,color:#17335e classDef result fill:#dcfce7,stroke:#16a34a,stroke-width:2px,color:#14532d classDef infra fill:#e5e9f0,stroke:#475569,stroke-width:2px,color:#1e293b style SYS fill:#f8fafc,stroke:#cbd5e1,color:#475569

關鍵:既有系統原封不動,你多加的是「卡 + API + 隔離層」這一層外皮。呼叫方碰不到你的資料庫,只碰隔離層放行的東西。

🔌 A2A 的 API 設計:兩個端點、兩層分工

端點做什麼要驗證嗎
GET /.well-known/agent-card.json公開發現:別的 Agent 讀卡,知道你會什麼通常不用(看得到 ≠ 能用)
POST /tasks實際執行:帶 skill 代號 + 參數來辦事一定要(帶憑證)
1兩層分工語言層 vs 傳輸層
自然語言層:呼叫方的 LLM 讀你的 skill 描述、自己挑對的一個;傳輸層:負責把請求送到、驗證身分。業務參數走語言層,憑證走傳輸層。
2憑證放 header,不放 skill 參數鐵則
token 一定放 HTTP header,絕不塞進 skill 參數——這樣憑證永遠不會流經 AI 的推理過程,不會被模型看到或說出去。
3兩種模式同步 vs 非同步
Message 模式:一來一回、像呼叫一個函式,適合查詢;Task 模式:回一個 taskId,任務在背景跑(submitted → working → completed),可追進度、可多輪——這才是「像 Agent」的行為。

🛡️ 既有系統的穩定性:開放的同時不被打垮

1Adapter 隔離,不直接開資料庫加一層翻譯
不要把資料庫直接對外。每個 skill 走一個小 handler,在這層做驗證、過濾、限流;後端完全不碰到未經檢查的輸入。
2長任務丟背景佇列系統不會被佔滿
A2A 立刻回 taskId,實際工作丟到獨立的背景佇列與工作池跑,不佔用網頁請求執行緒——就算有人塞一堆長任務,你的系統也不會被卡死。
3能看什麼由 server 推導別信呼叫方自報
從憑證取出身分,由 server 決定這個人能看哪些資料(可搭配資料庫的列級權限 RLS),絕不讓呼叫方自己宣稱權限——防止「假冒代理」越權。
4寫入動作要人工核准human-in-loop
查詢可以自動放行,但「會改資料、送出、付款」這類寫入動作,加一道人工核准關卡,別讓 Agent 自己一路寫到底。

📺 對應單集:A2A:讓 Agent 找 Agent 幫忙 · A2A 實戰:Agent Card 與溝通方法  |  📚 回課綱總表 →