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 服务器:

  1. 停止接受新连接
  2. 等待最多 runtime_api_shutdown_timeout_secs 秒(默认:5 秒)让正在处理的请求完成
  3. 超时后强制关闭剩余连接

扩展 API

新端点可在 internal/runtimeapi/ 中添加。开发者指南参见贡献指南架构概览