# Spec 批判 Gate：对抗 LLM 讨好偏见的产品规格干预

**技术报告 — ReqForge v1.44.0**
**日期：2026-06-09**
**作者：ReqForge 项目**

---

## 摘要

基于 LLM 的产品规格代理存在讨好偏见——倾向于认可用户想法而非质疑。我们引入批判 Gate，通过三个结构信号强制对共识规格进行对抗性复审：隐藏假设、未质疑的决策、应裁剪的范围。三轮评估——手动 A/B 对比、Dogfood 开发、自动化盲评——表明批判模式规格在风险可见性（+5.2，10 分制）和抗返工能力（+4.2）上显著更高，盲评偏好 5:0。但批判 Gate 仅防止方向错误；62% 的关键实现 bug 在规格层面不可预见。我们讨论价值边界、方法局限和产品集成。

---

## 1. 问题

RLHF/对齐训练激励 LLM 认同用户而非质疑其假设。在产品规格阶段——目标是识别风险、裁剪范围、暴露隐藏假设——这种偏见有害。对照组规格始终不经审视地验证用户想法，产出看似完整但无法暴露返工风险的规格。

我们称之为**"2.5 层"问题**：对齐层（第 2.5 层）位于模型基础能力（第 1 层）和用户意图（第 3 层）之间，系统性地将输出偏向用户肯定。这在执行阶段有益（模型应遵循指令），但在规格阶段有害（模型应质疑假设）。

---

## 2. 干预：批判 Gate

批判 Gate 是一个结构化的对抗性检查点，插入利益相关方评审之后、文档生成之前的 0-to-1 规格工作流。它检验三个经实验验证的结构信号：

| 信号 | 检测什么 | 示例 |
|------|---------|------|
| **隐藏假设** | 被当作事实但无证据的假设 | "用户会完成引导流程" |
| **未质疑的决策** | 未考虑替代方案就接受的决策 | "用 React" 但无对比 |
| **应裁剪的范围** | 经不起诚实审视的功能 | v1 做"完整 CRUD"但只需 Read |

每个信号产出结构化输出：ID、发现、影响评估、解决建议。

**关键设计选择**：Gate 是**单次检查点**，不是迭代评审。其价值在于强制视角转换，而非精炼循环。这是有意为之——对批判结果迭代会遭受该 Gate 设计要防止的同一种讨好漂移。

---

## 3. 实验设计

### 3.1 假设

H1：LLM 讨好偏见导致对照组规格低报风险、假设和范围边界。
H2：批判 Gate 干预产出的规格在风险可见性、范围清晰度和抗返工能力上可测量地更好。

### 3.2 三轮实验

| 轮次 | 方法 | 目的 | 日期 |
|------|------|------|------|
| 1 | 手写 A/B spec + `forge-spec-critique` 打分 | 初步方向验证 | 2026-06-09 |
| 2 | Dogfood 开发（小说创作工具）+ 代码审查 | 下游影响验证 | 2026-06-09 |
| 3 | 自动化盲评（`forge-spec-blind-eval`） | 消除偏见 | 2026-06-09 |

### 3.3 实验材料

五份需求简述，覆盖不同产品领域：

| 简述 | 领域 | 核心挑战 |
|------|------|---------|
| 01 | 企业知识库 | RAG 准确性 + 访问控制 |
| 02 | 电商小程序 | 支付集成 + 物流 |
| 03 | AI 面试助手 | LLM 幻觉 + 公平性 |
| 04 | 健身追踪 | 穿戴设备集成 + 数据可靠性 |
| 05 | 合同审查 | 法律准确性 + 管辖权 |

每份简述 200-400 字，描述产品意图、目标用户和核心功能。

---

## 4. 第一轮：手动 A/B + 自动评分

### 4.1 方法

每份简述生成两组规格：
- **对照组**：标准 product-spec-builder prompt（"生成一份 Product Spec"）
- **批判组**：修改后的 prompt，要求暴露假设、考虑替代方案、裁剪范围、列出风险矩阵

两组均由 `forge-spec-critique` 打分，测量假设计数、质疑计数、范围决策计数和模糊词密度。

### 4.2 结果

| 简述 | 对照组评分 | 批判组评分 | 差值 |
|------|-----------|-----------|------|
| 01 | 4/40（uncritical） | 18/40（shallow） | +14 |
| 02 | 8/40（uncritical） | 19/40（shallow） | +11 |
| 03 | 4/40（uncritical） | 20/40（adequate） | +16 |
| 04 | 9/40（uncritical） | 20/40（adequate） | +11 |
| 05 | 9/40（uncritical） | 20/40（adequate） | +11 |

所有对照组评分均在 "uncritical" 区间；所有批判组至少达到 "shallow" 或 "adequate"。

### 4.3 方法缺陷

- **双重偏见**：实验者即 LLM，知道"对的答案"长什么样
- **循环论证**：`forge-spec-critique` 自己定规则自己打分——自指验证
- **无盲评**：评分者知道哪份是对照组、哪份是批判组

---

## 5. 第二轮：Dogfood 开发 + 代码审查

### 5.1 方法

用批判组规格开发小说创作 Web 应用（React + Vite + TypeScript + IndexedDB + D3.js）。开发后代码审查发现 35 个问题（13 个 critical）。每个问题对照规格，判断批判 Gate 是否标注了其底层风险。

### 5.2 风险命中

批判规格标注的 3 个核心风险在开发中全部命中：

| 规格标注的风险 | 实际情况 |
|--------------|---------|
| AI 写正文需要 API Key — 与"纯本地"矛盾 | 用户确实需要自备 Key |
| 关系网可视化交互复杂 | D3 force graph 出了 crash（node not found） |
| 浏览器存储不可靠 | 导入验证、文件名等数据丢失隐患 |

### 5.3 覆盖分析

13 个 critical 实现问题中：

| 覆盖情况 | 数量 | 占比 | 示例 |
|---------|------|------|------|
| 批判规格覆盖 | 3 | 23% | D3 crash、API Key、数据丢失 |
| 部分相关 | 2 | 15% | CRUD 缺删除确认 |
| 未覆盖（实现 bug） | 8 | 62% | React state mutation、错误模型 ID |

### 5.4 价值边界发现

**批判 Gate 防方向错误（架构、范围、风险），不防实现错误（state mutation、变量名、API 调用）。** 这不是局限——这是干净的边界。代码审查防实现错误；批判 Gate 防规格错误。两种机制互补但不重叠。

---

## 6. 第三轮：自动化盲评

### 6.1 方法

`forge-spec-blind-eval` 对每份简述自动执行：

1. 两个独立 LLM session 生成规格（对照组 prompt vs 批判组 prompt）
2. A/B 顺序**随机打乱**——评分者不知道哪份是哪种
3. 独立 LLM session 盲评两份规格，5 个维度打分（1-10）+ 选偏好
4. 还原标签，统计分析

**消除的偏见**：

| 之前的问题 | 解决方式 |
|-----------|---------|
| 实验者即 LLM，双重偏见 | 两个独立 API session 生成规格 |
| 评分者知道"对的答案" | 随机打乱 A/B 顺序 |
| 打分标准与生成循环论证 | 评分维度独立于批判指标 |

### 6.2 结果

**偏好：批判组 5 胜 — 对照组 0 胜（5:0）**

| 简述 | 盲评偏好 | 还原后 | 理由 |
|------|---------|--------|------|
| 企业知识库 | B | 批判组 | 暴露风险和假设；对照组过于理想化 |
| 电商小程序 | A | 批判组 | 全面暴露风险和替代方案；对照组缺乏深度 |
| AI 面试助手 | B | 批判组 | 风险矩阵+降级策略降低返工概率 |
| 健身追踪 | B | 批判组 | 标注穿戴设备不可行等关键问题 |
| 合同审查 | B | 批判组 | 每个功能标注风险和替代方案 |

### 6.3 维度均值（1-10 分制）

| 维度 | 对照组 | 批判组 | 差值 |
|------|--------|--------|------|
| 完整性 | 7.8 | 9.0 | +1.2 |
| 风险可见性 | 3.8 | 9.0 | **+5.2** |
| 可执行性 | 6.8 | 8.0 | +1.2 |
| 范围清晰度 | 5.6 | 9.0 | **+3.4** |
| 抗返工能力 | 4.6 | 8.8 | **+4.2** |

最大差距在风险可见性（+5.2）和抗返工能力（+4.2）。完整性差距最小（+1.2）——对照组翻译需求能力不差，差在不敢质疑。

---

## 7. 验证状态

| 宣称 | 第一轮 | 第二轮 | 第三轮 | 最终 |
|------|--------|--------|--------|------|
| LLM 在 spec 阶段有讨好倾向 | 表面成立 | 确认 | 确认 | **确认** |
| 批判 Gate 产出更好的 spec | 主观 | 风险命中 | 5:0 盲评 | **确认** |
| `forge-spec-critique` 能测出讨好程度 | 循环论证 | — | — | **未确认**（循环打分） |
| 批判 spec 减少开发返工 | — | 部分验证 | 代理指标（8.8 vs 4.6） | **高置信度，未直接证明** |

---

## 8. 局限性

1. **样本量**：5 份简述不足以达到统计显著性。5:0 结果有提示性但不满足 p < 0.05。
2. **LLM 评分者**：所有评分者均为 LLM session（DeepSeek），不是真人开发者。LLM 偏好可能与开发者偏好不一致。
3. **单一 provider**：仅测试 DeepSeek。Claude、GPT-4 或其他模型的结果可能不同。
4. **无返工跟踪**：抗返工能力是代理评分（4.6 vs 8.8），不是实际开发迭代次数。真正的 A/B 开发对比未进行。
5. **第一二轮实验者偏差**：同一人设计实验、写规格、审查代码。第三轮通过自动化消除了此偏差。
6. **`forge-spec-critique` 循环性**：打分工具定义自己的成功标准然后测量——不是独立验证。

---

## 9. 设计决策

### 9.1 为什么用三个结构信号，不用模糊词密度？

早期版本用模糊词密度（计数"可能""也许""应该"）作为主指标。这不可靠——模糊语言可能表示讨好，也可能表示诚实的不确定，区分需要语义判断，规则计数做不到。三个结构信号（假设、质疑、裁剪）是**二元且结构的**：假设要么暴露要么隐藏；决策要么有替代方案要么没有；功能要么标记裁剪要么不经审视地包含。

### 9.2 为什么单次不迭代？

对批判 Gate 迭代会使其遭受设计要防止的同一种讨好漂移。第二轮倾向于"同意第一轮的发现"而非质疑。一次强制视角转换是机制；精炼不是。

### 9.3 为什么在 Multi-Stakeholder Review 之后而非之前？

Multi-Stakeholder Review 从利益相关方视角问"该不该建？"；批判 Gate 从对抗视角问"哪里搞错了？"。先跑批判为时过早——没有共识可质疑。后跑确保 Gate 挑战的是已形成的共识，这正是讨好偏见最强的地方。

### 9.4 与 Step 7 Council 的关系

0-to-1 工作流现在有三个顺序质量门：

| 门 | 时机 | 问题 | 方法 |
|----|------|------|------|
| Multi-Stakeholder Review | 文档生成前 | "该不该建？" | 4 个利益相关方视角 |
| 批判 Gate | 文档生成前（MS Review 之后） | "哪里搞错了？" | 3 个对抗信号 |
| Step 7 Council | Spec 写完后 | "Spec 是否可靠？" | 4 个质量维度 |

---

## 10. 集成

批判 Gate 已集成到 ReqForge 的 `product-spec-builder`，作为 0-to-1 工作流的可选阶段，位于 Multi-Stakeholder Review 之后、Document Generation 之前。配置：

- **0-to-1 模式**：默认开启；用户可说 "skip critique"
- **Quick 模式 / Iteration 模式**：始终跳过
- **Brownfield（`/change-manager`）**：跳过（owner 在 change proposal 中处理范围）
- **如果 MS Review 被跳过**：批判 Gate 仍然运行（独立门）

输出插入 `Product-Spec.md` 的 `## Critique Gate Summary` 部分（位于 Stakeholder Review Summary 和 Use Cases 之间），仅在 Gate 运行且产出发现时包含。

---

## 11. 开放问题

1. **真人验证**：开发者偏好是否与 LLM 评分者偏好一致？需要招募 3-5 名开发者进行盲评。
2. **跨 provider 复现**：5:0 结果在 Claude、GPT-4 或 Gemini 作为规格生成器和/或评分者时是否成立？
3. **返工测量**：能否在实际开发中跟踪迭代次数，对比有/无批判 Gate 的规格？
4. **信号可靠性**：三个结构信号（假设、质疑、裁剪）是否充分，还是存在未识别的信号？
5. **过度批判风险**：强制对抗评审是否有时产出过于保守的规格——裁剪了应留在 v1 的功能？

---

## 12. 可复现性

所有实验材料在 ReqForge 仓库中可用：

| 材料 | 位置 |
|------|------|
| 需求简述 | `forge-spec-experiment/briefs/` |
| 对照组规格（第一轮） | `forge-spec-experiment/control/` |
| 批判组规格（第一轮） | `forge-spec-experiment/experimental/` |
| 盲评结果 + 生成的规格 | `forge-spec-experiment/blind-eval/` |
| 盲评汇总数据 | `forge-spec-experiment/blind-eval/summary.json` |
| Dogfood 规格（小说应用） | `forge-spec-experiment/control/novel-app.md` + `experimental/novel-app.md` |
| 批判评分工具 | `scripts/forge-spec-critique.mjs` |
| 盲评实验工具 | `scripts/forge-spec-blind-eval.mjs` |
| 完整实验报告 | `forge-spec-experiment/result.md` |

复现盲评：

```bash
DEEPSEEK_API_KEY=xxx pnpm forge-spec-blind-eval
# 或：OPENAI_API_KEY=xxx pnpm forge-spec-blind-eval
# 或：ANTHROPIC_API_KEY=xxx pnpm forge-spec-blind-eval --use-anthropic
```

---

## 参考文献

- ReqForge 项目：https://github.com/zxpmail/ReqForge
- LLM Council 对比：`core/docs/llm-council-comparison.md`
- 产品规格构建器工作流：`core/skills/product-spec-builder/references/workflow-0-to-1.md`
- 批判 Gate 参考：`core/skills/product-spec-builder/references/critique-gate.md`