BYOK ── 自带密钥
使用 Sonzai 的托管基础设施,但将提供商的 token 计费记到自己账户。按项目、按提供商保存,静态加密。
BYOK 让你继续使用 Sonzai 的对话/会话/抽取整套栈,但底层的 提供商调用走 你自己的 API Key。token 费用计入你自己的提供商 账单;其他一切(记忆、人格、后处理模型、Sonzai 平台计费)行为 不变。
它和 Custom LLM (BYOM) 不是一回事。 BYOK 是把你的计费 Key 接到 Sonzai 已经原生集成好的提供商通道里; BYOM 是把整个对话补全调用换成 你自己托管的某个端点。
作用域
BYOK Key 按 (项目 × 提供商) 保存。同一项目同一提供商只有 一把 Key,没有 按 Agent / 按 Session / 按调用粒度的 BYOK Key。心智模型很简单 ── 某个项目的某次对话回合落到某个提供商上, 就走这个项目下该提供商的 BYOK Key,不论是哪个 Agent、哪个 Session 触发的。
| 对象 | 作用域 |
|---|---|
| 存储 | 按 (project_id, provider) ── 表的主键 |
| 请求时解析 | 由对话调用的 project_id → 查找解析后的提供商对应的 Key |
| 加密 | 静态 AES-256,仅在请求路径内解密 |
| API 访问 | 租户级 API Key 可管理其名下任意项目;项目级 Key 必须与请求中的 project_id 完全匹配 |
如果想让同一项目下不同 Agent 用不同 Key,请拆成不同项目 ── 能调的旋钮就这一个。
接入方式
线上等价的两种路径:
1. 控制台
一次性配置或轮换最快。
- 打开 platform.sonz.ai,选中项目。
- 进入 Settings → BYOK。
- 支持的 4 个提供商各有一张卡片,挑你要配的。
- 粘贴提供商的 API Key(OpenAI、Google AI Studio for Gemini、 xAI 控制台、OpenRouter 控制台)。
- 点 Save。和 API 同样的同步探针会跑一次 ── 上游若拒绝 这把 Key,保存直接失败,提供商的错误信息原样回显。坏 Key 不会被持久化。
- 保存后卡片切到「已配置」状态 ── 显示前缀掩码、健康徽章
(
healthy/unhealthy/unknown),并出现 Replace / Test / Disable / Delete 按钮。
控制台调用的就是 SDK 那一组端点,所以这里能做的都能脚本化。
2. API / SDK
适合 IaC、新租户的 CI 引导、Key 轮换 cron、自动租户接入流程 中的 provisioning。端点见下。
可接入的提供商
平台原生支持的 4 个:
openaigeminixaiopenrouter(内部回退路径 ── 这里配了 Key,平台落到 OpenRouter 时也会走你自己的)
custom BYOM 端点不是 BYOK 的提供商,通过
Custom LLM 配置。
存储与安全
- Key 静态加密,只在平台请求路径内解密。任何 API 都
不会 把原 Key 回传 ── List / Get 只回
api_key_prefix(前几个字符),够你识别哪把是哪把。 - 写入时跑一次 同步探针。Sonzai 用这把 Key 向上游打一次 no-op 调用,坏 Key 在 PUT 阶段就 400。配错在配置时就暴露, 不会拖到第一次用户对话才炸。
- 每把 Key 都 跟踪健康状态。每次读取都返回
health_status、last_health_error、last_health_check_at,可以接到监控、 在用户感知到对话失败之前先告警。
端点
按项目分,索引为 (project_id, provider)。能列、能 Set、能停用、
能删、能重测。
| Method | Path | 用途 |
|---|---|---|
GET | /api/v1/projects/{projectId}/byok-keys | 列出所有 Key(掩码) |
PUT | /api/v1/projects/{projectId}/byok-keys/{provider} | 设置或轮换某提供商的 Key(保存前先探针) |
PATCH | /api/v1/projects/{projectId}/byok-keys/{provider} | 不动 Key,只切 is_active true/false |
POST | /api/v1/projects/{projectId}/byok-keys/{provider}/test | 用已存 Key 对上游再探一次 |
DELETE | /api/v1/projects/{projectId}/byok-keys/{provider} | 删除该 Key |
完整请求/响应结构看 参考 → API → BYOK。
项目 API Key 的 Scope
通过控制台或 POST /api/v1/projects/{project_id}/api-keys 创建的项目 API Key
带有 scopes 数组。如需通过 SDK 以编程方式操作 BYOK,该 Key 需要:
read:byok— 列出提供商及查看健康状态。write:byok— 设置 / 停用 / 删除 / 重测 Key。
租户级凭据(Clerk 控制台会话、带 ["*"] 的默认 API Key)自动拥有所有
BYOK 操作的访问权限。
Scope 字符串区分大小写,以动词开头,全部小写(read:byok,而非 BYOK:Read)。
设置一把 Key
import { Sonzai } from "@sonzai-labs/agents";
const client = new Sonzai({ apiKey: process.env.SONZAI_API_KEY! });
const key = await client.byok.set("project_xyz", "openai", process.env.MY_OPENAI_KEY!);
console.log(key.api_key_prefix); // 例如 "sk-..." ── 永远不会是完整 Key
console.log(key.health_status); // 同步探针通过后为 "healthy"列出与查看
const keys = await client.byok.list("project_xyz");
for (const k of keys) {
console.log(k.provider, k.api_key_prefix, k.health_status, k.last_used_at);
}启用、停用、删除
PATCH 不换 Key,只切 is_active ── 想暂停但保留 Key 时用。
DELETE 把 Key 和它的历史一并清掉。
// 暂停这把 BYOK Key(后续调用回到平台计费)
await client.byok.setActive("project_xyz", "openai", false);
// 重测
const fresh = await client.byok.test("project_xyz", "openai");
// 永久删除
await client.byok.delete("project_xyz", "openai");缓存与失效
平台为了性能,会按 (project_id, provider) 在进程内缓存解析后的
BYOK Key。每次 Set / Patch / Delete 都会触发失效,轮换后的 Key
下次调用就生效,不需要重启。
BYOK 不适用的情形
如果某次对话调用最终落到的提供商在该项目下没有 BYOK Key,Sonzai 就照常用平台自己的 Key 计费 ── 体验和 SLA 完全不变。BYOK 是 纯加性 的:配上 Key 就接管那个提供商;删掉 Key 就回到 平台 Key。
参考
- Custom LLM (BYOM) ── 不是提供商透传,而是把整个端点换成你自己的。
- 参考 → API → BYOK ── 上述每个端点的 REST 结构。