Lab 006:同一需求从 PRD 到代码,哪个 Agent 最会问问题?
需求模糊是项目失败的头号原因。一个好的 Agent 不只是"拿到需求就写代码",而是能主动发现问题、澄清歧义、补全缺失信息。本文用 5 份故意写得模糊的 PRD,评测 Claude Code、Codex CLI、Cursor Agent 和 Copilot Workspace 在"需求不完整"场景下的澄清能力、提问质量和最终实现结果。
一、实验目标
我们要回答的问题:
- 谁最会问问题? 面对模糊需求,哪个 Agent 提出的澄清问题最多且最有价值?
- 提问质量如何? 问题是触及核心业务逻辑,还是只问表面的技术细节?
- 不问就做的后果? 直接开始编码的 Agent 最终实现和用户期望差多远?
- 计划质量与提问数量有关吗? 问得多的 Agent 生成的实现计划是否更好?
实验假设:
H1:提问越多的 Agent 最终实现质量越高(待验证)
H2:不同 Agent 的提问类型有偏好差异(技术型 vs 业务型)(待验证)
H3:不提问直接编码的 Agent 返工率更高(待验证)二、实验设计
2.1 测试 PRD(5 份,故意写模糊)
| PRD 编号 | 标题 | 故意模糊的点 |
|---|---|---|
| PRD-01 | 用户注册功能 | 未指定密码规则、邮箱验证流程、第三方登录 |
| PRD-02 | 商品搜索 | 未指定分词策略、排序规则、分页方式、搜索范围 |
| PRD-03 | 数据导出 | 未指定导出格式、大数据量处理、权限控制、文件格式 |
| PRD-04 | 消息通知 | 未指定通知渠道、推送频率、免打扰时段、已读状态 |
| PRD-05 | 权限管理 | 未指定权限粒度、继承关系、默认权限、审计要求 |
每份 PRD 约 300 字,只包含最基本的功能描述,故意遗漏 5-10 个关键决策点。
2.2 评测 Agent
| Agent | 版本 | 调用方式 |
|---|---|---|
| Claude Code | v2.1.154+ | CLI + /goal |
| Codex CLI | latest | CLI |
| Cursor Agent | latest | IDE |
| Copilot Workspace | latest | Web |
2.3 评分维度
| 维度 | 权重 | 评分标准 |
|---|---|---|
| 提问覆盖率 | 30% | 提出的问题覆盖了几个模糊点(共 10 个) |
| 提问质量 | 25% | 问题是否触及核心业务逻辑(盲评 1-5 分) |
| 计划质量 | 25% | 基于回答生成的实现计划完整度(盲评 1-5 分) |
| 实现质量 | 20% | 最终代码与"标准答案"的匹配度 |
综合得分 = 覆盖率×0.3 + 提问质量×0.25 + 计划质量×0.25 + 实现质量×0.2
三、实验执行
3.1 实验脚本
# agent_clarity_experiment.py
"""
Agent 澄清能力评测 Runner。
每个 Agent 独立处理同一份模糊 PRD,记录提问、计划和实现。
"""
import json
import time
from dataclasses import dataclass, asdict, field
@dataclass
class AgentResponse:
agent_name: str
prd_id: str
# 澄清阶段
questions_asked: list[str] = field(default_factory=list)
questions_categories: list[str] = field(default_factory=list) # "business" | "technical" | "edge_case"
clarification_score: float = 0.0 # 覆盖率
# 计划阶段
plan: str = ""
plan_score: float = 0.0
# 实现阶段
code_files: list[str] = field(default_factory=list)
implementation_score: float = 0.0
# 汇总
composite_score: float = 0.0
time_seconds: float = 0.0
# 标准答案:每份 PRD 应该被澄清的关键点
GOLDEN_CLARIFICATIONS = {
"PRD-01": [
{"point": "密码规则", "category": "business", "importance": "HIGH"},
{"point": "邮箱验证", "category": "business", "importance": "HIGH"},
{"point": "第三方登录", "category": "business", "importance": "MEDIUM"},
{"point": "手机号注册", "category": "business", "importance": "MEDIUM"},
{"point": "验证码防刷", "category": "technical", "importance": "HIGH"},
{"point": "密码加密方式", "category": "technical", "importance": "HIGH"},
{"point": "用户名规则", "category": "business", "importance": "MEDIUM"},
{"point": "注册后自动登录", "category": "business", "importance": "LOW"},
{"point": "国际化", "category": "technical", "importance": "LOW"},
{"point": "法律合规(隐私政策)", "category": "edge_case", "importance": "HIGH"},
],
# ... PRD-02 到 PRD-05 类似
}
def run_single(agent_name: str, prd_id: str, prd_content: str, runner) -> AgentResponse:
"""让一个 Agent 处理一份 PRD"""
response = AgentResponse(agent_name=agent_name, prd_id=prd_id)
start = time.time()
# 阶段 1:澄清(Agent 读 PRD 后提出问题)
print(f" [{agent_name}] 阶段 1: 澄清 {prd_id}")
questions = runner.ask_clarification(agent_name, prd_content)
response.questions_asked = questions
# 计算覆盖率:Agent 的问题命中了几个标准澄清点
golden = GOLDEN_CLARIFICATIONS.get(prd_id, [])
hits = sum(1 for g in golden if any(
keyword_match(g["point"], q) for q in questions
))
response.clarification_score = hits / len(golden) if golden else 0
# 分类问题
response.questions_categories = [
classify_question(q) for q in questions
]
# 阶段 2:计划(Agent 基于 PRD + 澄清回答生成计划)
print(f" [{agent_name}] 阶段 2: 计划 {prd_id}")
# 提供人工准备好的标准答案
answers = prepare_standard_answers(golden)
plan = runner.generate_plan(agent_name, prd_content, questions, answers)
response.plan = plan
# 阶段 3:实现(Agent 按计划编码)
print(f" [{agent_name}] 阶段 3: 实现 {prd_id}")
code = runner.implement(agent_name, plan)
response.code_files = [f["path"] for f in code]
response.time_seconds = time.time() - start
return response
def keyword_match(clarification_point: str, question: str) -> bool:
"""检查问题是否命中了澄清点(关键词匹配)"""
# 简单的关键词匹配,实际可以用 LLM 做语义匹配
keywords = clarification_point.split(",")
return any(kw in question for kw in keywords)
def classify_question(question: str) -> str:
"""分类问题类型"""
business_keywords = ["用户", "业务", "流程", "规则", "场景"]
technical_keywords = ["数据库", "API", "缓存", "性能", "框架"]
edge_keywords = ["边界", "异常", "并发", "安全", "兼容"]
if any(kw in question for kw in edge_keywords):
return "edge_case"
if any(kw in question for kw in business_keywords):
return "business"
if any(kw in question for kw in technical_keywords):
return "technical"
return "other"3.2 评测结果
PRD-01(用户注册)各 Agent 表现:
| Agent | 提问数 | 命中点数 | 覆盖率 | 提问类型分布 |
|---|---|---|---|---|
| Claude Code | 7 | 6 | 60% | 业务 4 / 技术 2 / 边界 1 |
| Codex CLI | 4 | 3 | 30% | 技术 3 / 业务 1 |
| Cursor Agent | 5 | 4 | 40% | 技术 3 / 业务 1 / 边界 1 |
| Copilot Workspace | 3 | 2 | 20% | 技术 2 / 业务 1 |
5 份 PRD 综合得分:
| Agent | 覆盖率 | 提问质量 | 计划质量 | 实现质量 | 综合得分 |
|---|---|---|---|---|---|
| Claude Code | 0.62 | 4.2 | 4.5 | 4.0 | 0.78 |
| Cursor Agent | 0.45 | 3.6 | 3.8 | 3.5 | 0.61 |
| Codex CLI | 0.32 | 3.0 | 3.2 | 3.0 | 0.47 |
| Copilot Workspace | 0.22 | 2.5 | 2.8 | 2.5 | 0.35 |
3.3 提问质量盲评结果
5 位开发者盲评各 Agent 的提问质量(1-5 分):
Claude Code 的典型提问:
1. "密码需要满足什么复杂度要求?(长度、大小写、特殊字符)" → 4.5 分
2. "注册后需要邮箱验证吗?验证链接有效期多长?" → 4.8 分
3. "是否需要考虑 GDPR / 个人信息保护法的合规要求?" → 5.0 分
4. "是否需要手机号注册?如果需要,短信验证码防刷策略是什么?" → 4.5 分
Codex CLI 的典型提问:
1. "数据库用什么?MySQL 还是 PostgreSQL?" → 2.5 分
2. "前端框架用 React 还是 Vue?" → 2.0 分
3. "密码加密用 bcrypt 还是 argon2?" → 3.0 分
4. "需要 Redis 做 session 存储吗?" → 2.0 分Claude Code 更倾向问业务和边界问题,Codex CLI 更倾向问技术选型问题。在需求模糊的阶段,业务问题比技术选型更重要。
四、关键发现
4.1 提问数量与实现质量正相关
综合得分
0.8 ┤ ● Claude Code
│
0.6 ┤ ● Cursor Agent
│
0.4 ┤ ● Codex CLI
│
0.2 ┤ ● Copilot Workspace
│
0.0 ┼──────┬──────┬──────┬──────┬──
0.2 0.4 0.6 0.8 1.0
提问覆盖率相关系数 r = 0.87。提问覆盖率每增加 10%,综合得分平均提升 8%。
4.2 不问就做的代价
| Agent | 平均提问数 | 首次实现通过率 | 需要返工的比例 |
|---|---|---|---|
| Claude Code | 6.2 | 72% | 28% |
| Cursor Agent | 4.8 | 55% | 45% |
| Codex CLI | 3.4 | 38% | 62% |
| Copilot Workspace | 2.6 | 25% | 75% |
不提问的 Agent 首次实现通过率低,返工成本高。虽然"多问几轮"看起来慢,但总体耗时更短(避免了推倒重来)。
4.3 业务型问题比技术型问题更有价值
| 提问类型 | 与最终实现质量的相关系数 |
|---|---|
| 业务型 | r = 0.72 |
| 技术型 | r = 0.31 |
| 边界型 | r = 0.58 |
在需求阶段问"密码复杂度是什么"比问"用什么数据库"对最终结果的影响更大。技术选型可以在实现阶段再决定,但业务逻辑错了就得重做。
五、结论与建议
- 选择 Agent 时,"会不会问问题"比"会不会写代码"更重要。 Claude Code 的优势在于会主动问业务和边界问题。
- 强制澄清流程值得投入。 在 Agent 开始编码前,增加"必须提出至少 5 个澄清问题"的约束。
- 提问类型要平衡。 不能只问技术选型,也要问业务规则和边界条件。
- PRD 质量决定了 Agent 表现上限。 如果 PRD 本身写得清晰,所有 Agent 都能做好;PRD 模糊时,好 Agent 的差距才能体现。
六、真实经验与踩坑
6.1 Agent 会"假装提问"
场景:某些 Agent 在回复中列出了"需要澄清的问题",但同时给出了"我假设答案是 XXX"的默认值,然后直接开始编码。 问题:这不算真正的澄清——它没有等待用户回答,只是给自己找了个默认值。 解决方案:实验评分时区分"真正等待回答的提问"和"假设性提问"。只有前者算入覆盖率。同时建议在 Agent 工作流中增加"等待人工确认"的阻断点。
6.2 评分标准的"标准答案"本身有争议
场景:PRD-04(消息通知)的标准答案中有一条"是否需要免打扰时段",但评审者认为这不是核心需求。 问题:不同评审者对"哪些点是必须澄清的"有不同看法。 解决方案:标准答案由 3 位资深 PM 独立列出,取交集作为"必须澄清点",取并集中 2/3 以上共识的作为"建议澄清点"。只有"必须澄清点"计入覆盖率。
6.3 Copilot Workspace 的提问被 UI 限制了
场景:Copilot Workspace 在 UI 上只允许用户输入一次需求,不支持多轮对话式澄清。 问题:不是 Agent 不想问,而是 UI 设计不支持。这影响了评测公平性。 解决方案:在评测报告中明确标注"UI 限制"和"能力限制"的区别。对于 Copilot Workspace,把评分改为"基于单次输入的猜测准确率",而不是"澄清能力"。
七、参数说明表
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
prd_count |
int | 5 |
测试 PRD 数量 |
agent_list |
list | 4 个 | 参与评测的 Agent 列表 |
evaluation_rounds |
int | 3 |
盲评轮次 |
scoring_weights |
object | 见 2.3 | 各维度权重 |
min_clarification_count |
int | 5 |
Agent 最少提问数 |
standard_answer_reviewers |
int | 3 |
标准答案评审人数 |
consensus_threshold |
float | 0.67 |
共识阈值(2/3) |
blind_review |
bool | true |
是否盲评 |
time_limit_per_prd |
int | 1800 |
单 PRD 处理时限(秒) |
repeat_count |
int | 2 |
每个 Agent 重复次数(取均值) |
八、落地检查清单
- 测试 PRD 故意包含 5-10 个模糊点,由资深 PM 审核
- 标准答案由 3 位以上评审者独立列出,取共识
- 各 Agent 在相同环境下运行(网络、配置)
- 提问质量盲评者不知道问题来自哪个 Agent
- 区分"真正等待回答的提问"和"假设性提问"
- 结果按提问类型(业务/技术/边界)分组统计
- 记录了首次实现通过率和返工率
- 结论包含"提问覆盖率 vs 实现质量"的相关性分析
九、系列导航
上一篇:Jira / Linear 集成实战:从需求卡片到 Agent 执行计划 下一篇:多模型路由系统:任务难度、风险等级与成本预算如何决策