> ## 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.

# 评测模式与产物

根据验证器需要访问的状态选择 `none`、`reuse` 或 `fresh`，并在任务 Environment 关闭前提取后续评测所需的产物。

## 三种模式

| 模式      | <span style={{ display: "inline-block", minWidth: "14rem" }}><code>evaluate()</code> 收到的 <code>env</code></span> | 生命周期                                           | 适用情况                   |
| ------- | ---------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- | ---------------------- |
| `none`  | `None`                                                                                                           | 执行和产物收集后关闭任务 Environment，再在 AgentCompass 进程中评测 | 精确匹配、结构化答案、进程内评测器      |
| `reuse` | 当前任务 `EnvironmentSession`                                                                                        | 执行、产物收集和评测都完成后才关闭任务 Environment                | 验证器必须检查执行后的同一文件系统或服务状态 |
| `fresh` | 新建的评测 `EnvironmentSession`                                                                                       | 提取产物并关闭任务 Environment，再打开独立评测 Environment      | 需要隔离测试、干净镜像或不同评测网络策略   |

`collect_artifacts()` 在三种模式下都会于任务 Environment 存活期间调用。它的职责是提取提交物，不是决定分数。

## 设置默认值和逐任务覆盖

如果所有样本都使用同一种模式，请在 Benchmark 类上设置默认值：

```python theme={"system"}
class ExampleBenchmark(BaseBenchmark):
    evaluation_environment_mode = "reuse"
```

如果不同样本需要不同的验证方式，请在 `TaskSpec` 上分别设置：

```python theme={"system"}
TaskSpec(
    task_id=task_id,
    question=question,
    category=category,
    ground_truth=ground_truth,
    evaluation_environment_mode="fresh",
)
```

runtime 规划器按以下顺序解析模式：

```text theme={"system"}
RunRequest.environment.evaluation_environment_mode
  > TaskSpec.evaluation_environment_mode
  > Benchmark.resolve_evaluation_environment_mode(req)
```

这是创建初始 `ExecutionPlan` 时的选择顺序。随后启用的 Recipe 可以按自身契约调整计划；如果 Recipe 会修改评测 Environment，必须在实现和测试中明确哪些字段可以覆盖、哪些字段必须保留。排查实际生效的模式时，应查看 `run_info.json` 的 `resolved_execution_plans`，其中记录了 Recipe 调整后的计划。

## `none`：进程内评分

`none` 适合只依赖 `TaskSpec`、`PreparedTask` 和 `RunResult` 的评测器。不要在这种模式下读取任务工作区：

```python theme={"system"}
async def evaluate(
    self,
    task: TaskSpec,
    prepared: PreparedTask,
    result: RunResult,
    req: RunRequest,
    plan: ExecutionPlan,
    env: EnvironmentSession | None = None,
) -> RunResult:
    _ = task, prepared, req, plan
    if env is not None:
        raise RuntimeError("none evaluation must not receive an Environment")
    return score_answer(result)
```

如果进程内评测器需要调用另一个 Model，应显式配置评审 Model，并记录其版本和推理参数；不要默认让被测 Model 为自己的结果评分。

## `reuse`：检查当前任务 Environment

`reuse` 在任务 Environment 关闭前执行评测，因此验证器能看到 agent 最终留下的工作区：

```python theme={"system"}
class WorkspaceBenchmark(BaseBenchmark):
    evaluation_environment_mode = "reuse"

    async def evaluate(
        self,
        task: TaskSpec,
        prepared: PreparedTask,
        result: RunResult,
        req: RunRequest,
        plan: ExecutionPlan,
        env: EnvironmentSession | None = None,
    ) -> RunResult:
        _ = task, prepared, req, plan
        if env is None:
            raise RuntimeError("workspace verification requires reuse mode")
        verifier = await env.exec(
            ["python3", "/opt/verifier/check.py"],
            timeout=300,
        )
        return apply_verifier_result(result, verifier)
```

验证器路径和依赖必须存在于任务 Environment 中。评测阶段使用解析后的 `evaluation_network_policy`；不要假定执行阶段仍保留原有的网络权限。

完整的 `reuse` 生产实现可参考 [`terminalbench2.py`](https://github.com/open-compass/AgentCompass/blob/main/src/agentcompass/benchmarks/terminalbench2/terminalbench2.py)。

## `fresh`：先提取，再隔离验证

`fresh` 不会自动把任务工作区复制到评测 Environment。先在 `collect_artifacts()` 中把提交物转成可跨 Environment 传递的 `RunResult.artifacts`：

```python theme={"system"}
from dataclasses import replace


async def collect_artifacts(
    self,
    task: TaskSpec,
    prepared: PreparedTask,
    result: RunResult,
    env: EnvironmentSession,
    req: RunRequest,
    plan: ExecutionPlan,
) -> RunResult:
    _ = task, prepared, req
    benchmark_plan = self._require_plan(plan.benchmark_plan)
    patch = await env.read_text(benchmark_plan.submission_path)

    artifacts = dict(result.artifacts)
    files = dict(artifacts.get("file") or {})
    files["submission.patch"] = patch
    artifacts["file"] = files
    return replace(result, artifacts=artifacts)
```

任务 Environment 关闭后，runtime 打开新的评测 Environment，并把它传给 `evaluate()`。评测器负责将捕获的产物写入新 Environment，再运行官方验证器：

```python theme={"system"}
async def evaluate(
    self,
    task: TaskSpec,
    prepared: PreparedTask,
    result: RunResult,
    req: RunRequest,
    plan: ExecutionPlan,
    env: EnvironmentSession | None = None,
) -> RunResult:
    _ = task, prepared, req, plan
    if env is None:
        raise RuntimeError("isolated verification requires fresh mode")

    patch = str(result.artifacts["file"]["submission.patch"])
    await env.write_text("/tmp/submission.patch", patch)
    verifier = await env.exec(
        ["bash", "/opt/verifier/run.sh", "/tmp/submission.patch"],
        timeout=600,
    )
    return apply_verifier_result(result, verifier)
```

生产实现还应限制产物大小、检查文件类型并处理空提交，同时在结果证据中记录验证器返回码、超时状态和截断后的输出。完整的 `fresh + collect_artifacts()` 实现可参考 [`deepswe.py`](https://github.com/open-compass/AgentCompass/blob/main/src/agentcompass/benchmarks/deepswe.py)。

## 选择模式时检查

* 评分只依赖答案或内存对象时选 `none`，不要为简单评分额外创建 sandbox。
* 验证器必须看到 agent 修改后的原始文件系统时选 `reuse`，并确保验证器不会污染后续需要保留的结果。
* 验证器不应信任 agent 留下的依赖或进程时选 `fresh`，并明确传输的最小提交物。
* `prepare_task()`、`collect_artifacts()` 中执行的命令以及验证器命令都要设置明确的超时，并保证重试时可以安全重复。
* 评测失败与正常零分必须使用不同状态，具体映射见[结果与聚合](/zh/developer_guide/extensions/benchmark/code_implementation/results_and_aggregation)。
