
AI Agent 这个词在过去一年里被反复提及但真正动手搭过的人都知道从能跑通一个 Demo到能扛住真实业务流量中间隔着的不是几行代码而是一整套工程决策。我前后参与过几个 Agent 项目有基于 LangGraph 做工作流编排的也有用 Spring AI 对接内部系统的踩过的坑从工具调用参数对不上到循环停不下来把 Token 烧光几乎每一类都遇到过。这篇内容不打算复述官方文档里那些概念定义而是想把我理解的 Agent 工程实现拆成两个视角一个是构成 Agent 的七个核心要素另一个是搭建过程中绕不开的七个决策点。前者帮你建立整体认知后者帮你在具体落地时少走弯路。不管你是刚接触 Agent 开发还是已经写过几个 Demo 想往生产环境推进应该都能从中找到对得上号的部分。1. 先把 Agent 拆开看七个构成要素很多人一上来就问用哪个框架好其实框架只是外壳真正决定 Agent 能不能干活的是它内部那几个组成部分。我把它们归纳成七个要素缺一个都会在某个环节出问题。1.1 模型Agent 的推理内核模型是整个 Agent 的大脑负责理解意图、做决策、生成内容。选模型的时候不能只看榜单排名得看你的任务类型。如果是需要复杂推理的规划类任务那推理能力强的模型更合适如果是高频的简单工具调用那响应速度和成本反而更重要。我自己的经验是一个 Agent 项目里往往不是只用一个大模型。常见做法是大小搭配主流程用能力强的模型做规划和决策一些格式转换、信息抽取的子任务用轻量模型处理这样整体成本和延迟都能压下来。另外要注意模型的上下文窗口Agent 在多轮循环里上下文增长很快窗口不够会直接导致任务中断。还有一个容易被忽略的点是模型的函数调用能力。不是所有模型都支持结构化的工具调用有些只能靠提示词让它输出 JSON 再自己解析这种方案在简单场景能用但一旦工具多了、参数复杂了解析失败率会明显上升。选型时一定要确认模型原生支持工具调用这会省掉大量兜底逻辑。1.2 工具Agent 伸向外部的手工具就是 Agent 能调用的外部能力可以是查数据库、调 API、读文件、发消息。工具定义得好不好直接决定 Agent 能不能准确完成任务。定义工具时我踩过最大的坑是描述写得太随意。工具的名称和描述是给模型看的模型靠这些信息判断什么时候该用这个工具。如果描述含糊模型要么该调用时不调用要么乱调用。后来我养成的习惯是工具描述里必须写清楚三件事这个工具做什么、什么情况下用、参数分别是什么含义。这其实就是把我是谁、我在找什么、我能提供什么这套逻辑翻译给模型听。工具的数量也要控制。我见过一个项目塞了三四十个工具进去结果模型选择困难准确率反而下降。一般建议单次暴露给模型的工具控制在十个以内多了就做分组或者用路由先筛选一轮。1.3 记忆Agent 的上下文管理记忆分短期和长期。短期记忆就是当前对话的上下文长期记忆则是跨会话保留的信息通常存在向量库或者关系库里。短期记忆的核心问题是上下文膨胀。Agent 每调用一次工具、每执行一步都会往上下文里追加内容几轮下来就可能超出窗口。解决办法有几种一是做摘要压缩把历史对话浓缩成要点二是只保留最近 N 轮三是把中间结果存到外部上下文里只留引用。我一般会组合使用关键决策信息保留原文过程性内容做摘要。长期记忆则要考虑写入和检索的时机。不是所有信息都值得存存太多会稀释检索质量。我的做法是只存那些下次可能还会用到的事实性信息比如用户偏好、历史结论过程性的推理链条一般不存。1.4 规划Agent 的任务分解能力规划就是 Agent 把一个大目标拆成可执行步骤的能力。简单任务可能一步就完成复杂任务就需要先规划再执行。规划的实现方式有两种主流思路。一种是显式规划让模型先输出一个步骤列表然后按列表逐步执行另一种是隐式规划模型在每一步根据当前状态决定下一步做什么也就是 ReAct 那种边想边做。显式规划的好处是可控、可审计适合流程相对固定的场景隐式规划更灵活适合探索性任务但容易跑偏。实际项目里我倾向于混合先让模型出一个粗粒度的计划执行过程中允许它根据中间结果调整后续步骤。这样既有全局方向又保留了应变空间。1.5 执行把决策变成动作执行环节负责真正调用工具、处理返回结果、把结果反馈给模型。这一步看起来简单其实坑很多。最常见的问题是工具返回结果的格式处理。工具返回的可能是 JSON、可能是纯文本、可能是错误码模型不一定能直接理解。我一般会在执行层做一层归一化把各种返回统一成模型容易理解的格式错误信息也要转成自然语言描述而不是直接抛一个堆栈给模型。另一个问题是超时和重试。外部工具调用失败是常态执行层必须有超时控制和重试策略。但重试要小心对于有副作用的操作比如发消息、扣款盲目重试可能造成重复执行这类操作要么做幂等设计要么失败后交给模型决策。1.6 循环Agent 的心跳循环机制是 Agent 区别于普通 LLM 调用的关键。普通调用是输入-输出一次完成Agent 是思考-行动-观察反复循环直到任务完成或触发终止条件。循环必须要有明确的终止条件否则就是烧钱机器。终止条件通常包括模型判断任务已完成、达到最大循环次数、遇到无法恢复的错误。我一般会设一个硬性的最大轮数比如 10 到 15 轮超过就强制停止并返回当前结果。这个数字要根据任务复杂度调太小学生意做不完太大又浪费。循环里还要注意状态传递。每一轮的结果都要正确累积到上下文里同时要避免重复信息堆积。我见过因为状态管理混乱导致模型反复执行同一步的情况排查了半天才发现是历史消息没去重。1.7 约束Agent 的行为边界约束是保证 Agent 安全、可控的那一层包括权限控制、输出格式约束、敏感操作拦截等。权限控制很好理解Agent 能调用的工具应该按最小权限原则分配不该碰的数据坚决不给。输出格式约束则是要求模型按指定结构返回方便下游程序解析。敏感操作拦截是在执行前做一道检查比如涉及资金、删除类操作要么二次确认要么直接禁止自动执行。这一层最容易被忽视但出事往往就出在这里。我的建议是凡是不可逆的操作都不要让 Agent 全自动执行至少加一道人工确认。2. 搭建时的七个决策点理解了七个要素接下来是实际搭建时要做的选择。这七个决策点基本覆盖了从架构到上线的全过程每一个选错都会在后面付出代价。2.1 决策一用框架还是自己写这是第一个要面对的问题。LangGraph、Spring AI、扣子这类平台都提供了现成的 Agent 编排能力用框架能快速起步但也会带来抽象层的束缚。我的判断标准是看任务复杂度和团队情况。如果任务流程相对标准团队对框架也熟悉那用框架效率高。如果任务有大量定制逻辑或者需要对循环、状态做精细控制那自己写核心循环反而更清晰。框架不是越重越好很多时候一个几百行的自研循环比引入一整套框架更好维护。还有一点框架的版本迭代很快API 经常变。如果项目周期长要评估框架升级带来的维护成本。我一般会把核心业务逻辑和框架解耦这样即使换框架迁移成本也可控。2.2 决策二单 Agent 还是多 Agent多 Agent 是这两年的热门话题但不是所有场景都需要。多 Agent 的好处是职责分离、可以并行、每个 Agent 的上下文更聚焦坏处是通信成本高、调试困难、容易出现互相等待或者死循环。我的经验是能用单 Agent 解决的就别上多 Agent。只有当任务确实可以清晰拆分成几个独立子领域且子任务之间耦合度低时多 Agent 才有明显收益。比如一个调研写作审核的流程拆成三个 Agent 就比较自然。但如果只是简单的工具调用单 Agent 完全够用。如果决定用多 Agent通信协议要提前设计好。Agent 之间传什么、用什么格式、谁负责汇总这些不定义清楚后期会非常乱。2.3 决策三工具怎么组织和暴露工具的组织方式直接影响模型的调用准确率。前面提到工具数量要控制那多了怎么办我的做法是分层暴露。第一层是路由根据用户意图先判断大概需要哪一类工具第二层才是把该类下的具体工具暴露给模型。这样每次模型看到的工具数量都可控。另一种做法是给工具打标签让模型先选标签再选工具效果类似。工具的命名也要讲究。名称要能自解释用动词开头比如search_orders、send_notification别用tool1、func_a这种。参数名同样要清晰模型是靠这些字面信息做判断的。2.4 决策四循环怎么终止终止条件的设计是 Agent 稳定性的关键。我一般会设多重保险模型主动声明完成、达到最大轮数、连续 N 轮没有产生有效动作、检测到重复调用同一工具且参数相同。其中检测重复调用这个特别有用。模型有时候会陷入死循环反复调同一个工具拿同样的结果。加一个重复检测发现连续两次调用完全一样就中断能省下不少 Token。最大轮数的设定要结合任务特点。我做过一个数据查询类的 Agent平均 3 到 5 轮就完成最大设 10 轮足够但一个复杂的报告生成 Agent可能要十几轮那就得放宽。这个值最好做成可配置的方便按场景调整。2.5 决策五状态和上下文怎么管状态管理是 Agent 工程里最琐碎也最容易出错的部分。我的原则是区分必须进上下文和可以外置的信息。必须进上下文的是当前任务目标、关键决策依据、最近几步的操作和结果。可以外置的是大块的原始数据、历史中间结果、工具返回的完整内容。外置的信息在上下文里只留一个引用或者摘要需要时再取。这样做的好处是上下文增长可控模型注意力也更集中。实现上可以用一个状态对象统一管理每一步更新状态而不是往消息列表里无脑追加。2.6 决策六错误怎么处理和恢复Agent 运行中出错是必然的关键是出错后怎么办。我把错误分成三类可重试的网络抖动、临时超时、可降级的某个工具不可用但有替代方案、不可恢复的参数错误、权限不足。可重试的直接重试但要设上限可降级的让模型决策是否走替代路径不可恢复的要把错误信息清晰地反馈给模型让它决定是换个方式还是终止任务。最忌讳的是把原始异常直接抛出去模型看不懂用户也看不懂。错误信息最好转成自然语言比如查询订单失败原因是订单号格式不正确而不是KeyError: order_id。模型看到前者能自己纠正看到后者只能干瞪眼。2.7 决策七怎么评估和迭代Agent 上线不是终点评估和迭代才是长期工作。评估不能只看最终结果对不对还要看过程是否合理、成本是否可接受、延迟是否达标。我一般会建一个小规模的评测集覆盖典型场景和边界情况每次改动后跑一遍看通过率和平均轮数、平均 Token 消耗的变化。过程指标往往比结果指标更能发现问题比如通过率没降但平均轮数涨了说明效率在下降。线上还要有日志和追踪把每一步的输入输出都记下来出问题时能复盘。这块投入不能省否则线上出问题只能靠猜。3. 工具调用里那些文档不会写的细节工具调用是 Agent 最核心的能力也是问题最集中的地方。这一节专门聊聊实际开发中遇到的细节。3.1 参数校验不能只靠模型模型生成工具参数时格式错误、类型错误、缺字段都是常事。虽然现在很多模型支持结构化输出但也不能完全信任。我的做法是在执行层加一道参数校验用 schema 验证不通过就返回明确的错误提示让模型重试。校验要给出具体的错误位置比如参数 start_date 格式应为 YYYY-MM-DD当前值为 2024/1/1这样模型才知道怎么改。笼统地说参数错误模型只能瞎猜。3.2 工具返回要控制体积工具返回的内容如果太大会迅速吃掉上下文。我遇到过查询接口一次返回几百条记录的情况直接导致后续几轮全部超窗。解决办法是在工具层做截断和摘要。比如只返回前 N 条或者返回统计摘要加少量样本。如果模型确实需要全量数据再提供一个分页工具让它按需取。原则是默认返回精简结果需要细节时再单独获取。3.3 并行调用要谨慎有些框架支持模型一次返回多个工具调用然后并行执行。这在查询类场景能提速但要注意几点并行调用的工具之间不能有依赖有副作用的操作不要并行并行结果返回时要和调用一一对应别搞混了。我一般只在纯查询场景开并行涉及写操作的还是串行执行稳妥优先。4. 循环机制Agent 的心跳与刹车循环是 Agent 的灵魂但也是最容易失控的地方。这一节展开讲讲循环的设计。4.1 一轮循环里到底发生了什么一轮完整的循环大致是这样把当前上下文发给模型模型返回要么是最终答案要么是一个或多个工具调用请求执行工具拿到结果把结果追加到上下文进入下一轮。理解这个流程很重要因为它决定了上下文是怎么增长的。每一轮都会增加模型的输出和工具的结果两部分所以轮数越多上下文越大。这也是为什么前面强调要做上下文管理。4.2 怎么判断该继续还是该停除了硬性的轮数限制还要有软性的判断。我常用的信号有模型输出里明确表示任务完成、模型不再请求工具调用而是直接给答案、连续几轮没有新的有效信息产生。其中不再请求工具调用是最自然的终止信号说明模型认为信息够了。但如果模型一直请求工具却拿不到有用结果就要靠重复检测和轮数上限来兜底。4.3 循环里的状态一致性多轮循环中状态的一致性很容易被破坏。比如模型在第一轮决定查 A 表第三轮又忘了查过重复查一遍。这通常是因为上下文里的信息组织得不好模型没记住。我的做法是在上下文里维护一个简明的已完成事项列表每轮更新让模型一眼能看到做过什么。这个列表不用很长几个关键词就够但能显著减少重复劳动。5. 从 Demo 到生产那些绕不过去的坎Demo 跑通只是开始真正上线要面对的问题完全是另一个量级。5.1 并发下的状态隔离单机跑 Demo 时状态存在内存里没问题但一旦并发上来多个会话的状态必须严格隔离。我见过因为状态对象被共享导致会话串号的 bug排查起来非常痛苦。做法很简单每个会话一个独立的状态实例用会话 ID 做键。如果用框架要确认框架的状态管理是不是线程安全的不确定就自己加一层隔离。5.2 成本控制Agent 的 Token 消耗比普通对话高得多因为每一轮都要把完整上下文发一遍。一个十几轮的任务Token 消耗可能是单次对话的几十倍。控制成本的手段有几个压缩上下文、减少不必要的轮数、子任务用轻量模型、缓存重复的工具结果。其中缓存特别有效很多查询类工具在短时间内结果是一样的缓存能省下大量调用。5.3 可观测性线上 Agent 出问题时如果没有详细的日志基本没法排查。我一般会记录每一轮的完整输入输出、工具调用参数和结果、耗时、Token 消耗。这些数据既能用于排错也能用于后续优化。日志要注意脱敏用户隐私和敏感数据不能明文记录。这块要提前设计事后补很麻烦。6. 几个真实场景的取舍思路理论讲完了说几个具体场景看看决策是怎么落地的。6.1 客服类 Agent这类场景流程相对固定我倾向于用显式规划加单 Agent。工具主要是查订单、查知识库、创建工单这几类数量可控。循环轮数一般不多因为大部分问题几轮就能解决。重点是权限控制涉及退款、改地址这类操作要加确认。6.2 数据分析类 Agent这类场景探索性强适合隐式规划。工具是各种查询和计算接口返回结果可能很大必须做截断。循环轮数可能较多要设合理的上限。成本控制是重点因为查询类操作容易反复执行。6.3 内容生成类 Agent这类场景对输出格式要求高约束层要做足。工具调用相对少主要是检索素材。评估时不能只看生成质量还要看事实准确性最好加一道校验环节。7. 我踩过的几个典型坑最后分享几个具体的坑都是真金白银换来的教训。第一个是工具描述里的歧义。有两个工具功能相近描述没写清楚区别结果模型总是选错。后来在描述里明确写了各自适用场景问题才解决。工具描述真的要当成产品文案来写。第二个是循环没有硬上限。早期有个版本忘了设最大轮数结果遇到一个模型判断不了的情况它就一直循环一晚上烧掉不少额度。从那以后最大轮数成了我的必设项。第三个是错误信息太技术化。工具报错直接把异常抛给模型模型完全不知道怎么处理只能重复调用。改成自然语言描述后模型能自己调整参数重试成功率明显提升。第四个是上下文没去重。多轮循环里同样的信息被反复追加上下文迅速膨胀。加了去重逻辑后同样的任务 Token 消耗降了将近一半。这些坑说起来都不复杂但没踩过就是想不到。Agent 工程就是这样概念不难难的是把这些细节都处理到位。希望这些经验能帮你少走点弯路。