
1. 为什么现在聊 Agent 不能只聊概念过去一年我见过太多团队在 Agent 项目上折戟。不是模型不够强而是把 Agent 当成了一个“更聪明的聊天机器人”来做。上线之后才发现它既不稳定也不可控更谈不上可靠。问题的根源在于大多数人跳过了工程实现这一层直接拿着 API 文档就开始拼装结果自然是踩坑无数。我自己从去年开始陆续参与了几个 Agent 相关的项目有做自动化内容分发的有做内部知识库问答的也有做代码辅助生成的。踩过的坑从 token 爆炸到工具调用死循环从记忆污染到多轮对话状态丢失几乎把能踩的都踩了一遍。后来我慢慢意识到Agent 的工程实现其实有一套相对固定的骨架我把它归纳为“七要素”和“七个决策点”。七要素是构成一个 Agent 的最小完备集合七个决策点是你在搭建过程中必须做出的关键选择。把这两件事想清楚Agent 的工程实现就不再是玄学。这篇文章适合谁看如果你已经了解 LLM 的基本调用方式想从“调 API”进阶到“搭系统”那这篇就是为你写的。如果你还在纠结 Agent 到底是什么我也会用最直白的方式把它拆开讲清楚。全文会围绕七要素和七个决策点展开穿插我自己的实操经验和踩坑记录尽量做到看完就能动手。2. 七要素一个 Agent 的最小完备集合在聊决策点之前得先把 Agent 的构成讲清楚。我见过很多人把 Agent 和“带工具调用的 LLM”混为一谈其实两者差别很大。一个真正意义上的 Agent至少包含七个要素。缺了任何一个它要么退化成普通的对话系统要么变成一个不可控的黑盒。2.1 目标与任务定义Agent 的起点Agent 和普通 LLM 调用最大的区别在于它是为目标服务的而不是为单轮问答服务的。你得先明确它要完成什么任务这个任务的边界在哪里成功的标准是什么。比如“帮我写一篇文章”和“根据给定的关键词和字数要求生成一篇结构完整的博文”后者才是可执行的目标定义。我在实际项目中的做法是把目标拆成三层顶层目标、子任务列表、每步的验收条件。顶层目标是给人类看的子任务列表是给 Agent 自己看的验收条件是给评估环节用的。这三层缺一不可。没有验收条件Agent 就不知道自己什么时候算做完很容易陷入无限循环。注意目标定义不要写成模糊的自然语言描述尽量结构化。我通常会用 JSON 或 YAML 来定义任务这样后续解析和校验都方便。2.2 规划与推理能力Agent 的大脑规划能力决定了 Agent 能不能把一个大目标拆成可执行的小步骤。目前主流的做法有两种一种是让 LLM 直接输出步骤列表另一种是用 ReAct 模式边想边做。前者适合任务边界清晰的场景后者适合需要动态调整的场景。我个人的经验是对于大多数业务场景先让 LLM 做一次静态规划然后在执行过程中允许它根据中间结果微调。纯 ReAct 模式虽然灵活但 token 消耗大而且容易跑偏。静态规划加动态修正是一个比较平衡的方案。推理能力则体现在每一步的决策上。比如工具返回了一个错误Agent 是重试、换工具还是直接放弃这需要 LLM 有一定的推理能力。实测下来模型在这方面的表现差异很大后面讲决策点的时候会细说。2.3 记忆机制短期与长期的分层设计记忆是 Agent 工程实现里最容易被低估的部分。很多人以为把对话历史塞进 context 就叫记忆了其实那只是短期记忆而且很快就会撑爆 token 限制。我把记忆分成三层工作记忆、会话记忆、长期记忆。工作记忆是当前任务执行过程中的临时状态比如已经完成了哪些步骤、当前在哪一步。会话记忆是这次对话的上下文通常保留最近 N 轮。长期记忆则是跨会话的知识沉淀需要向量化存储和检索。这三层的读写策略完全不同。工作记忆读写频繁但生命周期短会话记忆需要控制长度长期记忆则要考虑检索的准确性和召回率。我在一个项目里因为没做分层导致每次请求都要带上全部历史token 消耗直接翻了五倍。2.4 工具调用Agent 的手脚工具调用是 Agent 从“会说”到“会做”的关键。没有工具Agent 只能输出文本有了工具它才能查数据库、调 API、写文件、发消息。工具调用的核心难点不在于调用本身而在于工具的描述和参数设计。工具描述写得好LLM 就能正确选择工具参数设计得合理LLM 就能正确填充参数。我见过太多项目因为工具描述写得含糊导致 LLM 频繁选错工具。一个实用的技巧是给每个工具写清楚三件事什么时候用、输入是什么、输出是什么。最好再给一两个示例。这样 LLM 的选择准确率会明显提升。2.5 执行循环Agent 的心跳执行循环是 Agent 运转的核心机制。简单说就是观察当前状态、决定下一步动作、执行动作、更新状态然后重复这个过程直到任务完成或触发终止条件。这个循环看起来简单但工程实现上有不少细节。比如循环的最大次数限制、每步的超时控制、异常情况的处理、循环状态的持久化。我在一个项目里因为没设最大循环次数结果 Agent 在一个死胡同里转了上百圈token 直接烧光。循环机制的设计直接决定了 Agent 的稳定性和成本。后面讲决策点的时候我会详细展开怎么设计一个健壮的循环。2.6 状态管理让 Agent 知道自己在哪状态管理是执行循环的配套机制。Agent 每执行一步状态都会变化。这些状态包括当前任务进度、已收集的信息、待处理的事项、遇到的错误等。状态管理做得好Agent 就能在中断后恢复也能在多轮对话中保持连贯。做得不好就会出现“失忆”或者“重复劳动”。我的做法是用一个结构化的状态对象每次循环开始时读取结束时更新。状态对象尽量保持精简只存必要信息。2.7 评估与反馈Agent 的自我修正评估机制是很多 Agent 项目缺失的一环。没有评估你就不知道 Agent 做得好不好也不知道该往哪个方向优化。评估可以分两个层面过程评估和结果评估。过程评估看每一步是否合理结果评估看最终产出是否达标。我通常会用 LLM as Judge 的方式来做自动评估再辅以人工抽检。评估结果会反馈到规划环节形成一个闭环。这七个要素构成了一个 Agent 的完整骨架。接下来要讲的七个决策点就是在这七个要素的基础上你需要做出的关键工程选择。3. 七个决策点工程实现中的关键选择七要素讲的是“有什么”七个决策点讲的是“怎么选”。每一个决策点都会直接影响 Agent 的性能、成本和稳定性。我在实际项目中反复权衡过这些选择下面把我的思考过程分享出来。3.1 决策点一单 Agent 还是多 Agent这是搭建 Agent 时第一个要面对的问题。单 Agent 结构简单调试方便但能力上限有限。多 Agent 可以分工协作但通信成本和协调复杂度会大幅上升。我的判断标准是如果任务可以线性拆解且子任务之间依赖关系简单单 Agent 就够了。如果任务需要多种专业能力且子任务之间有复杂的交互才考虑多 Agent。大多数业务场景单 Agent 加多个工具就能解决没必要上多 Agent。多 Agent 的典型架构有几种主从模式、对等模式、流水线模式。主从模式适合有明确调度者的场景对等模式适合需要协商的场景流水线模式适合有固定处理顺序的场景。选哪种取决于你的任务结构。实操心得多 Agent 项目最容易出问题的地方是通信协议不统一。我建议在项目初期就把 Agent 之间的消息格式定死用 JSON Schema 约束避免后期扯皮。3.2 决策点二规划在前还是执行在前这个决策点指的是Agent 是先做完整规划再执行还是边执行边规划。两种方式各有优劣。规划在前的好处是全局视野清晰不容易跑偏适合步骤明确的任务。坏处是如果规划错了后面全错。执行在前的好处是灵活能根据实际情况调整适合探索性任务。坏处是容易迷失方向token 消耗也更大。我的做法是混合模式先做一个粗粒度的规划确定大方向然后执行过程中允许动态调整。粗粒度规划不需要太细只要把主要阶段划分出来就行。这样既有全局观又有灵活性。3.3 决策点三工具调用的粒度怎么定工具调用的粒度是个很容易被忽视的问题。粒度太粗一个工具做太多事LLM 难以正确使用粒度太细工具数量爆炸LLM 选择困难。我的经验是一个工具只做一件事但这件事要有足够的业务意义。比如“查询用户信息”是一个合适的粒度“查询用户姓名”和“查询用户邮箱”就太细了。一般来说一个 Agent 配置 5 到 15 个工具比较合适。超过 20 个LLM 的选择准确率会明显下降。如果工具确实很多可以考虑分层先让 LLM 选择工具类别再在类别内选择具体工具。这样每次选择的候选集就小了准确率会提升。3.4 决策点四记忆的存储和检索策略记忆策略的核心问题是存什么、存哪里、怎么取。存什么取决于你的业务需求存哪里取决于你的技术栈怎么取取决于你的检索方案。短期记忆通常放在内存或 Redis 里读写快但容量有限。长期记忆通常放在向量数据库里容量大但检索有延迟。我一般会用 Redis 存会话记忆用向量库存长期记忆两者通过一个统一的记忆管理模块来协调。检索策略上纯向量检索有时候不够准我会加上关键词过滤和元数据筛选。比如检索历史对话时先按用户 ID 和时间范围过滤再做向量相似度匹配。这样召回率和准确率都能兼顾。3.5 决策点五循环的终止条件怎么设循环终止条件是保证 Agent 不失控的关键。终止条件设得太松Agent 可能无限循环设得太紧任务可能没完成就停了。我通常会设多重终止条件任务完成、达到最大步数、连续 N 步没有进展、遇到不可恢复的错误、超时。这几个条件满足任何一个就终止。最大步数根据任务复杂度来定一般 10 到 30 步比较合理。连续无进展的检测也很重要。我的做法是比较连续几步的状态如果状态没有实质变化就判定为无进展。这个阈值一般设 2 到 3 步。3.6 决策点六错误处理和重试机制Agent 执行过程中出错是常态关键是怎么处理。我的原则是能重试的重试不能重试的降级降级不了的终止并报告。重试要区分错误类型。网络超时这类临时错误可以重试参数错误这类逻辑错误重试也没用。重试次数一般设 2 到 3 次每次重试之间加退避延迟。降级是指换一种方式完成任务。比如主工具调用失败可以尝试备用工具。降级策略需要提前设计好不能等出错了再想。3.7 决策点七评估和迭代的闭环怎么建最后一个决策点是评估闭环。没有评估Agent 就没法持续优化。评估闭环包括定义评估指标、收集评估数据、分析评估结果、迭代优化。评估指标要分维度任务完成率、平均步数、token 消耗、用户满意度。这几个指标要综合看不能只看一个。比如完成率上去了但 token 消耗翻倍那也不一定是好事。评估数据的收集要自动化人工评估只能作为补充。我通常会在每次 Agent 执行结束后自动记录关键指标和中间状态定期做批量分析。4. 从零搭建一个 Agent 的实操流程理论讲完了接下来是实操。我会以一个“自动化内容分发 Agent”为例完整走一遍搭建流程。这个 Agent 的任务是根据给定的主题生成一篇短文然后分发到指定的平台。4.1 环境准备和依赖安装先说一下技术栈选择。LLM 我用的是主流的大模型 API向量数据库用的是轻量级的方案状态存储用 Redis整体用 Python 编写。这套组合上手快社区资源多适合快速验证。pip install openai redis numpy如果你用的是其他模型把对应的 SDK 换掉就行。向量数据库我建议初期用内存版的比如 FAISS等数据量大了再换分布式方案。环境变量里要配好 API Key 和 Redis 连接信息。我习惯用 .env 文件管理避免硬编码。4.2 定义任务和工具第一步是定义任务结构。我用 YAML 来描述task: name: content_distribution goal: 根据主题生成短文并分发 steps: - generate_content - review_content - distribute_content max_steps: 15 timeout: 300然后是工具定义。这个 Agent 需要三个工具内容生成、内容审核、内容分发。每个工具都要写清楚描述和参数。tools [ { name: generate_content, description: 根据主题生成一篇短文输入主题和字数要求, parameters: { topic: string, word_count: integer } }, { name: review_content, description: 审核内容是否符合规范输入待审核文本, parameters: { content: string } }, { name: distribute_content, description: 将内容分发到指定平台输入内容和平台名称, parameters: { content: string, platform: string } } ]工具描述我写得比较直白没有用太复杂的术语。实测下来描述越简单直接LLM 的选择准确率越高。4.3 实现执行循环执行循环是整个 Agent 的核心。我用一个 while 循环来实现每轮做四件事读取状态、调用 LLM 决策、执行动作、更新状态。def run_agent(task, tools, max_steps15): state init_state(task) step 0 while step max_steps: if is_task_complete(state): break action llm_decide(state, tools) if action[type] tool_call: result execute_tool(action[tool], action[params]) state update_state(state, action, result) elif action[type] finish: break step 1 if no_progress(state, window3): break return state这个循环里llm_decide是最关键的函数。它把当前状态和可用工具列表发给 LLM让 LLM 决定下一步做什么。返回的动作有两种调用工具或结束任务。no_progress函数用来检测连续无进展。我的实现是比较最近三步的状态快照如果没有实质变化就返回 True。4.4 状态管理的具体实现状态对象我用一个字典来存包含任务信息、已完成步骤、当前步骤、收集的数据、错误记录。def init_state(task): return { task: task, completed_steps: [], current_step: None, data: {}, errors: [], history: [] }每次更新状态时我会把历史记录也存进去方便后续调试和评估。历史记录只存关键信息不存完整上下文避免状态对象过大。状态持久化我用 Rediskey 是任务 IDvalue 是序列化后的状态。这样即使服务重启任务也能恢复。4.5 记忆模块的搭建记忆模块分短期和长期两部分。短期记忆就是当前会话的上下文我保留最近 10 轮。长期记忆用向量库存存的是历史任务的成功案例和失败教训。def save_memory(content, memory_type): if memory_type short_term: redis.lpush(short_term, content) redis.ltrim(short_term, 0, 9) elif memory_type long_term: vector embed(content) vector_db.insert(vector, content)检索的时候短期记忆直接读 Redis长期记忆做向量相似度搜索。我一般会先查短期记忆如果没有相关信息再查长期记忆。4.6 评估模块的接入评估模块我在每次任务结束后调用计算几个关键指标任务是否完成、用了多少步、消耗了多少 token、有没有错误。def evaluate(state): return { completed: is_task_complete(state), steps: len(state[history]), tokens: state.get(token_count, 0), errors: len(state[errors]) }这些指标会存到数据库里定期做分析。如果发现某个指标异常就回溯对应的任务日志找出问题所在。5. 常见问题与排查技巧实录Agent 项目上线后问题会以各种意想不到的方式出现。我把遇到过的问题整理成了一份速查表希望能帮你少走弯路。5.1 工具调用失败排查表问题现象可能原因排查方法解决方案LLM 选错工具工具描述不清检查工具描述是否明确重写描述加示例参数填充错误参数定义模糊检查参数类型和说明用 JSON Schema 约束工具调用超时工具本身慢查看工具执行日志加超时和重试工具返回格式错返回未标准化检查返回结构统一返回格式这张表是我踩坑踩出来的。工具调用失败是最常见的问题大部分都能通过优化描述和参数定义来解决。5.2 循环失控的三种典型场景第一种是死循环。Agent 在两步之间反复横跳永远不结束。这种情况通常是终止条件没设好或者状态更新有问题。我的解决办法是加连续无进展检测连续三步状态没变化就强制终止。第二种是跑偏。Agent 做着做着就偏离了原始目标。这通常是规划环节出了问题或者工具返回的结果误导了 LLM。我的做法是在每步决策前把原始目标重新注入 prompt提醒 LLM 不要跑偏。第三种是提前终止。Agent 还没完成任务就自己结束了。这通常是 LLM 误判了完成条件。我的解决办法是在终止前加一道校验确认任务真的完成了才允许结束。5.3 Token 消耗优化的几个实用技巧Token 消耗是 Agent 项目的主要成本。我总结了几个优化技巧实测能省 30% 到 50%。第一个是精简 prompt。把不必要的说明和示例删掉只保留核心信息。我见过很多项目的 prompt 里塞了大量冗余内容其实 LLM 根本用不上。第二个是控制历史长度。会话历史不要全量带上只带最近几轮。长期记忆按需检索不要一次性全塞进去。第三个是缓存重复计算。有些中间结果是可以复用的比如工具描述、系统 prompt这些可以缓存起来不用每次都重新生成。第四个是选择合适的模型。不是所有步骤都需要用最强的模型。简单的决策可以用小模型复杂的推理再用大模型。这样能省不少钱。5.4 记忆污染的预防和处理记忆污染是指错误的信息被存入长期记忆后续检索时又被取出来导致错误累积。这个问题很隐蔽但危害很大。预防措施是在存入长期记忆前做一道校验。我通常会用 LLM 判断这条信息是否值得存、是否准确。只有通过校验的才存入。如果已经发生了污染处理起来比较麻烦。我的做法是定期做记忆审计抽样检查长期记忆的准确性。发现污染就标记出来后续检索时排除。实操心得长期记忆的写入一定要谨慎宁可少存也不要存错。我一般只存经过验证的成功案例和明确的失败教训模糊的中间状态不存。5.5 多轮对话状态丢失的修复多轮对话中状态丢失是个常见问题。用户说了几句话Agent 就忘了前面说过什么。这通常是状态管理没做好。我的修复方案是每次对话开始时先从 Redis 加载状态对话结束后再存回去。状态里要包含关键信息用户意图、已收集的参数、当前进度。如果状态对象太大可以只存关键字段其他信息按需重新计算。我一般会把状态控制在 1KB 以内这样读写都快。6. 一些关于 Agent 工程的个人体会做 Agent 项目这一年多我最大的体会是Agent 的难点不在模型而在工程。模型能力再强如果工程实现不到位Agent 照样跑不起来。另一个体会是不要追求一步到位。我见过很多团队想一开始就做一个全能 Agent结果什么都做不好。正确的做法是从小场景切入先把一个任务做稳再逐步扩展。还有一点是关于评估的。很多人觉得评估是锦上添花其实它是雪中送炭。没有评估你根本不知道 Agent 是在进步还是在退步。我建议在项目初期就把评估框架搭起来哪怕指标很简单也比没有强。最后分享一个我常用的小技巧在 Agent 的 prompt 里加一句“如果你不确定下一步做什么就输出当前状态并请求人工介入”。这句话能避免很多失控情况。Agent 不是万能的知道什么时候该停下来求助也是一种能力。