Proval:把代码审查 Agent 放进自己的 Git 网络
代码审查 Agent 最容易落地的地方,往往不是“再接一个聊天窗口”,而是 Pull Request 本身:它能看到明确的 diff、仓库上下文和讨论线程,也能把结果留在团队已经使用的工作流里。问题是,很多团队不愿意把私有代码和模型调用交给第三方审查 SaaS。Proval 的思路很直接:在自己的网络里运行一个代码审查 Agent,连接 GitHub、GitLab 或 Forgejo,并让模型通过 OpenAI 兼容接口工作。
这篇文章基于 Proval 当前公开仓库的 README 和文档示例,重点看它适合什么场景、如何部署,以及它的边界在哪里。
它解决的不是“能不能审查”,而是“代码去哪儿审查”
Proval 是一个采用 AGPL-3.0 的自托管 TypeScript 项目。官方描述的最小部署方式是一个 Docker 镜像,服务公开两个端口:7900 用于控制台,7901 用于 webhook。模型侧不绑定某一家云厂商:只要提供 OpenAI-compatible Chat Completions API,就可以使用 OpenAI、Ollama、llama.cpp 或内部模型网关。Anthropic 和 Gemini 在 README 中被列为计划中的一等集成,因此不应把它们描述成当前已经内置的原生 SDK 路径。
它支持 GitLab、Forgejo 和 GitHub。对内网、家庭实验室或有数据驻留要求的团队来说,这个取舍很重要:代码 diff、审查请求和模型调用可以留在自己控制的网络边界内;但“自托管”不等于自动获得安全性,模型 API、Git Provider token、webhook 入口和持久化目录仍要按生产服务管理。
审查链路:规划 Agent + 专项子 Agent
Proval 的公开架构可以概括成四步:webhook 触发后,先读取仓库与平台状态;规划 Agent 将变更文件分组;多个 specialist sub-agents 并行检查各组;写作 Agent 汇总结果并发布评论。这个设计比“把整个 diff 丢给一个模型”更适合大型 PR,因为每个子 Agent 都能独立探索代码库,寻找跨文件影响和隐藏依赖。
审查结果可以落到受影响代码行的 inline comment,也可以形成按严重级别分组的汇总。一个实用的设置是先只审查首次推送,再根据团队容忍度改成每次 push 都审查:前者减少模型费用和评论噪音,后者更适合高风险仓库,但必须配合去重和人工确认。
除了 Pull Request,Proval 也能处理 issue:issue 创建时留言,或者在后续评论中被提及时回复。每次 review、reply 和 issue comment 都会记录 token usage,这让团队至少有机会从运行日志估算模型成本,而不是只看“审查是否成功”。
十分钟启动:先用 Compose 验证边界
官方 README 给出的 Compose 骨架如下。ENCRYPTION_KEY 应使用随机值生成,不要把示例占位符直接用于生产。
openssl rand -base64 32
services:
proval:
image: ghcr.io/seoes/proval:latest
ports:
- "7900:7900"
- "7901:7901"
volumes:
- ./data:/data
environment:
- ENCRYPTION_KEY=${ENCRYPTION_KEY}
保存环境变量后启动容器,再访问 7900 端口的控制台。README 还给出了 HTTPS 场景的 COOKIE_SECURE=true 设置;如果暂时只在局域网通过 HTTP 试用,不要误把这个变量当成 TLS 配置,它只是让会话 Cookie 带上 Secure 属性。webhook 端口则应放在反向代理或防火墙明确允许的入口之后,避免把管理面板和事件入口无差别暴露到公网。
Kubernetes 示例有一个容易被忽略的前提:官方建议使用单副本、Recreate 策略,并把 /data 持久化,因为当前示例使用 SQLite。也就是说,先不要把它当成可以随意水平扩容的无状态审查服务。若需要多副本、高可用数据库或更细的权限模型,应先核对项目后续版本和文档,而不是自行推断。
模型与仓库连接的实际取舍
Proval 的 BYO LLM 设计很适合内部网关。你可以让 Proval 访问公司统一的 OpenAI 兼容端点,也可以在局域网连接 Ollama 或 llama.cpp。这样做的优点是模型供应商可以替换,审查服务不必跟着改;代价是你需要自己负责模型质量、上下文长度、限流、超时、日志脱敏和失败重试。
Git Provider 侧建议采用最小权限 token,并把“能读取什么、能写评论到哪里”分开规划。代码审查 Agent 最危险的默认值不是“漏掉一个风格问题”,而是拿到过大的写权限后自动修改分支、关闭 issue 或触发部署。Proval 当前公开材料强调的是评论、回复和 webhook 工作流;因此第一阶段应把它配置为只读代码加评论权限,把合并、发布和生产凭据留在人类审批链上。
审查策略也应从小开始:先选择一个非关键仓库,限制触发条件,观察误报、重复评论和 token 消耗,再逐步扩大范围。尤其要验证模型收到的 diff 是否包含足够上下文、子 Agent 的并行结果是否能正确汇总,以及 webhook 重试时是否会重复创建评论。
它适合谁,不适合谁
Proval 适合已经有 GitHub、GitLab 或 Forgejo 工作流,同时希望代码不离开自有网络的团队;也适合想用本地模型做第一轮审查、再由人处理高风险意见的个人开发者。它的价值不在于宣称“模型取代审查者”,而在于把机器审查接入已有的 PR 和 issue 记录,让结果可追踪。
它暂时不适合需要成熟身份与权限体系、多副本数据库、强合规审计或超大规模仓库的组织。公开 README 将认证授权、SSO、限流、按模型基准测试等列为计划功能,并明确说明项目仍处于早期阶段。自托管降低了代码外发风险,却增加了升级、备份、监控和安全响应成本;如果团队没有维护容器和 webhook 服务的能力,购买成熟 SaaS 可能反而更省心。
怎样判断一次审查真的有用
部署完成后,不要只用“评论已经出现在 PR 里”作为验收标准。先准备一组包含已知问题的测试变更,例如未检查的空值、权限判断顺序错误、数据库查询缺少索引或异常分支没有释放资源。让 Proval 对同一组变更运行多次,记录它是否能定位到正确文件和行号、严重级别是否稳定、汇总意见是否遗漏子 Agent 找到的问题。
还要把“没有发现问题”和“Agent 没有运行”区分开。模型接口超时、webhook 签名错误、仓库权限不足、上下文过长,都可能让一次审查看起来没有评论。建议在测试仓库里故意制造这些故障,并检查控制台、容器日志和 Git Provider 事件记录是否能形成闭环。只有失败可见、重试可控,团队才不会把沉默误认为绿色。同时把审查结论标记为辅助信号,而不是自动合并的唯一依据。
由于 Proval 当前使用 SQLite 的单副本部署建议,数据目录和升级策略也应在上线前演练:停止容器、备份 /data、升级镜像、恢复数据,再确认历史审查记录和连接配置仍然可用。对于模型请求日志,重点检查是否意外写入完整源码、访问令牌或 webhook 密钥;自托管并不意味着日志天然安全。
上线前检查清单
- 用随机生成的密钥替换
ENCRYPTION_KEY,并通过 Secret 或受控环境变量注入。 - 为 Proval、Git Provider 和模型网关分别建立最小权限凭据。
- 先在测试仓库验证首次 push、后续 push、issue 回复和 inline comment。
- 检查 webhook 重放、模型超时、错误评论和重复事件的行为。
- 把
/data纳入备份;SQLite 单副本前提下不要直接横向扩容。 - 为 token usage、容器健康、审查延迟和失败 webhook 建立监控。
- 明确人工 merge gate:Agent 可以提出意见,但不要默认拥有合并和部署权限。
Proval 的亮点是边界清楚:它把“审查服务的运行位置”和“模型的选择权”交还给使用者。对于愿意承担运维责任的团队,这是一条比直接上传私有 diff 更可控的路线;对于只想立即获得稳定审查体验的团队,则应先把自托管成本与它仍在开发中的功能状态放进评估表里。