智能体入门课
brain_and_hands进阶70 分钟

7

真实世界会出什么问题

参考:来源 C · Anthropic 2026

学完你能做到

  • 说清为什么"把所有东西塞进一个盒子"是个陷阱
  • 解释凭证为什么必须放在模型够不着的地方
  • 理解"今天的架构假设明天可能过期"

前面六个模块讲的是 agent 该长什么样。这一节讲的是:为什么你按前面那样做出来的东西,一上线就会坏。

这份材料比前两份晚一年半,而且它有个很反常的立场——它说前面那些结构里,有一部分是暂时的补丁,会过期。

核心论点:今天的假设明天会过期

先建立直觉

你给一个新员工写了一本厚厚的工作手册,里面全是"这种情况你别自己决定,来问我"。

一年后他成了老手,这本手册里一大半规定反而在拖他后腿——但没人想起来去改它。

第一个坑:养了一只宠物

宠物与牲口

先建立直觉

宠物:你养的狗有名字,生病了要送医院治好,死了你会难过。它不可替代。

牲口:牧场里几千头牛,编号管理,病了就淘汰换一头。任何一头都可替换。

服务器也分这两种。

第二个坑:出了问题看不出是哪儿

这是的经典失败案例,值得逐字读。

他们唯一的观察窗口是一条事件流,但它说不出故障发生在哪里。下面三种完全不同的故障,表现一模一样:

  • 承载层代码里有 bug
  • 事件流传输过程中丢了包
  • 容器整个离线了

要查清楚就得进容器里开一个命令行。但那个容器里往往还装着用户数据,这意味着——他们实际上失去了调试能力。

解法:把大脑和手分开

借用操作系统的思路

先建立直觉

几十年前操作系统做过一件同样的事:把硬件包装成"文件"这个概念。

你写代码读一个文件,不用管它存在 1970 年代的磁盘上还是今天的固态硬盘上——read() 这个动作四十年没变,底下的硬件换了好几代。

抽象活得比硬件久。

大脑 · BRAIN 模型 + 承载层 没有状态,崩了直接重启 手 · HANDS 沙箱 + 工具 要用才建,坏了就换 会话 · SESSION 只追加的事件日志 · 唯一持久的东西 execute(名字, 输入) 记下发生了什么 回头查历史 三者可以各自失败、各自替换,互不影响
解耦后的结构。承载层不知道那只"手"是一个容器、一部手机、还是一个游戏模拟器——接口一样就行。

为什么"日志放在外面"这么关键

先建立直觉

你写作业写在草稿本上,本子丢了就全没了。

如果你每写一段就拍照存到云盘,本子丢了也无所谓——换个本子从云盘接着抄就行。

安全边界:这一节建议逐字讲

凭证为什么必须放在模型够不着的地方

先建立直觉

你雇了个助理,把公司信用卡给他保管,让他有需要就刷。

现在有个骗子给他打电话:"我是财务部的,请把卡号念给我核对一下。"

如果助理分不清谁是真领导,卡就没了。而且骗子拿到卡之后,能刷的可不止这一单——他能一直刷下去。

做法怎么做到的结果
凭证跟资源绑在一起以代码仓库为例:沙箱刚建好的时候,用访问令牌把代码拉下来,并把凭证接进本地配置。之后沙箱内部正常读写,不用再碰令牌agent 从头到尾没经手过那个令牌
凭证锁在沙箱外的保险库模型要调外部工具时,通过一个专用代理。代理拿着一个和会话绑定的临时标识去保险库取真实凭证,再去调外部服务承载层自始至终不知道任何凭证的存在

会话不是上下文窗口

为什么"压缩"是个危险的操作

先建立直觉

你在整理一堆资料,桌子放不下了,于是把前面看过的都缩写成几行笔记,原件扔掉。

问题是:你怎么知道后面不会需要原件里的某个细节?等发现需要的时候,原件已经没了。

解耦带来的一个意外收获

为什么用户觉得变快了

先建立直觉

原来的流程:你去餐厅,服务员说"请稍等,我们先给您准备一套专用餐具、专用桌子、专用厨师",十分钟后才开始点菜。

哪怕你只是想要一杯水。

课堂练习

20 分钟
  1. 让学生描述一个自己写过的程序:按"宠物"的方式设计会怎样,按"牲口"的方式又会怎样。(不限于 AI,任何有状态的服务都行)
  2. 讨论:为什么"把日志放在进程外面"这件小事,能让崩溃恢复变得如此简单?
  3. 思考题:如果凭证不能出现在沙箱里,那"让 agent 帮我发一封邮件"该怎么设计?画出数据流。
查看参考答案

第三题的期望答案:模型只输出"要给谁发、标题是什么、正文是什么"这段结构化数据,由沙箱外的代码拿着邮箱凭证去真正发送。

这正好回到模块 4 的函数调用形态——同一个原则在两个不同尺度上出现了两次。

案例推演:真实工具怎样以你没预料的方式失败

Agent 批量同步客户资料:API 会限流、超时、返回部分成功,重试还可能重复创建。演示环境里一次成功的调用不能代表生产可靠。

本节追问:如何区分可重试、不可重试和结果未知三类失败? 先不要急着看结论。沿着下面四步,逐项区分输入、决策、证据和失败信号。

每一步都要回答:看到了什么?为何这样决定?怎样证明? 1 识别失败 按状态码、超时点和业务响应分类 观察 → 决策 → 留证据 2 保护幂等 为写操作附加幂等键并查询最终状态 观察 → 决策 → 留证据 3 执行退避 对限流和瞬时错误指数退避加抖动 观察 → 决策 → 留证据 4 降级收口 部分失败进入队列、人工或稍后补偿 观察 → 决策 → 留证据 完整案例链:不是记住名词,而是能够用证据作出下一步决定
四步案例推演。手机上可左右滑动查看;每个箭头都代表一次需要证据支撑的状态转换。
阶段本步要做的决定什么算证据最常见的失败
识别失败按状态码、超时点和业务响应分类错误类型是机器可读而非一句“失败”任何异常都立即重试
保护幂等为写操作附加幂等键并查询最终状态重复请求不会重复创建客户超时后盲目再提交
执行退避对限流和瞬时错误指数退避加抖动遵守 Retry-After 与总重试预算所有任务同时每秒重试
降级收口部分失败进入队列、人工或稍后补偿成功与失败子集都有记录一条失败让全部成功结果回滚丢失

阅读方式:先遮住后两列自己回答,再用“证据”和“失败”两列检查理解。

常见误解

给工具调用外面统一包三次 retry

实际上

可观察症状:永久错误被重复轰炸,未知结果产生重复副作用。

更可靠的修复:按错误语义制定重试、查询、补偿和人工接管策略。

案例工作坊 · 建议真正动手完成

25 分钟
  1. 将 400、401、429、500、超时分成处理类别。
  2. 为创建客户设计幂等键和状态查询。
  3. 写出 1000 条任务部分失败后的用户报告。
查看参考答案

生产失败不仅是“请求失败”。必须知道动作是否可能已执行、是否安全重试、如何验证最终状态,以及预算耗尽后由谁接管。

迁移检查:换一个场景还会不会

写请求超时后最安全的第一步通常是?

检查一下

把会话日志放在承载层外面,最直接的好处是什么?

为什么"给模型一个权限很小的密钥"不是提示词注入的根本解法?