ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

AI Agent工程真相:从七要素到七个决策点的实战指南

AI Agent工程真相:从七要素到七个决策点的实战指南 1. 从七个零件到七次抉择我眼中的 AI Agent 工程真相很多人第一次接触 AI Agent 这个词脑子里浮现的要么是科幻电影里那种能自己思考、自己行动的机器人要么就是某个大模型套了个壳能帮你查天气、发邮件。这两种理解都不太对。我在过去一年多的时间里从零搭过几个能跑起来的 Agent 项目也拆过不少开源框架的源码踩过的坑比写过的代码行数还多。今天我想把这件事讲透——AI Agent 到底是什么它的工程实现到底难在哪里以及为什么我说“七要素”只是静态的零件清单而“七个决策点”才是让它真正活起来的关键。先给结论一个能用的 AI Agent本质上是一个在循环中不断做决策的系统。它由七个核心要素构成——大语言模型LLM、提示词Prompt、工具Tools、记忆Memory、规划Planning、执行循环Loop、以及环境反馈Environment Feedback。这七个要素缺一不可但光把它们堆在一起Agent 是跑不起来的。真正决定 Agent 好不好用的是七个决策点什么时候调用工具、调用哪个工具、传什么参数、记忆怎么存怎么取、规划做多深、循环什么时候停、以及出错之后怎么办。这七个决策点每一个都对应着工程实现里最让人头疼的细节。这篇文章适合谁看如果你是一个开发者想自己搭一个 Agent 但不知道从哪下手或者你已经搭了一个但发现它要么死循环、要么乱调工具、要么记不住东西再或者你只是好奇想知道那些号称“自主智能体”的东西到底是怎么运转的——那这篇内容应该能帮你省下不少查文档和试错的时间。我会尽量用大白话把原理讲清楚同时给出可以直接抄的代码结构和参数配置。不扯虚的全是实操。2. 七要素拆解每个零件到底在干什么2.1 LLM 不是大脑是决策引擎很多人把 LLM 比作 Agent 的大脑这个比喻其实不太准确。大脑是有记忆、有情绪、有潜意识的而 LLM 在 Agent 里的角色更像是一个无状态的决策引擎。你给它一段输入它给你一个输出仅此而已。它不记得上一轮发生了什么除非你把历史记录重新塞给它。它也不知道自己调用了什么工具除非你把工具返回的结果再喂回去。这个认知非常重要因为它直接决定了你的 Agent 架构该怎么设计。我见过不少新手以为只要把 LLM 接上工具就完事了结果发现 Agent 调了一次工具之后就“失忆”了完全不知道下一步该干嘛。原因就是他们没有把工具调用的结果重新注入到 LLM 的上下文里。在实际工程中LLM 的选型要考虑三个维度推理能力、响应速度、成本。推理能力决定了 Agent 能不能正确处理复杂的多步任务响应速度决定了用户体验尤其是需要多轮循环的场景成本则直接关系到你能不能把这个 Agent 跑起来。我的经验是对于工具调用类的任务中等规模的模型往往就够了没必要上来就上最大的那个。因为工具调用的核心是格式遵循和意图识别而不是深度推理。当然如果你的 Agent 需要做复杂的规划那推理能力就不能妥协。还有一个容易被忽略的点LLM 的输出格式稳定性。在 Agent 里你通常需要 LLM 输出结构化的内容比如 JSON 格式的工具调用请求。但 LLM 有时候会“自由发挥”输出一些你解析不了的东西。这时候你需要做两件事一是用 few-shot 示例把格式固定下来二是在解析层做容错处理。我一般会在系统提示词里明确写清楚输出格式并且给两到三个示例。实测下来这样能把格式错误率降到很低。2.2 提示词是 Agent 的操作手册提示词在 Agent 里的重要性被严重低估了。很多人觉得提示词就是随便写几句话告诉 LLM 要干什么就行。但在 Agent 场景下提示词实际上是整个系统的操作手册。它需要告诉 LLM你有哪些工具可以用、每个工具是干什么的、什么情况下该用哪个工具、输出格式是什么、遇到错误该怎么处理。我习惯把 Agent 的提示词分成四个部分角色定义、工具说明、行为约束、输出格式。角色定义让 LLM 知道自己是谁比如“你是一个可以帮助用户查询天气和设置提醒的助手”。工具说明列出所有可用工具及其参数这部分要写得非常精确因为 LLM 会根据这些描述来决定调用哪个工具。行为约束是告诉 LLM 什么能做、什么不能做比如“不要编造工具返回结果”、“如果工具调用失败尝试换一种方式”。输出格式则是规定 LLM 每次回复的结构。这里有一个实操心得工具描述的质量直接决定工具调用的准确率。我试过同一个工具用不同的描述方式调用准确率能差出三成。好的工具描述应该包含工具的功能、适用的场景、每个参数的含义和格式、以及一个调用示例。不要嫌麻烦这部分写得越细后面调试越省事。2.3 工具是 Agent 的手和脚工具是 Agent 与外部世界交互的唯一途径。没有工具Agent 就是一个只会聊天的 LLM有了工具它才能查数据、发请求、写文件、控制设备。在工程实现上工具本质上就是一个函数接收输入参数返回执行结果。但要让 LLM 能正确调用工具你需要做一层封装。我一般会把工具定义成一个结构化的对象包含名称、描述、参数 schema 和执行函数。参数 schema 用 JSON Schema 来描述这样 LLM 能清楚地知道每个参数的类型和是否必填。执行函数则负责实际的业务逻辑。当 LLM 决定调用某个工具时它会输出一个包含工具名称和参数的 JSON你的代码解析这个 JSON找到对应的执行函数传入参数拿到结果再把结果返回给 LLM。这里有几个坑要注意。第一工具的执行结果要控制长度。有些工具返回的数据特别大比如一个 API 返回了几千行 JSON如果你直接塞回给 LLM不仅浪费 token还可能把上下文撑爆。我的做法是在工具层做一次摘要或截断只返回最关键的信息。第二工具要有超时和重试机制。外部 API 不稳定是常态如果工具调用卡住了整个 Agent 循环就会挂起。第三工具的错误信息要友好。不要直接把异常堆栈返回给 LLM而是返回一个结构化的错误信息比如“查询失败原因网络超时建议稍后重试”。2.4 记忆是 Agent 的笔记本记忆这个要素说起来简单做起来复杂。Agent 的记忆可以分为短期记忆和长期记忆。短期记忆就是当前对话的上下文通常直接放在 LLM 的上下文窗口里。长期记忆则是跨对话、跨会话的信息需要存到外部存储里比如向量数据库或键值存储。短期记忆的管理核心是上下文窗口的分配。LLM 的上下文窗口是有限的你不能把所有历史记录都塞进去。我的做法是保留最近 N 轮对话的完整记录更早的对话做摘要压缩。摘要可以用 LLM 来生成也可以用规则来提取关键信息。这里的关键是摘要要保留对当前任务有用的信息比如用户之前提到的偏好、已经确认的事实、未完成的任务等。长期记忆的难点在于什么时候存、什么时候取。存得太频繁会引入噪音取的不准确会干扰 LLM 的判断。我一般会在两种情况下触发长期记忆的存储一是用户明确说了“记住这个”二是 Agent 完成了一个重要任务把任务的关键信息存下来。取的时候用当前对话的内容去做相似度检索取回最相关的几条记忆注入到提示词里。注意长期记忆的检索不要贪多一般取 top 3 到 top 5 就够了。取太多反而会让 LLM 分心而且会增加 token 消耗。2.5 规划是 Agent 的路线图规划决定了 Agent 是“走一步看一步”还是“先想好再动手”。简单的 Agent 可以不做显式规划直接让 LLM 根据当前状态决定下一步动作。但复杂任务需要规划否则 Agent 很容易迷失方向或者陷入局部最优。规划的实现方式有好几种。最简单的是隐式规划就是在提示词里让 LLM“先思考再行动”比如 ReAct 模式。LLM 会先输出一段思考过程然后再决定调用什么工具。这种方式实现简单但规划的质量完全取决于 LLM 的能力。另一种是显式规划先让 LLM 生成一个完整的任务计划把大任务拆成若干子任务然后逐个执行。这种方式适合步骤明确的任务但缺点是计划一旦生成就不太容易根据实际情况调整。我自己的经验是对于大多数场景混合模式最好用。先让 LLM 生成一个粗粒度的计划比如三到五步然后每一步执行的时候再让 LLM 根据当前状态决定具体怎么做。这样既有全局方向又有局部灵活性。规划深度的控制也很重要太浅了容易跑偏太深了容易过度设计。我一般把规划步数控制在五步以内超过五步的任务说明需要拆成多个 Agent 来协作。2.6 执行循环是 Agent 的心跳执行循环是 Agent 的运行时骨架。它的基本逻辑是接收输入 - LLM 决策 - 执行动作 - 观察结果 - 判断是否继续 - 循环或结束。这个循环看起来简单但工程实现里有大量细节需要处理。首先是循环终止条件。如果没有明确的终止条件Agent 可能会无限循环下去。终止条件通常包括任务完成、达到最大循环次数、连续多次没有进展、或者 LLM 明确输出结束信号。我一般会设置一个最大循环次数比如 10 次超过就强制终止并返回当前的结果和状态。其次是状态管理。每一轮循环都会产生新的状态包括 LLM 的输出、工具调用的结果、错误信息等。这些状态需要被妥善保存以便在下一轮循环中注入给 LLM。我习惯用一个状态对象来管理包含对话历史、当前任务、已执行的动作、待执行的动作等字段。最后是异常处理。循环中任何一步都可能出错LLM 可能输出无法解析的内容工具可能调用失败网络可能超时。这些异常不能直接让循环崩溃而是要被捕获并转化为 LLM 能理解的反馈。比如工具调用失败时我会把错误信息包装成一条系统消息告诉 LLM“刚才的调用失败了原因是 XXX你可以尝试其他方式”。2.7 环境反馈是 Agent 的眼睛环境反馈是 Agent 感知自己行动结果的方式。在工程上环境反馈就是工具调用的返回值以及系统状态的变化。但要让 Agent 真正“理解”反馈你需要把原始反馈转化成 LLM 能消化的自然语言描述。举个例子如果 Agent 调用了一个数据库查询工具返回的是一个 JSON 数组。直接把这个 JSON 塞给 LLM它可能能看懂但效率不高。更好的做法是在工具层做一次转换把 JSON 转成一段描述性的文字比如“查询到 3 条记录第一条是 XXX第二条是 XXX”。这样 LLM 能更快地理解结果做出下一步决策。环境反馈的另一个作用是纠错。当 Agent 发现自己的行动没有达到预期效果时它需要根据反馈调整策略。比如 Agent 尝试调用一个 API但返回了 404 错误它应该意识到这个 API 可能不存在或者路径错了然后尝试其他方式。这种纠错能力是 Agent 从“自动化脚本”进化到“智能体”的关键。3. 七个决策点让 Agent 真正活起来的关键3.1 决策点一什么时候该调用工具这是 Agent 最基础的决策。LLM 需要判断当前的情况是需要直接回答还是需要调用工具来获取信息或执行操作。这个判断的准确率直接决定了 Agent 的可用性。我见过很多 Agent 犯两种错误一种是该调工具的时候不调比如用户问“今天天气怎么样”LLM 直接编了一个答案而不是去调用天气 API。另一种是不该调的时候乱调比如用户只是打了个招呼LLM 却去调用了一堆工具。解决这个问题的核心在于提示词的引导。我会在系统提示词里明确写清楚如果问题涉及实时数据、外部信息、或者需要执行操作必须调用工具如果只是闲聊或常识问题可以直接回答。同时我会给几个正例和反例让 LLM 有参照。还有一个技巧是给 LLM 一个“思考”的机会。在 ReAct 模式里LLM 会先输出一段思考比如“用户想知道天气我需要调用天气查询工具”然后再输出工具调用请求。这段思考过程虽然不直接产生行动但它能让 LLM 的决策更加谨慎和准确。实测下来加了思考步骤之后工具调用的准确率有明显提升。3.2 决策点二调用哪个工具当 Agent 决定要调用工具之后下一个问题就是调用哪个工具如果只有一个工具那没得选。但实际场景中Agent 往往有多个工具可用比如搜索工具、计算工具、数据库查询工具、邮件发送工具等。LLM 需要根据当前的任务选择最合适的工具。这个决策的准确率主要取决于工具描述的质量。如果两个工具的功能有重叠LLM 很容易选错。我的做法是尽量让每个工具的职责单一且明确避免功能重叠。如果确实需要多个工具完成类似的事情我会在描述里写清楚各自的适用场景比如“搜索工具用于查找公开信息数据库工具用于查询内部数据”。另一个技巧是给工具分组。如果工具特别多比如超过十个LLM 的选择难度会急剧上升。这时候可以把工具分成几组先让 LLM 选择组再选择组内的具体工具。这种两级选择的方式能显著降低决策难度。实操心得工具数量控制在 5 到 8 个之间LLM 的选择准确率最高。超过 10 个就需要考虑分组或者用专门的工具选择器了。3.3 决策点三传什么参数选好工具之后LLM 需要生成调用工具所需的参数。这个环节最容易出问题因为 LLM 可能会编造参数、遗漏必填参数、或者参数格式不对。我处理这个问题的办法是用 JSON Schema 严格约束参数格式。每个工具的参数都定义成 JSON Schema明确每个参数的类型、是否必填、取值范围。LLM 在生成参数时会参照这个 schema出错的概率会低很多。同时我会在代码层做参数校验如果参数不符合 schema直接返回错误给 LLM让它重新生成。还有一个常见问题是参数值的来源。有些参数需要从用户的输入里提取有些需要从上下文里推断有些需要从之前的工具调用结果里获取。LLM 需要正确地识别参数的来源。我一般会在提示词里强调不要编造参数值如果某个参数无法确定就使用默认值或者向用户询问。3.4 决策点四记忆怎么存怎么取记忆的存取策略直接影响 Agent 的“智商”表现。存得不好Agent 会显得很健忘取得不好Agent 会被无关信息干扰。短期记忆的存取相对简单就是维护一个对话历史列表。但要注意上下文窗口的预算管理。我一般会把上下文窗口分成三部分系统提示词占 20%最近对话历史占 50%工具调用结果占 30%。如果超出预算就压缩最早的历史记录。长期记忆的存取就复杂多了。我的做法是按需存储、按需检索。存储的触发条件包括用户明确要求记住、Agent 完成了重要任务、出现了值得记录的偏好或事实。检索的时候用当前对话的语义向量去匹配取回最相关的几条。这里的关键是相关性阈值的设定阈值太高会漏掉有用信息太低会引入噪音。我一般会把阈值设在 0.7 左右然后根据实际效果微调。3.5 决策点五规划做多深规划深度是一个权衡。规划太浅Agent 容易短视走一步看一步遇到复杂任务就卡住了。规划太深Agent 容易过度设计把简单问题复杂化而且计划一旦生成就很难调整。我的经验是根据任务复杂度动态调整规划深度。对于简单任务比如查天气、设提醒不需要显式规划直接让 LLM 决定下一步就行。对于中等复杂度的任务比如“帮我安排下周的出差行程”可以让 LLM 生成一个三到五步的计划。对于高度复杂的任务比如“帮我调研一下某个市场并写一份报告”可能需要多个 Agent 协作每个 Agent 负责一个子任务。还有一个技巧是滚动规划。不要一次性生成完整的计划而是先生成一个粗粒度的计划执行一步之后根据结果调整后续计划。这样既有方向感又有灵活性。3.6 决策点六循环什么时候停循环终止条件的设计是 Agent 工程里最容易被忽视但后果最严重的环节。如果终止条件太宽松Agent 会陷入死循环浪费 token 和时间。如果终止条件太严格Agent 可能在任务还没完成时就停了。我一般会设置多重终止条件只要满足其中一个就停止。第一LLM 明确输出“任务完成”或“结束”信号。第二达到最大循环次数我通常设为 10 到 15 次。第三连续两轮没有产生有效动作比如连续两次工具调用失败或者连续两次 LLM 输出相同的内容。第四检测到用户输入了终止指令。这里有一个细节最大循环次数不是固定的要根据任务类型调整。查询类的任务通常 3 到 5 次循环就够了。操作类的任务比如需要多步 API 调用的可能需要 10 次以上。我一般会先设一个保守值然后根据实际运行情况调整。3.7 决策点七出错之后怎么办错误处理是区分“玩具 Agent”和“生产级 Agent”的分水岭。在实验室里跑通的 Agent到了真实环境里会遇到各种意想不到的错误API 限流、网络超时、返回格式变化、LLM 输出异常等等。我的错误处理策略分三层。第一层是预防在工具层做参数校验、超时控制、重试机制尽量把错误挡在 Agent 循环之外。第二层是捕获和转化如果错误还是发生了把它捕获下来转化成 LLM 能理解的反馈信息比如“工具调用失败原因是网络超时建议稍后重试”。第三层是降级和兜底如果 Agent 连续多次失败就触发降级策略比如返回一个预设的回复或者把问题转交给人工处理。注意不要把原始的错误堆栈直接返回给 LLM那样只会让 LLM 困惑。要把错误信息翻译成自然语言并且给出明确的建议。4. 从零搭一个 Agent我的实操流程和参数配置4.1 技术选型和环境准备在动手写代码之前先要把技术栈定下来。我的选择是 Python FastAPI OpenAI 兼容的 LLM API SQLite用于记忆存储。为什么选 Python因为生态最成熟各种 LLM 客户端库、向量数据库客户端、工具库都是 Python 优先。FastAPI 用来暴露 HTTP 接口方便前端或其他服务调用。SQLite 足够轻量适合中小规模的记忆存储如果数据量大了再换 PostgreSQL 或向量数据库。环境准备很简单创建一个虚拟环境安装几个核心依赖python -m venv agent-env source agent-env/bin/activate pip install openai fastapi uvicorn pydantic sqlite-utils numpy这里重点说一下pydantic它是做参数校验的神器。我会用 pydantic 来定义工具的输入输出 schema这样既能做校验又能自动生成 JSON Schema 给 LLM 看。4.2 定义工具从函数到 LLM 可调用的接口工具的定义我一般分两步。第一步写一个普通的 Python 函数实现具体的业务逻辑。第二步用装饰器或配置文件把这个函数包装成 LLM 可调用的工具。from pydantic import BaseModel, Field class WeatherInput(BaseModel): city: str Field(description城市名称比如北京、上海) date: str Field(defaulttoday, description日期格式 YYYY-MM-DD默认今天) def get_weather(city: str, date: str today) - str: # 实际调用天气 API 的逻辑 # 这里返回模拟数据 return f{city} {date} 的天气晴温度 25 摄氏度然后定义一个工具注册表把工具的名称、描述、参数 schema 和执行函数关联起来TOOLS { get_weather: { name: get_weather, description: 查询指定城市的天气信息, parameters: WeatherInput.model_json_schema(), function: get_weather } }这样 LLM 就能通过工具描述知道有哪些工具可用以及每个工具需要什么参数。4.3 构建提示词让 LLM 知道该干什么提示词我一般写成模板方便动态填充。核心结构包括角色定义、工具列表、行为约束和输出格式。SYSTEM_PROMPT 你是一个智能助手可以帮助用户查询天气、设置提醒、搜索信息。 你可以使用以下工具 {tools_description} 行为约束 1. 如果需要实时数据或执行操作必须调用工具不要编造答案。 2. 调用工具时严格按照参数 schema 生成参数。 3. 如果工具调用失败尝试其他方式或告知用户。 4. 每次回复必须是以下 JSON 格式之一 - 工具调用{{action: tool_call, tool: 工具名, parameters: {{...}}}} - 直接回复{{action: reply, content: 回复内容}} - 任务完成{{action: finish, content: 最终结果}} 这个提示词的关键在于输出格式的约束。我要求 LLM 每次输出一个 JSON包含 action 字段来标识当前的动作类型。这样解析起来非常方便而且能避免 LLM 输出一堆无关的内容。4.4 实现执行循环Agent 的核心引擎执行循环是整个 Agent 的心脏。我的实现逻辑是这样的def run_agent(user_input: str, max_loops: int 10): messages [ {role: system, content: SYSTEM_PROMPT.format(tools_description...)} ] messages.append({role: user, content: user_input}) for i in range(max_loops): # 调用 LLM response call_llm(messages) # 解析 LLM 输出 try: action parse_json(response) except: messages.append({role: assistant, content: response}) messages.append({role: system, content: 输出格式错误请按 JSON 格式重新输出}) continue # 处理不同的动作类型 if action[action] tool_call: tool_name action[tool] params action[parameters] result execute_tool(tool_name, params) messages.append({role: assistant, content: response}) messages.append({role: system, content: f工具返回结果{result}}) elif action[action] reply: return action[content] elif action[action] finish: return action[content] return 任务未在限定步数内完成这个循环的核心逻辑是LLM 决策 - 执行动作 - 反馈结果 - 继续循环。每一轮循环都会把 LLM 的输出和工具的结果追加到消息历史里这样 LLM 在下一轮就能看到之前发生了什么。4.5 记忆模块短期和长期记忆的配合短期记忆就是上面代码里的messages列表。但要注意控制长度我一般会在消息数量超过 20 条时把最早的五条对话做一次摘要替换成一条摘要消息。长期记忆我用 SQLite 存表结构很简单id、内容、向量、时间戳。存储的时候把内容用 embedding 模型转成向量存进去。检索的时候把当前对话也转成向量算余弦相似度取 top 3。import sqlite3 import numpy as np def save_memory(content: str, embedding: list): conn sqlite3.connect(memory.db) conn.execute(INSERT INTO memories (content, embedding) VALUES (?, ?), (content, np.array(embedding).tobytes())) conn.commit() def retrieve_memory(query_embedding: list, top_k: int 3): conn sqlite3.connect(memory.db) rows conn.execute(SELECT content, embedding FROM memories).fetchall() # 计算相似度并排序 # ... return top_results4.6 错误处理和日志让 Agent 可观测错误处理我分两层。工具层用 try-except 捕获异常返回结构化的错误信息。循环层检测 LLM 的输出格式如果解析失败就提示 LLM 重新输出。日志记录非常重要。我会记录每一轮循环的输入、LLM 输出、工具调用、结果和耗时。这样出问题的时候能快速定位是哪一步出了错。日志我用 Python 的 logging 模块输出到文件和控制台。import logging logging.basicConfig(levellogging.INFO, format%(asctime)s - %(levelname)s - %(message)s) def execute_tool(tool_name: str, params: dict): try: logging.info(f调用工具{tool_name}参数{params}) result TOOLS[tool_name][function](**params) logging.info(f工具返回{result}) return result except Exception as e: logging.error(f工具调用失败{e}) return f工具调用失败原因{str(e)}建议检查参数或稍后重试5. 常见问题与排查技巧实录5.1 Agent 陷入死循环怎么办死循环是最常见的问题。表现是 Agent 反复调用同一个工具或者反复输出相同的内容循环次数用完了还没结束。排查思路先看日志确认是哪一步开始重复的。如果是工具调用重复检查工具返回的结果是不是没有变化导致 LLM 认为任务没完成。如果是 LLM 输出重复检查提示词里有没有明确的终止条件。解决方法第一设置最大循环次数这是兜底。第二在提示词里加入“如果连续两次得到相同结果请尝试其他方式或结束任务”。第三在代码层检测重复动作如果连续两轮的工具调用和参数完全相同强制终止并返回当前结果。5.2 工具调用参数错误怎么修参数错误的表现是工具执行时报错比如缺少必填参数、参数类型不对、参数值超出范围。排查思路看日志里 LLM 生成的参数是什么对比工具的 schema找出不匹配的地方。解决方法第一在提示词里把参数 schema 写清楚最好给一个调用示例。第二在代码层做参数校验如果参数不合法返回具体的错误信息给 LLM让它重新生成。第三对于容易出错的参数比如日期格式可以在工具层做兼容处理比如接受多种日期格式。5.3 LLM 输出格式不稳定怎么处理LLM 有时候会输出非 JSON 的内容或者在 JSON 外面包一层文字说明导致解析失败。排查思路看日志里 LLM 的原始输出确认格式问题的具体表现。解决方法第一在提示词里强调“只输出 JSON不要输出其他内容”。第二用 few-shot 示例固定格式。第三在解析层做容错比如用正则表达式提取 JSON 部分。第四如果解析失败把错误信息返回给 LLM让它重新输出。5.4 记忆检索不准确怎么优化记忆检索不准确的表现是 Agent 回忆起了无关的信息或者该回忆的信息没回忆起来。排查思路检查 embedding 模型的质量以及相似度阈值的设置。解决方法第一换一个更好的 embedding 模型。第二调整相似度阈值我一般从 0.7 开始试。第三在存储记忆的时候把内容写得更加结构化和具体避免模糊的描述。第四限制检索数量不要取太多。5.5 常见问题速查表问题可能原因排查方法解决方案死循环终止条件不明确看日志确认重复步骤设最大循环次数检测重复动作参数错误schema 不清晰对比 LLM 输出和 schema完善提示词加参数校验格式不稳定提示词约束不够看 LLM 原始输出加 few-shot解析层容错记忆不准检索策略问题检查相似度和 embedding调阈值优化存储内容工具选错工具描述重叠看工具描述职责单一化分组选择响应太慢循环次数太多统计每轮耗时优化提示词减少不必要的工具调用最后分享一个小技巧在开发阶段把 LLM 的温度参数设低一点比如 0.1 到 0.3这样输出更稳定。到了生产环境如果发现 Agent 太死板再适当调高。5.6 性能优化的几个实操方向Agent 的性能瓶颈通常在三地方LLM 调用延迟、工具执行时间、循环次数。优化 LLM 调用延迟可以用流式输出让用户先看到部分结果。优化工具执行时间可以并行调用多个独立的工具。优化循环次数可以通过更好的提示词和规划让 Agent 一次做对减少来回试错。我实测下来把工具描述写清楚、给 LLM 足够的上下文、设置合理的终止条件这三件事做好Agent 的成功率能从不到一半提升到八成以上。剩下的两成靠错误处理和降级策略兜底。这个内容后续还可以这样扩展加入多 Agent 协作的架构让一个 Agent 负责规划另一个负责执行第三个负责审核。或者加入工具的动态注册机制让 Agent 在运行时发现新工具。再或者把记忆模块换成向量数据库支持更大规模的记忆存储和检索。这些方向我都试过一些有机会再单独写。
返回列表