通过一个.tar.gz误报为.zip的真实案例,展示AI Agent在无明确错误信息时如何系统化排查问题,而非盲目猜测外部系统故障。
我写了一个自动化脚本,用来向外部服务上传提交文件。上传成功了,但下一步返回了 403 Forbidden,响应里没有一个字的解释。
我和 Agent 是这样推进的:
"看起来是账号认证缺失" → 让用户完成手机验证
验证已经做了 → "那一定是权限方案变了" → 申请了一个不同的 key
那也不是原因 → "需要基于身份 ID 的验证" → 再次请求用户
三次我们都怀疑是对方系统的问题,三次全猜错了。真正的原因是:
压缩包打包成了 .zip,但那个服务只接受 .tar.gz。
改了格式之后,第一次尝试就通过了。中间已经过去两天,期间用户一直在找一个根本不存在的设置页面。本来 5 分钟就能查清楚的事情,被推到了人身上。
① 我们首先怀疑自己无法控制的那一方。承认自己的代码有问题是痛苦的,甩锅给对方系统是舒服的。更何况"认证问题"是个常见说辞,听起来很合理。
② 我们把某个东西叫"原因"却没去验证它。一旦说出"认证是原因",这句话就留在了记录里,下一个判断就在它的基础上叠加。两天的工时就这样搭在一个错误前提上。
AI Agent 受这两个偏见的影响比人类更甚。自信地生成看似合理的解释,正是语言模型擅长的事情。
遇到外部错误且没有说明原因时,始终按这个顺序检查:
而且这种说话方式本身也成了一条规则。
在验证之前,不说"原因",说"候选"。
这一个词保持了记录的纯洁。候选可以被抹掉,但原因会被下一个人当作事实来读。
如果存在多个候选,先建一个能把候选区分开的测试。不做测试就选一个,那不叫判断,那叫猜。
我们损失了两天的原因,就是从未把第三个测试彻底执行到底。我们把最便宜的测试推迟到了最后。
为了让 Agent 每次都遵循这个顺序,把它钉进规则文件里。
如果你在第三章里已经建好了记忆结构,这类事故也会被记录到 mistakes.md 里。记录的唯一目的,是防止同一个错误再发生第二次。
找到原因之后,别停那儿。留一个测试,让那种格式以后再也不可能被生成出来。
def test_submission_is_targz_not_zip():
path = build_submission()
assert path.suffix == ".gz" and path.name.endswith(".tar.gz"), \
def test_required_files_are_at_archive_root():
with tarfile.open(build_submission()) as tar:
names = tar.getnames()
关键是:在测试的消息里写清楚这个测试为什么存在。没有原因,六个月后有人(或某个 AI)会把它当作"看起来没必要的约束"而删掉。
如果你一路走到了尽头,真的需要人类伸手,这样说:
❌ "你只需要验证一下身份" —— 一个未经证实的断言。如果是错的,就是在浪费对方的时间。
⭕ "还有两个候选。A 30 秒就能查完,请先从 A 开始。"
请求也要带上顺序和理由。人不是无限的测试工具。
想要完整的系统?本书有 10 章,外加 4 个可直接使用的模板(CLAUDE.md 起步文件、记忆文件、审计清单、度量指南),每章都有实操部分。PDF 版 $19:https://dbsoul.gumroad.com/l/autonomous-ai-agents-claude-code
还不确定?前三章免费,同样的 PDF 格式:https://dbsoul.gumroad.com/l/autonomous-ai-agents-claude-code-free-sample
关于配置的问题欢迎在评论区留言——我会用实际发生了什么来回答,而不是理论。