---
title: "在合并之前给代码变更加一道判断"
description: "一次请求同时给出变更的爆炸半径评分，以及是否触及安全或数据安全的是非判断。类型化的阈值让评审或 Agent 决定拦截、标记还是放行。"
canonical: "https://system-one.dev/zh-CN/use-cases/code-review-gate"
language: "zh-CN"
---

# 在合并之前给代码变更加一道判断

**要点**

1. 两道问题覆盖大多数评审关卡：四级风险评分，以及一个关于安全或数据安全的是非问题。
2. 两个答案来自同一次请求，所以一道关卡只花一次往返和少量积分。
3. 模型只给风险排序，不证明正确性；合并决定仍然由人负责。

## 关卡能决定什么，不能决定什么

评审者——人或 Agent——常常需要一个快速的第一道筛：这个 diff 有多危险，是否碰到可能丢数据的地方。这是一类有界判断，适合决策模型。

它不能告诉你代码是否正确。它不跑测试、不读整个仓库，也不证明某个路径检查足够。把输出当作分流信号，而不是批准。

## 问题形状

```ts
import { choice, booleanQuestion } from '@system-one-ai/core';

export const reviewQuestions = {
  risk: score('How risky is this change to merge?', {
    none: 'No risk',
    low: 'Low risk, normal review',
    high: 'High risk, needs an owner',
    block: 'Block merge until inspected',
  }),
  security: booleanQuestion('Does this change affect security or data safety?'),
};
```

把 diff、它触及的路径和上下文说明作为 state 发过去。把 diff 文本当作数据：一个在注释里写下指令的变更，不应该能左右判断。

> 示意代码，未经过实际运行测试。阈值只是占位。

```ts
export async function gateDiff(client, diff: { patch: string; paths: string[] }) {
  const result = await client.evaluate({
    state: { patch: diff.patch, paths: diff.paths },
    questions: reviewQuestions,
  });
  const security = result.answers.security.probability;
  const risk = result.answers.risk.score;

  if (security >= 0.7 || risk === 'block') return 'block';
  if (security >= 0.3 || risk === 'high') return 'needs_owner';
  return 'normal_review';
}
```

## 它该放在流水线的哪里

在 diff 存在之后、允许合并之前：

1. CI 照常构建并跑单元测试。
2. 关卡给 diff 打分，返回分流结果。
3. `block` 拦住合并；`needs_owner` 指派评审者；其余走正常路径。

先让它只提示、不拦截。用几十个真实变更，把它的判断与评审者实际做的决定对照之后，再考虑让它真的能拦。

## 费用与限制

每 4KB 算一块，不足 4KB 也按一块。费用 = 块数 × 问题数 × 模型单价。大 diff 按字节计费，所以传补丁而不是整个仓库。

超大 diff 可能需要先摘要；发送生成的 lockfile 或 vendored 依赖树之前，先看[模型页](https://system-one.dev/zh-CN/models/jev)上的请求上限。

新账号注册即送 100 积分，积分不会过期。详见 [定价](https://system-one.dev/zh-CN/pricing)。

[在线试用合并风险示例（需登录）](https://system-one.dev/zh-CN/demo/code-review-risk)，用示例数据看这两道问题。


## 常见问题

### 它能取代代码评审吗？

不能。它给风险排序、标出安全暴露面；正确性、设计与测试仍然由评审者和 CI 负责。

### 怎么避免 diff 操纵判断？

把 diff 当数据而不是指令。任务写在问题文本里，补丁放在 state 字段中；然后把关卡输出当作普通工具输出一样复核。

### 大 diff 能用吗？

它按请求字节计费，每个模型还有请求上限。diff 很大时，给改动的文件与摘要打分，而不是整个补丁。

### 什么时候该拦而不是提示？

只有在它与你的评审者在真实变更上的决定对照过、阈值也校准过之后。先只提示。
