---
title: "Harness 命令"
---

`veadk harness` 是一组命令，用于**脚手架生成、配置、部署并调用**一个 VeADK **Harness server**（`veadk.cloud.harness_app`）。

一个 *harness* 就是一份智能体规格 —— **模型 + 系统提示词 + 工具 + 技能**，外加创建时绑定的**知识库与长/短期记忆**。整个规格通过分层的 `harness.yaml` 描述；`deploy` 会把它展平成 runtime 的环境变量，由 Harness server 在启动时组装成一个智能体，并通过 `POST /harness/invoke` 对外服务。

<Callout type="info">
  部署需要火山引擎 AgentKit 凭证（`VOLCENGINE_ACCESS_KEY` / `VOLCENGINE_SECRET_KEY`）。端到端示例参见 [`14_harness_server_on_agentkit`](https://github.com/volcengine/veadk-python/tree/main/examples/14_harness_server_on_agentkit)。
</Callout>

## 命令一览

| 命令 | 描述 |
| :-- | :-- |
| `veadk harness create <dir>` | 生成一个可部署的 harness 目录。 |
| `veadk harness add` | 将智能体参数写入 `harness.yaml`。 |
| `veadk harness show` | 展示已配置参数，以及可在调用时覆盖的参数。 |
| `veadk harness deploy` | 云端构建镜像并创建 AgentKit runtime（无需本地 Docker）。 |
| `veadk harness invoke` | 调用一个已部署的 harness 并打印输出。 |

典型流程：**`create` → `add` → `deploy` → `invoke`**。

## `veadk harness create`

生成一个部署目录：

```bash
veadk harness create my-harness
```

该命令会写入：

- `harness.yaml` —— 智能体配置模板（见下）。
- `.env.example` —— 仅含火山引擎部署凭证（`VOLCENGINE_ACCESS_KEY`、`VOLCENGINE_SECRET_KEY`，以及可选的 `VOLCENGINE_REGION`）。模型/智能体配置都在 `harness.yaml`。
- `Dockerfile` —— 构建 harness 服务镜像。
- `README.md` —— 快速开始说明。

### `harness.yaml`

分层配置文件，每个组件自包含。`deploy` 会将其转换为 runtime 的环境变量：顶层字段与 `model` 直接展平（`model.name` → `MODEL_NAME`，`tools` → `TOOLS` 等），列表转为逗号分隔字符串；每个组件的 `type` 选择后端，组件下的其余参数映射为该后端实际读取的 VeADK 环境变量（如 viking 的 `project` → `DATABASE_VIKING_PROJECT`）。空值会被跳过，VeADK 回退到自身默认值。

```yaml
harness_name: ""          # -> HARNESS_NAME（runtime 名 + 知识库/长期记忆索引名）
model:
  name: ""                # -> MODEL_NAME（Ark 鉴权在部署后由 runtime 的 IAM 角色解析）
tools: []                 # -> TOOLS（逗号连接）
skills: []                # -> SKILLS（逗号连接）
system_prompt: ""         # -> SYSTEM_PROMPT（空 = VeADK 默认）
runtime: adk              # -> RUNTIME（"adk" 或 "codex"）
knowledgebase:
  type: ""                # -> KNOWLEDGEBASE_TYPE（空 = 不创建）
long_term_memory:
  type: ""                # -> LONG_TERM_MEMORY_TYPE（空 = 不创建）
short_term_memory:
  type: local             # -> SHORT_TERM_MEMORY_TYPE
```

每个组件下，按你设置的 `type` 取消对应后端参数的注释即可（模板里已逐项标注了环境变量与命令行 flag）。在 AgentKit runtime 上 Ark 鉴权由 IAM 角色解析，因此模型无需配置 API Key。

## `veadk harness add`

将智能体参数写入 `./harness.yaml`（或 `--path` 指定的目录）。当 `harness.yaml` 不存在时快速失败。

```bash
cd my-harness
veadk harness add \
  --name research-agent \
  --model-name doubao-seed-1-6-250615 \
  --system-prompt "You are a research assistant." \
  --tools web_search,web_fetch \
  --runtime adk
```

| 选项 | 说明 |
| :-- | :-- |
| `--name` / `--harness-name` | 逻辑 harness / runtime 名（设置 `harness_name`）。 |
| `--model-name` | 推理模型名（设置 `model.name`）。 |
| `--tools` | 逗号分隔的内置工具名，如 `web_search,web_fetch`（设置 `tools`）。 |
| `--skills` | 逗号分隔的技能 hub 名（设置 `skills`）。 |
| `--system-prompt` | 系统提示词 / 指令。 |
| `--runtime` | 智能体 runtime，`adk`（默认）或 `codex`。 |
| `--knowledgebase-type` | 知识库后端（设置 `knowledgebase.type`）。 |
| `--long-term-memory-type` | 长期记忆后端（设置 `long_term_memory.type`）。 |
| `--short-term-memory-type` | 短期记忆后端（设置 `short_term_memory.type`）。 |
| `--path` | 包含 `harness.yaml` 的目录，默认 `.`。 |

#### 组件连接参数

每个组件还会按其支持的后端，自动生成形如 `--<组件>-<参数>` 的连接参数 flag，例如：

```bash
veadk harness add --name kb-agent \
  --knowledgebase-type viking \
  --knowledgebase-project my-project --knowledgebase-region cn-beijing
```

| 组件前缀 | 可用 flag（取决于后端） |
| :-- | :-- |
| `--knowledgebase-*` | `project` / `region`（viking）、`host` / `port` / `username` / `password` / `use-ssl` / `cert-path` / `secret-token`（opensearch）、`host` / `port` / `username` / `password` / `db`（redis） |
| `--long-term-memory-*` | 同上各后端，外加 `api-key` / `api-key-id` / `project-id` / `base-url`（mem0） |
| `--short-term-memory-*` | `host` / `user` / `password` / `database` / `charset` / `port`（mysql / postgresql） |

凭证（access key / secret key）不通过这些 flag 传入，而是复用部署时 `.env` 里的 `VOLCENGINE_*`。

## `veadk harness show`

打印 `harness.yaml` 中已配置的参数，以及可在每次调用时覆盖的参数。`harness.yaml` 不存在时快速失败。

```bash
veadk harness show --path my-harness
```

该命令打印两段：

1. **已配置的智能体参数** —— `harness.yaml` 的内容（`harness_name`、`model`、`tools`、`skills`、`system_prompt`、`runtime`，以及已配置的 `knowledgebase` / `long_term_memory` / `short_term_memory`）。
2. **可在调用时覆盖的参数** —— 由 `HarnessOverrides` 派生的每个 `--<flag>`（`--model-name`、`--tools`、`--skills`、`--system-prompt`、`--runtime`）及其说明。记忆与知识库**不可**覆盖。

| 选项 | 说明 |
| :-- | :-- |
| `--path` | 包含 `harness.yaml` 的目录，默认 `.`。 |

## `veadk harness deploy`

填好部署凭证后，在该目录内执行：

```bash
cd my-harness
cp .env.example .env   # 然后设置 VOLCENGINE_ACCESS_KEY / VOLCENGINE_SECRET_KEY
veadk harness deploy
```

| 选项 | 必填 | 说明 |
| :-- | :-- | :-- |
| `--volcengine-access-key` | 否 | 火山引擎 Access Key（默认读 `VOLCENGINE_ACCESS_KEY`）。 |
| `--volcengine-secret-key` | 否 | 火山引擎 Secret Key（默认读 `VOLCENGINE_SECRET_KEY`）。 |
| `--region` | 否 | AgentKit 区域（默认 `cn-beijing` 或 `VOLCENGINE_REGION`）。 |
| `--path` | 否 | harness 目录，默认 `.`。 |
| `--discovery-url` | 否 | OIDC discovery URL，启用 OAuth2/JWT 鉴权（覆盖 `auth.discovery_url`）。 |
| `--allowed-id` | 否 | 逗号分隔的允许 client ID，用于 OAuth2/JWT 鉴权（覆盖 `auth.allowed_ids`）。 |

`deploy` 会加载 `harness.yaml`，将其展平为 runtime 环境变量，执行 AgentKit 的**云端**构建（无需本地 Docker）并创建 runtime。runtime 以 `harness_name` 命名。

成功后，端点与网关 API Key 会被记录到目录下的 **`harness.json`**（结构为 `{name: {url, key, runtime_id}}`），随后即可用 `veadk harness invoke --name <name>` 直接调用，无需手动复制 URL / Key：

```text
Harness runtime deployed: name=research-agent
Runtime id: r-xxxx
Endpoint:   https://xxxx.apigateway-cn-beijing.volceapi.com
API key:    ****

Recorded in .../harness.json. Invoke it with:
  veadk harness invoke --name research-agent --message "<message>"
```

### OAuth2 / JWT 鉴权部署（可选）

默认用网关 API Key（key_auth）。若想用**火山引擎 Identity 用户池**做 OAuth2/JWT 门禁，在 `harness.yaml` 加一个 `auth` 段即可——**有 `auth` 段就走 custom_jwt，没有就走默认 key_auth**：

```yaml
auth:
  discovery_url: "https://userpool-<池子id>.userpool.auth.id.cn-beijing.volces.com/.well-known/openid-configuration"
  allowed_ids: ["<client-id>"]   # 控制台建的客户端 client_id；网关只放行 aud 命中的 token
```

也可用 `--discovery-url` / `--allowed-id` 在 deploy 时覆盖。`auth` 段**不会**写入容器环境变量，只用于配置 runtime 网关的 authorizer。

- 用户池、客户端、外部身份提供商（如飞书）在 **Identity 控制台**一次性建好，CLI 只**引用** `discovery_url` + `allowed_ids`，**不涉及任何 secret**。
- custom_jwt 部署后 `harness.json` 记录 `{url, runtime_id, auth_type, discovery_url, allowed_ids}`（无 key）。调用该 runtime 需自带 `Authorization: Bearer <用户池签发的 JWT>`，CLI 不代为获取。

### A2A Registry 调用 OAuth remote-agent

当 Harness 启用 `agentkit_a2a` registry 后，运行时会通过 `SearchAgentCards` / `GetA2aAgent` 动态发现并挂载 `remote_a2a_*` 工具。命中的远程 Agent 如果是 `apiKey` 鉴权，会按 AgentCard 的 `securitySchemes` 注入对应 header；如果是 `oauth2` 且声明了 `clientCredentials.tokenUrl`，运行时会自动从 token URL 解析火山引擎 Identity UserPool，查询其中的 `MACHINE_TO_MACHINE` client，使用 `client_credentials` 换取 access token，并以 `Authorization: Bearer <access_token>` 调用远程 Agent 的 `message/send` / `tasks/get`。

通常只需要确保 Harness Runtime 有权限调用 AgentKit A2A Registry 和 Identity OpenAPI。若 registry endpoint 使用了自定义域名且不能同时访问 Identity OpenAPI，可通过 `REGISTRY_ID_ENDPOINT` 或 `AGENTKIT_ID_ENDPOINT` 指定 Identity OpenAPI 地址。

## `veadk harness invoke`

调用一个**已部署**的 harness 并打印输出。`url` 与 `key` 默认按 `--name` 从 `harness.json`（由 `deploy` 写入）解析，无需显式传入。

```bash
veadk harness invoke --name research-agent --message "总结一下强化学习的最新进展。"
```

消息既可用 `--message` / `-m`，也可作为位置参数传入。

| 选项 | 必填 | 说明 |
| :-- | :-- | :-- |
| `--name` / `--harness` | 是 | harness 名称；其 `url`/`key` 默认从 `harness.json` 读取。 |
| `MESSAGE`（位置参数）或 `--message` / `-m` | 是 | 发送给 harness 的消息。 |
| `--user-id` | 否 | 会话所属用户 id，默认 `cli-user`。 |
| `--session-id` | 否 | 本次调用的会话 id。 |
| `--url` | 否 | Harness URL（默认 `harness.json[name]`，或 `HARNESS_URL`）。 |
| `--key` | 否 | Bearer 鉴权 API Key（默认 `harness.json[name]`，或 `HARNESS_KEY`）。 |
| `--path` | 否 | 包含 `harness.json` 的目录，默认 `.`。 |
| `--model-name` | 否 | 仅本次调用覆盖模型。 |
| `--tools` | 否 | 仅本次调用覆盖工具（逗号分隔）。 |
| `--skills` | 否 | 仅本次调用覆盖技能（逗号分隔）。 |
| `--system-prompt` | 否 | 仅本次调用覆盖系统提示词。 |
| `--runtime` | 否 | 仅本次调用覆盖运行时（`adk` / `codex`）。 |

### 一次性覆盖

若提供了 `--model-name` / `--tools` / `--skills` / `--system-prompt` / `--runtime` 中的任意一个，服务端会克隆已部署的智能体并叠加这些覆盖，**仅对本次调用生效**：工具与技能为**增量**叠加（与已有同名项去重），记忆与知识库**永不**可覆盖。

```bash
veadk harness invoke --name research-agent \
  --tools get_city_weather \
  --message "北京今天天气怎么样？"
```

## 完整示例

端到端的部署与调用流程（含 `curl` 等价写法）参见示例 [`14_harness_server_on_agentkit`](https://github.com/volcengine/veadk-python/tree/main/examples/14_harness_server_on_agentkit)。
