前面的文章解释了 AI Coding、OpenSpec 和 OncallAgent 的系统结构,但真正开始开发时,最容易卡住的不是概念,而是到底怎么迈出第一步。

这篇文章直接做一遍。我们使用仓库根目录的 openspec从0到1项目实战的提示词.md,从 P01 开始,把一个空目录变成可验证的 Monorepo,再说明如何按相同节奏推进到完整 OncallAgent。文中的提示词来自准备稿,终端证据来自当前仓库 Git 历史与 OpenSpec 归档,最后一张图来自当前前端的实际运行页面。

先看最终操作路径

一次完整的 OpenSpec 实战不是“让 AI 写代码”,而是让 Codex 沿着一条可检查的链路工作:

  1. 在空仓库完成 Git、OpenSpec 和 Codex skills 初始化。

  2. 一次只复制一个提案提示词,例如 P01。

  3. Codex 先生成 proposal、design、tasks 和 delta spec。

  4. 继续 apply,让任务清单真正变成代码、配置与测试。

  5. 运行 verify;失败时让 Codex根据原始错误修复并重跑。

  6. 验证通过后同步 main specs,再 archive。

  7. 确认归档与质量门禁都通过,才进入 P02。

[!CAUTION] 本文用 P01 完整展开。P02–P27 的操作方式相同,但每次只推进一个 change。不要一次把 27 段提示词全部交给 Codex,也不要在上一个 change 未验证、未归档时开始下一个。

在 Codex 打开空仓库并做 preflight

先创建空目录,用 Codex 打开这个目录。不要一开始就把最终需求写成长篇自由文本;先让工具链处于可用状态。macOS 或 Linux 终端依次执行:

git --version
python3 --version
uv --version
node --version
npm --version
docker --version
docker compose version
openspec --version

git init
openspec init --tools codex .

这里的目的不是追求“所有工具版本越新越好”,而是尽早暴露缺失项。如果 openspec --version 返回 command not found,就先安装准备稿指定的 OpenSpec CLI 1.5.0,再继续初始化:

npm install -g @fission-ai/openspec@1.5.0
openspec --version
openspec init --tools codex .

初始化完成后,在 Codex 中确认可以调用以下四个 skills:$openspec-propose$openspec-apply-change$openspec-verify-change$openspec-archive-change。它们不是四个互不相关的快捷命令,而是同一个 change 的四个生命周期阶段。

🎬 视频「01. 开发环境初始化确认@小林coding.mov」(飞书视频,无法在博客播放)

第一次给 Codex 的提示词是什么

打开 openspec从0到1项目实战的提示词.md,定位到“P01:锁定技术栈与安全 Monorepo 骨架”,复制整个 text 代码块,不要只复制标题或前两段。下面是实际输入的核心部分:

请完成第 01 个 OpenSpec change:bootstrap-secure-monorepo-foundation。

请依次使用 $openspec-propose、$openspec-apply-change、
$openspec-verify-change、$openspec-archive-change 完成完整生命周期。
不要只生成 proposal/design/spec/tasks 后停止;若验证发现问题,
先修复并重新验证,再同步 delta specs 和归档。
所有 OpenSpec 文档使用简体中文。

这是一个全新项目的第一提案。本提案必须先锁定整个项目的技术栈、
目录骨架、工程边界和质量基线,但不要实现认证、聊天、知识库、
AIOps、MCP 等产品功能。

建立最终目录:
apps/backend、apps/frontend、packages/api-contracts、config、
infra、scripts、openspec、docs。

后端包必须位于 apps/backend/src/super_ai,
只允许 from super_ai...,禁止从 src.super_ai 导入。
模块 import 期间不得连接 SQLite、Milvus、LLM 或 MCP。

只提交无密钥的 config/project.template.json 与
config/user.project.template.json。本机 project.json 和
user.project.json 必须被 Git 忽略。

验收至少运行:openspec validate --all;backend 的
uv run ruff check .、uv run pyright、uv run pytest;
contracts typecheck/test;frontend typecheck/test/build;
git diff --check。所有门禁通过后才归档。

准备稿里的完整 P01 还明确了 Python、FastAPI、Vue、TypeScript、LangChain、Milvus、配置深合并、浏览器 public allowlist、Compose 边界和 sentinel secret 扫描。这里不要擅自删减,因为这些限制会进入 design、AGENTS.md、测试和后续所有 change 的上下文。

Codex 收到提示词后,应该怎样推进

🎬 视频「02. 第一个提案演示@小林coding.mov」(飞书视频,无法在博客播放)

3.1 propose:先把需求变成可审查的工程决策

Codex 首先读取仓库约束和 OpenSpec 配置,创建一个 focused change。此时先看文件,不要只看聊天窗口是否说“完成”。至少应出现:

openspec/changes/bootstrap-secure-monorepo-foundation/
├── proposal.md
├── design.md
├── tasks.md
└── specs/
    └── project-foundation/
        └── spec.md

proposal.md回答为什么要做、改什么;design.md锁定技术选择、边界和取舍;tasks.md把工作拆成可勾选任务;delta spec 则写清新增或修改后的可验证行为。只出现这四类文件,说明 change 已经被建模,但代码还没有实现。

3.2 apply:任务清单必须落到代码、配置与测试

进入 apply 后,Codex 才应该创建 apps/backendapps/frontendpackages/api-contractsconfiginfradocs 等实际目录,并按任务逐项实现。观察过程中重点看三件事:

  • 后端是否真的使用 apps/backend/src/super_ai 的 src layout,而不是临时放在根目录。

  • 配置模板是否无密钥,本机配置是否被 Git 忽略,前端构建是否无法拿到 LLM、CLS、MCP 等 secret。

  • 每个“完成”是否有测试或检查支撑,而不是只把 tasks.md 的复选框改成已完成。

如果 Codex 在生成 artifacts 后停下,可以继续发送:

继续执行当前 change 的 apply。请按 tasks.md 顺序实现代码与测试,
不要创建新的 change,不要跳过质量门禁。完成后继续 verify;
若验证失败,先修复并重跑,不要只汇报失败。

3.3 verify:让错误输出驱动下一轮修复

verify 的目标不是“执行过测试”,而是证明 proposal、design、tasks、delta spec、实现和测试互相一致。P01 至少要跑以下门禁:

# 仓库根目录
openspec validate --all
npm --workspace packages/api-contracts run typecheck
npm --workspace packages/api-contracts run test
npm run frontend:typecheck
npm run frontend:test
npm run frontend:build
git diff --check

# apps/backend
uv run ruff check .
uv run pyright
uv run pytest

如果某一条失败,不要把错误改写成一句“构建失败”再问 AI。保留原始命令、退出码和关键输出,让 Codex在同一 change 中定位。例如:

verify 中 npm run frontend:build 失败。请基于刚才的原始错误定位根因,
只修改当前 P01 范围内的文件;不要删除测试、不要放宽 TypeScript strict
选项、不要把 secret 注入浏览器。修复后重新运行受影响测试和完整 P01
门禁,全部通过后再继续 spec sync 与 archive。

3.4 archive:归档不是移动文件这么简单

验证通过后,Codex 会将 delta spec 同步到 openspec/specs,再把 change 移入 openspec/changes/archive。如果归档阶段询问是否同步规格,选择 Sync now。完成后再次执行 openspec validate --all,确认 main specs 与 archive 都有效。

归档成功以后才复制 P02。否则 P02 可能建立在未同步的 contracts 或错误的目录边界上,后面每个 change 都会放大这笔技术债。

如何从 P01 连续开发到 OncallAgent

P01 不是在“搭架子以后再随便写功能”,而是在建立后续 26 个 change 共同遵守的轨道。准备稿已经按依赖关系排好顺序:

阶段提案范围每阶段可见结果
工程底座P01–P09Monorepo、HTTP/SSE contracts、SQLite、认证与 tenant 隔离、Qwen、Milvus、Vue 壳、durable jobs
知识系统P10–P13文档上传与切分、持久索引、混合召回、RRF、真实 rerank、知识库桌面 UI
Chat AgentP14–P19会话、SSE Agent、Prompt/Skill、记忆、真实 MCP、引用和打字机效果
AIOpsP20–P24真实告警与 CLS、LangGraph 诊断、证据链、案例沉淀、AIOps UI、反馈
交付闭环P25–P27真实 fixtures、readiness、可观测性、运维文档、OpenSpec WIKI

每个阶段都重复同一个小闭环:复制一个提案提示词,观察 artifacts,完成 apply,执行 verify,修复,sync,archive。真正的项目进度不是 Codex 回答了多少字,而是 archive 中多了一个可验证 change,main specs 多了一组当前事实,代码和测试多了一段可运行能力。

下一步:按同样方式执行 P02

确认 P01 已归档且 openspec validate --all 通过后,回到准备稿复制 P02“统一 HTTP、错误、OpenAPI 与 SSE 契约”的完整提示词。P02 完成时,不只是多了几种 TypeScript 类型,而应该能在共享 contracts、FastAPI envelope、request-id、SSE parser 和前后端合同测试中看到同一套可验证结构。

之后严格按 P03、P04……推进。你不需要重新发明提示词,也不需要每次临场决定技术方案;准备稿已经把历史上被推翻的路线裁剪掉,把修复、重构和 UI polish 吸收到对应功能的最终态提案中。实战的重点,是在 Codex 中执行每个 change 的完整生命周期,并用代码、测试、归档和运行。

🎬 视频「03. 第二个提案演示@小林coding.mov」(飞书视频,无法在博客播放)

三个最容易踩的坑

只让 Codex 生成 artifacts。 proposal、design、tasks 和 spec 不是交付物的全部。看到 artifacts 后就开始下一个需求,会留下大量“规格已写、代码未做”的幽灵 change。

一次粘贴多个提案。 P01–P27 存在明确依赖。并发堆叠会让 contracts、migration、前后端 DTO 和 main specs 同时漂移,最后很难判断失败属于哪个 change。

为了通过测试削弱门禁。 删除测试、关闭 strict、把外部依赖改成运行时 mock、把 secret 放进环境变量或浏览器 bundle,都会让“绿色”失去意义。正确做法是保留约束,修复实现。