
学会写 Tool 之后我以为 Agent 会顺理成章地工作把模型和工具丢给create_agent它就能自己决定什么时候调用什么。结果它根本没按我想的走。有时候自己硬答有时候调了 Tool 但参数不对有时候甚至连 Tool 看都不看一眼。create_agent明明没报错但效果就是不对。这篇文章记录我理解 Agent 到底怎么思考的过程。一、我当时想干什么我已经有了两个 Tooladd(a, b)做加法search(query)模拟搜索我想让 Agent 完成这样的任务“3 5 等于几再搜索一下 LangChain 最新动态。”期望 Agent 自己判断先调用add再调用search最后综合回答。我写的代码fromlangchain.agentsimportcreate_agentfromlangchain_core.toolsimporttoolfromlangchain_openaiimportChatOpenAItooldefadd(a:int,b:int)-int:计算两个数的和returnabtooldefsearch(query:str)-str:搜索信息returnf关于{query}的搜索结果...llmChatOpenAI(modeldeepseek-chat,temperature0,openai_api_key你的 api key,openai_api_basehttps://api.deepseek.com/v1,)agentcreate_agent(modelllm,tools[add,search],)看起来没问题但运行后 Agent 有时候直接心算358根本不调add。二、我写的代码后来我加了一个system_prompt事情开始好转agentcreate_agent(modelllm,tools[add,search],system_prompt你是一个助手遇到数学问题必须调用 add 工具遇到信息查询必须调用 search 工具。,)resultagent.invoke({messages:[{role:user,content:3 5 等于几再搜索一下 LangChain 最新动态。}]})print(result[messages][-1].content)Agent 开始按规则调用工具了。我还试了结构化输出frompydanticimportBaseModelclassAnswer(BaseModel):答案结构定义summary:strconfidence:floatagentcreate_agent(modelllm,tools[search],response_formatAnswer,)resultagent.invoke({messages:[{role:user,content:总结 AI 最新趋势}]})answerresult[structured_response]print(answer.summary,answer.confidence)这样 Agent 的输出就被约束成了固定格式不会胡说八道。三、我遇到的坑坑 1以为 Agent 会自觉调 Tool我最开始的代码没写system_prompt以为 Agent 看到add工具就会用。结果模型有时候直接心算答案。后来我理解了Agent 本质上是一个循环——模型决定是继续推理还是调用工具。模型做决定时主要依据是system prompt 里的指令Tool 的 name 和 description当前对话上下文如果 system prompt 不明确模型就会偷懒用自己内部知识回答。坑 2Tool 描述和实际功能不匹配我早期写search的 docstring 是tooldefsearch(query:str)-str:搜索returnf关于{query}的搜索结果...然后问今天天气怎么样Agent 调用了search(今天天气)但返回的是模拟数据。我想让它返回真实天气但工具本身不支持。这教会我一件事Agent 的能力边界 Tool 的能力边界。你给它的工具只能做模拟搜索它就不可能给你真实天气。不要期望 Agent 弥补工具的缺陷。坑 3response_format和 Tool 调用冲突我一开始想同时做两件事让 Agent 调用search然后返回一个Answer结构。代码类似这样agentcreate_agent(modelllm,tools[search],response_formatAnswer,# 希望最终输出结构化)结果发现如果 Agent 调用了 ToolTool 的返回内容可能不会被自动塞进Answer的summary字段。response_format约束的是最终回复不是中间 Tool 的结果。要解决这个问题我学会了分两步先让 Agent 调用 Tool 拿到结果再用 Chain 或第二次调用把结果整理成结构化输出坑 4模型本身不支持 function calling我用某个模型测试时Agent 死活不调工具。换到deepseek-chat后正常。原因是不是所有模型都擅长 function calling。有些小模型或旧模型看不懂 Tool 的 schema自然不会按规则调用。如果你的 Agent 不调工具先确认模型是否支持工具调用。四、搞清楚后的结论create_agent不是魔法它只是搭了一个循环框架。真正决定 Agent 行为的是四个东西是否System Prompt行为准则Agent 决策Model推理能力Tools可调用的工具Response Format输出约束调用工具执行 ToolTool 结果回到上下文直接回答这四个参数的关系参数作用如果配错会怎样model负责推理的大脑模型不支持工具调用Agent 不会调 Tooltools能调用的外部能力工具描述不清Agent 乱调或漏调system_prompt告诉 Agent 什么时候该调工具不写的话Agent 会偷懒response_format约束最终输出格式不能替代 Tool 调用后的二次加工五、我的收获Agent 不是有了工具就会用是你得告诉它什么时候用、为什么用。我以前觉得写好 Tool、传给create_agent剩下的事交给模型就行。实际不是。Agent 就像一个刚入职的员工你给了它电话、电脑、系统账号但它不一定会按流程办事。你需要写清楚 SOPsystem prompt给它能力匹配的工具tools还要选一个有判断力的大脑model。理解这一点后我写 Agent 的顺序变了先想清楚要 Agent 做什么再设计 Tool每个 Tool 职责单一写 system prompt 明确调用规则最后加 response_format 约束输出这个顺序比直接create_agent(model..., tools...)稳得多。下一篇我会写记忆——为什么我加了InMemorySaverAgent 还是不记得上一句说了什么。