A2A 實戰:16 步、一步一停、逼它真的去查價
先給你看結論:我讓一個 AI agent,自己上網幫工廠採購一批鋼板 —— 它找廠商、真的查到報價、議價、定標、開單,一路把一張採購單從頭跑到尾。這一集不是講理論,是把我實際做這件事的全過程攤開給你看:包含它一度給我亂估「一包糖九百塊」的翻車現場,以及我怎麼逼它真的去查、而不是自己編。
這正好是這個系列一直在講的那道門。你問一般的 GPT「幫我採購一批鋼板」,它會給你一段很漂亮的建議 —— 然後呢?然後還是你自己打開系統、自己找廠商、自己填單。它出一張嘴,你出兩隻手。而 agent 的差別是:它**不經二手**,直接把這張採購單做出來給你看。找廠商、查價、開單,這些原本要你手動跑的步驟,它替你動了手。這一集就是要示範,這道門跨過去以後,長什麼樣子。
這裡要先分清楚一個技術選擇。你可能聽過 MCP,那是「agent 呼叫一個工具」,像是叫它去用一個函式、查一個資料庫。但採購不是一次性的動作,它是一整段流程 —— 要來回確認、跨很多步、中間還會卡住等人。這種東西適合做成一個 A2A,也就是「agent 對 agent」的服務:我把整條採購流程包成一個有狀態、會反問你的 agent,讓對方的 agent 當客戶端來驅動它。這一集蓋的就是這個伺服器端的採購 agent。
我把採購拆成十六步,做成一個伺服器端的狀態機。設計上很單純:一張採購單,就是一個任務;這張單的單號,就是跨回合對話的續接鍵 —— 對方 agent 拿著同一個單號回來,我就知道它要接哪一張、走到哪一步了。十六步從請購、分案、尋找廠商、詢價、開標比價、議價、定標,一路到開單、收貨、驗收、付款、最後彙整成管理報表。每一步做完的資料都落地存進它自己的表,整條軌跡查得到、追得到。
我們把這條對話畫成一張循序圖,你順著看一遍就懂了。客戶端的 agent 開一張單,伺服器回「停下來,我需要請購資料」;agent 填完,伺服器不會自己往下衝,而是停在下一步等它放行。遇到要查價的步驟,伺服器把查詢字串遞出去,agent 才上網去查真實報價、回填數字。最後一路放行到底,伺服器才回傳完整的採購報表。注意這裡每一個箭頭之間,都是一個「停下來」—— 這是刻意的,下一張投影片講為什麼。
第一版我做出來,業主一試就皺眉:「怎麼一按就全部自動跑完了?我要一步一步走。」他講得對。所以我把伺服器改成一個鐵律:一則訊息,只前進一步。做完當前這步,就停在下一步,把控制權交回去,絕不自己一路衝到底。連那種伺服器自己就能做的自動步驟 —— 像開標、開單 —— 我也讓它先停住,要對方回一句「放行」才執行。為什麼這麼龜毛?因為這樣一來,每一步都變成一個可以被人攔下來、可以審核的斷點。
這帶到一個這個系列一直強調的觀念:能力跟風險,是同一枚硬幣的正反面。正因為這個 agent 真的會替你動手 —— 它能不經二手地幫你送出訂單、花掉公司的錢 —— 所以它能動手這件事,跟你要不要能喊停,是同一件事。採購牽涉的是錢跟合約,定標定錯、單開錯,代價是真金白銀。自動一路跑完看起來很爽,但人根本插不進手,也沒辦法為結果背書。一步一停,才是真正把人留在迴圈裡,而不是嘴上說說的「人工審核」。
光是停下來要資料還不夠。我發現 agent 常常搞不清楚這一步到底該自己去查、還是該去問人。所以每一個需要輸入的步驟,伺服器都回一個很明確的訊號:這步是「該去搜尋」,還是「該找人互動」。如果是搜尋步 —— 像詢價、找廠商 —— 我甚至直接把查詢字串幫它拼好遞過去,告訴它「拿這串去採購網、去 B2B 平台查」。把每一步該做的動作講死,agent 就不會亂猜、不會跳步,這是讓它聽話的關鍵。
接下來是我印象最深的翻車。詢價這一步,我第一版好心留了一句話:「如果一時拿不到報價,可以只回廠商名單,系統會幫你估價。」結果呢?agent 立刻走捷徑,只丟了幾個廠商名字回來,系統就傻傻地對「一包彩虹糖」估出了九百多塊的單價。業主一看就抓包:「彩虹糖怎麼可能這麼貴?你是不是根本沒去查?」教訓非常清楚,而且放到任何 agent 系統都成立:**只要你留了一條偷懶的路,agent 一定會走那條路。**
修法就是把那條逃生門整個拆掉。詢價這步改成強制要真實的數字報價,只給廠商名字、沒有價格 —— 直接退回,不讓它過。指示也講得很白:「這個品項的價格,系統這邊沒有資料、也不會幫你估,你自己上網去查實際行情,查到多少填多少,禁止編造。」設計 agent 系統的時候,你要預設它會挑最省事的那條路,所以你的工作,是把所有你不想要它走的捷徑,一條一條堵死。
堵死捷徑、把搜尋訊號給清楚之後,見真章的時刻來了。業主的 agent 真的自己把一張熱軋鋼板的採購單,從第一步跑到第十六步完成。而且這次搜尋是真的有作用:找廠商那步,它查到了真實存在的鋼鐵供應商;詢價那步,它真的跑去 1688 這個 B2B 平台,抓到了以每公斤計價的實際報價;接著自己議價、選最低價定標、開出採購單、彙整報表。那一刻看板上十六張卡片一路變綠、進度條推到底 —— 一個 agent,真的不經二手地替你把一整條採購流程走完了。
但我要很誠實地說:跑完,不代表跑對。認真核對資料,有兩個明顯的洞。第一,它找廠商那步找的是台灣廠商,詢價那步卻跳去 1688 報了一批完全不同的供應商,兩邊對不上 —— 而系統的催報價那步還很盡責地把台灣那幾家列成「還沒報價」。第二,最後對帳金額算錯了:它拿「每公斤的單價」乘上「幾張鋼板」,單位根本兜不攏。我把這些照實記下來,因為誠實才有說服力:能跑通只是起點,資料一致性跟單位正確,才是採購系統真正的命。
工程上也踩了坑,講兩個。第一,這套 SDK 預設把任務存在記憶體裡,我開發時一直改程式、重開伺服器,每重開一次,對方正在跑的任務就整個消失 —— 它還以為是逾時,其實是被我重啟洗掉的。修法是自己把任務落地存進資料庫,重啟也接得回同一張單。但更痛的教訓在後面:我為了改資料表結構,圖方便直接把整個資料庫砍掉重建,把業主前一天建的資料也一起洗掉了。落地擋得住重啟,擋不住我手賤。資料是客戶的,改結構前該先備份,不是說砍就砍 —— 這個錯我認。
還有一個很實在的需求。業主說:「agent 是在跑沒錯,但用起來對方沒感覺,我需要一個畫面,看到資料在動。」所以我在同一個伺服器上加了一個唯讀的看板頁,每秒刷新、直接讀資料庫。十六步排成一面卡片牆:做完的變綠、正在停等的那格發琥珀色的光、還沒到的是灰的。agent 每送出一步,對應那格的資料就即時長出來、閃一下高亮、進度條往前推。它純粹是唯讀的,只反映資料、不從畫面輸入 —— 因為輸入端是 agent,不是人。這一下,原本看不見的自動流程,變得看得見了。
最後,把「採購」這兩個字抽掉,你會發現剩下的是一個非常通用的模式:任何一條「步驟很多、要來回確認、中間要卡人審核」的企業流程,都能做成這樣一個 A2A agent。一步一停的狀態機、告訴 agent 該搜尋還是該找人的訊號、落地不丟的任務、還有讓人看得見的即時看板 —— 這些零件可以直接搬。請假、報支、合約審批、維修工單、客訴處理…你只要換掉那張「步驟定義表」,就是另一條完全不同的流程。
用一句話收尾。這一集從頭到尾在講的,就是 agent 能替你不經二手地把一整條流程做出來 —— 這是它真正的威力,也是「從問 AI 到用 Agent」那道門的另一邊。但正因為它真的會動手、會動錢、會動合約,所以那幾步該你把關的,那一下,千萬別交出去。能動手跟要把關,從來都是同一件事的正反兩面。