
适合前后端/测试等有编程基础的同学手把手教你构建能自主决策的AI Agent前言通过前面几节课的学习我们已经掌握了LangChain的Model I/O模型调用、Chain流程编排、Memory记忆系统和Retrieval知识检索。现在你的AI应用已经能“听懂话”、“会干活”、“记得住”、“能查资料”了。但所有这些能力都需要你手动编排——用Chain把步骤串起来用RAG把检索和生成连起来。AI本身没有自主决策权。如果我们想让AI自己决定下一步做什么、调用哪个工具、什么时候停止呢这就是今天的主角——Tool工具与 Agent智能体。一句话定义Agent是一个能自主决定调用哪些Tool来完成任务的智能体它会在“思考→行动→观察”的循环中不断迭代直到完成任务。Tool是Agent的“手脚”——具体执行动作的函数。Agent是Agent的“大脑”——决定什么时候用什么Tool。全文约6500字代码均可直接复制运行。一、从Chain到Agent从“被动执行”到“自主决策”1.1 Chain的局限在前面的课程中我们构建的所有应用都是Chain——预先定义好的固定流程用户提问 → 检索知识库 → 生成回答 → 结束Chain就像一个流水线工人按照固定的步骤一步一步执行。优点是稳定、可预测缺点是没有灵活性——遇到需要动态决策的任务就无能为力了。1.2 Agent的革命让AI自己“想”和“做”Agent的核心思想来自2022年的ReAct论文Reasoning Acting。它让AI在一个循环中不断Thought思考→ Action行动→ Observation观察→ Thought思考→ ...一个真实的Agent执行过程用户帮我查一下北京天气然后根据天气推荐一个活动 Thought: 用户需要先查北京天气再基于天气推荐活动 Action: get_weather(city北京) Observation: 北京今天晴25°C Thought: 天气很好适合户外活动 Action: recommend_activity(weather晴, temp25) Observation: 推荐爬山、野餐、骑行 Thought: 我已经得到了天气和推荐可以给出最终答案了 Final Answer: 北京今天天气晴朗气温25°C推荐您去爬香山或去朝阳公园野餐Chain和Agent的核心区别维度ChainAgent执行路径固定预先定义动态自主决策决策权在开发者手中在模型手中工具调用手动编排自主决定调用哪些、何时调用适用场景流程固定的任务需要推理和动态决策的复杂任务二、ToolAgent的“手脚”在构建Agent之前我们首先要定义好Agent可以使用的工具Tool。Tool是Agent与外部世界交互的接口。2.1 用 tool 装饰器定义工具LangChain提供了最简洁的方式——tool装饰器fromlangchain.toolsimporttooltooldefget_weather(city:str)-str:获取指定城市的天气信息。# 模拟天气数据weather_db{北京:晴25°C,上海:多云28°C,深圳:小雨30°C}returnweather_db.get(city,f未找到{city}的天气信息)# 工具会自动从函数名获取名称从docstring获取描述print(get_weather.name)# get_weatherprint(get_weather.description)# 获取指定城市的天气信息。关键点函数名自动成为Tool的名称docstring自动成为Tool的描述类型注解自动定义输入参数的schema2.2 自定义工具名称和描述当需要更精确地控制工具的行为时可以自定义tool(weather_query,description查询任意城市的实时天气信息。适用于任何需要了解天气状况的场景。)defget_weather(city:str)-str:获取指定城市的天气信息。# ... 实现逻辑2.3 复杂参数使用Pydantic定义输入Schema当工具需要多个参数或复杂参数时使用Pydantic模型精确定义frompydanticimportBaseModel,FieldfromtypingimportLiteralclassWeatherInput(BaseModel):天气查询的输入参数location:strField(description城市名称如北京、上海)unit:Literal[celsius,fahrenheit]Field(defaultcelsius,description温度单位)include_forecast:boolField(defaultFalse,description是否包含未来5天预报)tool(args_schemaWeatherInput)defget_weather(location:str,unit:strcelsius,include_forecast:boolFalse)-str:获取指定城市的天气信息。# ... 实现逻辑2.4 内置工具开箱即用LangChain提供了大量预置工具无需自己实现# 网页搜索工具fromlangchain_community.toolsimportDuckDuckGoSearchRun searchDuckDuckGoSearchRun()# 计算器工具fromlangchain_community.toolsimportWikipediaQueryRunfromlangchain_community.utilitiesimportWikipediaAPIWrapper wikipediaWikipediaQueryRun(api_wrapperWikipediaAPIWrapper())# Shell命令执行谨慎使用fromlangchain_community.toolsimportShellTool shellShellTool()2.5 Tool命名规范不同模型提供商对工具名称有不同要求建议遵循以下规范✅ 使用snake_caseweb_search、get_weather❌ 避免空格和特殊字符Web Search、get-weather!✅ 使用字母、数字、下划线和连字符2.6 工具设计最佳实践实践说明清晰的docstring模型靠描述理解工具用途要简洁准确完整的类型注解自动生成输入schema帮助模型正确传参合理的参数默认值减少模型必须提供的参数数量友好的错误信息工具执行失败时返回可读的错误描述幂等性同一输入多次调用应返回相同结果三、Agent ExecutorAgent的执行引擎3.1 ⚠️ 重要提醒AgentExecutor已成历史如果你在网上搜索LangChain Agent教程很可能看到大量使用AgentExecutor的代码。但在2026年这是一个过时的做法。LangChain v1.02025年10月发布之后所有新Agent都运行在LangGraph运行时上。AgentExecutor已进入维护模式有效期至2026年12月。请勿在新代码中使用AgentExecutor应使用create_agent。旧写法已过时不要再用# ❌ 过时写法 —— AgentExecutor已进入维护模式fromlangchain.agentsimportAgentExecutor,create_openai_tools_agent agentcreate_openai_tools_agent(llm,tools,prompt)agent_executorAgentExecutor(agentagent,toolstools)resultagent_executor.invoke({input:...})新写法2026年标准# ✅ 推荐写法 —— 使用 create_agentfromlangchain.agentsimportcreate_agent agentcreate_agent(modelllm,tools[get_weather,search],system_prompt你是一个乐于助人的助手)resultagent.invoke({messages:[{role:user,content:北京天气怎么样}]})3.2 create_agent2026年创建Agent的标准方式create_agent是LangChain v1.0引入的新一代Agent工厂函数底层基于LangGraph构建。基本用法fromlangchain.agentsimportcreate_agentfromlangchain_openaiimportChatOpenAI# 1. 定义工具tooldefget_weather(city:str)-str:获取指定城市的天气信息。returnf{city}今天天气晴朗气温25°Ctooldefsearch_web(query:str)-str:搜索网页信息。returnf关于{query}的搜索结果...# 2. 初始化模型llmChatOpenAI(modeldeepseek-v4-flash,api_key你的Key,base_urlhttps://api.deepseek.com)# 3. 创建Agentagentcreate_agent(modelllm,# 语言模型tools[get_weather,search_web],# 可用工具列表system_prompt你是一个乐于助人的AI助手可以使用工具来回答问题。# 系统提示词)# 4. 执行resultagent.invoke({messages:[{role:user,content:北京天气怎么样顺便帮我搜一下故宫门票}]})# 5. 获取最终回答print(result[messages][-1].content)3.3 create_agent 的核心参数create_agent支持丰富的配置选项参数类型说明modelstr或BaseChatModel使用的语言模型toolsSequence[BaseTool]Agent可用的工具列表system_promptstr或SystemMessage系统提示词middlewareSequence[AgentMiddleware]中间件日志、限流等response_formatResponseFormat结构化输出格式checkpointerCheckpointer状态持久化支持断点续传interrupt_beforelist[str]在哪些节点前中断人工介入3.4 Agent的执行流程当你调用agent.invoke()时create_agent创建的Agent会执行以下循环1. Agent节点调用LLM传入消息列表和系统提示词 2. 如果LLM返回的AIMessage包含tool_calls → 进入工具调用节点 3. 工具节点执行对应的工具返回结果 4. 将工具结果作为消息追加到列表中 5. 回到步骤1继续循环 6. 当LLM不再返回tool_calls时停止循环输出最终答案可视化流程用户输入 → [Agent节点] → LLM推理 ↓ 有tool_calls ↙ ↘ 是 否 ↓ ↓ [工具节点] 输出最终答案 ↓ 执行工具 ↓ 返回结果 → (回到Agent节点)四、实战构建一个能自主决策的“旅行助手Agent”把上面学的所有知识综合起来构建一个完整的Agent应用。4.1 完整代码fromlangchain.agentsimportcreate_agentfromlangchain.toolsimporttoolfromlangchain_openaiimportChatOpenAIfromlangchain_community.toolsimportDuckDuckGoSearchRun# 第一步定义工具 tooldefget_weather(city:str)-str:获取指定城市的实时天气信息。适用于任何需要查询天气的场景。weather_db{北京:晴25°C空气质量良好,上海:多云28°C湿度较大,深圳:小雨30°C注意带伞,杭州:阴天22°C适合出游}returnweather_db.get(city,f未找到{city}的天气信息请尝试其他城市)tooldefsearch_attractions(city:str)-str:搜索指定城市的热门景点和旅游推荐。attractions_db{北京:故宫、天安门、长城、颐和园、天坛,上海:外滩、东方明珠、迪士尼、豫园,深圳:世界之窗、欢乐谷、大梅沙,杭州:西湖、灵隐寺、宋城、千岛湖}returnattractions_db.get(city,f未找到{city}的景点信息)tooldefcalculate_travel_time(distance_km:float,speed_kmh:float60)-str:计算旅行所需时间。distance_km: 距离公里speed_kmh: 速度公里/小时默认60。hoursdistance_km/speed_kmh minuteshours*60ifhours1:returnf大约需要{minutes:.0f}分钟else:returnf大约需要{hours:.1f}小时# 第二步初始化模型 llmChatOpenAI(modeldeepseek-v4-flash,api_key你的API_Key,base_urlhttps://api.deepseek.com,temperature0.3# 低温度保证决策稳定)# 第三步创建Agent agentcreate_agent(modelllm,tools[get_weather,search_attractions,calculate_travel_time],system_prompt你是一个专业的旅行规划助手名叫小旅。 你的职责是帮助用户规划旅行包括查询天气、推荐景点、计算行程时间。 重要规则 1. 当用户提到某个城市时先查询天气再推荐景点 2. 当用户提到距离或时间时使用计算工具 3. 回答要全面、有条理用友好的语气 4. 如果用户的问题不完整主动追问缺失的信息)# 第四步执行 deftravel_agent_chat(user_input:str):print(f\n 用户{user_input})resultagent.invoke({messages:[{role:user,content:user_input}]})# 提取最终回答final_messageresult[messages][-1]print(f 小旅{final_message.content})# 查看中间步骤工具调用记录print(\n 执行过程)formsginresult[messages]:ifhasattr(msg,tool_calls)andmsg.tool_calls:fortcinmsg.tool_calls:print(f 调用工具{tc[name]}({tc[args]}))ifmsg.typetool:print(f 工具返回{msg.content[:50]}...)# 第五步测试 if__name____main__:# 测试1综合旅行规划travel_agent_chat(我想去北京旅游帮我看看天气和景点)# 测试2时间计算travel_agent_chat(从北京到天津大约120公里开车要多久)4.2 运行效果 用户我想去北京旅游帮我看看天气和景点 小旅北京今天天气晴朗气温25°C空气质量良好非常适合出游 推荐您去以下景点故宫、天安门、长城、颐和园、天坛。 建议您安排3-4天的行程可以充分体验北京的历史文化魅力。 执行过程 调用工具get_weather({city: 北京}) 工具返回北京晴25°C空气质量良好... 调用工具search_attractions({city: 北京}) 工具返回故宫、天安门、长城、颐和园、天坛... 用户从北京到天津大约120公里开车要多久 小旅从北京到天津大约120公里以每小时60公里的速度行驶大约需要2.0小时。 如果走高速公路速度更快的话时间会更短。 执行过程 调用工具calculate_travel_time({distance_km: 120, speed_kmh: 60}) 工具返回大约需要 2.0 小时Agent成功实现了自主决策——它自己判断需要调用哪些工具、按什么顺序调用而不是我们预先编排好的五、Agent的高级特性5.1 中间件Middlewarecreate_agent支持中间件可以在Agent执行过程中插入自定义逻辑fromlangchain.agents.middlewareimportAgentMiddleware# 日志中间件classLoggingMiddleware(AgentMiddleware):defbefore_agent(self,state,runtime):print(f Agent开始思考...)returnstatedefafter_agent(self,state,runtime):print(f✅ Agent完成思考)returnstate agentcreate_agent(modelllm,tools[get_weather,search_attractions],middleware[LoggingMiddleware()],system_prompt你是一个旅行规划助手)5.2 结构化输出response_format强制Agent输出结构化数据fromtypingimportListfrompydanticimportBaseModelclassTravelPlan(BaseModel):city:strweather:strattractions:List[str]duration_days:inttips:stragentcreate_agent(modelllm,tools[get_weather,search_attractions],response_formatTravelPlan,# 强制输出TravelPlan格式system_prompt你是一个旅行规划助手请以结构化格式输出计划)resultagent.invoke({messages:[{role:user,content:规划北京三日游}]})# result[messages][-1].content 将是符合TravelPlan结构的JSON5.3 状态持久化checkpointer支持断点续传Agent可以在中断后从上次状态继续执行fromlanggraph.checkpoint.memoryimportMemorySaver checkpointerMemorySaver()agentcreate_agent(modelllm,tools[get_weather,search_attractions],checkpointercheckpointer,system_prompt你是一个旅行规划助手)# 第一次执行可以传入thread_idconfig{configurable:{thread_id:user_123}}resultagent.invoke({messages:[{role:user,content:我想去北京}]},configconfig)# 后续对话可以继续使用同一个thread_idAgent会记得之前的上下文result2agent.invoke({messages:[{role:user,content:推荐几个景点}]},configconfig# 同一个thread_id记忆延续)六、最佳实践与踩坑指南6.1 ⚠️ 不要使用AgentExecutor这是2026年最重要的提醒所有使用AgentExecutor的教程都是过时的。# ❌ 绝对不要这样写fromlangchain.agentsimportAgentExecutor agent_executorAgentExecutor(agentagent,toolstools)# ✅ 应该这样写fromlangchain.agentsimportcreate_agent agentcreate_agent(modelllm,toolstools)6.2 工具数量控制给Agent太多的工具会增加模型决策的难度也浪费Token。推荐3-6个工具功能明确、不重叠避免10个工具让模型难以选择6.3 工具描述要精准模型的决策完全依赖工具的描述❌模糊描述处理用户输入→ 模型不知道什么时候用✅精准描述将摄氏温度转换为华氏温度接收一个数字返回一个数字→ 模型知道用于温度转换场景6.4 设置合理的temperatureAgent需要稳定的决策能力temperature不宜过高推荐temperature0.1 ~ 0.3避免temperature 0.7会导致决策不稳定6.5 添加工具执行超时防止工具执行卡死importtimeout_decoratortooltimeout_decorator.timeout(10)# 10秒超时defcall_external_api(query:str)-str:# 可能耗时较长的外部调用pass七、实战小练习作业练习构建一个“智能数据分析Agent”需求定义3个工具query_database(sql: str)→ 模拟查询数据库calculate_statistics(data: str)→ 计算均值、中位数、最大值、最小值generate_chart(data: str, chart_type: str)→ 生成图表描述使用create_agent创建Agent测试以下场景“帮我查一下上个月的销售数据”“计算一下这些数据的平均值”“生成一个趋势图”提示代码框架fromlangchain.agentsimportcreate_agentfromlangchain.toolsimporttoolfromlangchain_openaiimportChatOpenAItooldefquery_database(sql:str)-str:执行SQL查询返回查询结果。# 模拟数据库查询returnf查询结果{sql}返回了100条记录...tooldefcalculate_statistics(data:str)-str:计算数据的统计指标均值、中位数、最大值、最小值。# 实现统计计算passtooldefgenerate_chart(data:str,chart_type:str)-str:根据数据和图表类型生成图表描述。chart_type: bar/line/piepass# 创建Agentagentcreate_agent(modelllm,tools[query_database,calculate_statistics,generate_chart],system_prompt你是一个数据分析专家...)# 测试resultagent.invoke({messages:[{role:user,content:帮我分析一下上个月的销售趋势}]})结语今天这节课我们全面学习了LangChain的Tool与Agent系统知识点核心内容Chain vs AgentChain固定流程Agent自主决策Tool定义tool装饰器、Pydantic schema、内置工具AgentExecutor⚠️ 已过时不要在新代码中使用create_agent2026年创建Agent的标准方式Agent执行流程Agent节点 → 工具节点 → 循环 → 输出高级特性中间件、结构化输出、状态持久化下节课第12节我们将深入学习LangGraph——LangChain的底层图编排引擎。你会发现create_agent底层就是基于LangGraph构建的。当我们掌握LangGraph后就能构建更复杂的、带分支和循环的Agent工作流如果觉得有帮助欢迎点赞、收藏、评论三连我们下节课见 本文是《AI Agent开发实战》课程第11节的完整内容系列文章持续更新中关注我不迷路