前言
很多人尝试AI 写代码,都会遇到一些同样的问题,比如
- 让AI 写个功能,你说一句话,它直接开干,但是写的都不是你想要的
- 前面聊的挺好,真正开始写了,又不是前面说的那样
- 写出来看着挺好的,但是启动就报错,或者出现莫名的bug
这个样子简单的聊天是没办法写出合格的代码的,所以需要软件工程化的手段进行把控。我最近尝试了这两个开源项目 OpenSpec 和 Superpowers 两套件
他们分别是什么
OpenSpec
它是一个 Spec-Driven Development 框架,也就是规格驱动开发。
它做的事情就是和你定需求,把需求,设计,细化任务列表 按照固定格式写下来,并且做需求实现审查和需求文档管理。
一个典型的 OpenSpec 的 change ,也可以称为需求文档。包含以下内容
arduino
├── changes
├── add-tool-framework
├── design.md 技术方案、决策过程和结果
├── proposal.md 需求背景,做哪些事情,功能点是新增还是修改
├── specs 此次修改的细节,按照功能点分类
│ ├── config-management 定义具体需求的边界框架,和代码具体行为
│ │ └── spec.md
└── tasks.md 具体的任务执行列表
它有一套完整的工程化实践
bash
/opsx:explore 需求讨论,澄清
/opsx:propose 需求创建 (创建change)
/opsx:apply 项目代码编写
/opsx:verify 代码编写完成 进行需求合规审核
/opsx:archive 审核通过,需求归档
当需求归档后,当前变更需求会沉淀下来,加入主需求文档
lua
├── changes
├── config.yaml
└── specs 沉淀下来的需求文档
├── adaptive-strategy-placeholder
│ └── spec.md
├── api-response-format
│ └── spec.md
整体来说OpenSpec 主要做的就是需求管控,防止项目在需求上有大的偏差。
Superpowers
它是一套完整的AI 编程方法论,主要做以下几件事
bash
/superpowers:brainstorm 需求讨论
/superpowers:writing-plans 创建任务列表
/subagent-driven-development 子代理驱动代码编写
/requesting-code-review 代码审查
它和上面的 OpenSpec 在流程上有很大的重合,因为都是一套完整的工作流。而Superpower 强大的地方在于 计划编写和代码实现上。
说到计划编写,你会不会有这种困惑,虽然有了计划列表,但是具体AI怎么做,做成什么样子你心里是没底。Superpower 写出来的计划既包含做什么,也包含怎么做,会把具体方案写出来给你审核,在具体是方案确定的情况下,项目编写的结果就靠谱多了。
两者结合
OpenSpec 强项在于需求管理,SuperPowers 强项在于代码编写 。让他们结合起来可以这么做
| 1 | OpenSpec | 需求讨论,澄清 | /opsx:explore |
|---|---|---|---|
| 2 | OpenSpec | 需求创建 (创建change) | /opsx:propose |
| 3 | Superpowers | 拿着 change 创建计划 | /superpowers:writing-plans |
| 4 | Superpowers | 编写代码 | /subagent-driven-development |
| 5 | Superpowers | 代码审核 | /requesting-code-review |
| 6 | OpenSpec | 需求审核 | /opsx:verify |
| 7 | OpenSpec | 代码归档 | /opsx:archive |
到这里一整套的工程实践就好了。当然可以看出来这一套下来是比较庞大的,在中大型优化上可以考虑,小改动就算了。
实战案例
我最近自己在做一个langchain 的项目,拿这来说说。
安装与配置
安装 Superpowers
我直接在 claude code 的 market 里装的 plugin 。
安装 Openspec
perl
npm install -g @fission-ai/openspec@latest
openspec init # 新项目需要初始化
openspec config profile # 可选,可开启全量工作流功能
openspec update # profile 改完记得更新
需求讨论
首先需求讨论 , 对话如下
我:
bash
/opsx:explore 当前项目langchain 没有接入tools ,现在要把这个加上
AI :
arduino
好的,让我们来探索一下在当前项目中接入 LangChain Tools 的可能性。先了解一下现有代码结构。
当前状态
当前 Graph 执行流程 (executor.node.ts)
task_executor:
┌──────────┐
LLM ──invoke(prompt)──▶ text response
ChatOpenAI
└──────────┘
❌ 没有 bindTools()
❌ 没有 ToolNode
❌ 没有 tool-calling loop
✅ 有 ToolError 异常类 (但未使用)
✅ 有 withStructuredOutput (LLM 结构化输出)
整个 graph 中,executor 节点只是把 subtask 的 description 作为 prompt 发给 LLM,拿回纯文本。没有工具调用能力------模型无法"做事",只能"说话"。
css
方案 A:LangGraph ToolNode(ReAct 循环)
方案 B:选择性工具绑定(固定流程)
方案 C:Graph 层面增加 ToolNode
markdown
现在回到关键问题------**你想让 LLM 能调用哪些工具?** 这决定了我们往哪个方向走。比如:
1. 先做通用框架,支持动态注册工具?
2. 还是有具体的工具需求(搜索、数据库、API)?
3. 工具是只读的(查询),还是也有写操作?
这样的问答来回几次就可以把问题从一句话细化成详细的文档了。在这过程中,你要不断的做决策和取舍,不懂的可以直接问,最终把要点全部确认了,就可以进行下一步了。
创建change
回答完AI 的提问,就可以创建change 了。
创建完如下
arduino
├── add-tool-framework
│ ├── design.md
│ ├── proposal.md
│ ├── specs
│ │ ├── config-management
│ │ │ └── spec.md
│ │ ├── event-bus
│ │ │ └── spec.md
│ │ ├── http-api-provider
│ │ │ └── spec.md
│ │ ├── planner-workflow
│ │ │ └── spec.md
│ │ ├── task-state
│ │ │ └── spec.md
│ │ ├── tavily-search-provider
│ │ │ └── spec.md
│ │ ├── tool-framework
│ │ │ └── spec.md
│ │ └── tool-react-loop
│ │ └── spec.md
│ └── tasks.md
proposal.md 截取片段
这文件主要告诉AI 任务背景(why),改什么(what changes),有哪些新功能点(New Capabilities),修改哪些原功能点(Modified Capabilities) , 有哪些影响(Impact)
markdown
## Why
当前 executor 节点仅通过 `chatModel.invoke()` 执行子任务,模型只能生成纯文本回答,无法调用外部工具(搜索、API 等)。这限制了系统处理需要实时信息或外部交互的任务能力。现在需要引入通用的工具框架,让 LLM 在执行子任务时能够自主调用工具,并支持动态注册新工具。
## What Changes
- 新增 `ToolModule`(`common/tools/`),提供 `IToolProvider` 接口和 `ToolRegistry` 服务,支持通过 NestJS DI 动态注册工具
.......
## Capabilities
### New Capabilities
- `tool-framework`: 工具框架核心 --- IToolProvider 接口、ToolRegistry 服务、ToolModule 注册,以及 DynamicStructuredTool 转换
......
### Modified Capabilities
- `task-state`: 新增 `toolHistory` 字段(Annotation + listAppendReducer)
......
## Impact
- **新增代码**: `common/tools/` 目录(module、registry、interface、providers)
tasks.md 截取片段
任务清单
markdown
## 1. 基础类型与接口
- [ ] 1.1 定义 `IToolProvider` 接口(`common/tools/tool-provider.interface.ts`):name、description、schema、enabled、execute
......
add-tool-framework/specs/tavily-search-provider 截取片段
这是功能点的细节规范部分, spec 这里规范了开发行为 使用 WHEN ,THEN 的格式
markdown
## ADDED Requirements
### Requirement: TavilySearchProvider 实现 IToolProvider
系统 MUST 提供 `TavilySearchProvider`,实现 `IToolProvider` 接口,通过 Tavily Search REST API 执行网页搜索。
#### Scenario: name 和 description
- **WHEN** TavilySearchProvider 实例化
- **THEN** `name` MUST 为 `"tavily_search"`,`description` MUST 为 LLM 可理解的中文搜索工具描述
当然有个值得关注的点,非常建议你仔细的去阅读这些文档 ,如果发现有需求边界遗漏的情况,或者其他不合适的地方,直接上手人工改。不管是传统方式做项目还是 AI 编码,在项目需求阶段,反复打磨需求都是节省时间的明智决定。
编写开发计划和开发
bash
/superpowers:writing-plans 按照这个写一个计划 openspec/changes/add-tool-framework
bash
/subagent-driven-development 2026-05-19-add-tool-framework.md
在开发的过程种,观察AI 它的每一个子任务都会
- 写红/绿灯测试
- 写实现代码
- 测试验证
- 测试验证成功则进入 两段代码审查 : Spec 合规审查 和 代码质量审查
- 测试验证失败则 修改代码或者测试用例设置,AI 会自己循环 直到测试通过
验证和归档
先验证需求
bash
/opsx:verify openspec/changes/add-tool-framework
验证结果
markdown
### Final Assessment
**无 critical issue。2 个 warning 需关注。** 工具框架实现完整,31 个任务全部完成,8 个 spec 的核心需求均已在代码中实现。测试覆盖良好(36 个测试全部通过),仅缺少 `maxIterations` 边界条件的显式测试。**可以 archive,建议补充 maxIterations 测试用例。**
有些小问题,可以归档前处理好,也可以归档完再处理。
现在来归档,归档的过程中会对比主Specs 里面的内容和当前change相比,看看有没有需要更新的,最后会把 需求文件夹移动到archive 文件夹里去
bash
/opsx:archive openspec/changes/add-tool-framework
现在看下归档结果:
发现当前change 有需要合并到主Specs 里的内容, 以下是分析结果截取举例:
| Delta Spec | 操作 | 说明 |
|---|---|---|
tool-framework |
ADD | 新 capability,主 specs 中不存在 |
event-bus |
MODIFY | 主 specs 已存在,需追加 tool.called/completed/failed 事件 |
合并的目的就是对每次的change spec 做一个整合,比如两次同一个主题的 change 可能会在主Specs 合并到一起,如果是不同的需求则会,分开见目录或者文件。
还有什么好玩的
当前遇到bug 了,不知道怎么解决,可以试试 systematic-debugging (来自 superpowers)
它会用结构化的调试流程,帮你解决问题,会展开以下4个子任务,系统化的展开一步步的排查,告别盲目猜测。
- 观察与复现
- 假设与定位
- 验证与修复
- 最终验证与回归检查
总结
核心要点:OpenSpec 侧重于文档管理 ,Superpowers 负责 代码编写。
前期和OpenSpec 做大量的需求沟通和决策,形成需求文档+ 开发计划 后人工仔细核对,有必要的话手工修改,后面放手给Ai 去做了。这么做可以把开发人员从大量的代码编写任务中抽离出来,但是对于需求的理解和整体代码设计仍然要亲历亲为,不能偷懒。
本文首发于微信公众号【小杰的AI成长之路】,掘金平台同步分享,如有不足之处,欢迎在评论区指正交流