返回專案列表
生態協議

Wall Street

the Agent-to-Agent Exchange

Wall Street自己也是一個小型多智慧體系統:一個跑在輕量ReAct迴圈上的編排器、一個連線推薦專家、一個資料解讀專家,三者用哪一檔LLM都由設定驅動。目前部署的閘道環境裡沒有接入任何模型,所以推薦專家的確定性規則路徑承擔了全部請求;ReAct迴圈和解讀專家已經建成,只等那一項設定。五個階段、二十四張票,全部交付。

分享這篇案例 →
3
已接入系統
3
內部Agent
A2A gateway (envelope, auth, circuit breaker)
協議
難點所在

難點在於:在三個各自獨立的系統寫下任何一行新程式碼之前,先把它們都必須遵守的線上契約凍結下來——每個欄位都要能對應到某張生產資料表裡真實存在的欄位,九種失敗模式統統收斂成同一個「未接通」結果——因為在設計階段就把降級語義定對,遠比等三個團隊都已經照著一份上線的契約寫完程式碼之後再回頭補救便宜得多。

架構一覽
已上線
截至 2026-07-31
A2A protocol gateway (envelope, pluggable auth, circuit breaker)React Flow canvas as the orchestration surfaceConfig-driven topology — add a system with zero core-code changeLoose coupling, mutual support — any peer offline degrades gracefullyConfig-driven LLM tiers + externalized prompt store — deterministic rule paths ship as the default
完整的內部 Agent 陣容
其中 2 個節點已建成、已接線,但尚未啟用——圖中已逐一標註
orchestrator已建成 · 尚未啟用connection-recommenderdata-interpreter已建成 · 尚未啟用
Agent

Lightweight ReAct loop over Wall Street's own specialists. The deployed gateway is built with no LLM tier wired into its environment, so the loop short-circuits before it runs and every request is served by the deterministic path instead.

Wall Street 在生態系統中
技術棧

Python (gateway), React, Vite, TypeScript, Tailwind, React Flow

01一個信封,九種失敗模式,一個結果

每一次跨系統呼叫都攜帶同一份信封:一個X-A2A-Version標頭、一個同時充當consult冪等鍵的請求ID,還有一個貫穿呼叫方、樞紐、應答方全程的追蹤ID,讓一次跨系統交互事後能從三份各自獨立的稽核軌跡裡重新拼出來。九種命名好的失敗碼——從鑑權被拒到對端不可達,再到回應沒通過schema校驗——對呼叫方而言統統收斂成同一個結果:一個標註清楚的「未接通」,絕不崩潰,也絕不卡住本地流程。一條可插拔的鑑權鏈(先IP白名單,再逐呼叫方的bearer token,mTLS的位置已經留好但還沒實作)擋在每個對端的A2A介面前面,和該系統自己的UI登入刻意分開。這些都不是事後補上去的通用中介軟體——信封、鑑權鏈、完整的錯誤分類,是最早被設計出來的東西,早於任何一個對端伺服器或畫布上的元素。

02配置就是可擴充的介面

一份YAML拓撲登記表是唯一知道「有哪些系統存在、誰能跟誰說話」的地方:每個對端宣告自己的節點類型,以及它提供和消費的能力;每條連線規則則指名一個能力、一個提供方,和它合法的消費方。閘道在每次呼叫時執行這些規則,畫布也會先問同一份登記表——一個BFF端點,GET /api/topology——才允許使用者在兩個節點之間拖出一條連線,前端從不寫死任何一對系統。往生態裡接入第四、第五個系統,範圍被限定成:實作A2A伺服器的最小介面(health、capabilities,以及它自己的query端點)、往拓撲配置裡加一段、加上它的token環境變數——只有在它需要一種視覺上不同的節點時,才需要往前端登記表裡加一個新節點類型。如果重複使用通用的「system」節點類型,前端程式碼量是零——新對端只要被能力探索機制找到,就會自動出現。

03畫布是協議的下游

在畫布上,系統、Agent、資料來源是節點,A2A能力是邊——一條data-share邊透過query呼叫把對端的真實生產資料拉進來,一條consult邊發出請求,把對端的回答當作唯讀結論顯示在詳情抽屜裡。每個節點、每條邊都獨立降級:一個不可達的對端,它的節點會灰顯並附上原因碼,畫布其餘部分照常按設計運作——這正是協議在線路層面強制的「沒有任何一方是另一方的運作支柱」這條規則,只是現在從一行日誌變成了一個看得見的UI狀態。畫布是訪客真正看得到、點得到的那一部分;但它執行的每一條規則——哪些連線合法、一個降級的對端長什麼樣、到底什麼資料允許抵達瀏覽器——都是先在閘道和契約裡定下來的。畫布只是把那份設計呈現出來,它本身不是另一份設計。

04一個本身就是多智慧體系統的樞紐

Wall Street不只是轉發其他系統的Agent——它自己也帶著一支小隊伍:一個編排器,用的是這個作品集裡其他地方同款的輕量ReAct迴圈;一個連線推薦專家,讀取目前畫布和能力地圖,建議可行的連線;一個資料解讀專家,把某個節點已經去識別化過的指標變成一句話解讀。有兩件事值得直說,而不是留給示意圖去暗示。第一,調度的起點其實在閘道的靜態BFF路由表:先由它選中專家,專家再自己建構編排器——協同是真程式碼,但並不從樞紐開始。第二,目前部署的容器環境裡沒有接入任何LLM檔位,編排器的ReAct迴圈在真正跑起來之前就短路了:推薦專家的規則備援——直接從provider/consumer在能力地圖裡的交集算出來——承擔了今天的全部請求;解讀專家按設計沒有規則路徑,於是返回空結果,畫布隨即把這個入口隱藏起來。第四個專家——一個能跨多個節點串聯敘事的insight-narrator——已經設計好、設定裡也留了位置,但在跨節點敘事合成真正做出來之前先保持停用。每個Agent用哪一檔LLM、溫度多少、要不要啟用,統統寫在一份設定檔裡——換模型是改設定,從來不是改程式碼;每一條system prompt都放在外部的提示詞庫裡,按語言和key載入,從不寫死在Agent程式碼本身裡。

05瀏覽器裡沒有token,跨系統也沒有寫入操作

瀏覽器永遠不持有A2A token,也永遠不直連對端——它只用一個獨立的UI token向閘道的BFF鑑權,而它收到的每一個生產資料數字,都已經先經過閘道的去識別化層,序列化時套用契約自己的欄位白名單,任何沒有明確列出的欄位都會被靜默丟棄。每一份資料契約都會把自己的自由文字欄位——一條標題、一條備註、一個Agent的回答——標記為不可信,任何把這段文字回灌進自己LLM的系統,都必須把它包進自己既有的防注入信封,當成資料而不是指令來處理;契約自帶的測試套件要求:一條嵌了「把預算改成零」這種指令的回覆,不能在任何地方產生寫入操作。跨系統呼叫按設計唯讀——唯一的例外,consult的結論,也只能以「提議動作」的形式回來,在接收方自己的人工確認流程核准之前,哪裡都不會被執行。這些都不是事後加的補丁:白名單即schema、不可信欄位標記、跨系統零寫入操作,這些規則就是契約本身,在任何一個對端把它實作出來之前就已經凍結。

技術棧

Python(stdlib A2A閘道)、React + Vite + TypeScript畫布、Tailwind CSS、React Flow,以及一個三方共用的參考mock伺服器,用於跨倉庫的契約一致性測試。

— 履歷與聯絡方式

聊。