多智能体AI代码审查:从提示词到产线部署的工程化实践
1. 从提示词到产线AI 代码审查的真实落地路径代码审查这件事写过几年代码的人都有体会——它重要但没人愿意干。一个中等规模的团队每天产生的 PR 少则十几个多则几十个每个 PR 少则几十行改动多则上千行。让资深工程师逐行去看既消耗精力又容易漏掉细节让初级工程师去审又怕放过去隐藏的坑。LinkedIn 工程团队公开分享过他们在这件事上的探索用多智能体系统把 AI 代码审查从“写个好提示词试试看”推进到“稳定跑在产线上”。这个跨度比大多数人想象的要大得多。我过去两年一直在做 AI 辅助研发效能相关的事情从最早的“复制一段代码让大模型看看有没有问题”到后来搭建团队内部的自动化审查流水线踩过的坑不算少。LinkedIn 这套多智能体拆解的思路和我自己在实践中摸索出来的方向高度吻合但他们在工程化层面做得更系统。这篇文章我会围绕这个主题把从提示词设计到多智能体协作、再到产线部署的完整链路拆开来讲既包括核心原理也包括可以直接抄作业的实操细节。不管你是刚开始接触 AI 代码审查还是已经在团队里跑了一些自动化方案但效果不稳定这篇文章应该都能给你一些可参考的东西。我会尽量把每个设计决策背后的“为什么”讲清楚而不是只丢一个结论。2. 为什么单智能体做不好代码审查2.1 代码审查到底在审什么很多人对代码审查的理解停留在“看看有没有 bug”实际上一个合格的 code review 至少覆盖以下几个维度正确性逻辑是否实现了预期功能边界条件是否处理了安全性有没有注入风险、权限漏洞、敏感信息泄露性能有没有明显的性能反模式比如循环里查数据库可维护性命名是否清晰、抽象是否合理、是否有重复代码一致性是否符合团队既定的编码规范和架构约定测试覆盖改动是否配套了足够的测试用例这六个维度对审查者的知识结构要求完全不同。安全性需要攻防经验性能需要系统设计能力可维护性需要架构审美一致性需要熟悉团队历史代码。你让一个模型同时把六件事都做好结果往往是每件事都做得马马虎虎。2.2 单智能体的三个典型失败模式我在早期用单个大模型做代码审查时反复遇到三类问题。第一类是注意力稀释。当一个 PR 改了 800 行代码你把整个 diff 塞进上下文模型对前面部分的审查质量明显高于后面部分。这跟人是一样的——连续看几百行 diff注意力必然下降。模型虽然不会“累”但上下文窗口内的注意力分配是不均匀的长上下文中间部分的信息容易被忽略。第二类是角色冲突。你给一个系统提示词里写“请检查代码的正确性、安全性、性能、可维护性”模型会在这些目标之间做隐式的权衡。有时候它发现了一个严重的安全问题但因为提示词里也强调了“不要过于挑剔”它可能就轻描淡写地带过了。这种目标之间的相互干扰在单智能体架构下很难消除。第三类是缺乏交叉验证。单个模型给出的审查意见你没有一个独立的信号来判断它是否靠谱。它说“这段代码有 SQL 注入风险”你只能靠自己去验证。如果它漏了一个严重问题你也没有任何机制能发现这个遗漏。2.3 多智能体架构的核心优势多智能体的思路本质上就是“分而治之”加“交叉验证”。把六个审查维度分配给不同的智能体每个智能体只关注自己的领域用专门的提示词和工具来增强这个领域的审查能力。然后通过一个协调机制把结果汇总、去重、排序。LinkedIn 的方案里我理解他们的核心设计是每个智能体有独立的系统提示词、独立的工具集、独立的输出格式。比如安全审查智能体可以调用静态分析工具SAST的接口性能审查智能体可以查询历史性能基线数据一致性审查智能体可以检索团队的历史代码库。这样做的好处很直接每个智能体的上下文更聚焦提示词可以针对特定领域深度优化而且不同智能体的结论可以相互印证。如果安全智能体和正确性智能体都指向同一段代码有问题那这个信号的置信度就比单模型输出要高得多。3. 提示词工程每个智能体的“专业训练手册”3.1 系统提示词的分层设计给代码审查智能体写提示词跟给通用对话模型写提示词是两回事。我的经验是要分三层来设计第一层是角色定义。不要写“你是一个代码审查助手”这种泛泛的表述。要具体到“你是一个专注于 Java 后端服务安全审查的专家有十年以上金融级系统的安全审计经验熟悉 OWASP Top 10 和 CWE 分类体系”。角色越具体模型在审查时的“注意力锚点”就越明确。第二层是审查清单。把你希望它检查的具体项目一条条列出来。比如安全智能体的清单可能包括SQL 注入、XSS、CSRF、不安全的反序列化、硬编码密钥、日志中的敏感信息、权限校验缺失等。每一条都要给出正例和反例让模型知道什么算问题、什么不算。第三层是输出规范。要求模型以结构化格式输出包括问题位置文件行号、严重等级、问题描述、修复建议、置信度。结构化输出是后续自动化处理的前提。3.2 少样本示例的选择策略提示词里放多少示例、放什么样的示例直接影响审查质量。我试过几种策略零样本只给指令不给示例。结果是最不稳定的模型容易自由发挥。单示例给一个典型问题示例。效果有提升但模型容易过度拟合这个示例的模式。多示例均衡每个审查维度给 2-3 个示例覆盖不同严重等级。这是我在实践中觉得最稳的方案。示例的选择要注意两点。一是多样性不能全是同一种问题。二是边界清晰要包含一些“看起来像问题但其实不是”的负例帮助模型建立更准确的判断边界。比如“这里用了字符串拼接 SQL但参数来自内部枚举常量不存在注入风险”这种负例能有效降低误报率。3.3 提示词模板的版本管理这一点很多人会忽略。提示词不是写完就完了它需要像代码一样做版本管理。我在团队里的做法是每个智能体的提示词存在独立的文件里用 Git 管理每次修改提示词都要记录变更原因和预期效果建立一套评估集一组已知有问题的 PR 和已知没问题的 PR每次改提示词后跑一遍评估看准确率和召回率的变化提示词版本和审查结果关联存储方便回溯“这个误报是哪个版本的提示词产生的”LinkedIn 的方案里应该也有类似的机制因为从他们的分享来看提示词是持续迭代的不是一次性的工作。提示提示词模板里不要写死具体的代码规范细节那些应该通过检索增强的方式动态注入。提示词负责定义“怎么审”知识库负责提供“审什么标准”。4. 多智能体协作机制的设计与实现4.1 智能体角色划分基于代码审查的六个维度我建议至少划分以下智能体角色智能体角色核心职责依赖工具正确性审查员逻辑正确性、边界条件、异常处理单元测试生成器、符号执行工具安全审查员漏洞检测、敏感信息、权限校验SAST 工具、依赖漏洞库性能审查员性能反模式、资源泄漏、复杂度性能基线数据库、profiler 历史数据可维护性审查员命名、抽象、重复代码、注释代码度量工具、克隆检测一致性审查员编码规范、架构约定、API 风格团队规范知识库、历史代码检索测试审查员测试覆盖率、测试质量、边界用例覆盖率报告、变异测试工具每个智能体独立运行互不干扰。这样做的好处是即使某个智能体出了问题比如工具调用失败也不会影响其他智能体的审查结果。4.2 协调器的核心逻辑协调器Orchestrator是整个多智能体系统的中枢。它负责任务分发接收 PR 事件提取 diff分发给各个审查智能体上下文准备为每个智能体准备它需要的上下文比如安全智能体需要依赖清单性能智能体需要历史性能数据结果收集等待所有智能体返回结果处理超时和失败去重合并不同智能体可能对同一段代码提出相似问题需要去重优先级排序根据严重等级、置信度、影响范围综合排序格式化输出生成最终的审查报告以 PR 评论的形式发布协调器的实现可以用简单的串行调用也可以用并行加超时控制。我建议用并行方式因为每个智能体的审查是独立的并行能显著降低整体延迟。但要注意设置合理的超时时间避免某个智能体卡住导致整个流程阻塞。4.3 智能体间的通信协议智能体之间需不需要直接通信我的经验是大多数情况下不需要。每个智能体独立审查协调器负责汇总这种星型拓扑最简单也最稳定。但在某些场景下智能体间的通信能提升效果。比如安全智能体发现了一个潜在的注入点它可以通知正确性智能体重点检查这个数据流。这种“线索传递”机制可以通过协调器中转实现安全智能体在输出里标记“需要正确性验证的数据流”协调器把这个信息作为额外上下文传给正确性智能体。LinkedIn 的方案里可能也有类似的机制因为从他们的描述来看智能体之间不是完全孤立的。4.4 置信度聚合与冲突消解当多个智能体对同一段代码给出不同判断时怎么处理我的做法是如果两个以上智能体都标记了同一段代码有问题提升该问题的优先级如果一个智能体标记了问题但另一个智能体明确说“这段代码没问题”降低置信度标记为“需人工确认”如果只有一个智能体标记了低严重等级的问题可以合并到“建议”类别不阻塞 PR 合并置信度的计算可以简单加权也可以训练一个小的分类模型来学习如何聚合。后者效果更好但需要标注数据。5. 从原型到产线工程化落地的关键环节5.1 与 CI/CD 流水线的集成AI 代码审查要真正产生价值必须嵌入到开发者的日常工作流里。最自然的接入点是 PR 创建和更新事件。具体来说PR 创建时触发一次完整审查PR 有新的 commit 推送时只审查增量部分审查结果以 PR 评论的形式发布按文件和行号定位严重问题可以设置为“Request Changes”阻止合并低优先级建议以普通评论形式呈现不阻塞流程集成的技术实现通常是通过 Webhook 接收 PR 事件然后调用审查服务。审查服务可以是独立的微服务也可以是无服务器函数。关键是响应时间要控制在开发者可接受的范围内我的经验是 2-5 分钟是比较合理的超过 10 分钟开发者就会觉得“太慢了不如自己看”。5.2 延迟优化与成本控制多智能体系统的延迟和成本是单智能体的数倍这是必须面对的问题。几个优化方向并行化所有智能体并行运行整体延迟取决于最慢的那个智能体而不是所有智能体之和。模型分级不是所有智能体都需要用最大的模型。正确性和安全审查可以用能力最强的模型可维护性和一致性审查可以用中等模型测试审查甚至可以用小模型加规则引擎。缓存对于没有变化的文件直接复用上次的审查结果。对于相似的代码模式可以缓存审查结论。增量审查只审查 diff 部分而不是整个文件。这能大幅减少 token 消耗。采样审查对于低风险的 PR比如只改了文档或注释可以跳过部分智能体只做快速检查。5.3 误报率的控制误报是 AI 代码审查最大的敌人。开发者被误报烦了几次之后就会完全忽略所有审查意见哪怕里面真的有严重问题。控制误报的几个手段置信度阈值低于阈值的审查意见不展示或者只展示在“低优先级”区域人工反馈闭环允许开发者标记“误报”这些反馈用于优化提示词和调整阈值规则过滤对于已知的误报模式用规则引擎直接过滤掉渐进式上线先在少数团队试点收集反馈调整到误报率可接受后再全量推广我在实践中发现误报率控制在 15% 以下时开发者对 AI 审查的接受度会明显提高。超过 30% 时基本就没人看了。5.4 审查结果的可解释性AI 给出的审查意见如果只是说“这里有问题”开发者很难判断是否值得采纳。好的审查意见应该包含问题定位具体到文件和行号问题描述说清楚是什么问题为什么是问题修复建议给出具体的修改方案最好有代码示例参考依据引用相关的编码规范、安全标准或历史案例置信度让开发者知道这个判断有多确定可解释性不仅提升开发者对审查结果的信任度也方便开发者快速判断是否采纳。6. 实操过程与核心环节实现6.1 环境准备与基础依赖假设你要从零搭建一套类似的多智能体代码审查系统以下是我建议的基础环境# 基础环境 Python 3.10 Git 2.30 Docker 20.10用于容器化部署 # 核心依赖 openai1.0.0 # 或其他大模型 SDK langchain0.1.0 # 智能体编排框架 pydantic2.0 # 数据模型定义 fastapi0.100 # API 服务 redis4.0 # 缓存和任务队列 postgresql14 # 审查结果存储如果你的团队已经有 CI/CD 基础设施审查服务可以作为一个独立的微服务部署通过 Webhook 接收 PR 事件。6.2 智能体基类的实现每个智能体共享一些基础能力比如调用大模型、解析输出、处理错误。我通常会定义一个基类from abc import ABC, abstractmethod from pydantic import BaseModel class ReviewIssue(BaseModel): file_path: str line_number: int severity: str # critical, major, minor, suggestion category: str description: str suggestion: str confidence: float class BaseReviewAgent(ABC): def __init__(self, llm_client, toolsNone): self.llm llm_client self.tools tools or [] self.system_prompt self._build_system_prompt() abstractmethod def _build_system_prompt(self) - str: 每个智能体实现自己的系统提示词 pass abstractmethod def _build_review_prompt(self, diff: str, context: dict) - str: 构建审查请求的提示词 pass def review(self, diff: str, context: dict) - list[ReviewIssue]: prompt self._build_review_prompt(diff, context) response self.llm.chat( systemself.system_prompt, userprompt, temperature0.1 # 低温度保证输出稳定 ) return self._parse_response(response) def _parse_response(self, response: str) - list[ReviewIssue]: 解析模型输出为结构化数据 # 实际实现中需要处理 JSON 解析失败、格式不符等情况 pass这个基类定义了智能体的核心接口。每个具体的智能体只需要实现提示词构建和输出解析两个方法。6.3 安全审查智能体的完整实现以安全审查智能体为例展示一个完整的实现class SecurityReviewAgent(BaseReviewAgent): def _build_system_prompt(self) - str: return 你是一名资深应用安全工程师专注于代码安全审查。 你的职责是识别代码变更中引入的安全漏洞和风险。 审查范围包括但不限于 1. 注入类漏洞SQL注入、命令注入、LDAP注入、XPath注入 2. 跨站脚本XSS反射型、存储型、DOM型 3. 认证与授权缺陷权限校验缺失、会话管理问题 4. 敏感信息泄露硬编码密钥、日志中的敏感数据、错误信息泄露 5. 不安全的反序列化 6. 依赖组件漏洞 输出要求 - 每个问题必须包含文件路径、行号、严重等级、问题描述、修复建议、置信度 - 严重等级分为critical必须修复、major应该修复、minor建议修复 - 置信度用 0-1 的小数表示 - 如果代码没有安全问题返回空列表 注意 - 不要报告理论上的问题只报告实际可利用或高概率存在的风险 - 对于需要更多上下文才能判断的情况降低置信度而不是直接报告 - 修复建议要具体最好给出修改后的代码示例 def _build_review_prompt(self, diff: str, context: dict) - str: dependencies context.get(dependencies, []) return f请审查以下代码变更 diff {diff}相关依赖信息 {chr(10).join(f- {d} for d in dependencies)}请按以下 JSON 格式输出审查结果 {{ issues: [ {{ file_path: 文件路径, line_number: 行号, severity: critical|major|minor, category: 漏洞类型, description: 问题描述, suggestion: 修复建议, confidence: 0.95 }} ] }}这个实现里系统提示词定义了审查范围和输出规范审查提示词注入了具体的 diff 和依赖信息。温度设为 0.1 是为了保证输出稳定减少随机性。 ### 6.4 协调器的实现 协调器负责调度所有智能体并汇总结果 python import asyncio from concurrent.futures import ThreadPoolExecutor class ReviewOrchestrator: def __init__(self, agents: list[BaseReviewAgent]): self.agents agents self.executor ThreadPoolExecutor(max_workerslen(agents)) async def review_pr(self, diff: str, context: dict) - dict: # 并行运行所有智能体 loop asyncio.get_event_loop() tasks [ loop.run_in_executor( self.executor, self._safe_review, agent, diff, context ) for agent in self.agents ] results await asyncio.gather(*tasks, return_exceptionsTrue) # 收集所有问题 all_issues [] for agent, result in zip(self.agents, results): if isinstance(result, Exception): # 记录失败但不阻塞其他结果 self._log_agent_failure(agent, result) continue all_issues.extend(result) # 去重和排序 deduped self._deduplicate(all_issues) sorted_issues self._sort_by_priority(deduped) return { issues: sorted_issues, summary: self._generate_summary(sorted_issues), agent_status: self._get_agent_status(results) } def _safe_review(self, agent, diff, context): try: return agent.review(diff, context) except Exception as e: raise AgentReviewError(f{agent.__class__.__name__} failed: {e}) def _deduplicate(self, issues): 基于文件路径行号问题类型去重 seen {} for issue in issues: key (issue.file_path, issue.line_number, issue.category) if key not in seen or issue.confidence seen[key].confidence: seen[key] issue return list(seen.values()) def _sort_by_priority(self, issues): severity_order {critical: 0, major: 1, minor: 2, suggestion: 3} return sorted(issues, keylambda x: (severity_order[x.severity], -x.confidence))这个协调器用线程池并行运行所有智能体用 asyncio 管理异步等待。去重逻辑基于文件路径、行号和问题类型保留置信度最高的那条。排序按严重等级和置信度综合排序。6.5 与 GitHub/GitLab 的集成审查服务需要接收 PR 事件并发布评论。以 GitHub 为例from fastapi import FastAPI, Request import hmac import hashlib app FastAPI() app.post(/webhook/github) async def github_webhook(request: Request): # 验证签名 signature request.headers.get(X-Hub-Signature-256) body await request.body() if not verify_signature(body, signature): return {status: invalid signature} payload await request.json() event_type request.headers.get(X-GitHub-Event) if event_type pull_request: action payload[action] if action in [opened, synchronize]: pr_number payload[pull_request][number] repo payload[repository][full_name] # 异步触发审查 asyncio.create_task(run_review_and_comment(repo, pr_number)) return {status: ok} async def run_review_and_comment(repo: str, pr_number: int): # 获取 diff diff await get_pr_diff(repo, pr_number) context await gather_context(repo, pr_number) # 运行审查 orchestrator ReviewOrchestrator(agentsbuild_agents()) result await orchestrator.review_pr(diff, context) # 发布评论 for issue in result[issues]: if issue.severity in [critical, major]: await post_pr_comment(repo, pr_number, issue)这个集成方案的关键点是Webhook 接收后立即返回审查任务异步执行避免超时。审查完成后通过 GitHub API 发布评论。7. 常见问题与排查技巧实录7.1 审查结果不稳定怎么办这是最常见的问题。同一个 PR两次审查结果不一样。原因通常有几个温度参数过高把 temperature 降到 0.1 以下最好用 0提示词不够明确模型在模糊地带自由发挥需要补充更多边界示例上下文不一致每次传入的上下文不同导致判断不同。确保上下文准备逻辑是确定性的模型版本变化如果用的是云端 API模型可能悄悄更新了。固定模型版本号我的做法是在提示词里明确要求“只报告高置信度的问题”并且在输出解析时过滤掉置信度低于 0.7 的结果。这样虽然会漏掉一些边缘问题但稳定性大幅提升。7.2 误报太多怎么调误报的来源通常是模型对“什么是问题”的理解过于宽泛。解决办法增加负例在提示词里加入“以下情况不算问题”的示例提高置信度阈值从 0.7 提到 0.8 或 0.85增加人工反馈让开发者标记误报定期分析误报模式针对性优化提示词规则前置过滤对于已知的误报模式用正则或 AST 规则直接过滤我踩过的一个坑是安全智能体对所有的字符串拼接都报 SQL 注入风险但实际上很多拼接的是内部常量根本不涉及用户输入。后来在提示词里明确要求“只有当拼接的变量来自用户输入或外部数据源时才报告”误报率直接降了一半。7.3 审查速度太慢怎么优化多智能体系统的延迟是累加的如果串行运行六个智能体每个 30 秒总共就是 3 分钟。优化方向优化手段预期效果实施难度并行运行所有智能体延迟降低 60-80%低增量审查只审 difftoken 消耗降低 50-70%中模型分级小模型做简单审查成本降低 40-60%中结果缓存相同代码复用重复 PR 延迟降低 90%低采样审查低风险 PR 跳过部分智能体整体延迟降低 30%中我通常先做并行化和增量审查这两个投入产出比最高。模型分级需要评估小模型的效果是否可接受缓存需要设计合理的缓存键。7.4 开发者不买账怎么办这是组织层面的问题但技术手段也能帮上忙控制误报率误报率低于 15% 是开发者能接受的前提提供可操作的修复建议不要只说“这里有问题”要说“建议改成这样”允许一键忽略对于不打算修复的问题提供“忽略”按钮记录忽略原因展示价值定期统计 AI 审查发现的问题数量、其中被采纳的比例、避免的潜在故障渐进式推广先在一个团队试点收集正面案例再推广到其他团队我在团队里推这套系统时最开始只做安全审查因为安全问题最容易达成共识。等大家看到 AI 确实能发现一些人工容易漏掉的安全问题后再逐步增加其他维度的审查。7.5 常见问题速查表问题现象可能原因排查方向解决方案审查结果为空提示词过于严格检查提示词中的过滤条件放宽置信度阈值增加示例同一问题重复报告去重逻辑不完善检查去重键的设计增加去重维度如问题描述相似度严重问题被漏报上下文不足检查传入的上下文是否完整补充依赖信息、历史数据审查意见无法定位行号计算错误检查 diff 解析逻辑使用标准 diff 解析库智能体超时模型响应慢或工具调用失败检查各智能体耗时设置超时失败时降级处理输出格式解析失败模型未按格式输出检查提示词中的格式要求增加格式示例使用 JSON mode提示建议在审查服务里加一个“调试模式”可以单独运行某个智能体并查看原始输出。排查问题时非常有用。8. 产线部署的架构考量8.1 服务架构设计产线部署的架构需要考虑可用性、扩展性和可观测性。我建议的架构是接入层Webhook 接收服务负责验证签名、解析事件、入队队列层用 Redis 或 RabbitMQ 做任务队列削峰填谷审查层多个审查 worker从队列消费任务运行多智能体审查存储层PostgreSQL 存储审查结果、反馈数据、提示词版本展示层PR 评论、内部 dashboard、统计报表这种架构的好处是各层可以独立扩展。PR 高峰期可以增加 worker 数量审查结果可以持久化用于后续分析。8.2 可观测性建设产线系统必须可观测。关键指标包括审查延迟从 PR 创建到审查完成的端到端时间各智能体耗时定位性能瓶颈误报率开发者标记误报的比例采纳率审查意见被实际修复的比例漏报率事后发现但审查未报告的问题比例需要人工标注token 消耗成本监控这些指标应该做成 dashboard定期 review。我通常每周看一次发现异常及时调整。8.3 灰度发布与回滚提示词和智能体逻辑的变更应该像代码变更一样做灰度发布新版本先在内部测试集上跑评估评估通过后在 10% 的 PR 上启用新版本对比新旧版本的误报率、采纳率、延迟确认无异常后逐步扩大比例保留快速回滚能力我踩过的一个坑是有一次改了一个安全智能体的提示词在测试集上效果很好但上线后发现对某类特定框架的代码误报率飙升。因为没有灰度机制影响了所有团队的 PR。后来加了灰度发布类似问题就再没出现过。9. 我在这套系统上踩过的坑和总结的经验说几个印象深刻的教训。第一个是关于提示词的“过度优化”。有一段时间我为了让安全智能体发现更多问题不断在提示词里增加检查项结果误报率飙升开发者开始忽略所有审查意见。后来我反过来做减法只保留最高频、最严重的几类问题误报率降下来之后开发者反而更愿意看审查意见了。审查系统的价值不在于发现多少问题而在于发现的问题有多少被真正修复。第二个是关于智能体数量的权衡。我一开始设计了八个智能体覆盖了代码审查的方方面面。但实际运行下来发现有些智能体的输出高度重叠有些智能体的建议开发者根本不看。后来精简到四个核心智能体正确性、安全性、性能、可维护性整体效果反而更好。智能体不是越多越好每个智能体都应该有明确的、不可替代的价值。第三个是关于人工反馈闭环的重要性。最开始我没有做反馈机制提示词改来改去都是凭感觉。后来加了“误报”和“已修复”两个反馈按钮积累了几千条反馈数据后优化方向就清晰多了。哪些提示词导致了误报、哪些类型的问题采纳率最高数据一目了然。没有反馈数据的提示词优化就是盲人摸象。第四个是关于成本的控制。多智能体系统的 token 消耗是单智能体的数倍如果不加控制月底账单会很吓人。我的做法是增量审查只传 diff 不传整个文件、简单审查用便宜模型、相同代码模式缓存结果、低风险 PR 采样审查。这几招组合下来成本能控制在可接受范围内。最后分享一个我觉得很有用的小技巧在审查结果的展示上不要把所有问题平铺直叙地列出来。按严重等级分组critical 和 major 放在最前面用醒目的格式minor 和 suggestion 折叠起来默认不展开。这样开发者第一眼看到的就是最重要的问题不会被大量低优先级建议淹没。这个小小的展示优化让审查意见的采纳率提升了将近一倍。