从零构建AI Agent:基于ReAct框架的文本处理助手实践指南
1. 从概念到代码一个AI Agent的诞生之旅最近在技术社区里“AI Agent”这个词的热度居高不下几乎成了每个技术讨论的必谈话题。从LangChain的ReactAgent Demo到Hermes Agent的安装教程再到各种关于Agent框架和开发心得的分享无不显示出开发者们对构建智能、自主的AI应用的浓厚兴趣。但说实话很多文章要么停留在高屋建瓴的概念阐述要么就是直接甩出一段复杂的代码对于“如何从零开始设计并实现一个能真正跑起来的Agent Demo”这个核心问题往往语焉不详。今天我就结合自己最近的一个小项目实践来聊聊这个话题。我们不谈那些宏大的架构就从最朴素的需求出发设计一个能理解任务、使用工具、并持续学习的简单Agent并把它实现成一个可以运行的Demo。这个过程就像搭积木关键在于理解每一块积木的作用和拼接逻辑。这个Demo的目标很明确我们要构建一个能够处理自然语言指令的文本处理助手。比如用户说“请总结一下这篇文章的核心观点并检查其中是否有拼写错误”我们的Agent需要能拆解这个指令依次调用“文本总结”和“拼写检查”两个工具最后将结果整合返回给用户。这听起来简单但背后涉及了任务规划、工具调用、记忆管理和执行控制等多个核心环节。通过实现这个Demo你不仅能对Agent的工作机制有直观的理解更能掌握一套可复用的开发模式为后续开发更复杂的智能体应用打下坚实基础。无论你是对AI应用开发感兴趣的初学者还是想深入理解Agent内部机制的中级开发者这篇手把手的实践指南都会对你有所帮助。2. 核心设计厘清Agent的四大支柱在动手写代码之前我们必须先想清楚设计。一个功能完整的Agent其核心可以抽象为四个相互协作的组件大脑规划器、记忆体、工具箱和执行引擎。这个设计模式脱胎于ReActReasoning Acting等经典框架但我们在实现时会做适当的简化和聚焦确保Demo足够轻量且易于理解。2.1 大脑规划器任务拆解与决策中枢规划器是Agent的“大脑”负责理解用户的原始指令并将其分解成一系列可执行的子步骤。在我们的文本处理助手场景中当用户输入“总结并检查拼写”时一个简单的规划器需要做两件事意图识别和任务序列生成。首先意图识别。我们不能指望大语言模型LLM每次都能完美输出结构化的任务列表。更稳健的做法是让LLM根据我们预定义的工具列表来判断当前指令需要用到哪些工具。例如我们可以设计一个提示词Prompt让LLM以JSON格式输出包含required_tools所需工具列表和next_action下一步动作说明字段。这样我们就将开放性的自然语言指令转化为了结构化的、程序可处理的数据。其次任务序列生成。对于简单的线性任务“总结”和“检查拼写”有明确的先后顺序必须先有文本才能检查拼写规划器需要能识别这种依赖关系。在Demo中我们可以实现一个简单的规则引擎如果任务列表中包含“总结”则将其排在“检查拼写”之前。对于更复杂的场景则可以引入基于图的规划让LLM或专门的规划模型来推理步骤间的依赖。注意规划器的设计直接决定了Agent的智能上限和稳定性下限。一个常见的坑是过度依赖LLM的自由发挥导致输出格式不稳定进而使程序解析失败。因此强制结构化输出如JSON并使用Pydantic等库进行验证和重试是保证规划环节鲁棒性的关键技巧。2.2 记忆体对话历史与工具结果的暂存区记忆体让Agent有了“上下文”的概念。它主要存储两类信息对话历史Memory和工具执行结果Intermediate State。对话历史确保了Agent在多轮对话中能保持连贯性。例如用户先说“请总结这段文字”Agent执行后用户又说“把它翻译成英文”这时Agent需要知道“它”指代的就是上一步的总结结果。在Demo中我们可以实现一个简单的窗口记忆只保留最近N轮的用户-助手对话对既节省上下文长度又保留了必要的连贯性。工具执行结果的暂存则更为关键。当规划器将任务分解为“总结-检查拼写”后第一步“总结”工具的输出即总结后的文本需要被妥善地传递给第二步“检查拼写”工具作为输入。我们可以在内存中维护一个键值对存储例如{summary_result: 这里是总结的文本...}。每个工具执行完毕后都将其输出以约定的键名存入这个存储区后续工具按需读取。这就构成了Agent执行过程中的“工作记忆”。2.3 工具箱Agent能力的扩展插座工具箱是Agent与外部世界交互的接口。每个工具都是一个独立的函数有明确的输入、输出和功能描述。在我们的Demo里我们需要两个工具文本总结工具输入是一段长文本输出是总结后的核心观点。拼写检查工具输入是一段文本输出是标注了可能错误及建议修改的文本。工具的设计有几个要点。第一功能描述要清晰准确这部分描述会被拼接到给LLM的提示词中帮助规划器判断何时调用该工具。第二输入参数的定义要规范最好使用类型注解便于后续的自动验证和绑定。第三工具的实现可以很简单初期甚至可以用规则或调用现有API如开源的文本处理库来模拟重点是先跑通流程。工具箱的设计遵循“高内聚、低耦合”的原则。每个工具只做好一件事并且不依赖其他工具的内部状态。这样后续扩展新功能比如增加“情感分析”工具就会非常容易只需定义新函数并注册到工具箱即可。2.4 执行引擎串联一切的调度循环执行引擎是Agent的“心脏”它驱动着整个工作流的运转。其核心是一个循环我们称之为“思考-行动-观察”循环这正是ReAct模式的核心思想。思考引擎将当前的用户问题、对话历史、可用工具列表和工作记忆中的中间结果组合成一个完整的提示词提交给LLM即规划器。LLM经过“思考”输出一个结构化的决策例如{action: call_tool, tool_name: text_summarizer, tool_input: {text: ...}}或者{action: final_answer, response: ...}。行动引擎解析LLM的决策。如果是调用工具则根据tool_name从工具箱中找到对应的函数并将tool_input参数绑定后执行。观察工具执行后会产生结果或错误。引擎将这个结果以特定的格式如Observation: 工具执行结果...更新到工作记忆中同时也可能将其追加到对话历史中为下一轮“思考”提供新的上下文。循环或终止引擎判断是否继续。如果LLM决策是final_answer或者工具调用达到了最大步数限制则循环终止将最终答案返回给用户否则回到步骤1开始新一轮的“思考”。这个循环机制赋予了Agent自主性和适应性。它可以根据上一步工具执行的结果动态地决定下一步做什么而不是僵化地执行一个预设的脚本。3. 实战构建用Python实现文本处理助手Agent理论说得再多不如一行代码。接下来我们就用Python一步步实现上面设计的文本处理助手Agent。我们将尽量使用轻量级的库核心逻辑自己实现以便你能透彻理解每一个环节。3.1 项目初始化与环境配置首先创建一个新的项目目录并初始化虚拟环境这是保证依赖隔离的好习惯。mkdir text_agent_demo cd text_agent_demo python -m venv venv # Windows: venv\Scripts\activate # Mac/Linux: source venv/bin/activate接着安装核心依赖。我们将使用openai库来调用大语言模型你也可以替换为其他兼容OpenAI API的模型服务使用pydantic来做数据验证和设置管理。pip install openai pydantic python-dotenv在项目根目录创建.env文件用于安全地存储你的OpenAI API密钥。OPENAI_API_KEY你的_api_key_here OPENAI_BASE_URL你的_api_base_url如果使用第三方兼容服务然后创建主要的项目文件结构text_agent_demo/ ├── .env ├── main.py # 主程序入口 ├── agent/ │ ├── __init__.py │ ├── core.py # Agent核心类规划器、执行引擎 │ ├── memory.py # 记忆体相关类 │ ├── tools.py # 工具箱定义 │ └── schemas.py # Pydantic数据模型 └── utils/ └── llm_client.py # LLM客户端封装3.2 定义数据模型与LLM客户端在schemas.py中我们定义整个Agent通信所用的数据结构。使用Pydantic可以确保数据格式正确并在解析失败时提供清晰的错误信息。from pydantic import BaseModel, Field from typing import List, Optional, Any, Literal class Tool(BaseModel): 工具定义模型 name: str Field(description工具的唯一名称) description: str Field(description工具功能的清晰描述用于提示词) args_schema: dict Field(description工具参数的JSON Schema定义) class AgentAction(BaseModel): Agent单步决策模型 thought: str Field(descriptionAgent当前的思考过程) action: Literal[call_tool, final_answer] Field(description下一步动作类型) tool_name: Optional[str] Field(defaultNone, description要调用的工具名当action为call_tool时必需) tool_input: Optional[dict] Field(defaultNone, description工具的输入参数) response: Optional[str] Field(defaultNone, description直接给用户的最终回答当action为final_answer时必需)在llm_client.py中我们封装一个简单的LLM调用客户端。这里的关键是构建一个支持结构化输出的调用函数。import os from openai import OpenAI from dotenv import load_dotenv from agent.schemas import AgentAction import json load_dotenv() class LLMClient: def __init__(self, model: str gpt-3.5-turbo): self.client OpenAI( api_keyos.getenv(OPENAI_API_KEY), base_urlos.getenv(OPENAI_BASE_URL, https://api.openai.com/v1) ) self.model model def get_structured_response(self, prompt: str) - AgentAction: 调用LLM并强制其以指定JSON格式返回 try: response self.client.chat.completions.create( modelself.model, messages[{role: user, content: prompt}], temperature0.1, # 低温度保证输出稳定性 response_format{type: json_object} # 关键强制JSON输出 ) result json.loads(response.choices[0].message.content) # 使用Pydantic模型验证和解析 return AgentAction(**result) except json.JSONDecodeError as e: print(fLLM返回了非JSON内容解析失败: {e}) # 这里可以加入重试逻辑 raise3.3 实现工具箱与记忆体在tools.py中我们实现两个简单的工具。在实际项目中这些工具可以替换为更强大的模型或API。from agent.schemas import Tool import re def text_summarizer(text: str, max_length: int 150) - str: 一个简单的基于规则的文本总结器Demo用。实际应用中应替换为LLM或专用模型。 # 这里仅作演示取前两句话作为总结 sentences re.split(r[.!?], text) summary .join(sentences[:2]).strip() if len(summary) max_length: summary summary[:max_length-3] ... return summary def spell_checker(text: str) - str: 一个简单的拼写检查模拟器。实际应用中可接入LanguageTool等库。 # 模拟检查将连续重复的字母标记为可能错误 import re def highlight(match): return f[可能拼写错误: {match.group(0)}] checked_text re.sub(r(\w)\1{2,}, highlight, text) # 查找连续出现3次及以上的字母 if checked_text text: return 文本中未发现明显的拼写错误。 else: return f检查完成。修改建议如下\n{checked_text} # 工具定义包含供LLM识别的描述和参数模式 TOOLS { text_summarizer: Tool( nametext_summarizer, description对输入的长文本进行核心观点总结。, args_schema{ type: object, properties: { text: {type: string, description: 需要总结的原始文本} }, required: [text] } ), spell_checker: Tool( namespell_checker, description检查输入文本中可能存在的拼写错误并给出提示。, args_schema{ type: object, properties: { text: {type: string, description: 需要检查拼写的文本} }, required: [text] } ) }在memory.py中我们实现一个简易的记忆体。from typing import List, Dict, Any class WorkingMemory: 工作记忆存储工具执行的中间结果 def __init__(self): self.storage: Dict[str, Any] {} def set(self, key: str, value: Any): self.storage[key] value def get(self, key: str, defaultNone): return self.storage.get(key, default) def clear(self): self.storage.clear() class ConversationMemory: 对话记忆存储最近的对话历史 def __init__(self, max_turns: int 5): self.history: List[Dict[str, str]] [] self.max_turns max_turns def add_interaction(self, user_input: str, agent_response: str): self.history.append({user: user_input, assistant: agent_response}) # 保持历史记录不超过最大轮数 if len(self.history) self.max_turns: self.history.pop(0) def get_formatted_history(self) - str: 将历史格式化为字符串用于构建提示词 lines [] for turn in self.history: lines.append(fUser: {turn[user]}) lines.append(fAssistant: {turn[assistant]}) return \n.join(lines)3.4 组装核心Agent与执行引擎最核心的部分在core.py这里我们将规划器和执行引擎合二为一实现主循环。from agent.schemas import AgentAction, Tool from agent.memory import WorkingMemory, ConversationMemory from utils.llm_client import LLMClient from agent.tools import TOOLS from typing import Dict, Callable, Any import json class SimpleAgent: def __init__(self, llm_client: LLMClient, max_steps: int 10): self.llm llm_client self.working_memory WorkingMemory() self.conversation_memory ConversationMemory() self.tools: Dict[str, Callable] self._load_tools() # 工具名到函数的映射 self.tool_definitions TOOLS # 工具定义用于提示词 self.max_steps max_steps def _load_tools(self) - Dict[str, Callable]: 加载工具函数。这里硬编码实际可从模块动态导入。 from agent.tools import text_summarizer, spell_checker return { text_summarizer: text_summarizer, spell_checker: spell_checker, } def _build_prompt(self, user_input: str) - str: 构建给LLM的提示词。这是Agent智能的关键所在。 # 1. 系统角色设定 system_role 你是一个专业的文本处理助手。你的任务是根据用户请求规划并调用合适的工具来解决问题。你必须严格按照指定的JSON格式回应。 # 2. 工具描述 tools_desc [] for tool in self.tool_definitions.values(): tools_desc.append(f- {tool.name}: {tool.description} 参数格式: {json.dumps(tool.args_schema, ensure_asciiFalse)}) tools_text \n.join(tools_desc) # 3. 工作记忆中间结果 working_memory_text if self.working_memory.storage: working_memory_text 当前已有的中间结果\n \n.join([f{k}: {v} for k, v in self.working_memory.storage.items()]) # 4. 对话历史 history_text self.conversation_memory.get_formatted_history() # 5. 输出格式指令 format_instruction 你必须以以下JSON格式回应且只包含这个JSON对象 { thought: 你的推理思考过程分析当前情况、可用工具和下一步计划。, action: call_tool 或 final_answer, tool_name: 当action为call_tool时填写工具名, tool_input: {arg1: value1} // 当action为call_tool时填写工具参数对象 response: 当action为final_answer时填写给用户的最终回答 } 注意tool_input必须严格匹配对应工具的参数格式。 # 组合成最终提示词 prompt f{system_role} 你可以使用的工具 {tools_text} {working_memory_text} 对话历史 {history_text} 当前用户请求{user_input} {format_instruction} return prompt def run(self, user_input: str) - str: 执行Agent的主循环 print(f\n[用户输入] {user_input}) step 0 final_response None while step self.max_steps: step 1 print(f\n--- 步骤 {step} ---) # 1. 思考调用LLM进行规划 prompt self._build_prompt(user_input) print(f[思考提示词] (已省略)) try: decision: AgentAction self.llm.get_structured_response(prompt) except Exception as e: return f调用规划器时出错{e} print(f[Agent思考] {decision.thought}) # 2. 行动根据决策执行 if decision.action final_answer: final_response decision.response print(f[最终回答] {final_response}) break # 循环终止 elif decision.action call_tool: tool_name decision.tool_name tool_input decision.tool_input or {} if tool_name not in self.tools: error_msg f错误工具 {tool_name} 不存在。 print(error_msg) # 将错误信息存入工作记忆让LLM在下轮知晓 self.working_memory.set(last_error, error_msg) continue print(f[调用工具] {tool_name}, 输入: {tool_input}) try: # 执行工具 tool_func self.tools[tool_name] result tool_func(**tool_input) observation f工具 {tool_name} 执行成功。结果{result} print(f[工具结果] {result}) # 3. 观察将结果存入工作记忆键名可以约定为工具名_result self.working_memory.set(f{tool_name}_result, result) # 同时也可以将本次观察以固定格式暂存供下次提示词使用 self.working_memory.set(last_observation, observation) except Exception as e: error_msg f调用工具 {tool_name} 时出错{e} print(error_msg) self.working_memory.set(last_error, error_msg) else: error_msg f无法识别的决策动作{decision.action} print(error_msg) self.working_memory.set(last_error, error_msg) # 循环结束处理 if final_response is None: final_response f已达到最大执行步数({self.max_steps})未能得出最终答案。 print(final_response) # 将本轮最终交互存入对话历史 self.conversation_memory.add_interaction(user_input, final_response) # 清理工作记忆为下一轮对话准备或选择性保留 self.working_memory.clear() return final_response3.5 运行与测试见证Agent的自主工作流最后在main.py中我们将所有部分组装起来并运行一个测试。from utils.llm_client import LLMClient from agent.core import SimpleAgent def main(): # 1. 初始化LLM客户端 llm_client LLMClient(modelgpt-3.5-turbo) # 或 gpt-4 # 2. 创建Agent agent SimpleAgent(llm_client, max_steps6) # 3. 测试用例 test_text 人工智能代理AI Agent是一种能够感知环境、自主决策并执行行动以实现目标的软件实体。近年来随着大语言模型LLM能力的突破基于LLM的Agent成为了研究热点。这类Agent利用LLM强大的理解和生成能力进行任务规划、工具调用和反思从而完成复杂的任务。然而其稳定性、可靠性和安全性仍是亟待解决的挑战。 user_query f请总结一下这段话并检查总结后的文本有没有拼写错误。原文{test_text} print(*50) print(启动文本处理助手Agent Demo) print(*50) response agent.run(user_query) print(\n *50) print(最终返回给用户的结果) print(response) print(*50) if __name__ __main__: main()运行python main.py你将在控制台看到Agent的完整思考和执行过程。它会先规划出需要调用text_summarizer总结完成后将结果存入工作记忆然后在下一轮规划中发现还需要调用spell_checker并且从工作记忆中取出上一步的总结结果作为输入最后给出最终答案。4. 从Demo到生产关键优化与扩展方向一个能跑通的Demo只是起点。要让这个Agent变得真正可靠、强大我们还需要在以下几个关键方向上进行优化和扩展。这些也正是当前Agent开发中的核心挑战和热门研究方向。4.1 规划器的稳定性强化超越简单提示词我们Demo中的规划器完全依赖LLM和精心设计的提示词。这在简单场景下有效但面对复杂、多步骤或模糊的指令时容易出错。强化规划器有几种常见策略多步规划与验证不让LLM一次性规划所有步骤而是采用“逐步规划即时验证”的策略。规划器每次只规划下一步动作执行后根据结果再规划下一步。这降低了单次规划的复杂度同时引入了环境反馈使规划更具适应性。我们的Demo循环已经体现了这一思想。规划结果的后处理与纠错即使LLM输出了结构化JSON也可能存在字段缺失、类型错误或逻辑矛盾如要求调用一个不存在的工具。我们需要在解析后增加一个“验证与修补”层。例如使用Pydantic的validator装饰器对AgentAction模型进行自定义验证或者当解析失败时自动触发一个“纠错”子流程将错误信息反馈给LLM要求它重新生成。引入规划模板与约束对于特定领域的常见任务如数据分析、客服对话可以预先定义任务流程模板。规划器的工作变为“填空”和“选择路径”而非完全自由生成这能极大提高稳定性和可控性。例如对于“数据获取-清洗-分析-可视化”这类任务可以固化流程让LLM只负责确定每个步骤的具体参数。4.2 工具生态的构建与管理工具箱是Agent能力的边界。一个强大的Agent离不开一个丰富、可靠的工具集。工具的动态发现与注册在Demo中我们是在代码中硬编码了工具。在生产环境中需要一套机制让工具能方便地注册和发现。可以设计一个工具注册中心每个工具作为一个独立的模块或服务在启动时向Agent注册自己的名称、描述、参数模式和执行端点。Agent在规划时可以动态地从注册中心拉取可用的工具列表。工具的组合与流水线有些复杂任务需要多个工具以特定顺序和方式组合。我们可以引入“复合工具”或“工作流”的概念。例如定义一个“生成报告”的复合工具它内部按顺序调用了“数据查询”、“图表生成”和“文档排版”三个基础工具。这允许我们在更高层次上抽象和复用能力。工具执行的安全与沙箱允许Agent任意调用外部工具存在安全风险如执行危险命令、访问敏感数据。必须为工具执行设计沙箱环境进行权限控制、输入过滤和资源隔离。对于执行不可信代码的工具如Python解释器尤其需要严格的沙箱机制。4.3 记忆系统的演进从短期到长期Demo中的记忆系统是短暂且简单的。复杂的Agent需要更强大的记忆能力。短期记忆与长期记忆的分离短期记忆如我们的WorkingMemory处理当前任务的上下文容量小但存取快。长期记忆则用于存储跨会话的知识、用户偏好、历史经验等通常需要向量数据库或传统数据库来支持。当Agent遇到新任务时可以先从长期记忆中检索相关经验来辅助规划。记忆的向量化与检索将对话历史、工具执行结果等文本信息通过嵌入模型Embedding Model转化为向量存入向量数据库如Chroma、Weaviate。当需要相关记忆时通过计算向量相似度进行语义检索而不是简单的关键词匹配。这使得Agent能更“智能”地联想到过去的经验。反思与记忆提炼Agent不应只是被动地存储记忆还应主动地对经历进行“反思”。例如在一个任务成功或失败后可以触发一个反思步骤让LLM分析成功的关键或失败的原因并将这些分析结论以结构化的形式如“在什么情况下使用A工具比B工具更好”存入长期记忆。这实现了Agent的持续学习。4.4 执行引擎的健壮性保障执行引擎是Agent的骨架必须健壮。错误处理与重试机制工具调用可能因网络、权限、输入无效等原因失败。引擎不能因此崩溃。我们需要为每个工具调用包裹完善的try-except并根据错误类型决定重试、切换备用工具还是将错误信息反馈给规划器让其调整计划。例如调用一个外部API失败可以重试2次如果仍然失败则尝试调用一个功能相似的备用API。超时与中断控制防止Agent陷入死循环或长时间无响应。必须设置每一步思考和执行的最大耗时以及整个任务的最大步数我们的max_steps参数就是干这个的。当超时或达到步数上限时优雅地终止任务并向用户返回当前进度和失败原因。执行过程的透明与可解释性对于用户或开发者来说Agent不应该是一个黑箱。引擎需要详细记录每一步的思考、决策、行动和观察形成完整的执行轨迹Execution Trace。这个轨迹对于调试、优化和向用户解释Agent的行为至关重要。我们的Demo中在控制台的打印输出就是一种简单的轨迹记录。5. 避坑指南Agent开发中的常见陷阱与应对结合我自己的实践和社区常见的讨论在Agent开发中以下几个坑几乎每个人都会遇到提前了解可以节省大量调试时间。5.1 提示词工程精确与泛化的平衡提示词是驱动LLM型Agent的“燃料”。一个常见的误区是追求一个“万能”的提示词希望它能处理所有情况。这往往导致提示词过于复杂、矛盾效果反而下降。问题表现Agent行为不稳定时而有效时而胡言乱语对于边界情况处理能力差响应速度慢因为提示词太长。解决策略采用“分层提示”和“上下文压缩”。将系统指令、工具描述、历史记忆、当前查询分开管理。系统指令保持稳定和精简只描述核心角色和规则。工具描述可以动态注入只包含当前步骤可能用到的工具。对于长对话历史不要全部塞进上下文而是进行摘要压缩只保留最相关的部分。此外为不同类型的任务准备不同的提示词模板而不是试图用一个模板解决所有问题。5.2 工具描述的“语义鸿沟”LLM通过工具的描述文本来理解工具功能。如果描述不准确或存在歧义就会导致“工具调用错误”——即LLM理解了任务但选择了错误的工具或传错了参数。问题表现Agent频繁调用不相关的工具工具参数总是填错LLM在应该调用工具时却选择了直接回答。解决策略首先工具描述要具体、无歧义。避免使用“处理数据”、“操作文件”这种模糊描述而是用“读取CSV文件的前10行并返回表头”、“将字符串中的所有单词转换为小写”这样精确的描述。其次提供丰富的示例。在给LLM的工具描述中可以附带1-2个调用该工具的示例输入和输出这比纯文字描述有效得多。最后建立工具调用验证层。在真正执行工具前先用一个轻量级的规则或模型检查tool_name和tool_input的合理性比如检查必填参数是否存在参数类型是否大致匹配。5.3 循环失控与“思维漩涡”Agent陷入无限循环反复执行相同的几个步骤而无法推进或者在一个无关紧要的细节上不断“思考”却不出结果这种现象被称为“思维漩涡”。问题表现控制台日志显示相同的工具被反复调用Agent的“思考”内容越来越偏离主题达到最大步数后任务失败。解决策略第一设置清晰的终止条件。除了最大步数还可以定义任务成功的明确标准如生成了最终答案、得到了用户确认并在提示词中告诉LLM。第二在工作记忆中引入“禁止重复”机制。记录最近N步已执行的动作如果规划器再次生成相同的动作则予以否决并强制其尝试新路径。第三设计“反思-调整”步骤。在循环中定期如每3步插入一个强制反思节点让LLM评估当前进展是否偏离目标并重新规划剩余步骤。这相当于给Agent一个“暂停并重新评估”的机会。5.4 上下文长度的管理与优化LLM有上下文窗口限制如4K、8K、128K tokens。Agent的对话历史、工具描述、中间结果都在消耗这个窗口。当上下文耗尽时最久远的信息会被丢弃可能导致Agent“失忆”。问题表现在多轮复杂交互后Agent忘记了早期的关键指令响应时间变长成本增加。解决策略核心是选择性记忆和记忆摘要。不是所有信息都需要原封不动地保存在上下文中。对于久远的对话可以用LLM生成一个简短的摘要来替代原始记录。对于工具执行产生的大量中间数据如一大段文本、一个表格可以只存储其引用或关键结论而不是全部内容。此外可以采用“滑动窗口”记忆只保留最近最相关的若干轮交互。对于超长文档处理则需要使用RAG检索增强生成技术只将与当前问题最相关的片段放入上下文。实现这个Demo的过程就像亲手搭建了一个会思考、会使用工具的机械小人。你清晰地看到了“规划-行动-观察”这个核心循环是如何一步步运转的也体会到了提示词设计、工具封装、记忆管理这些细节如何共同决定了Agent的智能程度和稳定性。这只是一个起点但掌握了这个基本框架你就拥有了理解和构建更复杂Agent系统的钥匙。无论是想集成更强大的模型、连接更丰富的API还是实现多Agent协作都可以在这个骨架上生长出血肉。