在上文《Agent 原理与构建上 —— 从零打造极简版 Agent》中我们介绍了什么是 AgentAgent 的几种模式并且从零开始搭建了一个极简版的 Agent然而留下了一些坑还没填上。先快速回顾一下上文首先Agent 的基本架构有四个核心组件LLM、工具、记忆、规划模块LLM是整个系统的大脑负责理解任务和做决策工具让 Agent 能跟外部世界交互、搜索、执行代码等记忆让 Agent 在任务执行过程中保持状态不会「失忆」并且还可划分为短期记忆和长期记忆规划模块负责把复杂目标拆解成可执行的步骤。这四个组合在一起才让 Agent 具备了自主完成任务的能力。然后介绍了 Agent 的两种工作模式ReAct 和 Plan-and-Execute。ReAct每走一步就根据当前结果重新思考下一步该做什么好处是灵活性极高能根据实际情况随时调整缺点是容易「走偏」有时候会忽略整体目标。Plan-and-Execute先让 LLM 输出一个完整的步骤列表然后按顺序逐步执行。好处是整体结构清晰能在执行前就看到完整计划缺点是如果中间某一步的结果和预期不一样原来的计划可能就需要重新调整。在实际工程里往往会把两种模式结合起来先做一个粗略的计划确定大方向执行过程中再根据反馈动态微调。这篇文章就来填补上文留下的 2 个坑重复造轮子流程的不确定性。1、什么是 LangChain无论使用 ReAct 或 Plan-and-Execute 哪种方式来开发 Agent我们都无需像上文一样从零开始实际上这套框架早就有人封装好了无需重复造轮子这套框架就是 LangChain。LangChain 是一套面向 LLM 应用的可组合抽象层其核心理念是将大模型调用、提示词管理、外部工具对接、记忆存储、数据检索等 AI 应用开发的核心环节拆解为标准化的组件与协议让开发者以声明式的方式快速拼装复杂工作流而非从零开始编写重复的代码。安装pip install -U langchain # Requires Python 3.10安装完成后在上一篇文章动手实现一个 ReAct Agent 就可以使用下面的代码来实现。之前代码里自己实现的几件事调用大模型维护 messages 历史识别工具调用执行工具把工具结果塞回历史里继续下一轮不是自己手写了而是交给 LangChain LangGraph runtime 代劳了。所以整体代码如下。def build_langchain_agent(model_name: str): model init_chat_model( modelmodel_name, model_provideropenai, base_urlCHAT_BASE_URL, api_keyCHAT_API_KEY, temperature0, ) tools [read_file, write_to_file, run_terminal_command_with_confirm] system_prompt render_system_prompt() return create_agent( modelmodel, toolstools, system_promptsystem_prompt, ) def main(): task input(请输入任务) inputs {messages: [{role: user, content: fquestion{task}/question}]} print(\n Initial Input ) print(inputs) agent build_langchain_agent(DEFAULT_MODEL) # 使用 stream 可以逐步看到模型消息和工具调用过程。 for step, chunk in enumerate(agent.stream(inputs, stream_modevalues), start1): # 每个 chunk 都包含当前累计的 messages这里只打印“最新新增”的那一条。 messages chunk.get(messages, []) if not messages: continue if final_chunk is None or not final_chunk.get(messages): raise RuntimeError(Agent 未返回任何消息。) # 最后一条消息通常就是最终 AI 回复若仍保留 XML 标签这里会提取最终答案内容。 final_message final_chunk[messages][-1] print(f\n✅ 最终答案{final_message})历史消息维护是create_agent()内部完成的。它会自动做这些事把 system prompt 放进上下文把 user message 加进去模型返回 AIMessage 后追加进历史如果 AIMessage 里有 tool call执行工具把 ToolMessage 追加进历史再把更新后的历史发给模型这样只需要把注意力放在业务逻辑上底层已经封装好了无需关注模型怎么调用消息怎么返回工具如何处理这些琐碎的事情了。2、Agent 的不确定性到这里还有个很重要的问题——不确定性。普通代码的每一步都是开发者预先写好的但 Agent 的执行路径是 LLM 实时决定的可以让它完成复杂的但事先根本没法预测路径的任务。同样的任务今天跑和明天跑或者说调了不同的工具就会走不同的路径甚至得到不同的结果。这是因为 LLM 本质上是个概率模型每次生成都带有随机性。也就是说Agent 的行为是不确定的。如果某次跑出来的结果有错很难复现它当时的执行路径来排查问题。所以在生产环境里很多团队会给 Agent 加上详细的执行日志记录每一步的思考过程和工具调用结果方便事后追溯。3、工作流工作流 Workflow 是上层的编排框架把 Agent、LLM、Tools 组织成一条确定性流程每个节点做什么、按什么顺序流转都是开发者事先写死的。把整个执行流程的「骨架」写在代码里LLM、Agent、Tools 都只是这个流程里的「节点」每个节点负责完成自己那一步但整体走哪条路、下一步去哪里全由开发者的代码决定不是任何节点自己说了算。Workflow 最大的优点是可预测、可控、好调试。在代码里看到什么它就做什么不会有任何「惊喜」。生产环境里出了问题可以打断点逐步追精确定位是哪个节点出了故障。这种确定性在线上系统里非常珍贵。在真实的场景里工具、Agent、工作流三者通常是同时存在、相互嵌套的完全靠 Agent 自主决策的系统其实很少在生产环境里出现原因很现实行为太难控制一旦出问题很难排查成本也容易失控。完全靠 Workflow 写死 的系统又太脆因为你没法把所有情况都穷举到代码里遇到预料之外的输入就容易失败或者给出很差的结果。所以目前生产环境里最主流的模式是**「Agentic Workflow」**用 Workflow 固定主流程的骨架在需要灵活判断的节点嵌入 Agent其余固定节点直接用 LLM 或 Tools。 骨架是确定的整体行为是可控的、便于调试关键节点是灵活的能应对各种复杂情况。两个优点都有两个缺点都被削弱了。4、总结一路走下来这篇最核心的收获其实可以凝练成这么几条体感能交给框架的就别自己从头写。像 LangChain 这类工具已经把模型调用、消息历史维护、工具执行这些脏活累活都封装好了我们只需要把注意力牢牢放在业务逻辑上。用 Workflow 把不可控变成可控。纯 Agent 模式太野那我们就用代码把执行骨架固定下来让每一步的走向都明明白白系统从“我看它怎么想”变成“我让它怎么做”。最好的落地姿势是把二者揉在一起。也就是 Agentic Workflow整体骨架是死的、可预测的只在真正需要灵活决策的节点放 Agent。这样既不会因为过度死板而脆弱又不会因为过度灵活而失控。说到底生产环境里的 Agent 从来不是要造一个全知全能的神而是用一套务实的工程手段把智能的灵活性和系统的确定性恰到好处地焊在一起。