LangChain Agent 从零入门让大模型学会自己动手从 Chain 到 Agent大模型终于有了手脚和判断力一、Chain 不够用了我需要一个能自己做决定的东西学 LangChain 的过程中我先搞定了 Model I/O怎么调模型又学会了 Prompt 模板和输出解析接着掌握了 Chain把几个步骤串起来。用 Chain 搭一个固定的流程比如翻译一段文字或者总结一篇文章确实够用了。但有一天我想做一个稍微复杂点的功能用户说帮我查查北京明天会不会下雨如果下雨就帮我把明天的户外活动取消掉。用 Chain 怎么实现我得提前把流程写死先调天气 API → 判断返回结果 → 如果下雨就调取消日程 API → 如果不下雨就直接回复。看起来还行但问题在于——如果用户换成查查上海后天的天气不下雨就帮我订一张迪士尼门票呢流程完全不一样了。每来一种新的问法我就得写一条新的 Chain。这时候我才意识到我需要的不是一个固定的流水线而是一个能“自己做决定”的东西——给它一个目标它能自己判断该干什么、怎么干、干完了没有。这就是 Agent智能代理。二、Agent 是啥一句话说清楚Agent LLM大脑 工具手脚 自主决策在 Chain 里流程是开发者定的——“你先干 A再干 B最后干 C”。在 Agent 里流程是 LLM 自己定的——“用户想要 X我看看……我需要先做 A拿到结果后再做 B好了任务完成回复用户”。用大白话总结Chain你告诉 LLM “怎么做”它照做Agent你告诉 LLM “要做什么”它自己想办法Agent 不是一次调用就结束的。它内部是一个感知 → 推理 → 行动的循环可能转好几轮才完成任务感知收到用户消息推理LLM 想我该干点啥行动调用一个工具或者直接回复观察拿到工具返回的结果回到第 2 步继续推理结果拿到了下一步呢直到 LLM 觉得搞定了输出最终答案整个过程里没有任何一行代码规定先调用哪个工具、再调用哪个工具。全是 LLM 自己判断的。如果天气是晴天它压根不会去调用取消预约那个工具。三、核心组件大脑、手脚、记忆、规划Agent 有四个核心组件但并不是所有 Agent 都需要全部具备。最简的 Agent 只需要大脑 手脚。① LLM大脑负责理解用户意图决定每一步干什么。这是 Agent 的核心驱动力。② Tools手脚负责执行具体操作。LLM说我要查天气工具就去调用天气 APILLM说我要搜索工具就去执行搜索。LLM 只负责想工具负责做。③ Memory记忆负责记住对话历史。没有记忆的话你上一句说我叫张三下一句问我叫什么名字它就答不上来了。④ Planning规划负责把复杂任务拆成步骤。在 LangChain 的基础 Agent 里规划不是单独一个模块而是融合在 LLM 的推理过程中——它每走一步都想一下下一步该干啥。这种方式叫ReAct 模式边走边看步步为营。四、定义工具用 tool 装饰器工具是 Agent 能动手做事的关键。LangChain 里定义工具超级简单用tool装饰器包一下普通 Python 函数就行。fromlangchain.toolsimporttooltooldefget_weather(city:str,date:str)-str:获取指定城市在指定日期的天气。 Args: city: 城市名称如北京、上海 date: 日期格式为 YYYY-MM-DD # 实际项目中调用真实天气 APIreturnf{city}在{date}天气多云有下雨的可能性。就这么几行LangChain 会自动帮你根据函数名生成工具名称根据 docstring 生成工具描述LLM 靠这个理解工具是干啥的根据参数类型注解生成 JSON SchemaLLM 靠这个知道该传什么参数三个影响准确率的关键点要素建议函数名用清晰的动词名词如get_weather、search_documentsdocstring写清楚这个工具做什么越具体越好参数注解每个参数都要有类型和说明LLM 靠这个决定传什么值经验之谈docstring 别写太简略。你写查天气LLM 可能不知道什么时候该用、该传什么格式的日期。你写获取指定城市在指定日期的实时天气返回温度和天气状况LLM 就清楚多了。五、构建 Agentcreate_agent 一行搞定工具定义好了LLM 选好了组装成 Agent 只需要一行fromlangchain.agentsimportcreate_agentfromlangchain.chat_modelsimportinit_chat_model llminit_chat_model(modelgpt-4o-mini,model_provideropenai)tools[get_weather,search_tool]# 所有工具放列表里agentcreate_agent(modelllm,toolstools,system_prompt你是一个智能助手请根据用户需求调用合适的工具。)create_agent帮你封装了所有底层细节工具描述的自动生成和注入LLM 返回的工具调用指令的解析工具执行结果的回传循环控制什么时候继续调工具、什么时候结束六、调用 Agentinvoke 和 streaminvoke一次性拿结果resultagent.invoke({messages:[{role:user,content:今天北京的天气怎么样}]})print(result[messages][-1].content)stream观察每一步适合调试forstepinagent.stream({messages:[{role:user,content:今天北京的天气怎么样}]}):print(step,end\n\n)stream会依次展示LLM 第一次推理决定调天气工具→ 工具返回结果 → LLM 第二次推理生成最终回复。开发阶段用它排查问题特别好使。七、MCP像插 U 盘一样接入外部工具前面定义的tool工具都是写在自己项目里的本地工具。但很多时候你想用的工具是别人已经封装好的——比如查火车票、操作数据库、读取 GitHub 仓库。每个服务的接入方式不一样如果每接入一个都要写一套适配代码太累了。MCP模型上下文协议就是来解决这个问题的。它统一了 LLM 和外部工具之间的通信方式可以理解成 AI 领域的USB-C 标准。MCP 的工作流程Agent 启动时连接 MCP Server问你有哪些工具Server 返回工具列表工具名 描述 参数Agent 把这些工具描述和用户问题一起发给 LLMLLM 根本不知道这工具是本地的还是远程的LLM 决定调用某个工具传什么参数Agent 通过 MCP 协议把调用请求发给 ServerServer 执行并返回结果Agent 把结果给 LLM继续推理LangChain 接入 MCPfromlangchain_mcp_adapters.clientimportMultiServerMCPClient clientMultiServerMCPClient({my-local-tools:{transport:stdio,command:python,args:[mcp_server.py]},remote-tools:{transport:streamable_http,url:https://xxx.com/mcp}})toolsawaitclient.get_tools()# 自动获取所有工具agentcreate_agent(llm,tools)# 和本地工具一样用核心价值一个 Agent 可以同时挂载多个 MCP Server本地工具和远程工具混合使用。对 Agent 来说没有任何区别。八、记忆管理让 Agent 别失忆默认情况下Agent 每次调用都是独立的——它不记得上一轮说了什么。你上一句说我叫张三下一句问我叫什么名字它就懵了。LangChain 通过Checkpointer机制解决这个问题fromlanggraph.checkpoint.memoryimportInMemorySaver checkpointerInMemorySaver()agentcreate_agent(modelllm,toolstools,checkpointercheckpointer)每次调用结束后Checkpointer 自动保存本次对话的所有消息下次调用时自动加载历史消息拼接到新的输入前面。LLM 看到的就是历史消息 新消息自然就记住了。Thread ID 实现多会话隔离# 用户张三的会话agent.invoke({messages:[{role:user,content:我叫张三}]},config{configurable:{thread_id:user_zhangsan}})# 用户李四的会话完全独立agent.invoke({messages:[{role:user,content:我叫李四}]},config{configurable:{thread_id:user_lisi}})不同thread_id的对话历史互不干扰。九、中间件拦截器模式记忆功能解决了失忆问题但带来了新问题——对话轮次多了历史消息列表会无限增长。100 轮对话就是 200 条消息每次都发给 LLMToken 消耗扛不住。SummarizationMiddleware自动压缩历史消息fromlangchain.agents.middlewareimportSummarizationMiddleware middlewareSummarizationMiddleware(modelChatOpenAI(modelgpt-4o-mini),trigger(messages,100)# 消息达到100条时触发压缩)agentcreate_agent(modelllm,toolstools,middleware[middleware])压缩效果100 条消息 → 压缩成一段摘要系统消息 最近几条消息。Token 消耗大幅降低。HumanInTheLoopMiddleware人工审核高风险操作fromlangchain.agents.middlewareimportHumanInTheLoopMiddleware middlewareHumanInTheLoopMiddleware(interrupt_on{transfer_money:True,# 转账要审核delete_record:True,# 删除要审核get_weather:False# 查天气不需要})配置后Agent 调用这些工具时会暂停等人类确认后才真正执行。十、一些实用经验工具设计五原则单一职责一个工具只做一件事。get_weather和get_forecast分开别搞一个handle_weather_and_forecast_and_alert描述清晰LLM 完全靠描述决定什么时候用工具。获取指定城市今天的实时天气返回温度和天气状况比查天气强一百倍参数具体date: str Field(description日期格式 YYYY-MM-DD)比date: str好错误友好返回城市名’北精’无法识别你是否指’北京’比抛一个KeyError好幂等安全get_user(id123)调用多次结果一样create_order()调用多次会创建多个订单——后者要小心系统提示词怎么写好的系统提示词 角色定位 工作流程 约束条件 输出格式你是一个专业的数据分析助手。 工作流程 1. 理解用户的分析需求 2. 使用 search 工具获取相关数据 3. 使用 calculate 工具进行计算 4. 用简洁的语言呈现结果 注意事项 - 计算结果保留 2 位小数 - 如果数据不足主动告知用户 - 不要编造数据调试三板斧开启日志logging.basicConfig(levellogging.DEBUG)看每次 LLM 调用的输入输出LangSmith可视化追踪每一步工具选错、参数传错一目了然stream 代替 invoke实时观察 Agent 的每一步在想啥、在干啥大多数 Agent 问题的根源就三类工具描述不够清晰LLM 选错工具、系统提示词不够明确LLM 执行顺序乱、工具返回值格式不规范LLM 看不懂结果。优先从这三个方向排查。十一、总结Agent 的核心就三句话为什么需要 AgentChain 只能处理固定流程动态任务需要 Agent 的自主决策Agent 是什么LLM大脑 工具手脚 自主决策通过感知→推理→行动循环完成任务什么时候用流程确定用 Chain简单可靠需要动态判断用 Agent灵活但更复杂从 Model I/O 到 Chain 到 RAG 到 Agent我算是把 LangChain 的核心模块都摸了一遍。下一步打算学LangGraph——当 Agent 的流程越来越复杂、需要多个 Agent 协作的时候LangGraph 能提供更精细的控制。到时候再来分享。