agent-skills:以 notifications-spec 为例,拆解"规格到可执行任务计划"的规划技能与行为评测机制
本文以 notifications-spec.md 这份通知功能规格文档为主线,完整解读 agent-skills 仓库中 planning-and-task-breakdown 技能如何将一份需求规格拆解为带验收标准、按依赖排序、可垂直切片的小型任务,并讲解该文档作为行为评测夹具(fixture)被评测管线自动验证的底层机制。读完后,你既能掌握"规格驱动任务拆解"的方法论本身,也能理解本仓库如何用它来度量一个技能是否真正改变了 Agent 的行为。
一、规格文档原文:一条通知功能的完整需求边界
planning-and-task-breakdown 技能的行为评测需要一个真实、自洽、边界清晰的需求输入。仓库为此提供的输入就是 evals/fixtures/planning-and-task-breakdown/notifications-spec.md,全文仅 18 行,但信息密度很高,包含背景现状、需求清单、验证要求和范围排除四个部分:
背景与现状(Already True):
- 用户可以**选择加入(opt-in)**邮件通知,触发时机有两个:任务被分配(assigned)、任务逾期(overdue);
- 偏好(preference)按用户存储,且默认为禁用;
- 任务分配事件(assignment events)已经存在于系统中——通知功能不需要新建事件源;
- 逾期检测(overdue detection)以每 15 分钟一次的周期运行。
这段背景的价值在于它明确了"哪些积木已经就位、哪些需要新建":事件源是现成的,规划者只需关注偏好读写、作业发布、去重、发送与投递记录,而不必把事件采集纳入计划。
六条需求要求(Requirements):
- 新增偏好读取/更新端点,并带边界校验(boundary validation);
- 从分配流程和逾期流程中发布通知作业(notification jobs);
- 作业必须去重,去重键为:用户 + 任务 + 事件类型 + 事件版本(user, task, event type, and event version)四元组;
- 邮件发送走现有的 provider 适配器(existing provider adapter),不引入新通道;
- 记录投递状态(delivery status),但不存储消息正文(without storing message bodies);
- 发送路径整体置于**特性开关(feature flag)**之后;禁用是安全默认值(disabled remains the safe default)。
验证要求(Verification):
验证必须包含四类:偏好 API 测试、作业去重测试、provider 适配器集成测试,以及一个端到端任务分配场景。
范围排除(Out of Scope):
明确不做 SMS、推送通知(push notifications)、通知历史 UI。
这份规格刻意做到了三件事:给出已存在的基础设施事实、给出可逐条验收的需求、给出明确的负向边界。这正是 SKILL.md 所要求的"spec or clear requirements"输入形态——它足够复杂以检验拆解能力(涉及存储、API、异步作业、去重、开关、投递记录多个子系统),又足够收敛以让"垂直切片 vs 水平分层"的区分有可判定的答案。
二、规格在仓库中的身份:一个行为评测夹具
单独看,这份文档只是一份需求;放进 agent-skills 的评测体系后,它的角色就变了。evals/README.md 将技能评测分为三层:
| 层级 | 检查内容 | 运行方式 | 成本 |
|---|---|---|---|
| 1. 结构性 | frontmatter、命名、必备章节、命令对齐 | CI(validate-skills.js、validate-commands.js) |
免费 |
| 2. 触发与路由 | 正向 prompt 能把该技能排进 top-k,负向 prompt 不能;描述不近义碰撞 | CI(run-evals.js) |
免费 |
| 3. 行为性 | 遵循技能的 Agent 满足其 expectations[] |
按需(run-evals.js --behavioral) |
消耗 tokens |
notifications-spec.md 服务的是第三层:它不是被测对象,而是喂给 Agent 的"真实项目输入"。对应的评测用例在 evals/cases/planning-and-task-breakdown.json,核心字段如下:
{
"skill_name": "planning-and-task-breakdown",
"trigger": {
"positive": [
{ "prompt": "Break this spec into small verifiable tasks with acceptance criteria", "top_k": 3 },
{ "prompt": "Turn the PRD into an ordered task list we can execute", "top_k": 3 },
{ "prompt": "Plan the work into implementable chunks before we start coding", "top_k": 3 }
],
"negative": [
{ "prompt": "Debug the crash on startup", "owner": "debugging-and-error-recovery" },
{ "prompt": "Encode the output so it is safe against XSS" }
]
},
"evals": [
{
"id": 1,
"prompt": "Break the attached notifications spec into an executable plan.",
"expected_output": "Ordered tasks in tasks/plan.md, each small, verifiable, with acceptance criteria and dependencies",
"files": [ "planning-and-task-breakdown" ],
"expectations": [
"Every task has acceptance criteria",
"Tasks are ordered by dependency",
"Tasks are vertical slices rather than horizontal layers",
"No implementation code is written during planning"
]
}
]
}
这里有几个值得注意的设计:
files: ["planning-and-task-breakdown"]按evals/fixtures/目录解析,指向的本就是这份 notifications-spec.md 所在的夹具目录。评测执行器会把它物化到一个临时工作区(机制见下文第四节)。- 四条
expectations全部是"行为而非措辞"的可判定陈述:每条任务都有验收标准、任务按依赖排序、任务是垂直切片而非水平分层、规划期间不写实现代码。最后一条尤其关键——它直接对应技能中"Step 1: Enter Plan Mode / Do NOT write code during planning"的纪律约束,防止 Agent 把"规划"偷换成"边写边想"。 - 负向触发用例声明了
owner:evals/README.md说明,声明 owner 后运行器会断言 owner 技能必须排在本技能之前,把负向用例变成真实的成对路由测试,避免"prompt 什么都不匹配就空转通过"。
三、如何拆解这份规格:技能方法论在 spec 上的映射
skills/planning-and-task-breakdown/SKILL.md 定义的规划流程共五步:进入只读规划模式、识别依赖图、垂直切片、按统一结构写任务、排序并设置检查点。仓库还提供了一键入口 commands/planning.toml,其 prompt 要求按上述五步执行,并把计划保存到 tasks/plan.md、任务清单保存到 tasks/todo.md。
把该流程套到 notifications-spec 上,可以这样推演(以下为基于技能规则的示例推演,不是仓库中的既有产出):
依赖图(Step 2)。 从规格文本可以推断出如下依赖链:
每用户偏好存储(含默认禁用语义)
│
├── 偏好读取/更新端点 + 边界校验
│ │
│ └── 特性开关读取(发送路径的开关位)
│
├── 通知作业去重(user+task+event type+event version 唯一键)
│
└── 通知作业发布
├── 分配流程挂接(复用已有 assignment 事件)
└── 逾期流程挂接(复用 15 分钟检测)
│
└── provider 适配器发送 + 投递状态记录
垂直切片(Step 3)。 技能的典型反例是"先做完所有存储,再做完所有 API,最后连起来"的水平分层。对这份规格,水平切法会是"任务 1:偏好 API 全量;任务 2:作业发布全量;任务 3:去重;任务 4:接线"。垂直切法则是让每条任务自成一条可验证的完整路径,例如:
- 偏好存储与 API:端点 + 边界校验 + 默认禁用,附 API 测试(对应需求 1、验证第 1 类);
- 去重键落地:四元组唯一约束/幂等逻辑 + 去重测试(对应需求 3、验证第 2 类);
- 分配事件垂直切片:从已有 assignment 事件发布作业、经去重、开关开启后经 provider 适配器发出、记录投递状态(不含正文)——端到端分配场景即在此闭合(对应需求 2/4/5/6 与验证第 3、4 类);
- 逾期事件垂直切片:复用 15 分钟检测,走同一条发布—去重—发送—记录路径。
这样的切法下,需求 6 的 feature flag 会作为贯穿性约束写进每个发送类任务的验收标准("开关关闭时零发送"),而不是单独成一个孤立任务——因为开关不是一个可独立交付的功能面。
任务结构(Step 4)。 技能规定每条任务必须包含 Description、可测试的 Acceptance criteria、Verification(聚焦测试命令、构建命令、人工检查项)、Dependencies、Files likely touched、Estimated scope(S/M/L 三档)。仓库另一处夹具 evals/fixtures/incremental-implementation/tasks/plan.md 展示了计划文档的最小形态:"每个任务必须可独立验证并提交后再开始下一个"——这条纪律在 notifications-spec 的拆解中同样适用。
检查点(Step 5)。 技能要求每 2–3 个任务后设置验证检查点(全部测试通过、构建干净、核心流程端到端可用、继续前人工复核)。对通知功能,一个自然的检查点是任务 3 之后:分配路径端到端可用且开关默认禁用,此时系统行为与上线前完全一致——这正是"disabled remains the safe default"在规划层的体现。
任务体量(Sizing)。 技能给出的体量表为 XS(1 文件)/S(1–2)/M(3–5)/L(5–8)/XL(8+,必须再拆),并列出必须继续拆的信号:超过一次专注会话、验收标准写不出 3 条以内、触及两个以上独立子系统、标题里出现"and"。按此标准,上述四条任务都在 S–M 区间;若有人把"逾期流程"和"投递状态存储"捆进一条任务,就会命中"标题带 and"与"跨子系统"两个拆分信号。
四、评测管线如何自动验证这份计划
行为评测的执行逻辑在 scripts/run-evals.js 中。核心机制可以确认如下(见 run-evals.js#L388-L427 的 materializeWorkspace):
- 物化夹具:为每个 eval 创建全新临时目录,把
files[]声明的夹具从evals/fixtures/递归复制进去——于是 Agent 拿到的是"真实代码可操作的工作区"而非凭空想象。notifications-spec.md 即在此步进入工作区。 - 建立 git 基线:临时目录
git init后以固定身份提交fixture baseline,让规划/实现型 eval 具备真实的 diff 与提交能力,评分时可以核对 Agent 是否"规划期间写了实现代码"(对应第 4 条 expectation)。 - 执行与评分:executor 以
claude -p无头模式运行(--permission-mode acceptEdits加预授权工具列表),完整stream-json执行轨迹被当作不可信数据封入 grader prompt,经 stdin 送入 grader;grader 输出必须解析为 JSON 且逐条对齐expectations[](每条含text/passed/evidence,summary的计数需与逐条结果自洽)才会写入evals/results/(该目录被 gitignore)。
运行方式(摘自 evals/README.md):
# Tier 2 —— 确定性,可在 CI 运行
node scripts/run-evals.js
node scripts/run-evals.js --min-rank1 80
# Tier 3 —— 行为性,消耗 tokens
node scripts/run-evals.js --behavioral planning-and-task-breakdown
node scripts/run-evals.js --behavioral planning-and-task-breakdown --dry-run
--dry-run 只打印执行计划(工作区、夹具数量、executor 命令),不花 tokens,适合先确认用例接线是否正确。Tier 2 侧则关注 trigger rank-1 rate:CI 以 --min-rank1 80 执行,低于仓库基线 86% 留出余量,且"只允许抬高地板,不允许为让回归变绿而降低"。
五、与 Definition of Done 的分工
规划技能为每条任务产出验收标准,回答"这件事做对了没有";而 references/definition-of-done.md 定义了项目级的常设完成标准(正确性、质量、集成、文档、可发布性五个维度),回答"是否达到我们的完成线"。两者的关系表可概括为:验收标准随任务变化、DoD 一次定义反复使用;任务完成 = 其验收标准满足 且 DoD 通过。对 notifications-spec 而言,"偏好 API 测试通过"是任务级验收标准,而"feature flag 已考虑""新关键路径有可观测性""人工在合并前已审查"则属于 DoD 的常设门槛——技能的 Verification 清单最后一项"人类已审阅并批准计划"也正是把人工门禁前置到了规划阶段。
小结
这份 18 行的通知规格文档是理解 planning-and-task-breakdown 技能的最佳样本:它以"现状事实 + 六条可验收需求 + 四类强制验证 + 明确排除项"提供了理想规格的全部要素;planning-and-task-breakdown.json 用四条行为级 expectation 把它变成可自动评分的测试;而 scripts/run-evals.js 的夹具物化、git 基线与 grader 校验机制,则保证"每条任务有验收标准、按依赖排序、垂直切片、规划期不写代码"这些要求能被逐条取证而非凭印象判定。若你的仓库也在为编码 Agent 编写技能,这套"规格夹具 + 可判定 expectation + 行为轨迹评分"的组合是一个可直接参照的落地范式。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00