自带模型通道(BYO Provider)
把对话用的 LLM 换成你自己的 OpenAI 兼容端点:你的 base_url、你的 key、你的模型账单。不配则一切照旧走平台通道;配了之后平台还能在你的通道故障时显式回落兜底(可关)。
是什么
- BYO = Bring Your Own:任何 OpenAI 兼容的
chat/completions端点都能接(OpenAI、MiniMax、DeepSeek、自建网关…)。 - 通道是租户级配置:整个租户的
/v1/agent对话都走它(与 App/人格/知识库等特性正交,模型/思考/温度仍按App > 租户设置 > 平台默认回落)。 - key AES-256-GCM 加密落库,明文永不回显(下文「安全模型」)。
配 BYO 时建议同时在「模型设置」里配上该端点认识的模型名——模型名仍按既有三级回落,留空会用平台默认模型名(你的端点多半不认识它,届时每轮都会触发故障转移)。
怎么配
控制台「自带模型通道」卡:填 Base URL + API Key,选好「失败自动回落」开关,保存。保存后输入框清空,状态行显示 已配置 · <base_url> · key …末4位。改任何一项(含开关)都需连同 Key 一起重新保存。
机器侧同形(Bearer 租户通用 key;App 级 key 一律 403 无管理权):
bash
# 配置(failover 缺省 true)
curl -X PUT "$BASE/v1/provider" \
-H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
-d '{"base_url":"https://api.openai.com/v1","api_key":"sk-…","failover":true}'
# 查看(只回 configured / base_url / key_tail / failover,绝无明文)
curl "$BASE/v1/provider" -H "Authorization: Bearer $KEY"
# 清除(回平台通道)
curl -X DELETE "$BASE/v1/provider" -H "Authorization: Bearer $KEY"校验规则:base_url 只许 http(s)://、≤300 字符、host 不得是内网字面量(localhost / 127.* / 10.* / 192.168.* / 169.254.* 等);api_key 非空 ≤500 字符。平台未注入加密密钥时配置端点回 503「BYO 未启用」。
测试通道
bash
curl -X POST "$BASE/v1/provider/test" -H "Authorization: Bearer $KEY"
# → {"ok":true,"latency_ms":842}
# → {"ok":false,"latency_ms":631,"error":"通道返回 HTTP 401"}用已保存的配置对你的端点真打一发最小补全(max_tokens:1,单次不重试),回连通性 + 时延;错误已脱敏(只有状态码分类,不含 key/URL 细节)。未配置时 400。
故障转移语义(显式,不静默)
- 你的通道每次请求都先经过平台同款流式安全重试(吐第一个字之前至多 5 次,退避递增)。
- 重试耗尽仍败,且
failover开:平台先在 SSE 流里发一条provider_fallback事件{type:"provider_fallback", from:"byo", reason:"<分类词>"},然后用平台通道重跑你这一轮——失败那次没有进会话历史,重跑语义干净。reason是脱敏分类词:retry_exhausted/upstream_4xx/upstream_5xx/channel_unavailable/provider_error。 - 该轮收尾的
stats事件带channel字段:byo(你的通道成功)/platform(没配 BYO)/platform_fallback(本轮是回落重跑的)——账单可解释。 failover关:不偷跑平台通道,按普通错误处理(流内error事件,友好话术)。- 客户端注意:极少数情况下你的通道是流到一半才断的——
provider_fallback之后的llm_delta流是从头重来的,收到该事件请清空本轮已渲染的增量;无论如何以llm_end.reply为权威全文(既有纪律)。
安全模型
- 密文落库:key 用 AES-256-GCM 加密后才进数据库,格式
v1:<nonce>:<密文+认证tag>;每次保存都用新的随机 nonce。 - 密钥分离:加密数据密钥存在 Workers Secret(
PROVIDER_ENC_KEY),与数据库分离——拖库只见密文,Secret 与库双泄才破。 - 明文不回显:GET 永远只回末 4 位(
key_tail);明文只在你保存的那一次请求体里出现,之后无从取回(忘了就重新保存)。 - 明文生命周期:解密只发生在请求路径内存中(对话装配 / 测试探针 / 取末 4 位),用后即弃;绝不进日志、SSE 事件、错误文本。
- 已知限制(如实):
base_url的内网防线是字面量级的(协议白名单 + 长度 + 内网 IP/localhost 字面量),不解析域名指向、不防 DNS rebinding/重定向/十进制 IP 变体;测试探针无超时控制(指向不响应的端点会等到平台侧链路超时)。BYO 端点的质量与兼容性由你负责——报错会被喵化,细节看provider_fallback.reason与测试端点。