写在前面:这篇文章是我在上一份前端工作中做的一项技术探索,脱敏后重建并分享出来。规范驱动开发(Spec-Driven Development)的流程、
/speckit.*命令、以及 OpenCode 集成本身,都来自 GitHub 官方开源的 spec-kit------这些不是我发明的。本文要讲的,是我在深度使用它之后,发现官方在 OpenCode 上的执行模型有一个缺口,然后自己动手补上的那一层。
一、先交代背景:规范驱动开发是什么
如果你也用 AI 写过稍微大一点的功能,大概率踩过这个坑:把需求一股脑甩给 AI,它噼里啪啦给你生成一大坨代码,但细看全是问题------接口是编的、和现有代码风格不一致、需求理解还偏了。
spec-kit 给的解法是"规范驱动开发":不让 AI 一步到位,而是拆成一条流水线,每一步产出一个可审查的文件:
bash
/speckit.constitution → 项目章程(技术栈、代码规范、约束)
/speckit.specify → 功能规范 spec.md
/speckit.clarify → 澄清规范里的模糊点
/speckit.plan → 技术实施计划 plan.md
/speckit.tasks → 任务清单 tasks.md
/speckit.implement → 按任务写代码
每一步你都能停下来检查、修改,再往下走。这套东西官方已经支持 OpenCode------specify init --integration opencode 一跑,命令就装好了。我最初就是直接用的官方版本。
二、用着用着,撞上了"上下文污染"
流程跑通了,但用久了我发现一个让人不安的现象:一条流程从 constitution 跑到 implement,越到后面 AI 的表现越差------前面还好好的,到了 tasks、implement 阶段开始答非所问,甚至把前面定好的约束忘了。
我去翻官方的 OpenCode 集成到底生成了什么,specify init --integration opencode 之后,目录是这样的:
bash
.opencode/
└── commands/ # 只有命令,10 个 speckit.*.md
├── speckit.specify.md
├── speckit.plan.md
└── ...
.specify/ # 模板、脚本、章程
注意:它只生成了 commands/。 在 OpenCode 里,普通 command 是在主会话(当前对话)里执行 的------也就是说,specify 生成的几百行 spec、plan 生成的几百行计划、tasks 拆出来的一长串任务......这些中间产物会全部堆积在主对话的上下文里。
等跑到 implement,主对话已经塞了几千行前置产物。上下文被撑满,模型注意力被稀释,质量下降几乎是必然的。这就是"上下文污染"------问题不在 spec-kit 的流程,而在它在 OpenCode 上的执行载体。
三、改造:把每个命令塞进独立的 subagent
OpenCode 其实提供了解决这个问题的原生机制,只是官方 spec-kit 集成没用上------那就是 subagent。
OpenCode 里有两种执行单元,语义完全不同:
| 执行上下文 | 上下文污染 | |
|---|---|---|
| command(官方用的) | 主会话 | 会 |
| subagent | 独立子会话 | 不会 |
subagent 跑在自己独立的上下文窗口里,不继承主对话历史,执行完只把结果摘要回传主会话。这正是我需要的。
于是我的改造很直接:给每个 speckit 命令配一个 mode: subagent 的 agent 定义。
markdown
---
description: Spec-Kit 规范创建器,从需求生成功能规范 spec.md
mode: subagent
temperature: 0
tools:
read: true
write: true
bash: true
---
你是 Spec-Kit 规范创建器,运行在独立子会话中。
## 核心职责
1. 创建规范目录
2. 从需求提取功能点
3. 生成 spec.md
...
然后让命令通过 frontmatter 的 agent: 字段声明式地绑定到它:
markdown
---
description: 从自然语言创建功能规范
agent: speckit-specify # ← 绑定到上面的 subagent
handoffs:
- label: 构建技术计划
agent: /speckit.plan
---
这样一来,用户打 /speckit.specify,OpenCode 会把它派发到 speckit-specify 这个 subagent 的隔离子会话里执行,生成 spec.md,只把"规范已创建,29 条需求"这样的摘要回传主会话。几百行的中间产物不再污染主对话。
验证一下是不是真的生效
光说不练假把式。我把改造后的 agent 定义放进 .opencode/agent/,用 opencode agent list 看 OpenCode 认不认:
scss
$ opencode agent list
build (primary)
explore (subagent)
general (subagent)
...
speckit-specify (subagent) ← 全部被识别为 subagent
speckit-plan (subagent)
speckit-tasks (subagent)
speckit-implement (subagent)
... (共 11 个 speckit-* subagent)
11 个 speckit 命令全部被 OpenCode 识别为 subagent,跑在隔离上下文里。对照官方配置------agent list 里一个 speckit subagent 都没有,因为官方只装了 command。
实测环境:OpenCode 1.17.7。顺带踩到一个小坑:命令目录现行标准是复数
commands/,单数command/是 legacy 兼容路径;而 agent 目录是单数agent/。
除了 subagent 隔离,我还顺手做了三件事:
- 调度 skill :加了一个
speckit-orchestrator,做意图识别------用户说"帮我把这个需求写成规范"也能路由到/speckit.specify,不必记命令。 - 后台执行:implement 这种长任务标记为后台跑,主会话不阻塞。
- 中文化:整套提示词和交互改成中文,适配中文团队。
四、真正的难点不在改造,在"规范的粒度"
改造完,我满怀期待跑了一个真实的前端列表功能。结果首版翻车了------这部分的复盘,其实比改造本身更有价值。
坑 1:UI 渲染不符合团队规范。 生成的页面布局乱七八糟,没用团队约定的栅格组件。 根因:我的章程(constitution)里只写了"用 Vue3 + Ant Design Vue",没有显性声明"页面布局必须用 <a-row>/<a-col> 栅格"。AI 不知道这条潜规则,自然自由发挥。
坑 2:公共组件被重复造。 明明有现成的搜索栏组件,AI 又写了一个。 根因:任务清单(tasks)里没把公共组件标成共享依赖,AI 不知道该复用。
坑 3:需求 UI 细节模糊导致理解偏差。 比如"数据列表"------加载中显示什么?空数据显示什么?出错呢?规范里没说,AI 就只实现了正常态。
这三个坑,根因高度一致:规范写得不够具体。 于是我把这些教训固化进了流程:
- 章程里强制显性声明 UI 组件库和布局系统,写"必须用 X"而不是"注意 X"
- clarify 阶段强制扫描交互三态(loading / empty / error)
- tasks 阶段把公共组件/类型显性标注为前置共享依赖,implement 强制复用
跑出来的结论,我觉得是这次探索最大的收获:
规范的粒度,决定 AI 输出的质量上限。模糊的约束等于没有约束。
这也回过头解释了为什么"规范驱动"比"让 AI 直接写"强------它逼着你把脑子里的隐性约束写成显性规范,而这正是 AI 最需要的。
五、诚实地说说这套东西的价值与边界
写到这里,我得划清楚边界,免得显得在邀功:
| 维度 | 官方 spec-kit(OpenCode 集成) | 我的改造 |
|---|---|---|
| 规范驱动流程、12 命令 | ✅ 官方提供 | 沿用 |
| 命令载体 | 普通 command | 加一层 subagent |
| 执行上下文 | 主会话(会污染) | 独立隔离子会话 |
| 命令路由 | 用户直接打命令 | 加调度 skill 做意图识别 |
| 长任务 | 同步 | 后台执行 |
| 语言 | 英文 | 中文化 |
这不是重造 spec-kit,而是"读懂官方实现 + 补上一个缺口"。 增量集中在执行模型------把 spec-kit 的命令从"主会话 command"改造成"隔离 subagent",解决长流程的上下文污染。
适用场景:你在 OpenCode 上重度使用 spec-kit、且功能流程较长、对上下文质量敏感。 不适用:短平快的小需求,官方 command 版完全够用,没必要加这层。
结尾
这次探索给我的最大体感是:工具用到深处,就会自然想去改它。 用 spec-kit 用到撞上上下文污染,顺着 OpenCode 的 subagent 机制把它补上------整个过程没写多少代码,但逼着我把 OpenCode 的 agent/command 执行模型、spec-kit 的集成方式都摸了一遍。
对我来说,这比"又调通了一个 AI 工具"更有意思:你开始把 AI 编码工具当成可以拆开改造的系统,而不是黑盒。
代码仓库整理中,稍后开源。欢迎交流。