Harness vibecoding:从 PRD 到可交付代码的结构化工法
AI写代码的速度很快,但“AI写完的代码能稳定跑在生产环境”是另一回事。很多团队在尝试Vibecoding时会遇到需求漂移、架构腐蚀、验证缺失等问题,最终导致项目不可持续。本文旨在提供一套完整的
“Harness Vibecoding”
1. 问题:为什么大部分Vibecoding不可持续
AI写代码很快,但“AI写完的代码能稳定跑在生产环境”是另一回事。常见的失败模式:

- :AI在第3轮对话时已经忘了第1轮的需求细节,开始自己“脑补”
需求漂移
- :AI为了快速实现功能,直接在API层写SQL、跳过Service层、引入循环依赖
架构腐蚀
- :AI说“改好了”,但3天后发现破坏了另一个模块的分层约束
验证缺失
- :token窗口耗尽后,下一个AI实例从零开始,重复劳动
上下文断裂
本质矛盾:AI的强项是“快速生成”,弱项是“持续保持一致性的约束”。而软件工程的本质恰恰是“在约束下持续演进”。
本文的核心命题是:
如何用工程手段把AI的快速生成能力关进约束的笼子,让它每一次输出都可验证、可修复、可接力。
2. 方法论全景:三阶段门禁流水线
2.1 贯穿全文的案例:archiving 数据归档平台
本文以
archiving
核心业务流程:
- 从企微会话存档拉取客户服务聊天记录,定时任务批量同步
- 多媒体内容自动提取:音频ASR转写、文档解析、压缩包递归解压
- LLM智能分块分类,将对话归类到预设业务标签体系
- 人工审核编辑后归档,支持全文检索与批量导出
项目从零开始严格遵循AGENTS.md分层架构,plan/ 和 task/ 目录即为本文方法论的核心产物。
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:
---
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。
小提示:开始前,请先在项目根目录创建 plan/ 和 task/ 文件夹,并确保你的AI工具(如Codex或Claude Code)能访问到它们。
3. Plan阶段:把模糊需求变成可执行的设计
3.1 为什么需要四份文档
传统开发中,一个需求讨论会可能产出半页白板笔记。AI拿着这个去写代码,大概率会写出“看起来对但实际不对”的东西。
Plan阶段强制产出四份结构化文档,每份回答一个不可跳过的问题:
| 文档 | 回答的问题 | 失败后果(如果跳过) |
|---|---|---|
design.md | 系统怎么做?模块边界在哪? | AI在API层写业务逻辑,破坏分层 |
db.md | 数据怎么存?字段类型和约束是什么? | 同名字段在不同表类型不一致,JOIN报错 |
api.md | 前后端契约是什么?入参出参长什么样? | 前端调不通,反复返工 |
test.md | 怎么证明功能是对的? | 改了A模块,B模块悄悄坏了 |
3.2 案例:archiving项目的Plan产出
以archiving项目为例,四份文档的产出内容:
design.md节选——核心处理链路:
企微会话存档 (数据源) │ ▼
定时任务拉取 → 原始消息存储 (customer_order表) │ ▼
消息组包 → MQ → 消费者解析落库 │ ├── 音频: ASR转写 → 文本内容提取 ├── 文档: 文档解析 → 文本内容提取 └── 压缩包: 解压 → 递归处理内层文件 │ ▼
LLM智能分块分类 → content_block (分类结果) │ ▼
人工审核/编辑 → 确认归档
db.md节选——状态字段约定:
所有状态字段使用大写字符串枚举,统一语义:
WAIT: 待处理DOING: 处理中(超时由补偿任务自动回收)DONE/SUCCESS: 完成FAIL: 失败SKIP: 跳过/无需处理
api.md节选——待开发接口契约:
POST /api/v1//update_content_block_info
请求: {content_block_id: str, update_content: str}
返回: {code: 200, message: “success”, data: bool}
校验: order_chat_block_id 非空, update_content 非空
test.md节选——验收用例:
### update_content_block_info
- [ ] 正常修改内容,返回true
- [ ] order_chat_block_id为空时返回失败
- [ ] update_content为空时返回失败
- [ ] 不存在的block返回false
3.3 如何从PRD生成Plan
三个来源组合:
- :功能需求 → design流程 + api接口
PRD直接映射
- :已有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 archiving项目的Task拆分案例
12个task的依赖拓扑:
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为例):
---
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在边界内可以任意发挥,一旦触及边界就会被拦住。
在archiving项目中,Harness由三层约束构成:
┌─────────────────────────────────────────────┐
│第一层:文件级地图 (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:
真实的AGENTS.md约束条目:
## 分层职责
- 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定义依赖方向:
[[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级细粒度拦截:
# 核心逻辑:用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中写了:
from app.storage.postgres.customer_order_chat_block_repository import (CustomerOrderChatBlockRepository,)
CI会输出:
[违规] app/api/coumter/customer_order_chat_block.py:10
原因: 接口层直接import了repository
规则: api → services → storage,接口层不得直接访问repository
修复: 删除该import,改为通过对应Service调用
5.3 正确姿势:三层协同的代码模式
AI被训练/约束后写出来的正确代码(来自archiving项目):
API层 (app/api/coumter/customer_order_chat_block.py):
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):
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层
5.4 DB会话的事务保证
session.py的get_db()上下文管理器强制了事务语义:
@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 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 自愈循环机制
Task开始
│
▼
AI生成代码
│
▼
bash scripts/verify.sh
│
├── [全绿] ──→ Task 完成 ✅
│
└── [红色] ──→ AI按报错信息自修复
│
├── 第1轮:修复 → verify.sh
├── 第2轮:修复 → verify.sh
├── 第3轮:修复 → verify.sh
│
└── 3轮仍未过 → 标记卡点写入progress.md
停止,等待人工介入
关键设计:每轮修复的输入是verify.sh的具体报错输出,而不是AI的猜测。这避免了“我觉得改好了”的主观判断。
小提示:自愈循环最多3轮,超过3轮应停止并标记卡点。这能避免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 门禁设计
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Plan审核 │ │ Task审核 │ │ CI门禁 │
│ (人工) │ │ (人工) │ │ (自动) │
└─────┬─────┘ └─────┬─────┘ └─────┬─────┘
│ │ │
审核通过才 审核通过才 全绿才
能进入Task 能进入Vibecoding 标记完成
人工审核的对象不是代码,而是设计文档。这比review代码高效得多——在文档阶段发现一个架构问题,比在代码阶段发现再返工的成本低10倍以上。
审核清单(来自WORKFLOW.md):
### Plan审核清单
- [ ] design.md是否覆盖全部PRD需求?
- [ ] db.md表结构是否合理,是否有遗漏字段?
- [ ] api.md入参/出参/异常码是否完整?
- [ ] test.md是否覆盖核心链路与边界?
- [ ] 所有文档之间的数据一致性是否可验证?
### Task审核清单
- [ ] 任务拆分粒度是否合理(单任务2-4h)?
- [ ] 依赖关系是否正确(无循环依赖)?
- [ ] 每个任务的验收标准是否可验证?
- [ ] 是否覆盖了plan/中全部接口与功能?
8. 关键设计决策与权衡
8.1 白名单vs零容忍
check_layers.py设计了白名单机制:
EXEMPT_DIRS = (“scheduler”, “mq”, “test”)
定时任务和MQ Consumer虽然放在app/api/目录下,但它们的角色实际上是“数据处理入口”,类似于Service层。强制它们走Service → Repository会增加不必要的间接层。白名单允许它们直接访问repository,同时保持纯HTTP路由的严格约束。
这是一个务实的权衡——在关键路径上零容忍,在类Service入口上允许豁免。
8.2 覆盖率阈值渐进提升
[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可持续的三根支柱
可持续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:项目文件结构总览
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 # 清理脚本
├── 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
└── 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的“唯一真相来源”,控制它的所有行为。关键配置段:
# 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模式在实际项目中的效果(以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模式(默认模式)。
关键设置:
-
:为每个Task创建Goal,设定token预算
Goal系统
/goal 实现Task 4: 内容块CRUD操作 token_budget=50000超过预算时Codex自动写
progress.md保存进度,下次对话可继续。 -
:verify.sh需要conda环境和系统级工具,需要预先批准
Sandbox权限
# 示例:批准verify.sh脚本运行权限
prefix_rule: [“bash”, “scripts/verify.sh”] -
:独立Task可以用多个Thread并行执行
Thread并行
Codex对话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模板:
# CLAUDE.md
## 项目概述
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阶段需要手动引导:
# Claude Code中
请读取PRD.md,分析现有代码库结构,按AGENTS.md规范生成plan/design.md, plan/db.md, plan/api.md, plan/test.md四份文档,并拆分为task/子任务。
Claude Code的独特优势:
-
:可以一次性读入整个代码库的核心文件,在复杂重构或跨模块改动时不需要频繁分段读取。
超大上下文窗口 (200K tokens)
-
:对于独立Task,启动子袋里并行执行:
子袋里 (Sub-agent)
# 主对话中
请为task_6、task_7、task_9分别启动子袋里并行开发 -
:直接运行
原生终端访问
bash scripts/verify.sh,无需sandbox配置。
10.3.3 Claude Code的Task执行模式
# 典型对话流程
用户: 执行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 推荐分工
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
在Codex中(Plan模式):
“读取PRD.md和现有代码库,按AGENTS.md规范生成plan/四份文档和task/子任务”
Codex Plan模式自动完成需求确认 → 代码分析 → 文档生成 → 任务拆分全流程。
第2步:人工审核plan/和task/
审核通过后把front matter改为status: approved。
第3步:分配Task给工具
独立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 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判断
架构决策
- :产品需求的定义需要领域专家,AI可以辅助提炼但不能替代
PRD撰写
- :权限模型、数据脱敏、注入防护——需要专业安全人员
安全审计
常见问题与解答
Q1: 如果AI在自愈循环中一直无法通过verify.sh怎么办?
答案:自愈循环最多进行3轮。如果3轮后仍未通过,AI会停止,并将卡点写入progress.md文件。此时需要人工介入,分析报错原因,可能是AI对架构理解有误或修复策略不对。人工修正后,可以手动重启Vibecoding流程。
Q2: 如何确保AI遵循AGENTS.md中的硬性规则,而不是试图“简化”或“绕过”?
答案:这是通过三层约束系统来保证的。AGENTS.md是“地图”,告诉AI规则;import-linter和check_layers.py是“警察”,在CI阶段自动拦截违规行为。如果AI试图绕过,CI会直接报错并给出修复指引,形成“违反→发现→强制修复”的闭环。也就是说,AI的“自由”被严格的工程约束锁死了。
Q3: 我的项目很小,只有几个模块,需要这么复杂的方法论吗?
答案:本方法论特别适合中大型项目(10+模块,持续迭代)。对于一次性脚本或小型POC,投入产出比不划算,建议直接使用AI的Vibecoding模式。但如果你希望小项目也能有良好的架构基础,可以简化流程,只保留AGENTS.md和verify.sh,跳过Plan和Task的详细拆分。
Q4: 如果AI在修改代码时,不小心破坏了原有的测试用例怎么办?
答案:这正是verify.sh中pytest测试的作用。CI门禁会执行所有测试用例,任何破坏行为都会被检测出来。如果AI破坏了测试,它会收到报错,并尝试修复代码或测试。如果3轮内无法修复,同样会标记卡点,等待人工介入。这保证了回归测试的完整性。
Q5: Codex和Claude Code,我该选择哪个?
答案:两者可以协同工作。推荐分工: