规格说明中的每一处歧义,
都是你的 AI 代理烧掉的 token。

然后是开发途中的一个澄清问题。然后是上线之后的一次修复。 然后是你一遍遍重新解释的上下文。

SpecScore 是一种用于规格说明的开放、可 lint 的文件格式—— 就像 JSON 之于数据。并配有 CLI,供你的 AI 代理调用以查询和 编辑它们——就像 jq 之于 JSON。

为你已有的规格说明提供格式。

SpecScore 是一种基于 Markdown + YAML 的格式,用于描述功能、 需求和验收标准。它定义了一种你的团队和 AI 代理都能理解的结构——而它只是仓库中的文件。

一个 SpecScore 项目包含三种生命周期制品:Idea(构想)捕捉一个半成形的方向;Feature(功能)冻结已达成共识的行为;Plan(计划)将功能分解为有序任务, 每个任务引用它所满足的验收标准。

为什么你的 AI 代理在意。因为结构是机器可读的, AI 代理可以通过 CLI 查询规格说明,而不必读取每一个文件。问一句“我接下来该做什么?”,CLI 就会返回开放的 Feature 和尚未回答的问题。和你团队评审的是同一份形态,但代理需要加载的 上下文要少得多。

Feature → Requirements → Acceptance Criteria → Scenarios.
示例ideas/apply-discount.md
# Idea: Discount codes at checkout

**Status:** Approved
**Date:** 2026-05-19
**Owner:** cart-team
**Promotes To:** features/apply-discount

## Problem Statement

How might we let returning customers redeem a
single promo code at checkout without breaking
the existing cart math or the site-wide promotion
engine?

## Recommended Direction

A registered user can apply **one** valid code per cart.
Codes are time-bounded and replaceable. Stacking
with site-wide promotions follows a deterministic
tiebreak rule (higher discount wins; site-wide
wins on tie).
示例features/checkout/apply-discount.md
---
status: approved
owners: [cart-team]
---

# Feature: Apply Discount

A registered user can apply one valid discount code to their cart at checkout.

## Requirements

### R1 — Single-code limit

- **AC-1** The cart accepts at most one discount code at a time.
- **AC-2** Applying a second code replaces the first, with a visible confirmation.
- **AC-3** Removing the code restores the original cart total.

### R2 — Code validity

- **AC-1** A code is valid only if `valid_from` ≤ now ≤ `valid_until`.
- **AC-2** Invalid codes show a specific error message.

### R3 — Discount application

- **AC-1** Percentage discounts apply to subtotal, not shipping.
- **AC-2** Discount totals round down to the nearest cent.
- **AC-3** Stacking with site-wide promotions follows the higher-of rule.

## Scenario: Apply a valid percent-off code

**GIVEN** a cart with subtotal $50.00 and shipping $10.00
**WHEN** the user applies code `SAVE20` (20% off)
**THEN** the cart shows subtotal $40.00, shipping $10.00, total $50.00
示例plans/apply-discount/README.md
# Plan: Apply Discount

**Status:** approved
**Features:**
  - [apply-discount](../../features/apply-discount.md)
**Author:** cart-team
**Effort:** M
**Impact:** high

## Context

The apply-discount Feature is Approved. This plan
breaks it into ordered tasks; each task cites the
acceptance criteria it satisfies.

## Tasks

### T1 — Accept a `code` field on the cart
Cites: R1.AC-1, R1.AC-2, R1.AC-3

### T2 — Validate code time-window
Cites: R2.AC-1, R2.AC-2

### T3 — Apply percentage to subtotal, round down
Cites: R3.AC-1, R3.AC-2

### T4 — Higher-of tiebreak vs site-wide promo
Cites: R3.AC-3

### T5 — Confirmation toast on apply / replace
Cites: R1.AC-2

规格说明是层级结构。所以你的规格树也是。

当 Feature 数量达到五十个时,扁平列表就会变成一堆乱麻。 SpecScore 让树保持可导航——父节点掌管范围,子节点掌管细节, 目录结构映射的正是你的团队早已在头脑中梳理的产品结构。

未决问题会向上汇总。任何深度上未解决的问题, 都会浮现在每个父节点的索引里。你可以从树顶看到是什么在阻塞发布, 而无需深入挖掘。

大多数规格工具假设扁平列表就够用了。确实够用——直到不够用为止。 SpecScore 正是为"这个 Feature 该放在哪里?"开始变得要紧的那一刻 而设计的。

在 specscore-cli 中实时查看 →

FROMspecscore-cli/spec/features/cli/
spec/features/cli/
├── agent/
│   └── setup/
├── feature/
│   ├── change-status/
│   ├── deps/
│   ├── info/
│   ├── list/
│   ├── new/
│   ├── refs/
│   └── tree/
├── idea/
│   ├── change-status/
│   ├── new/
│   └── relocate/
├── spec/
│   └── lint/
│       ├── issue-rules/     ← 子-子 Feature
│       └── plan-rules/
├── task/
│   ├── info/
│   ├── list/
│   └── new/
└── … 还有 10 个顶层 Feature

没有它会出什么问题。

  • 规格说明会漂移。

    文档中的规格、Slack 里的讨论和 PR 中的代码悄悄地 分歧了好几周。没人能找到哪个版本的对话才是权威的。

    解决方案

    仓库中的唯一权威规格,与代码一起进行版本管理。specscore lint 在 CI 中每次推送时运行; git 历史就是审计追踪。规格、讨论和 PR 不可能悄悄 分歧——它们审查的是同一个文件。

  • 验收标准含混不清。

    "优雅地处理错误"本来应该是指"显示提示并回滚"。还是"记录日志并重试?"AI 代理只能猜测。

    解决方案

    代码检查器在写任何代码之前就能捕获含混的标准。 动词无法通过检查,因为它缺少具体的对象或条件。 修复这个警告会迫使你写清楚"处理"到底 意味着什么。

  • AI 代理交付了错误的东西。

    人类会推断、提问、澄清。AI 代理不会——它们实现的 是训练数据中最常见的模式。代码通过了审查,因为它做了某些合理的事情。只是不是你想要的。

    解决方案

    结构化输入。AI 代理确定性地解析 REQ ID、AC ID 和GIVEN / WHEN / THEN场景——无需推断。Plan 必须引用每个任务满足的 AC ID, 所以构建的内容始终可以对照规格进行验证。

  • 含糊的规格,你要付两次钱。

    代理根据含糊的指令做出了东西,你发现不对,于是换四种说法 重新提示。每个做了一半的功能、每一次重试,都按 token 计费。 规格越含糊,落地前来回的轮次就越多。

    解决方案

    在代理运行前先 lint 规格。specscore lint在一开始就拒绝含糊的动词和缺失的验收标准,于是代理一次就 实现明确的指令,而不是在重试中反复猜测。最便宜的一次代理 运行,就是你不必重复的那一次。

  • AI 代理反复付费读取规格。

    AI 代理回答"什么依赖于这个功能?"时, 要读取整个功能 README。然后读每个父级索引。 然后以防万一再读兄弟功能。每次查询都是一次重新解析。 Token 在消耗;延迟在增加;费用也随之攀升。

    解决方案

    用结构化查询代替文件读取。specscore feature tree 以 YAML 格式返回层级结构;feature deps 遍历传递性依赖链;feature info 展示状态、负责人和待解决问题——每个只需 一次调用。代理导航的是图,而不是文本。

  • 代码忘记了它的规格。

    六个月后,你在调试一个函数,没人记得它实现了哪个 功能。代码和规格之间的关联存在于某人的脑袋里, 而那个人已经离职了。引入它的 PR 已经存档。

    解决方案

    源码注解。类似// specscore: features/checkout/apply-discount/R1.AC-2的注释使关联变得机器可读,并在每次重构中保留下来。specscore code deps 一次调用即可回答"这个文件实现了哪个规格?"; 代码检查器会标记指向已删除规格的引用。

  • 状态变更会泄漏。

    你把一个功能从 Draft 改为 Approved, 但父级的 features-index 仍然显示它是 Draft。三周后, 读取索引的 AI 代理认为它仍在变动中。状态现在存在于 两个地方,而且它们不一致。

    解决方案

    specscore feature change-status 在一个 原子操作中重写功能的 Status 字段并重新同步 features-index 中的行——检查失败会回滚修改。状态存在于唯一的权威位置; 索引只是它的生成视图。

  • 规格忘记了它不知道的东西。

    规格读起来像是已经定稿了——直到你想起两个月前在 Slack 讨论中丢失的"时区怎么办?"这个问题, 它从来没有进入文档。现在你们在实现阶段,没人能说出 答案是什么。

    解决方案

    每个 SpecScore 功能都有一个必填的Outstanding Questions 部分。代码检查器 会拒绝省略它的功能——留空可以 ("None at this time."),但不能没有。 未解决的问题在文档中可见,可从 CLI 查询,不可能被遗忘。

最简单的入门方式:面向 AI 代理的 SpecStudio Skills。

SpecStudio Skills是一个 Claude Code 插件,它将 SpecScore 生命周期转化为四个斜杠命令。 安装一次,然后按顺序运行——从原始想法到可执行计划。

$ /plugin marketplace add specscore/ai-marketplace
$ /plugin install specstudio@specscore
Claude Code自动补全
> /specstudio:
   /specstudio:ideate     将原始想法打磨为 SpecScore Idea
   /specstudio:specify    将已批准的 Idea 转化为 Feature 规格
   /specstudio:plan       将 Feature 分解为有序任务的 Plan
   /specstudio:implement  执行 Plan 中的下一个任务
Claude Code/ideate
> /ideate 让我们想想结账流程中购物车页面应该怎么设计。
Claude Code/specify
> /specify 定义 spec/ideas/checkout-basket.md
Claude Code/plan
> /plan 实现 spec/features/checkout/basket/README.md
Claude Code/implement
> /implement 执行 spec/plans/checkout-basket/README.md

对公开和开源仓库免费。插件源代码在specscore/specstudio-skills——MIT 许可证。

分两遍检查你的规格。

先是快速的确定性代码检查器,再是更深入的 AI 审查 — 都在你刚才看到的规格上运行。两遍检查,两种确定性。

运行代码检查器。

deterministic

每次运行结果都相同。免费、快速,可在每次提交时运行。

用 AI 审查并评分。

non-deterministic

像人类审查者一样按含义阅读。

它捕获不到的,我们也照实说。

一个声称什么都能查出来的代码检查器是在撒谎。SpecScore 是一个分层的系统 — 确定性的代码检查器、AI 审查器,以及你自己的判断 — 每一层都有真实的边界。 我们把它们全都写了下来:lint 能查到什么、AI 能查到什么,以及还有什么只能靠你 — 因为目前还没有工具能做到。

代码检查器查不到的东西 →

包含什么。

格式

Markdown + YAML。在任何能打开文本的编辑器中使用。 无需新工具即可开始编写。

代码检查器

Go 语言编写的 CLI。验证结构、引用和完整性。 失败时返回非零退出码——适用于你的终端和 CI。

无需绑定任何工具。

SpecScore 只是你仓库中的文件。无需注册任何 SaaS。无需编排器。 可以与 Linear、Jira、GitHub Projects、文件夹中的原始 Markdown 一起使用,或者完全不用任何项目管理工具。格式和代码检查器 不关心你的工单放在哪里。

更喜欢 CLI?

不使用 AI 代理,或者需要在 CI 流水线中验证规格? 有一个 CLI 工具可以做到。60 秒完成安装——无需账户、无遥测, 适用于任何 Markdown 规格目录。

$ curl -fsSL https://specscore.md/install/get-cli | sh

对随二进制文件附带的示例规格运行代码检查器:

$ specscore lint examples/checkout/apply-discount.md

查看输出:

  examples/checkout/apply-discount.md
    ✓ R1  has acceptance criteria
    ✓ R2  has acceptance criteria
    ✗ R3  no acceptance criteria
    ✗ link     "Related Feature: discount-tiers" not found
    ✗ section  "Open Questions" missing

  3 problems   exit 1

阅读完整文档在 GitHub 上贡献

基于 SpecScore 构建。

  • Codegrapher

    代码图引擎,用于快速代码探索以及规范与代码的双向关联。

    codegrapher.dev
  • DALgo

    使用 SpecScore 规范的 Go 数据访问层。

    dal-go.github.io
  • inGitDB

    使用 SpecScore 规范的基于 Git 的版本化数据库。

    ingitdb.com
  • Rehearse

    验收证据层——真实运行规范的验收标准,检查可复用,无需胶水代码。

    rehearse.ink
  • SpecScore Studio

    用于查看和编辑 SpecScore 规格的 Web UI。

    specscore.studio

还有疑问?

以下是大家最常问的问题。每条都链接到FAQ 页面的完整答案。

SpecScore 和 spec-kit 有什么区别?

spec-kit 是一种方法论;SpecScore 是你所写规格说明的存储格式, 外加一个 CLI。两者可以组合——一个能输出 SpecScore 的 spec-kit 扩展正在开发中。

完整答案 →
SpecStudio Skills 与 Superpowers、agent-skills 有何不同?

理念相近——三者都引导 AI 代理走完 ideate → specify → plan → implement。SpecStudio Skills 以 SpecScore 格式写出 产物,并通过 specscore CLI 完成查询和状态变更; 另外两者主要直接读写文件。当 token 消耗很重要时,选 SpecStudio。

完整答案 →
为什么要 CLI——只装技能不行吗?

技能无法可靠地保证引用完整性,无法在不读取所有文件的情况下 返回筛选后的查询结果,也无法在合适的时机更新正确的状态字段。 CLI 用一次调用就能完成每一项。技能要做同样的事,得读完每个文件。

完整答案 →
为什么叫"SpecScore"——它在给什么打分?

两层含义,都是有意为之。Partitura(总谱)——一份结构化的 需求总谱。以及字面上的质量评分——CLI 检查器给出确定性的分数,/score 技能则是 AI 评判的 A–F 就绪度评级。

完整答案 →
token 节省的数据在哪里?

实测的并排对比正在准备,会在 Habr 文章前发布。从结构上看: CLI 返回一个小的结构化列表;而普通代理则要读 N 份文档。

完整答案 →

通过检查的规格说明。

或 阅读文档

★ 在 GitHub 上加星 — 帮助更多人发现这个项目。GitHub stars

发现翻译问题或有改进此页面的想法? 告诉我们.