> ## Documentation Index
> Fetch the complete documentation index at: https://agent-compass.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# 网络策略

为 baseline、run 和 evaluation 三种网络策略进行选择、配置、验证和排查。

AgentCompass 可以分别控制可信 Environment 准备、完整的不可信运行边界以及正式验证阶段的出站网络。你可以用它复现 Benchmark 官方策略、防止 agent 获取外部解答，或只放行受控评测所需端点。

首先遵循所选 Benchmark 声明的策略。改变网络访问会改变任务难度和结果可比性，因此对齐运行不应静默放宽或收紧官方设置。

## 为每个阶段选择策略

网络策略会针对每个任务独立解析。Benchmark loader 可以在每个 `TaskSpec` 上声明三个字段，因此同一次运行中的两个 sample 可以使用不同策略。通过 `--env-params` 传入的值作用于整次运行，会显式覆盖每个已选 sample 的对应阶段：

| 字段                          | 保护阶段                                                                                          | 常见选择                                                                      |
| --------------------------- | --------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------- |
| `baseline_network_policy`   | Environment startup、benchmark preparation、可信 harness setup 和全新 evaluation Environment startup | 默认为 `public`；需要安装 package 或 harness executable 时保持 `public`               |
| `run_network_policy`        | Agent 或 harness rollout、Harness 关闭、artifact 收集以及 agent Environment 的剩余生命周期                    | 默认为 `public`；隔离 coding task 常用 `no-network`                               |
| `evaluation_network_policy` | 在复用 task Environment 或全新 evaluation Environment 中执行正式评测                                       | 默认为 `public`；本地测试使用 `no-network`，grading 依赖外部服务时使用 `allowlist` 或 `public` |

每个阶段按以下优先级解析：

| 优先级 | 来源                                         | 作用域                  |
| --- | ------------------------------------------ | -------------------- |
| 1   | 显式 Environment 覆盖，包括 `--env-params`        | 本次运行的所有已选任务          |
| 2   | Benchmark loader 写入 `TaskSpec` 的 sample 策略 | 单个任务                 |
| 3   | 兼容 Recipe 提供的策略                            | 每个匹配任务               |
| 4   | Runtime 默认值                                | 每个未设置的阶段独立取 `public` |

省略字段表示“继续使用下一层来源”；如果没有来源提供该阶段，就独立取 `public`。因此在没有其他来源提供策略时，显式传入 `public` 与不传值的实际策略相同。需要强制整次运行使用同一策略时使用 `--env-params`；需要保留官方逐 sample 行为时则省略这些覆盖，让 Benchmark 加载任务策略。Recipe 可以检查 Harness 所需的 endpoint，但不会改变已经解析出的策略；最终策略和 `applied_recipes` 会记录这一结果。

<Info>
  Harness 准备在应用 `run_network_policy` 之前发生，因此可信 Harness 可以在基线策略下安装 runtime，再在更严格的策略下运行不可信 agent。网络阶段是函数级信任边界，并非为每个进度阶段分别设置一项策略。
</Info>

## 理解函数级边界

AgentCompass 对两种评测 Environment 模式应用同一条 evaluation 规则：只有完整的 `benchmark.evaluate()` 函数调用使用 `evaluation_network_policy`。两种模式的区别在于 `fresh` 会创建另一个 Environment，而 `reuse` 在 agent Environment 中执行评测。fresh 运行中的 `evaluate_environment` 只是进度阶段，不是独立的 Benchmark hook；其准备边界对应评测 provider 的 `open()` 调用。

下表展示 Environment 操作执行时的有效策略。AgentCompass host 发出的 provider control-plane 请求位于 sandbox 网络强制范围之外。一个函数内部可以包含多个操作；runtime 不会继续把这些操作拆分成更细的策略作用域。

### Shared Environment

`reuse` 时，始终使用同一个 Environment，其生命周期函数依次经过 baseline、run 和 evaluation 策略：

| 顺序 | runtime 函数边界                                  | Environment | 有效策略                        | 条件                        |
| -- | --------------------------------------------- | ----------- | --------------------------- | ------------------------- |
| 1  | `environment_provider.open()`                 | Shared      | `baseline_network_policy`   | 始终执行                      |
| 2  | `benchmark.prepare_task()`                    | Shared      | `baseline_network_policy`   | 始终执行                      |
| 3  | `harness.start_session()`                     | Shared      | `baseline_network_policy`   | 仅使用 Harness 的 Benchmark   |
| 4  | `harness.run_task()` 或 `benchmark.run_task()` | Shared      | `run_network_policy`        | 根据实际情况从两条推理路径中选择一条        |
| 5  | `harness.close_session()`                     | Shared      | `run_network_policy`        | 已创建 Harness session 时     |
| 6  | `benchmark.collect_artifacts()`               | Shared      | `run_network_policy`        | 推理返回结果时调用；默认 hook 不执行额外操作 |
| 7  | `benchmark.evaluate()`                        | Shared      | `evaluation_network_policy` | 始终执行；接收同一个 Environment    |
| 8  | `environment_provider.close()`                | Shared      | `baseline_network_policy`   | 未保留 Environment 时         |

在第 7 步之前，runtime 会从 `run_network_policy` 直接切换到 `evaluation_network_policy`，调用完整的 `benchmark.evaluate()` 函数，并在 `finally` 中恢复 `baseline_network_policy`。这样无需经过一次中间 baseline 切换，也能把 evaluation 策略限制在评测函数范围内。

### Seperate Environment

`fresh` 会先结束 agent Environment 的生命周期，再创建独立的 evaluation Environment：

| 顺序 | runtime 函数边界                                  | Environment | 有效策略                        | 条件                        |
| -- | --------------------------------------------- | ----------- | --------------------------- | ------------------------- |
| 1  | `environment_provider.open()`                 | Agent       | `baseline_network_policy`   | 始终执行                      |
| 2  | `benchmark.prepare_task()`                    | Agent       | `baseline_network_policy`   | 始终执行                      |
| 3  | `harness.start_session()`                     | Agent       | `baseline_network_policy`   | 仅使用 Harness 的 Benchmark   |
| 4  | `harness.run_task()` 或 `benchmark.run_task()` | Agent       | `run_network_policy`        | 从两条推理路径中选择一条              |
| 5  | `harness.close_session()`                     | Agent       | `run_network_policy`        | 已创建 Harness session 时     |
| 6  | `benchmark.collect_artifacts()`               | Agent       | `run_network_policy`        | 推理返回结果时调用；默认 hook 不执行额外操作 |
| 7  | `environment_provider.close()`                | Agent       | `run_network_policy`        | 未保留 agent Environment 时   |
| 8  | `evaluation_provider.open()`                  | Evaluation  | `baseline_network_policy`   | `fresh` 模式下始终执行           |
| 9  | `benchmark.evaluate()`                        | Evaluation  | `evaluation_network_policy` | 始终执行；接收全新 Environment     |
| 10 | `evaluation_provider.close()`                 | Evaluation  | `baseline_network_policy`   | 未保留评测 Environment 时       |

第 8 步是选择 `fresh` 后引入的条件性评测 Environment 准备阶段，并不是可选的 Benchmark hook。runtime 只在 `evaluation_provider.open()` 完成后切换到 evaluation 策略，在 `benchmark.evaluate()` 结束后立即恢复评测 Environment 的基线策略，然后释放或保留该 Environment。

`benchmark.collect_artifacts()` 的可选性不同：它是带默认空实现的标准条件调用点。只有需要在 agent Environment 释放前固化 agent 输出的 Benchmark 才会覆写它。该 hook 始终位于 run 信任边界内，不会产生新的网络阶段。

## 网络模式

每个阶段支持四种 mode：

| 模式           | 行为                               | 适用场景                                                |
| ------------ | -------------------------------- | --------------------------------------------------- |
| `public`     | 允许正常出站访问。                        | Setup 需要 package registry、source download 或不受限外部服务。 |
| `no-network` | 阻止出站网络。                          | Task 必须只根据提供的 workspace 和本地工具解决。                    |
| `allowlist`  | 仅允许显式列出的 host、address 或 network。 | Agent 需要 model endpoint 或受控服务，但不应访问通用互联网。           |
| `denylist`   | 保持正常出站访问，但阻止显式列出的 target。        | 兼容的 Provider 需要广泛网络访问，同时必须屏蔽少量 endpoint。            |

`public` 和 `no-network` 可直接使用字符串：

```bash theme={"system"}
export MODEL_NAME=""

agentcompass run <benchmark> <harness> "$MODEL_NAME" \
  --env docker \
  --env-params '{
    "baseline_network_policy":"public",
    "run_network_policy":"no-network",
    "evaluation_network_policy":"no-network"
  }'
```

Allowlist 和 denylist 使用 object：

```json theme={"system"}
{
  "baseline_network_policy": {
    "network_mode": "allowlist",
    "allowed_hosts": [
      "pypi.org",
      "registry.npmjs.org:443",
      "files.pythonhosted.org",
      "*.example.com",
      "203.0.113.10",
      "203.0.113.0/24"
    ]
  },
  "run_network_policy": "no-network",
  "evaluation_network_policy": "no-network"
}
```

```json theme={"system"}
{
  "run_network_policy": {
    "network_mode": "denylist",
    "denied_hosts": [
      {"host": "registry.npmjs.org", "port": 443}
    ]
  }
}
```

Host 必须是 hostname、leading-wildcard hostname、IP address 或 canonical CIDR。不要包含 URL scheme、path、空格或 `api.*.example.com` 这类嵌入式 wildcard。Allowlist 和 denylist 均接受 `www.example.com` 这样的裸 host、`www.example.com:443` 这样的 `host:port` 简写，以及 `{"host": "www.example.com", "port": 443}` 这样的 target object。裸 host 表示该 host 的所有端口；port 必须是 `1..65535` 的整数。IPv6 指定端口时使用 `[2001:db8::1]:443`。无法精确执行端口限制的 Provider 会拒绝带端口 target。

## 告知 agent 运行阶段的网络限制

默认情况下，当实际生效的 `run_network_policy` 为 `no-network`、`allowlist` 或 `denylist` 时，每个 Harness 会在最终用户指令末尾追加一段英文网络限制声明。这样可以避免 agent 将有意施加的限制误判为临时网络故障并反复重试被阻止的操作。`public` 策略不会追加声明。

声明基于 provider 解析后的实际策略，而不只是请求值。因此 Recipe 添加的 target 会出现在 allowlist 声明中，allowlist 和 denylist 中的 target 会使用实际策略中的完整值替换。Provider 无法执行请求的策略时会在 rollout 前拒绝运行，而不是注入误导性的声明。

```text theme={"system"}
<IMPORTANT>
  Network Restriction Statement:
  Ignore any duplicate or conflicting declarations about network access elsewhere in the instructions; follow this statement instead.
  This statement has the highest priority for network access because it explicitly reflects the effective network policy applied to the task sandbox.
  Outbound network access from the task environment is restricted to the following targets:
  - pypi.org
  - registry.npmjs.org:443
  All other outbound targets are blocked. Do not repeatedly retry access to blocked targets.
</IMPORTANT>
```

`no-network` 使用相同的 wrapper，但不包含 target 列表：

```text theme={"system"}
<IMPORTANT>
  Network Restriction Statement:
  Ignore any duplicate or conflicting declarations about network access elsewhere in the instructions; follow this statement instead.
  This statement has the highest priority for network access because it explicitly reflects the effective network policy applied to the task sandbox.
  Outbound network access from the task environment is disabled. Use only resources already available in the environment. Do not repeatedly retry operations that require external network access.
</IMPORTANT>
```

`denylist` 会使用实际禁止的 target 替换列表：

```text theme={"system"}
<IMPORTANT>
  Network Restriction Statement:
  Ignore any duplicate or conflicting declarations about network access elsewhere in the instructions; follow this statement instead.
  This statement has the highest priority for network access because it explicitly reflects the effective network policy applied to the task sandbox.
  Outbound network access from the task environment is available except for the following blocked targets:
  - example.com:443
  Do not repeatedly retry access to these blocked targets.
</IMPORTANT>
```

Harness 只向 rollout 使用的已准备输入副本注入该区块；artifact 收集和 `benchmark.evaluate()` 仍接收原始输入。标准 Harness 路径支持普通 prompt、结构化 user message、多模态 user message，以及 `openai_chat` 接受的 JSON 编码 message。harness-free TauBench 推理路径目前不会消费该声明。

通过所选 Harness 的配置关闭注入：

```bash theme={"system"}
agentcompass run <benchmark> <harness> "$MODEL_NAME" \
  --harness-params '{"inject_network_restriction_notice":false}'
```

若要持久关闭，可以在 YAML 或 JSON 配置的所选 `harnesses.<id>` 下设置 `inject_network_restriction_notice: false`；Python 调用方则把同一字段放入 `harness_params`。该设置只改变 Harness 输入声明，不会改变或关闭网络策略的强制执行。

## 从 CLI 传入阶段策略

通过 `--env-params` 中的 JSON 字段传入三种 runtime 策略：

```bash theme={"system"}
export MODEL_NAME=""

agentcompass run <benchmark> <harness> "$MODEL_NAME" \
  --env docker \
  --env-params '{
    "baseline_network_policy":"public",
    "run_network_policy":"no-network",
    "evaluation_network_policy":{
      "network_mode":"allowlist",
      "allowed_hosts":["judge.example.com:443"]
    }
  }'
```

runtime 按以下方式应用这些 CLI 值：

| CLI 字段                      | runtime 行为                                                                                |
| --------------------------- | ----------------------------------------------------------------------------------------- |
| `baseline_network_policy`   | 使用该策略创建每个 Environment，并在 `benchmark.prepare_task()` 和 `harness.start_session()` 执行期间保持生效。 |
| `run_network_policy`        | 在推理前切换到该策略，并在 Harness 关闭和 `benchmark.collect_artifacts()` 执行期间保持生效。                       |
| `evaluation_network_policy` | 在完整的 `benchmark.evaluate()` 调用期间切换到该策略，结束后恢复基线策略。                                         |

也可以通过 [Python API](/zh/user_guide/using_agentcompass/python_api) 的 `environment_params` 传入相同字段，或者由 Benchmark loader 在 `TaskSpec` 上声明 sample 级策略。

## 选择最小可用策略

按以下顺序决定：

1. 查看 Benchmark 页面声明的官方或推荐策略。
2. 确认 Harness 在哪里安装，以及 model API 请求从哪里发出。
3. sandbox 需要安装软件包或可执行文件时保持基线策略为 `public`；否则优先允许列表或预构建镜像。
4. 任务应只使用本地证据时，将运行阶段设为 `no-network`。
5. Harness 关闭或 artifact 收集所需的 endpoint 必须包含在运行策略中；rollout 与验证之间不会放宽策略。
6. 只添加依赖网络阶段真正需要的 model、搜索、评委、软件包或 artifact host。
7. 先运行一个任务并检查解析后执行计划，再扩大规模。

AgentCompass 驱动使用的 Python 软件包安装在任务 sandbox 之外，不受这些策略控制。由 `harness.start_session` 在 Environment 内安装的软件包或 CLI 工具使用基线策略。若基线策略也必须是 `no-network`，需要先把依赖放入任务镜像或快照。

model 端点是否需要允许列表，取决于 Harness 在哪里发出请求：

* 本地 Harness 进程从 AgentCompass 主机调用 model，不受任务 Environment 策略控制。
* 在 sandbox 内运行的 Harness 需要把 model 端点加入运行阶段允许列表。
* 部分 Benchmark Recipe（包括 DeepSWE）会推断实际 model 端点。不要假设所有自定义 Benchmark 或外部 Recipe 都会这样做；请检查解析后计划。
* `run_network_policy` 的语义与来源无关。DeepSWE 会校验所需 model 端点是否被允许；如果 task 或 CLI 的有效策略阻止这些端点，计划构建会失败，Recipe 不会扩大该策略。remote Harness 需要使用 CLI 显式覆盖为包含模型 host 的 `allowlist`；local Harness 可以继续使用 `no-network`。

评委和搜索服务同理。AgentCompass 驱动发出的请求在 sandbox 策略之外；任务或验证器 Environment 内的进程发出的请求必须在对应阶段中获准。

## provider 支持

| provider       | 模式                                | 动态阶段切换 | 重要限制                                                                            |
| -------------- | --------------------------------- | ------ | ------------------------------------------------------------------------------- |
| `host_process` | 仅 `public`                        | 否      | 无法提供 sandbox network isolation。                                                 |
| `docker`       | `public`、`no-network`、`allowlist` | 是      | Phase switching 需要 bridge-style network；allowlist 使用 egress proxy sidecar。      |
| `daytona`      | `public`、`no-network`、`allowlist` | 是      | 支持 domain、wildcard domain、IPv4 address 和 IPv4 CIDR；domain 与 network entry 不能混用。 |
| `modal`        | `public`、`no-network`、`allowlist` | 是      | 支持 domain、IPv4 和 IPv6；动态切换需要兼容的 Modal SDK。                                      |

Daytona 最多接受 20 个域名条目或 10 个 IPv4 网络条目。Docker 的 `network` 设置为 `none`、`host` 或 `container:<id>` 时不能使用动态阶段策略。默认允许列表代理镜像是`python:3.12-alpine`；离线主机需要确保 Docker 守护进程已能获取该镜像。

Daytona `network_block_all`、Modal `block_network` 等 provider 原生字段描述 provider 创建选项。评测策略应优先使用上面的 provider 中立阶段字段，因为它们在 Docker、Daytona 与 Modal 间保持一致。

<Warning>
  当前公开文档中的 Provider 均不强制执行 `denylist`。AgentCompass 会拒绝该策略，而不会静默放宽为 `public`。如果有意接受不同的网络行为，请通过 `--env-params` 将对应的 `baseline_network_policy`、`run_network_policy` 或 `evaluation_network_policy` 显式覆盖为受支持的 mode。
</Warning>

## 验证实际 Policy

使用持久化调试日志运行一个已知任务：

```bash theme={"system"}
export MODEL_NAME=""

agentcompass run <benchmark> <harness> "$MODEL_NAME" \
  --env docker \
  --benchmark-params '{"sample_ids":["<task-id>"]}' \
  --env-params '{
    "baseline_network_policy":"public",
    "run_network_policy":"no-network",
    "evaluation_network_policy":"no-network"
  }' \
  --task-concurrency 1 \
  --max-retries 0 \
  --log-level INFO \
  --file-log-level DEBUG
```

每个任务执行计划构建时，运行日志会记录 `baseline_network_mode`、`run_network_mode` 和 `evaluation_network_mode`。每个任务详情还会保存最终策略与 `applied_recipes`。由于 Benchmark Recipe 可能添加推断端点或 provider 适配，请验证实际解析后的值，不要只依赖原始命令。

进行对抗性隔离测试时，可以要求 agent 访问一个已知外部 URL，并同时确认：

* 受限运行阶段中请求失败；
* 同一个 Environment 仍能完成基线策略允许的可信准备工作。

对于支持的终端轨迹，[`NetworkOperationAnalyzer`](/zh/user_guide/using_agentcompass/cli/analysis) 可以汇总 `curl`、`wget`、软件包安装或 `git clone` 等命令。它只能观察 agent 行为，不会强制策略，也不能替代 provider 切换日志。

<Warning>
  单次应用请求失败本身不足以证明网络隔离生效，因为 DNS、凭证或服务不可用也会导致失败；还需要确认解析后策略和 provider 切换日志。
</Warning>

## 排查网络失败

| 现象                              | 可能原因                                                         | 操作                                                            |
| ------------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------- |
| Harness 在 setup 阶段安装失败          | Baseline 受限，或缺少 registry host。                               | 使用 `public`、扩展 baseline allowlist，或在 image 中预装 harness。       |
| Model call 只在 harness setup 后失败 | Harness 在 sandbox 内请求 model，但运行策略阻止 endpoint。                | 将 endpoint hostname 加入 `run_network_policy.allowed_hosts`。    |
| Rollout 成功后 artifact 收集失败       | Session close 或收集 hook 需要访问被运行策略阻止的 endpoint。                | 只向 `run_network_policy` 添加必要 artifact endpoint，或保持本地收集。       |
| Allowlisted URL 仍被阻止            | 缺少 redirect、artifact CDN、authentication host 或 DNS target。   | 检查完整请求链并只加入确切 host，避免宽泛 wildcard。                             |
| Daytona 拒绝 allowlist            | 混用了 domain 与 IPv4 network、使用了 IPv6，或超过 provider entry limit。 | 只使用一种受支持 entry family，并遵守 provider limit。                     |
| Docker 拒绝 phase switching       | 所选 Docker network 不是 bridge-style。                           | 删除自定义 network，或使用 bridge network。                             |
| Docker egress proxy 无法启动        | Proxy image 不可用、Docker 权限不足或启动 timeout 太短。                   | 在线时拉取镜像、验证 Docker access，或增加 `allowlist_proxy_start_timeout`。 |
| Modal 或 Daytona 报告不支持动态切换       | 已安装 provider SDK 缺少所需 runtime API。                           | 通过 AgentCompass installation 升级 provider SDK，再重试一个 task。      |
| Rollout 成功后 verification 失败     | Verifier 需要被其 policy 阻止的本地依赖或外部服务。                           | 优先使用预构建 verifier；否则只为 verifier phase 配置必要访问。                  |

失败并非网络强制执行专属时，继续参考[评测故障排查](/zh/user_guide/other_features/troubleshooting)。

## 相关页面

* [选择 Environment](/zh/user_guide/modules/environments/overview)
* [sandbox 资源限制](/zh/user_guide/modules/environments/configuration/resource_limits)
* [Recipe](/zh/user_guide/other_features/recipes)
* [评测故障排查](/zh/user_guide/other_features/troubleshooting)
