---
title: "Harness"
description: "一个会话运行一个智能体 Harness：标准运行器 或实验运行器。本页面介绍项目如何选择其中一个，以及各自支持的功能。"
---

Harness 是会话沙箱中的 agent 运行时。它运行模型循环、调用工具并生成对话记录。Beeuni 有两个 harness：**标准运行器**（默认）和 **实验运行器**。每个会话恰好运行一个。

两个 harness 读取相同的项目内容：`beeuni.yaml`、`agents/` 中的 agent 文件、`skills/` 中的技能、根目录 `AGENTS.md`，以及 `memory/`。各客户端（Web、CLI、TUI、移动端、SDK）通过同一个会话 API 读取两者。区别在于下方[矩阵](#what-each-harness-supports)所列的会话功能，以及每个 harness 读取的自身配置文件。

<a id="how-a-session-selects-its-harness"></a>

## 会话如何选择 harness

Beeuni 会在会话启动、重启或恢复时做出决定。在此之前，运行中的会话会一直使用原来的 harness。

| 规则（按顺序） | Harness |
| --- | --- |
| 项目的 `llm_gateway` 标志为关闭 |标准运行器|
| 项目的 `pi_harness` 标志为开启 |实验运行器|
| `beeuni.yaml` 将 `runtime: pi` 设为相应值 |实验运行器|
| 其他情况 |标准运行器|

-实验运行器只能通过 Beeuni LLM 网关调用模型。`llm_gateway` 关闭的项目会启动标准运行器，无论标志或清单如何设置。请参阅[模型](/docs/zh/project/models)。
- `runtime` 是 `beeuni_version: 2` 清单键。旧版 `beeuni.toml` 项目无法设置此键。请参阅[清单参考](/docs/zh/project/manifest)。
- `pi_harness` 是按项目设置的功能标志，默认关闭。请参阅[功能标志](/docs/zh/feature-flags)。

要查看会话运行的是哪个 harness，请读取沙箱守护进程的 `GET /beeuni/health` 响应中的 `harness.id`：`opencode` 或 `pi`。

<a id="what-each-harness-supports"></a>

## 各 harness 支持的功能

Harness 会在 `GET /beeuni/health` 的 `capabilities` 数组中列出其提供的可选会话功能。如果会话的 `capabilities` 中没有相应 ID，客户端就会隐藏该控件。SDK 中的检查项是 `runtimeSupports`。

<a id="both-harnesses"></a>

### 两个 harness 均支持

| 功能 |标准运行器|实验运行器|
| --- | --- | --- |
| 聊天轮次、流式传输、停止 | 是 | 是 |
| Agent `.md`：提示词、`model`、`variant`、`mode`、`permission`、`temperature`、`top_p`、`steps` | 是 | 是。实验运行器 不应用 `options`（provider 选项）。 |
| 按 agent 设置[工具访问权限](/docs/zh/project/tools#who-may-use-which-tool)（`beeuni.yaml` 中的 `agents.<name>.tools`：`all`、`none`、列表、`exclude`） | 是 | 是 |
| 按 agent 设置 `permission` 规则和权限请求 | 是 | 是 |
| 问题（`question` 工具） | 是 | 是 |
| 项目的根目录 `AGENTS.md` 规则文件；如果根目录中没有 `AGENTS.md`，则使用 `CLAUDE.md` | 是。标准运行器 也会读取 `/workspace` 的父目录中的文件，并在运行配置发布时读取 `/workspace`。 | 是，仅根目录文件。它是会话和每个子 agent 系统提示词的一部分。[启用配置发布时](#agentsmd-on-pi)，实验运行器 读取发布副本。 |
| 子 agent（`task` 工具）、`session.subagents` | 是 | 是：`general`、`explore`（只读），以及每个带有 `mode: subagent` 或 `all` 的项目 agent。子 agent 不能再启动其他子 agent。 |
| 技能（`skills/` 和受管理的 `beeuni-*` 技能），受 agent 的 `skills` 授权控制 | 是。Agent 使用 `skill` 工具加载技能。 | 是。系统提示词会列出每个获授权的技能；agent 会读取对应文件。 |
| [Beeuni 工具](/docs/zh/project/tools#beeuni-tools-in-beeuniyaml)：`web_search`、`image_search`、`scrape_webpage`、`memory`、`show`。如果 `beeuni.yaml` 中没有 `tools:` 键，则五个工具全部启用；如果有，则启用其中列为 `beeuni:<name>` 的工具 | 是 | 是 |
| [项目工具](/docs/zh/project/tools)（`beeuni.yaml` 中的 `tools:`） | 是 | 是 |
| [配置发布](/docs/zh/work/runtime#config-convergence)、`config.release.v1` | 是 | 是 |
| 按需或在模型上下文窗口接近上限时自动精简（总结）对话，`session.compact` | 是 | 是。模型请求超出窗口时会精简上下文并重试一次。 |
| 项目斜杠命令，`session.commands` | 是，来自标准运行器配置目录中的 `commands/`。 | 是，来自实验运行器配置目录和实验运行器包中的 `prompts/` 提示词模板。实验运行器 不读取标准运行器的 `commands/`。 |
| 沙箱中的终端（PTY） | 是 | 是 |
| `bash`、`read`、`write`、`edit`、`glob`、`grep` 工具；Shell 中的[密钥](/docs/zh/project/secrets)；`beeuni` CLI | 是 | 是 |

Beeuni 工具和项目工具与 harness 无关](/docs/zh/project/tools)：沙箱守护进程为两个 harness 的每种工具运行同一个模块，名称、参数和输出均相同。实验运行器 在守护进程的进程中调用这些工具；标准运行器 则通过守护进程编写的插件调用。两个 harness 获取相同的工具列表：如果项目的 `tools:` 键未列出某个 Beeuni 工具，两个 harness 都不会启用该工具。项目中如果 `harnesses/opencode/tools/` 仍留有 Beeuni 工具的副本，标准运行器 会继续保留这些副本，直到项目将其删除。

两个 harness 上的 Web 工具都遵循 `websearch`（`web_search`、`image_search`）和 `webfetch`（`scrape_webpage`）权限键。在标准运行器中，这些工具无法请求权限：`ask` 规则会拒绝它们。在实验运行器中，`ask` 规则会发起权限请求。在实验运行器中，修改文件的 `memory` 命令遵循 `edit`，而 `view` 遵循 `read`；在标准运行器中，只有 `memory` 规则会控制该工具。

<a id="agentsmd-on-pi"></a>

### `AGENTS.md` 在实验运行器中

实验运行器 会将项目根目录中的 `AGENTS.md` 作为一个章节放入系统提示词中，位置在 agent 提示词之后，即 `<project_instructions path="AGENTS.md">`。如果根目录中没有 `AGENTS.md`，则会像标准运行器一样改用 `CLAUDE.md`。实验运行器 不读取子目录或父目录中的任何 `AGENTS.md`。

- **来源。**关闭[配置发布](/docs/zh/work/runtime#config-convergence)时，实验运行器 读取 `/workspace/AGENTS.md`。启用后，实验运行器 读取发布中的副本，不会读取 `/workspace` 中的文件：在 `/workspace` 中的更改要合并到基分支后才会对会话生效。启用配置发布但没有可用的发布版本（`config.source: image-default`）时，实验运行器 不读取任何 `AGENTS.md`，就像它不会读取任何项目技能一样。
- **时机。**实验运行器 会在运行时启动、配置重新加载（新发布版本、`/beeuni/env` 推送）以及仓库刷新后读取此文件。它不会在每轮对话前读取。新发布版本无需重启即可在下一轮生效；正在进行的轮次仍使用旧文件。
- **跳过的文件。**空文件、非普通文件，以及解析到仓库外部的符号链接都不会产生任何内容。后两种情况会在守护进程日志中写入一条警告。
- **检查。**守护进程 `GET /beeuni/health` 中的 `harness.details.agentsMd` 会列出实验运行器加载的文件：`source`（`release` 或 `workspace`）、`path`、`bytes` 和 `sha`（其 sha256 的前 12 个十六进制字符）。如果实验运行器未加载任何文件，则为 `null`。

<a id="opencode-only-today"></a>

### 目前仅标准运行器支持

| 功能 | 能力 |标准运行器|实验运行器|
| --- | --- | --- | --- |
| 回退到某条消息并恢复。编辑后重新发送会使用回退功能。 | `session.rewind` | 是 | 否 |
| MCP 服务器（`opencode.jsonc` 中的 `mcp`） | `session.mcp` | 是 | 否。没有 MCP 客户端。[连接器](/docs/zh/connect/connectors)可通过 `beeuni connectors` CLI 在两个 harness 上使用。 |
| 待办列表（`todowrite` 工具）和计划卡片 | `session.todo` | 是 | 否。计划卡片保持为空。 |
| 连接 harness 自带的终端客户端（`beeuni connect`、TUI `Alt+o`） | `session.attach` | 是 | 否。请参阅[TUI](/docs/zh/cli#sessions)。 |
| 运行时配置文档（`/global/config`） | `session.config` | 是 | 否。两个 harness 的 agent 和模型都来自项目。 |
| 在某条消息处分叉会话 | `session.fork` | 是 | 否 |
| 作为一个轮次运行 Shell 命令 | `session.shell` | 是 | 否 |
| 不通过 LLM 网关的模型提供方 | — | 是 | 否。实验运行器 需要开启 `llm_gateway`。 |

实验运行器 会通过 `501 feature_not_supported` 响应它不提供的功能请求；如果请求的是它没有的文档（`/global/config`），则会返回 `404`。它不会忽略该请求。

<a id="harness-configuration-files"></a>

## Harness 配置文件

每个 harness 都有一个专用目录，存放仅由该 harness 读取的文件。

| |标准运行器|实验运行器|
| --- | --- | --- |
| 目录 | `harnesses/opencode/`，或 `opencode.config_dir` | `harnesses/pi/`，或 `pi.config_dir` |
| 旧版目录 | `.beeuni/opencode/` | `.beeuni/pi/` |
| 内容 | `opencode.jsonc`、`plugins/`、`tools/`、`commands/` | `settings.json`、`extensions/`、`skills/`、`prompts/` |
| 扩展 | 该目录中的插件和仅供标准运行器使用的工具 | `harnesses.pi.packages` 中的 [实验运行器 包](/docs/zh/project/manifest#harnesses)，以及 `extensions/` 中的扩展文件 |

实验运行器 会话不会读取 `opencode.jsonc`、`plugins/`、`tools/` 或 `commands/`。标准运行器 会话不会读取实验运行器目录。两个 harness 都需要的工具应是[项目工具](/docs/zh/project/tools)，并在 `beeuni.yaml` 中声明，而不是放在任一目录中的文件。

实验运行器 包来自 packages。包可以为实验运行器添加原本不具备的工具，例如 MCP 适配器或待办工具。Beeuni 会加载该包，但不会测试第三方包。
