最近在使用opencode配合openspec对已有项目,进行二次开发,遇到一些坑记录一下:

一、初始化项目:

首先,在项目根目录运行CLI 命令来创建 OpenSpec 所需的基础目录结构。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
# openspec init 
Note: OpenSpec collects anonymous usage stats. Opt out: OPENSPEC_TELEMETRY=0
Detected tool directories: OpenCode (pre-selected for first-time setup)
✔ Select tools to set up (24 available) OpenCode
▌ OpenSpec structure created
✔ Setup complete for OpenCode

OpenSpec Setup Complete

Created: OpenCode
4 skills and 4 commands in .opencode/
Config: openspec/config.yaml (schema: spec-driven)

Getting started:
  Start your first change: /opsx:propose "your idea"

Learn more: https://github.com/Fission-AI/OpenSpec
Feedback:   https://github.com/Fission-AI/OpenSpec/issues

Restart your IDE for slash commands to take effect.

另外,为了更深入理解openspec,建议把所有openspec的扩展功能都开启了,后续opencode或者claude code里直接使用,修改完需要重启opencode或者claude code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# openspec config profile

Current profile settings
  Delivery: both
  Workflows: 11 selected (custom)
  Delivery = where workflows are installed (skills, commands, or both)
  Workflows = which actions are available (propose, explore, apply, etc.)

✔ What do you want to configure? Delivery and workflows
✔ Delivery mode (how workflows are installed): Both (skills + commands) [current]
? Select workflows to make available:
[x] Propose change
 [x] Explore ideas
 [x] New change
 [x] Continue change
 [x] Apply tasks
 [x] Fast-forward
 [x] Sync specs
 [x] Archive change
 [x] Bulk archive
 [x] Verify change
 [x] Onboard

Create proposal, design, and tasks from a request
Space to toggle, Enter to confirm

二、使用 explore 分析现有代码

这是最关键的一步,你需要使用 /opsx:explore 命令来引导 AI 分析你的代码库,并生成初始规范。

  • 操作方法: 在 AI 对话框中输入:
/opsx:explore 分析当前项目的架构和核心业务逻辑,并生成相应的规范文档
  • 作用: AI 会扫描你的代码文件,理解现有的技术栈、目录结构和功能模块,然后尝试为你生成一份初始的 proposal.md 或 specs 文档,作为后续开发的基线。

三、补全配置

我们都知道openspec的核心思想是“先立规矩,再动手”,通过规范驱动开发(Spec-Driven Development, SDD)来解决 AI 在大型项目中容易出现的“上下文丢失”和“代码混乱”问题。

因此,为了让 AI 更精准地理解你的项目,你可以手动编辑openspec“宪法”文件 openspec/config.yaml

  • 内容:添加你的技术栈(如 React, Python, Go)、编码约定、领域知识等。这能帮助 AI 在后续生成代码时更符合你的项目风格。

我这里直接在opencode里让agent直接输出了:

添加本项目的技术栈、编码约定、领域知识等到openspec/config.yaml 文件,方便后续openspec更精准地理解项目

调整项目openspec主配置文件

四、开始增量开发

完成上述步骤后,就可以按照标准的 OpenSpec 流程进行开发了:

1.创建变更:使用 /opsx:ff <功能名>(快速模式)或 /opsx:new <功能名>(完整模式)开始一个新功能的开发。

2.定义增量规范:在生成的 specs/ 文件中描述本次变更(新增/修改/删除)。

3.执行与归档:使用 /opsx:apply 生成代码,验证无误后使用 /opsx:archive 归档。归档时,增量规范会自动合并到主规范中。再次为之前提供的不准确信息表示歉意,希望这次的流程能帮助你顺利接入 OpenSpec。

举例: 这里给自己的技术工具箱,新增一个文本翻译工具:

/opsx:new 增加一个文本翻译工具,背后调用大模型,默认使用minimax API接口参考这里https://platform.minimaxi.com/docs/guides/text-generation,也支持调用glm的模型,API接口参考https://docs.bigmodel.cn/cn/guide/develop/claude/introduction;翻译功能类似https://fanyi.baidu.com/mtpe-individual/transText#/

新增功能1

新增功能2

最终项目目录结构如下:

openspec
├── changes
│   └── archive
│       └── 2026-03-30-add-text-translator
├── config.yaml
└── specs
    └── text-translator
        └── spec.md

五、功能跑不通怎么办?

如果你是在 AI 生成代码后进行验证,发现代码跑不通或不符合预期,验证失败 (/opsx:verify)

  • 不要直接修改代码:在 OpenSpec 的工作流中,代码是规范的产物。如果代码错了,通常是因为“规范”写得不够清楚,或者 AI 理解错了。
  • 正确的修复步骤:

1. 修改规范 (spec.md):

打开 openspec/changes/新功能1/specs/…/spec.md,把你的修正意见写进去。

  • 例如:在场景描述中增加“必须处理网络超时的情况”。

2. 重新应用 (/opsx:apply):

告诉 AI:“我已经更新了规范,请重新运行 /opsx:apply”。AI 会根据新的规范重新生成代码,覆盖之前的错误代码。

3. 再次验证:

再次运行 /opsx:verify 确认问题已解决。

六、修改代码后如何确保与spec.md同步?

在 OpenSpec 的工作流中,代码是规范的产物。如果你手动修改了代码,但 spec.md 没有同步,就会导致“文档与代码脱节”,下次 AI 再根据 spec.md 生成代码时,你的手动修改就会被覆盖或产生冲突。

为了确保两者同步,请根据你修改代码的时机和原因,选择以下三种策略之一:

1. 最佳策略:先改文档,再生成代码 (Spec-First)

这是 OpenSpec 最推荐的方式。如果你发现代码有问题(比如逻辑不对、参数错误),不要直接去改代码文件。

  • 操作步骤: 1.1 打开 openspec/changes/…/spec.md。 1.2 修改对应的需求描述或场景(Scenario)。 1.3 运行 /opsx:apply。 1.4 结果:AI 会根据新的文档重新生成代码,自动覆盖旧的实现。这是保持同步最彻底的方法。

2. 补救策略:代码已改,反向同步文档 (Reverse Sync)

如果你习惯先快速修改代码(比如修个 Bug 或微调样式),改完后必须立刻把变更“回填”到文档中。

  • 操作步骤:
    1. 保存代码:确保你的代码修改已保存。
    2. 运行验证:在 AI 对话框中输入 /opsx:verify。
      • AI 会对比你的新代码和旧 spec.md。
      • 它会发现不一致(例如:“代码中 Redis 过期时间是 600 秒,但文档写的是 300 秒”)。
    3. 接受建议:让 AI 根据代码更新 spec.md。
    4. 结果:文档被更新以匹配你的代码,两者重新达成一致。

3. 归档时的强制同步 (/opsx:archive)

当你完成功能开发准备归档时,OpenSpec 会强制检查同步状态。

  • 机制:
    • 当你运行 /opsx:archive 时,OpenSpec 会将当前变更目录下的 spec.md 合并到项目的全局规范库(openspec/specs/)中。
    • 注意:如果你手动改了代码但没更新 spec.md,归档后,你的代码逻辑将永远无法在文档中体现。下次有人(或 AI)查看归档文档时,看到的将是过时的逻辑。

七、归档后发现spec.md文档落后于代码

要避免这种情况,你需要建立一套“防御性”的工作习惯。

1. 养成“Verify -> Archive”的肌肉记忆

这是最直接、最有效的日常习惯。永远不要把 /opsx:archive 当作开发结束后的唯一动作。

错误习惯:改代码 -> 测试通过 -> /opsx:archive
正确习惯:改代码 -> /opsx:verify -> (若有差异则同步) -> 测试通过 -> /opsx:archive

具体操作: 在你手动修改代码后,归档前,必须运行 /opsx:verify(或者在 AI 对话框中让 AI 检查)。

  • 告诉 AI:“我手动修改了 xxx.ts,请对比 spec.md,如果有不一致,请帮我更新 spec.md。”
  • 只有当 AI 确认“代码与规范一致”后,再执行归档。

2. 利用 Git 钩子(Pre-commit Hook)强制检查

如果你担心自己偶尔会忘记,可以利用 Git 的机制进行强制拦截。这是团队协作中推荐的做法。

你可以在项目的 .git/hooks/pre-commit 文件中加入检查逻辑。虽然 OpenSpec 没有直接提供这个钩子,但你可以写一个简单的脚本:

脚本逻辑思路:

  • 检测是否有代码文件(如 .ts, .java, .py)被修改。
  • 检测对应的 openspec/changes/ 下的文档是否也被修改。
  • 如果代码变了但文档没变 -> 拦截提交,并提示:“检测到代码变更但 Spec 文档未更新,请先运行 verify 或更新文档!”
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
#!/bin/sh
# .git/hooks/pre-commit

# 检查暂存区是否有代码变更
CODE_CHANGES=$(git diff --cached --name-only | grep -E "\.(ts|js|java|py)$" | wc -l)
# 检查暂存区是否有 Spec 变更
SPEC_CHANGES=$(git diff --cached --name-only | grep "openspec/" | wc -l)

if [ "$CODE_CHANGES" -gt 0 ] && [ "$SPEC_CHANGES" -eq 0 ]; then
  echo "⚠️  警告:检测到代码变更,但未发现 OpenSpec 文档变更!"
  echo "⚠️  请确保你的代码逻辑已同步到 spec.md,或运行 /opsx:verify。"
  echo "如果想强制提交,请使用 --no-verify (不推荐)"
  exit 1
fi

exit 0

另外,对于现代项目,建议使用专门的工具来管理钩子,这样可以将配置写入代码库,全员共享。

  • Python 项目 / 通用:使用 pre-commit 框架。
    • 配置 .pre-commit-config.yaml,定义检查规则(如 flake8, black, detect-secrets)。
    • 运行 pre-commit install 即可自动配置钩子。
  • 前端/Node 项目:使用 Husky。
    • 它可以轻松在 package.json 中定义钩子逻辑,无需手动处理 shell 脚本权限。
  • Golang和Rust 项目:
    • 使用lefthook:https://github.com/evilmartians/lefthook ,通用工具,go开发并行执行,速度飞快

lefthook.yml通用配置模版:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# Lefthook 配置文件
# 支持多语言混合项目 (Polyglot/Monorepo)

# 全局设置
min_version: 1.4.0

# pre-commit 钩子:在 git commit 时触发
pre-commit:
  parallel: true # 核心优化:并行执行所有检查,极大提升速度
  commands:
    
    # ==========================================
    # 1. 前端 (JavaScript / TypeScript)
    # ==========================================
    frontend-lint:
      glob: "*.{js,ts,jsx,tsx,vue}"
      run: npx eslint {staged_files} --fix
      # 注意:如果项目没有 package.json,Lefthook 会自动跳过或报错,视配置而定

    frontend-format:
      glob: "*.{js,ts,jsx,tsx,vue,css,scss,json}"
      run: npx prettier --write {staged_files}

    # ==========================================
    # 2. Go (Golang)
    # ==========================================
    go-fmt:
      glob: "*.go"
      # gofmt -w 会直接修改文件,确保暂存区更新
      run: gofmt -w {staged_files}
    
    go-lint:
      glob: "*.go"
      # 假设你安装了 golangci-lint,这是 Go 社区标准 lint 工具
      run: golangci-lint run {staged_files}

    # ==========================================
    # 3. Rust
    # ==========================================
    rust-fmt:
      glob: "*.rs"
      run: cargo fmt -- {staged_files}

    rust-check:
      glob: "*.rs"
      # 使用 clippy 进行深度检查
      run: cargo clippy -- -D warnings

    # ==========================================
    # 4. Python
    # ==========================================
    python-lint:
      glob: "*.py"
      # 这里以 flake8 为例,也可以换成 black --check 或 pylint
      run: flake8 {staged_files}

    python-format:
      glob: "*.py"
      # 如果使用 black 格式化
      run: black {staged_files}

    # ==========================================
    # 5. Java / Kotlin
    # ==========================================
    # Java 通常依赖构建工具 (Maven/Gradle) 或特定的 linter (如 checkstyle)
    # 这里演示调用 Gradle 的检查任务,它会自动处理所有 Java 文件
    java-check:
      glob: "*.java"
      # 注意:Gradle 任务通常比较慢,且不支持只检查部分文件,
      # 建议只在 pre-push 中运行全量检查,或者使用 spotless 等支持增量检查的插件
      run: ./gradlew checkstyleMain checkstyleTest --quiet

    # ==========================================

3. 事后补救

  • 创建一个新的变更: 命名为 sync-logic-with-code 或 fix-docs-consistency。
  • 让 AI 逆向工程: 在这个新变更中,告诉 AI:“当前的 xxx 功能代码逻辑已经变更,但 spec.md 还是旧的。请以当前代码为准,重写/更新 spec.md。”
  • 归档这个“文档修复”: 运行 /opsx:apply(此时 AI 会生成更新后的文档)和 /opsx:archive。

结果:你的主规范库(openspec/specs/)会被这次新的归档更新,重新与代码保持一致。虽然历史归档里留下了“文档落后”的痕迹,但最新的主规范是准确的。

写在最后,在用OpenSpec开发项目过程中,一定要谨记OpenSpec核心原则:

文档(Spec)是源头,代码是结果。遇到问题,先修文档,再让 AI 重写代码。