
如果過去兩年里你一直用 LangChain 寫檢索問答大概率會撞上同一堵墻單輪問答很聽話多輪對話偶爾也還行但當你嘗試做一個真正能“自己決定下一步做什么”的 Agent 時流程就開始失控。工具調用中途失敗上下文越滾越長日志翻起來一頭霧水更不用說要讓流程支持重試、回退和人工審批。到 2026 年再看 Agent 開發我的核心判斷已經變成一句話真正卡住大多數人的不是“調大模型”而是“編排流程”。LangChain 解決的是模型接入層LangGraph 解決的是控制層MCP 解決的是工具層。這三者拼在一起才構成了從“能跑 demo”到“能上生產”的完整拼圖。這篇文章會按一條完整的技術路線展開先拆清楚四個概念各自的邊界再講如何用 LangGraph 設計帶狀態和循環的 Agent 工作流然后把 MCP 工具服務接入流程最后給出企業項目落地時的工程化注意事項、排查思路和學習路線。如果你正在從 RAG 應用往 Agent 方向走這篇文章應該能幫你節省不少試錯時間。1. 先想清楚Agent 開發真正難在哪里1.1 單次調用與多步流程的本質區別如果只是“大模型 檢索 生成答案”本質上仍然是一次請求一次響應。你需要處理的問題就三樣提示詞寫得對不對、檢索結果準不準、生成格式穩不穩定。這些問題當然也有難度但它們都停留在“單步計算”的范疇里。Agent 完全不同。你給它的不是一個明確指令而是一個目標。它需要自己拆解步驟判斷什么時候調用工具什么時候該停下來什么時候該換一種方法。比如一個企業客服智能體收到“幫我查一下訂單如果超時就申請退款”這句話之后它內部可能經歷這樣一串動作分析用戶意圖判斷要調用訂單查詢接口。調用工具拿到訂單狀態。檢查訂單是否已超時。如果超時繼續調用退款申請接口。如果退款需要審批進入等待狀態。整理結果回復用戶。這還只是一個比較規整的例子。真實業務里還有訂單數據缺失、接口超時、退款金額超限、用戶需求在中途改變等分支。這些分支加起來會形成一個非常復雜的流程網絡。單步調用只要考慮“這次輸入能不能得到合理輸出”多步 Agent 要考慮的是“整條流程能不能在所有分支下都保持穩定”。這完全是兩個量級的問題。1.2 2026 年智能體開發的核心矛盾現在大模型的推理能力已經不缺了。OpenAI、Claude、DeepSeek、Qwen 這些模型在工具調用和邏輯推理上都有明顯進步。那是什么在拖后腿答案是工程基礎設施。Agent 跑在真實業務里需要狀態管理需要日志需要錯誤恢復需要工具接入標準需要權限控制需要評測方法。這些工程能力不會因為模型變強就自動出現。2026 年的 Agent 開發真正的戰場已經從“模型選哪個”轉移到了“流程怎么編排、工具怎么接入、狀態怎么持久化”。這也是為什么 LangGraph 和 MCP 會在最近兩年被頻繁討論。LangChain 其實更像一個成熟的組件庫LangGraph 才是重新定義編排層的那股新力量而 MCP 則是試圖統一工具接入方式的開放協議。理解這三者的關系比再會十個提示詞技巧都重要。2. 模型、控制、工具四位主角的定位與邊界2.1 LangChain從鏈式封裝到組件庫LangChain 是大家最熟悉的框架。它提供了一套統一的接口來對接各種大模型、向量庫、文檔加載器和工具。在 2025 年之前很多人用它來搭 RAG 流程把“文檔加載 → 分割 → 向量化 → 檢索 → 生成”封裝成鏈。到了 2026 年如果你不打算把所有模塊都換成自研代碼LangChain 依然有價值。它的價值主要體現在三塊模型接入抽象讓你切換不同廠商模型時不用重寫業務邏輯。提示詞和文檔處理工具文本分割、模板管理、輸出解析器都有現成實現。生態兼容大量第三方庫和開源項目都基于它來集成。但也要接受一個現實LangChain 的抽象層級比較高如果項目復雜到一定程度調試成本會上升。你很難直觀看到每一步到底傳了什么數據。所以現在更常見的做法是把它當作“組件工具箱”而不是讓所有邏輯都躺在 LangChain 的 Chain 里。2.2 LangGraph把流程畫成一張可執行的圖LangGraph 解決的是 LangChain 解決不了的問題循環、分支和狀態持久化。普通鏈式結構是單向的A 執行完走 BB 走完走 C。但 Agent 的行為天然是循環的調用工具 → 觀察結果 → 再決定 → 再調用。如果想用普通鏈來寫你得自己手動寫 while 循環然后想辦法把每一步的結果存到某個全局變量或者文件里再處理異常和重試。非常痛苦。LangGraph 的核心模型是圖。你把每一步操作定義成一個節點節點之間的連接關系由邊來描述。其中既包括普通邊也包括條件邊。條件邊可以根據當前狀態決定下一步走哪個節點。整個圖內部維護一個 State 對象節點之間通過 State 來讀取和更新信息。這個模型和 Agent 的行為模式天然匹配。你不再需要手寫一層層循環嵌套只需要定義好圖結構讓大模型在節點之間做決策。2.3 MCP給所有工具裝上一個統一接口MCPModel Context Protocol模型上下文協議試圖解決工具接入標準化的問題。在沒有 MCP 之前你想讓 Agent 調用公司內部系統可能需要自己寫 HTTP 接口、Shell 腳本、Python 函數再按 LangChain 的 Tool 規范包一層。每個團隊接入方式都不一樣切模型或者換框架時工具層全部要重寫。MCP 的思路類似數據庫里的 JDBC或者前端世界里的瀏覽器標準。它定義了一套統一的客戶端-服務器架構MCP Host運行 Agent 的主程序比如你的 LangGraph 應用。MCP ClientHost 內部的連接組件負責和 Server 通信。MCP Server把具體工具能力暴露為標準化接口的服務比如訂單查詢服務、文檔檢索服務、表格處理服務。一個 MCP Server 可以暴露多個工具。Host 通過協議發現這些工具把工具的描述傳給大模型大模型決定調用哪個工具時Host 再通過協議把參數傳給 Server 執行。這個模式的好處是工具開發一次可以被任何支持 MCP 的 Agent 框架復用。團隊內部不需要再為每個 Agent 項目單獨定制一套工具接入代碼。2.4 三者的分工用一張表說清楚組件核心角色典型案例如果缺了它會怎樣LangChain模型接入與數據處理工具箱封裝 LLM API、文檔加載、輸出解析每次換模型都要重寫接入代碼LangGraph流程編排與狀態管理Agent 的多步決策、循環、條件分支、斷點恢復Agent 邏輯變成難以維護的嵌套 whileMCP工具接入標準化協議統一暴露訂單查詢、文檔檢索、代碼執行等工具每個項目都要重復寫工具封裝層你完全可以把它們組合成一套體系LangChain 負責跟模型對話LangGraph 負責決定對話的節奏和流程MCP 負責讓流程中的每一步都能方便地調用外部工具。3. 用 LangGraph 搭一個最小可控 Agent 工作流3.1 從狀態開始而不是從鏈開始很多人學 LangGraph 時犯的錯誤是直接去看節點怎么定義邊怎么連卻忽略了圖的核心State。LangGraph 的每一個節點本質上都是“接收 State → 處理 → 返回 State 更新”的函數。State 是一個可序列化的數據結構它保存著整個流程當前的所有信息包括用戶輸入、歷史消息、工具返回結果、當前步驟數、最終答案等等。設計 LangGraph 流程時最先做的不是畫圖而是定義 State。一個常見的訂單客服 Agent 的 State 可以長這樣from typing_extensions import TypedDict, Annotated def merge_dicts(left: dict, right: dict) - dict: # 常見 LangGraph 寫法不同節點產生的結果需要合并 return {**left, **right} class AgentState(TypedDict): messages: list # 本輪對話消息記錄 order_id: str # 當前處理的訂單號 tool_result: str # 最近一次工具調用的結果 tool_status: str # 工具調用是否成功 finish: bool # 是否結束流程 final_answer: str # 最終回復內容State 里放什么字段直接決定了流程能處理哪些業務。如果你想支持多輪工具調用就得有一個字段記錄“下一步該干什么”如果你想支持中途人工審批就得有一個字段保存“待審批的操作內容”。先定好 State再定節點順序不能反。3.2 節點與邊的常見設計模式還是以訂單客服 Agent 為例。一個最小可用的流程需要四個節點from langgraph.graph import StateGraph, START, END # 1. 分析用戶輸入決定下一步動作 def analyze_intent(state: AgentState) - dict: # 調用大模型識別用戶意圖返回需要調用的工具 return {next_action: query_order} # 2. 調用訂單查詢工具 def query_order(state: AgentState) - dict: # 這里可以走 MCP Server也可以直接調用內部函數 result call_order_api(state[order_id]) return {tool_result: result, tool_status: ok} # 3. 判斷是否要申請退款 def check_refund_condition(state: AgentState) - dict: if 超時 in state[tool_result]: return {next_action: apply_refund} return {finish: True, final_answer: 訂單未超時無需退款} # 4. 調用退款接口 def apply_refund(state: AgentState) - dict: result call_refund_api(state[order_id]) return {tool_result: result, tool_status: ok} # 構建圖 builder StateGraph(AgentState) builder.add_node(analyze, analyze_intent) builder.add_node(query, query_order) builder.add_node(check, check_refund_condition) builder.add_node(refund, apply_refund) builder.add_edge(START, analyze) builder.add_edge(analyze, query) builder.add_edge(query, check) builder.add_conditional_edges( check, lambda state: refund if state.get(next_action) apply_refund else END, {refund: refund, END: END} ) builder.add_edge(refund, END) graph builder.compile()這段代碼是典型的最小 Agent 工作流。analyze 節點負責“思考”query 節點負責“執行”check 節點負責“判斷”refund 節點負責“收尾”。條件邊則讓流程根據業務結果選擇是否進入退款分支而不是機械地一條道走到黑。實際業務里你通常還會再加一個“兜底節點”用于處理工具調用失敗或識別失敗的情況。比如 query_order 接口超時就應該走一個重試節點而不是直接把異常拋給用戶。3.3 把 MCP 工具接進工作流LangGraph 本身并不直接綁定 MCP。你在節點里調用工具時可以走普通函數調用也可以通過 MCP 客戶端訪問遠端工具。從工程上看后者的好處是解耦。假設你的團隊已經在內部部署了一個訂單查詢 MCP Server暴露了一個query_order工具。你在 LangGraph 節點里的寫法類似這樣import json from mcp import ClientSession # 以常見 MCP SDK 寫法為例 async def query_order_via_mcp(state: AgentState) - dict: async with ClientSession() as session: tools await session.list_tools() order_tool next(t for t in tools if t.name query_order) result await session.call_tool(query_order, {order_id: state[order_id]}) # 解析 result轉成文本存入 State text json.loads(result.content[0].text) return {tool_result: text, tool_status: ok}這里的關鍵不是代碼細節而是架構思路LangGraph 負責流程控制MCP 負責實際能力執行。節點里不需要關心訂單查詢接口的地址、鑒權、參數格式這些都由 MCP Server 處理。當查詢邏輯變化時你只需要改 Server不需要動 Agent 流程。注意2026 年的 MCP SDK 版本差異較大不同語言的客戶端 API 也在快速演進。上面代碼是結構示例落地前一定要以你當前使用的 SDK 版本為準先跑通一條最小調用鏈路再封裝進節點。4. 企業級落地六個必須提前想清楚的工程開關4.1 狀態持久化與斷點續跑Agent 流程不是瞬時完成的。涉及人工審批、異步等待工具返回、長時間執行的流程可能需要幾分鐘甚至幾小時才能結束。如果進程中途重啟狀態丟了整個任務就得重來。LangGraph 提供了 Checkpointer 機制可以把每一步的執行狀態保存到外部存儲。常見實現包括內存、文件系統、Redis 或數據庫。生產環境建議至少把狀態持久化到 Redis 或 PostgreSQL而不是默認內存。因為狀態里可能包含歷史消息和工具返回結果數據可能比較大。持久化時要同時做兩步寫入當前完整快照定期清理過期狀態。不然 Redis 會越積越多最終拖慢一次加載速度。4.2 人工介入與審批流企業業務里很多操作不能完全交給模型自主決定。退款超過一定金額、刪除數據、修改核心配置這些動作必須經過人工審批。LangGraph 的節點設計里可以專門加一個human_approval節點。流程執行到這一步時先把待審批內容寫入一個外部任務表然后暫停整條圖等待審批結果。審批通過后再從暫停節點繼續執行審批拒絕則跳到另一個收尾節點。這個模式看起來是加一個節點實際影響的是整個流程設計。所有“高權限操作”都不能直接由模型調用而是要拆成“生成操作 → 暫存操作 → 審批 → 執行”四步。提前把它設計進圖結構比上線后發現問題再補要高效得多。4.3 并發、限流與資源控制Agent 和多輪對話不同它一次運行可能會調用多次模型 API也可能會調用多個外部系統。并發一大問題就來了模型 API 的 QPS 限制、外部服務的連接池上限、數據庫寫入壓力。生產環境建議按三個維度做限制單 Agent 任務的最大迭代次數防止模型陷入死循環常見值是 10 到 20 次超了就強制終止。并發任務數同時運行的 Agent 實例上限防止擠垮下游服務。單次工具調用超時比如外部接口 15 秒沒返回就標記失敗走重試或降級。這里要理解一個關系工具調用超時和 Agent 整體超時不是一回事。工具超時影響的是當前這一步Agent 超時影響的是整個任務生命周期。設計時要分層設置。4.4 日志、鏈路追蹤與評測體系Agent 調試難難在它是一個多步過程。你很難只靠一句“最后答案不對”判斷問題出在哪一步。模型理解錯了工具執行錯了還是狀態合并錯了這些都需要可觀測性支撐。建議從一開始就給每次 Agent 運行分配一個全局唯一的 request_id。這個 ID 貫穿所有節點、所有工具調用、所有日志。每一步執行完把這一步的輸入、輸出、耗時、Token 消耗、錯誤信息全部落到日志或追蹤平臺。評測是另一個常被忽略的坑。Agent 的行為有隨機性同一個輸入在不同模型版本下可能走向不同分支。上線前不要只拿 10 個用例測一遍建議至少準備 50 到 100 個覆蓋典型分支的測試用例并且每個用例跑 3 到 5 次統計通過率和失敗模式分布。4.5 記憶管理與上下文壓縮Agent 在多輪交互中會不斷積累上下文。如果每一輪都把工具調用結果、中間判斷、歷史對話全部塞給模型Token 消耗會快速增長小模型甚至會因為上下文過長而開始“忘記”前面的指令。2026 年的實踐中長期記憶和短期記憶被明確分開短期記憶當前任務上下文存內存或緩存里任務結束后清空。長期記憶用戶偏好、歷史訂單模式、常用操作路徑存數據庫或向量庫跨任務復用。LangGraph 的 State 天然適合管理短期記憶。每個節點只取自己需要的那一段字段而不是把整個 State 都傳給模型做 processing。需要做上下文壓縮時可以加一個summarizer節點定期把過長的歷史對話總結成摘要替換掉完整內容。4.6 安全邊界與工具權限Agent 操作的是真實系統模型只是決策者不是執行者。權限控制必須落在工具層而不是模型層。也就是說不是靠提示詞告訴模型“不要刪數據”而是在工具函數里直接判斷當前調用是否有權限。MCP Server 設計階段就要考慮哪些工具是只讀的哪些是寫操作哪些是高風險操作。只讀工具可以默認開放給 Agent 自主調用寫操作必須走審批高風險操作直接禁止模型發起只能通過明確觸發條件執行。經驗建議MCP Server 不要只做“能力的薄封裝”要做“帶權限判斷的能力封裝”。每個工具函數里至少檢查三件事調用方身份、參數合法性、環境標識生產環境還是測試環境。5. 單次跑通不等于穩定生產常見故障排查順序很多團隊在演示環境跑通一次 Agent 就開始全面鋪開結果一上生產就連續踩坑。從經驗看Agent 故障排查應該嚴格按以下鏈路來不要跳步驟。5.1 先看現象判斷故障層面先明確屬于哪類故障現象可能原因層面Agent 一直循環不結束流程編排、max_iterations 設置返回結果混亂或答非所問模型提示詞、上下文管理工具調用報錯或超時工具服務、網絡、權限狀態丟失或流程中斷持久化配置、進程恢復速度慢、Token 消耗異常上下文過長、并發限制先定層面再深入排查不要上來就懷疑模型。5.2 再查輸入、狀態、環境、參數、日志確定故障層面后按五個順序排查輸入確認本次請求的輸入數據是否完整。order_id 是否真的傳進去了有沒有 None 值工具返回的 JSON 是否被正確解析狀態檢查 State 在每一步之間是否正確更新。最常見的問題是更新字段時用了覆蓋而不是合并導致前面節點寫的數據被后面節點沖掉。環境檢查依賴版本、MCP Server 是否在線、網絡策略是否放行。生產環境經常會漏配某個內部服務的訪問白名單。參數檢查超時時間、最大迭代次數、并發數、溫度參數是否被正確傳入。特別是 LangGraph 圖編譯時的配置每個 Agent 實例可能使用不同配置。日志最后再看日志。看 request_id 是否貫穿全鏈路每步的輸入輸出是否都落了日志。如果日志缺失說明可觀測性還沒有做到位先補日志再排查。5.3 高頻問題上下文越滾越大與工具返回格式不一致上下文膨脹是 Agent 項目里最高頻的翻車點。癥狀很典型前三輪正常第五輪開始模型經常“忘”了自己的角色設定偶爾把工具調用參數寫錯。解決方案是上下文壓縮不是盲目把模型換成更大參數版本。工具返回格式不一致是另一個高頻問題。MCP Server 返回的 JSON 結構或者 Markdown 文檔的解析結果有時候和模型預期格式不一致。模型解析不了就會編造內容。解決思路是在節點里增加一個“結果校驗”步驟返回格式不合法就自動觸發一次重新解析而不是直接交給模型。6. 邊界認知什么時候不該用這套組合討論 LangChain、LangGraph、MCP 組合的價值時也要說清楚它不適用的情況。不是所有項目都值得引入這套體系。6.1 簡單單輪問答不需要過度設計如果你的場景只是“用戶問一句模型答一句”不涉及多步工具調用沒有狀態流轉那用普通 LangChain 鏈或者直接調 API 就夠了。引入 LangGraph 反而增加了代碼復雜度。每增加一個抽象層都要付出維護成本。判斷標準很簡單流程有沒有循環需不需要跨步驟保留狀態需要就上 LangGraph不需要就別上。6.2 確定性要求高于智能性的場景要謹慎有些業務場景里系統行為必須完全可預測。比如沒有人工監督的定時任務、涉及資金轉賬的流程、法律風險高的自動決策。這類場景里Agent 的自主性和臨時決策能力反而是風險。你需要的是規則引擎加人工審核流程而不是一個每一步都靠模型判斷的 Agent。如果團隊堅持要用一定要把“模型自主決策范圍”收得非常窄所有高影響操作都走人工審批。6.3 團隊技術棧與維護能力要匹配LangGraph 生態以 Python 為主MCP 的 Java、Go、TypeScript SDK 雖然也在快速發展但生態成熟度略低。如果團隊完全沒有 Python 基礎設施也沒有運維能力那引入這套組合會有一段很痛苦的爬坡期。不要低估學習成本。LangGraph 的圖模型、State 管理、Checkpointer 機制以及 MCP 的 Client-Server 架構都需要時間消化。如果項目交付周期很短建議先用最熟悉的技術棧做一個簡化方案把流程跑通后再逐步引入更復雜的架構。7. 一條可復制的學習路徑四周從入門到最小生產如果你已經決定往這個方向走可以參考下面的節奏避免東一榔頭西一棒子。第一周用 LangChain 打通模型接入和提示詞管理不要一上來就學 LangGraph。先確保你能用 LangChain 完成一次標準的大模型對話調用理解 Message 結構、模型封裝、輸出解析器的基本用法。目標不是熟練所有模塊而是建立“模型調用也是一個可以編程的資源”這種意識。第二周用 LangGraph 復現一個帶循環的流程圖選一個非常簡單的業務場景比如“查天氣 → 判斷是否下雨 → 推薦出行方案”用 LangGraph 從零搭一遍。不需要接真實工具先讓節點返回硬編碼數據即可。重點理解 State 如何流轉、條件邊如何工作、圖怎么編譯運行。這一周如果卡住大概率是狀態更新邏輯沒想清楚。復盤一下你的 State 字段設計看看每個節點到底該讀什么、寫什么。第三周接一個 MCP Server選一個現成的 MCP Server 接入 LangGraph。可以從官方 Examples 或社區常見實現入手跑通“Agent 主動發現工具 → 決定調用 → 收到結果 → 繼續流程”全鏈路。同時對比一下不通過 MCP、直接用本地函數調用工具的區別感受一下標準化的價值。第四周做最小生產化改造把前三周搭的 Demo 加上三類生產能力狀態持久化、請求日志、異常重試。可以用 Redis 存 State用 JSON Lines 落日志在工具節點外層包一層超時和重試邏輯。做完這一套你就能理解“演示級 Agent”和“生產級 Agent”之間真正差的是什么了。8. 最后留一句話Agent 開發的上半場大家比的是誰能把模型調得更聰明下半場比的是誰能把流程編排得更穩、工具接入得更標準、狀態管理得更可靠。LangChain、LangGraph、MCP 只是這個階段最重要的三塊積木它們本身不是終點但理解了它們你就有能力在下一輪工具迭代時做出更合理的判斷。不用追求一次性把全套技術棧學完。先跑通一個最小流程把狀態和日志看明白再一步一步往上加復雜度。這條路比想象中漫長但也比想象中清晰。