真的代码审查 · 不是"给你 12 条通用建议"那种摘要

贴 PR 链接 · Agent 真的 clone 仓库 · 切到分支 · 跑测试套件 · 跑 semgrep / clippy / ruff / eslint · 输出 Markdown 评审 · 每条评论引用具体的 file:line · 不是模式猜测。每次评审存到 Drive · 团队沉淀机构记忆。

看一眼你能拿到什么

结论 + 摘要
1 页 / 共 4·结论 + 摘要
阻塞性问题
2 页 / 共 4·阻塞性问题
测试覆盖 diff
3 页 / 共 4·测试覆盖 diff
静态分析发现
4 页 / 共 4·静态分析发现

看 Agent 真的 clone / 构建 / 分析

下面每个框都是真实运行里的真实 shell 调用。底部评审评论引用的 file:line · 是 Agent 在你代码里真的看到的 · 不是对 diff 做模式匹配。

审 github.com/acme/api-server/pull/1284 · 完整评审。

V

收到。我先 clone 仓库 · 跑你的测试套件 · 再跑 semgrep + 项目自带 eslint。

run_shellgit clone --depth 50 github.com/acme/api-server && git fetch origin pull/1284/head:pr-1284 && git checkout pr-1284
run_shellpnpm install --frozen-lockfile · 缓存命中
run_shellpnpm test · 412 / 412 通过 · 但有 1 个改动函数 0% 覆盖
run_shellsemgrep --config p/owasp-top-ten --config p/typescript · 2 high · 1 medium
run_shellpnpm lint · 4 个新违规 · 8 个历史违规已压制
PR-1284-评审-2026-05-12.md
18 个发现 · 含修复建议

一条评审样例 · 引用 file:line

Agent 引用相关 3-5 行 · 在本代码库语境下解释为什么重要 · 用 unified diff 形式提出具体修复。

阻塞 · 安全src/routes/exports.ts:142

改动后端点直接把请求体里的 workspace_id 透传到下层服务 · 没有做归属检查。任何登录用户可以传别人的 workspace_id 把数据导出 —— IDOR。

140router.post('/exports', authMiddleware, async (req, res) => {
141 const { workspace_id, format } = req.body;
142 // ⚠ no ownership check before calling downstream
143 const data = await exportService.fetch(workspace_id, format);
144 res.json(data);
145});
建议修复 · unified diff
 router.post('/exports', authMiddleware, async (req, res) => {
  const { workspace_id, format } = req.body;
- // ⚠ no ownership check before calling downstream
+ if (!(await canAccessWorkspace(req.user.id, workspace_id))) {
+ return res.status(403).json({ error: 'forbidden' });
+ }
  const data = await exportService.fetch(workspace_id, format);
  res.json(data);
 });

本仓库其他 5 个 /exports* 端点已用 canAccessWorkspace · 这个新端点漏掉。

它怎么工作

步骤 01

贴 PR URL 或 diff

公开 GitHub / GitLab / Bitbucket repo URL 直接 clone —— 贴 PR URL 或 clone URL 都行。私有仓库当前最简路径是贴 unified `.patch` / `.diff` · Agent 不需要整个仓库就能审 diff。基于 OAuth 的私有仓库授权在 roadmap 上 · 现在请贴 diff。

步骤 02

选审深度

日常 PR 走完整评审 · 改动到鉴权 / 数据的走安全专项 · 马上要上线的走合并前清单。每条路径跑不同组合的工具 —— 完整评审几分钟 · 安全专项更快 · 合并前清单最快。

步骤 03

取走 Markdown 评审

产物以 Markdown 落到 Drive 的 /代码审查/{repo}/PR-{号}.md + 一份 PDF。每条评论引用 file:line · 作者可以直接跳过去。合并后评审留在 Drive · 半年后有人要理解"为什么这里这么写"时 · 能读到当时的判断。

为什么用 Vecbase 做这件事

它真的会 clone 和构建 · 不是在 diff 上做模式匹配

多数 AI 代码审查工具就是对 diff 跑正则 · 给通用建议。这里 Agent 真的 clone 仓库 · 跑你的构建 · 跑你的测试 · 跑你的 linter —— 跟人工审查一样。它说"这个函数改了 /src/foo.ts:142 的 caller 契约"是因为它真的在代码库里 grep 过 · 不是因为 diff 里碰巧出现了那个名字。

跑的是项目自带的静态分析 · 不是另起一套

仓库里有 .eslintrc / ruff.toml / clippy.toml / semgrep.yml · Agent 就用这些配置。发现与团队已经在乎的规则一致 · 不是第三方工具的另一套意见。改动代码里的新违规会从历史噪音中浮出来;历史噪音除非这个 PR 让它变严重了 · 否则不提。

引用 file:line · 评审读起来像资深工程师的留言

评审里每条评论都指名 file:line · 引用相关 3-5 行 · 在本代码库语境下解释问题 · 给具体修复建议。PR 作者点过去就到位置 —— 不会再有"模型说你改动里某处有问题"。评审读起来像懂上下文的资深工程师 · 不是一串通用废话。

评审存进 Drive · 团队沉淀机构记忆

PR 合并后 · 评审留在 /代码审查/{repo}/。半年后有人问"为什么这个具体端点上挂了限流"· 你在归档里一搜 —— "PR-1284 · 5 月 12 · 因为事故 IR-42 加的"。新工程师入职 = "把鉴权目录下最近 30 个评审读完"。每个评审对应的对话上下文也保留着 · 可追溯。

常见问题

主流支持:Python(ruff / mypy / pylint)· TypeScript / JavaScript(eslint / tsc)· Rust(clippy)· Go(golangci-lint)· Java(spotbugs / errorprone)· Ruby(rubocop)。沙盒里都预装 · Agent 读你项目的配置对齐家庭风格。冷门语言(Zig / Elixir / OCaml / Erlang)也能审 · 只是内置静态工具少一些 —— 那时 Agent 更多依赖测试套件结果和直接读代码。

90 秒内,拿到你的成品

登录后把任务交给 Agent —— 成品自动落到你的 Drive。