Spike S5 · OpenSpec 4 阶段流转 + 长时稳定性
状态:✅ 通过(2026-05-18)
验证目标
/opsx:proposeskill 能驱动 explore → propose → apply → archive 4 阶段串联- Agent 真改代码(隔离仓库
/tmp/spike-poc-repo) - 长时 SDK session(>4 min)不掉、不限流
- 4 阶段总成本可控
- Agent 遇到工程问题(typecheck 失败、缺依赖、配置错)能自主修复
环境
- 隔离仓库:
/tmp/spike-poc-repo(从git clone Xeonice/openspec-spike-poc) - skill 链路:
.claude/skills、.claude/commands软链到主仓库 - SDK:
@anthropic-ai/claude-agent-sdk0.3.143(subscription OAuth) - 脚本:
/tmp/openspec-spike-s1/four-stages-spike.mjs
Prompt
为 src/math.ts 添加一个 subtract(a: number, b: number): number 函数,
配套补 src/math.test.ts 的测试,并跑通 npx tsc --noEmit 验证类型正确。
走完整 4 阶段 openspec 流程:explore → propose → apply → archive。SDK 入参 /opsx:propose ${PROMPT}、skills: 'all'、maxTurns: 100、permissionMode: 'bypassPermissions'。
实测结果
| 指标 | 数值 |
|---|---|
| 耗时 | 4.16 min(249 s) |
| Turns | 42 |
| 总成本(USD) | $1.154(subscription 吸收) |
| 输入 token | 47 |
| 输出 token | 12,158 |
| Cache creation | 27,618 |
| Cache read | 1,354,476 |
| Cache hit rate | 98.0 % |
| 工具调用 | 41(Bash 26 / Read 6 / Edit 5 / Write 4) |
| subtype | success · is_error: false |
4 阶段时间线(关键事件)
| 时间 (s) | 阶段 | 事件 |
|---|---|---|
| 0–45 | explore | ls, read math.ts, openspec/config.yaml, package.json, tsconfig.json |
| 45.7 | propose 开始 | openspec new change add-subtract-function |
| 67.7 | propose | 写 proposal.md (1407 B) |
| 103.7 | propose/design | 写 design.md (2974 B)——含 Context/Goals/Decisions/Alternatives |
| 119.4 | propose/spec | 写 specs/math-utils/spec.md —— 3 个 subtract Scenario + 多加 1 个 strict-typecheck Requirement |
| 133.7 | propose/tasks | 写 tasks.md |
| 143.6 | apply | 真改 src/math.ts 加 subtract(a, b): number |
| 148.5 | apply | 真改 src/math.test.ts 加 3 个 test |
| 152.0 | apply | 标记 tasks.md 完成 |
| 153–220 | apply 自主修复 | typecheck 失败 → 排查 → 自修配置 |
| 223.5 | apply | 把环境修复也补进 tasks.md(如实记录) |
| 227–237 | archive | openspec archive add-subtract-function --yes + 验证 |
Agent 自主修复的工程问题
这是 S5 最有价值的发现——agent 不只是按 prompt 改代码,遇到环境问题会自己排查并定位是 pre-existing 项目配置问题,再决定怎么处理。
问题 1:npx tsc --noEmit 失败 · 缺 @types/node
- 第一次跑 typecheck 报错(
Cannot find module 'node:test') - agent 通过
git stash验证 HEAD 也报同样错 → 判定是项目预存在问题 - 决定补
npm install --save-dev @types/node
问题 2:.ts 扩展名 import 不被允许
- 装完 types 后还报
An import path can only end with a '.ts' extension when allowImportingTsExtensions is enabled - agent 改
tsconfig.json加"allowImportingTsExtensions": true(已在 noEmit 模式下,安全)
收尾
npx tsc --noEmitexit 0node --test3/3 passopenspec validate add-subtract-function --strictpass- 主动在
tasks.md加一段说明”环境修复”(如实记录,不藏 diff)
→ 这是 LLM-as-engineer 的真实表现:遇阻 → 探因 → 区分自己引入还是预存在 → 选合适处理方式 → 透明记录。
archive 阶段产物质量
openspec/specs/math-utils/spec.md(archive 合并的 live spec)
- 3 个 subtract Scenario:positive→positive、producing negative、zero identity
- 多加 1 个 Requirement:strict typecheck(超出 prompt,是 agent 自己的设计判断)
- Purpose 字段标 “TBD - update after archive”(OpenSpec 规范行为,不是 bug)
archived change 完整保留
openspec/changes/archive/2026-05-17-add-subtract-function/:
proposal.md·design.md·tasks.md·specs/math-utils/spec.md- 时间戳前缀格式正确
对 POC 的影响
1. 4 阶段流转可单 SDK call 端到端
不需要 multi-turn UI、不需要中间断点。一个 query() 调用走完全程,过程中触发的所有 sub-skill(openspec-propose / openspec-implement / openspec-archive)都在同一 session 内复用 cache。
2. 实际成本远低于预估
- §5 预估”单任务 token 部分 ~$5–$15”
- 实测 $1.15(这是 spike,subscription 吸收实际 0)
- Cache hit rate 98% 是关键——OpenSpec skill prompt 是 stable system prompt,重复 turn 几乎零增量
3. 长时稳定性 ≥ 4 min OK
- 42 turns · 4.16 min 期间 SDK session 无中断、无 401、无限流
- 印证 S1.5 的 OAuth fallback 链路在长任务下稳定
4. Agent 自主修复 = 真实可用
- 不只”按指令改”,能区分”我引入的错”vs”项目预存在错”
- 自主补依赖、修配置、更新 tasks 如实记录
- 这对 task-runner 至关重要:用户 prompt 通常是粗略意图,agent 必须自己解决遇到的工程细节
对 design.md 的补强
→ D1(4 阶段单 SDK call):补充实测——一个 query() 走完全程,98% cache hit、$1.15 实际成本
→ D2(私有化用 BoxLite):S3 + S5 联合验证完成
→ D11(双轨鉴权):S5 在 subscription OAuth 模式下跑 4.16 min 0 中断,验证了开发者面验证场景的稳定性
未覆盖
- ✗ Agent git commit/push —— 脚本未要求,agent 没做(也不该自做:push 是高风险动作) → 真 PR 验证需要单独再跑或手动补
- ✗ 更长时任务(>30 min)的稳定性——4 min 充分但不算”长时”;真长任务(如大重构)还需要更多 spike 数据点
后续可选验证
- 真 PR 闭环:手动或 spike 脚本里加
git checkout -b agent/subtract && git add ... && git commit && git push+gh pr create - 长时跑:换更复杂的 prompt(如 “实现完整 BST” 或 “重构 API”),看 30 min+ session 行为
- 失败注入:故意制造冲突(测试中故意写错),看 agent 修复路径
文件
- 脚本:
/tmp/openspec-spike-s1/four-stages-spike.mjs - 完整 stdout:
/tmp/spike-stdout.log - stats JSON:
/tmp/spike-4stages-stats.json - log 文件:
/tmp/spike-4stages.log - 隔离仓库:
/tmp/spike-poc-repo(archive 后状态保留)