Appearance
怎样写 Agent 能执行的任务契约:从一句愿望到可验收任务
系列第 05 篇
核心产物:目标、范围、非目标、约束、验收、验证和交付证据
最后核验:2026-07-20
对应视频:第 08 集《Agent 可执行的任务契约:把需求写成可验证交付》
“帮我优化订单系统”“给页面加一个高级搜索”“把这段代码重构得更优雅”,这些话适合开始讨论,却不适合直接启动高自治 Agent。人类同事听到后会追问业务场景、范围和验收;Agent 也可能追问,但如果产品默认鼓励它尽快行动,或者用户期待一次完成,它就会用训练数据中的常见模式补齐空白。
任务契约不是专门给 AI 的提示词格式,而是一份让执行者、Reviewer 和自动检查共享同一完成定义的工程接口。它应该使另一个不了解上下文的工程师也能开始工作,并能在结束时判断是否完成。
阅读路线:先看全局,再进入机制
视频版先展示整章地图,再逐层展开。博客沿用同一判断顺序,但保留更多机制、案例、失败模式和生产边界:
- 契约结构:用目标、背景、范围、非目标、约束、验收、验证和交付物消除决策空白。
- 场景与边界:把成功、冲突、缺失、幂等和禁止事项写成可观察行为。
- 证据与流转:让契约沿 Issue、Agent、测试、PR 与 Review 保持一致。
- 质量与治理:用五分钟评审和显式变更控制防止实现过程静默漂移。
这四步不是目录装饰,而是一条决策链:契约结构 → 场景与边界 → 证据与流转 → 质量与治理。阅读后面的案例时,可以随时回到这条链判断当前问题发生在哪一层。
真实问题:模糊需求怎样变成大范围返工
假设任务只有一句:“支持取消订单。”Agent 搜索后发现 OrderStatus 只有 CREATED,于是新增 CANCELLED、Controller 和 Service。但它不知道已支付订单能否取消,不知道是否需要退款,不知道重复请求是否幂等,不知道数据库是否允许迁移,也不知道前端和外部消费者期待什么错误码。
它可能做出一种合理实现,却不是团队想要的实现。Reviewer 此时才提出“PAID 不能取消、重复取消应成功、不要加数据库”,修改会跨越状态、异常、测试和协议。问题不是 Agent 不会写代码,而是决策发生得太晚。
机制:任务契约的八个部分

一个完整任务契约通常包含:
- 目标:要改变的用户或系统行为。
- 背景:当前现象、业务原因和相关证据。
- 范围:允许触及的模块、接口和数据。
- 非目标:本次明确不解决的事项。
- 约束:兼容、安全、性能、依赖和组织要求。
- 验收:可观察的输入、动作和输出。
- 验证:必须运行的测试、构建、截图或真实路径。
- 交付:代码之外需要的文档、迁移、风险和证据。
目标回答“为什么做”,范围和非目标回答“改到哪里为止”,验收回答“什么行为算对”,验证回答“怎样证明”,交付回答“团队怎样接手”。缺一项不一定失败,但任务越复杂,空白越容易成为模型假设。
1. 目标必须描述行为变化
“重构认证模块”描述的是活动;“无有效 Session 的个人资料请求返回 401,有效 Session 保持 200”描述的是行为。活动可以无限延伸,行为有明确停止条件。
好的目标通常包含主体、场景和结果:
text
当用户取消一个尚未支付的订单时,系统把订单状态改为 CANCELLED,
重复取消保持成功;已支付订单拒绝取消。目标不必包含具体类和方法。过早指定实现会让 Agent 忽略仓库已有模式。除非技术选择本身已经被团队确认,否则目标应先说行为,计划再说代码位置。
2. 背景提供事实,不提供故事堆积
背景应该包含当前行为、复现方式、错误日志、相关入口和业务原因。对缺陷,最好给出实际输入、实际输出、期望输出和稳定复现命令。对功能,说明现有工作流为何不足以及消费者是谁。
不要粘贴几十页聊天记录。Agent 需要的是支持当前决策的事实。如果长讨论中有三项已确认结论,把结论写成任务条目,并链接原讨论供追溯。
3. 歧义越晚消除,成本越高

一句愿望进入 Agent 后,未说明部分被补成假设;假设进入多个文件后变成结构;结构进入测试后看起来像规格;到了验收阶段,团队才发现方向分歧。越往后,修正需要删除更多代码、解释更多 Diff,并对抗沉没成本。
任务契约的价值是让高成本分歧在代码生成前出现。它不追求消除所有不确定性,只处理那些会改变公共行为、数据、安全或大范围结构的问题。
4. 坏 Prompt 与好任务的区别

坏 Prompt:
text
优化订单接口,让它更健壮。改进后的任务:
text
目标:增加取消订单 HTTP 能力。
背景:当前服务只能创建 CREATED 订单,Repository 只能 save。
范围:Order、OrderService、OrderRepository、Web adapter 和相关测试。
非目标:不增加数据库、支付接口、认证或新依赖。
验收:CREATED -> 200/CANCELLED;重复取消 -> 200/CANCELLED;
PAID -> 409;未知 UUID -> 404;创建接口保持不变。
验证:新测试实现前真实失败;实现后 mvn test 全部通过;
本地启动后走创建、首次取消、重复取消和 404。
交付:代码、测试、任务说明、验证证据和剩余限制。后者不是因为更长而更好,而是包含了执行和验收所需的决策信息。
5. Given-When-Then 把抽象目标变成场景

Given-When-Then 适合描述行为,但不要机械把所有句子改成语法模板。它的价值是分离前置状态、动作和可观察结果:
gherkin
Given an order is in CREATED state
When POST /api/orders/{id}/cancel is requested
Then the response is 200
And the returned status is CANCELLED
And the repository contains the cancelled order重复取消场景应明确第二次请求仍返回成功,以及是否允许再次写入。PAID 场景应明确 409 与错误代码。未知订单应明确 404。测试可以不使用 Cucumber,但必须覆盖同一语义。
验收关注外部行为,不要写“调用私有方法 doCancel”。实现细节可以变化,业务行为应该稳定。
6. 范围和非目标共同限制爆炸半径

范围告诉 Agent 可以在哪里寻找最小方案,非目标阻止它顺手扩大设计。订单取消任务明确不做数据库、支付、认证和前端;这允许使用现有内存仓库完成教学目标,也避免 Agent因为发现 PaymentClient 而自行创建支付工作流。
非目标还应包含高概率诱惑:不升级 Spring Boot,不替换 Repository 架构,不重命名原 API,不格式化整个仓库。它不是限制合理改进,而是把不相关改进留给独立任务,以保持 Diff 可审查。
7. 约束必须能被检查

“代码要优雅”“性能要好”“注意安全”无法直接验收。把它们转换为检查:原接口测试继续通过;不增加外部调用;不读取生产 Secret;不新增依赖;使用现有异常响应结构;mvn test 必须通过;Diff 不包含生成目录。
有些约束无法完全自动化,例如“与现有领域边界一致”。这类约束应指向权威范例或架构文档,并列入人工 Review 清单。不要假装所有要求都能变成单元测试。
从 Issue 到 Agent、PR 和证据

Issue 保存业务目标和验收,仓库规则提供长期约束,探索结果记录当前事实,Plan 说明方案和风险,Agent 执行小步修改,PR 汇总 Diff 和验证证据。每个阶段都不应重写上一阶段含义。
如果实现发现任务契约错误,应回到任务层确认,而不是让 Agent 私自改变验收。若只是计划中的文件名不准确,可以更新 Plan。区分“需求变化”和“实现发现”能避免任务、测试和代码变成三个冲突事实源。
一份可复用模板
markdown
# Task
## Goal
一句话描述用户或系统行为变化。
## Background
当前行为、复现、日志、业务原因和相关入口。
## Scope
- 允许修改的模块和接口。
## Non-goals
- 明确不做的系统、迁移和重构。
## Constraints
- 兼容、安全、性能、依赖、权限和风格。
## Acceptance Criteria
1. Given / When / Then 或输入输出示例。
2. 失败与边界场景。
## Verification
- 实现前应失败的检查。
- 实现后相关与全量命令。
- 需要的真实 API、浏览器或数据校验。
## Deliverables
- 代码、测试、文档、迁移、证据与限制。模板不是为了强迫每个任务填满。如果某项不适用,写“不需要以及原因”,比留空让执行者猜测更清楚。
验收证据怎样形成闭环

缺陷任务先证明问题存在;功能任务先用失败测试证明行为缺失。实现后同一检查通过,说明变化发生。相关回归和全量测试说明没有破坏已覆盖行为。真实 API 或浏览器说明用户路径成立。人工 Review 检查测试未覆盖的业务、兼容和安全。
证据应记录命令、工作目录、退出码和关键断言,而不是一句“已测试”。如果某项因环境无法运行,必须写明未验证,不用模型推断替代。
任务契约的质量门

在交给 Agent 前问四个问题:另一个工程师能否据此工作?Agent 是否有权限和工具完成验证?边界是否足以控制破坏半径?失败后是否知道回退和升级路径?
如果答案是否定的,继续完善任务或降低自治。任务契约不是越精细越好,而是要足以让执行者不依赖关键猜测。
不同任务需要不同契约重点
缺陷修复的背景应优先写复现、日志、影响版本和修复前失败证据。它的非目标要防止“顺手重构”,验收要证明根因被修复而不是错误被吞掉。若问题是间歇性的,还要说明出现频率、环境和并发条件,不能让 Agent 把一次无法复现当成问题消失。
新功能的重点是用户行为、状态边界、兼容和接口消费者。对于跨模块功能,任务契约上方可能还需要 Spec;单个 Agent 任务只承接其中一个可独立验证的切片。不要把整份产品需求原样扔给实现 Agent,让它自己决定本次边界。
重构任务必须写清哪些外部行为保持不变,以及用什么 characterization tests 保护。仅说“重构但行为不变”仍然太弱,因为团队要说明 HTTP、事件、数据库、副作用、性能或错误文本中哪些属于兼容合同。结构目标也要可检查,例如消除循环依赖、限制模块方向或减少重复路径。
数据迁移的契约重点不是代码文件,而是数据安全:源和目标、行数、批次、幂等、dry-run、断点续跑、备份、回滚、校验和与观测。此类任务即使转换逻辑简单,也不应直接给通用 Agent 生产写权限。
UI 任务需要视口、交互状态、参考图、可访问性和视觉验收。只写“与设计稿一致”无法自动判断;应规定桌面和移动尺寸、关键组件、文本不得溢出、交互可达,并要求真实浏览器截图或像素/结构检查。
任务评审的五分钟方法
在启动 Agent 前,责任人可以用五分钟朗读任务:每读一条验收,就问怎样观测;每读一个约束,就问由谁强制;每读一个非目标,就问 Agent 是否容易误触;最后让执行者复述最小改动面和停止条件。复述不同,说明契约仍有歧义。
评审不要求先决定每个类名,但应锁定会造成大范围返工的选择。若仍有两个合理业务答案,把任务退回决策;若只是两个局部实现方案,允许 Plan 比较。这样可以把人类判断用在高价值分歧,而不是微观编码。
失败模式
失败一:把实现方案写成目标
“在 Controller 增加方法并调用 Repository”可能绕过领域层。除非架构已经确认,先描述行为和约束,让探索阶段决定最小位置。
失败二:只写成功路径
Agent 会优化被描述的路径。缺少不存在、重复、非法状态、超时和权限拒绝,通常意味着它们不会被系统性处理。边界场景应按风险选择,不必穷举无关组合。
失败三:验收依赖自然语言自评
“确认代码质量良好”不是验收。替换为编译、测试、静态检查、HTTP、截图、性能或具体 Review 条目。
失败四:范围过窄到无法修根因
指定“只改这一行”可能迫使 Agent压制错误而非修复根因。范围应限制业务表面和系统边界,不必预先限制每个实现文件。若超出预期,Agent 应暂停说明原因。
失败五:任务中包含互相冲突的要求
例如既要求不改接口,又要求改变响应结构。Agent 可能任选一个或产生折中。冲突必须由责任人决策,不能靠模型猜优先级。
失败六:把长背景当成精确
大量文字会掩盖真正决策。任务开头给出简明合同,细节通过链接或附件按需读取。重要否定条件不要埋在会议记录中。
生产边界
任务契约只能指导行为,不能授予不应存在的权限。即使任务写着“不要访问生产”,Agent 如果持有通用凭据和网络仍存在风险。权限、沙箱、分支保护和审批必须独立强制。
安全敏感任务还应增加威胁模型、数据分类、日志要求和责任人。数据迁移应增加 dry-run、备份、可逆步骤、行数与校验和。公共 API 应列出消费者、兼容期和版本策略。任务模板可以相同,严格程度必须随风险变化。
实践清单
- [ ] 目标描述可观察行为,不只是开发活动。
- [ ] 背景包含当前事实和稳定复现。
- [ ] 范围说明系统边界,非目标阻止顺手重构。
- [ ] 约束能够自动检查或指向权威范例。
- [ ] 验收覆盖主要成功、失败和状态边界。
- [ ] 验证包含实现前失败与实现后通过。
- [ ] 交付要求包含证据、风险和未验证项。
- [ ] 需求变化回到任务层确认,不由 Agent 私改。
- [ ] 高风险任务增加权限、迁移和审批要求。
- [ ] 其他工程师能够在没有口头补充时执行任务。
读完之后,你应该能完成什么
- 能把一句愿望改写成 Agent 可执行接口。
- 能用 Given-When-Then 覆盖正常与异常路径。
- 能让每项验收对应具体证据。
- 能在需求变化时同步更新契约、测试和旧证据状态。
如果只能复述概念,却不能完成上述动作,说明还没有把内容转化成工程能力;可以回到对应机制图、失败模式和实践清单重新核对。
小结
任务契约把自然语言愿望转换为可执行接口。它不能消除所有实现决策,却能把目标、边界和完成定义从模型猜测中拿回来。越希望 Agent 独立工作,越需要让任务、环境和验证在开始前明确。
