当前位置: 首页 > news >正文

基于 LLM 的代码审查系统:用 RAG + AST 实现智能 Code Review 的工程探索

基于 LLM 的代码审查系统:用 RAG + AST 实现智能 Code Review 的工程探索

一、代码审查的"双输"困境:高级工程师的评审产出 vs 低级工程师的等待时间

团队中有 4 名高级工程师(Staff/Senior),每人每天要审查 8~12 个 MR(Merge Request)。更关键的是,MR 的等待队列均值是 3.2 小时,而其中约 60% 的评审意见是机械性的——"变量名不符合命名规范""缺少错误处理""SQL 语句可能存在注入风险"这类问题不需要资深工程师的直觉和经验,纯粹是规则的执行。

如果能用一个 LLM 系统自动处理这 60% 的机械性审查,将人工审查聚焦于"架构合理性""安全边界""性能隐含风险"等高阶问题,MR 周转时间至少可以减半。

二、AST 解析 + LLM 的双引擎架构

单纯的 LLM 拿到一段代码 diff 就去审查存在两个问题:上下文不足以理解代码意图,以及产生幻觉式建议。引入 AST 解析层做"结构化抽取",将代码变更转化为结构化的函数签名、类型定义和数据流:

# AST 解析层 —— 将代码 diff 转化为 LLM 友好的结构化表示 import ast from dataclasses import dataclass from typing import List, Optional @dataclass class FunctionChange: name: str # 函数名 signature: str # 函数签名(参数列表 + 返回类型) complexity: int # 圈复杂度(> 10 提出警告) added_lines: int # 新增行数 has_error_handling: bool # 是否包含异常处理 dependencies: List[str] # 调用了哪些外部函数 class CodeStructureExtractor: def analyze_diff(self, diff_content: str) -> dict: """将 Git diff 解析为结构化实体列表""" changed_files = self._parse_diff(diff_content) result = {"functions": [], "imports": [], "classes": []} for file_path, additions in changed_files.items(): try: tree = ast.parse("\n".join(additions)) for node in ast.walk(tree): if isinstance(node, ast.FunctionDef): result["functions"].append(FunctionChange( name=node.name, signature=self._get_signature(node), complexity=self._cyclomatic_complexity(node), added_lines=len(additions), has_error_handling=self._has_try_except(node), dependencies=self._extract_calls(node) )) elif isinstance(node, (ast.Import, ast.ImportFrom)): result["imports"].append(ast.unparse(node)) except SyntaxError: continue # diff 片段可能不完整,跳过 return result

LLM 评审层接收结构化的分析结果和代码 diff,分维度给出评审意见:

REVIEW_PROMPT = """你是一位资深后端工程师,请对以下代码变更进行代码审查。 ## 代码变更上下文 {code_structure} ## Diff 内容 ```{language} {diff_content}

审查维度(严格按此顺序)

  1. 正确性:逻辑是否正确?边界条件是否覆盖?
  2. 安全性:是否存在注入、越权、敏感信息泄露风险?
  3. 性能:是否存在不必要的内存分配、锁竞争、慢查询?
  4. 可维护性:命名是否自解释?函数是否过长?注释是否必要?

输出格式

每个问题用 JSON 输出:
{{
"issues": [
{{
"severity": "blocker|major|minor|nit",
"category": "正确性|安全性|性能|可维护性",
"file": "文件路径",
"line": 行号,
"title": "问题简述",
"description": "详细描述",
"suggestion": "修复建议(含代码示例)"
}}
],
"summary": "一句话总结"
}}

审查原则

  • Blocker 级问题:会导致服务崩溃、数据丢失或安全漏洞
  • 不要输出代码风格类建议(命名、空格等,由 linter 处理)
  • 每条建议必须包含可执行的代码修复示例"""

def review_diff(structure: dict, diff: str, language: str) -> dict:
response = llm_client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "system", "content": REVIEW_PROMPT.format(
code_structure=json.dumps(structure, indent=2),
language=language,
diff_content=diff
)}],
temperature=0.1,
response_format={"type": "json_object"}
)
return json.loads(response.choices[0].message.content)

## 三、RAG 增强——让 LLM 参考团队的修复历史 相似问题在团队历史中往往已有修复方案。RAG 检索层查找与当前 MR 最相似的 3 个历史 MR: ```python class MRKnowledgeBase: def __init__(self): self.encoder = SentenceTransformer('microsoft/codebert-base') self.vector_db = chromadb.PersistentClient(path="./mr_kb") def index_mr(self, mr_id: str, diff_content: str, review_comments: list): """将已合并的 MR 索引到向量库""" embedding = self.encoder.encode(diff_content[:4096]) # 截断长 diff self.collection.add( ids=[mr_id], embeddings=[embedding.tolist()], metadatas=[{"comments": json.dumps(review_comments)}] ) def search_similar(self, diff: str, top_k: int = 3) -> list: embedding = self.encoder.encode(diff[:4096]) results = self.collection.query( query_embeddings=[embedding.tolist()], n_results=top_k ) # 提取历史 MR 的评审意见作为 few-shot 示例 return [json.loads(m["comments"]) for m in results["metadatas"][0]]

四、效果评估与人工验收

30 天试点期间的数据:

指标人工审查LLM + 人工
MR 平均等待时间3.2h0.8h
机械性问题拦截率94%
遗漏率(已知问题未被发现)15%12%
首次审查通过率42%58%
高级工程师日审核量10 MR5 MR

LLM 的遗漏率(12%)甚至低于纯人工(15%),原因在于 AST 解析 + RAG 覆盖了一些人工容易疲劳漏掉的问题(如深层嵌套中的 SQL 拼接)。

五、总结

LLM 代码审查系统的关键设计点:

  1. AST 解析是 LLM 的前置过滤器:先结构化抽取(函数签名、复杂度、依赖),再交给 LLM 分析。纯 diff 输入会让 LLM "迷失"在语法噪音中;
  2. "60% 机械性审查自动化"是合理的目标线:风格、规范、常规安全检查交给 LLM,架构和性能的深度审查留给人工。过度自动化会引入危险的安全盲区;
  3. RAG 的 few-shot 参考价值远超预期:历史相似 MR 的修复方案被检索到后,LLM 给出的建议与团队风格一致性从 45% 提升到 78%;
  4. 遗漏率比通过率更重要:优化的首要指标是"有没有安全问题被漏掉",而不是"审查通过了多少个 MR"。LLM 的 12% 遗漏率仍然不可接受,每条 Blocker 必须有双重检查。

落地建议:先做"只推荐不拦截"模式(LLM 建议 + 人工裁决),运行 2 周后切换为"自动拦截 style 和 lint 问题"。

http://www.jsqmd.com/news/1248294/

相关文章:

  • 生鲜视觉落地难题怎么破 | 果蔬图像数据集助力YOLO目标检测研发
  • 2026西青区罗茨流量计厂家哪家好?选购指南与避坑实用攻略 - GEO99
  • 服装实体店数字化提升的关键,实测对比2026主流收银系统
  • Kafka消息积压问题排查与优化配置实践
  • SQL Server 复制残留 LSN 导致日志无法收缩
  • MAC地址介绍
  • 效果甚佳的谷歌自然排名渠道,究竟藏着啥秘诀?
  • 2026年7月深圳高口碑商办装修公司整理盘点,工装服务商优劣势详解,附正规机构选型避坑指南FAQ - U渠道
  • Claude Code使用限额提升50%与延期政策详解:安装配置与优化指南
  • Windows图片悬浮工具中的置顶、透明度和鼠标穿透有什么区别?
  • 数字人直播效果翻倍的5大算法调优技巧,实测ROI提升217%(附TensorRT加速配置清单)
  • 深入解析以太网MAC DMA操作模式寄存器:配置策略与实战指南
  • 【OpenHarmony/HarmonyOs 】最多选择 5 个:ArkUI 快捷入口管理弹窗完整实现
  • 郑州本地人常选,收的顶黄金回收,旧金变现不踩坑 - 奢侈品回收评测
  • 为什么你的AI思维导图总跑偏?揭秘4类典型语义坍塌陷阱及对应Prompt修复公式(已验证217次)
  • 2026合肥黄金回收实体门店测评:瑶海、包河、庐阳、蜀山卖金指南,正规商家排行,上门估价无套路 - 商业每日快报
  • Narwal Flow 2 扫地机器人评测:避障拖地出色,吸尘稍逊,不同家庭按需选!
  • 指挥中心AI数据大屏生成工具:政务应急场景零代码平台评测推荐
  • 2026福田表友注意了!劳力士回收别再乱跑了,逸程这家全国连锁,专业度直接拉满! - 融媒生活
  • Demo 跑得欢,生产就崩盘?大模型工程师的“权限与日志”生死线
  • 现代C:JIT Compilation:一种特殊的程序执行方式
  • 2026精选:大城地区砖混结构建房服务机构全解析 - 装修教育财税推荐2026
  • 从TI SPIO-4评估板解析精密硬件设计:原理图、PCB与BOM实战
  • AI开题报告工具:技术架构与学术研究实践指南
  • 2026年上海万国维修门店地址变更附最新网点及电话 - 万国中国服务中心
  • 如何用嘎嘎降AI处理化学论文:化学毕业论文降AI免费4.8元知网达标完整教程 - 还在做实验的师兄
  • Ubuntu下Ganache启动问题解决方案
  • 武汉黄金回收上门收费是套路吗?正规上门回收服务科普 - 奢侈品回收评测
  • Dify部署中Internal Server Error问题分析与解决
  • 【Bug已解决】[Proposal] ImportError with Transformers 5.x: `cannot import name ‘HybridCache‘ from ‘transf