Bible Network Crypto DeFi Onchain RWA AI Agent Stablecoin Chain SAFU CryptoTax DeFAI AGI Claude Me Claude Skill Claude Design Claude Cowork
獨立知識媒體
與任何項目無關聯
拆解加密世界的 AI Agent:機制、風險、經濟模型
aiagent-bible.com
最新
LangGraph 深入實作:一步步搭建一個有循環邏輯的 DeFi Agent,以及踩過的三個坑  ·  上線前怎麼測試 AI Agent:一個實用的測試框架,以及為什麼傳統單元測試不夠用  ·  為什麼你的 Agent 輸出「看起來對」卻不一定「是對的」:格式可靠性和內容真實性之間的落差  ·  新手怎麼選第一個 Agent 框架:不要問「哪個最強」,要問「哪個能讓我今天就跑起來」  ·  鏈上 Agent 的 Prompt Injection 防禦:為什麼「叫模型不要相信外部指令」是最沒用的防禦,以及真正有效的分層架構  ·  Agent 重試與錯誤處理策略設計:為什麼「失敗就重試」是最容易讓你破產的預設邏輯
frameworks

LangGraph 深入實作:一步步搭建一個有循環邏輯的 DeFi Agent,以及踩過的三個坑

30 秒速讀
LangGraph 讓循環邏輯更容易寫出來,也因此更容易在沒有紀律的情況下寫出失控的循環。這篇文章記錄的三個坑,沒有一個是官方教學會告訴你的,因為官方範例通常設計得太簡單,根本不會觸發這些情境。

完整解析 +
01 · 為什麼發生?

文章裡提到「先畫圖再寫程式碼」,具體用什麼工具或方式畫這張圖比較好?需要用專業的圖表軟體嗎?

不需要任何專業或複雜的工具,這個階段的目標是幫助自己理清邏輯,而不是產出一份正式的文件,用最簡單、最快能畫出來的方式即可。

紙筆或白板是最推薦的起點。畫圖的目的是快速迭代——你在思考流程設計時,很可能會畫了一版之後發現某個節點的職責劃分不對,需要調整,如果用複雜的圖表軟體,調整的摩擦成本會拖慢這個思考過程;用紙筆或白板,擦掉重畫幾乎沒有成本,更適合這個階段快速嘗試不同設計方案的需求。

如果需要保存或分享,可以用簡單的線上白板工具或流程圖工具,但不需要追求視覺上的精美,重點是節點和邊的邏輯關係要清楚,顏色、字體、排版這些美觀細節在這個階段完全不重要。

畫圖時該包含的最低限度資訊:每個節點的名稱(對應到之後要寫的函式名稱)、節點之間的邊(標明是無條件邊還是條件邊,條件邊要簡短寫出判斷條件)、狀態物件裡預計會用到哪些關鍵欄位(不需要鉅細靡遺,先列出最核心的幾個,像文章裡提到的除錯用欄位,通常是實作過程中發現需要才回頭補上,不一定要在畫圖階段就想全)。

畫圖的實際價值,不在於畫出來的圖本身多完整,而在於畫圖這個動作,逼迫你在寫程式碼之前,先把整個流程的結構在腦中(或紙上)想清楚一遍——很多設計上的漏洞或不合理之處,在畫圖階段用眼睛看整體結構時,比邊寫程式碼邊摸索時更容易被發現,因為寫程式碼的時候,注意力很容易被單一節點的實作細節佔據,反而看不清整體流程的問題。

02 · 運作原理是什麼?

文章第一個坑提到「狀態物件要保留中間過程的依據」,但如果每個節點都記錄大量除錯用的欄位,會不會讓狀態物件變得過於龐大,反而影響效能或增加複雜度?

這是一個真實存在的取捨,但通常不需要在「完全不記錄」和「記錄所有東西」之間二選一,有幾個實務上的折衷做法可以參考。

分層記錄:核心欄位 vs 除錯欄位。把狀態物件的欄位分成兩類——「核心欄位」是流程實際運作邏輯需要用到的(例如 current_ratesshould_execute,這些欄位如果沒有,流程就跑不下去),「除錯欄位」是流程運作本身不直接依賴、但對事後追溯很有幫助的(例如 evaluation_reasoning)。多數 LangGraph 的狀態管理機制,對欄位數量本身的效能影響通常不大(狀態物件的大小,相對於一次 LLM 呼叫的成本,通常是微不足道的),所以「記錄稍微多一點的除錯欄位」帶來的效能負擔,實務上很少是真正的瓶頸,不需要過度擔心。

只在關鍵節點記錄,而非每個節點都記錄一樣多。不是所有節點都需要一樣詳細的除錯記錄——通常「做出關鍵決策的節點」(例如這個案例裡的 evaluate_opportunity)最值得詳細記錄依據,因為這是最需要被追溯的環節;單純的資料查詢節點或格式轉換節點,除錯欄位可以精簡很多,因為這類節點的邏輯通常很單純,出問題時比較容易直接看程式碼定位,不太需要額外的欄位輔助追溯。

除錯欄位可以設計成「事後可清理」而非永久保留。如果擔心除錯欄位長期累積讓狀態物件過於龐大,可以在任務正常完成、確認結果符合預期後,把這些除錯用的中間欄位清空或移除,只保留最終結論相關的核心欄位——除錯欄位的價值主要體現在「這次執行出問題,需要診斷」的情境,一旦確認這次執行沒問題,繼續保留這些欄位的邊際價值就降低了。

核心判斷原則:與其擔心「記錄太多會不會拖累效能」,更值得優先考慮的是「這個欄位,在我未來某次除錯時,能不能幫我更快定位問題」——多數情況下,適度多記錄一些除錯欄位帶來的除錯效率提升,遠大於這些欄位本身造成的效能負擔,除非你的 Agent 系統本身有極端嚴格的效能要求(例如毫秒級的延遲敏感場景),否則不需要因為擔心效能而過度精簡除錯資訊。

03 · 如何應用

文章第三個坑提到「循環要有全域上限」,如果我的 Agent 任務本質上就需要長時間持續運行(例如 24 小時不間斷監控市場),這種情況下該怎麼設定合理的上限,而不是乾脆不設上限?

對於本質上需要長時間持續運行的 Agent,上限的設計思路要從「限制總執行次數」轉換成「限制單一個查詢週期的資源消耗,並定期重置計數」,而不是完全不設上限。

核心思路轉換:從「總次數上限」變成「週期性重置的上限」。24 小時不間斷監控的 Agent,不適合用「總共只能查詢 50 次就強制停止」這種設計(因為這樣的話,Agent 運行沒多久就會被強制中止,無法達成「持續監控」的任務目標)。更合適的設計是,把 query_count 這個計數器,改成「這個小時內已經查詢了幾次」,每小時重置一次,同時設定「每小時最多查詢 N 次」的上限——這樣既能持續長時間運行,又能防止在異常情況下(例如某個判斷邏輯的 bug 導致查詢頻率意外飆升)無限制地消耗資源。

額外疊加成本速率的監控,而不只是次數。除了限制查詢次數,也可以疊加「這個小時內累積消耗了多少 API 呼叫成本」這個指標,如果成本速率明顯超出正常運作時的預期範圍(例如平常一小時消耗 $0.5,突然飆升到 $5),即使查詢次數還沒達到上限,也應該觸發告警,因為這通常代表某個環節出現了異常(例如查詢邏輯意外進入了比預期更密集的迴圈),值得提前介入,而不是等到次數上限被觸發才發現問題。

分離「持續運行」和「無限制運行」這兩個概念。「持續運行」代表 Agent 的生命週期本身很長(可能是數天、數週甚至更久),這是任務需求決定的,合理的設計;「無限制運行」代表 Agent 內部沒有任何機制去偵測和攔截異常的資源消耗模式,這是應該避免的設計缺陷。兩者不衝突——你可以設計一個生命週期很長、持續運行的 Agent,同時在它內部的每個運作週期(例如每小時、每天)都設定明確的資源消耗上限,一旦某個週期異常超標,觸發告警或暫停,等人工確認後再恢復,而不是讓整個 Agent 因為單次上限被觸發就完全停止運作。

具體實作建議:狀態物件裡除了原本的 query_count,可以額外加入 period_start_timestamp(記錄當前計數週期的起始時間)和 period_cost_accumulated(記錄當前週期累積的成本),條件邊的邏輯判斷「是否超過本週期上限」時,同時檢查次數和成本兩個維度,任一超標就觸發告警機制,而不只是單純的次數計數。

04 · 我該怎麼做?

如果我想把文章裡的這個 DeFi 收益優化 Agent,擴展成一個多 Agent 系統(例如把「查詢」和「執行」拆成兩個獨立的 Sub-agent),用 LangGraph 該怎麼調整架構?

這個延伸剛好對應前面 LangGraph 詞條 Q4 討論過的「巢狀圖」設計模式,具體調整方向如下。

把現有的單一圖,拆解成一個外層 Orchestrator 圖 + 兩個內層 Sub-agent 圖。原本 query_ratesevaluate_opportunity 這兩個節點,可以合併成一個獨立的「查詢與評估 Sub-agent」子圖;execute_rebalance 這個節點,可以獨立成一個「執行 Sub-agent」子圖。外層的 Orchestrator 圖,節點內容變成「呼叫查詢評估 Sub-agent」「呼叫執行 Sub-agent」「等待」這幾個更高層次的步驟,原本每個細節節點的實作邏輯,被封裝進對應的 Sub-agent 子圖裡。

狀態物件的設計要對應這個拆分做調整。原本單一圖共用一個扁平的狀態物件,拆分成多 Agent 架構後,可以考慮讓每個 Sub-agent 子圖有自己內部的、更詳細的狀態(例如查詢評估 Sub-agent 內部可能需要更多中間計算過程的欄位),外層 Orchestrator 圖的狀態物件,則只保留跨 Sub-agent 需要共享的關鍵資訊(例如前面 Handoff 詞條提到的「任務目標」「已知進度」「交接原因」這類摘要層級的資訊),而不是把所有細節都攤平在同一個扁平狀態裡。

權限範圍要跟著拆分收斂。這是延伸前面最小權限詞條和多 Agent 系統章節討論過的原則——查詢評估 Sub-agent 只需要唯讀存取市場數據的權限,不需要持有任何簽署交易的能力;執行 Sub-agent 才需要持有實際的交易簽署權限,且應該對呼叫它的 Orchestrator 傳來的建議,做前面 Handoff 詞條 Q4 提到的「執行前重新驗證」,而不是盲目信任查詢評估 Sub-agent 給出的結論。

這樣拆分後的實際好處:如果之後想要獨立優化「查詢與評估」這個環節的邏輯(例如加入更複雜的多協議比較策略),可以只修改對應的 Sub-agent 子圖,不需要動到執行環節的程式碼,兩者的變更互相獨立;同樣地,如果之後想要幫執行環節加上更嚴謹的風險控管(例如前面提到的滑點動態計算、執行前重新驗證),也只需要修改執行 Sub-agent,不會影響查詢評估的邏輯。這種模組化的架構,對應到文章裡提到的第二個坑(條件邏輯要拆解成具名函式以利維護)這個原則的更大尺度應用——不管是函式層級還是 Sub-agent 層級,把職責清楚拆分、獨立可測試,都是同一個工程紀律在不同尺度上的體現。

完整內容 +

知道 LangGraph 用「圖」的結構表達循環和條件分支是一回事,實際動手搭建一個會用到這些特性的 Agent,又是另一回事。這篇文章不重複介紹 LangGraph 的基礎概念(節點、邊、狀態這些定義),而是用一個具體的 DeFi 收益優化 Agent 為例,走一遍實際的設計和實作過程,並記錄過程中真正踩過的幾個坑——這些坑通常不會出現在官方入門教學裡,因為官方教學的範例通常刻意設計得簡單,不會觸發這些邊界情況。

從需求出發,先畫圖再寫程式碼

這個 Agent 的任務是:定期檢查多個借貸協議的利率,如果發現值得套利的機會(把資金從利率較低的協議移到利率較高的協議,扣除 Gas 成本後仍然划算),就執行移倉操作;如果沒有找到好機會,就等待一段時間後重新檢查。

在寫任何程式碼之前,先把這個流程畫成一張圖:`query_rates`(查詢所有協議的當前利率)→ `evaluate_opportunity`(計算是否有值得執行的套利空間,並產出一個信心分數)→ 條件邊分岔:信心分數夠高,走向 `execute_rebalance`;信心分數不夠高,走向 `wait`,等待後回到 `query_rates` 形成循環。畫完這張圖後,才開始寫對應的節點函式——這個順序很重要,先確定流程的結構,再填入每個節點的實作細節,比邊寫程式碼邊設計流程,更容易維持整體邏輯的一致性。

第一個坑:狀態物件的欄位設計得太粗糙,導致除錯困難

第一版實作裡,狀態物件只包含最基本的欄位:`current_rates`、`decision`、`should_execute`。這個設計在功能上是能動的,但實際測試時遇到問題——當某次執行結果不符預期(例如 Agent 判斷不該執行,但其實市場上明明有一個看起來不錯的套利機會),沒有辦法追溯「Agent 到底是根據什麼數據做出這個判斷」,因為狀態物件裡只保留了最終結論,沒有保留中間過程的依據。

修正方式是把狀態物件的欄位設計得更細緻,加入 `rate_snapshot_timestamp`(查詢利率的時間戳記)、`opportunity_confidence`(信心分數本身,而不只是布林值的最終決定)、`evaluation_reasoning`(簡短記錄評估時的關鍵依據)。這些欄位在正常運作時看起來是多餘的,但在除錯或事後分析「為什麼這次沒有執行」時,是唯一能重建決策過程的依據。這個坑的教訓是:狀態物件的欄位設計,不能只考慮「流程正常運作需要什麼」,還要考慮「出問題的時候,我需要知道什麼才能診斷」。

第二個坑:條件邊的判斷邏輯寫得太隱晦,難以維護

第一版的條件邊判斷邏輯,直接寫成一個複雜的巢狀 if-else,混雜了「信心分數夠不夠高」「距離上次執行的時間夠不夠久」「當前 Gas 價格是否過高」三個條件。這段邏輯能動,但幾週後回頭要調整某個判斷門檻時,很難一眼看出這三個條件之間的優先順序和交互關係。

修正方式是把這個複雜的條件判斷,拆解成幾個具名的輔助函式(例如 `is_confidence_sufficient()`、`is_cooldown_elapsed()`、`is_gas_price_acceptable()`),條件邊的主邏輯只負責呼叫這些函式並組合結果,不直接寫巢狀判斷式。這個修正不影響功能,純粹是為了可讀性和未來維護的便利性——這也呼應了前面框架選擇文章提到的「圖結構的價值是讓流程可以被視覺化理解」,如果條件邊內部的邏輯本身寫得像一團亂麻,圖結構帶來的可讀性優勢會被削弱大半。

第三個坑:沒有給循環設定明確的退出條件,測試階段差點跑出失控迴圈

這是三個坑裡最接近生產事故的一個。第一版的 `wait` 節點,設計邏輯是「等待一段固定時間後,回到 `query_rates` 重新檢查」,沒有限制這個循環總共能跑幾輪。在一次連續好幾天市場都沒有出現足夠好的套利機會的測試情境下,這個 Agent 持續不斷地查詢、評估、等待、再查詢,累積消耗了遠超預期的 API 呼叫成本,而且因為沒有上限,理論上這個循環可以無限期地跑下去。

修正方式是在狀態物件裡加入 `query_count` 欄位,每次進入 `query_rates` 節點就遞增,並在條件邊裡加入一條規則:如果 `query_count` 超過某個上限(例如單次任務最多查詢 50 輪),無論信心分數如何,都強制結束這個任務,標記為「暫時沒有找到好機會,需要人工決定是否要重新啟動」,而不是讓它無限期地跑下去。這個坑直接對應前面重試策略文章討論過的「循環性失敗需要有全域上限」這個原則,只是這裡的「循環」不是因為失敗而觸發的重試循環,而是設計本身就有循環結構的正常流程——但兩者面對的風險是一樣的:沒有上限的循環,最終都可能變成失控的成本黑洞。

這跟你的實戰有什麼關係

如果你正在用 LangGraph 搭建有循環結構的 Agent,這三個坑值得在設計階段就提前考慮,而不是等測試或上線後才發現:狀態物件的欄位,除了滿足正常流程需要,也要能支撐事後除錯;條件邊的判斷邏輯,拆解成具名函式而不是寫成一團巢狀判斷式;任何循環結構,都必須有一個明確的、獨立於業務邏輯本身之外的硬性上限,避免在你沒注意到的情況下無限期運行。這三點都不是 LangGraph 特有的問題,本質上是任何有循環結構的系統都該注意的工程紀律,只是 LangGraph 讓循環邏輯更容易寫出來,相對地也更容易在沒有紀律的情況下寫出失控的循環。

圖解
Layered Architecture: From Single Graph to Orchestrator + Subgraphs分層架構圖:上層呈現原始的單一 LangGraph 圖(query → evaluate → conditional branch → execute/wait),下層呈現擴展後的分層架構(Orchestrator 圖呼叫兩個獨立的 Sub-agent 子圖),用箭頭連接兩層,展示從單一圖到巢狀多 Agent 架構的演From Single Graph to Layered ArchitectureStage 1: Single Graph (this article)query_ratesevaluate_opportunityexecute_rebalancewait → loop back↓ extends to ↓Stage 2: Orchestrator + Nested SubgraphsOrchestrator Graphcalls Sub-agents, holds no execution permissionQuery+Evaluate SubgraphRead-only market accessOwn detailed internal stateExecution SubgraphHolds signing keyRe-verifies before executingAI Agent Bible · aiagent-bible.com
歡迎截圖分享,轉載請註明來源
提問
請至少輸入 10 個字
相關文章
怎麼建你的第一個 Onchain Agent:從零開始的最小可行架構,以及部署前必確認的 Checklist
beginners · 06/29
DeFi Agent 框架深度比較:LangGraph 為何成為首選,以及其他框架在 DeFi 場景的真實表現
frameworks · 07/02
2026 年五個主流 Onchain Agent 框架比較:LangGraph、ElizaOS、AutoGen、Olas、ZerePy,各自適合誰
frameworks · 06/27
AutoGen vs LangChain vs ElizaOS:三大框架選哪個,加密 AI Agent 開發者的完整決策指南
frameworks · 06/20