第1871篇:AI加速的需求分析——用LLM把模糊需求转化为清晰的技术规格
第1871篇:AI加速的需求分析——用LLM把模糊需求转化为清晰的技术规格
我做了十几年Java开发,见过太多项目死在需求阶段。不是技术不行,是一开始大家说的根本不是同一件事。
产品经理说"用户要一个更快的搜索",开发理解成优化SQL索引,测试理解成压测响应时间,运营理解成搜索结果更相关。三个月后上线,产品说"这不是我要的"。这场景你熟吗?
现在我有了LLM这个工具,需求分析这件事开始变得不一样。不是说AI能帮你把需求做对,而是它能帮你在早期暴露那些本来要等三个月才爆的分歧。
需求模糊的本质问题
先说说需求为什么总是模糊的。不是因为产品经理懒,而是需求天然就有三层结构:
问题在于,大多数需求文档直接从"业务目标"跳到"技术实现",把中间两层省了。然后开发按照自己理解的技术实现去做,产品按照自己脑子里的用户需求去验收,必然对不上。
LLM的价值在于:它能帮你系统性地把这四层都展开,而且速度极快。
实战:一个电商搜索需求的全流程拆解
我们拿一个真实场景练手。某电商平台产品经理提了这样一个需求:
"优化商品搜索功能,让用户能更容易找到想买的商品"
就这一句话。我见过比这更短的,也见过写了五页却同样模糊的。
第一步:用LLM做需求澄清问卷
我的做法是先让LLM生成一份结构化澄清问卷,而不是直接开会。
// 核心提示词模板(我在项目里封装成了工具类)
public class RequirementAnalysisPrompt {
public static String buildClarificationPrompt(String rawRequirement) {
return """
你是一位资深产品技术顾问,专门做需求澄清工作。
我有一个原始需求描述如下:
【%s】
请从以下维度生成结构化澄清问题清单:
1. 业务背景(为什么现在要做这个?触发事件是什么?)
2. 用户画像(哪类用户?使用频率?痛点场景?)
3. 成功标准(怎么衡量"更好"?有没有可量化指标?)
4. 边界约束(性能要求?数据量级?兼容性?)
5. 优先级(MVP是什么?哪些是加分项?)
输出格式:每个维度3-5个具体问题,问题要可以用数字/比较句回答。
""".formatted(rawRequirement);
}
}这段代码很简单,但背后的逻辑是重要的:你不是让AI替你想答案,而是让AI帮你构建问题框架。
跑完之后,你会得到类似这样的问卷:
业务背景:
- 当前搜索功能的用户满意度评分是多少?
- 有没有搜索流失率数据(搜索后无点击退出的比例)?
- 这是响应用户投诉还是主动优化?
用户画像:
- 日均搜索请求量是多少?
- 用户搜索关键词平均长度?(1-2字 vs 长句)
- 移动端/PC端比例?
成功标准:
- 搜索结果点击率目标是多少?(当前vs目标)
- 响应时间要求?(P99是多少ms以内)
- 上线后观测周期?把这份问卷给产品填,你会发现两件事:第一,他们之前根本没想过这些问题;第二,填完之后需求已经清晰了一半。
第二步:用LLM把回答转化为结构化规格
产品填了问卷回来,答案往往还是很散。比如:
"现在搜索很慢,用户老是搜不到东西,特别是搜品牌名搜不出来,我们想做语义搜索,另外搜索结果顺序也不对,热销的应该排前面"
三个诉求混在一起:性能、召回率、排序。用LLM来做结构化拆解:
@Service
public class RequirementStructureService {
private final ChatClient chatClient;
public RequirementSpecDocument structureRequirement(
String rawRequirement,
Map<String, String> clarificationAnswers) {
String prompt = buildStructurePrompt(rawRequirement, clarificationAnswers);
String response = chatClient.call(prompt);
return parseToDocument(response);
}
private String buildStructurePrompt(String req, Map<String, String> answers) {
StringBuilder sb = new StringBuilder();
sb.append("原始需求:").append(req).append("\n\n");
sb.append("澄清问答:\n");
answers.forEach((q, a) ->
sb.append("Q: ").append(q).append("\nA: ").append(a).append("\n"));
sb.append("""
\n请将以上信息整理为标准技术规格文档,包含:
## 功能需求拆解
- 将混合需求拆分为独立的功能点
- 每个功能点说明:做什么、为什么、优先级
## 非功能需求
- 性能指标(P50/P95/P99响应时间)
- 数据规模(QPS、数据量)
- 可用性要求
## 技术约束
- 现有技术栈约束
- 时间约束
## 验收标准(可测试)
- 每个功能点对应的验收条件,用Given-When-Then格式
## 风险与假设
- 需要外部确认的假设项
- 潜在技术风险
""");
return sb.toString();
}
}这里用了Spring AI的ChatClient,实际上用任何LLM客户端都行,核心在提示词结构。
输出的规格文档大概长这样(节选):
## 功能需求拆解
### FR-001:搜索性能优化
- 做什么:降低搜索接口响应时间
- 为什么:当前P99超过3秒,导致用户放弃搜索
- 优先级:P0
- 验收标准:
Given 用户发起搜索请求
When 关键词长度<=10字
Then P99响应时间<500ms,P50<100ms
### FR-002:品牌名召回增强
- 做什么:提升品牌名搜索的召回率
- 为什么:品牌名精确搜索召回率低于60%
- 优先级:P0
- 验收标准:
Given 用户搜索品牌全称
When 品牌在商品库中存在
Then 第一页至少出现3个该品牌商品
### FR-003:热销商品权重排序
- 做什么:在搜索结果中提升热销商品权重
- 为什么:相关性相近时,用户更倾向购买热销
- 优先级:P1(MVP后迭代)你看,原来一句含糊的话,被拆成了三个有验收标准的独立需求。这个转化过程,原来可能要开三次会,现在一个下午就搞定了。
第三步:自动检测需求冲突
这是我最喜欢的一步,也是传统需求分析最容易漏掉的。需求之间往往有隐性冲突,等实现的时候才发现。
@Component
public class RequirementConflictDetector {
public List<ConflictItem> detectConflicts(List<RequirementItem> requirements) {
String prompt = buildConflictDetectionPrompt(requirements);
String analysis = chatClient.call(prompt);
return parseConflicts(analysis);
}
private String buildConflictDetectionPrompt(List<RequirementItem> reqs) {
StringBuilder sb = new StringBuilder();
sb.append("以下是一组需求规格,请分析其中的潜在冲突:\n\n");
for (int i = 0; i < reqs.size(); i++) {
RequirementItem req = reqs.get(i);
sb.append(String.format("需求%d [%s]:%s\n",
i + 1, req.getId(), req.getDescription()));
sb.append("验收标准:").append(req.getAcceptanceCriteria()).append("\n\n");
}
sb.append("""
请检查以下类型的冲突:
1. 资源冲突:两个需求对同一资源有互斥要求
2. 逻辑冲突:需求A的前置条件与需求B的结果矛盾
3. 优先级冲突:同时标为P0但开发时间有限
4. 性能冲突:语义搜索增加延迟 vs 响应时间要求
输出格式:
冲突ID | 涉及需求 | 冲突类型 | 冲突描述 | 建议解决方案
""");
return sb.toString();
}
}以搜索优化为例,LLM会发现一个很典型的冲突:FR-001要求P99<500ms,FR-002和FR-003如果引入语义搜索和复杂排序,响应时间会增加。这个冲突在需求文档里写得好好的,但人工审查经常视而不见。
LLM输出的冲突报告可能是这样的:
冲突-001
涉及需求:FR-001(性能)vs FR-002(语义搜索)
冲突类型:性能冲突
冲突描述:语义向量搜索通常需要向量相似度计算,在大规模商品库
下(假设100万SKU),该操作延迟约200-800ms,与FR-001
的P99<500ms目标存在冲突
建议方案:
方案A:分层搜索架构,先关键词召回Top200,再语义重排,
控制向量计算范围
方案B:降低语义搜索的覆盖范围(仅对Top品类开启)
方案C:放宽性能目标至P99<1s,P50<300ms把这个冲突报告给产品和架构师看,他们往往会很惊讶——"这个问题原来我们没想到"。
需求稳定性评分:量化模糊度
除了结构化,我还会用LLM对需求的"稳定性"做评分。这个思路来自我踩过的坑——有些需求看起来清晰,但其实建立在很多假设上,一旦假设不成立,需求就要大改。
public class RequirementStabilityAnalyzer {
/**
* 评估需求稳定性,返回0-100分
* 分数越高,需求越稳定,越适合早期开发
*/
public StabilityScore analyze(RequirementItem requirement) {
String prompt = """
请评估以下需求的稳定性(0-100分),并给出理由:
需求描述:%s
验收标准:%s
评分维度:
- 业务逻辑明确性(0-25):能否不依赖额外信息就能实现?
- 验收标准可测性(0-25):验收标准是否可以自动化测试?
- 外部依赖风险(0-25):是否依赖第三方系统/数据/决策?
- 历史变更概率(0-25):该类型需求历史上多久改一次?
输出:JSON格式,包含total_score、各维度得分、主要风险点
""".formatted(requirement.getDescription(),
requirement.getAcceptanceCriteria());
String response = chatClient.call(prompt);
return parseStabilityScore(response);
}
}实践中,稳定性评分低于60分的需求,我会标记为"需要进一步澄清后再排期",避免开发到一半需求大改。
一个完整的需求分析Pipeline
把上面几个步骤串起来,就是我现在的需求分析流程:
这个Pipeline跑一遍大概需要2-4小时(主要是等产品填问卷),但换来的是:开发前就达成对齐,而不是上线后打脸。
踩过的坑:LLM不是万能的需求分析师
说几个真实踩过的坑,省得你走弯路:
坑一:LLM生成的规格文档太"理想化"
LLM会生成非常漂亮的Given-When-Then格式验收标准,但有些标准根本没法测。比如它可能生成"搜索结果的相关性满意度>85%"——这怎么测?需要用户调研还是A/B测试?LLM不知道你的测试资源情况。
解决方案:在提示词里明确加入约束:"验收标准必须可以通过自动化接口测试验证,不依赖人工评判"。
坑二:产品不愿意填那么多问题
我第一次生成问卷有23个问题,产品直接放弃了。后来我加了一个过滤步骤:让LLM根据需求类型,只保留最关键的5-7个问题,其他的作为"可选项"。
坑三:LLM的冲突检测有误报
LLM有时会把"互相补充"的需求误判为"冲突"。比如它可能认为"性能优化"和"功能增强"冲突,但其实可以在不同时间节点实现。
解决方案:冲突检测结果要经过人工过滤,LLM只是提供候选,不是最终裁判。
坑四:拿LLM生成的文档直接开发
这是最大的坑。LLM生成的规格文档是草稿,不是最终版。必须有资深开发或架构师过一遍,确认技术可行性。我见过一个团队直接拿AI生成的规格排期,结果里面有个需求依赖了一个他们根本没有的数据字段,白做了两周。
实际效果量化
我在两个项目里对比过用LLM辅助需求分析和传统方式的数据(样本量小,仅供参考):
| 指标 | 传统方式 | LLM辅助 |
|---|---|---|
| 需求澄清会议次数 | 3-5次 | 1-2次 |
| 需求变更率(开发中) | 约35% | 约18% |
| 需求文档完成时间 | 3-5天 | 1-2天 |
| 遗漏验收标准比例 | 约40% | 约12% |
这些数字不是说LLM多神奇,而是说有个结构化框架本身就能减少遗漏,LLM帮你把框架变成了低成本可执行的动作。
扩展:把需求分析工具做成内部平台
如果你的团队需求量大,可以考虑把上面的能力封装成一个轻量内部工具:
@RestController
@RequestMapping("/api/requirement-analysis")
public class RequirementAnalysisController {
@Autowired
private RequirementAnalysisService analysisService;
@PostMapping("/clarify")
public ResponseEntity<ClarificationQuestionnaire> generateClarification(
@RequestBody @Valid RawRequirementRequest request) {
ClarificationQuestionnaire questionnaire =
analysisService.generateClarificationQuestions(
request.getRequirement(),
request.getProjectType(),
request.getTopQuestionCount() // 默认7个
);
return ResponseEntity.ok(questionnaire);
}
@PostMapping("/structure")
public ResponseEntity<RequirementSpecDocument> structureRequirement(
@RequestBody @Valid StructureRequest request) {
RequirementSpecDocument doc = analysisService.structure(
request.getRawRequirement(),
request.getClarificationAnswers()
);
return ResponseEntity.ok(doc);
}
@PostMapping("/detect-conflicts")
public ResponseEntity<ConflictReport> detectConflicts(
@RequestBody @Valid ConflictDetectionRequest request) {
ConflictReport report = analysisService.detectConflicts(
request.getRequirements()
);
return ResponseEntity.ok(report);
}
@PostMapping("/stability-score")
public ResponseEntity<StabilityScoreReport> scoreStability(
@RequestBody @Valid StabilityRequest request) {
StabilityScoreReport report = analysisService.analyzeStability(
request.getRequirements()
);
return ResponseEntity.ok(report);
}
}加一个简单的前端,产品经理就能自助完成需求澄清,不需要每次都拉着技术团队开会。
写在最后
需求分析这件事,本质上是信息的结构化和对齐。LLM在这里的价值不是替代人的判断,而是提供一个低成本的结构化框架,让遗漏和冲突在早期就浮出水面。
我认为未来的需求工程会变成这样:产品提出方向性意图,LLM帮助展开和结构化,人负责决策和对齐。这个分工比"所有工作都是人写文档"或"全交给AI"都要高效得多。
当然,LLM生成的任何东西都必须有人审核。这一点请务必记住。
