行流程:從AgentExecutor到LangGraph)
很多人在學(xué) LangChain 的時候都會遇到一個極其相似的分水嶺調(diào)大模型 API 已經(jīng)很熟練了但一寫 Agent 就卡住。卡住的原因通常不是 Prompt 寫不好也不是模型能力不夠而是根本不清楚 Agent 被調(diào)用之后內(nèi)部到底是怎么跑完一趟的。工具定義的順序有沒有影響Agent 為什么有時候不調(diào)用工具、有時候反復(fù)調(diào)用同一個工具為什么加了 Memory 之后還是“失憶”這些問題如果不理解執(zhí)行流程就只能靠試錯去猜。這篇文章要做的就是把 LangChain Agent 的執(zhí)行流程完整拆開從入口開始一步步看到它如何決定調(diào)用工具、如何把工具結(jié)果送回模型、如何在一個循環(huán)里最終收斂??赐曛竽悴粌H能讀懂 AgentExecutor 的機(jī)制也能明白為什么現(xiàn)在的 LangGraph 會逐漸成為更推薦的編排方式。如果你是剛接觸 Agent 開發(fā)或者準(zhǔn)備面試但被問到底層執(zhí)行鏈路時答不清楚這篇文章建議收藏備用。1. Agent 到底解決的是什么問題先回到一個最基礎(chǔ)的問題為什么不能只靠大模型本身完成復(fù)雜任務(wù)大模型本質(zhì)上是一個“純文本推理器”。它可以根據(jù)上下文生成回答但它沒有能力去做這些事查詢實(shí)時天氣、股票價格、數(shù)據(jù)庫內(nèi)容執(zhí)行業(yè)務(wù)系統(tǒng)里的下單、審批、發(fā)送郵件等操作搜索最新的網(wǎng)絡(luò)信息運(yùn)行一段代碼并獲取結(jié)果。傳統(tǒng)做法是開發(fā)者寫死規(guī)則判斷用戶意圖再調(diào)用對應(yīng)接口。這種做法在小場景下沒問題但一旦用戶的說法千變?nèi)f化規(guī)則就會膨脹到無法維護(hù)。Agent 的思路完全不同讓大模型自己根據(jù)用戶的問題決定“我現(xiàn)在需要調(diào)用哪個工具”再根據(jù)工具返回的結(jié)果繼續(xù)推理下一步動作。用一個類比來理解普通 LLM 調(diào)用像和一個知識淵博但從不邁出房間的顧問對話。 Agent 像是給這個顧問配了一個辦公室他可以隨時拿起電話工具查數(shù)據(jù)、發(fā)指令、跑任務(wù)然后把新信息拿回來繼續(xù)思考。LangChain 做的事就是把“思考、調(diào)用、觀察結(jié)果、再思考”這個循環(huán)封裝成一套可復(fù)用的執(zhí)行機(jī)制。你不需要自己寫 while 循環(huán)去處理模型返回的 tool_calls只需要定義好工具交給 Agent 執(zhí)行即可。2. LangChain Agent 涉及的核心概念在拆執(zhí)行流程之前先把幾個容易混淆的概念說清楚。2.1 Agent 與 LLM 的關(guān)系A(chǔ)gent 不是一個新的模型它是在大模型之上構(gòu)建的一套“推理 行動”系統(tǒng)。LLM 負(fù)責(zé)兩件事理解用戶的自然語言輸入生成“下一步動作”的決策比如調(diào)用哪個工具、參數(shù)是什么。Agent 框架負(fù)責(zé)其余所有事情維護(hù)完整的消息歷史調(diào)用 LLM解析 LLM 返回的結(jié)構(gòu)化工具調(diào)用執(zhí)行工具把工具結(jié)果作為新的消息追加進(jìn)上下文判斷繼續(xù)循環(huán)還是返回最終答案。2.2 Tool 與 ToolExecutorTool 是可被調(diào)用的功能單元在 LangChain 里通常是一個函數(shù)加上一段描述。這個描述非常重要因?yàn)榇竽P鸵克鼇砼袛唷笆裁磿r候該用這個工具”。Tool 的簡單示例# 文件路徑tools/current_time.py from langchain_core.tools import tool from datetime import datetime tool def get_current_time() - str: 返回當(dāng)前系統(tǒng)時間用于查詢當(dāng)前日期和時間的場景。 return datetime.now().strftime(%Y-%m-%d %H:%M:%S)ToolExecutor 負(fù)責(zé)真正去執(zhí)行這個工具。在 AgentExecutor 中模型返回工具名和參數(shù)后框架會根據(jù)工具名找到對應(yīng)的函數(shù)并傳入?yún)?shù)執(zhí)行。2.3 AgentExecutor 與 Agent很多初學(xué)者把 AgentExecutor 和 Agent 當(dāng)作同一個東西其實(shí)它們是兩層Agent負(fù)責(zé)“思考和決策”的那部分邏輯輸入是消息列表輸出是 AgentAction 或 AgentFinishAgentExecutor負(fù)責(zé)“循環(huán)調(diào)度”的運(yùn)行時反復(fù)調(diào)用 Agent執(zhí)行工具直到 Agent 返回 AgentFinish。可以這樣理解Agent 是大腦AgentExecutor 是軀干和循環(huán)泵。2.4 Memory 在 Agent 中的位置Memory 在 Agent 里比普通對話鏈更復(fù)雜。普通 ChatModel 對話只需要維護(hù) user/assistant 消息列表而 Agent 的多輪交互中還要把每輪的工具調(diào)用和工具結(jié)果都塞進(jìn)上下文。缺少記憶模塊時Agent 只能“看到”當(dāng)前這一次執(zhí)行的消息無法跨會話保留信息。LangChain 的 Memory 模塊負(fù)責(zé)把歷史會話壓縮、截斷或匯總后放回提示詞中。但要注意Memory 解決的是跨會話記憶同一個執(zhí)行流程內(nèi)的工具調(diào)用結(jié)果默認(rèn)就在消息列表里不依賴 Memory 組件。3. 傳統(tǒng) FSM 寫法和 Agent 寫法的本質(zhì)差異在沒有 LangChain Agent 之前實(shí)現(xiàn)一個“自動查詢工具”的需求通常使用有限狀態(tài)機(jī)FSM或者硬編碼條件分支來寫。傳統(tǒng)寫法大概長這樣# 傳統(tǒng)思路偽代碼僅用于對比 def handle_query(user_input: str): if 時間 in user_input: return get_current_time() elif 天氣 in user_input: return get_weather(user_input) elif 搜索 in user_input: return search_web(user_input) else: return default_answer(user_input)這種寫法的最大問題不是代碼難看而是模式匹配的脆弱性用戶說“現(xiàn)在幾點(diǎn)了”能匹配到“時間”用戶說“麻煩幫我看看現(xiàn)在時間方便嗎”可能匹配不到用戶說“今天適合出門嗎”會命中天氣分支但用戶其實(shí)可能想要的是“天氣 建議”的組合。Agent 的做法是讓模型理解語義并自行判斷工具不需要維護(hù)一個龐大的意圖規(guī)則表。當(dāng)然這也帶來新的不確定性模型可能會選錯工具也可能會在工具調(diào)用中迷路這就要靠 Prompt 設(shè)計、合理的工具描述和迭代次數(shù)限制來控制。從工程角度看傳統(tǒng) FSM 的優(yōu)勢是結(jié)果確定、可控LangChain Agent 的優(yōu)勢是靈活、擴(kuò)展成本低。兩者不是完全替代關(guān)系在業(yè)界實(shí)際項(xiàng)目中很多系統(tǒng)依然是規(guī)則兜底 Agent 組合使用。4. LangChain Agent 執(zhí)行流程完整拆解這一節(jié)是全文的核心把 AgentExecutor 從收到用戶輸入到最后返回答案的完整鏈路拆開講清楚。4.1 輸入處理與消息組裝當(dāng)用戶輸入到達(dá) AgentExecutor 時第一件事不是直接調(diào)用 LLM而是把輸入整理成完整的消息列表。這個列表通常包括System Prompt定義 Agent 的身份和工具使用規(guī)則可選的 Memory 歷史消息來自之前輪次的對話摘要或消息片段當(dāng)前用戶輸入Agent 自身附加的 instructions比如“請根據(jù)以下工具決定下一步”。關(guān)鍵點(diǎn)工具描述并不是直接拼在系統(tǒng)提示詞里而是通過工具綁定bind_tools的方式注入到模型請求的 tools 參數(shù)中。對支持工具調(diào)用的模型如 GPT、Claude、Qwen 的 tool-call 版本來說工具列表是結(jié)構(gòu)化傳入的不是普通文本。4.2 模型決策階段生成工具調(diào)用或直接回答消息組裝完成后會進(jìn)入 Agent 的決策階段。模型拿到上下文后有兩種可能的輸出返回 AgentFinish模型認(rèn)為自己已經(jīng)有足夠信息回答問題直接輸出最終回答返回一個或多個 AgentAction模型決定調(diào)用某個工具并給出了工具名和參數(shù)。以 OpenAI Function Calling 類模型為例當(dāng)模型決定調(diào)用工具時返回的結(jié)構(gòu)里會有一個 tool_calls 數(shù)組包含工具名稱和參數(shù)字典。LangChain 會把這些結(jié)構(gòu)解析成 AgentAction 對象。這里有一個新手容易誤解的點(diǎn)模型“決定調(diào)用工具”時并不會真的執(zhí)行工具。它只是輸出一個“調(diào)用意圖”。真正執(zhí)行工具的是后面幾步。4.3 工具執(zhí)行階段AgentExecutor 收到 AgentAction 后會遍歷使用的工具集合根據(jù) action.tool 找到匹配的 Tool 對象然后調(diào)用它。這一步有幾個隱性規(guī)則工具名是精確匹配大小寫敏感工具參數(shù)會按模型輸出的 JSON 傳入框架會對類型做基礎(chǔ)轉(zhuǎn)換工具執(zhí)行的結(jié)果是一個字符串如果工具拋出異常LangChain 會把異常信息也作為結(jié)果返回給模型讓模型嘗試?yán)斫饣蛐拚?。工具?zhí)行階段最容易出的問題是模型“憑空捏造”一個不存在的工具名。這在模型能力弱或者工具描述不清時比較常見。緩解方式是使用 Strict Tools 校驗(yàn)?zāi)J讲糠帜P椭С只蛘咴鰪?qiáng) Prompt 中的工具使用說明。4.4 觀察結(jié)果回填與循環(huán)迭代工具執(zhí)行完畢后LangChain 會把工具結(jié)果封裝成一條 ToolMessage或 Observation 類型追加到消息列表中。這時候消息列表里會出現(xiàn)這樣一個完整片段user: 現(xiàn)在紐約幾點(diǎn) assistant: tool_call: get_current_time(locationNew York) tool: 2025-06-02 08:30:00這之后AgentExecutor 又會回到模型決策階段把包含工具結(jié)果的全量消息再次發(fā)給模型。模型看到工具返回后有兩種選擇如果工具結(jié)果已經(jīng)滿足問題需求輸出最終答案如果還需要更多信息繼續(xù)輸出下一個工具調(diào)用。這個“模型決策 → 工具執(zhí)行 → 結(jié)果回填 → 再決策”的過程就是 Agent 的執(zhí)行循環(huán)。AgentExecutor 通過max_iterations參數(shù)控制最大迭代次數(shù)默認(rèn)值通常是 15 左右。超過限制后Agent 會強(qiáng)制停止并返回一條提示超時的信息。4.5 終止條件AgentExecutor 的退出條件有三個任何一個滿足都會終止Agent 返回 AgentFinish正常結(jié)束達(dá)到 max_iterations 上限拋出未捕獲的異常異常會向調(diào)用方傳播。其中第二種是最常見的問題來源Agent 陷入死循環(huán)反復(fù)調(diào)用同一個工具或者工具結(jié)果沒有讓模型收斂。遇到這種問題不是簡單地調(diào)大 max_iterations 就能解決的而是要檢查工具描述是否清晰、工具返回信息是否足夠、Prompt 是否讓模型走偏甚至要考慮工具是不是太容易被誤調(diào)用。分步驟理解 LangChain 中任務(wù)規(guī)劃能力如何實(shí)現(xiàn)要看的就是這一整條執(zhí)行鏈路Agent 的“規(guī)劃”并不是一次性生成完整步驟表而是每輪決策下一步靠循環(huán)來逐步逼近目標(biāo)。5. 完整示例用 LangChain Agent 實(shí)現(xiàn)一個帶工具的任務(wù)執(zhí)行前面講了原理這一節(jié)用一個可運(yùn)行的最小示例把流程串起來。示例需求實(shí)現(xiàn)一個 Agent能夠根據(jù)用戶提問自行決定使用“查詢當(dāng)前時間”和“計算字符串長度”兩個工具最終輸出答案。5.1 環(huán)境準(zhǔn)備本文代碼不綁定具體 LangChain 大版本因?yàn)椴煌姹镜?import 路徑和參數(shù)名有過調(diào)整。建議使用較新的穩(wěn)定版本并保持依賴一致。pip install langchain pip install langchain-openai pip install langchain-core pip install langchain-community如果你使用的模型是 OpenAI 兼容接口可以是云廠商或本地模型服務(wù)。關(guān)鍵點(diǎn)是把 API Base 指向模型服務(wù)地址。# 文件路徑config/env.py import os # 如果使用第三方或本地模型服務(wù)打開下面一行 # os.environ[OPENAI_BASE_URL] http://your-model-service:8000/v1 os.environ[OPENAI_API_KEY] your-api-key5.2 定義工具這里定義兩個簡單工具為了可驗(yàn)證性工具內(nèi)部邏輯不強(qiáng)依賴外部服務(wù)。# 文件路徑tools/custom_tools.py from langchain_core.tools import tool tool def get_current_time() - str: 返回當(dāng)前系統(tǒng)時間用于查詢時間、日期相關(guān)的場景。 from datetime import datetime return datetime.now().strftime(%Y-%m-%d %H:%M:%S) tool def get_string_length(text: str) - int: 計算輸入字符串的長度適用于需要統(tǒng)計字符數(shù)的場景。參數(shù) text 是需要計算的字符串。 return len(text) # 導(dǎo)出工具列表后面會綁定到 Agent tools [get_current_time, get_string_length]工具描述是模型決策的重要依據(jù)。例如get_current_time的注釋里寫了“查詢時間、日期相關(guān)”模型遇到“現(xiàn)在幾點(diǎn)了”就會優(yōu)先選擇它get_string_length的注釋寫清楚參數(shù)text的含義模型才能正確傳參。5.3 創(chuàng)建 AgentExecutor接下來創(chuàng)建模型、Agent 和 AgentExecutor。# 文件路徑agent/run_agent.py from langchain_openai import ChatOpenAI from langchain.agents import create_tool_calling_agent, AgentExecutor from tools.custom_tools import tools # 1. 創(chuàng)建支持工具調(diào)用的模型 llm ChatOpenAI( modelgpt-4o-mini, # 請根據(jù)你的模型服務(wù)修改 temperature0, ) # 2. 綁定工具列表 llm_with_tools llm.bind_tools(tools) # 3. 編寫 Agent 的系統(tǒng)提示詞 system_prompt ( 你是一個能調(diào)用工具完成任務(wù)的助手。 當(dāng)用戶的問題需要實(shí)時數(shù)據(jù)時請先調(diào)用工具獲取結(jié)果再綜合你已有的知識回答。 ) # 4. 創(chuàng)建 Agent agent create_tool_calling_agent(llm_with_tools, tools, system_prompt) # 5. 創(chuàng)建 AgentExecutor并打開中間過程輸出 agent_executor AgentExecutor( agentagent, toolstools, verboseTrue, max_iterations5, )這里有幾個值得解釋的點(diǎn)bind_tools是關(guān)鍵步驟它會將工具列表作為結(jié)構(gòu)化參數(shù)傳入模型請求system_prompt不是傳給 Agent 的普通對話消息而是作為 SystemMessage 進(jìn)入消息列表verboseTrue可以在控制臺打印出每一步的 AgentAction 和工具結(jié)果是調(diào)試執(zhí)行流程最直接的手段max_iterations5是為了避免 Agent 陷入循環(huán)時消耗過多 token。5.4 運(yùn)行 Agent# 文件路徑agent/run_agent.py續(xù) if __name__ __main__: result agent_executor.invoke( {input: 請告訴我當(dāng)前時間順便計算一下「LangChain Agent」這個字符串的長度。} ) print(最終輸出, result[output])運(yùn)行命令python agent/run_agent.py如果一切正常控制臺會打印類似下面的中間過程 Entering new AgentExecutor chain... Invoking: get_current_time with {} 2025-06-02 08:30:00 Invoking: get_string_length with {text: LangChain Agent} 16 Finished chain.這說明 Agent 先調(diào)了時間工具又調(diào)了字符串長度工具最后模型基于兩次工具結(jié)果生成最終回答。6. AgentExecutor 執(zhí)行細(xì)節(jié)與常見誤區(qū)這一節(jié)補(bǔ)充一些新手很容易忽略的細(xì)節(jié)把這些搞明白排查問題會快很多。6.1 verbose 輸出怎么讀開啟verboseTrue后日志中出現(xiàn)的 “Invoking” 代表模型決策出要調(diào)用某個工具“Finished chain.” 代表 AgentExecutor 正常終結(jié)。如果看到工具被連續(xù)調(diào)用了一次以上說明模型拿到工具結(jié)果后仍然認(rèn)為信息不足。6.2 工具返回報錯會怎樣工具內(nèi)部如果拋異常默認(rèn)不會讓整個 Agent 崩潰。LangChain 會把異常信息封裝成工具執(zhí)行結(jié)果的一部分返回給模型。模型看到類似 “Error: xxx” 的內(nèi)容后可能會重新調(diào)整參數(shù)再次調(diào)用或者直接告訴用戶執(zhí)行失敗了。這個設(shè)計的初衷是增強(qiáng)容錯但也帶來一個副作用模型如果連續(xù)出錯可能會用更多迭代次數(shù)消耗 token。生產(chǎn)環(huán)境建議在工具內(nèi)部做防御性捕獲返回簡潔清晰的錯誤信息。6.3 create_tool_calling_agent 與 create_react_agentLangChain 提供了多種創(chuàng)建 Agent 的函數(shù)最容易混淆的是這兩個create_tool_calling_agent依賴模型原生支持 tool calling返回結(jié)構(gòu)化工具調(diào)用解析穩(wěn)定是當(dāng)前主流用法create_react_agent不依賴原生 tool calling通過讓模型輸出 ReAct 格式的文本Thought/Action/Action Input來決策兼容更老的模型但解析更容易出錯。如果你使用 Qwen、GPT、Claude、GLM 等支持工具調(diào)用的新模型優(yōu)先用 create_tool_calling_agent。如果模型不支持原生 tool calling再考慮 ReAct 方式。7. LangGraph 與 LangChain Agent 的關(guān)系現(xiàn)在很多文章會同時出現(xiàn) LangChain 和 LangGraph初學(xué)者容易把兩者對立起來。實(shí)際上 LangGraph 是 LangChain 團(tuán)隊(duì)推出的狀態(tài)化編排框架可以理解為更底層、更靈活的 Agent 運(yùn)行時。7.1 AgentExecutor 與 LangGraph 的對比AgentExecutor 把整個執(zhí)行循環(huán)封裝成了黑盒你給它輸入它返回輸出中間過程雖然可通過 verbose 查看但定制能力有限。LangGraph 則不同它把 Agent 的執(zhí)行流程顯式地建模成一個圖節(jié)點(diǎn)模型節(jié)點(diǎn)、工具節(jié)點(diǎn)、條件判斷節(jié)點(diǎn)邊節(jié)點(diǎn)之間的流轉(zhuǎn)關(guān)系狀態(tài)全局可讀寫在節(jié)點(diǎn)之間傳遞。你可以自己定義“判斷是否繼續(xù)調(diào)用工具”的條件也可以插入人工審核節(jié)點(diǎn)、自定義日志節(jié)點(diǎn)、失敗重試節(jié)點(diǎn)。這些都很難在 AgentExecutor 里實(shí)現(xiàn)。7.2 什么時候該選 LangGraph簡單判斷標(biāo)準(zhǔn)項(xiàng)目只需要一個 LLM 兩三個工具的簡單助理AgentExecutor 足夠項(xiàng)目包含多個 Agent 協(xié)作、需要人工審批、需要精細(xì)控制在某一步暫停或回退用 LangGraph項(xiàng)目需要把執(zhí)行狀態(tài)持久化、恢復(fù)或展示給前端尤其是后臺任務(wù)場景LangGraph 更方便。更準(zhǔn)確地說AgentExecutor 是 LangGraph 的一個特殊形態(tài)當(dāng)你只需要“決策 → 執(zhí)行 → 循環(huán)”的默認(rèn)流程時用一個已經(jīng)實(shí)現(xiàn)好的 AgentExecutor 就夠了當(dāng)你需要打破默認(rèn)流程時就應(yīng)該考慮用 LangGraph 手動搭一個。從 LangChain 團(tuán)隊(duì)近期的演進(jìn)方向看AgentExecutor 相關(guān)代碼逐漸不再作為新功能的主要迭代對象LangGraph 會成為更長期的選擇。8. 常見問題與排查思路Agent 執(zhí)行中的問題非常依賴上下文下面整理幾類高頻問題按排查優(yōu)先級排列。問題現(xiàn)象可能原因排查方式解決方案模型拒絕調(diào)用任何工具工具描述不清開啟 verbose觀察模型輸出增強(qiáng)工具注釋在 Prompt 中舉例說明什么時候用工具模型反復(fù)調(diào)用同一個工具直到超限工具結(jié)果不滿足模型預(yù)期或 Prompt 缺少終止約束打印工具返回內(nèi)容確認(rèn)返回是否為空/報錯改進(jìn)工具結(jié)果內(nèi)容在 Prompt 中強(qiáng)調(diào)“信息足夠時直接回答”工具調(diào)用時報“工具不存在”工具名大小寫或拼寫不一致打印 tools 列表名稱統(tǒng)一工具命名啟動時做一次名稱檢查Agent 無法正確處理多工具組合結(jié)果模型能力不足或上下文過長檢查中間日志看工具結(jié)果是否完整進(jìn)入上下文精簡工具結(jié)果切換更強(qiáng)模型調(diào)用超時長期無響應(yīng)模型服務(wù)連接慢或工具執(zhí)行外部請求慢看日志停在哪個環(huán)節(jié)為工具增加超時控制把耗時的工具體驗(yàn)改為異步任務(wù)Memory 不生效多輪對話“失憶”沒有配置 Memory 模塊或會話沒有復(fù)用同一個 AgentExecutor檢查消息列表確認(rèn)歷史消息是否被傳入使用記憶組件或由上層應(yīng)用統(tǒng)一維護(hù)會話歷史最常見且容易被忽視的是第一個模型不調(diào)用工具。很多人的第一反應(yīng)是換一個大模型但實(shí)際上工具描述寫得是否足夠清楚對模型決策的影響非常大。比如把工具描述從 “獲取時間” 改成 “當(dāng)用戶詢問當(dāng)前時間、日期、幾點(diǎn)了時調(diào)用此工具獲取最新系統(tǒng)時間不要根據(jù)你已有的知識推測”模型的工具調(diào)用觸發(fā)率會明顯提升。9. 最佳實(shí)踐與工程建議結(jié)合執(zhí)行流程的機(jī)制整理幾條對實(shí)際項(xiàng)目最有效的建議。9.1 工具設(shè)計的三條原則單一職責(zé)一個工具只做一件事避免一個工具內(nèi)部塞多個不相關(guān)邏輯描述即 Prompt工具的描述是給模型看的要寫清楚“什么時候用”和“怎么傳參數(shù)”參數(shù)盡量少參數(shù)越多模型傳錯的概率越高。能設(shè)計成無參數(shù)的就不要讓模型填參數(shù)。9.2 給工具加超時與容錯工具執(zhí)行階段可能調(diào)用第三方 API不可不加超時。如果不加模型等待工具結(jié)果時會一直懸掛白白浪費(fèi) token 和用戶時間。from langchain_core.tools import tool import time tool def call_external_api(url: str) - str: 調(diào)用外部 HTTP 接口適用于需要獲取實(shí)時外部數(shù)據(jù)的場景。 import requests try: resp requests.get(url, timeout5) resp.raise_for_status() return resp.text[:500] except Exception as e: return f請求失敗: {str(e)}注意最后把異常轉(zhuǎn)成字符串返回這樣模型能理解發(fā)生了什么而不是讓整個鏈路崩潰。9.3 開啟結(jié)構(gòu)化執(zhí)行與可觀測性生產(chǎn)環(huán)境使用 Agent 時強(qiáng)烈建議保留執(zhí)行日志尤其是每輪的 tool_calls、tool 返回值、token 數(shù)把 verbose 的輸出接入日志系統(tǒng)而不是只在本地打印對 Agent 的輸入輸出做敏感信息過濾避免工具把用戶的隱私內(nèi)容傳給第三方服務(wù)對 Agent 的權(quán)限做最小化設(shè)計能只讀就不要給寫權(quán)限能只查一個表就不要連整個庫。9.4 別讓 Agent 直接操作生產(chǎn)庫Agent 的靈活性是把雙刃劍。模型可能因?yàn)?Prompt 注入或用戶誤導(dǎo)生成一個意想不到的 SQL 或刪除操作。在實(shí)際業(yè)務(wù)中不要讓 Agent 直接連接生產(chǎn)數(shù)據(jù)庫執(zhí)行寫操作。正確的做法是Agent 生成操作意圖提交到審批隊(duì)列由人工或受限服務(wù)執(zhí)行。9.5 為 Agent 設(shè)定成本上限使用工具調(diào)用時每一輪 LLM 調(diào)用都會產(chǎn)生 token 消耗。一個陷入死循環(huán)的 Agent 可能短時間內(nèi)消耗比普通對話高一個數(shù)量級的成本。除了設(shè)置 max_iterations建議在模型客戶端層再設(shè)一層 token 限額超限直接中斷。10. 總結(jié)與后續(xù)學(xué)習(xí)方向把這篇文章讀完你應(yīng)該已經(jīng)掌握了幾個關(guān)鍵點(diǎn)Agent 不是新模型而是“LLM 工具 循環(huán)調(diào)度”的組合AgentExecutor 的默認(rèn)執(zhí)行鏈路是組裝消息 → 模型決策 → 工具執(zhí)行 → 結(jié)果回填 → 再次決策工具描述的質(zhì)量直接影響模型能否正確調(diào)用工具當(dāng)默認(rèn)執(zhí)行鏈路無法滿足需求時LangGraph 是更可控的替代方案。下一步的實(shí)踐建議是不急著搭建復(fù)雜框架先用一個最小 Agent 跑通“時間查詢”場景打開 verbose 觀察每一輪輸出再把工具數(shù)量逐步增加觀察模型在不同工具數(shù)量下的決策質(zhì)量變化。親手過一遍agent_executor.invoke()的調(diào)用棧比背任何框架文檔都更有用。如果你已經(jīng)能熟練使用 AgentExecutor建議開始研究 LangGraph從寫一個“模型節(jié)點(diǎn) 工具節(jié)點(diǎn) 條件邊”的最小圖開始理解狀態(tài)如何流轉(zhuǎn)、循環(huán)如何退出。這一步的投入會直接遷移到你后面所有 Agent 項(xiàng)目的架構(gòu)設(shè)計中。