2026 年 AI Agent 堆疊:LangGraph vs 自訂 vs DIY
我大多數週期都會把 agent 部署到正式環境,而在每次啟動會議中,框架的選擇總是重複出現。誠實的答案是,「正確」的堆疊取決於你能容忍多少分支、多少狀態,以及多少爆炸半徑。我在去年用三種方式建置了相同的 agent,而這些取捨比框架行銷所呈現的更加明顯。以下是我實際的決策方式。
我經常使用的三種堆疊
當我開始一個新的 agent 時,我會從三個類別中選擇。其他一切都是這些的變體:
-
DIY loop,意指一個普通的
whileloop,圍繞 LLM 呼叫、工具執行和訊息陣列。大約 150 行 Python 或 TypeScript。 - 框架,現在幾乎總是 LangGraph,偶爾是 Pydantic AI 或 OpenAI Agents SDK 用於特定案例。
- 自訂編排,意指我自己撰寫狀態機,通常建置在訊息佇列或耐久執行器(如 Temporal、Inngest 或 AWS Step Functions)之上。
決策取決於三個問題:有多少步驟、多少並行性,以及當它在凌晨 3 點當機時會發生什麼。其他一切(可觀測性、評估、人機回圈)都可以附加到這三者中的任何一個。
什麼時候 DIY loop 是正確答案
對於任何少於約五個工具且具有線性 think-act-observe loop 的 agent,普通 loop 會勝出。我用這個方式處理我部署的約 40% 的 agent,包括 BizFlowAI ContentStudio 中的大多數子 agent。框架增加了抽象成本,只有在你有真正的分支時才會有回報。
以下是整個內容的樣子,扣除日誌記錄:
def run_agent(task: str, tools: dict, max_steps: int = 12):
messages = [
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": task},
]
for step in range(max_steps):
resp = client.messages.create(
model="claude-sonnet-4-5",
messages=messages,
tools=list(tools.values()),
max_tokens=4096,
)
messages.append({"role": "assistant", "content": resp.content})
if resp.stop_reason == "end_turn":
return resp.content[-1].text
tool_results = []
for block in resp.content:
if block.type == "tool_use":
try:
result = tools[block.name]<a href="**block.input">"fn"</a>
tool_results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": str(result),
})
except Exception as e:
tool_results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": f"ERROR: {e}",
"is_error": True,
})
messages.append({"role": "user", "content": tool_results})
raise RuntimeError("Agent exceeded max_steps")
進入全螢幕模式 退出全螢幕模式
就是這樣。優點是真實的:
- 你在 IDE 中進行除錯。 堆疊追蹤指向你的程式碼,而不是三層框架內部。
- Token 使用是透明的。 你可以看到並控制每一條發送的訊息。當我上季在一個專案中削減 40% 的 LLM 支出時,大部分都是在此 loop 中修剪訊息陣列。
-
你擁有重試和錯誤表面。 工具錯誤會以
is_error: true的形式返回給模型,使其能夠恢復,而如果模型在損壞的工具上迴圈,你會因為自己撰寫了計數器而捕捉到它。
DIY 失效的地方:跨長時間執行的任務進行平行工具執行、多 agent 交接,或任何需要檢查點以在程序重新啟動後倖存的東西。此時你要么正在建置框架,要么正在尋求一個。
什麼時候 LangGraph 值得其複雜性
LangGraph 是我在 2026 年經常使用的框架,主要是因為它將 agent 視為具有型別狀態的節點圖,而這種模型實際上符合複雜 agent 的行為方式。當工作流程有真正的分支(三個或更多有意義的路徑)、需要跨數小時或數天的耐久執行,或有多個 agent 相互通訊時,我會使用它。
價值體現在三個特定功能中:
-
型別狀態作為一等物件。 你為狀態定義
TypedDict或 Pydantic 模型,每個節點返回部分更新。這比聽起來更有價值,因為它強迫你思考狀態轉換,而不是傳遞訊息陣列。 -
檢查點。 使用
SqliteSaver或PostgresSaver,如果程序當機,圖形會從最後一個節點恢復。對於長時間執行的研究 agent 或人機回圈工作流程,這是不可或缺的。 - 用於人工審核的中斷。 你可以在節點處暫停圖形,等待外部輸入(Slack 核准、表單提交),然後恢復而不必重新執行之前的節點。
我被燒傷的地方:LangGraph 對 LLM 呼叫的抽象隱藏了 token 記帳,除非你明確地連接回呼。文件更新很快,有些六個月前有效的模式現在已被不鼓勵。如果你使用它,請固定你的版本並撰寫整合測試,以快照實際發送的 API 呼叫。
根據我部署的內容,大致的經驗法則:
| Agent 類型 | 節點 | 最佳選擇 |
|---|---|---|
| 單一用途工具呼叫器 | 1-3 | DIY loop |
| 研究 + 撰寫 + 審核 | 4-8 | LangGraph |
| 具有交接的多 agent | 8+ | LangGraph 或自訂 |
| 長時間執行的工作流程(數小時以上) | 任何 | 自訂編排 |
| 扇出到 50+ 平行任務 | 任何 | 自訂編排 |
什麼時候自訂編排值得撰寫
自訂編排意味著將 agent 視為分散式系統:耐久執行器(Temporal、Inngest、Step Functions,或在 SQS 上自行建置的東西)驅動工作流程,而每個 LLM 呼叫或工具執行都是該系統中的任務。當我需要倖存機器故障、單一「agent 回合」可能需要一小時,或必須扇出到數百個平行分支時,我會使用此方式。
我為 SLA 合規性建置的無伺服器 AWS + Zendesk 整合是自訂編排。不是因為它確實是「agent」,而是因為相同的推理適用:EventBridge 驅動工作流程,Lambda 函數是任務,DynamoDB 持有狀態。如果 Lambda 當機,EventBridge 會重試。如果工具失敗,狀態機知道從哪裡恢復。一旦你接受 LLM 呼叫只是另一個冪等任務,這種模式就能乾淨地對應到 agentic 工作流程。
自訂編排為你帶來的、框架無法提供的:
- 真正的耐久性。 LangGraph 的檢查點器適合數小時。Temporal 或 Step Functions 適合數月。
- 大規模扇出。 當我需要一個 agent 平行審核 500 份文件並彙總結果時,我需要一個真正的佇列和工作池,而不是試圖管理並行性的圖形庫。
- 爆炸半徑控制。 每個任務都在隔離中執行。有毒的工具回應無法損壞整個執行,因為狀態是在步驟之間具體化的。
成本是真實的。你撰寫更多程式碼,你擁有基礎設施,你必須建置自己的 agent 行為視覺化。對於任何執行時間少於一小時且少於 10 個平行分支的任何內容,這都是過度的。超過此範圍,框架開始感覺像玩具。
我實際選擇的堆疊,一個決策一個決策
以下是我在新的 agent 專案開始時腦海中的流程圖:
- 工作流程是否線性且少於五個工具? DIY loop。在一週內部署。加入結構化日誌記錄、token 計數和重試包裝器。
-
它是否有真正的分支,或需要暫停以等待人工輸入? LangGraph,使用
PostgresSaver進行檢查點,並使用 OpenTelemetry 回呼進行可觀測性。 - 單一執行是否持續數小時,或扇出到數百個平行分支,或需要倖存基礎設施故障? 在 Temporal 或 Step Functions 上的自訂編排。將每個 LLM 呼叫視為活動。
- 多 agent 且有三個或更多不同的 agent 相互通訊? 如果執行時間短則使用 LangGraph,如果執行時間長則使用自訂。絕不使用 DIY,因為 agent 之間的訊息路由是 DIY loop 變成難以維護的義大利麵程式碼的地方。
我比框架行銷所建議的更常傾向 DIY。野外的多數 agent 並不需要圖形。它們需要一個好的 loop、仔細的提示工程、緊密的工具結構描述,以及誠實的評估。當工作流程圖形不再適合單一畫面時,框架就會變得有用。
沒有人會告訴你、直到你部署的事物
一些讓我付出真實時間的經驗教訓:
工具結構描述比模型選擇更重要。 我曾見過相同的任務僅透過重寫工具描述和參數名稱,就從 60% 成功率提升到 95%。在你切換模型或新增框架之前,花一天時間在你的工具結構描述上。模型只能像你的工具允許的那樣聰明。
訊息陣列修剪是 token 節省的關鍵。 在 20 步驟的 agent 中,如果保留所有工具結果,訊息陣列在 token 方面呈平方增長。我保留最後 3-5 個工具結果原文,並摘要其餘部分。在一個內容 agent 上,這將成本削減了 40%,且沒有可衡量的品質損失。
錯誤字串是提示。 當工具失敗時,錯誤訊息會返回到模型的上下文中,並成為下一個提示的一部分。"Database connection failed" 是一個無用的提示。"Database query returned no rows for user_id=42. Try a different user_id or check if the user exists." 讓模型能夠恢復。
沒有冪等性的檢查點是謊言。 如果你的圖形從步驟 7 恢復,而步驟 7 呼叫了支付 API,你就向客戶收取了兩次費用。每個變更狀態的工具都需要冪等性金鑰。這對任何框架都是如此。
評估不是可選的。 我在每次部署之前,針對固定的一組 20-50 個測試案例執行我建置的每個 agent。不是花俏的 LLM-as-judge 東西,只是確定性檢查:它是否呼叫了正確的工具、最終答案是否包含了所需的欄位、它是否保持在 token 預算之內。這是 agent 工作中單一最高的投資報酬率工程實務。
如果我明天要開始一個新的 agent,我會做什麼
從 DIY loop 開始。首先確定工具、系統提示和評估集。從第一天起就對 token 使用和步驟計數進行儀表化。部署它,觀察它在真實輸入上失敗,然後修復它。
只有在工作流程圖形有真正的分支,或你需要耐久的暫停和恢復時,才使用 LangGraph。只有在單一執行超過一小時,或扇出超出單一程序應管理的範圍時,才使用自訂編排。不要跳過 DIY 階段:它會教導你你的 agent 實際在做什麼,而這些知識是讓框架選擇在後續變得明顯的關鍵。
框架辯論大多是噪音。部署且保持部署的 agent 是那些具有緊密工具結構描述、誠實評估,以及讓你能在 10 分鐘內除錯正式環境故障的可觀測性的 agent。其他一切都是支架。
如果你現在正在建置一個 agent 且在這些堆疊之間猶豫,我很樂意查看工作流程圖形並告訴你我會選擇什麼。請聯絡 lazar-milicevic.com/#contact,或閱讀更多關於 blog 的內容,我已在其中撰寫關於 agent 評估、上下文工程以及削減正式環境中的 token 支出。
0 Comments
Log in to join the conversation.No comments yet. Be the first to share your thoughts.