---
url: /blog/87lxaur0/index.md
---
# ClawFeed 从 0 到 1：AI 协作开发经验 SOP

项目地址：https://github.com/kevinho/clawfeed

> 基于 92 次提交、7 天、6 个贡献者（其中 5 个是 AI Agent）的真实项目复盘。

***

## 0. 写在前面：这个项目的本质

ClawFeed 是一个**人指挥 AI 团队**做出来的项目。

| 人类 | AI Agent | 职责 |
|------|----------|------|
| **Kevin He** (80 commits) | — | 产品方向、架构决策、直接编码、最终审批 |
| — | **Jessie** (6 commits) | Lead Dev，写 PRD、开发、协调 |
| — | **Lisa** (2 commits) | QA + Code Review，写测试用例、Codex 审查 |
| — | **lucy-coco** (2 commits) | Dev，补充实现 |
| — | **Xushen** (1 commit) | 安全加固 |
| — | **TianLun Song** (1 commit) | Docker 支持 |

Kevin 是唯一的"真人"，其余都是 AI Agent。项目的核心经验是：**一个人如何指挥多个 AI Agent 协作交付一个完整产品。**

***

## 1. 时间线复盘：7 天从 0 到上线

### Day 0 (02-21 18:38) — 大爆炸：2134 行代码一次提交

**做了什么：** 一次性提交了完整可运行的产品，包含后端、前端、数据库、OAuth、文档。

**初始提交包含：**

* `src/server.mjs` (308 行) — 完整 HTTP 服务器
* `src/db.mjs` (151 行) — SQLite 数据层
* `web/index.html` (536 行) — 完整前端 SPA
* `migrations/001_init.sql` + `002_auth.sql` — 数据库 schema
* `templates/` — AI 摘要提示模板
* `docs/PRODUCT.md` (150 行) — 产品设计文档
* `SKILL.md` (79 行) — 技能入口文档
* `README.md` (138 行) — 项目说明

**可复用经验 #1：MVP 先跑通，再迭代**

> 第一次提交就是可运行的产品。不是"脚手架"，不是"Hello World"，是用户能看到界面、能登录、能看摘要的完整体验。Kevin 很可能在本地已经打磨好了才推到 GitHub。
>
> **原则：第一个 commit 必须能 `npm start && 打开浏览器看到东西`。** 不要提交半成品。

### Day 0 (02-21 18:57 ~ 20:50) — UI 精调：1 小时 15 次提交

接下来 1 小时内连续提交了 **15 个 fix/feat commit**，全在做 UI 微调：

* 语言切换按钮的位置、样式、行为反复调整（6 次 fix）
* GitHub 图标从文字→SVG→合并到工具栏（3 次 fix）
* 头像下拉菜单设计（2 次 feat+fix）
* 时区处理、goHome 函数提取

**可复用经验 #2：快速试错，小步提交**

> 每个 commit 改动极小（几行到十几行），但频率极高。这是典型的 AI 辅助开发节奏：指令 → AI 输出 → 看效果 → 不满意 → 微调指令 → 再输出。
>
> **原则：对 AI 下达小而具体的指令，每次只改一个点，立刻看效果。不要一次让 AI 改 5 个东西。**

### Day 0 (02-21 22:15 ~ 23:30) — 核心功能冲刺：Sources → Feeds → Packs

晚间集中完成了三个核心功能模块：

| 时间 | 功能 | 说明 |
|------|------|------|
| 22:15 | Sources 管理 (Phase 1) | CRUD + 公开/私有 + 所有权 |
| 22:32 | Feed 输出端点 | JSON Feed + RSS + Simple API |
| 22:40 | 智能 Source 添加 | URL 自动检测类型 |
| 22:47 | 隐藏未配置的 Auth UI | 无 OAuth 时不显示登录按钮 |
| 22:52 | Changelog 弹窗 | API + Markdown 渲染 |
| 23:07 | Source 预览 | RSS/JSON Feed URL 检测时显示最近条目 |
| 23:20 | Source Packs (Phase 2) | 完整的打包分享系统 |
| 23:51 | 新用户引导体验 | 空状态引导 |

**可复用经验 #3：Phase 驱动开发**

> 注意 commit message 里的 "Phase 1"、"Phase 2" 标记。Kevin 把功能拆成阶段，每阶段交付可用的子集。
>
> * Phase 1: Sources CRUD — 能增删改查信息源
> * Phase 2: Source Packs — 能打包分享
>
> **原则：每个 Phase 是一个独立可交付的功能增量。先跑通最小闭环，再叠加下一层。**

### Day 1 (02-22 凌晨) — 测试 + 文档

| 时间 | 事项 |
|------|------|
| 01:45 | E2E 多用户交叉测试 (44 cases) |
| 02:01 | 正式的 E2E 测试套件 (setup/teardown/57 cases) |
| 02:02 ~ 02:15 | 测试文档 (TESTING.md, test/README.md) |
| 02:18 | 产品路线图 + 架构 Scale 分析 |
| 02:21 ~ 02:24 | Roadmap 页面 + i18n |

**可复用经验 #4：功能做完立刻写测试**

> Kevin 在核心功能做完后，立刻投入写 E2E 测试。不是"以后补"，是**当天完成**。44 个测试用例 → 第二版扩展到 57 个，覆盖认证、CRUD、权限隔离、安全、边界情况。
>
> **原则：测试是功能的一部分，不是后续任务。做完一个 Phase，立刻用测试锁住它。**

### Day 1 (02-22 下午) — 产品重塑

| 时间 | 事项 |
|------|------|
| 15:00 | 品牌更新 subtitle |
| 15:24 | **改名 AI Digest → ClawFeed** |
| 15:28 | **移除 admin 机制**（is\_admin 字段、ADMIN\_EMAILS） |
| 15:29 | 移除过时的迁移工具 |

**可复用经验 #5：敢于在早期推翻决策**

> Kevin 果断做了几个"大手术"：
>
> 1. 产品改名 — 代码、文档、repo 全改
> 2. 砍掉 admin 机制 — 认为不需要管理员角色，简化权限模型
> 3. 移除遗留工具 — 减少维护负担
>
> **原则：早期架构决策不是永恒的。发现不对就改，越晚改成本越高。**

### Day 1~2 (02-22 ~ 02-23) — 锦上添花

* 暗色/亮色主题切换
* Mark/Unmark 功能
* README 重写 + Demo 视频/GIF
* 版本同步 (v0.7.0)

### Day 3 (02-24) — AI Agent 团队上线

这是转折点。Kevin 引入了 AI Agent 团队，开始通过 PR 流程协作：

| 时间 | Agent | PR | 内容 |
|------|-------|----|------|
| 03:16 | Lisa | #2 | GitHub Actions CI 流水线 |
| 03:46 | Jessie | #3 | PR 模板 + CONTRIBUTING.md |
| 04:19 | lucy-coco | #4 | /api/health 端点 |
| 04:21 | lucy-coco | #5 | FEEDBACK\_LARK\_WEBHOOK 配置 |
| 04:27 | Jessie | #7 | 更新 PROCESS.md |
| 04:41 | Lisa | — | PR 模板改进（需求理解部分） |
| 13:11 | Jessie | #26 | Release v0.8.1 |

**可复用经验 #6：先手动跑通，再用 Agent 自动化**

> Kevin 自己手动做了 80 个 commit（Day 0-2），把产品从 0 做到 v0.7.0。**然后才**引入 Agent 团队做 CI、文档、模板、Release 这些流程性工作。
>
> **原则：创始人必须亲手做过一遍，才知道每个环节要什么。自动化建立在理解之上，不是替代理解。**

***

## 2. 核心方法论：五层 SOP

### SOP-1：产品定义先行（PRODUCT.md）

在写第一行代码之前，先写 `docs/PRODUCT.md`，定义：

```
定位 → 功能划分 → 两种模式 → 技术架构 → 实施路线（Phase 1~4）
```

**为什么有效：**

* AI Agent 需要明确的上下文，PRODUCT.md 就是项目的"宪法"
* 每个 Phase 有清晰的交付目标，避免范围蔓延
* 功能按"类型"和"作用域"两个维度拆分，方便分配给不同 Agent

**实操模板：**

1. 一句话说清楚产品是什么
2. 列出所有功能，按"用户可见功能"和"管理功能"分类
3. 定义两种运行模式（如：开源版 vs 托管版）
4. 画出技术架构图
5. 按阶段排列路线图，每阶段 3-5 个交付项

### SOP-2：PRD 驱动开发（docs/prd/）

```markdown
# [功能名称] PRD

## 背景 — 为什么做
## 方案 — 怎么做（数据模型 + API + UI）
## 影响范围 — 改哪些文件
## 验收标准 — checklist 格式
## 测试用例 — 表格格式（场景/步骤/预期结果）
## 回滚方案 — 出问题怎么办
## 负责人 — 谁开发/谁测试/谁审批
```

**为什么有效：**

* **验收标准是 checklist**，不是模糊描述。`[x]` 和 `[ ]` 一目了然
* **测试用例表**直接从 PRD 衍生，不需要额外的测试文档
* **回滚方案**强制思考"最坏情况"
* **负责人**明确每个 Agent 的职责边界

**实操关键：**

* PRD 以 **PR 形式提交**，必须经过 review 才能开发
* 例外：Bug fix / hotfix 可跳过 PRD，但事后补说明
* PRD 里就包含测试用例，不需要单独的测试设计阶段

### SOP-3：角色分工（PROCESS.md）

```
Kevin (人类) — PO + 最终审批 + 架构决策
Jessie (AI)  — Lead Dev + 写 PRD + 协调
Lucy (AI)    — Dev + 补充技术细节
Lisa (AI)    — QA + Code Review
```

**关键发现：不是所有 Agent 都一样。**

| Agent 角色对应 | 适合的工作 | 不适合的工作 |
|----------------|------------|--------------|
| **Lead Dev** (Jessie) | 写 PRD、架构设计、复杂功能开发 | 重复性测试 |
| **Dev** (lucy-coco) | 单点功能实现、配置补充 | 架构决策 |
| **QA** (Lisa) | 写测试用例、Code Review、Staging 验收 | 开发新功能 |

**实操原则：**

* 每个 Agent 有明确职责边界，不越界
* 代码类 PR 和文档类 PR 走相同流程
* Kevin 是唯一有 merge 权限的人
* Agent 的 review 会被新 commit 自动撤销（Branch Protection），必须重新 review

### SOP-4：开发节奏

从 git 历史提炼出的典型开发循环：

```
一个功能的开发周期：

1. Kevin 提需求（飞书群里说一句话）
      ↓
2. Jessie 写 PRD（1-2 小时）
   - docs/prd/xxx-feature.md
   - 包含验收标准 + 测试用例
      ↓
3. Kevin Review PRD（PR 形式）
   - 方向不对直接打回
   - approve 后才能开发
      ↓
4. Jessie/Lucy 开发（feat/xxx 分支）
   - 涉及 DB 变更必须写 migration
   - 不直接改 production 数据
      ↓
5. Lisa Code Review
   - Codex CLI 自动审查 → 迭代至 CLEAN
   - 手动检查安全性、是否符合 PRD
      ↓
6. Lisa 在 Staging 自测
   - 按 PRD 测试用例逐项过
   - 移动端、未登录用户都要测
      ↓
7. Kevin 在 Staging 验收
   - 对照 PRD 确认功能
      ↓
8. Kevin merge develop → main
   - 打 release tag
   - 部署 production
      ↓
9. Lisa 跑 Production Smoke Test
   - API 健康检查
   - 核心功能快速过一遍
```

**实操原则：**

* **PRD 未 approve 不开发** — 避免方向性返工
* **Staging 是必经之路** — production 不能出问题
* **Smoke Test 是最后一道关** — 部署后必须验证

### SOP-5：技术约束即架构决策

这个项目做了几个看似"简陋"但实为刻意的技术选择：

| 选择 | 原因 | 效果 |
|------|------|------|
| **无框架**（手写 HTTP server） | 减少依赖、Agent 易理解、无黑盒 | server.mjs 虽然有 870 行，但逻辑透明 |
| **单文件前端**（web/index.html） | 无构建步骤、部署简单 | 前端 1916 行，但零工具链成本 |
| **SQLite** | 零运维、单文件部署、WAL 模式够用 | 至今无需迁移 PostgreSQL |
| **ESM 纯 JS** | Agent 生成 JS 比 TS 更准确 | 无编译步骤 |
| **手动 .env 解析** | 不引入 dotenv 依赖 | 代码重复但可控 |
| **Bash E2E 测试** | 无测试框架依赖、Agent 可直接写 shell | 52 个测试用例，覆盖 15 个类别 |

**实操原则：**

* **工具链复杂度 = Agent 出错概率**。越简单的技术栈，AI 协作效率越高
* **零构建步骤**是关键优势。`npm start` 就是全部
* **依赖越少越好**。唯一运行时依赖是 better-sqlite3

***

## 3. 指挥 AI 的实操技巧

### 技巧 1：用 PR 模板控制 AI 输出质量

`.github/pull_request_template.md` 的"需求理解"字段是关键发明：

```
## 需求理解 / Requirement Understanding

> 用 1-2 句话复述你对需求的理解。
> Reviewer 会优先检查这里是否正确，方向不对直接打回。
```

**为什么有效：** AI Agent 容易"自以为是"地实现。强制它在 PR 开头复述需求，如果理解错了，reviewer 在第一个字段就能打回，不需要看代码。

### 技巧 2：验收标准用 Checklist 格式

```markdown
## 验收标准
1. [ ] 标准 1
2. [ ] 标准 2
```

**为什么有效：** AI Agent 看到 `[ ]` 会逐条对照。表格比段落更不容易遗漏。验收标准直接从 PRD 拷贝到 PR，确保不跑偏。

### 技巧 3：每个功能配回滚方案

```markdown
## 回滚方案
删除 migration 010 和 collector 模块即可。raw_items 表独立于现有功能。
```

**为什么有效：** AI 不会主动思考"如果出问题怎么办"。强制写回滚方案，迫使 Agent（和人类）考虑失败场景。

### 技巧 4：Branch Protection + 强制 Review

```
develop 分支: CI 通过 + 1 review
main 分支: Kevin approve
```

**为什么有效：** AI Agent 可以提 PR，但不能自己 merge。每行代码都经过至少一层人工确认。Branch Protection 的 `dismiss stale reviews` 确保新 commit 必须重新 review。

### 技巧 5：Staging 环境验证

```
feat/xxx → develop (自动部署 staging) → Kevin 验收 → main (生产)
```

**为什么有效：** AI Agent 的代码可能在本地测试通过但在真实环境失败。Staging 环境和 production 同配置、独立数据库，确保验证结果可信。

### 技巧 6：先用 "Phase" 拆分，再分配给 Agent

```
Phase 1: Sources CRUD（Jessie 负责）
Phase 2: Source Packs（Jessie 负责）
Phase 3: 个性化 Digest（后续）
```

**为什么有效：** Agent 一次只做一件事。Phase 是自然的任务边界，每个 Phase 有自己的 PRD、测试用例、验收标准。

***

## 4. 数据驱动：项目增长的真实数字

### 代码增长

| 时间点 | server.mjs | db.mjs | index.html | 总计 |
|--------|-----------|--------|------------|------|
| Day 0 (初始) | 308 行 | 151 行 | 536 行 | 995 行 |
| 当前 | ~870 行 | ~457 行 | ~1916 行 | ~3243 行 |

核心文件增长了 **3.3 倍**，但文件数量没有增加（后端仍然是 2 个文件）。

### 提交类型分布

| 类型 | 数量 | 占比 |
|------|------|------|
| fix | 24 | 26% |
| feat | 15 | 16% |
| 其他（docs/chore/refactor） | 53 | 58% |

**注意：** fix 数量 > feat 数量。这说明大量工作在"调教"AI 的输出——它做出来的东西需要反复修正。

### 开发速度

* Day 0 (6 小时): 0 → 完整产品 + 2 个 Phase
* Day 1: 测试体系 + 品牌重塑 + 产品文档
* Day 2: 锦上添花功能
* Day 3: AI Agent 团队流程化

**从 0 到可演示的产品：6 小时。**

***

## 5. 可复用的检查清单

### 开始一个新项目时

* \[ ] 写 `PRODUCT.md`：定位、功能清单、架构图、Phase 路线图
* \[ ] 第一个 commit 就是可运行的产品（不是脚手架）
* \[ ] 技术栈选择以"AI Agent 易理解和操作"为原则
* \[ ] 画出 Phase 分界，每个 Phase 可独立交付

### 指挥 AI 开发时

* \[ ] 每个功能先写 PRD（含验收标准 + 测试用例 + 回滚方案）
* \[ ] PR 模板强制"需求理解"字段，AI 先复述再实现
* \[ ] 一次只给 AI 一个 Phase 的任务
* \[ ] 每次指令小而具体，改完立刻验证
* \[ ] Branch Protection 开启，AI 不能自己 merge

### 功能完成后

* \[ ] 立刻写 E2E 测试锁住功能
* \[ ] Staging 环境验证
* \[ ] 对照 PRD 验收标准逐项 check
* \[ ] Production Smoke Test

### 做架构决策时

* \[ ] 问自己：这个选择会让 AI Agent 更难工作吗？
* \[ ] 依赖越少越好
* \[ ] 构建步骤越少越好
* \[ ] 文件越少越好（但要保持可读性）
* \[ ] 敢于在早期推翻错误决策

***

## 6. Q\&A：为什么选择极简技术栈？

> **Q：为什么该项目用的技术都很简单，而不是复杂的框架？这对 AI 更友好，或者这就是 7 天完成的奥秘吗？**

### 6.1 先看事实：这个"简单"到底有多极端

| 层面 | ClawFeed 的选择 | 主流选择 | 差异 |
|------|----------------|----------|------|
| **HTTP 服务** | 手写 `createServer()` if/else | Express / Fastify / Nest | 无路由抽象 |
| **前端** | 单文件 `index.html` 1916 行 | React/Vue + 构建工具链 | 无组件化 |
| **类型系统** | 纯 JS (.mjs) | TypeScript | 无编译步骤 |
| **数据库** | SQLite + 手写 SQL | PostgreSQL + ORM | 无抽象层 |
| **测试** | Bash + curl | Jest / Vitest / Playwright | 无测试框架 |
| **配置** | 手写 `.env` 解析器 | dotenv 库 | 无依赖 |
| **依赖总数** | **1 个** (better-sqlite3) | 通常 50-200 个 | 极端克制 |

这不是"简单"，这是**几乎为零的工具链**。

### 6.2 真正的原因：不是"为了 AI 友好"，是三个因素叠加

#### 因素 1：7 天赶工 → 选择最短路径（占比 50%）

从 git 历史看，Day 0 那天 Kevin 从 18:38 到 23:51 连续做了 **35 个 commit**，6 小时内交付了完整的后端、前端、数据库、文档。

**这个速度下，你有时间装 Express 但没时间调 Webpack。** 更准确地说：

```
引入 Express:        5 分钟   — 值得
引入 TypeScript:     2 小时   — 来不及（配置 tsconfig + 编译 + 类型定义）
引入 React:          1 天     — 不可能（组件拆分 + 状态管理 + 构建配置）
引入 Jest:           30 分钟  — 但 bash 写测试更快，Agent 直接写 curl
```

Kevin 在 PRODUCT.md 里画的架构图就是 `server.mjs + db.mjs + index.html`，说明他在动手之前就决定了极简架构。**这是有意识的选择，不是偷懒。**

#### 因素 2：AI Agent 确实更擅长简单技术（占比 35%）

AI 对以下东西的生成质量明显更高：

| AI 擅长 | AI 容易出错 |
|----------|------------|
| 原生 Node.js `http.createServer` | Express 中间件执行顺序 |
| 直接 SQL (`SELECT ... WHERE`) | ORM 链式调用 (`User.where().include()`) |
| 原生 DOM 操作 | React hooks 依赖数组 |
| 简单的 if/else 路由 | 装饰器路由 + 依赖注入 |
| Bash curl 断言 | Jest mock/timer |

**原因不是"简单"，是"确定性"。**

* `http.createServer((req, res) => { ... })` — 每一行代码的行为都是确定的，AI 可以精确预测
* `app.use(cors())` + `app.use(auth())` + `app.use(router())` — 中间件执行顺序、错误传播、异步边界都是隐式的，AI 容易搞错

**反例：** 870 行的 `server.mjs` 其实并不简单——一个函数里塞了所有路由。但它是**线性可读**的：从上到下，每个 `if (method === 'GET' && path === '/api/xxx')` 都一目了然。AI 不需要理解框架的"魔法"。

#### 因素 3：产品性质决定的（占比 15%）

ClawFeed 的本质是：`采集数据 → AI 生成摘要 → 存 SQLite → REST API 读出来 → 前端展示`

这是一个**数据管道 + CRUD 应用**。核心复杂度在 AI 摘要生成（在 Agent 那边，不在本仓库），本仓库只做"搬运和展示"。

对于这种性质的应用：

* **并发量低** — SQLite 完全够用，不需要 PostgreSQL
* **无实时协作** — 不需要 WebSocket/CRDT
* **无复杂前端交互** — 不需要虚拟 DOM diff
* **无复杂权限模型** — 不需要 RBAC/ABAC

如果做的是 Figma 那样的实时协作编辑器，这套技术栈绝对不行。但做新闻摘要，**简单技术 = 正确技术**。

### 6.3 反直觉的结论

很多人会得出"简单技术 = AI 更友好 = 开发更快"的结论。但真实的因果关系是：

```
不是：简单技术 → 开发快
而是：明确的约束条件 → 选择简单技术 → 减少决策疲劳 → 开发快

        ┌─────────────┐
        │ 产品范围明确 │ ← 只有 CRUD + 展示，不需要复杂框架
        └──────┬──────┘
               ↓
        ┌─────────────┐
        │ 时间约束极紧 │ ← 7 天必须上线
        └──────┬──────┘
               ↓
        ┌─────────────────────┐
        │ 选择最小可用技术栈   │ ← 零依赖 = 零调试时间
        └──────┬──────────────┘
               ↓
        ┌─────────────────────┐
        │ AI 生成代码更准确    │ ← 确定性代码 = AI 出错率低
        └──────┬──────────────┘
               ↓
        ┌─────────────────────┐
        │ fix 少 → 迭代快      │ ← fix 占 26%，如果用复杂框架会更高
        └─────────────────────┘
```

**真正的奥秘不是"简单技术"，是"极小的决策空间"。**

Kevin 在 Day 0 启动之前就已经锁定了所有技术决策：

* 不讨论用什么框架 → 没有框架
* 不讨论用什么数据库 → SQLite
* 不讨论测试方案 → bash curl
* 不讨论前端方案 → 单文件 HTML

**零决策 = 零时间浪费在选型上。** 这才是 7 天的奥秘。

### 6.4 这个策略的代价

| 代价 | 现状 |
|------|------|
| **前端可维护性** | `index.html` 已有 1916 行，再增长会很难维护 |
| **无法加单元测试** | 没有 import/模块系统，无法 mock |
| **IDE 支持差** | 没有 TypeScript，没有类型提示 |
| **团队扩展困难** | 新人看到 870 行 if/else 会崩溃 |
| **性能天花板低** | SQLite 单写锁，高并发写会瓶颈 |

Kevin 知道这些代价——他在 ARCHITECTURE.md 里写了 10K 用户的 Scale 分析和 PostgreSQL 迁移计划。但他选择**先跑通再优化**，而不是**先完美再上线**。

**结论：技术选型的目标不是"最佳实践"，是"在这个约束条件下能最快交付的方案"。**

***

## 7. 这个 SOP 的局限

1. **规模限制：** 这个经验适用于小型团队（1人 + AI）。到 10 人团队需要调整。
2. **项目类型限制：** ClawFeed 是 CRUD 密集型 Web 应用。算法密集型或嵌入式项目的 SOP 会不同。
3. **测试深度限制：** 只有 E2E 测试，无单元测试。适合快速迭代，不适合安全关键系统。
4. **AI Agent 可靠性：** fix 远多于 feat 说明 AI 输出质量不稳定。需要人工兜底。
5. **单人瓶颈：** Kevin 是唯一的 merge 人。这是有意为之（控制质量），但也限制了吞吐量。
