不想自己搭 Docker、管模型 key、配端口计费?本文用怡途Claw 的 /api/app/* 接口,从拿 token 到发出第一条消息,四个请求跑通 AI Agent 部署全链路,附真实字段与易踩的坑。
自己搭一套 AI Agent 运行环境,要处理的事不少:Docker 镜像、模型 API key、网络端口、用量计费。怡途Claw 把这些收进了一个 SaaS 平台,对外暴露 /api/app/* 一组接口。这篇文章把「创建一个 Agent 实例并和它说上话」拆成四个 HTTP 请求,每个都带真实字段和容易踩的坑。
一、先拿到访问令牌
所有 /api/app/* 接口都要 JWT,放在 Authorization: Bearer <token>。注册和登录走这两步:
POST /api/app/auth/send-verify-code
POST /api/app/auth/login
登录成功返回 token,之后每个请求都带上它。这里有个贯穿全程的约束要先记住:APP 端的大模型配置只能「选系统提供的供应商 + 选模型」,不能自己填 baseUrl 和 apiKey——平台替你托管了 key 和计费。想用自己的 key,得走网页端配置,APP 接口这条线不开放。这点会在第三步卡住不少人。
二、挑一个大模型供应商
创建实例前先选模型。拉供应商列表:
GET /api/app/llm/providers
Authorization: Bearer <token>
返回里每家供应商带 id(一个 UUID)、providerId(业务标识,比如 deepseek)、supportedModels、modelPricing。怡途Claw 接了 14 家以上主流模型商,DeepSeek、通义、文心、Kimi 这些都在里面。记下你要用的那家的 id 和具体 modelId,下一步要用。
如果你不想挑,直接调 GET /api/app/llm/providers/default 拿默认供应商,省一步。
三、创建并启动实例
核心请求:
POST /api/app/instances
Authorization: Bearer <token>
Content-Type: application/json
{
"name": "我的第一个 Agent",
"type": "standard",
"llmProviderId": "8f3a6c4c-3f82-4e20-a0b6-4b1a2b5e91f2",
"llmConfig": { "modelId": "deepseek-chat" }
}
成功后返回实例 id 和 status: "pending"。注意 llmConfig 里只放 modelId。如果你手贱传了 baseUrl 或 apiKey:
{
"statusCode": 400,
"message": "APP端不支持自定义大模型地址或密钥,请选择系统提供的模型供应商",
"error": "Bad Request"
}
这是设计上的约束,不是 bug:模型 key、计费、网关都在平台侧,所以 APP 接口不暴露这些字段。providerId / llmProviderId 支持两种值——供应商的数据库主键 id(UUID)或业务标识 providerId(如 deepseek),两个都认。
实例刚建出来是 pending,要手动启动:
POST /api/app/instances/<id>/start
启动后 status 变 running。返回里有个 runtimeType 字段,告诉你这个实例跑在哪种运行时上——openclaw(标准)、hermes、claude-code、codex。不同运行时,下一步聊天接口的行为会不一样,这点很关键。
四、发第一条消息并接住流式回复
这一步最容易踩坑。发消息是异步的:
POST /api/app/chat/instances/<id>/messages
Authorization: Bearer <token>
{ "content": "你好", "sessionId": "main" }
返回里 pending: true、assistantMessage: null——别以为失败了。回复走另一条 SSE 长连接拿:
GET /api/app/chat/instances/<id>/stream?sessionId=main&slim=1
Accept: text/event-stream
Authorization: Bearer <token>
这是 text/event-stream,不是普通 GET,要用 SSE 客户端接,别拿 HTTP 轮询去硬拉。从 2026-07 起默认走 clawpilot 格式,事件分两类:event: chat 是主对话流(started / delta / final / aborted / error),event: agent 是侧信道(思考过程和工具调用)。
两个最容易漏的点:
chat的state: delta事件——agent 实时打字全靠它。漏了这个分支,用户就看不到字一个个冒出来,以为界面卡死。delta里的text默认是累计全文,直接替换显示就行,别+=拼接,否则文字会重复。只有加了slim=1且帧里带patch: true时才是真增量,这时才用+=。
工具调用走 agent 流的 tool 卡片:phase: started 建卡片,phase: result 写结果。大输出(比如一次 grep 出几十 KB)在 slim 模式下会拆成 4KB 一片的 result_chunk,按 toolCallId 拼接,chunkFinal: true 时定型——这是为了不让一帧 200KB 的 JSON 把手机主线程卡死,长回答流量也从 O(N²) 降到 O(N)。
还有一个不那么显眼的坑:runtimeType='claude-code' 的实例默认走终端 PTY,不产生 chat 事件。要让它在 SSE 通道里也冒出 run.started / message.delta 这些事件,得开 Agent Mode——单实例设 instance.metadata.useAgentMode = true,或后端 .env 加 CLAUDE_CODE_DEFAULT_AGENT_MODE=true。这是灰度特性,接入前确认一下你的实例开没开。
收尾:查计费、停实例
跑起来就开始按 token 计费,查余额和用量:
GET /api/app/billing/balance
GET /api/app/billing/token-usage
不用了就停掉,不删不扣费:
POST /api/app/instances/<id>/stop
套餐到期会自动暂停(suspendReason: subscription_expired),续费重新激活,不续费才会被删。
这条链路之后能干什么
四个请求跑通之后,你要做的产品化东西——多实例编排、统一计费、按渠道分发——都建立在这条链路上。怡途Claw 的价值就在于:模型 key、容器、网关、计费这些脏活它都接了,你只对着 /api/app/* 写业务。想进一步把多个 Agent 编到一起统一管,实例列表、批量启停、用量统计这几个接口已经够用了,不需要再自建一套编排层。