
在上一篇文章中我们理解了 AI Agent 的本质——它是一个以目标为输入、在“决策—执行—观察”闭环中往复运行的程序。但这个闭环具体是怎么运转的Agent 怎么知道该做什么、怎么记住之前做了什么、怎么调用外部能力答案藏在规划Planning、记忆Memory、工具使用Tool Use 这三个核心模块里。它们相互融合、相互依赖共同对任务进行拆解得到可验证的子步骤。 本文深入拆解这三者并通过一个完整的代码实战帮你理解 Agent 的内部运作机制。一、规划模块任务拆解与推理规划是 Agent 的“大脑中枢”。 复杂任务通常不能一步到位。以“制定一份新能源汽车市场分析报告”为例Agent 需要自己判断怎么拆先收集市场数据再分析主要厂商然后梳理技术路线最后整合成报告。这个拆解过程不是靠写死流程而是靠规划模块动态生成。目前业界广泛采用的规划方法之一是 ReActReasoning Acting 。它的核心思路是让模型在一个循环中交替输出“思考”Thought、“行动”Action、“观察”Observation然后根据观察结果继续思考形成闭环。这种方式允许模型在执行过程中根据反馈修正自己的计划。ReAct 循环的完整流程textThought: 我需要先了解当前的数据情况Action: query_database(“SELECT * FROM sales WHERE quarter ‘Q3’”)Observation: 返回了 150 条销售记录Thought: 数据已获取现在需要分析下降原因Action: analyze_trend(data)Observation: 发现华东地区销售额下降了 30%Thought: 问题定位在华东地区需要进一步分析…其他常见的规划方法还包括 Chain-of-ThoughtCoT 和 Tree-of-ThoughtToT 但在实际工程中ReAct 的模式更接近真实执行场景因为它天然对接了工具调用。二、记忆模块短期、工作与长期记忆没有记忆的 Agent 每次都在“从零开始”。 Agent 的认知包括对话历史、工具输出以及在前面步骤中检索到的任何数据。记忆是实现一致性的关键当用户说“实际上这是错误的颜色”时Agent 知道“它”指的是前面讨论的项目。Agent 的记忆系统分为三个层次短期记忆通常由框架自动管理。以 GitHub Copilot SDK 为例它通过跟踪会话中的聊天历史记录自动管理短期内存。对于可能超过模型上下文窗口的会话SDK 的“无限会话”功能会压缩较旧的上下文以防止令牌溢出同时保留基本信息。长期记忆需要显式实现。常见方案是将重要信息嵌入为向量存储在向量数据库中在需要时通过语义检索召回。这是 RAG检索增强生成的基础设施。三、工具使用Agent 真正能“干活”的关键LLM 本身无法直接操作外部系统它只能输出文本。 要让 Agent 执行具体操作必须引入工具调用Function Calling 机制。工具是 Agent 在其推理过程中可以调用的外部函数或 API。每个工具都表示 Agent 可以执行的特定操作查找数据库记录、调用 REST API、发送电子邮件或运行诊断命令。设计工具集的关键原则每个工具都应很好地执行一项操作并提供清晰的名称和说明帮助 AI 模型了解何时使用它。你希望为 Agent 提供足够有用的工具但不要过多以免让其困惑或不堪重负。工具的规划器协调机制是规划器决定何时调用工具、何时提出澄清问题、何时生成最终答案。现代 AI Agent 使用 ReAct 循环在思考LLM 建议一个步骤和行动调用工具之间交替。四、生产级 Agent 的关键设计原则从工程落地的视角一个生产级 Agent 需要遵循以下设计原则结构化输出Agent 的工具调用和最终响应都应遵循明确的 Schema便于程序化解析和验证。多级记忆不要把所有信息都塞进上下文窗口。短期记忆用消息列表工作记忆用状态对象长期记忆用向量检索。幂等工具调用同一个工具调用重复执行不应产生副作用。这对重试和错误恢复至关重要。全链路可观测性每一步的思考、行动、观察都应被记录和追踪便于调试和优化。五、实战用 ReAct 模式实现一个最简单的 Agent以下代码展示了 ReAct 模式的核心逻辑伪代码风格聚焦理解importjsonclassSimpleAgent:def__init__(self,llm,tools):self.llmllm self.tools{t.name:tfortintools}self.memory[]# 短期记忆对话历史defrun(self,goal:str,max_steps:int10)-str:执行 ReAct 循环直到任务完成或达到最大步数contextf目标:{goal}\n\nforstepinrange(max_steps):# 1. 思考 行动决策promptself._build_prompt(context)responseself.llm.invoke(prompt)# 2. 解析 LLM 的输出thoughtresponse.get(thought,)actionresponse.get(action)action_inputresponse.get(action_input,{})contextfThought:{thought}\n# 3. 判断是否完成ifactionfinish:returnaction_input.get(answer,thought)# 4. 执行工具ifactioninself.tools:try:observationself.tools[action].execute(**action_input)exceptExceptionase:observationf工具执行错误:{e}else:observationf未知工具:{action}# 5. 将观察结果追加到上下文这就是记忆contextfAction:{action}({action_input})\ncontextfObservation:{observation}\n\nself.memory.append((thought,action,observation))return达到最大步数限制任务未完成def_build_prompt(self,context:str)-str:tool_descriptions\n.join(f-{name}:{tool.description}forname,toolinself.tools.items())returnf{context}可用工具:{tool_descriptions}finish: 任务完成时调用传入最终答案请输出 JSON 格式:{{“thought”: “你的思考”, “action”: “工具名或finish”, “action_input”: {{…}}}}“”代码要点run() 方法是 ReAct 循环的核心每一步都执行“思考→行动→观察”。context 变量就是工作记忆随着每一步的执行不断累积。self.memory 是短期记忆记录完整的决策历史。工具调用结果作为 Observation 追加到上下文供下一步决策使用。max_steps 是防止死循环的安全护栏。六、三者的协作关系铁三角规划、记忆、工具使用不是三个独立模块而是相互依赖的铁三角规划依赖记忆没有记忆规划无法知道之前做过什么、结果如何。记忆依赖工具工具调用的输出是记忆的重要内容来源。工具依赖规划没有规划Agent 不知道何时该调用哪个工具。规划依赖工具工具的能力边界决定了规划的可能性空间。三者共同对任务进行拆解得到可验证的子步骤并在“决策—执行—观察”的闭环中持续迭代。七、小结规划模块用 ReAct 模式实现“思考→行动→观察”循环动态生成任务拆解。记忆模块短期记忆对话历史、工作记忆任务状态、长期记忆向量检索三层协作。工具使用通过 Function Calling 让 Agent 真正能“干活”工具设计遵循“一个工具一个目标”原则。关键设计原则结构化输出、多级记忆、幂等工具调用、全链路可观测性。铁三角协作规划、记忆、工具三者相互依赖共同驱动 Agent 的自主执行闭环。