第1799篇:技术选型的AI辅助——建立结构化评估框架而不是依赖直觉
第1799篇:技术选型的AI辅助——建立结构化评估框架而不是依赖直觉
「我们用Redis吧,我比较熟。」
「这个项目上Kafka,大厂都在用。」
「用PostgreSQL,不用MySQL,我觉得PostgreSQL更好。」
技术选型,是工程团队最频繁面临的决策之一,也是最容易拍脑袋的决策之一。我见过太多团队的技术选型过程:技术负责人或某个有话语权的工程师凭自己的偏好和经验拍板,其他人默默接受,然后项目做到一半发现选的技术不合适,换也换不了,只能硬撑。
更糟糕的是,当选型出了问题,没有人记得当初为什么选这个。「反正就这样了,别动它。」
AI辅助技术选型,不是让AI替你选,而是帮你把选型过程结构化、可记录、可复盘。
技术选型的典型问题
在讲解决方案之前,先诊断问题:
问题一:评估维度不完整
大多数团队只想到几个显眼的维度:性能、易用性、社区活跃度。但忽略了:学习成本、团队现有技能匹配度、供应商锁定风险、运维复杂度、在当前团队规模和系统规模下的适用性。
问题二:缺乏约束条件
「哪个消息队列最好」这个问题是没有答案的。「对于3人团队、日消息量100万、不要求严格顺序、运维能力有限的场景,哪个消息队列最适合」才有明确答案。不带约束条件的选型讨论,容易变成「互联网面经背诵大会」。
问题三:没有决策记录
6个月后,新来的同事问「当初为什么选这个」,没人能说清楚。这导致后来者无法正确评估「是否需要换」,也没有经验积累。
问题四:个人偏好遮蔽系统性分析
「我就是喜欢这个技术」是一个合理的感受,但不是一个合理的决策理由。个人偏好应该是加分项,不应该是决定项。
结构化选型框架
我设计了一套结构化选型框架,分4步:
第一步:需求与约束的结构化收集
@Service
public class TechSelectionFramework {
private final ClaudeApiClient claudeClient;
public SelectionContext buildContext(TechSelectionRequest request) {
// 让AI帮助补全需求分析
String prompt = String.format("""
我们在为以下场景做技术选型,请帮我完善需求和约束分析。
场景描述:%s
技术类别:%s(比如:消息队列/缓存/数据库/API网关等)
初步的已知约束:
%s
请帮我分析:
## 1. 功能需求清单(必须满足的)
基于场景描述,列出技术方案必须支持的功能特性
## 2. 非功能需求(量化的)
- 性能要求:预估TPS/QPS,P99延迟要求
- 可用性:SLA要求
- 数据量:当前+未来1年的预估规模
- 并发:峰值并发请求数
## 3. 约束条件(会直接排除某些选项的)
- 团队技能:团队对哪些技术栈有经验?
- 运维能力:团队能维护多复杂的系统?
- 成本:云资源预算或开源授权费用限制?
- 合规:数据驻留要求、安全合规要求?
- 生态:需要与现有系统集成的要求?
## 4. 可能被遗忘的考量点
针对这类技术选型,有哪些常被忽略但重要的考量点?
对每个分析结果,说明为什么它重要。
""",
request.getScenarioDescription(),
request.getTechCategory(),
formatKnownConstraints(request.getKnownConstraints()));
String analysis = claudeClient.complete(prompt);
SelectionContext context = new SelectionContext();
context.setScenario(request.getScenarioDescription());
context.setTechCategory(request.getTechCategory());
context.setAiEnrichedAnalysis(analysis);
context.setKnownConstraints(request.getKnownConstraints());
return context;
}
}第二步:候选方案生成与过滤
@Service
public class CandidateEvaluator {
private final ClaudeApiClient claudeClient;
public List<TechCandidate> generateAndFilterCandidates(SelectionContext context) {
// 生成候选列表
String candidatePrompt = String.format("""
基于以下需求和约束,生成技术候选方案列表。
需求分析:
%s
要求:
1. 只列出真正适合这个场景的选项(不是所有同类技术)
2. 包含主流选项,也可以包含1-2个「黑马」选项
3. 对每个候选,简要说明它的核心优势和主要局限
4. 如果某个明显不适合的技术在行业内很流行,也列出来并解释为什么在这个场景下不推荐
返回JSON格式:
[
{
"name": "技术名称",
"version": "推荐版本",
"category": "子类别(如开源/商业/云托管)",
"core_strengths": ["核心优势列表"],
"main_limitations": ["主要局限"],
"why_included": "为什么包含在候选列表",
"initial_fit_score": 0-10
}
]
""", context.getAiEnrichedAnalysis());
String candidatesJson = claudeClient.complete(candidatePrompt);
List<TechCandidate> candidates = parseCandidates(candidatesJson);
// 过滤:排除不满足硬性约束的候选
return candidates.stream()
.filter(c -> !isHardConstraintViolation(c, context.getKnownConstraints()))
.collect(Collectors.toList());
}
public ScoringMatrix buildScoringMatrix(
List<TechCandidate> candidates,
SelectionContext context) {
// 确定评估维度和权重
String weightPrompt = String.format("""
为以下技术选型场景,确定评估维度和权重。
场景:%s
候选技术:%s
请生成评估维度,注意:
1. 维度要具体可评估,不要「好用」这种模糊维度
2. 权重要基于场景实际重要性,不要平均分配
3. 权重合计100
4. 最多8个维度,否则评估矩阵太复杂
返回JSON:
[
{
"dimension": "维度名称",
"description": "具体说明如何评分这个维度",
"weight": 权重,
"scoring_guide": {
"1-3": "低分描述",
"4-6": "中分描述",
"7-9": "高分描述",
"10": "满分描述"
}
}
]
""",
context.getAiEnrichedAnalysis(),
candidates.stream().map(TechCandidate::getName).collect(Collectors.joining(", ")));
String dimensionsJson = claudeClient.complete(weightPrompt);
List<EvaluationDimension> dimensions = parseDimensions(dimensionsJson);
return new ScoringMatrix(candidates, dimensions);
}
public ScoredMatrix scoreMatrix(
ScoringMatrix matrix, SelectionContext context) {
// 对每个候选技术在每个维度上评分
for (TechCandidate candidate : matrix.getCandidates()) {
String scoringPrompt = String.format("""
请对以下技术在指定评估维度上评分。
技术:%s %s
评估场景:
%s
请对以下维度评分(1-10分),说明理由:
%s
返回JSON:
[
{
"dimension": "维度名",
"score": 分数,
"rationale": "评分理由(具体说明,不要泛泛而谈)",
"evidence": "支持评分的具体证据或案例",
"caveats": "需要注意的条件或例外情况"
}
]
""",
candidate.getName(),
candidate.getVersion(),
context.getAiEnrichedAnalysis(),
formatDimensionsForScoring(matrix.getDimensions()));
String scoresJson = claudeClient.complete(scoringPrompt);
List<DimensionScore> scores = parseScores(scoresJson);
for (DimensionScore score : scores) {
matrix.setScore(candidate.getName(), score.getDimension(), score);
}
}
return new ScoredMatrix(matrix);
}
}第三步:深度比较分析
@Service
public class DeepComparisonAnalyzer {
private final ClaudeApiClient claudeClient;
public ComparisonReport generateDeepComparison(
ScoredMatrix scoredMatrix,
SelectionContext context) {
// 找出评分最高的前3个候选
List<TechCandidate> topCandidates = scoredMatrix.getTopN(3);
// 生成两两对比分析
List<PairwiseComparison> comparisons = new ArrayList<>();
for (int i = 0; i < topCandidates.size(); i++) {
for (int j = i + 1; j < topCandidates.size(); j++) {
PairwiseComparison comparison = compareTwo(
topCandidates.get(i),
topCandidates.get(j),
context,
scoredMatrix);
comparisons.add(comparison);
}
}
// 生成综合建议
String recommendation = generateRecommendation(topCandidates, comparisons, context);
return new ComparisonReport(topCandidates, comparisons, recommendation);
}
private PairwiseComparison compareTwo(
TechCandidate a, TechCandidate b,
SelectionContext context,
ScoredMatrix matrix) {
String prompt = String.format("""
深度对比以下两个技术选项,聚焦在我们的具体场景中的差异。
场景:
%s
技术A:%s(评分:%.1f)
技术B:%s(评分:%.1f)
请分析:
### 核心差异点
在这个具体场景中,两者最本质的差异是什么?(不要列通用特性对比)
### A优于B的场景
在什么情况下A是更好的选择?(要具体)
### B优于A的场景
在什么情况下B是更好的选择?(要具体)
### 迁移成本分析
如果先选了A,后来发现需要换成B,成本是多少?反之呢?
### 常被忽略的差异
工程师在对比这两个技术时,容易忽略的重要差异点
""",
context.getAiEnrichedAnalysis(),
a.getName(), matrix.getWeightedScore(a.getName()),
b.getName(), matrix.getWeightedScore(b.getName()));
String analysis = claudeClient.complete(prompt);
return new PairwiseComparison(a, b, analysis);
}
}第四步:自动生成ADR文档
选型完成后,自动生成架构决策记录:
@Service
public class ADRGenerator {
private final ClaudeApiClient claudeClient;
public String generateADR(
SelectionContext context,
ScoredMatrix matrix,
ComparisonReport comparison,
TechCandidate finalChoice,
String decisionRationale) {
String prompt = String.format("""
基于以下技术选型过程,生成一份标准的ADR(架构决策记录)文档。
选型场景:%s
评估过的候选技术及评分:
%s
最终选择:%s
决策理由(工程师提供):
%s
对比分析摘要:
%s
请生成Markdown格式的ADR,包含:
# ADR-XXX: [简短标题]
**状态**:已通过
**日期**:[今天日期]
**决策者**:[预留]
## 背景
[为什么需要做这个技术选型,业务背景和技术背景]
## 决策
[选择了什么,用一句话说清楚]
## 考虑的选项
[评估过的所有选项,简要说明各自的优劣]
## 决策理由
[详细说明为什么选这个,关键的权衡点]
## 后果
**正面影响**:
- [列出选择这个技术带来的好处]
**负面影响/风险**:
- [列出这个选择的局限和风险]
**需要采取的行动**:
- [为了成功实施这个技术,需要做哪些准备工作]
## 复盘触发条件
[在什么情况下应该重新评估这个决策]
""",
context.getScenario(),
formatScoredMatrix(matrix),
finalChoice.getName(),
decisionRationale,
comparison.getSummary());
return claudeClient.complete(prompt);
}
}一个完整的选型案例演示
让我用一个真实场景走一遍这套流程。
场景:为一个B2B SaaS产品选择消息队列。场景特点:
- 月活企业客户500家,每家日消息量约1万条,总量500万/天
- 主要用途:订单状态变更通知、系统间数据同步
- 团队:5名后端工程师,有RabbitMQ经验,无Kafka运维经验
- 云平台:AWS
- 每条消息至少一次投递,不需要严格顺序
AI评估矩阵(精简版):
| 维度 | 权重 | RabbitMQ | Kafka | AWS SQS | Redis Streams |
|---|---|---|---|---|---|
| 功能满足度 | 25% | 9 | 8 | 7 | 7 |
| 运维复杂度(低分=复杂) | 20% | 7 | 3 | 10 | 6 |
| 团队熟悉度 | 20% | 9 | 2 | 5 | 4 |
| 当前规模适配性 | 15% | 8 | 6 | 9 | 8 |
| 未来扩展性 | 10% | 6 | 10 | 7 | 5 |
| 成本 | 10% | 7 | 5 | 8 | 8 |
| 加权总分 | 7.9 | 5.1 | 7.7 | 6.4 |
AI的关键分析:
RabbitMQ vs AWS SQS(最接近的竞争):
评分很接近,但决策方向不同。选RabbitMQ的理由是:团队已有经验,功能更丰富(支持路由、优先级队列、延迟消息),适合复杂的消息路由场景。选AWS SQS的理由是:零运维,AWS原生集成,按量付费。
这个场景的关键权衡是:你更愿意花钱(SQS按量),还是花运维精力(RabbitMQ)?
补充建议:考虑 AWS AmazonMQ(托管版RabbitMQ),结合了两者的优点——团队熟悉的RabbitMQ接口 + AWS托管运维。这个选项在候选列表中没有出现,但最符合你的约束条件。
这个「补充建议」是AI真正有价值的地方——它发现了一个我们没想到的选项,并说明了理由。
最终决策:AWS AmazonMQ(托管RabbitMQ)。决策耗时从以前的「开两次会,最后技术负责人拍板」,变成了「2小时完成系统性评估,有完整记录」。
让评估过程更可信的细节
几个让这套方法更有效的小技巧:
加入「魔鬼代言人」步骤
在生成推荐之后,专门让AI扮演反对者:
"现在请你用最强的理由反对上面的推荐结果,找出这个结论的漏洞"这一步经常能发现被忽略的风险。
明确标注不确定性
在Prompt中加入:
"对于你不确定的信息,明确标注'需要验证',不要假装确定"AI会诚实地告诉你哪些分析需要进一步POC验证。
记录异见
如果团队里有人不同意最终选择,把他的理由也写进ADR的「考虑的选项」里。6个月后可能会发现他是对的。
技术选型没有标准答案,但可以有更好的决策过程。结构化的评估,让「为什么选这个」有了可追溯的答案,让未来的技术演进有了更扎实的起点。
