在 AI Agent 的开发过程中,从 demo 跑通到生产可用之间有很长的路。很多问题不是架构设计阶段能预见的,而是在实际运行中才暴露出来。这篇文章整理了 5 个高频踩坑点,以及对应的排查和解决思路,希望能帮同样在做 Agent 开发的团队少走弯路。
坑 1:Tool Call 解析失败,Agent 卡死在循环里
表现: Agent 调用工具时,LLM 返回的 JSON 格式不合规(多了逗号、缺了引号、混入了自然语言解释),解析失败后 Agent 不知道下一步该干什么,陷入重试死循环或直接报错退出。
为什么容易忽略: 开发阶段用 GPT-4 级别模型测试,格式问题极少出现。一旦换成成本更低的模型(7B-14B 本地模型或 DeepSeek 等),格式稳定性明显下降,问题集中爆发。
排查思路:
- 在 tool call 解析层加一个"宽容模式":先尝试严格 JSON 解析,失败后用正则提取关键字段(function name、arguments),能救回大部分格式偏差的情况
- 设置最大重试次数(建议 2-3 次),超过后走 fallback 路径,而不是无限重试
- 记录每次解析失败的原始 LLM 输出,定期分析失败模式。很多时候是 prompt 里的 tool 定义方式导致模型容易输出歧义格式
- 如果用的是本地小模型,考虑在 prompt 中给一个严格的输出模板示例,比"请按 JSON 格式返回"有效得多
坑 2:多轮对话记忆溢出,上下文窗口悄悄被塞满
表现: Agent 在前几轮对话中表现正常,到第 15-20 轮时开始"失忆"或回答质量明显下降。更隐蔽的情况是:Agent 没有报错,但悄悄丢掉了早期的关键信息,导致后续决策出错。
为什么容易忽略: 开发阶段测试通常只跑 3-5 轮对话就过了。生产环境中用户一个 session 可能有 30-50 轮交互,上下文长度问题被测试覆盖不到。
排查思路:
- 明确区分"短期记忆"和"长期记忆":短期记忆只保留最近 N 轮完整对话,长期记忆用摘要压缩存储
- 实现滑动窗口机制:保留系统提示词 + 最近 N 轮对话 + 关键上下文摘要,总 token 数控制在模型窗口的 70-80%
- 对关键信息(用户姓名、任务目标、已完成步骤)做显式提取,存入结构化状态,而不是依赖 LLM 从历史对话中自己找
- 加入 token 计数监控:当 context 接近上限时主动触发压缩,不要等到截断才发现问题
坑 3:异步工具调用超时,没有合理的降级策略
表现: Agent 调用外部 API 或执行耗时操作(网页抓取、文件处理、数据库查询)时,偶尔超时。没有超时处理机制的情况下,整个 Agent 链路阻塞,用户看到的是长时间无响应。
为什么容易忽略: 本地开发环境网络稳定、数据量小、API 响应快。生产环境中网络波动、大数据集、第三方服务不稳定等因素叠加,超时变成常态。
排查思路:
- 每个工具调用设置明确的超时阈值(建议根据工具类型分级:本地操作 5s、API 调用 15s、复杂任务 60s)
- 超时后的降级策略要提前设计:是返回部分结果、还是切换备选工具、还是告知用户"这个操作需要更多时间"
- 对同一工具的连续失败做熔断处理:连续 3 次超时后暂停调用该工具 5 分钟,避免雪崩
- 耗时操作考虑异步化:Agent 先告知用户"正在处理",后台完成后推送结果,而不是同步阻塞等待
坑 4:日志全是自然语言,事后排查像大海捞针
表现: Agent 出了问题想排查原因,打开日志一看全是 LLM 的自然语言输出,几百行对话记录,根本找不到"它为什么做了这个决定"。
为什么容易忽略: 传统软件的日志是结构化的(时间戳 + 级别 + 模块 + 消息)。Agent 开发中很多人只记录了 LLM 的输入输出原文,没有做结构化处理,觉得"反正都在里面了"。
排查思路:
- 每次 Agent 决策点(选择工具、规划步骤、执行操作)都打结构化日志,至少包含:时间戳、决策类型、输入摘要、输出结果、耗时
- LLM 原文日志单独存一路(debug 用),结构化日志走另一路(监控和告警用)
- 给每个 Agent session 分配唯一 trace_id,跨工具调用时传递,方便串联一次完整任务的全部步骤
- 在关键决策点记录"Agent 此时的状态":当前任务目标、已完成步骤、可用工具列表。出问题时能快速还原当时的决策上下文
坑 5:Prompt 版本管理失控,改了一个字全链路崩了
表现: 为了修复某个边界 case,调整了 system prompt 里的一句话,结果其他原本正常的场景开始出错。回滚后发现上一个版本也记不清了。多人协作时更混乱——不知道谁改了什么、什么时候改的、为什么改。
为什么容易忽略: 代码有 Git 管理,但 prompt 经常散落在代码里的字符串常量中,甚至存在数据库或配置文件里,没有被正式纳入版本管理体系。
排查思路:
- 把所有 prompt 抽出来独立管理,用文件(如 prompts/agent_system.md)而非代码内字符串存储
- 纳入 Git 版本控制,每次修改写清楚 commit message:改了什么、为了解决什么问题
- 建立 prompt 的回归测试:准备 10-20 个典型用例,每次修改 prompt 后跑一遍,确认没有引入新问题
- 如果团队多人维护 prompt,建议走 PR 流程,至少有一个人 review。prompt 的改动影响面比看起来大
通用建议:评估先行
以上 5 个问题有一个共性:都是在"开发阶段看着没问题,上线后才暴露"。根本原因是 Agent 的行为有随机性,同一个输入跑两次可能走不同路径。
应对这种不确定性,比较实用的方法是建立一个轻量的评估体系:
- 准备一组覆盖核心场景的测试用例(不需要很多,20-30 个够了)
- 每次改动后自动跑一遍,统计成功率和平均步骤数
- 跟踪趋势:这周的通过率比上周高还是低?哪些 case 变得不稳定了?
有了这个基础,大部分问题可以在合入前发现,而不是等用户反馈。
延伸:端侧 Agent 的特殊考量
上面的问题在所有 Agent 项目中都会遇到。如果 Agent 运行在本地设备上(而非云端),还有一些额外的约束:
- 模型更小,tool call 格式稳定性更差 → 坑 1 的宽容解析层更加必要
- 没有云端的弹性资源,内存和算力有硬上限 → 坑 2 的记忆管理必须更精细
- 不能依赖外部 API 做关键路径 → 坑 3 的离线 fallback 是刚需
明略科技开源的 Mano-P 在端侧 GUI Agent 的工程实践中积累了不少经验。这是一个完全在本地运行的 Agent(Apple M4 + 32GB RAM,4B 量化模型,峰值内存 4.3GB),在 OSWorld 基准中排名第一(58.2%)。
对端侧 Agent 开发感兴趣的可以看看源码和⭐:github.com/Mininglamp-…(Apache 2.0)