OpenSpec案例
本文档网站其实就是由Codex+OpenSpec构建而成的,正好可以作为案例来说明OpenSpec的用法。每一轮OpenSpec交互主要有以下几步:
- Create Proposal:向AI描述自己的需求以及任何必要的信息,让AI生成一份OpenSpec Proposal
- Review Proposal:审核AI生成的Proposal,与AI反复沟通修改直到满意
- Implement Proposal:让AI根据Proposal生成代码
- Review Implementation:审核AI生成的代码,与AI反复沟通修改直到满意
- Archive Proposal:归档本轮Spec,作为项目需求的长期记录
以上每一步都可以通过提示词触发,只需要在对话中提到对应的关键字即可,详细信息如下:
Create & Review Proposal
向AI描述新的需求,可以是一个已经想好的新功能,也可以只是一个需要调整的问题。可以用create openspec proposal开头,这样就能触发OpenSpec的create proposal功能。例如我在构建本页面时发现点击进入文章的功能有问题,于是我向AI描述了我的观察,解释了我的思考以及需求。
create openspec proposal: right now on the cover page, only clicking the article title text will work, clicking the empty area of the box will not enter the article, this is a bit counter-intuitive. make the entire box an entry to the article.
OpenSpec随后新建了如下的Proposal,可以看到一个Proposal中主要有三个Markdown文件,proposal.md,spec.md,tasks.md:

其中proposal.md是AI对我的需求的润色和总结,AI在其中解释了为什么需要更改,需要怎么更改以及会更改哪些文件:
# Change: Make cover page article cards fully clickable
## Why
On the cover page, each article is displayed as a boxed list item, but only the title text is currently a link. Clicking the empty area inside the box does nothing, which is unintuitive and makes the click target unnecessarily small (especially on touch devices).
## What Changes
- Render each cover page article list item as a single full-card link so clicking anywhere in the box navigates to the article.
- Preserve existing ordering and titles from `list.json`.
- Keep styling consistent (hover/focus states apply to the entire card).
## Impact
- Affected specs: `static-docs-site` (cover page UX)
- Affected code (expected):
- `scripts/build.mjs` (cover page markup)
- `assets/style.css` (card/link styles)
- `deploy/index.html` (generated output)
而spec.md则是对需求的正式定义,AI将我们本轮的需求结合过往的需求,以一条一条的逻辑表达式记录了下来。通常我们不需要直接审核这个文件:
## MODIFIED Requirements
### Requirement: Cover page listing all articles
The system SHALL generate a cover page at `deploy/index.html` that lists all published articles defined in `list.json` and links to their generated HTML pages. Each article list item SHALL provide a full-card click target such that clicking anywhere within the visible item box navigates to the corresponding article page.
#### Scenario: Single listed article
- **GIVEN** `list.json` lists only `introduction.md`
- **WHEN** the user runs the build command
- **THEN** `deploy/index.html` lists exactly 1 article
- **AND** that list item links to `introduction.html`
- **AND** clicking within the list item box (including whitespace around the title) navigates to `introduction.html`
#### Scenario: Only listed articles appear
- **GIVEN** `md/a.md` and `md/b.md` exist
- **AND** `list.json` lists only `a.md`
- **WHEN** the user runs the build command
- **THEN** `deploy/index.html` lists only `a.md`
- **AND** `deploy/b.html` is NOT produced
最后,tasks.md则是AI为自己生成的一个TODO List,列出了本轮需求需要完成的所有任务,这个功能可以督促AI充分完成任务。在没有此功能的情况下,AI在处理超长任务时可能会产生幻觉导致提前结束并嘴硬说自己已经完成了所有任务:
## 1. Proposal Acceptance Criteria
- [ ] 1.1 Confirm behavior applies to all devices (desktop + mobile).
- [ ] 1.2 Confirm each card remains a single semantic link (no JS click handlers required).
- [ ] 1.3 Confirm hover and focus styling expectations for the full-card link.
## 2. Implementation
- [ ] 2.1 Update cover page HTML generation so the full card is a block-level `<a>` link.
- [ ] 2.2 Update CSS so border/padding/hover styles apply to the full-card link.
- [ ] 2.3 Rebuild and verify clicking whitespace inside the card navigates to the article.
## 3. Regression Checks
- [ ] 3.1 Cover page still lists articles in `list.json` order.
- [ ] 3.2 Cover page still displays manifest titles only (no filename/slug).
- [ ] 3.3 Mobile layout has no horizontal overflow regressions.
如果在审核中发现Proposal有不符合意愿的地方,建议通过对话的方式让AI修改Proposal。不建议直接手动修改Markdown文件,因为这可能会破坏三个文件之间的关联逻辑。在我的案例中,Proposal基本符合我的预期,所以未作任何修改。
Implement Proposal
审核完Proposal之后便可让AI开始写代码,只需要以下一句简单的指令:
implement the proposal
在我的案例中,AI顺利完成了任务并给出以下答复:
Implemented: cover page article “boxes” are now full-card links (clicking whitespace inside the box opens the article).
- Updated cover page generation to render each list item as a block-level link in scripts/build.mjs:176.
- Updated card styles/hover/focus to apply to the full link in assets/style.css:354 (propagated to deploy/assets/style.css:354) and rebuilt deploy/index.html:30.
- Marked the OpenSpec checklist complete in openspec/changes/update-cover-page-clickable-cards/tasks.md:1.
No commit made. To verify: run npm run preview, open http://localhost:8000/index.html, and click the empty area of a card.
AI一般会引导你检查它的工作,我在检查完页面之后发现符合预期。如果在这一步发现代码有问题,那么分两种情况处理:
- 如果发现AI顺利完成了Proposal,只是自己的Proposal之前考虑得不对,那么建议先走完当前的轮次,在下一轮中新建Proposal来修正。
- 如果发现AI并没有完全实现Proposal中规定的内容,那么可以直接向AI指出问题并让它立即调整。
Archive Proposal
当完成本轮代码之后,用以下指令让OpenSpec归档本轮Spec并提交代码:
archive the proposal and commit the changes
AI答复如下:
Archived OpenSpec change update-cover-page-clickable-cards as 2026-01-16-update-cover-page-clickable-cards and updated openspec/specs/static-docs-site/spec.md.
Committed the changes: 5d7881d (“Make cover page cards fully clickable”).
至此,一个完整的OpenSpec轮次就结束了。我们使用OpenSpec分三步实现了一个对页面的调整,同时我们的需求被记录进了Spec文件,将来当新AI接受这个项目时,或者我们对相关功能做其他调整时,AI都能了解到这个需求并保持一致。
Proposal的大小
然而,上述案例中展现的其实是一个相当简单的需求,对于这个需求我们依然完整走了OpenSpec的三步,并且与传统对话相比消耗了更多Token。对于这样一个简单的需求来说,即便用传统对话我相信AI也能顺利完成。同时,整个流程很短,也没有充分发挥出OpenSpec的TODO List优势。因此当Proposal简单且短小时,OpenSpec的短期优势消失了,只剩下长期优势。在实际使用中,可以适当地将多个相关的需求放进同一个Proposal当中并让OpenSpec一次解决,从而更好地发挥OpenSpec的优势。
赛博牛马,Slow is Fast
在Codex实力强劲的同时,它也几乎是一线模型/工具中最慢的一个。然而这对于有着充分摸鱼时间的用户来说却并不一定是一件坏事。除了代码需求,我们甚至可以把一些流程性的任务放进OpenSpec Proposal中交给Codex牛马。比如在Proposal中描述了一个脚本的需求之后,还在继续写"help me debug the script with data XXX. after debugging, run the script with these 10 different configurations XXX and summarize the results into ./outputs/results.md"。OpenSpec会将这些事务放进tasks.md中,并督促Codex一一完成,虽然Codex可能需要一个小时甚至两个小时的龟速来完成,但是充分仔细的思考以及慢工出细活的风格都更有可能让你在愉快摸鱼回来后看到一份完整可靠的结果且无需二次修改,慢就是快。