Add dedicated template agent contract doc

This commit is contained in:
elipitc
2026-06-04 23:40:14 +08:00
parent f6851c9680
commit 8e9032e74a
2 changed files with 280 additions and 0 deletions
@@ -0,0 +1,267 @@
# Heicode Template Agent Runtime 对接文档
更新时间:2026-06-04
本文档只描述 **模板 Agent (`/agents`)** 这一条联调链路,适用于 Heicode Manager 创建常驻 A2A Agent、查询状态、停止、删除,以及客户端直连 Agent 的场景。
这不是 `/api/agent/sub-agile/*` 或 `/api/swarms/*` 的 sub-mode runtime 文档。
如果你们对接的是普通 sub 模式 Runtime,请看 [HEICODE_API_INTEGRATION.md](/Users/mac/Projects/agent-manager/tools/agent-manager/docs/HEICODE_API_INTEGRATION.md)。
## 1. 场景说明
模板 Agent 的典型链路如下:
1. HM 调 `POST /agents` 创建一个模板 Agent。
2. AM 返回 `runtime_id` / `agent_id` / `id`、`subdomain`、`status`。
3. HM 轮询 `GET /agents/{agent_name}` 获取生命周期状态。
4. 客户端拿到 `subdomain` 后,直连 Agent 的 A2A 接口:
- `POST /message/send`
- `POST /message/stream`
- `GET /.well-known/agent.json`
- `GET /health`
5. 如需停止或删除:
- `POST /agents/{agent_name}/stop`
- `DELETE /agents/{agent_name}`
## 2. Agent Manager 生命周期接口
### 2.1 接口列表
| 方法 | 路径 | 说明 |
|------|------|------|
| `POST` | `/agents` | 创建模板 Agent |
| `GET` | `/agents/{agent_name}` | 查询模板 Agent 生命周期状态 |
| `POST` | `/agents/{agent_name}/stop` | 幂等停止模板 Agent |
| `DELETE` | `/agents/{agent_name}` | 删除模板 Agent |
| `GET` | `/agents/{agent_name}/status` | 查询详细 Pod/容器状态 |
| `GET` | `/agents/{agent_name}/metrics` | 查询资源使用情况 |
### 2.2 创建接口
```http
POST /agents
```
最小请求示例:
```json
{
"name": "dep-b5fab27e9255",
"template": "coding_a2a_agent",
"framework": "A2A",
"config": {
"user_id": "22",
"manager_deployment_id": "dep_b5fab27e9255",
"callback_url": "https://code.xinghanlab.com/api/agent/callbacks/runtime-events"
},
"env": {
"OPENAI_BASE_URL": "https://code.xinghanlab.com/v1",
"OPENAI_API_KEY": "sk-xxxx",
"MODEL_NAME": "gpt-5.4",
"AGENT_ROLE_NAME": "architect",
"AGENT_INSTRUCTION_TEXT": "# Role\nYou are architect",
"AGENT_ACCESS_TOKEN": "550e8400-e29b-41d4-a716-446655440000",
"HEICODE_AGENT_ID": "dep-b5fab27e9255"
}
}
```
当前响应中,HM 重点关心这些字段:
| 字段 | 说明 |
|------|------|
| `runtime_id` | 当前等于 Agent 名称,可用于后续状态/停止/删除 |
| `agent_id` | 当前等于 Agent 名称 |
| `id` | 当前等于 Agent 名称 |
| `status` | 当前生命周期状态 |
| `runtime_status` | `status` 的兼容别名 |
| `state` | `status` 的兼容别名 |
| `subdomain` | 优先取 `access_info.domain`,否则回退到 `access_info.external_ip` |
| `access_info` | 访问地址详情 |
响应示例:
```json
{
"name": "dep-b5fab27e9255",
"runtime_id": "dep-b5fab27e9255",
"agent_id": "dep-b5fab27e9255",
"id": "dep-b5fab27e9255",
"namespace": "agent-dep-b5fab27e9255",
"status": "running",
"runtime_status": "running",
"state": "running",
"framework": "A2A",
"subdomain": "dep-b5fab27e9255.taijiagnet.com",
"access_token": null,
"access_info": {
"domain": "dep-b5fab27e9255.taijiagnet.com",
"domain_url": "http://dep-b5fab27e9255.taijiagnet.com",
"external_ip": "20.212.121.126"
}
}
```
## 3. 状态接口
### 3.1 生命周期状态
```http
GET /agents/{agent_name}
```
这个接口给 HM 轮询用,返回平铺生命周期字段,便于直接解析:
```json
{
"runtime_id": "dep-b5fab27e9255",
"agent_id": "dep-b5fab27e9255",
"id": "dep-b5fab27e9255",
"name": "dep-b5fab27e9255",
"namespace": "agent-dep-b5fab27e9255",
"status": "running",
"runtime_status": "running",
"state": "running",
"framework": "A2A",
"template": "coding_a2a_agent",
"subdomain": "dep-b5fab27e9255.taijiagnet.com",
"access_token": null,
"access_info": {
"domain": "dep-b5fab27e9255.taijiagnet.com"
}
}
```
当前 `status` / `runtime_status` / `state` 可能值:
- `pending`
- `running`
- `stopped`
- `failed`
### 3.2 详细 Pod 状态
```http
GET /agents/{agent_name}/status
```
这个接口偏排障用途,除了生命周期状态外,还会返回:
- `health_status`
- `containers`
- `resources`
- `conditions`
- `access_info`
适合 AM / 运维 / 联调同学排查“为什么 agent 没 ready”这类问题。
### 3.3 资源指标
```http
GET /agents/{agent_name}/metrics
```
返回请求/限制和实时资源使用信息。
## 4. 停止与删除
### 4.1 停止
```http
POST /agents/{agent_name}/stop
```
响应示例:
```json
{
"status": "success",
"message": "Agent dep-b5fab27e9255 已停止"
}
```
约定:
- 这是 **幂等** 的停止接口。
- 停止时会删除当前运行 Pod,并把数据库状态收敛为 `stopped`。
- 停止后仍可继续查询 `GET /agents/{agent_name}`。
### 4.2 删除
```http
DELETE /agents/{agent_name}
```
约定:
- 会清理 DNS、K8s namespace 和数据库记录。
- 当前已修复旧版本里模板 Agent 删除时可能触发的 `UnboundLocalError` 500。
## 5. 客户端直连 Agent 的鉴权
模板 Agent 当前支持 HM 约定的 **本地校验** 访问鉴权。
### 5.1 规则
- HM 创建 Agent 时,会把 `AGENT_ACCESS_TOKEN` 注入到 Agent env。
- 客户端访问 Agent 时,请把这把令牌放到请求头:
```http
X-Agent-Access-Token: <AGENT_ACCESS_TOKEN>
```
- Agent 本地使用常量时间比较校验:
```text
X-Agent-Access-Token == AGENT_ACCESS_TOKEN
```
- 命中则放行,不命中拒绝。
### 5.2 当前生效范围
以下 Agent 直连接口会做本地校验:
| 方法 | 路径 |
|------|------|
| `POST` | `/message/send` |
| `POST` | `/message/stream` |
| `GET` | `/tasks/{task_id}` |
### 5.3 返回约定
- 缺少 `X-Agent-Access-Token`:返回 `401`
- `X-Agent-Access-Token` 不匹配:返回 `403`
- 如果实例没有注入 `AGENT_ACCESS_TOKEN`:继续兼容放行
### 5.4 和模型 `api_key` 的区别
- `X-Agent-Access-Token`:控制“谁有权访问这个 agent”
- A2A body 里的 `api_key`:控制“本次请求用谁的模型额度”
两者职责分离,不互相替代。
## 6. Agent 直连接口
客户端从 HM 拿到 `subdomain` 后,可以直连这些 Agent 接口:
| 方法 | 路径 | 说明 |
|------|------|------|
| `GET` | `/health` | 健康检查 |
| `GET` | `/.well-known/agent.json` | A2A agent card |
| `POST` | `/message/send` | 同步 A2A 调用 |
| `POST` | `/message/stream` | 流式 A2A 调用 |
| `GET` | `/tasks/{task_id}` | 查询任务状态 |
如果实例启用了访问鉴权,`/health` 和 `/.well-known/agent.json` 仍可访问;响应中会带:
- `auth_required`
- `agent_id`
- `authentication`(agent card 中)
## 7. 当前建议
1. HM 轮询状态时优先用 `GET /agents/{agent_name}`。
2. 排障时再看 `GET /agents/{agent_name}/status`。
3. 客户端直连前,先确认 HM 已拿到 `subdomain` 和 `access_token`。
4. 若模板 Agent 对外公网暴露,建议始终注入 `AGENT_ACCESS_TOKEN`,不要依赖兼容放行。