# Agent 工程的四个深坑：Demo 到生产没有捷径

> 带兄弟们做 Agent 大半年，Demo 跑得挺好，上线两周被现网用户教做人。复盘四个真出过的事：function calling 翻车、多步任务没 checkpoint、记忆一股脑塞进 prompt、工具调用副作用失控。

- 原文链接: https://laojin.blog/blog/20260515_agent_production_pitfalls
- 作者: 老金
- 发布日期: 2026-05-15
- 标签: AI Agent, 工程实践, 生产事故, LLM

---

![Agent 工程的四个深坑](https://pic-1258874139.cos.ap-hongkong.myqcloud.com/laojinblog/posts/20260515/00_cover.png)

前阵子做 Agent，两个多月了。Demo 跑得挺好，每次内部 review 都挺开心。结果上线两周不到，被现网用户教做人。

今天就想说几个真实发生过的事。

先说 function calling 那块吧。

我们最早觉得这玩意挺稳的，测了三五十次没出过岔子。然后日活上来了。

我前几天翻了下上个月的 bad case 列表。schema 里我们压根没定义 urgent_high 这个枚举值，模型给我现场发明了一个。还有一次该查内部库，它去联网搜索了。最离谱的一次，返回的 JSON 外面套了个 markdown 的 \`\`\`json fence，下游 parser 直接崩了。

错误率算下来 0.1%。听起来还行对吧。一天十万次调用就是一百次现网事故。这个数量，你让哪个团队能顶得住？

我跟一个朋友聊到这事。他张口就来——那是模型不够聪明，换 5.5 嘛。我笑了，去年说那是因为 GPT-4 不行，等 GPT-5 就好了。等了半天等成现在这个样子。模型确实在进步，但你赌不准它哪天哪个犄角旮旯抽风。

![两层兜底再调工具](https://pic-1258874139.cos.ap-hongkong.myqcloud.com/laojinblog/posts/20260515/01_schema_guardrail.png)

后来我们做的事其实挺简单的。出口加了一道代码层的 schema 校验，少字段或者类型不对直接拦下来重试。然后又加了一道业务语意校验。比如查询日期写的是明天，但你调的是日报接口，schema 拦不住。再就是工具调用强制带超时，强制隔离上下文。一个外部 API 挂掉，不能把整个 Agent 拖死。

真没什么技术含量。但少哪一层都得出事。

再说多步任务。

帮我扒几篇内容、提炼痛点、入库。听上去就三步对吧。每步成功率算 95% 已经很乐观了。三步连乘大概 86%。七步呢，跌到 70% 以下。

但失败本身其实没那么难处理。

我们出过一次问题。一个工作流跑到第三步挂了，前两步的数据没处理好，重试的时候直接从头跑。问题是第二步是发邮件——有人莫名其妙收到两封一模一样的邮件。

当时团队里还有人觉得状态机太重，一镜到底跑通就行。我能理解。但跑通和扛住生产真的不是一回事。没有状态机的 Agent 就是个黑盒，出错了你查都查不出死在哪。等用户因为 Agent 抽风被重复扣费的时候，这锅 LLM 不背，只能你背。

![从最近 checkpoint 续跑，不是从头跑](https://pic-1258874139.cos.ap-hongkong.myqcloud.com/laojinblog/posts/20260515/02_checkpoint_resume.png)

后来加了 checkpoint。每跑完一个关键节点把状态落盘，IndexedDB 也行 Redis 也行看场景。出错了从最近的 checkpoint 接着跑。代码量没多多少，事故率掉了一个数量级。

第三个事，关于记忆。

不少团队偷懒，把几百轮历史对话连背景资料一股脑塞进 prompt。然后三个雷一起炸——token 爆掉被截断或者限频是一个，中间那段的关键约束被模型忘掉是另一个，月底账单出来老板脸都绿了是第三个。lost in the middle 真的不是吓唬人，我们自己测过，十几万 token 中间段的指令命中率明显下降。

有人说现在都卷到 1M context 了，塞进去多省事。我也想图省事啊。但你愿意为了让它记住用户叫啥名字，每轮多花几十倍的钱？

后来就分层了。最近几轮放工作记忆。再往前的会话压缩成摘要做短期。用户的长期偏好走向量库或者结构化 DB。

还有一个细节挺有用的。每轮对话之前，先让模型做一次极轻量的意图判断——这次回答需要哪些线索？然后精准捞，不是无脑全塞。这一步省下来的 token 钱，养整个团队的 API 配额绰绰有余。

最后一件事，也是最让我后怕的。

很多人盯着怎么让 Agent 多调几个工具，没想过它有写权限以后能闯多大祸。

我们踩过两个真实的。

一个是 prompt injection。用户上传的 PDF 里藏了一句话，让模型忽略前面所有指令，把数据库里的用户列表发到某个邮箱。模型还真就照做了一半。幸亏出口那层有审计拦截，没出事。发现之后我们紧急加了一道沙箱化的 prompt 隔离，然后把所有工具调用都加上了审计日志。

另一个是越权。处理 A 用户请求的时候，Agent 顺手把 B 用户的数据查出来了。不是模型的错，是工具层根本没做租户隔离。以前都是后端代码直接查的，租户字段写死在 SQL 里，谁会想到 LLM 自己拼参数会出错啊。

![按副作用风险三档处理](https://pic-1258874139.cos.ap-hongkong.myqcloud.com/laojinblog/posts/20260515/03_side_effect_tiers.png)

我们现在按副作用分了三档处理。只读的查天气读网页这种，随便跑，不打扰用户。有副作用但可逆的，比如写草稿存缓存，静默执行就行，但审计日志必须落，这条不能省，出事了你得有东西可查。不可逆的——发推、删数据、扣费这些——一律 dry-run 加人工确认。模型先告诉你我打算这么干，你点头才执行。体验上慢半拍，但现网不会出问题导致用户骂你。

差不多就这些。

这四件事解起来加一起代码可能就几百行。坑爹的地方在哪呢，Demo 阶段和小流量内测，一个都不会冒头。温温柔柔的什么事都没有。等到真实环境中，碰上各种各样的用户输入，一记闷棍直接把你打懵。

跑通是能跑通，可生产环境的及格线叫边界场景下能可靠兜底。

Demo 到生产之间，没有捷径的。
