打造可稳定持续的 Vibecoding:从 PRD 到可交付代码的结构化工法
作者:AI + 人工协作 | 日期:2026-07-13 | 版本:v1.0
摘要:本文提出一套将 AI 编码从"随机试探"升级为"可预期交付"的工程方法论。 核心思路是将传统软件工程中的需求→设计→任务→编码→验证流水线,适配到人机协作场景, 在每个阶段植入可验证的门禁和自愈循环,让 vibecoding 从一次性的 prompt 变成可持续运转的开发引擎。
1. 问题:为什么大部分 Vibecoding 不可持续
AI 写代码很快,但"AI 写完的代码能稳定跑在生产环境"是另一回事。常见的失败模式:
- 需求漂移:AI 在第 3 轮对话时已经忘了第 1 轮的需求细节,开始自己"脑补"
- 架构腐蚀:AI 为了快速实现功能,直接在 API 层写 SQL、跳过 Service 层、引入循环依赖
- 验证缺失:AI 说"改好了",但 3 天后发现破坏了另一个模块的分层约束
- 上下文断裂:token 窗口耗尽后,下一个 AI 实例从零开始,重复劳动
本质矛盾:AI 的强项是"快速生成",弱项是"持续保持一致性的约束"。而软件工程的本质恰恰是"在约束下持续演进"。
本文的核心命题是:如何用工程手段把 AI 的快速生成能力关进约束的笼子,让它每一次输出都可验证、可修复、可接力。
2. 方法论全景:三阶段门禁流水线
2.1 贯穿全文的案例:data_archiving 数据归档平台
本文以 data_archiving 项目为贯穿案例。该项目是一个客户服务数据归档与智能分类平台, 技术栈为 Python 3.12 + FastAPI + PostgreSQL + Redis,前端 React + Vite + TypeScript。
核心业务流程:
- 从企微会话存档拉取客户服务聊天记录,定时任务批量同步
- 多媒体内容自动提取:音频 ASR 转写、文档解析、压缩包递归解压
- LLM 智能分块分类,将对话归类到预设业务标签体系
- 人工审核编辑后归档,支持全文检索与批量导出
项目从零开始严格遵循 AGENTS.md 分层架构,plan/ 和 task/ 目录即为本文方法论的核心产物。
scss
PRD.md ──→ [Plan 阶段] ──→ [Task 阶段] ──→ [Vibecoding 阶段] ──→ 可交付代码
│ ▲ │ ▲ │ ▲
▼ │ ▼ │ ▼ │
人工审核 人工审核 CI 自愈循环
(门禁1) (门禁2) (门禁3)
每个阶段的输出是下一阶段的唯一输入,且必须通过门禁才能流转。这不是"建议",而是通过文件状态机强制执行的硬约束。
工具定位
| 阶段 | 主力工具 | 角色 |
|---|---|---|
| Plan 生成 | Codex Plan 模式 | 从 PRD + 代码库逆向生成四份文档 |
| Plan 审核 | 人工 | 校验架构决策、API 契约、DB 设计 |
| Task 拆分 | Codex 或 Claude Code | 按依赖拓扑拆成可并行任务 |
| Task 审核 | 人工 | 校验粒度、依赖关系、验收标准 |
| Vibecoding | Codex 或 Claude Code | 逐个 task 写代码 + CI 自愈 |
| CI 验证 | verify.sh (自动) | 七道关卡,全绿才能标记完成 |
2.2 文件状态机
每个 plan/ 和 task/ 文件头部携带 YAML front matter:
yaml
---
status: draft | in_review | approved | implemented
reviewer: "审核人"
last_update: 2026-07-13
dependencies: ["task_1", "task_2"]
plan_refs: ["plan/api.md#5.1", "plan/db.md#2.3"]
---
状态流转规则:
draft→in_review: 作者提交审核in_review→approved: 人工审核通过approved→implemented: Vibecoding 完成 + CI 全绿
这是一个不可逆的有向图:已 approved 的文档不能随意修改,如需变更必须新建 task 而非回头改 plan。
3. Plan 阶段:把模糊需求变成可执行的设计
3.1 为什么需要四份文档
传统开发中,一个需求讨论会可能产出半页白板笔记。AI 拿着这个去写代码,大概率会写出"看起来对但实际不对"的东西。
Plan 阶段强制产出四份结构化文档,每份回答一个不可跳过的问题:
| 文档 | 回答的问题 | 失败后果(如果跳过) |
|---|---|---|
design.md |
系统怎么做?模块边界在哪? | AI 在 API 层写业务逻辑,破坏分层 |
db.md |
数据怎么存?字段类型和约束是什么? | 同名字段在不同表类型不一致,JOIN 报错 |
api.md |
前后端契约是什么?入参出参长什么样? | 前端调不通,反复返工 |
test.md |
怎么证明功能是对的? | 改了 A 模块,B 模块悄悄坏了 |
3.2 案例:data_archiving 项目的 Plan 产出
以 data_archiving 项目为例,四份文档的产出内容:
design.md 节选------核心处理链路:
scss
企微会话存档 (数据源)
│
▼
定时任务拉取 → 原始消息存储 (customer_order 表)
│
▼
消息组包 → MQ → 消费者解析落库
│
├── 音频: ASR 转写 → 文本内容提取
├── 文档: 文档解析 → 文本内容提取
└── 压缩包: 解压 → 递归处理内层文件
│
▼
LLM 智能分块分类 → customer_order_chat_block (分类结果)
│
▼
人工审核/编辑 → 确认归档
db.md 节选------状态字段约定:
所有状态字段使用大写字符串枚举,统一语义:
WAIT: 待处理DOING: 处理中(超时由补偿任务自动回收)DONE/SUCCESS: 完成FAIL: 失败SKIP: 跳过/无需处理
api.md 节选------待开发接口契约:
css
POST /api/v1/customer-order-chat-block/update_content_block_info
请求: {order_chat_block_id: str, update_content: str}
返回: {code: 200, message: "success", data: bool}
校验: order_chat_block_id 非空, update_content 非空
test.md 节选------验收用例:
markdown
### update_content_block_info
- [ ] 正常修改内容,返回 true
- [ ] order_chat_block_id 为空时返回失败
- [ ] update_content 为空时返回失败
- [ ] 不存在的 block 返回 false
3.3 如何从 PRD 生成 Plan
三个来源组合:
- PRD 直接映射:功能需求 → design 流程 + api 接口
- 现有代码库参考:已有 models/ 目录 → db.md 表结构;已有 main.py → api.md 路由清单
- 工程经验补充:并发一致性、状态补偿、幂等设计等非功能需求 → 补充到 design.md
4. Task 阶段:从设计到可执行工作单元
4.1 拆分原则
| 原则 | 说明 | 反例 |
|---|---|---|
| 单任务 2-4h | AI 一次对话可完成的工作量 | 把整个模块拆成一个 task,token 耗尽做不完 |
| 依赖显式 | 每个 task 标明 dependencies |
task_5 调用了 task_3 的接口但没标依赖 |
| 验收可测 | 每个 task 有明确的 [ ] 验收标准 |
"实现用户管理功能"没有具体验收条件 |
| 关联可追溯 | 每个 task 标明 plan_refs |
AI 不知道这个 task 对应 plan 里哪个章节 |
4.2 data_archiving 项目的 Task 拆分案例
12 个 task 的依赖拓扑:
scss
task_1 (标签+文件夹) ──→ task_2 (预览下载)
│ │
└──→ task_3 (分类树) ──→ task_4 (内容块CRUD) ──→ task_5 (共享空间)
task_6 (媒体上传) ──→ task_7 (补偿任务)
│
└──→ task_8 (状态增强)
task_9 (权限开关) ──→ task_11 (服务单同步)
│
task_6 ──┘
task_10 (智能分类) ──→ (独立,依赖 task_3 的分类树)
task_12 (批量下载) ──→ (独立,依赖 task_2 的文件集成)
每个 task 文件的典型结构(以 task_4.md 为例):
markdown
---
status: draft
dependencies: ["task_3"]
plan_refs: ["plan/api.md#5.5", "plan/api.md#5.6", "plan/api.md#5.7", "plan/api.md#5.8"]
---
# Task 4: 内容块 CRUD 操作
## 任务概述
实现内容块的编辑、移除、详情查询、确认四个操作接口。
## 涉及模块
- `app/api/coumter/customer_order_chat_block.py` - 四个接口入口
- `app/services/customer/` - Service 层
- `app/storage/postgres/customer_order_chat_block_repository.py` - Repository 层
## 实现要点
### 4.1 update_content_block_info
- 参数: order_chat_block_id, update_content (均必填)
- 更新 customer_order_chat_block.update_content 和 updated_at
### 4.2 remove_classification_info
- 设置 is_transfer=1 (软移除,不物理删除)
## 验收标准
- [ ] 编辑后 updated_at 和 update_content 正确更新
- [ ] 移除后 is_transfer=1,前端 DOM 移除
- [ ] ruff + mypy + import-linter + check_layers + pytest 全部通过
5. Vibecoding 阶段:约束驱动的 AI 编码引擎
这是整个方法论的核心------如何让 AI 在写代码时既保持速度,又不破坏架构约束。
5.1 Harness 架构思想
"Harness"(挽具)的隐喻:给 AI 一个可以自由奔跑的空间,但这个空间有明确的边界。AI 在边界内可以任意发挥,一旦触及边界就会被拦住。
在 data_archiving 项目中,Harness 由三层约束构成:
scss
┌─────────────────────────────────────────────┐
│ 第一层:文件级地图 (AGENTS.md) │
│ - 分层职责 (api/services/storage) │
│ - 命名后缀 (_service / _repository / _model) │
│ - 日志规范 (loguru,禁止 print) │
│ - 提交规范 (Conventional Commits) │
├─────────────────────────────────────────────┤
│ 第二层:静态约束 (pyproject.toml) │
│ - ruff: lint + format (E/F/I/UP/B/SIM 规则)│
│ - mypy: 类型检查 │
│ - import-linter: 分层依赖方向 (layers 契约) │
├─────────────────────────────────────────────┤
│ 第三层:自定义校验 (check_layers.py) │
│ - AST 解析拦截 api → repository 直接访问 │
│ - 比 import-linter 更细粒度 │
│ - 白名单机制 + 文件/目录豁免 │
└─────────────────────────────────────────────┘
5.2 三层约束如何协同工作
第一层------AGENTS.md 作为地图:
AGENTS.md 不是一纸空文,而是 AI 在每次改代码前必须读取的"项目宪法"。它明确告诉 AI:
"你看到
app/api/下的文件,只能做三件事:参数校验、调 service、组装响应。如果你直接 import 了 repository,check_layers.py 会在 CI 阶段把你拦下来。"
真实的 AGENTS.md 约束条目:
markdown
## 分层职责
- `api/`: 参数校验 + 调 service + 组装响应。不写业务。
- `services/`: 业务编排 + 事务 + 调 repository。
- `storage/`: CRUD + 连接管理,不写业务。
- 命名后缀: `*_repository.py` / `*_service.py` / `*_schema.py` / `*_model.py` / `*_consumer.py` / `*_task.py`。
## 自验证闭环(改完代码必须跑)
bash scripts/verify.sh
第二层------import-linter 的分层契约:
在 pyproject.toml 中,用 layers contract 定义依赖方向:
toml
[[tool.importlinter.contracts]]
name = "分层依赖方向 api→services→storage(禁止反向)"
type = "layers"
layers = ["app.api", "app.services", "app.storage"]
这条配置的意思是:app.api 只能依赖 app.services 和 app.storage(基础设施),app.services 只能依赖 app.storage,app.storage 不能依赖任何人。任何反向 import 都会被 lint-imports 命令检测出来。
但这里有一个漏洞:api 依赖 storage 是被 layers contract 允许的(因为 storage 是基础设施层,比如 api 需要 import storage.postgres.session 获取 DB 会话)。而业务规则要求"api 不得直接 import repository"。这就引出了第三层。
第三层------check_layers.py 的 AST 级细粒度拦截:
python
# 核心逻辑:用 AST 解析每个 api/*.py 文件,检查是否 import 了 *_repository
def _is_repo_import(module: str) -> bool:
if not module.startswith("app.storage"):
return False
leaf = module.rsplit(".", 1)[-1]
return leaf.endswith("_repository") # 精确拦截
当 AI 在 app/api/coumter/customer_order_chat_block.py 中写了:
python
from app.storage.postgres.customer_order_chat_block_repository import (
CustomerOrderChatBlockRepository,
)
CI 会输出:
arduino
[违规] app/api/coumter/customer_order_chat_block.py:10
原因: 接口层直接 import 了 repository
规则: api → services → storage,接口层不得直接访问 repository
修复: 删除该 import,改为通过对应 Service 调用
5.3 正确姿势:三层协同的代码模式
AI 被训练/约束后写出来的正确代码(来自 data_archiving 项目):
API 层 (app/api/coumter/customer_order_chat_block.py):
python
from fastapi import APIRouter
import app.storage.postgres.session as session_mod
from app.schemas.request.customer_order_chat_block_schema import (
UpdateContentBlockInfoRequest,
)
from app.services.customer.customer_order_chat_block_service import (
CustomerOrderChatBlockService, # ✅ 只 import service,不 import repository
)
router = APIRouter()
@router.post("/update_content_block_info", summary="修改内容块内容")
def update_content_block_info(req: UpdateContentBlockInfoRequest):
with session_mod.get_db() as db: # ✅ 获取 DB 会话(基础设施,允许)
service = CustomerOrderChatBlockService(db) # ✅ 注入到 service
ok = service.update_content_block_info(
order_chat_block_id=req.order_chat_block_id,
update_content=req.update_content,
)
return {"code": 200, "message": "success", "data": ok} # ✅ 只组装响应
Service 层 (app/services/customer/customer_order_chat_block_service.py):
python
from sqlalchemy.orm import Session
from app.storage.postgres.customer_order_chat_block_repository import (
CustomerOrderChatBlockRepository, # ✅ service 层允许 import repository
)
class CustomerOrderChatBlockService:
def __init__(self, db: Session):
self._repo = CustomerOrderChatBlockRepository(db) # ✅ 封装 repository
def update_content_block_info(self, *, order_chat_block_id: str, update_content: str) -> bool:
"""业务逻辑 + 事务编排"""
block_id = order_chat_block_id.strip()
if not block_id:
return False
return self._repo.update_content_by_order_chat_block_id(block_id, update_content)
Repository 层:纯粹的 CRUD,不包含任何业务判断。
5.4 DB 会话的事务保证
session.py 的 get_db() 上下文管理器强制了事务语义:
python
@contextmanager
def get_db() -> Generator[Session, None, None]:
db = SessionLocal()
try:
yield db
db.commit() # 正常 → 提交
except Exception:
db.rollback() # 异常 → 回滚
raise
finally:
db.expunge_all() # 分离 ORM 对象
db.close() # 归还连接池
这意味着 AI 不需要手动写 try/except/commit/rollback------只要把业务逻辑放在 with get_db() as db: 块里,事务一致性由框架保证。
6. CI 自愈循环:失败→修复→重试→通过
6.1 verify.sh 的七道关卡
bash
bash scripts/verify.sh
一次运行会顺序执行:
| 序号 | 检查项 | 工具 | 失败时输出 |
|---|---|---|---|
| 1 | Lint | ruff check |
违规代码 + 修复命令 ruff check --fix . |
| 2 | 格式 | ruff format --check |
格式差异 + 修复命令 ruff format . |
| 3 | 类型 | mypy app |
类型错误 + 指引"补类型注解,勿用 # type: ignore" |
| 4 | 分层方向 | lint-imports |
反向依赖 + 指引"删除反向 import" |
| 5 | 细粒度分层 | check_layers.py |
api→repository 越权 + 具体修复模板 |
| 6 | 测试+覆盖率 | pytest --cov |
失败用例 + 覆盖率不足 |
| 7 | 新增代码覆盖 | diff-cover |
新增代码测试覆盖率 < 80% |
6.2 自愈循环机制
scss
Task 开始
│
▼
AI 生成代码
│
▼
bash scripts/verify.sh
│
├── [全绿] ──→ Task 完成 ✅
│
└── [红色] ──→ AI 按报错信息自修复
│
├── 第 1 轮:修复 → verify.sh
├── 第 2 轮:修复 → verify.sh
├── 第 3 轮:修复 → verify.sh
│
└── 3 轮仍未过 → 标记卡点
写入 progress.md
停止,等待人工介入
关键设计:每轮修复的输入是 verify.sh 的具体报错输出,而不是 AI 的猜测。这避免了"我觉得改好了"的主观判断。
6.3 报错→修复映射表
AGENTS.md 中维护了一张映射表,AI 可以机械套用:
| 报错 | 含义 | 修复动作 |
|---|---|---|
check_layers: 接口层直接 import 了 repository |
api 越层访问 storage | 删除该 import,改为经 Service 调用 |
import-linter: layers contract broken |
出现反向依赖 | 把反向 import 删掉,或把共用逻辑下沉 |
ruff: E/F/B... |
语法/导入/陷阱问题 | 按 ruff 提示修,ruff check --fix . 可自动修一部分 |
mypy: error: ... |
类型不符 | 补类型注解或修正调用 |
pytest --cov-fail-under |
覆盖率不足 | 为新增 service/repository 补单元测试 |
这种可操作的报错信息是自愈循环能跑通的前提。如果报错是 "Something went wrong",AI 无法自愈。
7. 人机共审核模式
7.1 为什么不是全自动
三个原因:
- 需求理解偏差:AI 可能实现了"技术上正确"的东西,但不是用户想要的。Plan 阶段的审核可以早期纠偏。
- 架构决策:数据库表设计、API 契约的选择往往有 tradeoff,需要人的领域知识。
- 任务拆分粒度:太粗做不完,太细管理成本高------需要人对业务复杂度的判断。
7.2 门禁设计
scss
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Plan 审核 │ │ Task 审核 │ │ CI 门禁 │
│ (人工) │ │ (人工) │ │ (自动) │
└─────┬─────┘ └─────┬─────┘ └─────┬─────┘
│ │ │
审核通过才 审核通过才 全绿才
能进入 Task 能进入 Vibecoding 标记完成
人工审核的对象不是代码,而是设计文档。这比 review 代码高效得多------在文档阶段发现一个架构问题,比在代码阶段发现再返工的成本低 10 倍以上。
审核清单(来自 WORKFLOW.md):
markdown
### Plan 审核清单
- [ ] design.md 是否覆盖全部 PRD 需求?
- [ ] db.md 表结构是否合理,是否有遗漏字段?
- [ ] api.md 入参/出参/异常码是否完整?
- [ ] test.md 是否覆盖核心链路与边界?
- [ ] 所有文档之间的数据一致性是否可验证?
### Task 审核清单
- [ ] 任务拆分粒度是否合理(单任务 2-4h)?
- [ ] 依赖关系是否正确(无循环依赖)?
- [ ] 每个任务的验收标准是否可验证?
- [ ] 是否覆盖了 plan/ 中全部接口与功能?
8. 关键设计决策与权衡
8.1 白名单 vs 零容忍
check_layers.py 设计了白名单机制:
python
EXEMPT_DIRS = ("scheduler", "mq", "test")
定时任务和 MQ Consumer 虽然放在 app/api/ 目录下,但它们的角色实际上是"数据处理入口",类似于 Service 层。强制它们走 Service → Repository 会增加不必要的间接层。白名单允许它们直接访问 repository,同时保持纯 HTTP 路由的严格约束。
这是一个务实的权衡------在关键路径上零容忍,在类 Service 入口上允许豁免。
8.2 覆盖率阈值渐进提升
toml
[tool.coverage.report]
fail_under = 10 # 从 10% 起步,逐步提升
从 0% 覆盖率直接要求 80% 是不现实的。设计思路是"让 CI 先转起来,再逐步收紧":
- 第 1 阶段:fail_under=10,确保 CI 能跑通
- 第 2 阶段:补 service 层单元测试 → fail_under=30
- 第 3 阶段:补 repository 层单元测试 → fail_under=50
- 第 4 阶段:diff-cover 拦截新增代码 → 新增代码必须 ≥80%
9. 总结:Vibecoding 可持续的三根支柱
scss
可持续 Vibecoding
/ | \
/ | \
结构化设计 约束系统 自愈循环
(Plan/Task) (Harness) (CI + 报错映射)
- 结构化设计:PRD → Plan → Task 的层层细化,让 AI 始终知道自己"在哪里、做什么、怎么验证"
- 约束系统:AGENTS.md / CLAUDE.md(地图)+ import-linter(方向)+ check_layers.py(细粒度)+ ruff/mypy(质量),四层防线把 AI 的随机性关进笼子
- 自愈循环:verify.sh 失败 → 读报错 → 按映射表修复 → 重跑 → 全绿,最多 3 轮自动修复
这三根支柱缺一不可。没有结构化设计,AI 会在需求迷雾中迷路;没有约束系统,AI 的代码会像藤蔓一样爬满反模式和循环依赖;没有自愈循环,每一次 CI 失败都需要人工介入,vibecoding 的效率优势就消失了。
9.1 适用场景与限制
适用:
- 中大型项目(10+ 模块,5+ 开发者,持续迭代)
- 已有一定代码基础需要持续演进的项目
- 团队有 AI 编码工具(Codex / Cursor / Copilot)但缺乏工程纪律
不适用:
- 一次性脚本/POC(投入产出比不划算)
- 纯前端展示页面(不需要分层架构)
- 团队完全没有 code review 文化(人工门禁形同虚设)
9.2 实施路线图
| 阶段 | 工作 | 时间 |
|---|---|---|
| Day 0 | 创建 AGENTS.md / CLAUDE.md + 配置 pyproject.toml (ruff/mypy/import-linter) | 2h |
| Day 1 | 编写 check_layers.py + verify.sh | 2h |
| Day 2 | 用 Codex Plan 模式从 PRD/现有代码生成 plan/ 四份文档 | 30min (AI 自动) + 2h (人工审核) |
| Day 3 | Plan 审核 + 修订 | 2h (人工) |
| Day 4 | 用 Codex 或 Claude Code 从 plan/ 拆分 task/ | 30min (AI 自动) + 1h (人工审核) |
| Day 5 | Task 审核 | 1h (人工) |
| Day 6+ | Vibecoding:Codex / Claude Code 逐个 task 开发 + CI 自愈 | 每 task 2-4h |
总计约 3 天搭建基础设施 + 每个迭代的 Plan/Task 半天审核 + Vibecoding 持续运转。
附录 A:工具清单
| 工具 | 用途 | 配置位置 |
|---|---|---|
| ruff | Lint + 格式化 | pyproject.toml tool.ruff |
| mypy | 类型检查 | pyproject.toml tool.mypy |
| import-linter | 分层依赖方向 | pyproject.toml tool.importlinter |
| check_layers.py | api→repository 细粒度拦截 | scripts/check_layers.py |
| pytest + pytest-cov | 单元测试 + 覆盖率 | pyproject.toml tool.pytest.ini_options |
| diff-cover | 新增代码覆盖率 | scripts/verify.sh |
| pre-commit | 本地提交前拦截 | .pre-commit-config.yaml |
| verify.sh | 一键全量验证 | scripts/verify.sh |
附录 B:项目文件结构总览
ruby
data_archiving/
├── AGENTS.md # AI Agent 项目地图与操作规程
├── CLAUDE.md # Claude Code 项目地图(可软链接到 AGENTS.md)
├── PRD.md # 产品需求文档
├── WORKFLOW.md # 三阶段工作流说明
├── docs/
│ ├── architecture.md # 系统架构文档
│ ├── module-boundaries.md # 模块边界与依赖规则
│ ├── coding-standards.md # 编码规范
│ ├── api-spec.md # API 规范
│ ├── testing.md # 测试规范
│ ├── error-codes.md # 错误码
│ └── vibecoding-methodology.md # 本文档
├── plan/
│ ├── design.md # 方案设计
│ ├── db.md # DB 设计
│ ├── api.md # API 接口文档
│ └── test.md # 测试案例
├── task/
│ ├── task_1.md ~ task_12.md # 子任务(按依赖拓扑拆分)
├── scripts/
│ ├── verify.sh # 一键全量验证
│ ├── check_layers.py # AST 分层检查
│ └── cleanup.sh # 清理脚本
├── data_archiving_python/ # 后端代码
│ ├── app/
│ │ ├── api/ # 接口层(路由/MQ/定时任务入口)
│ │ ├── services/ # 服务层(业务编排+事务)
│ │ ├── storage/ # 存储层(CRUD+连接管理)
│ │ ├── models/ # ORM 模型
│ │ ├── schemas/ # Pydantic 模型
│ │ ├── config/ # 配置
│ │ └── main.py # 入口
│ ├── tests/ # 测试
│ ├── scripts/ # 后端脚本
│ ├── pyproject.toml # 后端工程配置(ruff/mypy/import-linter)
│ └── .pre-commit-config.yaml # pre-commit hooks
└── data_archiving_web/ # 前端代码
├── src/
│ ├── pages/ # 页面组件
│ ├── components/ # 通用组件
│ ├── api/ # API 调用层
│ ├── hooks/ # 自定义 Hooks
│ ├── types/ # TypeScript 类型
│ └── utils/ # 工具函数
├── package.json
├── tsconfig.json
└── vite.config.ts
10. 工具集成:Codex 与 Claude Code 的 Vibecoding 实践
本章详细说明如何将 OpenAI Codex 和 Anthropic Claude Code 接入三阶段工作流, 包括各自的配置方式、擅长环节、以及它们如何取代传统开发中的具体步骤。
10.1 两个工具的定位
| 维度 | Codex (OpenAI) | Claude Code (Anthropic) |
|---|---|---|
| 核心能力 | Plan 模式生成结构化文档 + 多线程并行执行 | 长上下文深度理解 + 子代理并行 |
| 最适合的阶段 | Plan 生成、多 Task 并行 Vibecoding | 复杂 Task 的深度推理、大文件重构 |
| 项目地图 | AGENTS.md (自动读取) |
CLAUDE.md (需手动放置) |
| 任务追踪 | Goal 系统 (token/时间预算) | TodoWrite (手动标记) |
| 终端集成 | exec_command + sandbox |
原生终端访问 |
| 前端验证 | Browser/Playwright 技能 | 终端 Playwright CLI |
| Plan 模式 | ✅ 内置,自动拆解 PRD → Plan | ❌ 需手动引导 |
| 上下文窗口 | 中等 (128K-200K tokens) | 大 (200K tokens) |
| 并行能力 | Thread 管理 + 多 Agent | Sub-agent 子任务 |
10.2 Codex 配置:从零到 Vibecoding
10.2.1 项目级配置 (AGENTS.md)
Codex 在每个对话开始时自动读取项目根目录的 AGENTS.md。该文件是 Codex 的"唯一真相来源", 控制它的所有行为。关键配置段:
markdown
# AGENTS.md
> 本文件是给 AI Agent(opencode / Claude 等)的项目地图与操作规程。
> Agent 在本项目做任何改动前必须读完本文件,并按"自验证闭环"执行。
## 硬性规则(违反即 CI 失败,不要试图绕过)
1. 依赖方向 `api → services → storage`(单向)
2. Python 3.12,不得升级
3. 日志统一 loguru,禁止 print / 自行 logging.getLogger
4. 写操作必须事务一致
5. 定时任务用 Redis 分布式锁
6. models/ 禁止擅改
## 自验证闭环(改完代码必须跑,失败按报错自修复后再提交)
bash scripts/verify.sh
## 常见报错 → 修复动作(Agent 自动套用)
| 报错 | 含义 | 修复动作 |
| --- | --- | --- |
| `check_layers: 接口层直接 import 了 repository` | api 越层 | 删除该 import,改为经 Service 调用 |
| `import-linter: layers contract broken` | 反向依赖 | 把反向 import 删掉 |
| `mypy: error: ...` | 类型不符 | 补类型注解,不要用 # type: ignore 掩盖 |
Codex 读取 AGENTS.md 后的行为变化:
- 写代码前先 grep 定位相关文件,不盲改
- API 层自动只写参数校验 + 调 Service + 组装响应
- 改完代码自动跑
verify.sh - CI 失败时按报错→修复映射表自修,不猜测
10.2.2 Plan 模式:自动生成 Plan 与 Task
Codex 的 Plan 模式是这个工作流中最关键的一步。启用 Plan 模式后,Codex 不会直接写代码, 而是先问清楚需求、分析代码库、然后生成结构化的 Plan 文档。
触发方式:在 Codex 对话中说"用 Plan 模式"或系统切换到 Plan 模式。
Plan 模式下的行为:
- 需求确认阶段 :Codex 使用
request_user_input工具向用户确认模糊点 - 代码库分析阶段 :并行读取
models/、services/、api/、main.py等关键文件 - 文档生成阶段:基于 PRD + 现有代码生成 plan/ 四份文档
- Task 拆分阶段:按依赖拓扑拆成 task/ 子任务
Plan 模式在实际项目中的效果(以 data_archiving 为例):
| 步骤 | 传统方式 | Codex Plan 模式 |
|---|---|---|
| 分析 PRD 需求文档 | 人工通读 2h | Codex 读取 30s,提炼核心需求 |
| 提取现有 API 路由清单 | 人工翻 main.py 梳理 | Codex 自动解析 include_router 调用 |
| 归纳 DB 表结构 | 人工翻 20+ model 文件 | Codex 并行读取所有 model,自动归纳字段/索引 |
| 生成 plan/ 四份文档 | 人工写 1-2 天 | Codex 10 分钟生成 |
| 拆分成子任务 | 人工拆 2-4h | Codex 5 分钟按依赖拓扑拆分 |
Plan 模式取代的传统步骤:
- ❌ 技术方案评审文档的人工撰写
- ❌ 数据库设计文档的人工维护
- ❌ API 文档的人工同步更新
- ❌ WBS 任务拆分会议
10.2.3 Vibecoding 模式:逐个 Task 执行
当 plan/ 和 task/ 审核通过后,Codex 进入 Vibecoding 模式(默认模式)。
关键设置:
-
Goal 系统:为每个 Task 创建 Goal,设定 token 预算
ini/goal 实现 Task 4: 内容块 CRUD 操作 token_budget=50000超过预算时 Codex 自动写
progress.md保存进度,下次对话可继续。 -
Sandbox 权限:verify.sh 需要 conda 环境和系统级工具,需要预先批准
bash# 示例:批准 verify.sh 脚本运行权限 prefix_rule: ["bash", "scripts/verify.sh"] -
Thread 并行:独立 Task 可以用多个 Thread 并行执行
lessCodex 对话 A: 执行 task_6 (媒体上传) Codex 对话 B: 执行 task_9 (权限开关)两个 Thread 互不阻塞,完成后汇总。
Codex 在 Vibecoding 中自动做的事:
- 每个 task 开始前先读 task_N.md 明确验收标准
- 写代码时遵循 AGENTS.md 的分层约束
- 改完代码自动跑
bash scripts/verify.sh - CI 红色时按报错→修复映射表自修,最多 3 轮
- 3 轮未过 → 写
progress.md标记卡点,停止
10.2.4 推荐的 Codex Skills
为 Vibecoding 工作流启用的技能:
| Skill | 用途 | 在哪个阶段用 |
|---|---|---|
playwright |
自动化浏览器测试、截图验证 | Task 完成后验证前端功能 |
browser:control-in-app-browser |
在 Codex 内嵌浏览器中预览前端 | 前端 Task 调试 |
skill-creator |
把反复使用的约定创建为 Skill | 团队标准化 |
10.3 Claude Code 配置:从零到 Vibecoding
10.3.1 项目级配置 (CLAUDE.md)
Claude Code 通过 CLAUDE.md 文件获取项目上下文。放在项目根目录或 ~/.claude/ 下。
推荐的 CLAUDE.md 模板:
markdown
# CLAUDE.md
## 项目概述
data_archiving 是一个客户服务数据归档与智能分类平台。
技术栈: Python 3.12 + FastAPI + PostgreSQL + Redis + RocketMQ。
前端: React 18 + Vite 5 + TypeScript 5。
## 硬性规则
1. 依赖方向: api → services → storage (单向)
2. Python 3.12,不得升级
3. 日志统一 loguru,禁止 print
4. models/ 禁止擅改
5. API 层不能直接 import repository
## 验证命令
改完代码后运行:
bash scripts/verify.sh
## 分层职责
- api/: 参数校验 + 调 service + 组装响应
- services/: 业务编排 + 事务 + 调 repository
- storage/: CRUD + 连接管理
## 命名约定
*_repository.py / *_service.py / *_schema.py / *_model.py / *_consumer.py / *_task.py
Claude Code 读取 CLAUDE.md 后的行为变化:
/init命令自动加载 CLAUDE.md 作为系统提示- 写代码时自动遵循分层架构
- 支持 TodoWrite 跟踪任务进度
10.3.2 Claude Code 的工作流集成
Claude Code 没有 Plan 模式,因此在 Plan 阶段需要手动引导:
bash
# Claude Code 中
请读取 PRD.md,分析现有代码库结构,
按 AGENTS.md 规范生成 plan/design.md, plan/db.md, plan/api.md, plan/test.md 四份文档,
并拆分为 task/ 子任务。
Claude Code 的独特优势:
-
超大上下文窗口 (200K tokens):可以一次性读入整个代码库的核心文件, 在复杂重构或跨模块改动时不需要频繁分段读取。
-
子代理 (Sub-agent):对于独立 Task,启动子代理并行执行:
bash# 主对话中 请为 task_6、task_7、task_9 分别启动子代理并行开发 -
原生终端访问 :直接运行
bash scripts/verify.sh,无需 sandbox 配置。
10.3.3 Claude Code 的 Task 执行模式
bash
# 典型对话流程
用户: 执行 task_4,见 task/task_4.md
Claude:
1. 读取 task_4.md → 理解 4 个接口的验收标准
2. 读取 plan/api.md#5.5-5.8 → 理解接口契约
3. 读取现有代码 → order.py, service, repository
4. 实现代码 → 按分层架构写入
5. 运行 bash scripts/verify.sh → 发现 check_layers 报错
6. 读报错 → 找到 api 层直接 import 了 repository
7. 自修复 → 改为 import service,重新跑 verify.sh
8. 全绿 → Task 完成
10.4 两者协同的最佳实践
10.4.1 推荐分工
scss
Codex Claude Code
│ │
Plan 生成 ────────────●──────────────────────────│
(Plan 模式自动拆解) │ │
│ │
复杂架构设计 ─────────│──────────────────────────●
(大上下文深度推理) │ │
│ │
Task 快速实现 ────────●──────────────────────────│
(单 Task 2-4h) │ │
│ │
大文件重构 ───────────│──────────────────────────●
(200K 上下文优势) │ │
│ │
CI 自愈循环 ──────────●─────────────●────────────│
(两者都擅长) │ │
│ │
前端可视化验证 ───────●──────────────────────────│
(Browser/Playwright │ │
技能开箱即用) │ │
│ │
并行多 Task ──────────●─────────────●────────────│
(Thread vs Sub-agent)│ │
10.4.2 实际操作流程
第 1 步:用 Codex Plan 模式生成 Plan
arduino
在 Codex 中(Plan 模式):
"读取 PRD.md 和现有代码库,按 AGENTS.md 规范生成 plan/ 四份文档和 task/ 子任务"
Codex Plan 模式自动完成需求确认 → 代码分析 → 文档生成 → 任务拆分全流程。
第 2 步:人工审核 plan/ 和 task/
审核通过后把 front matter 改为 status: approved。
第 3 步:分配 Task 给工具
less
独立 Task (无依赖冲突):
→ Codex Thread A: task_1
→ Codex Thread B: task_6
→ Claude Code 子代理: task_9
三者并行执行
串行 Task (有依赖):
→ Codex: task_1 → task_2 → task_3 → task_4 → task_5 (串行 Thread)
或 Claude Code: 按依赖顺序逐个 TodoWrite
复杂 Task (跨模块重构):
→ Claude Code (大上下文优势): task_10 (智能分类,涉及 LLM 调用链路)
第 4 步:每个 Task 的验收
bash
bash scripts/verify.sh # 全绿才能标记 complete
第 5 步:汇总与归档
所有 Task 的 front matter 改为 status: implemented,提交代码。
10.4.3 配置清单
| 配置项 | Codex | Claude Code |
|---|---|---|
| 项目地图文件 | AGENTS.md (根目录) |
CLAUDE.md (根目录) |
| 分层约束配置 | pyproject.toml + check_layers.py |
pyproject.toml + check_layers.py |
| CI 验证脚本 | scripts/verify.sh |
scripts/verify.sh |
| Pre-commit | .pre-commit-config.yaml |
.pre-commit-config.yaml |
| Plan/Task 目录 | plan/ + task/ |
plan/ + task/ (共享) |
| 进度文件 | progress.md (Codex Goal 系统自动生成) |
progress.md (手动维护) |
| 前端测试 | playwright skill |
playwright-cli 终端命令 |
| 前端预览 | browser:control-in-app-browser skill |
open 命令打开浏览器 |
10.5 具体取代了哪些传统步骤
| 传统步骤 | 被谁取代 | 取代方式 |
|---|---|---|
| 技术方案评审会 | Codex Plan 模式 | 10 分钟生成 plan/ 四份文档 |
| 数据库设计文档编写 | Codex Plan 模式 | 从 models/ 自动逆向生成 db.md |
| API 文档编写与同步 | Codex Plan 模式 | 从 main.py + 代码自动生成 api.md |
| WBS 任务拆分会 | Codex / Claude Code | 按依赖拓扑自动拆 task,2-5 分钟 |
| 代码 Review (分层检查) | import-linter + check_layers.py |
CI 自动拦截,不需要人工逐行检查 |
| 代码 Review (格式/类型) | ruff + mypy |
CI 自动检查 |
| 单元测试编写 | Codex / Claude Code | 根据 plan/test.md 自动生成测试骨架 |
| 回归测试 | verify.sh |
一键全量验证 |
| Bug 修复 (分层类) | Codex / Claude Code + CI 自愈 | 读报错 → 按映射表修 → 重跑,最多 3 轮 |
| 前后端联调 | Codex Browser 技能 | 在 Codex 内嵌浏览器中直接预览前端页面 |
没有被取代的步骤:
- 架构决策:数据库选型、消息队列选型、缓存策略------这些需要人的领域知识和 tradeoff 判断
- PRD 撰写:产品需求的定义需要领域专家,AI 可以辅助提炼但不能替代
- 安全审计:权限模型、数据脱敏、注入防护------需要专业安全人员
10.6 常见问题
Q: AGENTS.md 和 CLAUDE.md 需要分别维护吗?
不需要。两者的核心内容(分层规则、验证命令、报错映射表)完全一致。如果你同时使用两个工具, 建议以 AGENTS.md 为主文件,CLAUDE.md 用软链接指向它:
bash
ln -s AGENTS.md CLAUDE.md
Q: Codex 的 Plan 模式和 Claude Code 哪个更适合生成 Plan?
Codex 的 Plan 模式更适合------它有内置的 request_user_input 工具在需求模糊时主动提问, 有 Goal 系统跟踪 token 预算,有自动化的 Plan → Task 拆分流水线。Claude Code 需要手动 引导每一步,更适合在 Plan 已经确定后的深度实现阶段。
Q: verify.sh 在 Codex sandbox 里跑不了怎么办?
verify.sh 依赖 conda 环境和系统级 Python 包,需要预先在 Codex 中批准:
vbnet
prefix_rule: ["bash", "scripts/verify.sh"]
或者把单个检查命令拆开,逐个在 sandbox 内运行。
Q: 两个工具能同时操作同一个 Git 仓库吗?
可以,但要避免编辑同一个文件。按 Task 拆分时已经考虑了文件冲突------ 一个 Task 对应一组明确的文件,不同 Task 不编辑同一个文件。