diff --git a/.env.example b/.env.example index a6484ce..e4963be 100644 --- a/.env.example +++ b/.env.example @@ -1,7 +1,18 @@ +# Required in production: generate a unique 32+ byte random secret in your local .env, keep it out of git, and do not reuse AUTH_TOKEN. +ACCOUNT_CREDENTIAL_SECRET=REPLACE_WITH_STRONG_RANDOM_SECRET AUTH_TOKEN=change-me-admin-token -PROXY_TOKEN=change-me-proxy-sk-token CHECKIN_CRON=0 8 * * * BALANCE_REFRESH_CRON=0 * * * * +# Optional OAuth overrides. Fill the matching credentials when an override is enabled; Claude requires a client secret with no fallback. +CLAUDE_CLIENT_ID= +CLAUDE_CLIENT_SECRET= +# Codex OAuth override only needs CODEX_CLIENT_ID. +CODEX_CLIENT_ID= +# Gemini CLI override requires both GEMINI_CLI_CLIENT_ID and GEMINI_CLI_CLIENT_SECRET together. +GEMINI_CLI_CLIENT_ID= +GEMINI_CLI_CLIENT_SECRET= +PROXY_TOKEN=change-me-proxy-sk-token +SYSTEM_PROXY_URL= WEBHOOK_URL= BARK_URL= SERVERCHAN_KEY= diff --git a/README.md b/README.md index 8a4308d..ce9be22 100644 --- a/README.md +++ b/README.md @@ -82,15 +82,14 @@ 现在 AI 生态里有越来越多基于 New API / One API 系列的聚合中转站,要管理多个站点的余额、模型列表和 API 密钥,往往既分散又费时。 -**Metapi** 作为这些中转站之上的**元聚合层(Meta-Aggregation Layer)**,把多个站点统一到 **一个入口(可按项目配置多个下游 API Key)**——下游所有工具(Cursor、Claude Code、Codex、Open WebUI 等)即可无感接入全部模型。当前已支持以下上游平台: +**Metapi** 作为这些中转站之上的**元聚合层(Meta-Aggregation Layer)**,把多个站点统一到 **一个入口(可按项目配置多个下游 API Key)**——下游所有工具(Cursor、Claude Code、Codex、Open WebUI 等)即可无感接入全部模型。当前支持的上游范围已经不止传统聚合面板,还包括: -- [New API](https://github.com/QuantumNous/new-api) -- [One API](https://github.com/songquanpeng/one-api) -- [OneHub](https://github.com/MartialBE/one-hub) -- [DoneHub](https://github.com/deanxv/done-hub) -- [Veloera](https://github.com/Veloera/Veloera) -- [AnyRouter](https://anyrouter.top) — 通用路由平台 -- [Sub2API](https://github.com/Wei-Shaw/sub2api) — 订阅制中转 +- 聚合面板: [New API](https://github.com/QuantumNous/new-api)、[One API](https://github.com/songquanpeng/one-api)、[OneHub](https://github.com/MartialBE/one-hub)、[DoneHub](https://github.com/deanxv/done-hub)、[Veloera](https://github.com/Veloera/Veloera)、[AnyRouter](https://anyrouter.top)、[Sub2API](https://github.com/Wei-Shaw/sub2api) +- 通用兼容接口:OpenAI / Claude / Gemini compatible endpoints,以及 `cliproxyapi` / CPA +- 官方预设:阿里云 / 智谱 / 豆包 Coding Plan,DeepSeek,Moonshot(Kimi),MiniMax,ModelScope +- OAuth 连接:Codex、Claude、Gemini CLI、Antigravity + +详细接法见 [上游接入](./docs/upstream-integration.md) 与 [OAuth 管理](./docs/oauth.md)。 | 痛点 | Metapi 怎么解决 | | ------------------------------------- | ---------------------------------------------------------------------- | diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts index b193fd4..9a49d17 100644 --- a/docs/.vitepress/config.ts +++ b/docs/.vitepress/config.ts @@ -58,6 +58,7 @@ export default withMermaid( { text: '首页', link: '/' }, { text: '快速上手', link: '/getting-started' }, { text: '上游接入', link: '/upstream-integration' }, + { text: 'OAuth 管理', link: '/oauth' }, { text: 'FAQ', link: '/faq' }, { text: '文档维护', link: '/README' }, { text: '项目主页', link: 'https://github.com/cita-777/metapi' }, @@ -75,6 +76,7 @@ export default withMermaid( text: '使用与运维', items: [ { text: '上游接入', link: '/upstream-integration' }, + { text: 'OAuth 管理', link: '/oauth' }, { text: '配置说明', link: '/configuration' }, { text: 'K3s 更新中心(高级)', link: '/k3s-update-center' }, { text: '客户端接入', link: '/client-integration' }, diff --git a/docs/README.md b/docs/README.md index e1cfa7a..037275b 100644 --- a/docs/README.md +++ b/docs/README.md @@ -28,10 +28,11 @@ npm run docs:build |------|--------|------------| | 对外第一印象、产品定位、核心入口 | [文档首页](/) | 需要调整公开落地页信息架构、首页 CTA 或首屏导航时 | | 新用户部署与首条请求 | [快速上手](./getting-started.md) | 新安装流程、默认端口、首次调用步骤变化时 | -| 上游平台选择与接法 | [上游接入](./upstream-integration.md) | 平台支持范围、默认连接分段、自动识别规则变化时 | +| 上游平台选择与接法 | [上游接入](./upstream-integration.md) | 平台支持范围、官方预设、AI 请求地址池、自动识别规则变化时 | +| Provider OAuth 授权 | [OAuth 管理](./oauth.md) | 支持的 OAuth provider、授权流程、回调方式或自动重绑能力变化时 | | 生产部署与回滚 | [部署指南](./deployment.md) | Docker Compose、反向代理、升级回滚策略变更时 | | K3s / Helm 高级升级面板 | [K3s 更新中心(高级)](./k3s-update-center.md) | 需要说明谁适合使用更新中心、helper 怎么配、K3s/Helm 发布链路怎么接入时 | -| 环境变量、参数和配置项 | [配置说明](./configuration.md) | 新增配置、默认值变化、兼容行为变化时 | +| 环境变量、参数和配置项 | [配置说明](./configuration.md) | 设置页 / 通知设置 / 下游密钥这些 UI 入口变化,或仅剩 env-only 的部署级参数变化时 | | 客户端与工具接入 | [客户端接入](./client-integration.md) | Open WebUI、Cherry Studio、Cursor 等接入方式变化时 | | 管理后台脚本化调用 | [管理 API](./management-api.md) | 需要说明如何用脚本批量导入站点/账号,或对接外部自动化时 | | 运维排障与日常维护 | [运维手册](./operations.md) / [常见问题](./faq.md) | 新排障案例、备份恢复、健康检查、典型报错变化时 | diff --git a/docs/configuration.md b/docs/configuration.md index 12bb653..c73c9f7 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -1,56 +1,172 @@ # ⚙️ 配置说明 -本文档列出 Metapi 的环境变量,并单独说明管理后台中的运行时设置。 +本文档按实际使用场景说明 Metapi 的配置入口。 + +对大多数用户来说,日常配置优先通过管理后台完成;环境变量主要用于首次启动、部署级参数和当前没有 UI 的高级项。 [返回文档中心](./README.md) --- -## 配置来源 +## 概述 -| 配置类型 | 入口 | 生效方式 | 适用场景 | -|----------|------|----------|----------| -| 环境变量 | `.env` / 容器环境变量 | 服务启动时读取,作为启动配置或默认值 | 部署、容器编排、首次初始化 | -| 运行时设置 | 管理后台「设置」 | 持久化到当前运行数据库;大部分即时生效,数据库运行配置保存后需重启 | 在线调整、运维排障 | +Metapi 当前有三类主要配置入口: -## 必填配置 +1. **管理后台「设置」** — 适合日常系统设置与运行时调整 +2. **管理后台「通知设置」与「下游密钥」** — 适合通知渠道和项目级下游 Key 管理 +3. **环境变量** — 适合首次启动、部署级参数、OAuth client 覆盖、Deploy Helper token 等当前没有 UI 的项 -> ⚠️ 以下变量**必须修改**,不要使用默认值。 +下表可用于快速判断: + +| 你要改什么 | 优先去哪里 | 说明 | +|----------|------------|------| +| 日常系统设置 | 管理后台「设置」 | 大部分运行时配置都在这里,保存后直接生效或按提示重启 | +| 通知渠道 | 管理后台「通知设置」 | Webhook / Bark / Server酱 / Telegram / SMTP 都有 UI | +| 下游项目级 Key | 管理后台「下游密钥」 | 不要再回到环境变量里硬塞 | +| 首次启动令牌、端口、数据目录 | `.env` / 容器环境变量 | 这类属于部署级初始化 | +| OAuth 客户端 ID / Secret | `.env` / 容器环境变量 | 当前没有 UI | +| Deploy Helper token / helper 进程参数 | `.env` / helper manifest | 当前没有 UI,且属于集群侧部署参数 | +| 少数高级部署级参数 | `.env` / 容器环境变量 | 例如日志保留、部分探测细粒度参数 | + +--- + +## 配置入口总览 + +### 1. 管理后台「设置」 + +侧边栏入口:**系统 → 设置** + +当前已经能直接在这里配置的内容包括: + +| UI 项 | 对应能力 | 生效方式 | +|------|----------|----------| +| 管理员登录令牌 | `AUTH_TOKEN` 的后续修改 | 保存后即时生效 | +| 定时任务 | `CHECKIN_CRON`、`BALANCE_REFRESH_CRON`、日志清理计划 | 保存后即时生效 | +| 系统代理 | `SYSTEM_PROXY_URL` | 保存后即时生效 | +| 代理失败判定 | 失败关键词、空内容失败判定 | 保存后即时生效 | +| Codex 上游传输与会话并发 | WebSocket 开关、并发与队列参数 | 保存后即时生效 | +| 批量测活 | 后台模型可用性探测开关 | 保存后即时生效 | +| 下游访问令牌 | `PROXY_TOKEN` | 保存后即时生效 | +| 路由策略 | 成本/余额/使用率权重、默认单价、首字超时、协议回退、失败冷却上限 | 保存后即时生效 | +| 全局品牌屏蔽 | 全局品牌屏蔽 | 保存后即时生效,并触发路由重建 | +| 全局模型白名单 | 全局模型白名单 | 保存后即时生效,并触发路由重建 | +| 数据库迁移 / 运行数据库 | `DB_TYPE`、`DB_URL`、`DB_SSL` | 保存后下次后端重启生效 | +| 更新中心 | K3s / Helm 更新中心配置 | 保存后即时生效 | +| 会话与安全 | `ADMIN_IP_ALLOWLIST` | 保存后即时生效 | + +> [!TIP] +> `AUTH_TOKEN` 和 `PROXY_TOKEN` 并不是“只能靠环境变量改”的配置。 +> 正常情况下,**首次启动先给一个值,后续都可以在 UI 里改**。 + +### 2. 管理后台「通知设置」 + +侧边栏入口:**系统 → 通知设置** + +当前已经有独立页面可直接配置: + +| UI 项 | 说明 | 生效方式 | +|------|------|----------| +| Webhook | 企业微信 / 飞书 / 通用 Webhook | 保存后即时生效 | +| Bark | Bark 推送地址与开关 | 保存后即时生效 | +| Server酱 | SendKey 与开关 | 保存后即时生效 | +| Telegram | API Base URL、Chat ID、Topic ID、Bot Token、是否走系统代理 | 保存后即时生效 | +| SMTP | SMTP 主机、端口、账号、密码、发件/收件地址 | 保存后即时生效 | +| 告警冷静期 | `NOTIFY_COOLDOWN_SEC` | 保存后即时生效 | + +通知设置页面已经支持: + +- 直接保存 +- 直接发测试通知 +- 屏蔽回显已保存的敏感字段 + +通知配置可直接在该页面完成,无需先记环境变量名。 + +### 3. 管理后台「下游密钥」 + +侧边栏入口:**控制台 → 下游密钥** + +「下游密钥」页面负责的是项目级下游 API Key,而不是全局 `PROXY_TOKEN`。 + +适合在这里配置的内容: + +- Key 名称 +- 过期时间 +- 费用 / 请求上限 +- 模型白名单 +- 路由白名单 +- 站点权重倍率 +- 启停、重置用量、趋势与统计 + +这类能力可直接在页面里完成,不需要额外依赖环境变量。 + +--- + +## 首次启动时,至少准备这些环境变量 + +**首次把服务跑起来**时,建议先在环境变量里准备以下几项: | 变量名 | 说明 | 默认值 | |--------|------|--------| -| `AUTH_TOKEN` | 管理后台登录令牌 | `change-me-admin-token` | -| `PROXY_TOKEN` | 代理接口 Bearer Token(下游客户端使用此值作为 API Key) | `change-me-proxy-sk-token` | +| `AUTH_TOKEN` | 初始管理员登录令牌 | `change-me-admin-token` | +| `PROXY_TOKEN` | 初始下游访问令牌 | `change-me-proxy-sk-token` | +| `PORT` | 服务监听端口 | `4000` | +| `DATA_DIR` | 数据目录(SQLite 默认落这里) | `./data` | +| `TZ` | 时区 | `Asia/Shanghai` | -## 基础配置 +说明: + +- `AUTH_TOKEN` 只是**第一次登录前**必须要有;登录后可以去「设置」里改。 +- `PROXY_TOKEN` 也只是建议先给一个初始值;后续可以在「设置」里改。 +- `PORT`、`DATA_DIR`、`TZ` 这类属于部署级参数,更适合留在环境变量。 + +--- + +## 环境变量配置 + +### 1. 启动与部署级 + +这类配置要么属于进程启动参数,要么属于当前确实没有 UI 的部署项: | 变量名 | 说明 | 默认值 | |--------|------|--------| | `PORT` | 服务监听端口 | `4000` | | `DATA_DIR` | 数据目录(SQLite 数据库存储位置) | `./data` | | `TZ` | 时区 | `Asia/Shanghai` | -| `SYSTEM_PROXY_URL` | 系统代理 URL(留空表示不使用) | 空 | | `ACCOUNT_CREDENTIAL_SECRET` | 账号凭证加密密钥(用于加密存储的上游账号密码) | 默认使用 `AUTH_TOKEN` | -## 更新中心与 Deploy Helper +### 2. OAuth 与 Provider 登录 -如果你现在只是一个普通 Docker / Docker Compose 部署,没有 K3s / Kubernetes、没有 Helm release、也没有 Deploy Helper,那么这一节可以先跳过。 +这一节只在你需要覆盖默认 OAuth client 配置时才看。 -这一节只写给已经准备使用“K3s 更新中心”的用户。除了设置页里的运行时字段,还需要补齐主服务和 helper 的环境变量。 +| 变量名 | 说明 | 默认值 | +|--------|------|--------| +| `CODEX_CLIENT_ID` | 覆盖内置 Codex OAuth Client ID | 内置默认值 | +| `CLAUDE_CLIENT_ID` | 覆盖内置 Claude OAuth Client ID | 内置默认值 | +| `CLAUDE_CLIENT_SECRET` | 预留的 Claude OAuth Client Secret(默认留空) | 空 | +| `GEMINI_CLI_CLIENT_ID` | 覆盖内置 Gemini CLI OAuth Client ID | 内置默认值 | +| `GEMINI_CLI_CLIENT_SECRET` | 覆盖内置 Gemini CLI OAuth Client Secret | 内置默认值 | -如果你是老用户,正在从 Docker Compose 迁到 K3s / Helm,这一节可以提前看,先把迁移后的环境变量和组件关系理解清楚。 +说明: -### 主 Metapi 服务 +- `Antigravity` 当前不需要额外环境变量即可启用。 +- 如果你的部署环境访问 provider 受限,优先先在 UI 里配置**系统代理**。 +- 如果 OAuth 页面运行在远程服务器上,还要考虑 SSH 隧道或手动回填 callback,详见 [OAuth 管理](./oauth.md)。 + +### 3. K3s 更新中心与 Deploy Helper + +这里要分清楚两层: + +- **主 Metapi 后台里的日常更新中心配置**:优先在 UI 里填 +- **主服务访问 helper 的 token / helper 自己的监听参数**:仍然是环境变量 + +#### 主 Metapi 服务 | 变量名 | 说明 | 默认值 | |--------|------|--------| | `DEPLOY_HELPER_TOKEN` | 主服务访问 Deploy Helper 的 Bearer Token | 空 | | `UPDATE_CENTER_HELPER_TOKEN` | `DEPLOY_HELPER_TOKEN` 的兼容别名,二选一即可 | 空 | -> [!IMPORTANT] -> 主 Metapi 和 Deploy Helper 必须使用同一个 token,否则更新中心可以显示页面但无法完成 helper 状态查询或部署。 - -### Deploy Helper 服务 +#### Deploy Helper 服务 | 变量名 | 说明 | 默认值 | |--------|------|--------| @@ -58,9 +174,11 @@ | `DEPLOY_HELPER_PORT` | helper 监听端口 | `9850` | | `DEPLOY_HELPER_TOKEN` | helper Bearer Token,必须和主服务一致 | 空 | -### 设置页里的持久化字段 +#### 更新中心里真正建议在 UI 配的字段 -更新中心页面本身还会把下面这些字段持久化到运行数据库: +这些字段不建议再教用户去改 env,而是直接去: + +**设置 → 更新中心** - `helperBaseUrl` - `namespace` @@ -71,161 +189,101 @@ - `dockerHubTagsEnabled` - `defaultDeploySource` -完整接入步骤见: +完整接入步骤见 [K3s 更新中心(高级)](./k3s-update-center.md)。 -- [K3s 更新中心](./k3s-update-center.md) +### 4. 当前没有 UI 的高级部署级参数 -## 数据库配置 +下面这些参数目前更偏部署级,仍然建议通过环境变量维护: | 变量名 | 说明 | 默认值 | |--------|------|--------| -| `DB_TYPE` | 运行数据库类型:`sqlite` / `mysql` / `postgres` | `sqlite` | -| `DB_URL` | 数据库连接串;使用 `mysql` / `postgres` 时必填 | 空 | -| `DB_SSL` | 连接 MySQL / Postgres 时启用 SSL | `false` | +| `TOKEN_ROUTER_CACHE_TTL_MS` | Token 路由缓存 TTL(毫秒) | `1500` | +| `PROXY_LOG_RETENTION_DAYS` | 代理日志保留天数 | `30` | +| `PROXY_LOG_RETENTION_PRUNE_INTERVAL_MINUTES` | 代理日志清理任务执行间隔(分钟) | `30` | +| `MODEL_AVAILABILITY_PROBE_INTERVAL_MS` | 批量测活间隔(毫秒) | `1800000` | +| `MODEL_AVAILABILITY_PROBE_TIMEOUT_MS` | 批量测活单次探测超时(毫秒) | `15000` | +| `MODEL_AVAILABILITY_PROBE_CONCURRENCY` | 批量测活并发数 | `1` | -`DB_TYPE=sqlite` 时,`DB_URL` 留空即可,服务会使用默认 SQLite 路径。 +注意: -## 定时任务 +- **批量测活开关本身**已经在 UI 里有了 +- 这里只剩下间隔、超时、并发这些更高级的细项还没有 UI -| 变量名 | 说明 | 默认值 | 示例 | -|--------|------|--------|------| -| `CHECKIN_CRON` | 自动签到计划 | `0 8 * * *` | 每天 8:00 | -| `BALANCE_REFRESH_CRON` | 余额刷新计划 | `0 * * * *` | 每小时整点 | +--- -Cron 表达式格式:`分 时 日 月 周`(标准五段式) +## 常见配置与入口对照 -常用示例: -- `0 8 * * *` — 每天 08:00 -- `0 */2 * * *` — 每 2 小时 -- `30 7,12,20 * * *` — 每天 07:30、12:30、20:30 +### 通常已经有 UI 的配置 -## 智能路由 +- 管理员令牌 +- 下游访问令牌 +- 系统代理 +- 定时任务 +- 路由策略 +- 批量测活开关 +- 安全白名单 +- 通知渠道 +- 下游密钥 +- 数据库运行配置 +- 更新中心主体配置 -Metapi 的路由引擎按多因子加权选择最优通道。 +### 通常仍需看环境变量的配置 -### 成本信号优先级 +- 端口 +- 数据目录 +- 时区 +- 账号凭证加密密钥 +- OAuth client 覆盖 +- Deploy Helper token +- helper 进程自身监听参数 +- 少数高级部署级性能 / 清理参数 -``` -实测成本(代理日志) → 账号配置成本 → 目录参考价 → 兜底默认值 -``` +--- -### 路由权重参数 +## UI 与环境变量的关系 -| 变量名 | 说明 | 默认值 | 范围 | -|--------|------|--------|------| -| `ROUTING_FALLBACK_UNIT_COST` | 无成本信号时的默认单价 | `1` | > 0 | -| `BASE_WEIGHT_FACTOR` | 基础权重因子 | `0.5` | 0~1 | -| `VALUE_SCORE_FACTOR` | 性价比评分因子 | `0.5` | 0~1 | -| `COST_WEIGHT` | 成本权重(越大越偏向低成本通道) | `0.4` | 0~1 | -| `BALANCE_WEIGHT` | 余额权重(越大越偏向余额充足的通道) | `0.3` | 0~1 | -| `USAGE_WEIGHT` | 使用率权重(越大越偏向使用较少的通道) | `0.3` | 0~1 | +Metapi 当前的配置关系可以概括为: -> 三个权重之和建议为 1.0,但不强制。 +1. **环境变量负责启动默认值和部署参数** +2. **UI 负责用户日常操作和运行时调整** +3. **UI 保存后的值会持久化到当前运行数据库** +4. **大多数 UI 设置会覆盖原始默认值** -### 路由缓存 +例外主要有两类: -| 变量名 | 说明 | 默认值 | 范围 | -|--------|------|--------|------| -| `TOKEN_ROUTER_CACHE_TTL_MS` | Token 路由缓存 TTL(毫秒) | `1500` | >= 100 | +- **纯部署级参数**:例如端口、数据目录 +- **保存后需重启的配置**:例如运行数据库类型 / 连接串 / SSL -### 模型弹活探测 +--- -用于异步校正“上游 `/models` 能看到,但实际调用不可用”的假阳性模型。 +## 通知渠道详细说明 -| 变量名 | 说明 | 默认值 | 范围 | -|--------|------|--------|------| -| `MODEL_AVAILABILITY_PROBE_ENABLED` | 启用后台模型可用性探测 | `false` | `true` / `false` | -| `MODEL_AVAILABILITY_PROBE_INTERVAL_MS` | 后台定时探测间隔(毫秒) | `1800000` | >= 60000 | -| `MODEL_AVAILABILITY_PROBE_TIMEOUT_MS` | 单次探测超时(毫秒) | `15000` | >= 3000 | -| `MODEL_AVAILABILITY_PROBE_CONCURRENCY` | 单账号模型探测并发数,默认串行避免对上游形成批量测活 | `1` | 1 ~ 16 | - -说明: - -- 探测任务在后台异步执行,不阻塞前台请求。 -- 只对看起来像对话/推理模型的条目发最小化探测请求,明显的 embedding、rerank、moderation、tts、image/video 等模型会先跳过。 -- 只有“明确模型不存在 / 不支持 / 无权限”的错误才会写回不可用;超时、5xx、网络抖动会归为“不确定”,不会误杀现有模型。 -- 为了避免对上游形成意外的批量测活,默认关闭;只有显式开启后才会按间隔执行,且不会在服务启动后立刻扫全量模型。 -- 同一批探测任务带去重,上一轮未结束时不会并发堆积;默认并发为 `1`,建议只在确认上游允许主动探测时启用。 - -### 路由预设建议 - -| 场景 | COST_WEIGHT | BALANCE_WEIGHT | USAGE_WEIGHT | 说明 | -|------|:-----------:|:--------------:|:------------:|------| -| **成本优先** | 0.7 | 0.2 | 0.1 | 适合预算敏感场景,总是选最便宜的通道 | -| **均衡(默认)** | 0.4 | 0.3 | 0.3 | 兼顾成本、余额和负载均衡,推荐大多数用户 | -| **稳定优先** | 0.2 | 0.5 | 0.3 | 适合生产环境,优先选余额充足的通道避免中断 | -| **轮转均匀** | 0.1 | 0.1 | 0.8 | 适合测试场景,尽量让每个通道都被使用到 | - -**调参建议:** - -- 如果某个站点总是被选中导致余额很快耗尽 → 调高 `BALANCE_WEIGHT` -- 如果你有几个很便宜的站点想优先用 → 调高 `COST_WEIGHT` -- 如果你想让请求均匀分散到所有站点 → 调高 `USAGE_WEIGHT` -- 如果你需要对特定项目偏好某个站点 → 使用[下游 API Key 的 `siteWeightMultipliers`](#下游-api-key-策略) 而非调全局权重 - -## 代理日志保留 - -| 变量名 | 说明 | 默认值 | 范围 | -|--------|------|--------|------| -| `PROXY_LOG_RETENTION_DAYS` | 代理日志保留天数 | `30` | >= 0 | -| `PROXY_LOG_RETENTION_PRUNE_INTERVAL_MINUTES` | 代理日志清理任务执行间隔(分钟) | `30` | >= 1 | - -## 安全配置 - -| 变量名 | 说明 | 默认值 | -|--------|------|--------| -| `ADMIN_IP_ALLOWLIST` | 管理端 IP 白名单(逗号分隔,支持单个 IP 与 IPv4 CIDR) | 空(不限制) | - -示例:`ADMIN_IP_ALLOWLIST=192.168.1.10,192.168.1.0/24,10.0.0.0/8` - -## 下游 API Key 策略 - -除了全局 `PROXY_TOKEN`,Metapi 支持在管理后台「设置 → 下游 API Key」中创建多个项目级下游 Key。 - -每个 Key 可独立配置以下约束: - -| 字段 | 说明 | 示例 | -|------|------|------| -| `name` | Key 名称(仅供标识) | `team-backend` | -| `expiresAt` | 过期时间 | `2026-12-31T23:59:59Z` | -| `maxCost` | 累计费用上限 | `100`(超限后拒绝请求) | -| `maxRequests` | 累计请求数上限 | `10000` | -| `supportedModels` | 模型白名单(JSON 数组) | `["gpt-4o", "claude-*", "re:deepseek.*"]` | -| `allowedRouteIds` | 可走的路由 ID 白名单 | `[1, 3, 5]` | -| `siteWeightMultipliers` | 站点权重倍率 | `{"1": 2.0, "3": 0.5}` | - -模型白名单支持三种匹配模式: - -- **精确匹配**:`gpt-4o` -- **通配符**:`claude-*`(glob 风格) -- **正则表达式**:`re:deepseek.*`(`re:` 前缀) - -## 通知渠道 +虽然我更推荐直接去「通知设置」页面,但为了方便查字段,这里保留一个速查表。 ### Webhook -| 变量名 | 说明 | 默认值 | +| UI / 变量 | 说明 | 默认值 | |--------|------|--------| | `WEBHOOK_ENABLED` | 启用 Webhook 通知 | `true` | | `WEBHOOK_URL` | Webhook 推送地址 | 空 | ### Bark(iOS 推送) -| 变量名 | 说明 | 默认值 | +| UI / 变量 | 说明 | 默认值 | |--------|------|--------| | `BARK_ENABLED` | 启用 Bark 推送 | `true` | | `BARK_URL` | Bark 推送地址 | 空 | ### Server酱 -| 变量名 | 说明 | 默认值 | +| UI / 变量 | 说明 | 默认值 | |--------|------|--------| | `SERVERCHAN_ENABLED` | 启用 Server酱 通知 | `true` | | `SERVERCHAN_KEY` | Server酱 SendKey | 空 | ### Telegram Bot -| 变量名 | 说明 | 默认值 | +| UI / 变量 | 说明 | 默认值 | |--------|------|--------| | `TELEGRAM_ENABLED` | 启用 Telegram 通知 | `false` | | `TELEGRAM_BOT_TOKEN` | Telegram Bot Token(形如 `123456:abc`) | 空 | @@ -233,18 +291,18 @@ Metapi 的路由引擎按多因子加权选择最优通道。 **配置步骤:** -1. **创建 Bot**:在 Telegram 中搜索 [@BotFather](https://t.me/BotFather),发送 `/newbot`,按提示设置名称后获取 Bot Token(格式如 `123456789:ABCdefGHIjklMNOpqrsTUVwxyz`) +1. **创建 Bot**:在 Telegram 中搜索 [@BotFather](https://t.me/BotFather),发送 `/newbot`,按提示设置名称后获取 Bot Token 2. **获取 Chat ID**: - - **个人聊天**:向你的 Bot 发送任意消息,然后访问 `https://api.telegram.org/bot<你的Token>/getUpdates`,在返回的 JSON 中找到 `chat.id`,或者在 Telegram 搜索 @userinfobot 或是 @getmyid_bot。点击 Start,它会立刻回复一串数字(通常是 9 到 10 位)。 - - **群组**:将 Bot 邀请进群组,在群内发送消息后同样通过 `getUpdates` 接口获取群组 Chat ID(通常为负数,如 `-1001234567890`) - - **频道**:使用频道用户名,如 `@your_channel`(需先将 Bot 添加为频道管理员) -3. **填入配置**:将获取的 Token 和 Chat ID 填入管理后台「通知设置」页面 -4. **大陆服务器反代**:如果服务器无法直连 Telegram,可在「通知设置」里填写 `Telegram API Base URL`,例如 `https://your-proxy.example.com`,Metapi 将请求 `https://your-proxy.example.com/bot/sendMessage` -5. **测试**:保存后点击页面上的「测试通知」按钮验证是否收到消息 + - 个人聊天:给 Bot 发消息后,通过 `getUpdates` 或 @userinfobot / @getmyid_bot 查看 `chat.id` + - 群组:把 Bot 拉进群并发送消息后,通过 `getUpdates` 查看群组 Chat ID + - 频道:可直接使用 `@your_channel`(前提是 Bot 是频道管理员) +3. **填入位置**:优先去 **通知设置** 页面填写 +4. **大陆服务器反代**:如果服务器不能直连 Telegram,可在 UI 里填写 `Telegram API Base URL` +5. **测试**:保存后直接点“发送测试通知” ### SMTP 邮件 -| 变量名 | 说明 | 默认值 | +| UI / 变量 | 说明 | 默认值 | |--------|------|--------| | `SMTP_ENABLED` | 启用邮件通知 | `false` | | `SMTP_HOST` | SMTP 服务器地址 | 空 | @@ -257,23 +315,11 @@ Metapi 的路由引擎按多因子加权选择最优通道。 ### 告警控制 -| 变量名 | 说明 | 默认值 | +| UI / 变量 | 说明 | 默认值 | |--------|------|--------| -| `NOTIFY_COOLDOWN_SEC` | 相同告警冷却时间(秒),防止同一事件重复通知 | `300` | +| `NOTIFY_COOLDOWN_SEC` | 相同告警冷静期(秒),防止同一事件重复通知 | `300` | -## 运行时设置 - -管理后台「设置」中的运行时设置与环境变量分开管理:环境变量负责启动默认值;保存后的运行时设置会持久化到当前运行数据库,并覆盖对应默认值。 - -| 分类 | 对应项 | 生效方式 | -|------|--------|----------| -| 代理访问与网络 | `PROXY_TOKEN`、`SYSTEM_PROXY_URL`、`ADMIN_IP_ALLOWLIST` | 保存后即时生效 | -| 定时任务 | `CHECKIN_CRON`、`BALANCE_REFRESH_CRON` | 保存后即时生效 | -| 智能路由 | `ROUTING_FALLBACK_UNIT_COST`、各路由权重 | 保存后即时生效 | -| 通知渠道 | Webhook / Bark / Telegram / Server酱 / SMTP / `NOTIFY_COOLDOWN_SEC` | 保存后即时生效 | -| 数据库运行配置 | `DB_TYPE`、`DB_URL`、`DB_SSL` | 保存后在下次 Metapi 后端启动时生效 | - -> `TOKEN_ROUTER_CACHE_TTL_MS`、`PROXY_LOG_RETENTION_DAYS`、`PROXY_LOG_RETENTION_PRUNE_INTERVAL_MINUTES` 当前仍属于部署级环境变量,不在后台运行时设置里单独维护。 +--- ## 站点公告 @@ -296,6 +342,8 @@ Metapi 的路由引擎按多因子加权选择最优通道。 ## 下一步 - [部署指南](./deployment.md) — Docker Compose 与反向代理 +- [K3s 更新中心(高级)](./k3s-update-center.md) — K3s / Helm 用户的后台升级入口 - [客户端接入](./client-integration.md) — 对接下游应用 - [上游接入](./upstream-integration.md) — 添加和管理上游平台 +- [OAuth 管理](./oauth.md) — 授权 Codex / Claude / Gemini CLI / Antigravity - [运维手册](./operations.md) — 备份、日志与健康检查 diff --git a/docs/faq.md b/docs/faq.md index a738e1c..19352fd 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -6,35 +6,51 @@ -## 账号认证方式与兼容性(Access Token / Cookie) +## 账号认证方式与兼容性(Session / API Key / OAuth) -### Q: Access Token 和 Cookie 有什么区别?优先用哪个? +### Q: Access Token、Cookie、API Key、OAuth 应该选哪个? -**A:** Metapi 支持两种 Session 凭证来源(都用于管理接口,如余额、签到等): +**A:** 现在最稳妥的判断方式不是只看“有没有 Token”,而是先看你接的是哪一类上游: -| 凭证 | 特点 | 适用场景 | +| 方式 | 特点 | 适用场景 | |------|------|----------| -| **Access Token(系统访问令牌)** | 支持多账号、通常更稳定、更适合长期使用 | 标准 NewAPI / OneAPI / OneHub / DoneHub / Veloera 等站点 | -| **Cookie(浏览器登录态)** | 兼容性强,但可能过期,且多账号体验较差 | 访问令牌不可用、魔改站点、特殊兼容场景 | +| **Access Token(系统访问令牌)** | 稳定、适合长期使用、适合多账号 | 标准 New API / One API / OneHub / DoneHub / Veloera 等面板站 | +| **Cookie(浏览器登录态)** | 兼容性强,但更容易过期 | Access Token 不可用、AnyRouter 一类魔改站点、特殊兜底场景 | +| **API Key** | 最简单,适合代理调用 | OpenAI / Claude / Gemini 兼容入口、CPA、各类官方预设 | +| **OAuth** | 不手填普通凭证,走浏览器授权 | Codex、Claude、Gemini CLI、Antigravity | -> 结论:优先使用 **Access Token**。仅在站点不支持或令牌不可用时使用 Cookie。 +结论: + +1. 面板型站点优先 **Access Token** +2. Access Token 拿不到时再考虑 **Cookie** +3. 兼容接口、CPA、官方预设优先 **API Key** +4. Provider 原生授权优先 **OAuth** ### Q: 在 Metapi 里怎么切换认证方式? -**A:** 在「账号管理 → 添加账号 → Cookie / Token 导入」中: +**A:** 入口已经分成两条: -1. 选择站点 -2. 在「凭证模式」下拉选择: - - 自动识别(推荐) - - Session 模式(Access Token / Cookie) - - API Key 模式(仅代理) -3. 粘贴凭证并点击「验证 Token」 +1. **普通站点**:在「账号管理 / API Key 管理」里选择 Session 或 API Key +2. **OAuth provider**:在左侧「OAuth 管理」里完成授权 + +如果你不确定该去哪一页,先看 [上游接入](/upstream-integration)。 ### Q: 以 NewAPI 为例,Access Token 在哪里生成? **A:** 通常路径是:**控制台 → 个人设置 → 安全设置 → 系统访问令牌**。 如果你确实需要 Cookie 兜底,可在浏览器 `F12 → Application → Cookie` 获取对应登录态。 +### Q: 什么情况下应该直接走 OAuth? + +**A:** 当你接的不是一个普通面板站,而是 provider 自己的账号授权时: + +- Codex +- Claude +- Gemini CLI +- Antigravity + +这时不要再把它当成“账号管理里的一条普通 Session”去处理,直接看 [OAuth 管理](/oauth)。 + ### Q: AnyRouter 这类魔改站点为什么更容易报错? **A:** AnyRouter 在 Metapi 中按 NewAPI 兼容站点处理,但不少实例会隐藏 Access Token 入口,或额外加登录盾。建议: @@ -43,6 +59,10 @@ 2. 如果没有 Access Token 入口,或验证时被盾/认证页拦截,再改用 Cookie 导入 3. 若返回 HTML 盾页错误,先在浏览器完成验证后再重新绑定 +### Q: CPA / CLIProxyAPI 应该怎么接? + +**A:** 这类站点现在走 `cliproxyapi` 平台类型,推荐直接加 API Key,不建议把它当成可签到、可登录的面板站。详细步骤见 [上游接入](/upstream-integration)。 + ### Q: Sub2API 站点怎么处理? **A:** Sub2API 常见 JWT 短期会话机制,和传统 NewAPI 站点差异较大。当前建议: @@ -52,7 +72,7 @@ 3. Sub2API 通常为订阅制使用,不支持签到;如果你只关心代理调用,也可以直接改用 API Key 模式 4. 若 `GET /v1/models` 为空,先确认该账号下已有可用用户 API Key,Metapi 会再尝试用它发现模型 -详细操作截图见 [上游接入 → Sub2API](./upstream-integration.md#sub2api)。 +详细操作说明见 [上游接入](/upstream-integration)。 ## 部署相关 diff --git a/docs/getting-started.md b/docs/getting-started.md index 3c1d6a9..441be5b 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -137,15 +137,27 @@ npm run dev 进入 **站点管理**,添加你使用的上游中转站: - 填写站点名称(自己想怎么取就怎么取)和 URL -- 选择平台类型(`new-api` / `one-api` / `one-hub` / `done-hub` / `veloera` / `anyrouter` / `sub2api` / `openai` / `claude` / `gemini` / `cliproxyapi`),通常可自动检测,检测有误或者因为防护页导致检测失败可以手动选择。 +- 按你手上的上游形态选择: + - 有后台面板:`new-api` / `one-api` / `one-hub` / `done-hub` / `veloera` / `anyrouter` / `sub2api` + - 通用兼容接口:`openai` / `claude` / `gemini` / `cliproxyapi` + - 官方入口:直接在下拉里选对应**官方预设**,例如阿里云 / 智谱 / 豆包 Coding Plan,DeepSeek,Moonshot,MiniMax,ModelScope +- 平台通常可自动检测;如果因为防护页、反向代理或特殊路径导致检测失败,再手动选择。 - 可选是否开启系统代理,方便国内机器访问国外中转站。 - 可选站点权重,站点权重越大,路由将更加频繁使用这个站点的模型。 +- 如果这个站点的控制台 URL 和真实 AI 请求地址不同,不要直接把主站点 URL 改掉,而是在表单下方补「AI 请求地址池」。 -如果你不确定该选哪个平台,先看 [上游接入](./upstream-integration.md)。 +> [!IMPORTANT] +> 通用平台常见写法是填控制台地址或 provider base URL;但如果你选的是**官方预设**,请保留预设自动带出的完整路径,哪怕它本来就包含 `/v1`、`/anthropic` 或 `/api/coding/...`。 + +如果你不确定该选哪个平台或预设,先看 [上游接入](/upstream-integration)。 ![站点管理](./screenshots/site-management.png) -### 步骤 2:添加账号(可签到、查询余额等) +### 步骤 2:添加连接(账号 / API Key / OAuth) + +这一步不要再死记“所有站点都先加账号”。现在推荐按场景分流: + +#### 2A. 面板型站点:添加账号 / Session 进入 **连接管理中的账号管理**,为每个站点添加已注册的账号: @@ -161,15 +173,42 @@ npm run dev - 启用自动签到(如站点支持) -### 步骤 3:添加 API Key(Base URL+Key模式,只可获取模型和使用模型) +适合这一分支的平台: -首先你需要在步骤1中,确保添加了(`new-api` / `one-api` / `one-hub` / `done-hub` / `veloera` / `anyrouter` / `sub2api` / `openai` / `claude` / `gemini` / `cliproxyapi`)的类型的Base URL。 +- `new-api` +- `one-api` +- `one-hub` +- `done-hub` +- `veloera` +- `anyrouter` +- `sub2api` -- 进入 **连接管理中的API Key管理**,为每个站点添加你的API Key: +#### 2B. 兼容接口 / 官方预设 / CPA:添加 API Key + +进入 **连接管理中的 API Key 管理**,为站点添加你的 API Key: ![API Key 管理](./screenshots/api-key-management.png) -### 步骤 4:同步账号令牌 +适合这一分支的平台: + +- `openai` +- `claude` +- `gemini` +- `cliproxyapi` +- 所有官方预设(Coding Plan、DeepSeek、Moonshot、MiniMax、ModelScope 等) + +#### 2C. Provider 原生授权:走 OAuth 管理 + +如果你要接的是: + +- Codex +- Claude provider 账号 +- Gemini CLI +- Antigravity + +那就不要在这里手填普通账号,而是直接去左侧菜单 **OAuth 管理** 完成授权,详见 [OAuth 管理](/oauth)。 + +### 步骤 3:同步账号令牌(可选,仅面板型站点) 进入 **连接管理中的账号令牌管理**: @@ -179,14 +218,16 @@ npm run dev ![Token管理](./screenshots/token-management.png) -### 步骤 5:路由管理 +如果你走的是 API Key-only 或 OAuth 流程,这一步通常不是必需的。 + +### 步骤 4:路由管理 进入 **路由管理**: - 系统会自动发现模型并生成路由规则 - 点击右上角的刷新选中概率可以显示并将概率载入缓存中 - 可以手动调整通道的优先级和权重 -- 关于路由权重参数调优,参考 [配置说明 → 智能路由](./configuration.md#智能路由) +- 关于路由权重参数调优,参考 [配置说明 → 智能路由](/configuration#智能路由) - 左侧可以进行品牌、站点、接口等的筛选,如下图所示: ![路由筛选](./screenshots/routes-filter.png) diff --git a/docs/index.md b/docs/index.md index da88117..c261b07 100644 --- a/docs/index.md +++ b/docs/index.md @@ -24,8 +24,11 @@ features: details: 从部署到第一条请求,按步骤完成最小可用环境搭建。 link: /getting-started - title: 上游接入 - details: 按当前代码支持的平台类型,快速判断该选什么平台、先走哪个连接分段。 + details: 按平台类型、官方预设和 AI 请求地址池的现状,快速判断站点该怎么接。 link: /upstream-integration + - title: OAuth 管理 + details: 直接接入 Codex、Claude、Gemini CLI、Antigravity 等 provider 授权账号。 + link: /oauth - title: 问题排查 details: 汇总高频报错、根因定位和标准修复路径,降低重复沟通成本。 link: /faq diff --git a/docs/k3s-update-center.md b/docs/k3s-update-center.md index 6287334..35177d4 100644 --- a/docs/k3s-update-center.md +++ b/docs/k3s-update-center.md @@ -4,7 +4,19 @@ --- -这页写给已经把 Metapi 部署到 **K3s / Kubernetes + Helm** 的用户。 +本页适用于已经把 Metapi 部署到 **K3s / Kubernetes + Helm** 的用户。 + +K3s 更新中心的日常入口位于: + +```text +设置 → 更新中心 +``` + +本文主要说明三件事: + +- 哪些配置直接在后台页面里填写 +- 哪些配置仍然需要主服务环境变量或 helper manifest +- 哪些前提不满足时,页面虽然能打开,但无法真正部署 如果你现在的环境只是一个最普通的 **Docker Compose 安装**,只有一个 Metapi 容器,其他什么都没有,那么先记住一句话: @@ -15,12 +27,32 @@ > > 但如果你是老用户,正打算 **从 Docker Compose 迁到 K3s / Helm,以获得滚动更新能力**,那这页仍然值得看,因为它描述的就是迁移完成后的目标形态。 -## 先判断:你需不需要看这页 +## 配置到底在哪里配 -| 你的现状 | 要不要看这页 | 你现在该怎么做 | +更新中心涉及后台页面、主服务环境变量、helper 部署清单三层配置,最容易混淆,建议先看下面这张对照表。 + +| 你要配什么 | 去哪里配 | 说明 | +|------|------|------| +| 是否启用更新中心 | UI:设置 → 更新中心 | 日常使用优先在 UI 操作 | +| Deploy Helper URL | UI:设置 → 更新中心 | 例如集群内 Service 地址 | +| Namespace / Release Name / Chart Ref / Image Repository | UI:设置 → 更新中心 | 都是页面里直接填的部署配置 | +| GitHub Releases / Docker Hub / 默认部署来源 | UI:设置 → 更新中心 | 属于页面里的版本来源策略 | +| 主 Metapi 到 helper 的认证 token | 主 Metapi 环境变量 | `DEPLOY_HELPER_TOKEN` 或 `UPDATE_CENTER_HELPER_TOKEN` | +| helper 自己监听在哪个地址和端口 | helper 环境变量 / manifest | `DEPLOY_HELPER_HOST` / `DEPLOY_HELPER_PORT` | +| helper 自己的 Bearer Token | helper 环境变量 / manifest | `DEPLOY_HELPER_TOKEN`,且必须与主服务一致 | +| chart 是否真的支持 digest 部署 | chart 文件本身 | 这不是 UI,也不是普通 env,要看 chart 模板 | + +其中可以这样理解: + +- 日常使用时,更新中心的大部分配置直接在 **设置 → 更新中心** 页面填写 +- 环境变量主要负责主服务与 helper 之间的认证,以及 helper 自身的监听参数 + +## 先判断:是否适用 + +| 你的现状 | 是否适用 | 你现在该怎么做 | |------|------------|--------------| | 只有一个 `docker compose up -d` 跑起来的 Metapi 容器 | 不需要 | 继续用普通 Docker 升级方式 | -| 目前是 Docker Compose,准备迁到 K3s / Helm 来获得滚动更新 | 需要 | 把这页当成迁移后的目标架构说明,先完成迁移,再启用更新中心 | +| 目前是 Docker Compose,准备迁到 K3s / Helm 来获得滚动更新 | 需要 | 把本页当成迁移后的目标架构说明,先完成迁移,再启用更新中心 | | 有 K3s / Kubernetes 集群,但 Metapi 不是用 Helm release 部署的 | 暂时不建议 | 这套更新中心无法直接接管现有部署 | | Metapi 已经是 Helm release,想在后台里看版本并手动点一次升级 | 需要 | 继续看下文 | @@ -45,7 +77,7 @@ docker compose up -d - 额外的 Bearer Token - 集群内 Service 地址 -也就是说,除非你本来就在用 K3s / Helm,否则这页可以直接跳过。 +除非你本来就在用 K3s / Helm,否则本页可以直接跳过。 ## 如果你正准备从 Docker Compose 迁到 K3s @@ -57,7 +89,7 @@ docker compose up -d - 用 Helm 管理版本和回滚 - 后续在后台里看版本来源,并人工触发一次升级 -对这类用户来说,这页不是“现在立刻就能用”的操作手册,而是: +对这类用户来说,本页不是“现在立刻就能用”的操作手册,而是: - “迁移完成后,你会得到什么能力” - “为了用上这个能力,集群侧要提前满足什么前提” @@ -160,7 +192,7 @@ Deploy Helper 是一个跑在集群里的小服务。它不负责对外提供 Me 那答案是: -- 这是一个合理场景,这页正是给你看迁移后该怎么接入的。 +- 这是一个合理场景,本页正是说明迁移后该如何接入更新中心。 ## K3s / Helm 用户的接入步骤 @@ -253,8 +285,12 @@ helper 端使用: 它们的值必须完全一致。 +这一步仍然是**环境变量级配置**,因为它本质上是主服务与 helper 之间的认证,而不是普通用户日常在 UI 里调的业务参数。 + ### 3. 在后台“设置 → 更新中心”里填配置 +从这一步开始,**优先按 UI 来操作**,不要再回头把下面这些字段硬塞进环境变量。 + 需要填写的核心字段有: | 字段 | 怎么理解 | 典型示例 | @@ -272,6 +308,12 @@ helper 端使用: - `GitHub Releases` - `Docker Hub` +对已经跑起来的 K3s / Helm 用户来说,更新中心的日常配置主要就在这一页: + +```text +设置 → 更新中心 +``` + ### 4. 实际操作顺序 推荐这样用: @@ -329,9 +371,9 @@ About 页里的“更新提醒”更像一个轻量入口: - K3s / Kubernetes - Helm release - Deploy Helper +- 主服务的 `DEPLOY_HELPER_TOKEN`(或兼容别名 `UPDATE_CENTER_HELPER_TOKEN`)与 helper 侧 `DEPLOY_HELPER_TOKEN` 保持一致 另外,如果你想用“按 digest 精确部署/回退”这条链路,还要确认你的 chart 没有忽略 `image.digest` 这个值;否则页面虽然能显示 digest,真正部署时还是只会落到 tag 语义。 -- 对齐的 token 缺其中任何一项,都只能看,不能真正部署。 diff --git a/docs/management-api.md b/docs/management-api.md index 55c67e1..198ef82 100644 --- a/docs/management-api.md +++ b/docs/management-api.md @@ -77,9 +77,12 @@ curl -sS "${METAPI_ADMIN_BASE_URL}/api/sites" \ 脚本化添加一个新站点并绑定账号,通常按下面顺序: 1. `POST /api/sites/detect` 自动识别平台 -2. `POST /api/sites` 创建站点 -3. `POST /api/accounts/verify-token` 验证凭证 -4. `POST /api/accounts` 保存账号 +2. 如命中官方预设,记下返回的 `initializationPresetId` +3. `POST /api/sites` 创建站点 +4. `POST /api/accounts/verify-token` 验证凭证 +5. `POST /api/accounts` 保存账号 + +如果你要自动化的是 Codex / Claude / Gemini CLI / Antigravity 这类 provider 授权,则改看本文后面的 **OAuth 接口**,不要强行走普通账号导入。 最小流程示例: @@ -159,13 +162,13 @@ curl -sS "${METAPI_ADMIN_BASE_URL}/api/sites" \ `POST /api/sites/detect` -用于在真正创建站点前,先根据 URL 探测平台类型。 +用于在真正创建站点前,先根据 URL 探测平台类型;如果命中官方预设,还会顺带返回 `initializationPresetId`。 请求体: | 字段 | 类型 | 必填 | 说明 | |------|------|------|------| -| `url` | `string` | 是 | 站点根地址,**不要**带 `/v1` | +| `url` | `string` | 是 | 待识别的站点地址。通用平台通常传根地址;如果你想命中官方预设,则直接传预设对应的完整地址 | 示例: @@ -187,6 +190,16 @@ curl -sS "${METAPI_ADMIN_BASE_URL}/api/sites/detect" \ } ``` +命中预设时,响应可能类似: + +```json +{ + "url": "https://coding.dashscope.aliyuncs.com/v1", + "platform": "openai", + "initializationPresetId": "codingplan-openai" +} +``` + 失败响应: ```json @@ -204,8 +217,9 @@ curl -sS "${METAPI_ADMIN_BASE_URL}/api/sites/detect" \ | 字段 | 类型 | 必填 | 说明 | |------|------|------|------| | `name` | `string` | 是 | 站点名称 | -| `url` | `string` | 是 | 站点根地址,**不要**带 `/v1` | +| `url` | `string` | 是 | 站点地址。通用平台通常用根地址;官方预设可直接保留完整官方路径 | | `platform` | `string` | 否 | 平台类型;留空时服务端会再次尝试自动识别 | +| `initializationPresetId` | `string` | 否 | 官方预设 ID;用于保留预设语义、初始化建议和后续跳转 | | `proxyUrl` | `string \| null` | 否 | 站点专用代理地址,支持 `http(s)` / `socks` | | `useSystemProxy` | `boolean` | 否 | 是否使用全局 `SYSTEM_PROXY_URL` | | `customHeaders` | `string \| null` | 否 | 自定义请求头,注意这里传的是 **JSON 字符串** | @@ -214,6 +228,7 @@ curl -sS "${METAPI_ADMIN_BASE_URL}/api/sites/detect" \ | `isPinned` | `boolean` | 否 | 是否置顶 | | `sortOrder` | `number` | 否 | 排序值,非负整数 | | `globalWeight` | `number` | 否 | 站点全局权重,必须为正数 | +| `apiEndpoints` | `array` | 否 | 仅用于 AI 请求的数据面地址池;不替代主站点 URL | 示例: @@ -258,6 +273,24 @@ curl -sS "${METAPI_ADMIN_BASE_URL}/api/sites" \ > [!TIP] > `customHeaders` 不是对象,而是 JSON 字符串;并且 value 必须是字符串。 +### 4. 使用官方预设创建站点 + +如果你前一步 `detect` 已经拿到了 `initializationPresetId`,推荐在创建时显式带回去: + +```bash +curl -sS "${METAPI_ADMIN_BASE_URL}/api/sites" \ + -H "Authorization: Bearer ${METAPI_AUTH_TOKEN}" \ + -H "Content-Type: application/json" \ + -d '{ + "name": "Aliyun CodingPlan", + "url": "https://coding.dashscope.aliyuncs.com/v1", + "platform": "openai", + "initializationPresetId": "codingplan-openai" + }' +``` + +这样响应里也会保留该预设信息,便于脚本按预设类型做后续分流。 + ## 账号接口 ### 1. 获取账号列表 @@ -481,6 +514,127 @@ curl -sS "${METAPI_ADMIN_BASE_URL}/api/accounts/1/rebind-session" \ } ``` +## OAuth 接口 + +如果你要自动化的是 Codex / Claude / Gemini CLI / Antigravity 这类 provider 授权,请使用下面这组接口。 + +### 1. 获取可用 provider + +`GET /api/oauth/providers` + +示例: + +```bash +curl -sS "${METAPI_ADMIN_BASE_URL}/api/oauth/providers" \ + -H "Authorization: Bearer ${METAPI_AUTH_TOKEN}" +``` + +示例响应: + +```json +{ + "providers": [ + { + "provider": "codex", + "label": "Codex", + "platform": "codex", + "enabled": true, + "loginType": "oauth", + "requiresProjectId": false, + "supportsDirectAccountRouting": true, + "supportsCloudValidation": true, + "supportsNativeProxy": true + } + ] +} +``` + +### 2. 启动 OAuth 授权 + +`POST /api/oauth/providers/:provider/start` + +请求体字段: + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| `projectId` | `string` | 否 | 某些 provider 可选传入的项目 ID,例如 Gemini CLI | +| `proxyUrl` | `string \| null` | 否 | 本次 OAuth 流程使用的显式代理;传 `null` 可清空继承代理 | + +示例: + +```bash +curl -sS "${METAPI_ADMIN_BASE_URL}/api/oauth/providers/codex/start" \ + -H "Authorization: Bearer ${METAPI_AUTH_TOKEN}" \ + -H "Content-Type: application/json" \ + -d '{}' +``` + +成功响应: + +```json +{ + "provider": "codex", + "state": "oauth-state-123", + "authorizationUrl": "https://auth.example.com/authorize?...", + "instructions": { + "redirectUri": "http://localhost:1455/auth/callback", + "callbackPort": 1455, + "callbackPath": "/auth/callback", + "manualCallbackDelayMs": 15000 + } +} +``` + +### 3. 查询 OAuth 会话状态 + +`GET /api/oauth/sessions/:state` + +示例: + +```bash +curl -sS "${METAPI_ADMIN_BASE_URL}/api/oauth/sessions/oauth-state-123" \ + -H "Authorization: Bearer ${METAPI_AUTH_TOKEN}" +``` + +典型状态包括: + +- `pending` +- `success` +- `error` + +### 4. 手动回填 callback URL + +`POST /api/oauth/sessions/:state/manual-callback` + +当浏览器已经完成授权,但回调没有自动打到 Metapi 时,可以手动提交最终 callback URL。 + +```bash +curl -sS "${METAPI_ADMIN_BASE_URL}/api/oauth/sessions/oauth-state-123/manual-callback" \ + -H "Authorization: Bearer ${METAPI_AUTH_TOKEN}" \ + -H "Content-Type: application/json" \ + -d '{ + "callbackUrl": "http://localhost:1455/auth/callback?code=demo&state=oauth-state-123" + }' +``` + +### 5. 列出已有 OAuth 连接 + +`GET /api/oauth/connections` + +示例: + +```bash +curl -sS "${METAPI_ADMIN_BASE_URL}/api/oauth/connections?limit=50&offset=0" \ + -H "Authorization: Bearer ${METAPI_AUTH_TOKEN}" +``` + +### 6. 重绑或删除 OAuth 连接 + +| 接口 | 作用 | +|------|------| +| `POST /api/oauth/connections/:accountId/rebind` | 为已有 OAuth 账号重新发起授权 | +| `DELETE /api/oauth/connections/:accountId` | 删除 OAuth 连接 | + ## 常见失败返回 ### 站点创建冲突 @@ -545,5 +699,6 @@ curl -sS "${METAPI_ADMIN_BASE_URL}/api/accounts/1/rebind-session" \ ## 下一步 - [上游接入](./upstream-integration.md) — 查看不同站点类型应该怎么填 URL、凭证和 User ID +- [OAuth 管理](/oauth) — 查看浏览器授权、回调和重绑逻辑 - [配置说明](./configuration.md) — 查看 `AUTH_TOKEN`、`ADMIN_IP_ALLOWLIST`、系统代理等配置项 - [客户端接入](./client-integration.md) — 如果你要接的是 `/v1/*` 代理接口而不是后台管理接口,请看这里 diff --git a/docs/oauth.md b/docs/oauth.md new file mode 100644 index 0000000..345ff19 --- /dev/null +++ b/docs/oauth.md @@ -0,0 +1,224 @@ +# 🔐 OAuth 管理 + +本文档介绍 Metapi 里的「OAuth 管理」页面,适合需要直接授权 provider 账号的场景。 + +[返回文档中心](/) + +--- + +## 这页解决什么问题 + +不是所有上游都适合手填 API Key、Access Token 或 Cookie。 + +对下面这类 provider 账号,更推荐直接走 OAuth: + +- Codex +- Claude +- Gemini CLI +- Antigravity + +这类接法的特点是: + +- 使用浏览器授权,而不是手填用户名密码 +- 授权成功后,Metapi 会自动创建或复用对应 provider 的站点 +- 账号会按 OAuth 连接保存,后续刷新和重绑也走同一套流程 + +如果你接的是 New API、One API、Sub2API、CPA、OpenAI-compatible、Claude-compatible 这类**普通站点或网关**,请看 [上游接入](/upstream-integration)。 + +--- + +## 入口在哪里 + +管理后台左侧菜单已经有独立入口: + +```text +OAuth 管理 +``` + +这不是站点编辑器里的一个隐藏选项,而是和「站点管理」「账号管理」并列的一页。 + +--- + +## 当前支持的 provider + +| Provider | 对应平台 | 自动创建的站点名 | 典型用途 | +|------|------|------|------| +| Codex | `codex` | `ChatGPT Codex OAuth` | 直接用 Codex 账号授权 | +| Claude | `claude` | `Anthropic Claude OAuth` | 直接用 Claude / Anthropic 账号授权 | +| Gemini CLI | `gemini-cli` | `Google Gemini CLI OAuth` | 复用 Gemini CLI / Google Cloud 账号授权,可选输入 Project ID | +| Antigravity | `antigravity` | `Google Antigravity OAuth` | 复用 Antigravity 账号授权 | + +授权完成后,这些站点会出现在「站点管理」里,但通常**不建议你手动创建**它们。 + +--- + +## 授权前的准备 + +### 1. 确保 Metapi 能访问 provider 的 OAuth 端点 + +如果你的部署环境访问外网受限,可以: + +- 先配置全局 `SYSTEM_PROXY_URL` +- 或在 OAuth 启动 / 重绑时使用单次代理参数 + +相关环境变量见 [配置说明](/configuration) 里的「OAuth 与 Provider 登录」一节。 + +### 2. 远程部署要提前考虑回调方式 + +OAuth 默认使用 Metapi 本机上的 loopback 回调地址,例如本机 `127.0.0.1` 端口。 + +如果你的 Metapi 跑在远程服务器上,而浏览器跑在本地电脑上,常见做法有两个: + +1. **SSH 隧道**:按页面给出的命令,把回调端口转发到远端 +2. **手动回填 callback URL**:如果浏览器已经完成授权,但自动回调没打通,可把最终回调地址手动贴回管理页 + +### 3. 了解它和普通站点接入的边界 + +OAuth 连接更适合“provider 原生账号授权”,而不是: + +- 面板站点账号密码登录 +- New API / One API 后台管理 +- CPA / OpenAI-compatible 的普通 API Key 托管 + +--- + +## 标准流程 + +### 步骤 1:打开 OAuth 管理 + +进入左侧菜单「OAuth 管理」,等待页面加载 provider 列表和已有连接。 + +### 步骤 2:点击要连接的 provider + +页面会为 provider 发起一个 OAuth 会话,并弹出授权窗口。 + +Metapi 会同时给出: + +- 授权链接 +- 本机回调端口 +- 手动回填等待时间 +- 如果当前是远程访问,还会给出 SSH 隧道命令模板 + +### 步骤 3:在 provider 页面完成授权 + +完成授权后,Metapi 会轮询当前会话状态: + +- `pending`:等待回调 +- `success`:授权成功 +- `error`:授权失败,需要重新检查浏览器回调或网络 + +### 步骤 4:必要时手动回填 callback URL + +如果弹窗里已经能看到类似 `...?code=...&state=...` 的回调地址,但 Metapi 页面还没成功: + +1. 复制浏览器最终回调 URL +2. 回到「OAuth 管理」 +3. 粘贴到手动回填区域提交 + +### 步骤 5:确认站点与连接都已出现 + +成功后通常会看到两层结果: + +- 「OAuth 管理」页里出现新的连接记录 +- 「站点管理」页里出现对应 provider 的站点行 + +--- + +## 和普通站点 / API Key 的区别 + +| 方式 | 入口 | 适合什么 | 典型例子 | +|------|------|------|------| +| 普通站点 + Session | 站点管理 / 账号管理 | 有后台面板,需要签到、余额、账号令牌管理 | New API、One API、DoneHub、AnyRouter、Sub2API | +| 普通站点 + API Key | 站点管理 / API Key 管理 | 只关心代理调用和模型列表 | OpenAI-compatible、Claude-compatible、CPA | +| OAuth 连接 | OAuth 管理 | 需要 provider 官方授权、刷新、重绑 | Codex、Claude、Gemini CLI、Antigravity | + +简单判断: + +- 你拿到的是 **站点后台地址**,优先看 [上游接入](/upstream-integration) +- 你拿到的是 **provider 登录授权**,优先看这页 + +--- + +## 自动生成的站点有什么用 + +OAuth 成功后,Metapi 会确保对应 provider 的站点存在。这样做是为了让 OAuth 连接也能融入现有的: + +- 站点列表 +- 路由通道 +- 账号归属 +- 代理与重绑逻辑 + +但这类站点和普通面板站点仍然不同: + +- 它们通常不是拿来手动登录的 +- 不要把它理解成“我又多了一个可签到的面板站” +- 更准确地说,它是 OAuth 账号在 Metapi 里的宿主站点 + +--- + +## 管理 API 里怎么自动化 + +如果你想脚本化处理 OAuth,可以用这些接口: + +| 接口 | 作用 | +|------|------| +| `GET /api/oauth/providers` | 获取当前可用 provider 列表 | +| `POST /api/oauth/providers/:provider/start` | 启动 OAuth 流程 | +| `GET /api/oauth/sessions/:state` | 轮询会话状态 | +| `POST /api/oauth/sessions/:state/manual-callback` | 手动回填 callback URL | +| `GET /api/oauth/connections` | 列出现有连接 | +| `POST /api/oauth/connections/:accountId/rebind` | 重绑已有 OAuth 连接 | +| `DELETE /api/oauth/connections/:accountId` | 删除 OAuth 连接 | + +脚本示例见 [管理 API](/management-api)。 + +--- + +## 常见问题 + +### provider 显示“当前不可用” + +通常说明回调监听器不可用,或当前 provider 的启动条件不满足。优先检查: + +1. 服务是否刚启动但回调监听失败 +2. 端口是否被占用 +3. 当前环境是否缺少必要的 OAuth 配置 + +### 浏览器授权成功了,但页面一直停在“等待授权完成” + +优先怀疑回调链路没通: + +1. 如果是远程服务器,先按页面提示建 SSH 隧道 +2. 如果不方便建隧道,直接用手动 callback 回填 +3. 如果 provider 页面最终没有 `code` / `state` 参数,说明授权本身还没成功 + +### OAuth 连接需要系统代理吗 + +有可能需要,尤其是: + +- 国内服务器访问 OpenAI / Anthropic / Google OAuth 端点 +- 服务器本身不能直连 provider + +优先使用: + +1. 全局 `SYSTEM_PROXY_URL` +2. OAuth 启动 / 重绑时指定单次代理 + +### OAuth 成功后为什么还会在站点管理看到一行站点 + +这是预期行为。Metapi 需要一个明确的站点记录来承载: + +- 账号所属平台 +- 路由与通道归属 +- 后续重绑 / 刷新逻辑 + +它不代表你又新增了一个普通面板站点。 + +--- + +## 相关文档 + +- [上游接入](/upstream-integration) +- [管理 API](/management-api) +- [配置说明](/configuration) +- [常见问题 FAQ](/faq) diff --git a/docs/upstream-integration.md b/docs/upstream-integration.md index 6afdc9a..2cce3a4 100644 --- a/docs/upstream-integration.md +++ b/docs/upstream-integration.md @@ -1,6 +1,6 @@ # 🔌 上游接入指南 -本文档详细说明如何将不同类型的 AI 中转站接入 Metapi。 +本文档详细说明如何将不同类型的 AI 中转站、官方兼容入口和 OAuth 连接接入 Metapi。 [返回文档中心](./README.md) @@ -8,12 +8,19 @@ ## 概述 -Metapi 支持两大类上游站点: +Metapi 当前支持三类上游接入方式: -1. **中转聚合平台** — New API / One API / OneHub / DoneHub / Veloera / AnyRouter / Sub2API 等 +1. **中转聚合平台** — New API / One API / OneHub / DoneHub / Veloera / AnyRouter / Sub2API / CPA 等 2. **官方 API 端点** — OpenAI / Claude (Anthropic) / Gemini (Google) 直连 +3. **官方预设与 OAuth 连接** — Coding Plan / DeepSeek / Moonshot / MiniMax / ModelScope 等官方兼容入口,以及 Codex / Claude / Gemini CLI / Antigravity 的浏览器授权登录 -每种站点类型的接入方式略有不同,本文档按站点类型分别说明。 +其中: + +- **平台类型** 决定协议适配和管理能力 +- **官方预设** 还是落在 `openai` / `claude` 这类平台上,但会自动带出官方地址和推荐模型 +- **OAuth 连接** 不在「站点管理」里手填账号密码,而是在「OAuth 管理」里单独授权 + +每种接入方式略有不同,本文档按类型分别说明。 --- @@ -24,10 +31,19 @@ Metapi 支持两大类上游站点: 1. **登录管理后台** — 访问 `http://your-metapi-host:4000`,使用 `AUTH_TOKEN` 登录 2. **进入站点管理** — 点击左侧菜单「站点管理」 3. **添加站点** — 点击「添加站点」按钮 -4. **填写站点信息** — 根据站点类型填写对应字段(见下文详细说明) -5. **添加账号** — 站点创建后,在站点详情页添加账号凭证 +4. **填写站点信息** — 根据站点类型填写对应字段;如果是官方入口,也可以直接选择预设 +5. **添加连接** — 按场景继续添加账号、API Key,或改去「OAuth 管理」授权 6. **验证连接** — 系统自动验证账号可用性并获取模型列表 +### 一句话判断该走哪条路 + +| 你手上有什么 | 推荐入口 | 推荐方式 | +|------|------|------| +| 有后台面板的聚合站 | 站点管理 | 先加站点,再加账号 / Session | +| 只有 Base URL + API Key 的兼容接口 | 站点管理 | 先加站点,再加 API Key | +| 官方 Coding / API 兼容入口 | 站点管理 | 直接选择官方预设 | +| Codex / Claude / Gemini CLI / Antigravity 的 provider 账号 | OAuth 管理 | 直接浏览器授权 | + --- ## 📦 中转聚合平台接入 @@ -50,7 +66,7 @@ Metapi 支持两大类上游站点: New API 支持三种凭证类型: -##### 1. 用户名密码登录(推荐AnyRouter使用) +##### 1. 用户名密码登录(推荐 AnyRouter 使用) - **适用场景:** 有完整账号权限,需要自动签到、余额查询、账号令牌管理 - **填写方式:** @@ -64,9 +80,9 @@ New API 支持三种凭证类型: - **填写方式:** - 在「Access Token」字段填入以下任一格式: - Session Cookie:**(最不推荐)** - - 可通过浏览器F12获取 ![Session Cookie 获取](./screenshots/session-cookie-f12.png) + - 可通过浏览器 F12 获取 ![Session Cookie 获取](./screenshots/session-cookie-f12.png) - 一般为如下格式:`session=MTczNjQxMjM0NXxEdi1CQUFFQ180SUFBUkFCRUFBQVB2LUNBQUVHYzNSeWFXNW5EQThBRFhObGMzTnBiMjVmZEdGaWJHVUdjM1J5YVc1bkRBSUFBQT09fGRlYWRiZWVmMTIzNDU2Nzg5MGFiY2RlZjEyMzQ1Njc4OTBhYmNkZWY=` - - 系统访问令牌和用户ID**(推荐非Anyrouter的其他New API站点使用)** + - 系统访问令牌和用户 ID **(推荐非 AnyRouter 的其他 New API 站点使用)** - ![](./screenshots/account-management.png) - **自动解析:** 系统自动识别凭证类型并提取用户信息 @@ -85,7 +101,7 @@ New API 支持三种凭证类型: 2. 从 Session Cookie 中提取 User ID(支持 Gob 编码解析) 3. 通过探测常见 ID 范围验证可用性 -如果以上方法都不能获取到ID,则需要用户手动获取。 +如果以上方法都不能获取到 ID,则需要用户手动获取。 **防护盾穿透:** 自动处理阿里云盾 / Cloudflare 等 JS 挑战(`acw_sc__v2` / `cdn_sec_tc`),无需手动配置。 @@ -143,7 +159,7 @@ OneHub 继承 One API 的凭证体系,支持用户名密码、Access Token、A #### 账号凭证 -DoneHub 完全兼容 OneHub 的凭证体系,配置方式相同,DoneHub获取令牌位置如下图所示:![DoneHub 令牌位置](./screenshots/donehub-token.png) +DoneHub 完全兼容 OneHub 的凭证体系,配置方式相同,DoneHub 获取令牌位置如下图所示:![DoneHub 令牌位置](./screenshots/donehub-token.png) --- @@ -162,6 +178,7 @@ DoneHub 完全兼容 OneHub 的凭证体系,配置方式相同,DoneHub获取 #### 账号凭证 Veloera 基于 New API 架构,支持相同的凭证类型。特别注意: + - Veloera 需要 `Veloera-User` 请求头,Metapi 会自动添加 --- @@ -182,21 +199,49 @@ Veloera 基于 New API 架构,支持相同的凭证类型。特别注意: Sub2API 常见 JWT 短期会话机制,和传统 NewAPI 站点差异较大。按下面步骤进行添加: -首先去中转站点F12打开如下界面: +首先去中转站点 F12 打开如下界面: ![Sub2API 认证字段示例](./screenshots/sub2api-auth-f12.png) -然后回到Metapi账号添加处: +然后回到 Metapi 账号添加处: ![Sub2API Session 配置](./screenshots/sub2api-session-config.png) -1. 在「凭证模式」里选择 Session 模式,分别粘贴F12界面中的auth_token、refresh_token、token_expires_at字段进行验证,无需配置用户ID。 +1. 在「凭证模式」里选择 Session 模式,分别粘贴 F12 界面中的 `auth_token`、`refresh_token`、`token_expires_at` 字段进行验证,无需配置用户 ID。 2. 不要使用账号密码登录,Metapi 不支持代替 Sub2API 做登录 3. Sub2API 通常为订阅制使用,不支持签到;如果你只关心代理调用,也可以直接改用 API Key 模式 4. 若 `GET /v1/models` 为空,先确认该账号下已有可用用户 API Key,Metapi 会再尝试用它发现模型 --- +### CLIProxyAPI / CPA + +**适用平台:** CLIProxyAPI / CPA 一类标准 API provider + +#### 站点配置 + +| 字段 | 说明 | 示例 | +|------|------|------| +| **站点名称** | 自定义名称 | `本地 CPA` | +| **站点 URL** | CPA 暴露的 Base URL | `http://127.0.0.1:8317` | +| **平台类型** | 选择 `cliproxyapi` | - | + +#### 账号凭证 + +CPA 这类站点推荐直接使用 **API Key**: + +- 在「API Token」字段填入 CPA 提供的密钥 +- 不建议把它当成可签到、可查余额、可账号登录的传统面板站 + +#### 特殊说明 + +- 本地默认地址常见为 `http://127.0.0.1:8317` +- 远端实例也可能通过 `cliproxy` / `cpa` 风格 URL 或响应头被自动识别 +- 当前重点支持 **模型发现** 与 **代理调用** +- 不支持用户名密码登录、自动签到、站点余额 / 用户信息抓取 + +--- + ## 🌐 官方 API 端点接入 ### OpenAI @@ -215,6 +260,7 @@ Sub2API 常见 JWT 短期会话机制,和传统 NewAPI 站点差异较大。 #### 账号凭证 **仅支持 API Key:** + - 在「API Token」字段填入:`sk-proj-xxxxxxxxxxxxxx` - 不支持用户名密码登录(OpenAI 无此接口) @@ -245,6 +291,7 @@ Sub2API 常见 JWT 短期会话机制,和传统 NewAPI 站点差异较大。 #### 账号凭证 **仅支持 API Key:** + - 在「API Token」字段填入:`sk-ant-api03-xxxxxxxxxxxxxx` #### 功能限制 @@ -276,6 +323,7 @@ Sub2API 常见 JWT 短期会话机制,和传统 NewAPI 站点差异较大。 #### 账号凭证 **仅支持 API Key:** + - 在「API Token」字段填入:`AIzaSyxxxxxxxxxxxxxx` #### 功能限制 @@ -292,6 +340,71 @@ Sub2API 常见 JWT 短期会话机制,和传统 NewAPI 站点差异较大。 --- +## 🧩 官方兼容预设(推荐) + +除了手动选择 `openai` / `claude` 平台,现在站点编辑器里还内置了一批**官方预设**。这类预设更适合: + +- 直接接官方兼容入口 +- 自动填入官方推荐 URL +- 先用 API Key 初始化,再补推荐模型 +- 保留接入语义,后续创建完站点后更容易知道下一步怎么配 + +### 当前内置预设 + +| 预设 | 底层平台 | 默认地址 | 推荐说明 | +|------|------|------|------| +| 阿里云 CodingPlan / OpenAI | `openai` | `https://coding.dashscope.aliyuncs.com/v1` | 推荐先加 API Key,再补编程模型 | +| 阿里云 CodingPlan / Claude | `claude` | `https://coding.dashscope.aliyuncs.com/apps/anthropic` | 适合 Claude Code 一类工具直连 | +| 智谱 Coding Plan / OpenAI | `openai` | `https://open.bigmodel.cn/api/coding/paas/v4` | 推荐先加 API Key,再补 GLM 编程模型 | +| 智谱 Coding Plan / Claude | `claude` | `https://open.bigmodel.cn/api/anthropic` | 当前更适合手动选择预设 | +| DeepSeek / OpenAI | `openai` | `https://api.deepseek.com/v1` | 适合直接接 DeepSeek 官方兼容入口 | +| DeepSeek / Claude | `claude` | `https://api.deepseek.com/anthropic` | 适合 Claude 兼容用法 | +| Moonshot(Kimi) / OpenAI | `openai` | `https://api.moonshot.cn/v1` | 适合 Kimi 官方 OpenAI 兼容入口 | +| Moonshot(Kimi) / Claude | `claude` | `https://api.moonshot.cn/anthropic` | 适合 Claude 兼容用法 | +| MiniMax / OpenAI | `openai` | `https://api.minimaxi.com/v1` | 推荐先加 API Key | +| MiniMax / Claude | `claude` | `https://api.minimaxi.com/anthropic` | 适合 Claude Code 兼容入口 | +| ModelScope / OpenAI | `openai` | `https://api-inference.modelscope.cn/v1` | 适合开源编程模型兼容接入 | +| ModelScope / Claude | `claude` | `https://api-inference.modelscope.cn` | 适合 Claude 兼容接入 | +| 豆包 Coding Plan / OpenAI | `openai` | `https://ark.cn-beijing.volces.com/api/coding/v3` | 适合火山方舟 Coding Plan | + +#### 使用建议 + +1. 选中预设后,优先保留它自动填好的 URL +2. 如果你只是接一个普通自建网关,不想保留预设语义,再手动改回通用 `openai` / `claude` +3. 对官方预设来说,**不要机械地把 `/v1` 或 `/anthropic` 删掉**,以预设默认值为准 + +--- + +## 🔐 OAuth 连接接入 + +有些 provider 更适合在左侧菜单 **OAuth 管理** 里直接授权,而不是在「站点管理 → 账号管理」里手填凭证。 + +### 当前推荐走 OAuth 的 provider + +| Provider | 对应平台 | 自动创建的站点名 | 适用说明 | +|------|------|------|------| +| Codex | `codex` | `ChatGPT Codex OAuth` | 直接授权 Codex 账号 | +| Claude | `claude` | `Anthropic Claude OAuth` | 直接授权 Claude / Anthropic 账号 | +| Gemini CLI | `gemini-cli` | `Google Gemini CLI OAuth` | 支持浏览器授权,可选 Project ID | +| Antigravity | `antigravity` | `Google Antigravity OAuth` | 适合 Antigravity provider 登录 | + +#### 什么时候应该走 OAuth + +- 你接的不是一个普通面板站,而是 provider 自己的账号 +- 你不想手填 Cookie / Session / API Key +- 你希望后续刷新、重绑也继续走 provider 官方授权流程 + +#### 使用建议 + +1. 进入左侧菜单 **OAuth 管理** +2. 选择对应 provider 发起授权 +3. 如果是远程部署,按页面提示使用 SSH 隧道或手动回填 callback URL +4. 授权成功后,Metapi 会自动创建或复用对应站点与连接 + +完整流程见 [OAuth 管理](./oauth.md)。 + +--- + ## 🔧 高级配置 ### 站点级代理 @@ -303,6 +416,7 @@ Sub2API 常见 JWT 短期会话机制,和传统 NewAPI 站点差异较大。 ``` **配置方式:** + 1. 在站点编辑页面填写「代理 URL」字段 2. 格式:`http://proxy-host:port` 或 `socks5://proxy-host:port` 3. 支持 HTTP / HTTPS / SOCKS5 代理 @@ -324,17 +438,62 @@ Sub2API 常见 JWT 短期会话机制,和传统 NewAPI 站点差异较大。 **适用场景:** 某些站点的签到接口非标准路径,或需要通过外部服务触发签到。 **配置方式:** + 1. 在站点编辑页面填写「外部签到 URL」 2. Metapi 会向该 URL 发送 POST 请求执行签到 3. 请求头自动携带账号凭证 +### AI 请求地址池 + +现在不少站点已经不是“一个 URL 同时负责后台面板和 `/v1/*` AI 请求”。 + +Metapi 当前支持把这两层拆开: + +- **主站点 URL**:用于登录、签到、后台接口、系统访问令牌管理 +- **AI 请求地址池**:用于真正转发 `/v1/*`、`/chat/completions`、`/responses` 等模型请求 + +适合填写 AI 请求地址池的场景: + +1. 控制台地址和 AI 网关地址不同 +2. 同一个站点有多个 API host,需要健康切换 +3. 你想保留面板地址不变,只把模型流量导向专用网关 + +简单理解: + +```text +主站点 URL = 控制面 +AI 请求地址池 = 数据面 +``` + --- ## 🔍 站点自动检测 -Metapi 支持自动识别站点类型,检测优先级如下: +Metapi 支持自动识别站点类型,当前检测优先级如下: -### 1. URL 特征检测 +### 1. 官方预设检测 + +下列地址会优先识别成官方预设,并返回 `initializationPresetId`: + +| URL / 特征 | 识别结果 | +|------|------| +| `coding.dashscope.aliyuncs.com/v1` | `codingplan-openai` | +| `coding.dashscope.aliyuncs.com/apps/anthropic` | `codingplan-claude` | +| `open.bigmodel.cn/api/coding/paas/v4` | `zhipu-coding-plan-openai` | +| `api.deepseek.com/v1` | `deepseek-openai` | +| `api.deepseek.com/anthropic` | `deepseek-claude` | +| `api.moonshot.cn/v1` | `moonshot-openai` | +| `api.moonshot.cn/anthropic` | `moonshot-claude` | +| `api.minimaxi.com/v1` | `minimax-openai` | +| `api.minimaxi.com/anthropic` | `minimax-claude` | +| `api-inference.modelscope.cn/v1` | `modelscope-openai` | +| `api-inference.modelscope.cn` | `modelscope-claude` | +| `ark.cn-beijing.volces.com/api/coding/v3` | `doubao-coding-openai` | + +> [!NOTE] +> 智谱 Coding Plan 的 Claude 兼容入口当前不会按 URL 强制自动识别,更适合手动选预设。 + +### 2. URL 特征检测 根据 URL 中的关键字自动识别: @@ -343,24 +502,28 @@ Metapi 支持自动识别站点类型,检测优先级如下: | `api.openai.com` | OpenAI | | `api.anthropic.com` | Claude | | `generativelanguage.googleapis.com` | Gemini | +| `chatgpt.com/backend-api/codex` | Codex | +| `127.0.0.1:8317` / `localhost:8317` / `cliproxy` | CLIProxyAPI / CPA | | `anyrouter` | AnyRouter | | `donehub` / `done-hub` | DoneHub | | `onehub` / `one-hub` | OneHub | | `veloera` | Veloera | | `sub2api` | Sub2API | -### 2. 页面标题检测 +### 3. 页面标题检测 访问站点首页,解析 `` 标签识别平台类型。 -### 3. API 探测 +### 4. API 探测 依次尝试各平台的特征接口: + - New API:`/api/status` 返回 `system_name` - One API:`/api/status` 返回特定结构 - OpenAI:`/v1/models` 返回模型列表 +- CPA:`/v0/management/openai-compatibility` 返回兼容信息或特征响应头 -**手动指定:** 如果自动检测失败,可在添加站点时手动选择平台类型。 +**手动指定:** 如果自动检测失败,可在添加站点时手动选择平台类型或直接选择官方预设。 --- @@ -403,11 +566,16 @@ Metapi 会定期抓取已接入站点的公告,并在首次发现时写入站 ### 问题:添加站点后无法获取模型列表 **可能原因:** -1. 站点 URL 填写错误(检查是否包含 `/v1` 后缀,应去除) + +1. 站点 URL 填写错误 + - 通用平台常见是填根地址,错误地带上了不该带的 `/v1` + - 官方预设则相反,**不要**把预设自动带出的 `/v1` / `/anthropic` / `/api/coding/...` 手动删掉 2. 网络不通(检查代理配置或防火墙) -3. 凭证无效(重新验证账号密码或 Token) +3. 凭证无效(重新验证账号密码、Session 或 API Key) +4. 主站点 URL 和真实 AI 请求地址不同,但还没配置 AI 请求地址池 **解决方法:** + - 在站点详情页点击「测试连接」 - 查看「事件日志」中的错误信息 - 检查「代理日志」中的请求详情 @@ -417,22 +585,44 @@ Metapi 会定期抓取已接入站点的公告,并在首次发现时写入站 **原因:** 该站点是 New API 衍生版本,需要 User ID。 **解决方法:** + 1. Metapi 会自动探测 User ID,通常无需手动配置 2. 如果自动探测失败,可在账号编辑页面的「额外配置」中手动填写: + ```json { "platformUserId": 12345 } ``` +### 问题:CPA 为什么没有账号登录、签到、余额刷新 + +**原因:** `cliproxyapi` / CPA 在 Metapi 里按标准 API provider 处理,重点支持模型发现与代理调用,不按传统面板站处理。 + +**解决方法:** + +- 直接使用 API Key 模式 +- 不要再按「用户名密码登录 + 自动签到」的思路排查 + +### 问题:什么时候不该再用账号管理,而应该去 OAuth 管理 + +**原因:** 你接的不是普通面板站,而是 provider 自己的授权账号。 + +**解决方法:** + +- Codex / Claude / Gemini CLI / Antigravity 这类连接直接去左侧 **OAuth 管理** +- 不要在账号管理里反复尝试 Cookie / Session / API Key 兜底 + ### 问题:签到失败 **可能原因:** + 1. 凭证过期(Access Token 有效期到期) 2. 站点签到接口变更 3. 已经签到过(部分站点限制每日一次) **解决方法:** + - 查看「签到记录」中的失败原因 - 尝试重新登录获取新凭证 - 配置「外部签到 URL」使用备用签到方式 @@ -442,8 +632,9 @@ Metapi 会定期抓取已接入站点的公告,并在首次发现时写入站 **原因:** 不同平台的余额单位不同。 **说明:** + - New API 系列:余额单位为「美元」,内部存储为 `quota / 500000` -- OpenAI / Claude / Gemini:官方 API 无余额查询接口,显示为 `N/A` +- OpenAI / Claude / Gemini / CPA:官方或兼容 API 通常无余额查询接口,显示为 `N/A` --- @@ -453,40 +644,46 @@ Metapi 会定期抓取已接入站点的公告,并在首次发现时写入站 | 场景 | 推荐凭证类型 | 原因 | |------|-------------|------| -| 个人站点,需要完整功能 | 用户名密码 | 支持自动签到、账号令牌管理 | +| 个人站点,需要完整功能 | 用户名密码 / Access Token | 支持自动签到、账号令牌管理 | | 共享账号,只读权限 | Access Token | 避免密码泄露 | | 仅用于模型调用 | API Token | 最小权限原则 | +| Provider 原生账号 | OAuth | 更适合后续刷新、重绑与统一管理 | ### 2. 站点命名规范 建议使用清晰的命名规则,便于管理: -``` +```text [平台类型] - [站点特征] - [用途] ``` 示例: + - `New API - 主站 - 生产环境` - `OneHub - 备用 - 测试` - `OpenAI - 官方 - 高优先级` +- `CPA - 本地 - 调试` ### 3. 代理配置策略 -- **国内访问 OpenAI / Claude / Gemini:** 必须配置代理 +- **国内访问 OpenAI / Claude / Gemini / 部分 OAuth provider:** 通常需要代理 - **国内中转站:** 通常不需要代理 - **海外中转站:** 根据网络情况选择 +- **远程 OAuth 部署:** 除了代理,还要考虑回调端口连通性 ### 4. 定期维护 - **每周检查:** 账号健康状态、余额预警 - **每月清理:** 禁用长期不可用的站点和账号 - **凭证轮换:** 定期更新 Access Token 和 API Key +- **官方预设站点:** 新增模型时记得补充推荐模型和 AI 请求地址池 --- ## 🔗 相关文档 - [配置说明](./configuration.md) — 环境变量与路由参数 +- [OAuth 管理](./oauth.md) — Codex / Claude / Gemini CLI / Antigravity 授权接入 - [客户端接入](./client-integration.md) — 下游应用配置 - [常见问题](./faq.md) — 故障排查与优化建议 @@ -498,3 +695,4 @@ Metapi 会定期抓取已接入站点的公告,并在首次发现时写入站 - 支持同时接入多个相同类型的站点(如多个 New API 实例) - 站点禁用后,关联的所有账号和路由通道会自动禁用 - 删除站点会级联删除所有关联账号、Token 和路由配置,请谨慎操作 +- 如果你看到站点创建成功后的“官方预设”提示,请按它建议的下一步走,一般会更省事