官方仓库:Guyao146/Sakura-AI-Gateway。 从改名前版本升级请先阅读名称与数据迁移说明,尤其是 Docker 数据卷与桌面客户端数据目录。
📚 Wiki 文档:
- 服务器/浏览器浏览:
wiki/index.html(自包含阅读器,切页自动回到顶部;需通过 http 访问)- 源码版:
wiki/index.md—— 包含架构与模块、接口参考、模型路由与轮询池、指标与请求日志、认证与安全、部署与配置、开发与测试。
一个运行在本机的轻量模型聚合网关。它不依赖 npm 第三方包,使用 Node.js 内置 HTTP 服务和 fetch,可以把本地客户端的 OpenAI / Anthropic 请求转发到多个可配置的上游站点。
- OpenAI 兼容接口:
POST /v1/chat/completions、GET /v1/models - OpenAI Responses 兼容接口:
POST /v1/responses - OpenAI Responses 原生透传,保留 Codex、Computer Use、Shell、Apply Patch 等 Agent 工具、状态字段和 SSE 事件
- Anthropic 兼容接口:
POST /v1/messages - OpenAI ↔ Anthropic 请求、响应和 SSE 流式响应转换
- 流式响应保持统一的响应 ID,支持文本增量、结束事件和上游返回的 usage 统计
- 后台添加、编辑、删除、测试上游站点,并支持单个或批量按需查询余额
- 上游协议支持 OpenAI 兼容和 Anthropic;支持 Bearer、
x-api-key、无鉴权 - 本地模型名到上游模型名的路由映射,支持
*兜底路由 - 路由支持备用上游;主上游连接失败、超时、429 或 5xx 时按顺序切换
- 请求统计和最近请求元数据,可查看成功率、故障转移次数、Token 数量及按上游统计;请求日志支持按关键字、本地 API Key 和时间段组合筛选,关键字可检索客户端内容摘要
- 路由支持故障转移、轮询、加权轮询和随机四种策略
- 添加上游时填写地址和 API Key 即可从
/v1/models拉取并回填模型列表 - 已保存的上游支持从
/v1/models同步模型列表 - 余额查询支持 NewAPI Token Usage、常见额度字段和 Sub2API 平台额度响应;结果仅缓存在内存中
- 模型目录会合并不同上游的同名模型,并支持按前缀展开/收起、搜索和复选框选择
- 同名模型可自动轮询所有健康来源站,也可通过下拉框固定某一个站点
- 可为每个模型设置本地别名、默认思考强度和接口协议(Chat Completions 或 Responses)
- 思考强度支持“遵循客户端设置”,选择该项时网关不注入默认思考参数,由客户端显式参数决定
- 支持“拉取思考强度”:对上游未声明档位的模型发送极小探测请求,确认真实支持的低/中/高档位
- 管理后台的上游、路由和本地 Key 卡片支持拖拽排序,顺序保存在当前浏览器中
- 管理页面支持 F5 刷新;请求统计可导出最近 100 条或当前保留的全部用量记录
- 每个模型的自动站点池可调整使用优先级,优先顺序随模型选择一起保存
- 请求统计面板每 5 秒自动刷新,不会重新加载配置或打断模型选择草稿
- 后台支持检查 GitHub Release;正式 Release 包含 SHA-256 digest 时可备份
data/后自动升级并重启 - 支持从上游模型元数据识别 reasoning/thinking 能力,并转换思考参数
- 管理后台按访问来源认证:本机回环访问免认证,远程访问可使用外部 OIDC 提供商统一登录或本地账号密码,两者可在后台随时切换
- OIDC 使用 Authorization Code + PKCE、state、nonce、JWKS 签名校验和 HttpOnly 会话
- 本地账号密码使用 scrypt 加盐哈希,登录带来源失败锁定;会话绑定登录时的访问来源
- 本地 API Key 管理
- 第三方账号授权:管理员登记应用与回调白名单,用户通过已有本地账号/OIDC 登录并明确同意;使用 OAuth 2.0 授权码 + S256 PKCE 换取独立模型访问令牌,支持刷新、过期与撤销,不共享密码或原始 API Key,也不授予管理权限
- 本地 API Key 支持启用/停用和重命名,至少保留一个可管理的 Key
- 每个 Key 可独立设置允许的模型分组与组内模型:进入「本地调用 Key → 新建/编辑 → 自定义分组与模型」,启用分组后逐个勾选或组内全选。分组沿用目标模型 ID 的前缀,别名独立授权;新同步模型不会自动加入权限。旧 Key 默认允许全部模型,自定义为空则禁止全部模型;模型列表与 Chat / Messages / Responses 调用均受限制。
- 可配置上游超时、每个上游的重试次数、备用尝试次数和切换前等待时间
- 每次模型请求返回
x-request-id,启动转发前在网关控制台输出该 ID,并把同一 ID 传递给上游;错误响应也会连同 ID 输出到控制台和后台日志 - 上游健康状态和内存熔断:连续失败达到阈值后暂时跳过,冷却后自动半开探测
- 配置保存在
data/config.json,该文件已加入.gitignore - 默认只监听
127.0.0.1,避免未经配置暴露到局域网
在后台「访问控制 → 本地调用 Key」页的「账号授权应用」登记应用名称、来源 Key(模型权限与配额上限)以及准确的回调地址。将生成的 Client ID 交给接入方,不需要提供来源 Key 明文。目前复用已有管理员账号/OIDC 登录,并非新增普通用户体系;本机免登录管理也不能跳过账号登录和授权确认。
- 发现:
GET /.well-known/oauth-authorization-server - 授权:
GET /oauth/authorize,只接受response_type=code、随机state和 S256 PKCE - 换码/刷新:
POST /oauth/token,支持表单编码与 JSON;访问令牌有效期 1 小时,offline_access持续连接最长 30 天 - 模型请求携带
Authorization: Bearer <access_token>;配置读取使用GET /api/integration/config - 撤销:
POST /oauth/revoke或后台「第三方接入授权 → 取消授权」;撤销使该授权的访问与刷新令牌立即失效 - 远程授权必须使用 HTTPS;只有回环开发访问允许 HTTP。反向代理需配置
TRUSTED_PROXY_ADDRESSES并正确传递Host、X-Forwarded-For、X-Forwarded-Proto
原有 API Key 流程继续保留:第三方填写网关地址和本地 Key 后,可调用 POST /api/integration/verify 自动拉取配置;后续使用原始 Key 调用模型。旧 sakura-int_ 接入登记令牌仅用于配置与登记管理,不能调用模型,不要与 OAuth 访问令牌混用。
完整参数、权限规则、刷新与撤销示例见第三方接入指南。
仓库包含两种桌面客户端:
clients/webview2:.NET 8 WinForms + Microsoft Edge WebView2;客户端目录内带有官方 Node.js 20 Windows x64 runtime,网关配置保存在当前用户的 LocalAppData,不会随程序升级覆盖。clients/electron:Electron + electron-builder;Electron 自带运行时,网关配置保存在 Electron 的 userData 目录。
推送 vX.Y.Z tag 后,GitHub Actions 会在 Windows runner 上编译并创建同一个 GitHub Release,
制品名称带有技术栈后缀:
Sakura-AI-Gateway-X.Y.Z-WebView2-win-x64.zip
Sakura-AI-Gateway-X.Y.Z-Electron-win-x64-Setup.exe
Sakura-AI-Gateway-X.Y.Z-Electron-win-x64-Portable.exe
WebView2 客户端要求 Windows 已安装 Microsoft Edge WebView2 Runtime;Electron 客户端不要求
额外安装 Electron。网关源码升级包另为 Sakura-AI-Gateway-vX.Y.Z.tar.gz。
桌面客户端会为内嵌网关自动选择空闲的 127.0.0.1 端口,并覆盖旧配置中的监听端口,避免
以前手动运行网关留下的 data/config.json 导致客户端白屏或连接到错误端口。
需要 Node.js 18 或更高版本(当前服务使用 Node 18+ 内置 fetch)。在 Windows PowerShell 中:
cd "D:\VSProject\Sakura-AI-Gateway"
node src/server.js如果 PowerShell 的执行策略阻止 npm.ps1,本项目不需要 npm 安装依赖,直接使用 node src/server.js 即可。也可以使用:
npm.cmd start启动时终端会打印默认本地 API Key:sk-local_...。打开 http://127.0.0.1:8787/ 后,本机回环访问会自动进入后台,不需要输入任何管理凭据。
管理认证与模型调用认证彼此独立:
- 管理后台和
/api/admin/*:本机回环访问免认证;远程访问需要登录,可在后台「访问控制 → 管理认证」里选择外部 OIDC 提供商统一登录或本地账号密码 /v1/*模型接口:无论本机还是远程,仍然必须使用后台创建的本地 API Key
如果不想部署独立的 OIDC 提供商,也可以让网关自己验证管理账号密码。两种远程认证方式可以随时切换:
- 本机回环访问默认免认证;只有远程访问管理后台时才需要登录(也可以在后台开启「本机访问也要求登录」,见下文)
- 密码使用 scrypt(含随机盐)哈希后保存在
data/config.json,明文不会回传前端,也不会写入请求日志 - 登录接口带来源失败锁定:同一来源 5 次失败后锁定 60 秒
- 模型调用接口不受影响,仍使用本地 API Key
- 在网关所在本机打开 http://127.0.0.1:8787/(回环访问免认证)
- 进入「访问控制 → 管理认证」,点击「+ 新建账号」创建第一个管理员账号
- 选择「本地账号密码」并点击「保存认证方式」
之后远程访问网关首页会进入登录页,输入账号密码即可进入后台。需要换回统一登录时,在同一面板选择「外部 OIDC 提供商」保存即可(前提是已配置下面的环境变量)。
桌面客户端和本机浏览器都走回环地址,默认免认证。如果希望本机打开后台也要登录,在「管理认证」面板勾选「本机访问也要求登录」再保存即可:
- 仅在「本地账号密码」模式下、且至少存在一个启用账号时生效;
- 还没有任何账号时不会生效,保留创建第一个账号的入口;
- 保存后当前页面会立即失效,跳转到登录页,用刚配置的账号登录即可;
- OIDC 模式下不生效(避免外部 OIDC 提供商不可用时把管理员锁死在本机)。
也可以在启动时用环境变量直接指定初始认证方式:
$env:ADMIN_REMOTE_MODE = "password" # 或 oidc(默认)注意:
ADMIN_REMOTE_MODE只决定启动时使用的模式;在后台切换后会以配置文件为准。
- 用户名 3 到 32 个字符,可用字母、数字以及
. _ @ + - - 密码至少 8 个字符,不能包含空白字符
- 账号可启用/停用;本地账号模式下至少保留一个启用账号
- 编辑账号时密码留空表示不修改;密码以哈希存储,无法找回明文,只能重新设置
创建一个 OAuth2/OpenID Provider,并建议使用:
- Client type:
Confidential - Authorization flow:
Authorization Code - Redirect URI:你的公网网关地址加
/auth/oidc/callback,例如https://gateway.example.com/auth/oidc/callback - Scopes:
openid profile email - Signing Key:建议选择证书密钥,让 ID Token 使用非对称签名并通过 JWKS 校验
- Encryption Key:不要配置;当前网关验证签名 JWT,不支持加密的 JWE ID Token
然后创建 Application 并绑定该 Provider。哪些用户或组能进入后台,应通过提供商 Application 的 Policy/Binding 控制;只要用户能通过这个 Application 的认证,就拥有网关管理权限。
Issuer URL 使用该 Application 的 OIDC issuer,通常格式为:
https://auth.example.com/application/o/<application-slug>
不要在 AUTHENTIK_ISSUER_URL 末尾填写 /.well-known/openid-configuration,网关会自动请求 discovery 地址。
OIDC Client Secret 只从环境变量读取,不会写入 data/config.json 或 Git。Windows PowerShell 示例:
$env:HOST = "0.0.0.0"
$env:AUTHENTIK_ISSUER_URL = "https://auth.example.com/application/o/sakura-ai-gateway"
$env:AUTHENTIK_CLIENT_ID = "在外部 OIDC 提供商中生成的 Client ID"
$env:AUTHENTIK_CLIENT_SECRET = "在外部 OIDC 提供商中生成的 Client Secret"
$env:AUTHENTIK_REDIRECT_URI = "https://gateway.example.com/auth/oidc/callback"
node src/server.js远程用户访问 https://gateway.example.com/ 时会先进入网关自身的登录页,再由用户选择跳转外部 OIDC 提供商。登录页和会话状态检查不依赖提供商响应,因此认证服务临时不可用时仍能显示明确错误并重新尝试,不会只留下超时或空白页面。认证成功后,网关验证 discovery、issuer、audience、过期时间、state、nonce、PKCE 和 ID Token 签名,并创建仅服务端保存的 HttpOnly 会话。服务重启后远程会话失效,需要重新登录。
网关默认只根据 TCP socket 的来源地址判断本地或远程,不会直接信任客户端发送的 X-Forwarded-For。如果使用 Nginx、Caddy 或 Traefik 反向代理,必须把代理实际连接网关时使用的 IP 明确加入 TRUSTED_PROXY_ADDRESSES,多个地址用逗号分隔。例如代理与网关都在本机:
$env:TRUSTED_PROXY_ADDRESSES = "127.0.0.1,::1"反向代理必须覆盖而不是盲目透传客户端提供的来源头。例如 Nginx:
location / {
proxy_pass http://127.0.0.1:8787;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $remote_addr;
}如果不使用反向代理、远程客户端直接连接网关,不要设置 TRUSTED_PROXY_ADDRESSES。该变量只接受精确 IP 地址,不接受主机名或 CIDR。错误地信任客户端可以直接连接的地址会造成认证绕过风险。
注意:如果同机反向代理连接
127.0.0.1,但没有配置TRUSTED_PROXY_ADDRESSES,网关看到转发头时会拒绝把该连接当作本地访问,并要求完成统一登录,防止远程请求被错误地免认证。
本机免认证访问请使用 http://127.0.0.1:8787/、http://localhost:8787/ 或 IPv6 回环地址。管理后台会校验回环 Host、Origin 和浏览器来源信息,防止 DNS Rebinding 或跨站页面利用本机免认证权限修改配置。
通常填写:
- 地址:站点的 API 根地址,例如
https://example.com/v1 - 协议:
OpenAI 兼容 - 鉴权:
Bearer - API Key:该站点的 Key
- 客户端兼容标识:默认不覆盖;遇到站点按客户端区分兼容性时可选择预设或自定义
User-Agent - 余额接口路径:通常留空自动探测;私有站点可填写同源相对路径
- 模型列表:填写地址和 API Key 后可点击“拉取模型”自动获取,也可以每行手工填写一个
如果站点明确要求 x-api-key,把鉴权方式改为 x-api-key。
每个上游可以独立选择客户端兼容标识,应用于模型调用、连接测试、模型拉取和余额查询:
- 默认:不主动覆盖
User-Agent,由 Node.jsfetch使用自身默认值 - Claude Code:发送
User-Agent: claude-code - OpenAI Codex CLI:发送稳定标识
User-Agent: codex_cli_rs和originator: codex_cli_rs;官方完整 UA 还会动态包含版本、系统、架构和终端信息,需要精确值时请使用自定义模式 - Cherry Studio:发送
User-Agent: CherryStudio - 自定义:发送用户填写的
User-Agent
该功能只用于兼容需要识别客户端类型的上游,不会修改 Authorization、x-api-key 或 Host,也不会伪造动态会话头、设备证明、账号签名或 attestation。自定义值最长 300 个字符并拒绝 CR/LF、Tab 等控制字符,避免请求头注入。请仅在上游服务条款允许的情况下使用;它不能替代站点授权,也不保证绕过服务端的完整客户端校验。
上游卡片中的“查询余额”只查询当前站点,“查询全部余额”会以最多 4 个并发查询所有上游。查询使用上游现有的 Bearer、x-api-key 或无鉴权设置,不会修改模型请求的健康状态或触发熔断。
- 留空“余额接口路径”时,会自动尝试 NewAPI 的
/api/usage/token和 Sub2API 的/api/v1/user/platform-quotas。 - NewAPI
/api/usage/token返回的是站点内部额度单位,后台会显示为“额度”,不会擅自换算为美元。 - Sub2API 的
daily_*_usd、weekly_*_usd、monthly_*_usd字段会按 USD 展示,并计算各窗口剩余额度。 - 部分 Sub2API 或私有站点的账户额度接口只接受面板 JWT,不接受模型 API Key;这种情况会显示查询失败或不支持。可以填写站点提供的同源余额接口路径,但当前不会额外保存面板登录凭据。
- 自定义路径必须以
/开头,且只能访问当前上游同源地址;不接受完整 URL、查询参数或片段。 - 查询结果和失败原因仅保存在进程内存中,重启后需要重新查询;不会写入
data/config.json,也不会把上游原始响应返回给浏览器。
填写:
- 地址:站点 API 根地址,例如
https://example.com或https://example.com/v1 - 协议:
Anthropic - 鉴权:默认
x-api-key - API Key:该站点的 Key
网关会请求上游的 /v1/messages,并自动转换 system、文本、工具调用以及流式事件。
例如将本地客户端请求的 claude-3-5-sonnet 转发为某个上游实际模型:
- 本地模型名:
claude-3-5-sonnet - 上游:选择目标站点
- 上游模型名:
claude-3-5-sonnet-20241022
路由优先级:精确路由 → * 兜底路由 → 上游模型列表匹配 → 仅有一个启用上游时自动转发。
路由可以配置多个备用上游。非流式请求在主上游连接失败、请求超时、返回 408/425/429 或 5xx 时,会依次尝试备用上游;如果上游已经返回 4xx 参数或鉴权错误,网关不会自动换站点掩盖配置问题。流式请求也只会在建立上游响应之前切换,一旦开始向客户端输出内容就不会中途重试,避免重复生成内容。
路由的分流策略可以选择:
failover:按主上游和备用上游顺序尝试,旧路由默认使用此策略round_robin:健康候选上游轮询分配weighted:按路由中配置的正整数权重进行平滑加权轮询random:从健康候选上游中随机选择
轮询、加权和随机策略仍会在选中的上游失败时尝试本次请求的其它候选;熔断中的上游不会参与分流。策略游标只存在内存中,重启后重新开始。
Base URL 填:
http://127.0.0.1:8787/v1
API Key 填后台创建的本地 Key,模型名填配置的“本地模型名”。例如:
curl http://127.0.0.1:8787/v1/chat/completions ^
-H "Content-Type: application/json" ^
-H "Authorization: Bearer sk-local_xxx" ^
-d "{\"model\":\"claude-3-5-sonnet\",\"messages\":[{\"role\":\"user\",\"content\":\"你好\"}]}"Base URL 同样填:
http://127.0.0.1:8787/v1
请求 POST /v1/messages,使用本地 API Key 作为 x-api-key 或 Bearer Token。网关会根据模型路由选择上游。
支持常见的 Responses 请求字段 input、instructions、max_output_tokens、tools 和 stream。OpenAI 上游默认优先使用原生 /v1/responses;普通请求在自动模式下可于原生端点不可用时兼容回退。Agent 专有字段以及“function tools + 非 none 的 reasoning_effort”必须使用原生 Responses,禁止有损回退到 /v1/chat/completions。非流式示例:
客户端调用网关的 /v1/chat/completions 时,自动或 Chat 模式保持使用上游 Chat 接口,function tools 与 reasoning_effort 可以同时传递,不会因为开启思考切换协议。显式选择 native(Responses)模式时,网关才将 Chat 请求转换到 /v1/responses,再将结果转回 Chat;工具输出项 ID、调用 ID 和输出序号会关联到同一个 Chat 工具 index,保证工具首帧携带字符串 ID。
curl http://127.0.0.1:8787/v1/responses ^
-H "Content-Type: application/json" ^
-H "Authorization: Bearer sk-local_xxx" ^
-d "{\"model\":\"gpt-4o\",\"instructions\":\"Be concise\",\"input\":\"你好\",\"max_output_tokens\":100}"Responses 流式请求会返回 response.created、response.output_text.delta、response.output_text.done 和 response.completed 等 SSE 事件。当前版本重点兼容文本输出;如果上游在流中返回 usage,网关会同步到后台统计。复杂的 Responses 专有事件和部分高级工具事件会在后续继续扩展。
后台“配置备份”区域可以导出完整 JSON 配置,也可以从备份文件导入上游和路由。导入默认保留当前机器的本地 API Key;备份中的完整上游 API Key 会恢复,掩码 Key 会尝试使用当前相同上游 ID 的 Key。旧备份中的管理员 Token 字段仅为格式兼容保留,不再参与后台认证。监听地址或端口导入后需要重启服务才会生效。
后台的“请求统计”区域会显示请求总数、成功率、故障转移次数、输入/输出/总 Token、按上游统计以及请求元数据日志。日志默认保留最近 5000 条(可用环境变量 SAKURA_AI_GATEWAY_MAX_LOGS 调整,最少 100),页面先显示最新 100 条,点击“加载更多”按 100 条为一页向下翻。从 v2.0.7 起,每条日志还会带一份请求诊断(点该行即可展开):网关实际发给上游的请求体、上游返回与网关输出的前若干帧样本,以及自动修正过的异常(例如上游返回了非字符串 id)。这些样本用于排查协议转换问题,因此会包含消息内容,但不会包含请求头、API Key 或上游完整地址(只记录路径,如 /v1/responses);每个字段都做了长度截断。可以在后台点击“清空统计”。聚合计数保存在 data/metrics.json,请求日志以追加写入的方式保存在 data/metrics-log.jsonl(旧版内联日志会在首次启动时自动迁移),与上游配置分开保存。
添加或编辑上游时,填写地址和 API Key 后可以直接点击“拉取模型”,网关会调用该站点的 /v1/models 并把模型 ID 回填到表单;确认列表后仍需点击“保存上游”。编辑已有上游时 API Key 可以留空,拉取会安全复用已保存的 Key。已保存的上游卡片也提供“同步模型”按钮。部分 Anthropic 上游没有标准模型列表接口,此时仍需手工填写模型。
每行「拉取能力」会刷新各来源站的模型元数据,并仅为当前模型补充思考强度探测(上游已声明时跳过,探测可能收费)。拉取全部模型同样读取模态声明。界面按来源站显示输入/输出模态,路由时以实际候选站的能力为准,不使用合并后的并集进行校验。
- 识别
input_modalities/output_modalities、驼峰写法、supported_input_modalities/supported_output_modalities、capabilities、modalities.input/output、OpenRouter 风格architecture.input_modalities/output_modalities与architecture.modality(如text+image->text)。vision、supports_image等布尔声明只影响对应模态。 - 上游未声明的能力显示未知,不是“纯文本”。未知时保持原有透传行为;不根据模型名称或 HTTP 200 猜测视觉能力,不自动发图片/音频付费探测。同步缺少字段或失败时保留原有结论,新声明覆盖旧声明。
- 在模型行或手工路由中选择「模态转译模型」(一个已启用的本地模型名/别名)。确认目标不支持某个附件时,先将该附件单独发送给转译模型,再用标记过的文字记录替换原位置。其他文字、工具调用和消息顺序不变。同一请求的重复附件复用转译结果,目标仍可流式输出。
- 留空则返回
400 unsupported_input_modality;Key 必须同时有权访问目标与转译模型,否则403 model_not_allowed。转译模型必须明确支持该输入,不能自引用,也不会递归调用它的转译配置。删除/停用转译模型后返回配置错误。 - 支持检查 Chat、Messages、Responses 中的图片、音频、视频、文件块及工具结果内附件。图片有跨协议转换;其他媒体优先使用同协议上游,无法无损转换时明确报错,绝不静默删除。跨上游的
file_id不可转译,应改传文件内容/URL;只处理本次请求显式携带的附件,不读取 Responses 历史状态。 - **费用与隐私:**附件会发送给所选转译模型,产生额外费用与延迟,文字记录可能有误或丢失细节。转译不发送完整对话、不启用工具;单次最多转译 16 个附件,每个最多输出 4096 tokens,超时上限 120 秒(更短的上游超时仍生效),空结果、截断或失败返回 502,不再调用目标模型。转译请求单独计入统计,日志 ID 带
-translation-,不包含额外的附件诊断样本。仅支持输入转为文本,不生成或转译图片/音频输出;目标明确不支持请求的输出模态时返回 400。
能力字段与 modalityTranslator 均会持久化,并随配置导出/导入保留。转译模型可先创建为手工路由或保存为已选择模型,再为目标配置。
后台“本地模型选择”区域会先按模型 ID(忽略大小写)合并所有来源站,再按模型 ID 前缀分组展示。前缀默认收起。前缀取模型 ID 中第一个 -、_、: 或 / 之前的部分,例如 gpt-4o 归入 gpt、claude-3-7-sonnet 归入 claude。大小写不同的拼写视为同一个模型,合并成一行并以「当前名称」显示,转发时按各站自己的拼写发送。可以:
- 点击“拉取全部模型”尝试从所有启用上游的
/v1/models获取模型;不提供该接口的 Anthropic 站点继续使用上游表单中的手工模型 - 使用搜索框按站点名、模型 ID 或显示名筛选
- 点击前缀标题展开、收起,也可以使用顶部“全部展开/全部收起”控制所有前缀
- 按单个模型前缀“全部勾选/全部取消”
- 勾选要暴露给本地 APP 的模型
- 同一个模型 ID 在多个站点存在时,从行内下拉框选择“自动选择”或固定某一个来源站;选“自动选择”后会出现“轮询站点”勾选框,可以只勾选想参与轮询的上游(至少保留两个,全部取消时自动回退为全部站点)
- 给模型设置本地别名
- 为每个模型设置默认思考强度:自动、关闭、低、中、高
- 为每个模型设置接口协议偏好:
auto(默认,按上游支持情况自动选择)、native(强制/v1/responses)、chat(强制/v1/chat/completions)。该设置覆盖上游的responsesMode,适合同一个站点上不同模型走不同协议的场景;选native时即使上游返回 404/405/501 也不会悄悄回退到 Chat Completions
新勾选的同名模型默认使用“自动选择”:网关会为所有提供该模型的站点创建轮询候选池,只在启用且未熔断的站点之间分配请求;连接失败、超时、408/425/429 或 5xx 时仍会尝试本次请求的其它候选。选择具体站点则只使用该站。旧配置中的单站选择会继续显示为固定站,不会在未保存时改变行为;重新选择“自动选择”并保存后才会启用候选池。
点击“保存勾选”后,网关会自动创建或更新选择器管理的本地路由;同名模型只保留一个选择器路由。旧版按站点重复保存的同名选择会自动合并为候选池,并保留第一条记录的本地别名;导入旧备份时也会删除多余的旧托管路由。原有手工路由不会被覆盖。进入选择器模式后,/v1/models 只展示勾选的本地模型和手工路由,不再展示未勾选的上游原始模型。取消所有勾选也会生效,表示只保留手工路由。
思考强度的转换规则:
- Responses 出站始终发送
reasoning: { effort: "none" },覆盖客户端、路由和模型默认思考强度,并移除reasoning_effort/thinking冲突字段。 - 自动接口模式会识别接口不支持、function tools 与思考参数不兼容等错误,在同一已配置上游尝试 Chat / Responses / Messages;持续服务失败会触发按模型、接口隔离的冷却(默认连续 3 次、60 秒)。显式锁定接口、鉴权/普通参数错误不盲目切换;已输出的流不重放。详见 接口智能切换与冷却。
- OpenAI Chat 兼容上游:低/中/高转换为
reasoning_effort: low/medium/high - 上游声明的
none / minimal / xhigh也会保留、显示并可选,支持档位数组及reasoning.effort.enum/reasoning.supported_efforts等形式;Chat 按原档位发送,Responses 固定none。none会显式发送,和「关闭(剥离思考参数)」不同。主动探测仍只试低/中/高三档,不凭空补全额外档位 - Anthropic 上游:低/中/高转换为
thinking: { type: "enabled", budget_tokens: 2048/4096/8192 } - Anthropic 的预算映射不支持
none / minimal / xhigh这些默认档位,配置后返回明确错误,不会偷偷改成中档;可改用低/中/高或遵循客户端 - 自动:不主动添加思考参数
- 上游明确声明不支持思考时:不会添加思考参数
- 上游能力未知时:后台仍允许配置;如果客户端没有显式思考参数,网关会按选择的强度尝试发送
- 客户端请求显式提供
reasoning_effort或thinking时,优先使用客户端值 - 参数形态与目标端点自动匹配:发往
/v1/responses的一律使用reasoning: { effort },发往/v1/chat/completions的一律使用reasoning_effort,客户端传入的另一种形态会被转换,避免上游以「调用的接口类型和传入的参数不匹配」拒绝请求
网关会识别常见的模型能力字段,包括 supports_thinking、supports_reasoning、thinking_levels、reasoning_effort、capabilities.thinking、supported_parameters 等;部分常见 Claude 3.7/4、o1/o3/o4、GPT-5 模型也会按模型名做保守推断。不同站点的私有字段可能需要后续适配。
上游没给档位时,可以点模型目录工具栏的「拉取思考强度」(或在某个上游卡片上点「探测思考」)主动确认:
- 网关对每个能力未知的模型逐档发送
reasoning_effort: low/medium/high探测请求;OpenAI 兼容上游用max_tokens: 1,Anthropic 上游取协议允许的最小思考预算(budget_tokens: 1024) - 已由上游元数据声明过能力的模型会跳过,不会重复消耗额度;也可以只对单个上游重新探测
- 只有上游确实接受的档位才会保留,模型行会显示「支持思考 + 低/中/高」和「探测」标记;探测为不支持时网关不会向该模型发送思考参数
- 连接失败、超时、429 与 5xx 视为「没能得出结论」,会保留原有判断,不会把不确定写成不支持
- 探测请求不写入请求统计、不触发熔断;结论写入配置文件,重新同步模型也不会被抹掉
- 之后该模型的思考强度下拉只列出探测到的档位;此前保存过但上游未探测到的档位仍会保留并标注,不会静默改写你的选择
后台“可靠性设置”可以调整:
- 上游超时:1000 到 3600000 毫秒,默认 600000 毫秒
- 每个上游重试次数:0 到 10 次,默认 0。某个上游出现连接失败、超时、429 或 5xx 时,先原地重试同一个上游这么多次,仍失败才切换到下一优先级的备用上游;4xx 参数/鉴权类错误不重试也不切换,直接返回
- 最大备用尝试次数:0 表示不限制;1 表示主上游失败后最多再尝试 1 个备用
- 切换前等待:0 到 30000 毫秒
- 熔断失败阈值:1 到 20 次,默认 3 次
- 熔断冷却时间:1000 到 3600000 毫秒,默认 60000 毫秒
- 最大并发请求数:0 表示不限制,范围 0 到 1000
- 每 Key 每分钟请求数:0 表示不限制,范围 0 到 10000
- 错误消息前缀:最长 60 个字符,默认为空。JSON 和 SSE 错误消息统一为
自定义前缀 [request_id=请求ID] [code=错误码] 原始报错内容,例如[SakuraGateway] [request_id=req_xxx] [code=400] model 不能为空。错误码优先使用上游code,缺失时使用 HTTP 错误状态码;流内错误没有 HTTP 错误状态时用502,不把type或握手的200当成错误码。留空只省略自定义前缀,请求 ID 和错误码仍显示;成功响应及正常流式内容不受影响
本地 Key 的完整值可以在已认证的管理后台直接查看和一键复制,也可以编辑名称、启用或停用。停用会立即使该 Key 的模型请求返回 401;系统不允许删除最后一个本地 Key。
后台上游卡片会显示健康状态、连续失败次数和熔断冷却时间。熔断状态只存在内存中,网关重启后会清除;也可以点击“重置状态”立即恢复该上游。熔断失败阈值默认是 3 次,冷却时间默认是 60000 毫秒。
每次 /v1/chat/completions、/v1/messages 或 /v1/responses 请求都会返回 x-request-id。如果客户端自己提供符合格式的 x-request-id,网关会沿用它并传给上游;否则自动生成一个。后台请求日志也会保存这个 ID。
限流只作用于模型调用接口,不影响 /v1/models 和管理接口。并发限制是全局模型请求数;每分钟限制按本地 API Key 独立计算。被拒绝请求返回 HTTP 429、Retry-After 和 x-request-id,不会消耗并发槽或每分钟配额。
HOST:监听地址,默认127.0.0.1PORT:监听端口,默认8787SAKURA_AI_GATEWAY_DATA_DIR:可选,指定配置数据目录;默认是项目下的dataADMIN_REMOTE_MODE:可选,远程管理认证方式,oidc(默认)或password;在后台切换后以配置文件为准AUTHENTIK_ISSUER_URL:外部 OIDC 提供商 Application 的 OIDC issuer URLAUTHENTIK_CLIENT_ID:外部 OIDC 提供商 OAuth2/OpenID Provider 的 Client IDAUTHENTIK_CLIENT_SECRET:Confidential Provider 的 Client SecretAUTHENTIK_REDIRECT_URI:完整回调地址,必须以/auth/oidc/callback结尾并与外部 OIDC 提供商配置一致AUTHENTIK_SCOPES:可选,默认openid profile emailAUTHENTIK_TOKEN_AUTH_METHOD:可选,client_secret_basic或client_secret_post;默认按 discovery 自动选择AUTHENTIK_SESSION_TTL_SECONDS:可选,远程管理会话最长有效期,默认 28800 秒,范围 300 到 604800AUTHENTIK_COOKIE_SECURE:可选;默认根据回调 URL 是否为 HTTPS 自动决定,生产环境不要关闭AUTHENTIK_POST_LOGOUT_REDIRECT_URI:可选,外部 OIDC 提供商登出后的返回地址TRUSTED_PROXY_ADDRESSES:可选,允许提供X-Forwarded-For的反向代理精确 IP 列表
如果需要让其它设备访问,可以用 HOST=0.0.0.0 启动。远程管理访问需要配置本地账号或外部 OIDC 提供商;模型接口使用本地 API Key 或获准的 OAuth 访问令牌。远程账号授权强制 HTTPS,并建议同时设置防火墙和网络访问控制。
data/config.json含有上游 API Key、本地 API Key、账号密码哈希、OAuth 应用与令牌哈希以及旧版兼容字段,请不要提交或分享;OIDC Client Secret 不会写入该文件。配置导出是敏感备份,完整恢复备份也会恢复其中的授权状态。data/metrics.json/data/metrics-log.jsonl只包含脱敏请求元数据、Token 数字与内容摘要(最后一条用户消息的截断文本,用于日志搜索),不包含完整请求正文、请求头、Key 或上游完整地址;仍建议不要分享运行数据目录。- 已认证的管理后台会显示完整本地调用 Key;上游 API Key 仍只显示掩码。请避免向不受信任的用户授予外部 OIDC 提供商的管理后台访问权限。
- 第一版按最常见的 OpenAI Chat Completions 与 Anthropic Messages 协议实现,复杂的供应商私有字段、图片 URL 的特殊格式、部分高级工具参数可能需要后续适配。
- 当前余额功能是手工按需查询,不提供定时余额监控或告警;请求用量统计也不等同于上游账单。多用户权限可在后续继续扩展。
Sakura-AI-Gateway 采用 Sakura-License:源码可用,受覆盖衍生作品须共享并保留署名,特定商业利用需书面授权;它不是 OSI 批准的开源许可证。采用声明与商业授权联系方式见 LICENSING.md。
v2.4.0及之前的历史发布版本仍按LGPL-2.1授权,已合法取得的权利不受影响。wiki/assets/marked.min.js为第三方 MIT 作品,保留其原许可,不属于本许可覆盖范围。
本项目已在 "LinuxDo - 新的理想型社区" 公开发布,创建美好社区,你我共享