diff --git a/content/posts/forgot-who-it-is.md b/content/posts/forgot-who-it-is.md new file mode 100644 index 0000000..06cfb75 --- /dev/null +++ b/content/posts/forgot-who-it-is.md @@ -0,0 +1,62 @@ +--- +title: "它忘了自己是谁" +description: "会话重置清空了 4036 条历史之后,执行 Agent 拿管理员的身份建了单。根因不是权限漏洞,是更隐蔽的东西:它对「我是谁」的全部感知,建立在会被重启抹掉的对话记忆上。" +date: 2026-09-02T18:40:00+08:00 +draft: false +tags: + - AI Agent + - 架构 + - 身份 + - 事故复盘 +--- + +## 事故:五笔张冠李戴的审计记录 + +一次会话重置,清空了某执行 Agent 的 4036 条对话历史。紧接着它处理建单请求时,做了件危险的事:**操作人参数填了管理员**——建单、审核、修改、派单,五笔操作全部挂在错误的用户名下,直接污染了操作审计库。 + +排查权限体系:没有漏洞。代码逻辑:也是对的。问题出在一个更隐蔽的地方。 + +## 根因:它的「我是谁」是幻觉 + +两层反直觉的事实: + +**1. 它对身份的全部感知,来自对话记忆。** 会话没重置时,历史消息里出现过"我是谁",它就照着办;历史一清空,这个认知就跟着消失。之前 13 天里它还往自己的记忆库塞了上千条客户手机号——**「记忆」这个东西在 Agent 身上,既不可靠也不安全**。 + +**2. 运维文档里写着「从会话头部读用户 ID」——这是一条幻觉规则。** 文档假设了一个不存在的能力:框架压根没把用户 ID 拼进系统提示(实测相关钩子触发 0 次)。规则写得再清楚,读不到的信息就是不存在。 + +排查方向还被纠偏过一次:一开始在翻框架源码找拼接逻辑,用户一句「别翻源码,直接验证」——把真实消息跑一遍,看系统提示里到底有什么。答案:没有身份。 + +## 修复:五版补丁的演进 + +既然框架没给,那就框架来给。补丁迭代了五版,每一版都在教我们一件事: + +- **v1** 在消息通道层加身份前缀 → 私聊有效,群聊不覆盖 +- **v2** 群聊场景三重判断 → 补上群聊 +- **v3** 修幂等时发现诡异现象:**同一条消息出现双前缀**——消息处理管线把同一条消息构建了两次,两个通道各注入一次 +- **v4** 注入点迁移到「每请求单次必经路径」——从根上消除重复 +- **v5** 最终形态:在构建 Agent 的系统提示里写强指令(查成员映射表 → 显式传操作人 → 禁止猜测默认值),且身份信息**不进对话历史**——每请求重新构建,不累积 + +v5 还配了升级体检脚本:框架每次更新后自动检查补丁在位,防止悄悄丢失。 + +重启后第一个真实建单请求,操作人参数自动填对了。闭环。 + +## 同一天,它还「假装干了活」 + +身份只是今天 Agent 不可控性的其中一面。同一天另外三起,像四张面孔的同一个人: + +- **日报推送了两次**。Agent 第一次明明执行成功,却误判「输出被截断疑似失败」,自作主张「再跑一次拿完整输出」——重复推送到工作群。修复不是改 Agent 的判断,是给脚本加**当日去重标记**:推过就不再推 +- **巡检连续六次超时**。LLM 流式响应无首包时,并发信号量的槽不释放;定时任务的 120 秒超时只杀调用方,杀不掉底层挂死的流——并发池卡死。处置:超时放宽到 600 秒 + 这类任务迁移到系统级 crontab 直调脚本 +- **假运行第三例**。两个定时任务状态显示 success,实际从未真跑(文本型任务发到空会话,无人执行)——这正是上周 Agent 记忆污染反弹的根因:调度系统以为每天在清理,实际一天都没跑过 + +## 戒律 + +1. **身份必须在系统提示里。** 对话记忆会丢(重启/重置/压缩),文档规则可能依赖不存在的能力。凡「每次请求都必须成立」的东西,走框架的单次必经路径注入 +2. **执行真相只看业务日志。** 调度层说 success、Agent 回复了文本,都不等于脚本跑了。有没有开始/结束记录、写没写数据,以业务侧为准 +3. **幂等必须在脚本层。** Agent 会误判、会重试、会「验证性重跑」——推送类脚本一律加当日去重,不能指望上层永远判断正确 +4. **验证要实证,不要读码。** 「框架应该会拼进去」和「实际拼进去了」之间,隔着一整个生产事故 + +> Agent 的记忆、身份、甚至进程生死,都托管在基础设施手里。**凡是丢不起的,都别存在它的脑子里。** + +--- + +*本文已脱敏,不含真实用户名、工单号、域名或系统内部标识。*