代理工程的五层结构:从需求规格与并行代理到规则设定与监督机制
卡尔帕西将这一阶段称为“超越传统编码”。了解代理工程的五层结构:需求规格、协调机制、编码规则、人工审核与可观测性,以及周计划。
“氛围编码”曾风靡一时。这一术语的提出者安德烈·卡帕西如今已宣布那个时代已经结束,他不仅指出了存在的问题,还提出了替代方案:代理工程。在这种方法中,人工智能代理负责规划、编写、测试和部署代码,而人类则进行结构化的监督。人类设定目标,代理执行任务,人类再检查结果。这是一种利用人工智能进行开发的专业方法,而非仅仅将其作为辅助工具,与那种随意发起指令后寄予希望的做法有着天壤之别。
早先推动的规范驱动开发理念,即在任何智能体生成任何内容之前先明确系统必须完成的任务,实际上仅涵盖了这一领域的一个层面。此后,实际开发团队又补充了另外四个层面。下文将梳理这五个层面,展示每个层面的实际应用情况,并提供一个为期一周的入门练习计划。
名称为何重要
这个名称不仅仅是品牌标识,它划分了两种截然不同的工作方式。Karpathy通过两个问题划定了这一界限:Vibe coding关注的是某事物是否能够实现功能,而Agentic engineering则关注的是它能否在保持可靠性的同时大规模运行且不引入安全漏洞。
第一个问题打破了限制,让任何人都能开始制作原型:周末开发者可以描述自己的需求,接受反馈结果,最终得到可运行的演示版本,这对于真正的探索而言非常有用。第二个问题则设定了上限,处理支付、管理健康数据或运行基础设施的软件仍然需要专业的规范。虽然程序员可以编写代码,但必须由专业人士来设计系统、界定其范围并验证输出结果。
卡帕西自己的表述很直接:智能体工程是一门工程学科,而这些智能体具有随机性、不可预测性且能力极强,因此真正的难题在于如何协调它们以更快地行动的同时不降低质量标准。这个“在不牺牲质量的前提下提升速度”的问题,如今已成为该领域的核心议题。这并非只有他的观点。IBM、Forrester和Anthropic都在同一季度内分别提出了针对这一新兴学科的正式框架,且是独立得出这些结论的。当那些平时很少达成共识的组织同时指向同一个方向时,这个理念便具有了实质意义。
这个术语之所以流行,是因为工程师们需要一个词来描述他们已经在做的那种工作:比简单提示更有结构,比氛围编码更规范,同时又不同于传统开发方式。它所指的这种规范体系包含五层,每一层都建立在下一层的基础之上。如果缺少其中任何一层,上层的一切都会变得不可靠。
第一层:规范定义
在任何智能体生成代码之前,先撰写规范文档。明确系统必须始终执行的任务、绝不能执行的操作、如何判断其正在运行以及如何判断其已停止工作。将所有内容放在一份文档中,保持该文档的实时更新,并以之为标准来评估智能体构建的所有成果。
人工智能工程领域的不同人士将此称为战略规划、意图定义或简称为“规范”。虽然称呼各异,但核心做法一致:在让智能体进行构建之前,先明确所需的目标。
有一点很容易被忽视:规范并非发布时的固定文件,而是一份动态更新的文档。每当实现过程中出现规范未预见的情况——而这几乎不可避免——规范就会随之更新。那些团队成员逐渐偏离最初设计意图的团队,往往就是那些在最初制定规范后就再未查看过的团队。
一个最简单的模板以一段声明该文档为权威依据的标题开头:
# Feature Spec: [Feature Name]
## Last updated: [Date] — this document is the source of truth
接着是行为检查表,其中包含必需的行为规范以及严格限制条款,例如未经人工审批不得处理超过500美元的退款:
## What this must always do
- [ ] [Behaviour 1 — specific, testable]
- [ ] [Behaviour 2 — specific, testable]## What this must never do
- [ ] [Boundary 1 — e.g. "Never process refund >$500 without human approval"]
- [ ] [Boundary 2 — e.g. "Never fabricate a citation"]## Success criteria (measurable)
- Context recall: >0.85
- Faithfulness: >0.90
- Cost per query: <$0.15
- Latency p95: <2s## Failure signals (alert if breached)
- Any metric drops >5% from 7-day baseline
- Cost per task exceeds 3x expected range
- User complaint rate exceeds 2% of sessions## Decomposition (for parallel agents)
- [ ] Task A: [scope] — can be delegated independently
- [ ] Task B: [scope] — depends on Task A output
- [ ] Task C: [scope] — can run parallel with Task A
请将内容限制在一页之内。如果需求描述过长,说明该功能规模过大,需要拆分直至每部分都适合单独处理。
即便将完善的需求描述交给单个代理,仍会面临处理速度的上限,这就是需要第二层架构的原因。
第二层:协调机制
设想一个涉及数据库结构、API、前端界面以及测试套件的功能。传统上,一名工程师会依次处理这些部分,或者整个团队在迭代周期内协同工作。而在代理工程模式下,四个代理会同时处理这四部分内容:一个负责编写数据迁移代码,另一个负责开发接口端点,第三个负责构建前端组件,第四个则负责编写测试用例并检查其余部分是否存在安全问题。每个代理都有其特定的工作环境和约束条件,它们的输出会被整合为一次连贯的变更。
这并非假设。Stripe在实际生产环境中就采用了这种模式,其内部代理系统每周会生成1000多个合并的拉取请求,每个请求都由代理编写、人工审核,通过持续集成测试后才会发布。所带来的效率提升是一个数量级的,而非两倍而已。
这一流程是一个针对每个功能重复执行的循环:规划、执行、验证。有些团队将其称为PEV循环。
- 规划。人工根据第一层需求编写规范,并将工作分解为可独立分配的任务单元。此处需要做出的重要决策是:哪些任务可以并行执行(因为它们不依赖彼此的输出),哪些任务必须按顺序执行。
过去需要两周时间才能完成的工作,现在只需几小时或一天的集中处理即可。人类工程师的主要工作在于规划与验证,而具体的执行任务则由智能体承担。
这种细微差别需要时间去理解:关键在于实现有用的并行处理,而非追求最大程度的并行。在紧密耦合的模块上运行三个代理会导致冲突,解决这些冲突的成本会高于并行处理所带来的收益。而在独立模块上运行两个代理,并由第三个代理对两者进行协调,就能得到一致的输出。其中的技巧在于合理分解任务,使其能够被分配出去,从而避免日后出现集成方面的问题。
一个框架级的协调器可以在其文档字符串中说明循环逻辑:
class AgenticOrchestrator:
"""Plan → Execute (parallel) → Verify"""
并执行规划步骤,即将某个功能拆分为可分配的任务:
def plan(self, feature_spec: dict) -> dict:
"""Decompose feature into independently delegatable tasks."""
tasks = []
for component in feature_spec["decomposition"]:
tasks.append({
"id": component["id"],
"spec": component["scope"],
"constraints": feature_spec["must_never"] + component.get("local_rules", []),
"depends_on": component.get("depends_on", []),
"verification": component.get("success_criteria", []),
})
independent = [t for t in tasks if not t["depends_on"]]
sequential = [t for t in tasks if t["depends_on"]]
return {"parallel": independent, "sequential": sequential} async def execute(self, plan: dict):
"""Run independent tasks in parallel, sequential tasks in order."""
parallel_results = await asyncio.gather(*[
self.delegate_to_agent(task) for task in plan["parallel"]
])
for task in plan["sequential"]:
result = await self.delegate_to_agent(task, prior=parallel_results)
parallel_results.append(result)
return parallel_results def verify(self, results: list, spec: dict) -> dict:
"""Check all outputs against the spec — structural, not line-by-line."""
issues = []
for result in results:
if not self.satisfies_spec(result, spec):
issues.append(f"{result['id']}: does not satisfy spec")
if self.conflicts_with(result, results):
issues.append(f"{result['id']}: conflicts with another module")
return {"passed": len(issues) == 0, "issues": issues}
核心原则是严格限定上下文范围。每个智能体应仅接收其对应的规格说明、代码文件以及规则。将整个代码库放入每个上下文窗口中会浪费计算资源、增加成本,并削弱模型的注意力分配能力。
协调机制能够提升处理效率,但缺乏一致性的高效处理只会带来混乱。每个智能体都必须了解团队的规范、架构限制与安全策略,以及自身任务的具体规格要求。下一层功能负责提供这些信息。
第三层:编码规则
大多数工具都已具备类似功能。Claude Code在每次会话开始时加载CLAUDE.md,Cursor读取.cursorrules文件,而Codex则读取AGENTS.md文件。其核心理念一致:即在项目根目录中放置一个文件,用来指导智能体的行为方式。
到2026年,各团队更进一步,将整个开发文化编码为智能体可读取的约束条件,而不仅限于技术栈层面。保罗·杜瓦尔等从业者一直在记录来自实际开发团队的模式,InfoQ也持续追踪这些模式的成熟度。在采用智能体工程的场景中,总会出现四种重复出现的模式:
- 以规范驱动的开发,即由开发规范来指导工作(第一层)。
- 编码化的规则与架构约束:包括惯例、安全策略、错误处理模式、命名标准以及部署流程,所有这些内容都存储在智能体启动前会加载的文件中。
- 利用并行智能体进行原子化分解:将功能拆解为最小的独立单元以便单独处理(第二层)。
规模问题是大多数团队会遇到的障碍。对于1,000行的原型,一个CLAUDE.md文件就足够使用。但100,000行的代码库无法用一个文件来描述,即便可以,规则也会在智能体开始执行实际任务之前就占满上下文窗口。
为解决这一问题,一些团队会构建分层规则系统,类似ESLint配置从组织预设中继承并可根据项目进行覆盖的方式。其文件夹结构如下:
your-company/
├── .ai-rules/
│ └── org-rules.md ← Company-wide: security, compliance, style
│
├── team-payments/
│ ├── .ai-rules/
│ │ └── team-rules.md ← Team-level: error handling, testing, deploys
│ │
│ ├── service-checkout/
│ │ ├── CLAUDE.md ← Repo-level: architecture, tech stack, builds
│ │ ├── src/
│ │ │ ├── auth/
│ │ │ │ └── .ai-rules.md ← Module: auth-specific constraints
│ │ │ └── payments/
│ │ │ └── .ai-rules.md ← Module: PCI compliance rules
最上方是组织配置文件,为每个仓库中的每个代理都加载了该文件。其中规定了诸如绝不对敏感信息进行提交、公共 API 必须要求身份验证,以及错误响应中绝不能暴露堆栈跟踪信息等规则:
# org-rules.md (loaded for every agent, every repo)
- Never commit secrets or credentials
- All public APIs require authentication
- Error responses must never expose stack traces
- Log every state-changing operation with user context
在其下方,团队文件会继承这些规则并添加自己的规则,例如使用结果模式而非抛出异常,所有数据库访问都通过仓库层实现,同时测试需涵盖正常流程以及至少两种故障场景:
# team-rules.md (inherits org, adds team specifics)
- Use Result<T, E> pattern — never throw exceptions
- All database queries go through the repository layer
- Tests must cover the happy path + 2 failure modes minimum# CLAUDE.md (inherits team, adds repo specifics)
- This repo uses Express.js + Prisma + PostgreSQL
- Run `npm test` before suggesting any PR is ready
- Migrations are append-only — never modify applied migrations# module .ai-rules.md (inherits repo, adds module specifics)
- auth/: All token operations must use constant-time comparison
- payments/: PCI DSS requires field-level encryption on card data
代理会加载组织规则、团队规则、仓库中的CLAUDE.md文件以及其所涉及的模块的规则。这样能使上下文范围保持清晰且简洁。处理支付模块的代理会获取PCI合规规则,而处理前端模块的代理则不需要,因为那些规则只会无谓地占用上下文资源。
规则规定了工作方式,但最终输出仍需人工判断。代码即便遵循了所有规范,也可能在架构上存在问题,以解决某个问题的方式却在其他地方引发更大的问题。正因如此,下一层处理是不可或缺的。
第4层:人工监督
三个词可以概括目前形成的运作模式:授权、审核、负责。
委托任务。给智能体一个要求明确、约束清晰的特定任务,让其独立完成。无需过度干预执行过程,也不用盯着它打字。因为有明确的规范和规则,所以可以信任智能体会遵守这些要求。
审核结果。将返回的输出视为来自一位能力较强但经验较少的工程师的拉取请求:他们工作高效、技术娴熟,但也容易犯一些只有了解整个系统架构的人才能发现的细微错误。需检查其设计是否符合整体架构以及是否存在边缘情况。要确认任务规范已得到满足,也就是说真正实现了预期目标,而不仅仅是测试通过了而已。
承担责任。最终的质量由人负责。虽然智能体完成了工作,但需由人进行最终确认,若出现生产环境故障,则由此人承担责任。这种责任归属机制将智能体驱动的编程方式与那种无人对输出结果负责的随意编码区分开来。
这一瓶颈确实存在。智能体生成代码的速度远快于人们审查的速度,因此人们往往会为了跟上进度而放松严格标准。正是这种诱惑让“氛围编码”得以流行:开发者们因为代码看起来没问题、能通过测试且截止日期临近,就接受了这些输出结果。智能体工程的存在就是为了防止这种模式再次出现。
Anthropic的智能体编码趋势报告阐述了经验丰富的工程师是如何处理这一问题的。他们会将那些正确性一目了然或风险较低的任务委派出去。而那些在概念上较为复杂或高度依赖设计的任务,他们更有可能自己处理或与智能体共同完成。懂得该将什么任务交出去、什么任务留给自己,已成为新的核心能力。这项能力需要通过实践来提升,没有任何框架或工具可以替代,它也能区分出那些能高效运用智能体并产出优质成果的工程师,与那些虽能做出表面好看但经不起仔细检验的成果的工程师。
在将任何由智能体生成的成果投入生产之前,一份审查清单能提供帮助。其标题为:
## Agent Output Review Checklist
其内容按章节组织,首先探讨规范符合性(是否实现了所有要求的行为、是否遵守了限制条件、是否满足成功标准),随后再讨论架构与商业合理性:
### Spec alignment (does it do what was asked?)
- [ ] All "must always do" behaviours are implemented
- [ ] No "must never do" boundaries are violated
- [ ] Success criteria from the spec are met or tested### Architectural coherence (does it fit the system?)
- [ ] No new dependencies introduced without justification
- [ ] Consistent with naming, patterns, and structure of existing code
- [ ] No duplication of logic that exists elsewhere### Safety and edge cases
- [ ] Error handling covers the failure modes the spec anticipated
- [ ] No hardcoded credentials, keys, or environment-specific values
- [ ] Input validation present on all external-facing boundaries### What the agent cannot check for itself
- [ ] Does this make business sense? (not just technical correctness)
值得将其打印出来并贴在显示器旁。代码检查工具和持续集成系统可以部分自动化前三个环节,而最后一个环节——商业意识,则是必须由人工持续关注的原因。
代码审查能在发布前发现问题。而质量缓慢下降、细微的回归故障以及那些直到收到账单才被发现的成本增加等问题,都只能在后期被发现,这时就需要最后这一层保障了。
第五层:可观测的开发
监控与可观测开发听起来相似,但实际上承担着不同的任务。监控只是表明系统正在运行,延迟正常、错误较少,控制面板显示状态良好;而可观测开发则能说明系统具体做了什么:哪个节点处理了哪项任务,依据的是何种规范,使用了哪些工具,生成了怎样的代码,以及最终结果是否符合预期。
差异在凌晨2点显现。仅靠监控的话,虽然能发现系统出了问题但原因不明,因此整晚都得花在查看差异和猜测问题出在哪个模块上。而采用可观测开发方式后,部署的追踪记录显示是代理3将认证流程从原本忽略并发令牌刷新的规范改成了新方式。这样只需12分钟就能有针对性地调试问题,而非花费2小时猜测。
实际上,这归结为三个习惯:
- 每个代理任务都会生成结构化的追踪记录:包括它接收的规范、使用的工具、修改的文件、模型版本、消耗的令牌以及验证结果。即便三天后出现故障,这些追踪记录也能说明发生了什么,无需大家再费力回忆。
最简化的设置是从导入少量跟踪记录开始的:
from dataclasses import dataclass, field
from datetime import datetime
以及应用于每个委托任务的追踪数据类:
@dataclass
class AgentTrace:
"""Minimum trace for every agent-delegated task."""
task_id: str
agent_id: str
spec_given: str # What was the agent told to do?
tools_used: list[str] # Which tools did it invoke?
files_modified: list[str] # What did it change?
model_version: str # Which model, which version?
tokens_consumed: int # What did it cost?
started_at: datetime = field(default_factory=datetime.utcnow)
completed_at: datetime | None = None
verification_result: str = "" # pass / fail / needs_review
human_reviewer: str = "" # Who signed off?
issues_found: list[str] = field(default_factory=list)
添加每周15分钟的复习环节。其标题为:
## Weekly Observable Development Review (15 minutes)
以及相关问题:共分配了多少任务,初次尝试中通过验证的任务占比是多少(目标值需高于80%),哪一类问题最多,以及三大主要问题是什么:
1. How many agent tasks were delegated this week? ___
2. How many passed verification on first attempt? ___ (target: >80%)
3. Which task category had the most issues? ___
4. Top 3 issues found during review:
- ___
- ___
- ___
5. Which issues should become codified rules (Layer 3)? ___→ Update CLAUDE.md with any new rules from this week's observations.
每周投入15分钟即可形成闭环。观察结果会转化为规则,规则能提升协调效率,更好的协调效率会带来更优的输出,而这些输出又会产生新的观察结果。
其有效性的证据
有两个数据尤为突出。Stripe每周有1000多个合并的拉取请求,这些请求均由自动化工具生成、经过人工审核、通过持续集成测试并投入实际使用,这绝非沙箱环境中的实验。这样的处理量在一年前是无法实现的。不同群体看到的数字也有所不同:麦肯锡的调查显示运营成本可降低20%至40%,这样的降幅足以让人工智能从创新项目转变为运营基础设施,这是首席财务官而非仅首席技术官所期望的。
这对工程职业意味着什么
这一角色正在发生变化,但并未消失。2026年的工程师会减少编写基础代码的工作量,转而花更多时间协调智能体、设计架构、明确目标与约束条件,并验证输出结果。核心技能也从语法层面转向系统思维,从思考如何编写函数转变为思考如何设计一个能让智能体正确编写函数的系统。
Karpathy将这一理念延伸到招聘环节:不必设置谜题类问题,而是布置一个实际项目,比如构建一个安全的Twitter克隆版本,然后让智能体尝试破解它,同时观察候选人如何处理工具、技术规范及监督工作。这能检验候选人的自律性,而非打字速度。
在与工程领域领导者的对话中,有三项能力被反复提及:
- 规范表述的精准性。要写出能让智能体毫无歧义地执行的精确规范,其难度远高于编写代码。代码有编译器来发现错误,而规范只能依赖智能体的理解。如果规范含糊不清,智能体就会自行选择一种解读方式,基于此进行操作,并将结果呈现为看似符合要求的输出。
- 协调决策能力。需要判断哪些任务可以委托,哪些必须亲自处理;何时并行执行有益,何时耦合度过高;以及何时输出需要全面审查而非仅做结构检查。这种能力是在无数次任务委托中逐步形成的,每次委托都会揭示哪些方法有效,哪些会导致集成问题。
Gergely Orosz说得很对:有比编程更重要的因素让工程师与众不同,而这些因素值得培养。2026年让工程师脱颖而出的是他们设计的系统、撰写的规范、在任务分配上的判断力,以及他们绝不降低的质量标准。正因机械性的执行工作已被自动化,这些技能如今才显得更为珍贵。
五天入门计划
一周内完成五项练习,每项都建立在前一项的基础上:
- 周一:整理团队知识。为当前项目编写CLAUDE.md或.cursorrules文件。无需列出所使用的技术,只需记录相关规范:错误处理方式、测试结构、命名规则,以及每位新人入职第一天就应了解的那些不成文规定。
- 周二:明确需求并分配任务。从待办功能列表中挑选一个,按照模板撰写其需求规格:该功能必须实现的功能、禁止实现的内容、成功标准及失败信号。将整个任务完全分配给某位成员,并为需求明确阶段和审核阶段分别安排时间,通过时间比例就能看出实际的工作投入点在哪里。
一周时间无法让任何人成为代理工程师。但它确实能让人感受到这项工作的特点,以及从编写代码转向协调代理工作是会带来动力还是消耗精力。两种答案都是合理的,但知道哪一个是真的会有所帮助。
仅依赖需求文档的局限性
将规范视为唯一的答案,即依据其撰写、遵循并以此进行验证,这种做法虽必要但并不充分。规范只是编排系统的输入依据,而非独立的操作准则。将一份完美的规范交给一个执行者就能得到良好的结果;而若将同一份规范分配给五个并行工作的执行者,每个执行者都受既定规则约束、在结构化的监督下工作,并且整个开发过程都可被追踪,那么在保持相同质量的前提下,产出效率大约能提升十倍。
第四层也容易被低估。规范仅阐述意图,是否实现该意图则由人类来判断。规范本身无法强制执行,其验证环节同样需要与撰写时一样的严谨态度。一旦截止日期临近,大多数团队往往会在模型、框架或工具方面偷工减料,却忽视了验证环节。
下一步是什么
有两种可能性,一种近乎确定,另一种则属于推测。
几乎可以确定的是,大约18个月后,智能工程将成为专业软件开发的默认方法。这并非因为所有人都了解它,而是因为其经济优势极具吸引力。三名运用这种方法的工程师,在拥有明确需求规格、并行协调机制以及严格监管的前提下,所能产生的成果相当于12名按传统方式工作的工程师。当计算结果如此明确时,争论便不复存在。
另一种推测是智能代理集群:由多个相互协作的代理组成的网络,在最少人工干预的情况下就能完成整个工作流程或业务功能。一些团队已经在对此进行试验。不过,尚不清楚这种模式在企业规模下能否保持企业级的可靠性,因此对于这一技术应持谨慎态度并辅以怀疑精神。
不可置疑的是,工程师的角色已经发生了变化。关键问题在于,这一新角色所要求的技能——即规范制定、协调与验证——是否正在被培养,还是工作仍像过去那样以编写代码为核心。过去的工作就是输入代码,而现在的工作则是设计生成代码的系统,并确保其输出结果正确。