服务模式(ante serve)
服务模式(Server mode)将 Ante 作为长寿命守护进程运行,外部客户端可通过结构化的消息协议对其进行驱动。非常适合用于构建编辑器插件、Web UI 界面或任何需要长期以编程方式控制 Ante 的自动化工作流。
基础用法
ante serve
该命令将启动守护进程,并通过 stdin/stdout 桥接 JSONL 协议。进程会持续运行,直到客户端发送 Shutdown 操作指令或关闭 stdin。
Stdio 标准输入输出传输(默认)
ante serve --stdio
--stdio 参数为可选 —— stdio 是默认传输方式。守护进程从 stdin 逐行读取 OpMsg JSON 对象,并将 EventMsg JSON 对象逐行写入 stdout。
Unix 套接字传输
ante serve --sock # ~/.ante/run/serve.sock
ante serve --sock /tmp/ante.sock
--sock 将协议托管在 Unix 域套接字上,因此生命周期长于单次连接的客户端可以直接连入宿主,而无需每次都拉起一个新进程。未指定路径时,套接字位于 Ante 主目录下的 run/serve.sock。
每个连接驱动各自的会话。某个客户端的 Shutdown 只结束该客户端的连接,宿主继续监听;宿主进程在收到 SIGINT 或 SIGTERM 时退出。
同一时刻只有一个宿主拥有某个套接字路径。所有权由套接字旁 .lock 文件上的排他锁表示:同一路径上的第二个 ante serve --sock 会拒绝启动,而不是抢占该路径,因此正在运行的宿主不会被从其客户端下方抽走。崩溃遗留的套接字文件不持有锁,会在下次启动时被替换,无需手动清理。
WebSocket 传输
ANTE_SERVE_TOKEN="your-secret-token" ante serve --ws 127.0.0.1:8080
--ws 参数在指定地址上启动 WebSocket 服务端。ante serve --ws 强制要求通过 ANTE_SERVE_TOKEN 环境变量传入 Bearer Token,未配置则拒绝启动。客户端必须在升级握手时提供 Authorization: Bearer <token> 请求头;缺失或错误的 Token 会被返回 HTTP 401 拒绝,握手设有 10 秒超时。每个客户端在共享主机上拥有独立连接与会话。服务端会持续接受连接,直到宿主收到 SIGINT 或 SIGTERM;某个客户端的 Shutdown 只关闭该连接。
传输方式参数互斥 —— 只能在 --stdio、--sock、--ws 中选择其一。
监听地址必须为本地回环地址(127.0.0.0/8 或 ::1)。Ante 拒绝绑定任何其他地址 —— 传入 0.0.0.0:8080 会在绑定前直接报错退出。跨机器访问守护进程时,请通过 SSH 隧道或带身份验证与 TLS 加密(wss://)的反向代理转发。
查看服务端记录
v0.2.8 的 --sock 与 --ws 会向 stdout 打印可读记录,包含连接、会话开始、消息、工具调用与轮次状态。每条记录带有服务端或客户端标签,便于区分并发连接。可重定向 stdout 保存本地记录:
NO_COLOR=1 ante serve --sock > serve-transcript.log
仅在终端中启用样式,任意非空 NO_COLOR 都会禁用样式。该记录按尽力而为方式输出:输出管道过慢时可能丢弃部分记录,而不会阻塞协议通信。需要完整事件的客户端应读取协议。--stdio 的 stdout 专用于 JSONL,不打印此记录。
工作原理
- 主机启动并等待所选传输方式上的操作指令
- 发送
StartSession操作,使用所选模型和提供商初始化会话 - 发送
UserInput操作提交提示词 - 在同一连接上接收流式事件 —— 思考增量、消息增量、工具调用、审批请求
- 对
TurnPause中的Approval使用ApprovalResponse,对Question使用QuestionResponse;无法提供交互界面的客户端应在启动会话时设置unattended: true - 发送
Shutdown(或断开连接)以优雅关闭连接。stdio 模式下这也会结束单连接进程;Unix 套接字与 WebSocket 宿主则继续服务其他客户端,直到收到信号
完整消息目录与报文格式请参阅通信协议参考手册。
协议输入与事件输出相互独立读取,因此即使对端停止消费事件,Interrupt 与 Shutdown 仍能及时响应。每次事件写入的期限为 30 秒;持续阻塞或用响应淹没队列的对端会被断开,而不会拖住宿主。
调用会话示例
将以下代码保存为 client.cjs,并运行 node client.cjs(需在 PATH 上安装 Ante,且已配置 Anthropic 凭证)。示例保持 stdin 开启,等待 SessionStart 后提交提示词,并在轮次结束或发生错误时发送 Shutdown。unattended: true 会立即拒绝需要审批的调用,并跳过结构化提问,以便此无交互示例顺利结束。
const { spawn } = require("node:child_process");
const { createInterface } = require("node:readline");
const ante = spawn("ante", ["serve", "--stdio"], {
stdio: ["pipe", "pipe", "inherit"]
});
const lines = createInterface({ input: ante.stdout, crlfDelay: Infinity });
let sequence = 0;
let stopping = false;
const send = (op) => ante.stdin.write(
JSON.stringify({ op, id: `op_${++sequence}` }) + "\n"
);
const fail = (error) => {
console.error(error.message);
process.exitCode = 1;
};
ante.on("error", fail);
ante.stdin.on("error", fail);
ante.on("exit", (code) => {
if (code) process.exitCode = code;
});
lines.on("line", (line) => {
if (!line.trim()) return;
const { event } = JSON.parse(line);
console.log("Event:", event);
if (stopping) return;
if (event.SessionStart) {
send({ UserInput: "explain what this project does" });
} else if (event.TurnEnd || Object.hasOwn(event, "Error")) {
if (event.TurnEnd?.status !== "Completed") process.exitCode = 1;
stopping = true;
send("Shutdown");
ante.stdin.end();
}
});
send({ StartSession: {
model: "claude-sonnet-5-5",
provider: "anthropic",
unattended: true
} });
Rust SDK
ante-sdk 是面向外部程序的 Ante 客户端,因此 Rust 集成无需自行处理 JSONL 分帧或管理宿主进程。connect 会返回一个 Client —— 即一个 op 发送端与一个事件接收端 —— 适用于任意传输方式:
use ante_sdk::{ConnectOptions, connect, protocol::{Evt, Op, SessionRequest}};
let mut client = connect("stdio".parse()?, ConnectOptions::default()).await?;
client.send(Op::StartSession(SessionRequest {
model: Some("claude-sonnet-5-5".into()),
provider: Some("anthropic".into()),
unattended: Some(true),
..Default::default()
})).await?;
client.send(Op::UserInput("explain what this project does".into())).await?;
while let Some(event) = client.next_event().await {
println!("{event:?}");
if matches!(event.event, Evt::TurnEnd { .. } | Evt::Error(_)) {
break;
}
}
client.close().await;
Endpoint 描述的是宿主在哪里可达 —— 而非某个会话。连接驱动哪个会话,由其上发送的 op(StartSession、ResumeSession)决定:
| Endpoint | 客户端行为 | 宿主生命周期 |
|---|---|---|
stdio | 将 ante serve --stdio 作为自身子进程拉起 | 随连接结束 —— 丢弃 op 发送端即关闭子进程的 stdin |
unix:<path> | 连接某个 ante serve --sock 宿主的套接字文件 | 属于他人;宿主的生命周期长于该连接 |
ws://<addr>, wss://<addr> | 连接 ante serve --ws 宿主,附带 ConnectOptions::token 作为 Bearer 认证 | 属于他人;宿主的生命周期长于该连接 |
原生 ws:// 仅允许连接本地回环地址;跨网络远程连接必须使用 wss://(在启用可选 wss 特性时提供),确保 Bearer Token 绝不明文传输。
每种方式都产出同一个 Client;自身托管会话的进程也直接从其宿主获得同一类型 —— 进程内通道传递的正是远程编解码器所序列化的协议类型,因此客户端所能观察到的一切并无差别。
ConnectOptions 全部字段可选:executable(默认为 PATH 上的 ante)、追加在 serve --stdio 之后的 args、cwd、额外的 env,以及连接 ws:///wss:// 时的 token(Bearer 认证 Token)。连接成功仅代表传输层成功 —— 管道已打开,或套接字已连上。协议没有握手问候,因此第一个 op 的回复才是存活性检查。
// 连接他人正在运行的宿主
let client = connect("unix:/tmp/ante.sock".parse()?, ConnectOptions::default()).await?;
完整客户端示例可参考 examples/mini-tui:一个单文件的交互式 Chat TUI,展示了如何流式接收 MessageDelta、通过 y/n 响应 TurnPause 审批,以及按 Esc 发送 Interrupt。在该目录下运行 cargo run 即可体验。
SDK 0.2.2 已移除 ante_sdk::claude 和旧版子进程 stdio API。Ante 宿主的 stdio 连接仍通过 connect(Endpoint::Stdio, options) 支持,如上例所示。
服务模式与无头模式的区别
| 无头模式(Headless) | 服务模式(Server) | |
|---|---|---|
| 生命周期 | 执行单次提示词后退出 | 长寿命常驻,支持多轮持续交互 |
| 输入方式 | CLI 参数或 stdin 管道 | 结构化 JSONL 操作指令 |
| 输出形式 | 格式化文本(minimal/human/json) | 原始协议事件流(JSONL) |
| 传输层 | 无 | Stdio(默认)、Unix 套接字 (--sock) 或 WebSocket (--ws) |
| 会话管理 | 隐式创建 —— 单次调用对应单会话 | 显式声明 —— 客户端发送 StartSession |
| 工具审批 | 默认为 yolo;显式 strict/auto 会拒绝原本需要提示的调用 | 客户端必须响应 TurnPause,或将会话声明为 unattended 以自动拒绝 |
命令行参数参考
| 参数标识 | 说明 |
|---|---|
--stdio | 通过 stdin/stdout 提供 JSONL 协议服务(默认) |
--sock [PATH] | 通过 Unix 域套接字提供协议服务(默认为 Ante 主目录下的 run/serve.sock) |
--ws <ADDR> | 在本地回环地址上通过 WebSocket 提供协议服务 |
--offline-model [MODEL] | 加载本地或验证模型,启动共享的 llama serve 路由器并注册 local 提供商。接受路径、已发现的文件名或验证模型名称/URL;省略值则使用 ante offline use 保存的默认模型 |
--prompt 参数不能与 ante serve 同时使用。请通过 UserInput 操作指令传递提示词。