AI生成代码的能力已不稀奇,但真正的风险在于开发者给AI的提示词往往省略了业务上下文——AI为不完整的世界写出了代码逻辑正确但业务错误的实现,而这类问题编译器测不出来。
AI 写代码已经变得非常擅长。
对于清晰且有边界限制的任务,AI 生成的代码比许多人手写的代码更干净、更快、更一致。它不会疲劳。在漫长的的一天之后,它不会忘记一个右括号。它可以在几秒钟内跨多个文件遵循一个已知模式。
AI 仍然会产生普通的编码错误,所以编译器、测试和代码审查不会消失。但这些错误对我来说已不再是问题中最有趣的部分。
更困难的失败往往在第一行代码生成之前就开始了。
我们打开一个强大的 AI 智能体,给它一个提示:
添加一个归档功能。
这也许就是它所知道的一切。
它不会自动知道"归档"在我们的业务中意味着什么。它不知道哪个服务拥有数据,哪些用户有权限,移动端应用期望什么,为什么存在一个旧的数据库规则,或者哪个后台任务仍然可以更改这条记录。
然后 AI 为我们描述的这个不完整的世界写出了干净的代码。
代码可能按照提示是正确的,但按照系统来说是错误的。
这就是我试图命名的想法。在旧的工作流中,我们经常在条件、查询、API 调用或状态变更中找到 bug。在 AI 智能体工作流中,bug 可能始于我们未能提供的信息。
我现在也会调试智能体周围的空间。
智能体知道这个项目是如何运作的吗?它看到规则了吗?它能找到正确的文档吗?它有合适的工具吗?它知道"完成"是什么意思吗?我能检查它做了什么吗?
有时候失败不在 src/ 中。它在我们为智能体构建的提示、指令、技能、工具、权限、检索或反馈循环中。
想象一个熟练工人进入一座沉默的工厂
想象一个熟练工人在周一早上到达一家工厂。
没有人给他一张地图。房间没有标注。安全规则藏在一本旧文件夹里。一些工具缺失了。他们的门禁卡能打开每扇门,包括他们永远不应该进入的房间。工作单只写着:"修好机器。"没有检查清单。
工人是有能力的。工厂没有为他做好准备。
如果他们修错了机器,用错了零件,或者在修好之前就停下来了,只怪工人就忽略了问题的一半。
这就是许多团队使用 AI 智能体的方式。他们选择一个强大的模型,指向一个大型仓库,写一个简短的请求,然后期望智能体理解那些没有人给它的、多年积累的决策。
编码智能体不仅仅是模型。它是一个由模型、指令、技能、工具、权限、记忆、仓库上下文和测试组成的系统。每个部分都可以帮助智能体成功。每个部分也可能会失败。
Anthropic 将这个更广泛的工作称为"上下文工程"。上下文可以包括系统指令、工具、外部数据、消息历史以及智能体工作时检索到的信息。Anthropic 也警告说上下文是有限的。给模型更多的文本并不能保证它会很好地使用正确的文本。[1]
模型很重要。环境也同样重要。
一个模糊的工单,五种不同的失败
假设我告诉一个智能体:
为客户项目添加一个归档功能。
智能体添加了一个 archived 字段,从主页隐藏已归档的项目,并编写了一个测试。代码编译通过。测试通过。智能体报告功能已完成。
然后我发现了缺失的部分:
我们的移动端应用仍然显示已归档的项目。
一个旧的后台任务仍然可以修改它们。
该项目使用软删除规则,智能体从未见过。
只有管理员才能归档项目,但 API 接受任何已登录的用户。
数据库变更没有回滚计划。
代码有 bug 吗?部分可能有。
但第一次失败发生得更早。智能体从未收到"归档"的完整含义。它不知道系统边界、安全规则或迁移流程。它的测试只证明了它自己发明的那一小部分行为。
当前的研究给我们一个有用的警告。在 SWE-Bench Pro 中,当任务描述包含人类添加的需求和接口细节时,智能体表现得好得多。GPT-5 High 解决了 25.9% 的这些任务,但当这些细节被移除时只有 8.4%。Claude Opus 4.1 从 22.7% 下降到 8.2%。[8]
这些数字不是通用的生产 bug 率。它们来自一个基准测试,而且这个基准测试有局限性。但方向很难忽视:系统告诉智能体的内容可以显著改变结果。
智能体需要入职培训,而不是一个巨大的提示
人类开发者不是通过阅读一个工单来学习一个成熟项目的。他们学习它的语言、边界、命令、习惯和历史。他们会问为什么存在一个奇怪的抽象。他们发现哪些规则是写下来的,哪些规则只存在于高级开发人员的头脑中。
智能体需要这个入职培训的实用版本。
OpenAI 的 Codex 在开始工作之前会读取分层的 AGENTS.md 文件。团队可以在仓库根目录放置通用指导,在子目录内放置更具体的指令。[2] 开放的 AGENTS.md 格式将文件描述为"智能体的 README",包含设置命令、测试、约定和其他项目知识。[3]
Claude Code 使用 CLAUDE.md 来实现类似的目的。它的文档包含一个重要的警告:Claude 将这些文件视为上下文,而不是强制执行的配置。它还建议简洁的指令,因为冗长或矛盾的文档会降低可靠的遵从性。[4]
这个差异很重要。
一条指令可以说"未经批准永不部署"。硬控制防止部署命令在没有批准的情况下运行。第一种引导行为。第二种执行边界。
好的智能体架构知道什么时候书面规则就足够了,什么时候系统需要在门上加锁。
答案不是把整个公司粘贴到上下文窗口中
当团队注意到智能体缺少上下文时,第一反应通常是给它一切。
每个源文件。每个设计文档。每个旧的讨论。每个日志。每条政策。
这就创造了不同的问题。重要的细节被无关的细节埋没了。旧的指令与新的冲突。智能体花时间阅读而不是工作。
更好的设计是给智能体一张小地图和通往更深知识的清晰路径。
Aider 的仓库地图是一个有用的例子。它给模型一个重要的文件、类、函数、类型和调用签名的紧凑视图。它选择适合 token 预算的内容,而不是将整个仓库倾倒到提示中。[7]
技能提供了另一层。Claude Code 技能可以打包可重用的过程、脚本、模板和参考资料。简短的技能描述保持可用以供发现,而完整的指令只在需要时才加载。[5]
MCP 提供了与外部系统的连接,如文件、数据库、API 和工具。[6] 这很重要,因为仓库很少是全部真相。需求可能在问题跟踪器中。失败可能在监控中。经过批准的设计可能在文档中。当前的 schema 可能在实时数据库中。
公司某处存在一个事实并不意味着智能体知道它。系统需要提供一条安全、可靠的路径。
提示是请求,不是整个系统
这就是我认为团队对提示的理解误区。
提示告诉智能体我们现在想要什么。它不应该被期望携带整个历史和产品设计。
当我告诉一个有经验的开发者"添加一个归档功能"时,这个简短的句子之所以有效,只是因为开发者已经与团队共享了大量上下文。他们了解产品、用户、架构、发布流程,以及在不清楚时该问谁。
给一个新的智能体相同的句子并不是相同的任务。
智能体可能理解每个单词,但仍缺乏这些单词背后的知识。如果它完全按照提示的要求构建,干净的代码也救不了我们缺失的上下文。
这就是为什么我将其视为信息 bug 或上下文 bug。提示到达了模型,但实现它所需的含义没有。
解决方案不是一个巨大、完美的提示。解决方案是一个为智能体准备好的系统:稳定的项目指令、可发现的技能、最新的文档、有用的工具、安全的访问权限、独立的测试,以及一种寻求帮助的方式。
在责怪智能体之前,我的 BRIEF 检查
我现在用五个问题来思考智能体设置。它们共同构成了 BRIEF。
方位:它知道自己在哪吗?
智能体需要一张仓库和系统的简略地图。
哪个服务拥有数据?验证应该放在哪里?哪些术语有特殊含义?哪些旧的决策必须保留?
架构决策记录(Architecture Decision Records)之所以有用,是因为它们保留了做出某个有意义决策的原因,而不仅仅是代码今天长什么样。[13] 一个只看到当前代码的智能体,可能会"清理掉"某些有存在理由的东西。
有用的导航参考包括:一份精简的 AGENTS.md、系统架构图、术语表、仓库地图,以及重要决策的链接。
规则:它知道这里的工作是怎么做的吗?
智能体需要遵循这里的"家规"。
这可能包括代码规范、数据处理策略、迁移步骤、受保护的文件、必要的评审流程,以及意味着"停下来询问人类"的条件。
保持这些规则简短且具体。如果两条指令相互矛盾,要修复指令本身,而不是指望模型选择正确的那一条。
当某条规则绝对不能被打破时,要用权限、钩子、受保护分支、策略检查或审批门来强制执行。不要只依赖一段文字。
实现与身份:它有正确的工具和访问权限吗?
机械师需要正确的扳手。编码智能体可能需要搜索功能、测试工具、构建工具、日志、问题跟踪器或 API 文档。
缺少工具会迫使智能体去猜测。过多的访问权限则会造成更大的危险。
NIST 将最小权限定义为:只赋予用户或进程执行其任务所需的最低访问权限。[11] 这一原则同样适用于智能体设计。默认使用只读访问。将开发环境与生产环境分离。对破坏性操作要求审批。只给智能体一把任务钥匙,而不是主钥匙。
完成标准:它能证明工作完成了吗?
"让它能跑"不是终点线。
智能体需要能够运行的检查项:测试、构建、类型检查、安全扫描、预期截图、验收示例或已知输出。Scrum 指南中"完成的定义"对团队也有同样的整体观点:工作需要一个对所需质量状态的共同描述,才能算完成。[14]
但测试本身也可能出错或不完整。
SWE-ABS 对已经通过 SWE-Bench Verified 的 11,041 个补丁加强了测试。更强的测试套件拒绝了其中 2,184 个,占比 19.78%。[9] 这不意味着生产补丁中有五分之一是坏的。它的含义更窄,但仍很重要:弱的评估器可以让一个不正确的补丁看起来是成功的。
智能体不应该是其任务、实施方案和证明的唯一作者。
反馈:我们能看到发生了什么吗?
"完成了"是一个声明。我需要证据。
哪些文件变了?执行了哪些命令?哪些工具失败了?哪些测试通过了?智能体做了哪些假设?它在哪里请求了审批?
OpenTelemetry 通过追踪(traces)、指标(metrics)和日志(logs)等信号来解释可观测性。[12] 智能体系统需要自己的版本。记录工具调用、审批、测试结果、错误和重要决策。当出现问题时,团队应该能够重建运行过程,而不是将其归类为随机幻觉。
良好的反馈也能在智能体工作时帮助它。Anthropic 建议智能体从其环境中接收真实信息,比如工具结果或代码执行情况,以便判断进度。它也警告说,自主智能体可能会叠加错误,应该用护栏进行测试。[10]
指令、技能和工具现在是架构的一部分
我们通常认为架构是服务、数据库、队列、API 和部署系统。
对于智能体驱动的软件开发,这个边界太小了。
指示智能体的文件是架构。技能库是架构。仓库搜索方法是架构。工具描述是架构。权限是架构。测试工具是架构。运行历史是架构。
这些部分并不取代良好的应用设计。它们决定了智能体如何看待和修改那个设计。
这也改变了我诊断失败的方式。
如果一个智能体编辑了错误的包,我仍然会审查它的推理过程。但我也会问它是否有仓库地图。
如果它违反了一条安全规则,我仍然会拒绝这个补丁。但我也会问为什么这条规则被隐藏了,以及为什么环境允许了这个操作。
如果它过早停止,我仍然会让输出负责。但我也会问"完成"是否被写成了一个可执行的检查。
如果它忽略了一个技能,我检查的是这个技能的名称、描述、触发条件和可用性,而不是假设安装它就意味着它可用。
重点不是为模型开脱。重点是调试整个系统。
我现在使用的检查清单
在我将智能体送入一个重要项目之前,我会问:
地图在哪里?它能找到系统中相关的部分并理解重要的边界吗?
规则在哪里?它们是否简洁、时效性强且没有矛盾?
它需要哪些技能和工具?它能否发现并使用它们,而不需要接收不必要的权限?
什么能证明完成了?验收检查是否足够独立,能够捕捉到一个看似合理但实际错误的结论?
留下了什么记录?人类能否在事后审查操作、证据、假设和审批?
一个更好的模型可能会改进这个工人。它不会为我们标注工厂、编写安全政策、选择门禁卡权限或定义检验流程。
那些是工程职责。
新的调试问题
代码 bug 仍然在这里。AI 没有让编译器、测试套件、代码评审、安全评审或架构工作退休。
它添加了另一个可能被错误配置的系统。
所以,当一个 AI 智能体失败时,我不再只问:"生成的代码有什么问题?"
我们给智能体的是一个什么样的工作场所?
一个有天赋的工人位于一个空荡荡的、没有标签的工厂里,会犯可以避免的错误。一个有能力的智能体,如果指令缺失、检索薄弱、工具错误、权限过大、没有终点线,也会做同样的事。
新的 bug 不总是在代码里。
有时候,bug 是我们为智能体建造的那个房间。
[1] https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents — Anthropic: Effective context engineering for AI agents [2] https://learn.chatgpt.com/docs/agent-configuration/agents-md — OpenAI: Custom instructions with AGENTS.md [3] https://agents.md — AGENTS.md: A README for agents [4] https://code.claude.com/docs/en/memory — Claude Code: How Claude remembers your project [5] https://code.claude.com/docs/en/skills — Claude Code: Extend Claude with skills [6] https://modelcontextprotocol.io/docs/getting-started/intro — Model Context Protocol: What is MCP? [7] https://aider.chat/docs/repomap.html — Aider: Repository map [8] https://arxiv.org/abs/2509.16941 — SWE-Bench Pro: Can AI Agents Solve Long-Horizon Software Engineering Tasks? [9] https://arxiv.org/abs/2603.00520 — SWE-ABS: Adversarial Benchmark Strengthening Exposes Inflated Success Rates [10] https://www.anthropic.com/engineering/building-effective-agents — Anthropic: Building effective agents [11] https://csrc.nist.gov/glossary/term/least_privilege — NIST: Least privilege [12] https://opentelemetry.io/docs/concepts/observability-primer — OpenTelemetry: Observability primer [13] https://cognitect.com/blog/2011/11/15/documenting-architecture-decisions — Documenting Architecture Decisions [14] https://scrumguides.org/scrum-guide.html — The Scrum Guide
Originally published at https://blog.jenuel.dev/blog/the-new-bug-isnt-always-in-the-code