返回

Planning-with-files 教程 5:findings.md 研究管理

findings.md 是 3-File Pattern 的知识库,用于存储研究发现和技术决策。本文详解 2-Action 规则、研究发现记录方法和技术决策最佳实践。

教程概述

findings.md 是 3-File Pattern 中的"知识库",用于存储研究发现、技术决策和资源引用。它解决了 AI 长会话中信息容易丢失的问题。

你将学到

  • ✅ findings.md 的完整结构
  • ✅ 2-Action 规则的核心原理
  • ✅ 研究发现的记录方法
  • ✅ 技术决策的最佳实践

findings.md 的定位

flowchart TB
    subgraph 三个文件的关系
        A[task_plan.md<br/>大脑: 目标与进度]
        B[findings.md<br/>知识库: 发现与决策]
        C[progress.md<br/>日记: 动作与结果]
    end

    A --> D[存储"做什么"]
    B --> E[存储"知道了什么"]
    C --> F[存储"做了什么"]

    style B fill:#fff3e0

与其他文件的区别

文件 存储 更新时机
task_plan.md 目标、阶段、状态 开始、完成阶段、出错
findings.md 研究、发现、决策 每 2 次查看操作、做决策
progress.md 动作、测试、日志 每次操作后

核心问题

为什么需要单独的 findings.md?为什么不把所有信息都放在 task_plan.md?

答案:职责分离。

  • task_plan.md 是任务导向的,关注"要做什么"
  • findings.md 是知识导向的,关注"学到了什么"

标准结构

完整模板

# Findings: [任务名称]

## Research Findings

### [主题 1]
- 发现 1
- 发现 2

### [主题 2]
- 发现 1
- 发现 2

## Technical Decisions

### TD-1: [决策标题]
- **决策**: [具体决策]
- **理由**: [决策理由]
- **替代方案**: [被否决的方案]
- **日期**: [日期]

## Resources & References

### 文档
- [文档标题](URL)

### 代码
- [文件描述](文件路径)

### 相关 Issue/PR
- [#123: Issue 标题](URL)

各部分详解

Research Findings

存储研究过程中的发现:

## Research Findings

### 现有代码库结构
- 项目使用 Next.js 14 + App Router
- 数据库使用 Prisma + PostgreSQL
- 认证使用 NextAuth.js

### 性能瓶颈分析
- 首页加载时间 3.2s(目标 < 2s)
- 主要瓶颈:图片未优化、API 串行请求
- 优化方向:图片 CDN、并行请求

### 竞品功能对比
| 产品 | 标签系统 | 筛选功能 |
|-----|---------|---------|
| 产品 A | 扁平标签 | 多条件筛选 |
| 产品 B | 层级标签 | 单条件筛选 |
| 我们计划 | 扁平标签 | 多条件筛选 |

Technical Decisions

存储技术决策及理由:

## Technical Decisions

### TD-1: 数据库选择 PostgreSQL
- **决策**: 使用 PostgreSQL 而非 MySQL
- **理由**:
  1. 需要 JSON 类型存储复杂配置
  2. 更好的全文搜索支持
  3. 团队更熟悉 PostgreSQL
- **替代方案**: MySQL(不支持复杂 JSON 查询)
- **日期**: 2026-03-26

### TD-2: 认证方案选择
- **决策**: 使用 JWT + Refresh Token
- **理由**:
  1. 无状态,利于水平扩展
  2. 支持移动端
  3. 实现简单
- **替代方案**: Session(需要 Redis 存储)
- **日期**: 2026-03-26

Resources & References

存储有用的资源链接:

## Resources & References

### 官方文档
- [Prisma 多对多关系](https://www.prisma.io/docs/concepts/components/prisma-schema/relations/many-to-many-relations)
- [Next.js Server Actions](https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions)

### 代码文件
- [数据库 Schema](./prisma/schema.prisma)
- [API 路由](./src/app/api/)

### 设计参考
- [Figma 设计稿](https://figma.com/xxx)
- [竞品截图](./docs/competitor-screenshots/)

2-Action 规则详解

什么是 2-Action 规则?

每完成 2 次查看/浏览器/搜索操作,必须更新 findings.md

sequenceDiagram
    participant AI
    participant Context as 上下文
    participant File as findings.md

    Note over AI: 操作 1: Read 文件
    AI->>Context: 存储信息(易失)

    Note over AI: 操作 2: Grep 搜索
    AI->>Context: 存储信息(易失)
    AI->>File: 必须写入 findings.md!

    Note over AI: 操作 3: WebSearch
    AI->>Context: 存储信息(易失)

    Note over AI: 操作 4: WebFetch
    AI->>Context: 存储信息(易失)
    AI->>File: 必须写入 findings.md!

为什么是 2 次?

原因 说明
防止信息堆积 等太久会忘记前面的发现
保持上下文精简 不需要把所有信息都塞入上下文
强制整理 2 次操作后自然形成整理节点
可追溯 每个发现都有记录

什么算"查看操作"?

操作类型 示例 是否计数
Read 文件 Read schema.sql ✅ 是
Grep 搜索 Grep "function" ✅ 是
WebSearch 搜索技术文档 ✅ 是
WebFetch 获取网页内容 ✅ 是
Glob 文件 Glob "*.ts" ✅ 是
Write 文件 Write index.ts ❌ 否
Edit 文件 Edit config.json ❌ 否
Bash 命令 npm test ❌ 否

实践示例

场景:研究如何实现标签系统

操作 1: Read prisma/schema.prisma
→ 发现:当前数据模型

操作 2: Grep "Tag" in src/
→ 发现:无现有标签实现
→ ⚠️ 必须更新 findings.md!

更新 findings.md:

## Research Findings

### 数据库现状
- 模型位置: prisma/schema.prisma
- 文章表: Article (id, title, content, createdAt)
- 用户表: User (id, email, name)
- 评论表: Comment (id, articleId, userId, content)
- **无现有标签实现**

### 代码搜索结果
- 搜索关键词 "Tag": 无匹配
- 结论: 需要从零实现标签系统

继续:

操作 3: WebSearch "Prisma many-to-many best practices"
→ 发现:推荐的多对多关系实现方式

操作 4: WebFetch Prisma 官方文档
→ 发现:具体的 schema 写法
→ ⚠️ 必须更新 findings.md!

继续更新:

### Prisma 多对多最佳实践
- 文档: https://www.prisma.io/docs/...
- 推荐写法: 隐式多对多(不需要显式中间表)
- 示例:
  ```prisma
  model Article {
    tags Tag[]
  }
  model Tag {
    articles Article[]
  }

### 例外情况

**可以不遵循 2-Action 规则**:

1. **快速修复**:只查看一个文件然后立即修改
2. **简单确认**:只确认一个文件存在
3. **重复内容**:发现的已经在 findings.md 中

**应该更频繁更新**:

1. **复杂研究**:发现的信息很复杂
2. **关键信息**:涉及安全或架构决策
3. **多人协作**:需要分享给团队

---

## 研究发现记录

### 记录什么?

| 应该记录 | 不需要记录 |
|---------|-----------|
| 关键发现 | 显而易见的信息 |
| 影响决策的信息 | 临时调试信息 |
| 可复用的知识 | 一次性查询结果 |
| 非预期的发现 | 预期内的结果 |

### 记录格式

**结构化记录**:

```markdown
## Research Findings

### [主题名称]

**发现**: [具体发现内容]
**来源**: [文件路径/URL]
**影响**: [对任务的影响]
**行动**: [后续行动]

示例

### 性能问题分析

**发现**: 首页 API 响应时间 2.5s,超出目标 1s
**来源**: Chrome DevTools Network 面板
**影响**: 用户流失风险,SEO 排名下降
**行动**: 需要 API 优化(添加缓存、减少查询)

常见研究发现类型

代码库探索

### 代码库结构

src/ ├── app/ # Next.js App Router │ ├── api/ # API 路由 │ └── (main)/ # 页面组件 ├── components/ # 共享组件 ├── lib/ # 工具函数 └── types/ # TypeScript 类型


关键发现:
- 使用 Server Components,大部分组件不需要客户端 JS
- API 路由在 app/api/ 下

技术调研

### 状态管理方案对比

| 方案 | 学习成本 | 性能 | 适用场景 |
|-----|---------|------|---------|
| Redux | 高 | 高 | 大型应用 |
| Zustand | 低 | 高 | 中型应用 |
| Jotai | 低 | 高 | 小型应用 |
| Context | 低 | 中 | 简单场景 |

**结论**: 推荐使用 Zustand,平衡了学习成本和性能

问题分析

### 登录失败问题分析

**问题**: 用户反馈登录偶尔失败
**排查过程**:
1. 检查日志 → 发现 JWT 验证超时
2. 检查服务器时间 → 正常
3. 检查密钥配置 → 发现多实例配置不一致

**根本原因**: 多实例部署时 JWT 密钥配置不一致
**解决方案**: 统一使用环境变量配置密钥

技术决策记录

决策记录的重要性

flowchart LR
    A[做出决策] --> B[记录到 findings.md]
    B --> C[后期回顾]
    C --> D{情况变化?}
    D -->|是| E[有依据地调整]
    D -->|否| F[坚持原决策]
    E --> B

    style B fill:#fff3e0

ADR 风格(推荐)

Architecture Decision Record 风格的决策记录:

### TD-001: 使用 Redis 做缓存

**状态**: ✅ 已采纳
**日期**: 2026-03-26
**决策者**: 开发团队

**背景**:
- 用户增长导致数据库压力大
- 需要缓存热点数据
- QPS 预计达到 5000+

**决策**:
使用 Redis 作为缓存层。

**理由**:
1. 高性能:单实例支持 10万+ QPS
2. 数据结构丰富:String、Hash、Set 等
3. 团队有使用经验
4. 社区活跃,问题容易解决

**替代方案**:
1. Memcached:功能简单,不支持复杂数据结构
2. 本地缓存(如 Map):不支持分布式
3. 不做缓存:无法满足性能要求

**影响**:
- 正面:性能提升 10 倍,数据库压力降低
- 负面:增加运维复杂度,需要处理缓存一致性

**后续行动**:
- [ ] 搭建 Redis 集群
- [ ] 实现缓存预热
- [ ] 添加缓存监控

简化格式

对于简单决策,可以使用表格格式:

| Decision | Rationale | Date |
|----------|-----------|------|
| 使用 Tailwind CSS | 开发效率高,团队熟悉 | 2026-03-26 |
| 选择 Vercel 部署 | 与 Next.js 集成最佳 | 2026-03-26 |

决策编号规则

编号 含义
TD-001 第 1 个技术决策
DR-001 第 1 个设计决策
AD-001 第 1 个架构决策

资源管理

为什么记录资源?

  1. 避免重复搜索:URL 已经在文件里
  2. 团队共享:其他人可以直接使用
  3. 追溯依据:知道信息来源
  4. 离线参考:即使原文删除也有记录

资源记录格式

## Resources & References

### 官方文档
- [Next.js 文档](https://nextjs.org/docs)
- [Prisma 文档](https://www.prisma.io/docs)

### 代码文件
- [数据库模型](./prisma/schema.prisma)
- [API 路由](./src/app/api/)

### 设计资源
- [Figma 设计稿](https://figma.com/xxx)
- [图标库](https://lucide.dev/)

### 相关 Issue
- [#42: 标签功能需求](https://github.com/xxx/issues/42)

### 学习资源
- [React 最佳实践](https://xxx)

实战案例

案例:技术选型研究

findings.md

# Findings: 状态管理方案选型

## Research Findings

### 项目背景
- 技术栈: Next.js 14 + TypeScript
- 团队规模: 3 人
- 经验: 都是 React 新手

### 候选方案分析

#### Redux Toolkit
- ✅ 生态成熟,文档完善
- ✅ DevTools 强大
- ❌ 学习曲线陡峭
- ❌ 样板代码多

#### Zustand
- ✅ API 简洁,学习成本低
- ✅ 无样板代码
- ✅ 支持 TypeScript
- ❌ 生态较小
- ❌ DevTools 不如 Redux

#### Jotai
- ✅ 原子化设计
- ✅ 性能最优
- ❌ 概念较新,学习成本
- ❌ 社区较小

### 性能对比
| 方案 | Bundle 大小 | 首次渲染 | 更新渲染 |
|-----|-----------|---------|---------|
| Redux | 42KB | 120ms | 15ms |
| Zustand | 3KB | 100ms | 12ms |
| Jotai | 4KB | 95ms | 8ms |

## Technical Decisions

### TD-001: 选择 Zustand

**决策**: 使用 Zustand 进行状态管理

**理由**:
1. 团队是 React 新手,需要低学习成本的方案
2. Bundle 小,性能好
3. TypeScript 支持完善
4. 满足当前项目需求(中型应用)

**替代方案**:
- Redux:学习成本太高
- Jotai:原子化概念对新手不友好

**日期**: 2026-03-26

## Resources & References

### 官方文档
- [Zustand 文档](https://zustand-demo.pmnd.rs/)
- [对比文章](https://xxx)

### 示例代码
- [Zustand 最佳实践](./examples/zustand-demo.ts)

小结

findings.md 核心要点

  1. 知识库定位 - 存储发现和决策,而非进度和动作
  2. 2-Action 规则 - 每 2 次查看操作必须更新
  3. 结构化记录 - 按主题组织研究发现
  4. ADR 风格 - 技术决策要有完整上下文
  5. 资源追踪 - 记录 URL 和文件引用

检查清单

  • 每 2 次查看操作后更新了 findings.md
  • 研究发现按主题分类
  • 重要技术决策使用 ADR 格式
  • 记录了资源 URL 和文件路径
  • 决策包含了理由和替代方案

系列导航