技术评审不求人:AI大模型解析架构图精准排雷

AI辅助技术方案评审:;从架构图解析到风险识别的智能分析

「这个方案你也帮我看一下」——技术 Leader 每天平均收到 5~8 份待评审方案,;真正能逐行看完的不到 3 份。AI 辅助评审不是要替代人的判断,;而是把人的精力聚焦在「AI 发现的可疑点上」。

一、C4 模型:;让架构图可被机器解析

AI 要理解架构图,;第一步是让架构图变成结构化数据。手绘的白板图、Visio 的方框箭头——这些对 AI 来说就是像素矩阵,;我们需要的是
可解析的架构描述语言

C4 模型(Context → Container → Component → Code)是 Simon Brown 提出的架构可视化方法,;它的四级抽象恰好对应了从「系统全景」到「代码实现」的渐进式细化。在 AI 辅助评审场景中,;我们主要使用 C1~C3 级别:;

graph TD
    subgraph C1["C1: 系统上下文图 (System Context)"]
        User["用户"] --> System["电商平台"]
        System --> Payment["支付网关"]
        System --> Logistics["物流系统"]
    end

    subgraph C2["C2: 容器图 (Container Diagram)"]
        WebApp["Web 应用"] --> APIGW["API 网关"]
        APIGW --> OrderSvc["订单服务"]
        APIGW --> ProductSvc["商品服务"]
        OrderSvc --> DB[(MySQL)]
        ProductSvc --> Cache[(Redis)]
    end

    subgraph C3["C3: 组件图 (Component Diagram)"]
        OrderSvc --> CreateOrder["订单创建组件"]
        OrderSvc --> PayCallback["支付回调组件"]
        OrderSvc --> OrderQuery["订单查询组件"]
        CreateOrder --> MQ["消息队列\n(异步通知)"]
    end

    style C1 fill:#cfc,stroke:#333
    style C2 fill:#fc6,stroke:#333
    style C3 fill:#f96,stroke:#333

对于 AI 解析,;我们使用
Structurizr DSL
(C4 模型的代码化描述)作为输入格式。它本质上是 YAML 或 JSON 描述的架构拓扑图,;每一条边都带有了明确的语义:;

# C4 模型的结构化描述 —— 可直接被 AI 解析
model:
  people:
    - id: user
      name: 用户
      description: 终端消费者
  softwareSystems:
    - id: ecommerce
      name: 电商平台
      containers:
        - id: api-gateway
          name: API 网关
          technology: Spring Cloud Gateway
        - id: order-service
          name: 订单服务
          technology: Spring Boot 3.2 + MyBatis
  relationships:
    - source: user
      target: api-gateway
      protocol: HTTPS
      description: 用户请求
    - source: api-gateway
      target: order-service
      protocol: gRPC
      description: 订单请求路由
    - source: order-service
      target: mysql-orders
      protocol: JDBC
      description: 订单持久化
      tags: [critical, persistent]

二、AI 解析架构图的三个层次

将结构化架构描述喂给 LLM 后,;AI 的分析分为三个递增层次:;

第一层:;拓扑解析
—— 识别组件、连接关系、协议类型。这是结构化数据可以直接回答的问题,;不需要 AI。但 AI 可以自动生成拓扑摘要:;「本方案包含 8 个微服务、3 个数据库实例、2 个消息队列 Topic,;服务间共 15 条依赖关系。」

第二层:;模式匹配
—— 将当前架构与已知的反模式库进行对比。这是一个典型的模式识别任务,;LLM 对此非常擅长:;

"""
架构反模式检测引擎。
将 C4 结构化描述输入 LLM,;匹配已知风险模式库。
"""
from dataclasses import dataclass, field
from typing import List, Optional
from enum import Enum


class RiskSeverity(Enum):
    CRITICAL = "critical"   # 必须修复,;否则生产事故
    HIGH = "high"           # 强烈建议修复
    MEDIUM = "medium"       # 建议修复
    LOW = "low"             # 可选优化


@dataclass
class RiskFinding:
    """单条风险发现"""
    severity: RiskSeverity
    pattern: str               # 匹配到的反模式名称
    description: str           # 人类可读的风险描述
    affected_components: List[str]  # 受影响的组件
    suggestion: str            # 修复建议
    references: List[str] = field(default_factory=list)  # 参考文档链接


# 预定义的反模式库 —— 可通过 LLM 持续扩展
ANTI_PATTERN_LIBRARY = [
    {
        "id": "SINGLE_POINT_OF_FAILURE",
        "name": "单点故障",
        "severity": RiskSeverity.CRITICAL,
        "pattern_desc": "关键路径上有且仅有一个服务实例、数据库实例或网络链路",
        "prompt_for_llm": """
        在以下架构中,;是否存在单点故障风险?请列出所有「如果该组件挂掉,;
        整个系统将不可用」的组件或连接。
        """,
        "fix_suggestion": "增加冗余实例 + 健康检查 + 自动故障转移",
    },
    {
        "id": "CIRCULAR_DEPENDENCY",
        "name": "循环依赖",
        "severity": RiskSeverity.HIGH,
        "pattern_desc": "服务 A 调用服务 B,;服务 B 又(直接或间接)调用服务 A",
        "prompt_for_llm": """
        分析架构中的所有依赖关系,;找出循环依赖链路(A→B→C→A 或 A→B→A)。
        如果一个微服务的启动或故障会影响另一个形成循环的服务,;请标注。
        """,
        "fix_suggestion": "通过事件驱动解耦,;或引入中间层打破循环",
    },
    {
        "id": "MISSING_CIRCUIT_BREAKER",
        "name": "缺少熔断保护",
        "severity": RiskSeverity.HIGH,
        "pattern_desc": "服务间同步调用链路上未标注熔断/降级机制",
        "prompt_for_llm": """
        检查所有服务间同步调用(特别是跨网络边界的调用),;
        是否在描述中提及了熔断、超时、重试、降级中的至少一种保护机制。
        未提及的标注为风险点。
        """,
        "fix_suggestion": "添加 Resilience4j / Sentinel 熔断配置",
    },
    {
        "id": "DATABASE_AS_INTEGRATION",
        "name": "数据库反模式——共享数据库集成",
        "severity": RiskSeverity.MEDIUM,
        "pattern_desc": "多个微服务直连同一个数据库/表,;绕过服务接口",
        "prompt_for_llm": """
        检查是否有多个服务连接到同一个数据库 schema 或表。
        如果存在,;这破坏了微服务的数据自治原则。
        """,
        "fix_suggestion": "通过 API 暴露数据访问,;逐步拆分共享表为独立 schema",
    },
    {
        "id": "CHATSY_SERVICES",
        "name": "过度微服务化(Chatty Services)",
        "severity": RiskSeverity.MEDIUM,
        "pattern_desc": "完成一个业务操作需要 5+ 个服务间的链式同步调用",
        "prompt_for_llm": """
        分析每个请求路径上涉及的同步调用数量。
        标注所有超过 5 跳的调用链——它们存在延迟放大和故障域扩大的风险。
        """,
        "fix_suggestion": "合并高频协作的服务,;或引入聚合层减少调用跳数",
    },
]


class ArchitectureReviewer:
    """基于 LLM 的架构方案评审引擎"""

    def __init__(self, llm_client):
        self.llm = llm_client
        self.findings: List[RiskFinding] = []

    def review(self, c4_model: dict) -> List[RiskFinding]:
        """对 C4 结构化模型执行全量风险检测"""
        self.findings.clear()

        for pattern in ANTI_PATTERN_LIBRARY:
            try:
                findings = self._detect_pattern(c4_model, pattern)
                self.findings.extend(findings)
            except Exception as e:
                # 单个模式检测失败不影响其他检测
                # logger.warning("Pattern detection failed for {}: {}", pattern["id"], e)
                pass

        # 按严重程度排序:;CRITICAL → HIGH → MEDIUM → LOW
        self.findings.sort(key=lambda f: (
            [RiskSeverity.CRITICAL, RiskSeverity.HIGH,
             RiskSeverity.MEDIUM, RiskSeverity.LOW].index(f.severity)
        ))

        return self.findings

    def _detect_pattern(
        self, c4_model: dict, pattern: dict
    ) -> List[RiskFinding]:
        """调用 LLM 检测单个反模式"""
        system_prompt = """
        你是一位资深后端架构师。请根据给定的架构 C4 模型描述,;
        检测是否存在指定反模式。只列出确认存在的风险,;不要猜测。
        对于每个风险,;给出受影响的组件名称和具体的修复建议。
        """

        user_prompt = f"""
        ## 反模式:;{pattern['name']}
        ## 描述:;{pattern['pattern_desc']}

        {pattern['prompt_for_llm']}

        ## 架构 C4 模型:;
        ```json
        {json.dumps(c4_model, ensure_ascii=False, indent=2)}
        ```

        请以 JSON 数组格式输出检测结果,;每项包含:;
        - is_found: bool
        - affected_components: string[]
        - description: string
        - suggestion: string
        """

        response = self.llm.chat(
            system=system_prompt,
            messages=[{"role": "user", "content": user_prompt}],
            response_format={"type": "json_object"},
        )

        return self._parse_llm_response(response, pattern)

    def _parse_llm_response(self, response, pattern) -> List[RiskFinding]:
        """解析 LLM 返回的 JSON 结果"""
        # 实际项目中需要处理 JSON 解析异常、格式校验等
        import json
        try:
            data = json.loads(response)
            findings = []
            for item in data.get("findings", []):
                if item.get("is_found"):
                    findings.append(RiskFinding(
                        severity=pattern["severity"],
                        pattern=pattern["name"],
                        description=item.get("description", ""),
                        affected_components=item.get("affected_components", []),
                        suggestion=pattern.get("fix_suggestion", ""),
                    ))
            return findings
        except json.JSONDecodeError:
            return []

三、风险优先级排序:;不是所有风险都值得修复

AI 列出了 15 个风险点,;技术 Leader 不可能全部处理。这里需要一个
优先级排序算法
:;综合风险严重程度、影响范围、修复成本三个维度。

def prioritize_risks(findings: List[RiskFinding], c4_model: dict) -> List[RiskFinding]:
    """
    风险优先级排序。
    排序因子:;
    1. 严重程度(CRITICAL > HIGH > MEDIUM > LOW)
    2. 影响范围(受影响组件数 × 是否在关键路径上)
    3. LLM 给出的置信度(避免假阳性排在前面浪费人力)
    """
    # 构建关键路径上的组件集合
    critical_path_components = _identify_critical_path(c4_model)

    def score(finding: RiskFinding) -> float:
        severity_weight = {
            RiskSeverity.CRITICAL: 100,
            RiskSeverity.HIGH: 50,
            RiskSeverity.MEDIUM: 20,
            RiskSeverity.LOW: 5,
        }[finding.severity]

        # 关键路径上的风险加权 1.5 倍
        on_critical_path = any(
            comp in critical_path_components
            for comp in finding.affected_components
        )
        path_multiplier = 1.5 if on_critical_path else 1.0

        # 影响组件数(最小为 1)
        impact_scope = max(len(finding.affected_components), 1)

        return severity_weight * path_multiplier * impact_scope

    return sorted(findings, key=score, reverse=True)


def _identify_critical_path(c4_model: dict) -> set:
    """
    识别关键路径——从入口到核心数据的调用链路。
    简化实现:;标记所有数据库操作和支付/订单相关服务。
    生产环境应使用 LLM 自动识别。
    """
    critical = set()
    for rel in c4_model.get("relationships", []):
        if rel.get("tags") and "critical" in rel["tags"]:
            critical.add(rel["source"])
            critical.add(rel["target"])
    return critical

四、评审意见生成:;从风险列表到可操作的建议

风险列表不能直接发给方案作者——那相当于「你的方案有 15 个问题,;自己改」。AI 需要将冷冰冰的风险列表转化为
带上下文、带示例、带优先级
的评审意见:;

LLM 的 Prompt 设计在这里是关键。与其让 LLM 自由发挥,;不如给它一个结构化模板:;

你是一位资深后端架构师。请根据以下风险发现,;生成一份技术方案评审意见。

## 输入风险发现:;
{json.dumps(findings, indent=2)}

## 评审意见模板(严格按此格式输出):;

### 一、总体评价
[2~3 句话概括方案整体质量]

### 二、必须修复(CRITICAL)
- **风险点 1**:;[风险名称]
  - 影响:;[受影响的组件和后果]
  - 建议:;[具体修复方案,;含代码示例或配置示例]
  - 参考:;[相关文档或最佳实践链接]

### 三、强烈建议(HIGH)
...

### 四、可选优化(MEDIUM / LOW)
...

### 五、下一步行动
[建议的后续步骤:;重新评审 / 方案修订 / 技术讨论会]

模板化的益处:;输出格式一致,;方案作者知道每一条评审意见的「要求等级」,;Leader 可以快速浏览「必须修复」部分做最终决策。

五、总结

AI 辅助技术方案评审的核心价值是
将人的精力从「发现」转移到「决策」
:;

C4 模型是 AI 的「接口语言」
:;没有结构化描述的架构图,;对 AI 来说只是一张像素图。投入时间学习 C4 建模,;回报是 AI 可以自动完成 80% 的基础评审工作。

反模式库是 AI 的「知识库」
:;预定义的反模式(单点、循环依赖、缺少熔断、共享数据库)覆盖了生产事故的常见根源。这个库可以通过每次事故复盘持续扩展。

优先级排序比发现风险更重要
:;15 个风险点只有 3 个值得立即修复。基于严重程度 × 关键路径 × 影响范围的排序公式,;把人引向最高价值项。

评审意见需要结构化模板
:;自由格式的 AI 输出是不可复用的。模板化输出确保 Leader 和方案作者用同一种语言讨论问题。

这是一条正在快速演进的赛道——今天 AI 能做到的是「发现已知模式的已知风险」,;明天可能是「从历史事故中学习新的风险模式」。

0

评论0

请先
显示验证码
没有账号?注册  忘记密码?