Spike
当用户想要在投入正式构建前试探一个想法时使用此技能 —— 验证可行性、比较不同方案或揭示仅凭文档无法发现的未知问题。Spike 本质上是可丢弃的,一旦发挥完作用即可抛弃。
当用户说出以下内容时加载此技能:“让我试试这个”、“我想看看 X 能不能行”、“spike 一下这个”、“在投入 Y 之前”、“快速原型 Z”、“这真的可行吗?”或“比较 A 和 B”。
何时不应使用此技能
- 问题的答案可以通过文档或阅读代码获知 —— 只需研究,无需构建
- 工作属于生产路径 —— 应使用
plan技能 - 想法已验证通过 —— 直接进入实现阶段
如果用户安装了完整的 GSD 系统
如果 gsd-spike 作为兄弟技能出现(通过 npx get-shit-done-cc --hermes 安装),当用户希望使用完整的 GSD 工作流时,优先使用 gsd-spike:包括持久的 .planning/spikes/ 状态、跨会话的 MANIFEST 追踪、Given/When/Then 判定格式以及与 GSD 其余部分集成的提交模式。此技能是面向未安装或不需要完整系统的用户的轻量独立版本。
核心方法
无论规模大小,每个 Spike 都遵循以下循环:
分解 → 研究 → 构建 → 判定
↑__________________________________________↓
根据发现迭代
1. 分解
将用户的想法拆解为 2-5 个独立的可行性问题。每个问题是一个 Spike。以表格形式呈现,使用 Given/When/Then 框架:
| # | Spike | 验证内容 (Given/When/Then) | 风险 |
|---|---|---|---|
| 001 | websocket-streaming | Given a WS connection, when LLM streams tokens, then client receives chunks < 100ms | 高 |
| 002a | pdf-parse-pdfjs | Given a multi-page PDF, when parsed with pdfjs, then structured text is extractable | 中 |
| 002b | pdf-parse-camelot | Given a multi-page PDF, when parsed with camelot, then structured text is extractable | 中 |
Spike 类型:
- 标准型 —— 一种方法回答一个问题
- 对比型 —— 同一问题,不同方法(共享编号,字母后缀
a/b/c)
好的 Spike 问题: 具体可验证,有可观察的输出。 不好的 Spike 问题: 过于宽泛,无可观察的输出,或只是“阅读关于 X 的文档”。
按风险排序。 最有可能否决该想法的 Spike 最先执行。如果困难部分行不通,先验证容易的部分毫无意义。
跳过分解 仅当用户已经确切知道他们想 Spike 什么并明确指示。此时直接将他们的想法视为单个 Spike。
2. 对齐(针对多 Spike 的想法)
展示 Spike 表格。询问:“按此顺序全部构建,还是需要调整?”让用户在编写任何代码之前删除、重新排序或重新定义范围。
3. 研究(每个 Spike,在构建之前)
Spike 并非无需研究 —— 你需要进行足够的研究以选择正确的方法,然后构建。每个 Spike:
-
简述。 2-3 句话:这个 Spike 是什么,为什么重要,关键风险。
-
列出竞争方案(如果确实存在选择):
方案 工具/库 优点 缺点 状态 ... ... ... ... 维护中 / 已废弃 / 测试版 -
选择一个。 说明原因。如果 2 个以上的方案都可信,则在 Spike 内构建快速变体。
-
跳过研究 适用于纯逻辑且无外部依赖的情况。
使用 Hermes 工具进行研究步骤:
web_search("python websocket streaming libraries 2025")—— 寻找候选方案web_extract(urls=["https://websockets.readthedocs.io/..."])—— 阅读实际文档(返回 markdown)terminal("pip show websockets | grep Version")—— 检查项目虚拟环境中已安装的内容
对于没有文档页面的库,通过 read_file 克隆并阅读其 README.md / examples/。如果用户配置了 Context7 MCP,这也是一个很好的来源 —— 使用 mcp_*_resolve-library-id 然后 mcp_*_query-docs。
4. 构建
每个 Spike 一个目录。保持独立。
spikes/
├── 001-websocket-streaming/
│ ├── README.md
│ └── main.py
├── 002a-pdf-parse-pdfjs/
│ ├── README.md
│ └── parse.js
└── 002b-pdf-parse-camelot/
│ ├── README.md
│ └── parse.py
倾向于用户可交互的产物。 如果唯一的输出是一行“它工作了”的日志,Spike 就失败了。用户需要 感受到 Spike 在工作。按优先级排序的默认选择:
- 可运行的 CLI,接收输入并打印可观察的输出
- 最小化的 HTML 页面,演示行为
- 带一个端点的小型 Web 服务器
- 一个单元测试,使用可识别的断言来验证问题
深度优于速度。 绝不要在仅一次快乐路径运行后就宣布“它工作了”。测试边缘情况。追踪令人惊讶的发现。只有当调查是诚实的时,判定才可信。
避免(除非 Spike 特别需要):复杂的包管理、构建工具/打包器、Docker、环境文件、配置系统。硬编码所有内容 —— 这只是一个 Spike。
构建单个 Spike —— 典型的工具序列:
terminal("mkdir -p spikes/001-websocket-streaming")
write_file("spikes/001-websocket-streaming/README.md", "# 001: websocket-streaming\n\n...")
write_file("spikes/001-websocket-streaming/main.py", "...")
terminal("cd spikes/001-websocket-streaming && python3 main.py")
# 观察输出,迭代。
并行对比 Spike(002a / 002b)—— 委托。 当两种方法可以并行运行,并且两者都需要真正的工程工作(而非 10 行的原型)时,使用 delegate_task 进行分发:
delegate_task(tasks=[
{"goal": "构建 002a-pdf-parse-pdfjs: ...", "toolsets": ["terminal", "file", "web"]},
{"goal": "构建 002b-pdf-parse-camelot: ...", "toolsets": ["terminal", "file", "web"]},
])
每个子代理返回自己的判定;你编写最终的对决报告。
5. 判定
每个 Spike 的 README.md 以以下内容结尾:
## 判定:VALIDATED | PARTIAL | INVALIDATED
### 有效结果
- ...
### 无效结果
- ...
### 意外发现
- ...
### 正式构建建议
- ...
VALIDATED = 核心问题得到肯定回答,有证据支持。 PARTIAL = 在 X、Y、Z 约束下有效 —— 记录这些约束。 INVALIDATED = 不工作,原因如上。这是一个成功的 Spike。
对比 Spike
当两种方法回答同一个问题时(002a / 002b),依次构建它们,然后在最后进行对决比较:
## 对决:pdfjs vs camelot
| 维度 | pdfjs (002a) | camelot (002b) |
|-----------|--------------|----------------|
| 提取质量 | 9/10 结构化 | 7/10 仅表格 |
| 设置复杂度 | npm install, 1 行 | pip + ghostscript |
| 100 页 PDF 性能 | 3 秒 | 18 秒 |
| 处理旋转文本 | 否 | 是 |
**胜出者:** 我们的用例选择 pdfjs。如果后续需要以表格为主的提取,则选择 camelot。
前沿模式(选择下一个 Spike)
如果 Spike 已存在且用户问“接下来应该 Spike 什么?”,浏览现有目录,查找:
- 集成风险 —— 两个已验证通过的 Spike 接触了相同的资源但单独测试
- 数据交接 —— Spike A 的输出被假定与 Spike B 的输入兼容,但从未验证
- 愿景中的空白 —— 假设存在但未经证实的能力
- 替代方案 —— 对 PARTIAL 或 INVALIDATED Spike 的不同角度
提出 2-4 个候选方案,采用 Given/When/Then 格式。让用户选择。
输出
- 在仓库根目录创建
spikes/(如果用户使用 GSD 约定,则创建.planning/spikes/) - 每个 Spike 一个目录:
NNN-descriptive-name/ - 每个 Spike 的
README.md记录问题、方法、结果和判定 - 将代码视为可丢弃的 —— 一个需要 2 天“清理干净以供生产”的 Spike 是一个失败的 Spike
归属
改编自 GSD (Get Shit Done) 项目的 /gsd-spike 工作流 —— MIT © 2025 Lex Christopherson (gsd-build/get-shit-done)。完整的 GSD 系统提供持久的 Spike 状态、MANIFEST 追踪以及与更广泛的规范驱动开发管线的集成;使用 npx get-shit-done-cc --hermes --global 安装。