Runtime API 设计
Alice 本地 HTTP API 背后的理念和设计决策。
为什么需要一个本地 API?
Alice 将 bundled skill 作为子进程脚本运行。这些脚本需要与运行中的连接器交互 — 发送图片、管理任务、查询状态。从 shell 脚本中无法直接进行 Go 互操作,因此 Alice 暴露了一个本地 HTTP API。
设计原则
1. 默认仅本地访问
API 绑定到 127.0.0.1(可通过 runtime_http_addr 配置)。它并非设计为对外暴露。如果需要远程访问,请使用反向代理或 SSH 隧道 — 但这并非预期用例。
2. Bearer Token 认证
每个请求(/healthz 除外)都需要:
Authorization: Bearer <token>
Token 在启动时自动生成。环境变量 ALICE_RUNTIME_API_TOKEN 自动将其注入到 skill 脚本中。
3. 纵深防御
多层保护:
- 认证速率限制:每个 token 每分钟 120 个请求
- 请求体大小限制:每个请求 1 MB
- 文件验证:上传的文件必须是可读、非空的常规文件
- 飞书大小限制:上传仍受飞书文件大小和类型限制的约束
4. 无纯文本发送端点
Runtime API 没有纯文本发送端点。为什么?
文本回复通常走主回复流水线 — 它们需要 session 上下文、正确的线程和回复元数据。Runtime API 设计用于副作用(发送图片、文件、管理任务),而非绕过回复流水线。
如果 skill 需要以自动化任务的方式发送文本消息,它会通过 automation API 创建一个 send_text 任务。自动化引擎处理其余工作。
API 接口
消息
POST /api/v1/messages/image— 上传并发送图片POST /api/v1/messages/file— 上传并发送文件
两者接受 multipart/form-data,可选 caption 字段。
自动化
- 自动化任务的完整 CRUD:创建、列表、获取、更新、删除
Goal
- Goal 生命周期管理:获取、创建、暂停、恢复、完成、删除
健康检查
GET /healthz— 无需认证,服务器运行时返回 200
环境变量注入
Skill 无需知道 API 地址或 token。Alice 注入它们:
ALICE_RUNTIME_API_BASE_URL="http://127.0.0.1:7331"
ALICE_RUNTIME_API_TOKEN="<auto-generated>"
ALICE_RUNTIME_BIN="/usr/local/bin/alice"
额外的上下文变量:
ALICE_RECEIVE_ID_TYPE="chat_id"
ALICE_RECEIVE_ID="oc_xxxxxxxxxxxxx"
ALICE_SOURCE_MESSAGE_ID="om_xxxxxxxxxxxxx"
ALICE_ACTOR_USER_ID="ou_xxxxxxxxxxxxx"
ALICE_ACTOR_OPEN_ID="ou_xxxxxxxxxxxxx"
ALICE_CHAT_TYPE="group"
ALICE_SESSION_KEY="chat_id:oc_xxx|scene:chat"
多 Bot API 端口
在多 bot 模式下,每个 bot 在自动递增的端口上获得自己的 Runtime API 服务器:
| Bot 序号 | 端口 |
|---|---|
| 第一个 | 7331 |
| 第二个 | 7332 |
| 第三个 | 7333 |
| …… | …… |
Skill 通过继承其被触发所在对话作用域的环境变量来指向正确的 bot。
优雅关闭
当 Alice 收到关闭信号时,Runtime API 服务器:
- 停止接受新连接
- 等待最多
runtime_api_shutdown_timeout_secs秒(默认:5 秒)让正在处理的请求完成 - 超时后强制关闭剩余连接