
外面很多人把 Agent 说得神乎其神好像只要接个大模型、写两个工具函数就是一个能自主干活的智能体了。但真正放到生产环境、扛住线上流量之后你才会发现一个 Agent 能不能稳定跑下去根本不取决于模型有多聪明而是工程做得有多糙。我这两年在大厂里从零搭过 Agent 平台也接手过好几个从 POC 到生产的项目踩了一堆坑之后总结下来大厂 Agent 不崩核心就是把四件事做到位——编排、记忆、可观测、安全。这篇就把我实际落地过程中沉淀下来的经验拆开讲清楚给正在做 Agent 开发、或者准备把 Agent 推上线的同学一个参考。1. 先想清楚一件事Agent 崩不崩拼的是工程而不是模型很多人有个误区认为 Agent 效果差、不稳定是因为模型不够强。我见过不少团队领导一拍脑袋说“换更强的模型就行”结果换了 GPT 级别的模型该崩还是崩。真正的原因在于Agent 本质上是一个软件系统不是一次 API 调用。模型只负责其中“理解与决策”这一环而系统的稳定性取决于你有没有把流程、状态、数据、异常处理这些工程问题设计好。1.1 为什么大厂 Agent 看起来“不会崩”大厂的核心优势不是模型而是他们在工程上做得足够“笨”——把每个环节都设计了兜底而不是靠模型自由发挥。我举个例子之前我们做内部运维助手最早的方案是让模型自己决定调用哪个 API、参数怎么填结果模型经常发挥创意把参数格式搞错、调用顺序搞反。后来改成“流程模板 模型填槽”的模式模型只能决定关键参数执行路径由平台控制稳定性立刻上去了。再一个例子是重试机制。模型接口偶发超时、限流、返回格式不合法这些都是家常便饭。大厂的 Agent 框架普遍内置了指数退避重试、结果校验、降级策略。而很多独立开发的 Agent只做了一次 try-catch返回异常就直接给用户道歉这在线上是不可接受的。1.2 四个关键词直接决定 Agent 的生死我把决定 Agent 稳定性的因素归纳成四个词编排、记忆、可观测、安全。这四个词看起来分散其实是一条完整链路。编排决定 Agent 遇到多步任务时怎么走、走错了怎么办。记忆决定 Agent 在长对话、多轮任务里怎么保持上下文不丢、不串、不爆。可观测决定 Agent 出错时你能不能快速定位是模型的问题、工具的问题还是流程的问题。安全决定 Agent 拿着工具权限时会不会闯祸、被人恶意利用。这四个词对应了 Agent 从启动到执行再到结束的整个生命周期。任何一个环节出问题Agent 就会表现得像个不稳定的实习生——时灵时不灵你还不知道它哪根筋搭错了。下面我一个个展开讲。2. 第一件事任务编排不是让模型自由发挥而是“流程兜底”任务编排是整个 Agent 架构的骨架。我见过的所有线上翻车事故几乎都跟编排层设计得太自由有关。很多人受 ReAct 这类论文影响觉得 Agent 就应该是“模型循环思考-行动-观察”但实际上纯 ReAct 在复杂任务上的成功率根本无法保障。2.1 从 ReAct 到 DAG确定性优先的编排思维ReAct 的流程是模型自己决定下一步做什么这在 demo 里很惊艳但在生产环境就是灾难——你无法预判它会走哪条路也就无法预判它在哪一步会崩。大厂的做法通常是把任务拆成 DAG有向无环图也就是把复杂任务预先分解成步骤模型只负责在每个节点上做局部决策。我参与的一个合同审核 Agent 就是典型的 DAG 设计节点依次是“上传文件 → 解析提取 → 风险规则检查 → 模型总结 → 输出报告”。其中只有“风险规则检查”这一步会调用模型其他步骤全是确定性代码。这样即使模型在某一步抽风整个流程也不会失控最多是这一步的结果质量差一些。还有很多场景用到了Plan-and-Execute模式第一轮让模型生成执行计划后续每个步骤严格按计划执行每执行完一步就把结果追加进上下文。这比纯 ReAct 好的地方在于规划是一次性的后续执行过程不容易跑偏。当然如果任务本身是探索性的比如“帮我研究一下某个竞品”纯 ReAct 会更合适但这种场景通常也不追求“不崩”而是追求“结果丰富”。2.2 Harness 与 Agent 的区别很多人没搞明白在 Agent 框架里Harness 是我们经常听到但又容易混淆的概念。Harness 是跑 Agent 的“外壳”负责管理工具调用、解析模型输出、组织上下文Agent 本身则是“大脑”负责决定下一步做什么。简单类比Agent 是司机Harness 是汽车——司机决定往哪开但方向盘、刹车、油门能不能正常工作是汽车的事。我看到很多 Agent 崩掉问题其实出在 Harness 上而不是模型上。比如模型输出了一段带 markdown 的 JSON解析出错或者模型调用工具时参数格式差了一点Harness 没有做容错就直接报错。所以现在主流框架里Harness 都会做一层“宽容解析”——模型输出不完全合法时尝试修复而不是直接失败。我个人的建议是如果你在自研 Agent 框架一定不要把 Harness 和 Agent 逻辑耦合在一起。Harness 要做得“厚”一点把重试、校验、沙箱、日志全部沉淀进去这样换模型、换 Agent 策略时Harness 完全不用动。2.3 实操要点用状态机控制 Agent 的生命周期执行一个 Agent 任务本质上是一个状态流转过程。我推荐用状态机State Machine来管理而不是靠模型自己保证流程正确。状态一般包括状态说明异常处理idle任务初始化未开始无planning模型生成执行计划失败则降级为单步执行executing执行工具调用/子任务失败重试超时熔断observing处理工具返回结果结果解析失败清洗后重试waiting等待用户输入/人工审批超时自动挂起finished正常结束无failed无法自动恢复的错误记录快照转人工处理这么设计的好处是每一步都有明确的前置条件和后置动作你可以针对每个状态做监控、做告警、做恢复策略。比如 executing 状态连续重试 3 次还失败就进入 failed 状态并保存整个执行上下文快照方便后续排查或者人为诊断。我踩过的一个典型的坑是一开始为了“灵活”没有状态机直接靠模型描述来推进流程。结果有一次模型在中间步骤突然“失忆”开始胡说八道导致整个流程走进死胡同。后来改成状态机模型只负责在 specific state 里产出决策执行逻辑全部由代码控制再也没出现过这种“鬼打墙”式的问题。3. 第二件事记忆不是越长越好管理不好就是灾难Agent 的记忆问题本质上是上下文工程问题。很多人觉得给模型塞越多上下文它就越聪明实际上恰恰相反——上下文越长模型的注意力越分散越容易忽略关键信息还会带来 token 成本暴涨和响应延迟增加。大厂 Agent 的记忆系统核心工作不是“记住”而是“忘掉”——有策略地丢掉不重要的信息保留关键信息。3.1 上下文爆炸是怎么毁掉 Agent 的我接手过一个客服 Agent 项目最初的设计是每轮对话都拼接全部历史消息跑了不到两周就出问题了用户说了一句“刚刚我说那个事怎么样了”模型完全不知道用户指的是哪个事因为前面的关键信息已经被海量闲聊冲淡了。而且随着上下文增长单次请求的 token 费用直线上升响应时间从 1 秒涨到 5 秒以上用户体感非常差。这就是没有做记忆管理的典型症状。模型在处理长上下文时对中间部分信息的注意力会显著下降这就是所谓的“lost in the middle”现象。你塞进去 10 万 token模型真正用到的可能就几千 token其他全是噪音。3.2 分层记忆短期、工作、长期怎么划分我实践下来比较有效的方案是分层记忆分为三层短期记忆Short-term只保存当前任务或最近几轮对话通常作为 prompt 的有效部分直接传给模型。工作记忆Working保存当前执行计划、已执行步骤、中间结果让 Agent 能持续推进多步任务。长期记忆Long-term保存用户画像、历史偏好、总结性记忆通过检索按需注入而不是全量携带。举个例子一个购物推荐 Agent 的长期记忆里可能会有“用户偏好运动户外类产品”但这些不会全量塞进每次请求而是在用户提到“想买点东西”时通过向量检索把相关商品类目和历史行为注入到当前上下文。这样既保留了记忆又不会污染当前轮次的重点。3.3 记忆清洗与压缩的实操方法记忆管理最重要的一环是压缩与提炼。我这里分享两个我一直在用的方法第一个是滚动式摘要。当对话或任务日志超过一定长度比如 2000 token就调用模型对旧内容做一次摘要然后把摘要作为历史记忆存下来丢弃原始细节。这比直接截断效果要好得多因为截断可能把关键信息切掉。我一般会设置一个摘要触发阈值上下文接近模型窗口的 70% 时对最早 50% 的内容做摘要压缩然后继续执行。第二个是关键信息结构化抽取。从每轮对话中提取结构化信息用户的需求、提供的材料、确认过的决策存入数据库或 KV 存储。后续需要时用规则或模型检索出最相关的几条注入上下文。我常用的是把每轮对话抽象成 {time, user_intent, entities, action, result} 这样的结构比纯文本日志更容易检索。还有一个容易被忽略的点工具返回结果也要做记忆治理。Agent 调用搜索、查数据库后可能拿到很长的返回内容不能一股脑塞进上下文。我曾经调一个订单查询接口返回结果有 8000 多行直接导致后续决策质量急剧下降。后来加了“返回结果摘要”节点无论工具返回多少内容到模型之前都先做一轮摘要控制在 500 token 以内问题立刻解决。4. 第三件事可观测性决定你的 Agent 是“失控”还是“可控”Agent 系统的调试难度比传统后端高一个量级。传统后端你只要看报错堆栈基本能定位问题但 Agent 是“模型决策 工具调用 外部数据”的混合体任何一个环节出问题表象可能都一样——用户觉得“它变傻了”。没有一套完善的可观测体系你根本无从下手。4.1 没有 trace 的 Agent就是黑盒我接手的一些早期 Agent 项目日志就只有一句“agent execution terminated due to error”没有任何上下文数据这等于什么都没说。是模型输出异常是工具超时是 JSON 解析失败是触发了安全拦截你完全不知道。这种系统别说优化了连恢复正常都靠运气。所以我在任何 Agent 项目里第一件事就是加 trace链路追踪。每一个环节都要记录关键信息模型调用输入/输出 token 数、模型名、温度、耗时、返回内容是否合法。工具调用工具名、入参、出参大小、耗时、状态码、错误信息。流程节点节点名、进入时间、退出时间、是否走了异常分支。记忆操作检索到了什么、注入了什么、摘要压缩前后的大小。如果你用的是成熟的 Agent 框架很多 trace 能力是内置的如果是自研建议直接接 OpenTelemetry 标准每个 Agent 实例一个 trace ID贯穿一次完整任务。这样你可以在一个页面里看完整条执行链路就像调试普通接口一样方便。4.2 关键指标token 消耗、延迟、错误率、工具调用失败率光有 trace 还不够你还需要一套指标监控实时反映 Agent 的健康状态。我重点盯这几个指标预警信号应对措施token 消耗增速单任务 token 消耗异常增长检查是否上下文泄漏、记忆治理失效端到端延迟P95 延迟持续上涨检查模型响应、工具耗时、重试是否过多工具调用失败率失败率超过 5%检查工具接口稳定性、参数生成是否正确任务完成率完成率低于 90%检查编排逻辑、模型输出质量重试触发率重试次数过多搜索限流、超时配置以及解析容错率上下文压缩频率高频触发摘要说明单任务过长调整任务拆分逻辑我在搭建 Agent 监控面板时始终把一个指标放在第一位用户可感知的失败率。这个指标不是看 Agent 内部报了多少错而是看最终用户有没有得到他想要的答案或动作。很多内部错误可能被重试消化掉了用户无感那就不是严重问题但用户反馈“答非所问”即使系统内部没有任何报错那也是重大故障说明决策质量出了问题。4.3 一个简单的排查流程当 Agent 出问题时我一般按下面的顺序排查先看 trace 里有没有异常是模型层还是工具层还是流程层。如果是模型层回放当时的输入和输出看是不是 prompt 问题或者上下文信息不足。如果是工具层直接试一下工具接口看是不是外部依赖挂了。如果是流程层检查状态机看是不是走到了预期外的状态。检查记忆层确认注入的上下文是否准确有没有过期数据。有一招我觉得特别实用在 Agent 执行平台的每个关键节点都支持“重放”功能。也就是说我可以把某一次任务的全部输入和状态快照拿回来在测试环境里重新跑一次甚至在中间某个节点改一下 prompt 再跑。这比对着日志猜要高效太多了。目前一些开源 Agent 框架也开始支持这种 run replay 能力我建议自研平台一定要考虑做进去。5. 第四件事权限与安全是最后一道防线很多人把 Agent 安全当成上线前的合规检查其实这是大错特错。Agent 的安全问题是一旦发生就是大事故的问题。因为 Agent 手里拿着工具权限它的一句错误决策可能直接触发一笔转账、删除一条数据、发送一封邮件。在大厂里这甚至是 Agent 能不能上线的“一票否决项”。5.1 工具越权比模型幻觉更可怕我见过不少 Agent 事故最典型的几种是模型被 prompt injection 诱导调用不该调用的高危工具比如从“帮我查天气”被诱导成“帮我转账”。工具权限过大Agent 能访问它根本不需要的数据。比如一个只负责汇总日报的 Agent居然有数据库的写权限。用户在对话中上传了恶意文档文档内容里藏了指令模型读到后被带偏执行了恶意操作。这些事故的根源不是模型不够聪明而是权限管控太松。把工具权限全部交给模型决策等于把方向盘交给了一个容易被人忽悠的司机。5.2 最小权限、沙箱隔离、确认机制关于 Agent 安全我建议一定做三层防护第一层是最小权限原则。Agent 生态里每个 Agent 都能配置独立的访问凭证只给当前任务必需的最小权限。比如一个“汇总周报”的 Agent只能读周报相关数据不能碰任何写接口一个“发邮件”的 Agent只能调用发邮件工具的指定模板不能自由编辑任意收件人和内容。第二层是沙箱隔离。Agent 执行的代码、访问的网络、操作的文件系统都要跑在隔离环境里。往极端了说即便 Agent 被诱导执行了恶意脚本也只能影响沙箱不能触碰核心资产。我自己在给 Agent 做代码执行功能时用的是容器隔离加网络白名单确保 Agent 只能访问白名单内的内网服务出网全部禁止。第三层是风险操作的人工确认。凡是涉及转账、删除、发布、发送外部消息这类高风险动作一律走“Agent 发起 → 系统拦截 → 用户确认 → 再执行”的流程。技术实现上可以在工具层包一层 guard 函数检查目标操作的风险等级超过阈值就返回“需要用户授权”的状态由前端弹出确认按钮。5.3 Agent 安全的实操清单我把自己落地过的安全防线整理成一个清单你可以直接抄检查项具体要求凭证管理每个 Agent 独立 key不共用权限定期轮换工具白名单每个任务只能调用白名单内的工具严禁通配数据脱敏模型注入前过滤手机号、身份证、密钥等信息Prompt 注入防护对用户输入和外部内容做特殊标记与系统指令隔离高危操作审批高危动作必须人工确认且有操作审计记录沙箱隔离代码执行在容器内文件系统只读网络白名单操作审计每次工具调用都有完整留痕包括入参、出参、执行者限流配额单任务 token 上限、调用次数上限超限自动熔断安全这里我还想说一个反直觉的经验越“智能”的 Agent安全设计要越“笨”。不要相信模型能自己判断“这句话是不是恶意指令”它就是会被骗。你只有从架构上让它没有权限做危险的事才能真正安全。我之前参与过一个内部 Agent 平台最初把敏感操作权限都放开给模型理由是想“让 Agent 更自主”。结果测试时一条精心构造的 prompt 直接让 Agent 删了一张测试表。幸好是测试环境但这件事给团队提了个醒自主不等于放权安全必须硬编码在系统里。6. 常见问题与排查技巧实录最后这部分我把自己实际调试 Agent 时碰到的高频问题整理成一张速查表附带我用的排查思路和解决办法。如果你也正在被这些问题折磨可以直接对照操作。6.1 经典故障agent execution terminated due to error这个错误大概率不是模型不行而是中间某个环节没有被兜住。我遇到过的具体原因包括模型返回的 JSON 里有非法字符、工具超时未处理、上下文超出模型窗口、状态机进入了未定义状态等。排查步骤很简单第一步一定先看 trace定位错误发生在哪个节点。如果发生在模型节点就把模型的原始输出存下来再用宽松解析器重新解析一下如果发生在工具节点检查是不是工具接口超时或者返回数据格式不符。这个错误之所以臭名昭著是因为它本身不提供任何上下文只靠这句话你根本不知道发生了什么所以一定要配合 trace 数据一起去查。6.2 测试 Agent从单测到混沌Agent 的测试和普通后端不一样。普通后端是“输入固定断言输出”但 Agent 是“同样输入每次输出可能都不一样”。所以我们的测试策略要做成多层次的测试层级重点验证内容单元测试每个工具的入参出参、状态机状态转换是否正确模型输出校验测试模型输出格式、JSON 可解析性、意图分类准确性场景回归测试固定一批典型任务跑 10 次统计成功率是否达标对抗测试注入恶意 prompt、异常输入验证安全防护是否生效混沌测试随机让某个工具超时或返回异常验证重试和降级逻辑是否生效我尤其推荐场景回归测试用固定 seed 或者固定温度0来保证一定的可重复性。虽然模型仍然不完全确定但温度设为 0 时输出稳定性会提高很多。对于生产环境我通常要求核心场景的成功率不低于 90%低于这个数值就直接阻止发布。6.3 我的一些经验和体会按照我个人的经验Agent 想做到“能上线、不崩”精力分配大概是20% 花在模型调优上80% 花在工程兜底上。模型只是决策引擎真正决定用户体感的是你在这个引擎外面包了多厚的保护层。如果你刚开始做 Agent不要一上来就搞复杂的自主规划。先跑通一个“有限步骤 确定性流程 工具调用”的最小闭环把 trace 和监控接上再逐步放开自主性。每放开一个自由度都要先补上对应的兜底措施。这个顺序走对的话你的 Agent 会越做越稳反过来一上来就想全自主大概率是上线即翻车。最后分享一个我在实战中一直用的习惯每个 Agent 任务结束后都自动生成一份“执行摘要”记录这个 Agent 这次干了什么、调用了哪些工具、消耗了多少 token、有没有异常。这样你不仅能对外交代清楚 Agent 的行为也为后续优化积累了最真实的样本数据。做 Agent 开发和做传统后端最大的区别就是你不能完全信任代码之外的“智能部分”所以要靠工程手段把不确定性控制住。这套方法论执行到位了你的 Agent 距离“不崩”就不远了。