feat: 添加管理台、额度与计费、用量与统计及用户访问管理文档

This commit is contained in:
chuan
2026-08-15 15:29:59 +08:00
parent 7e450372f8
commit 660d215a06
5 changed files with 661 additions and 0 deletions
+60
View File
@@ -4,6 +4,66 @@
每个 Key 同时拥有独立的美元额度账户。管理员可以分配本周期额度、设置日/周/月自动重置和并发上限,并查看不可变的扣费、额度调整与重置账目。额度采用请求结束后结算的软限制:余额为正时放行,实际 Usage 到达后扣费,最后一个或多个在途请求可能产生负余额,之后的新请求返回 429。
## 一次请求如何通过 CPA
```mermaid
sequenceDiagram
autonumber
participant Client as 用户 / Codex
participant CPA as CLIProxyAPI
participant Ext as cpa-ext
participant DB as SQLite
participant Upstream as 实际模型服务
Client->>CPA: 携带下游 Key 发起模型请求
CPA->>Ext: frontend_auth.authenticate
Ext->>DB: 查询 Key 与状态
DB-->>Ext: 用户访问配置
alt Key 无效或已停用
Ext-->>CPA: 认证失败
CPA-->>Client: 401 Unauthorized
else 认证成功
Ext-->>CPA: 返回用户身份(稳定 Key ID)
CPA->>Ext: request.intercept_before
Ext->>DB: 检查模型权限、余额与并发并占用名额
alt 模型、额度或并发不允许
Ext-->>CPA: 终止请求(403 / 429 / 503
CPA-->>Client: 返回结构化错误
else 请求准入
Ext-->>CPA: 允许继续
CPA->>Ext: scheduler.pick(可用上游候选)
alt 自动路由
Ext-->>CPA: 委托 CPA 内置调度
else 严格路由
Ext->>DB: 读取该用户绑定的上游账号
Ext-->>CPA: 指定唯一 Auth ID
end
CPA->>Ext: request.intercept_after
Ext-->>CPA: 复核价格配置与实际上游
alt 价格缺失或严格路由失效
CPA-->>Client: 503 Service Unavailable
else 复核通过
CPA->>Upstream: 使用选定凭证转发请求
Upstream-->>CPA: 模型响应 / 流式输出
CPA-->>Client: 返回模型结果
CPA->>Ext: request.complete(请求终态)
Ext->>DB: 释放并发名额,保存成功、失败或取消结果
CPA->>Ext: usage.handle(如有最终 Token 用量)
Ext->>Ext: 按模型价格计算成本
Ext->>DB: 保存用量、扣减余额并写入账目
end
end
end
```
CLIProxyAPI 负责 HTTP 接入、协议转换、上游凭证和实际请求执行;`cpa-ext` 通过插件回调参与请求决策与记录,不直接连接模型服务。`request.complete``usage.handle` 是独立事实回调,实际到达顺序不作为数据正确性的前提。
## 当前兼容目标
- CLIProxyAPI 源码:`CLIProxyAPI/`,检查时 revision 为 `f43aad7637ad813745bf7d341acb5663617570c5`
+153
View File
@@ -0,0 +1,153 @@
# 管理台
## 模块定位
管理台是 cpa-ext 各业务模块的统一操作和查看入口。它不单独保存业务事实,而是通过 CLIProxyAPI 受保护的 Management API 读取或修改 SQLite 中的真实配置与记录。
当前管理台采用单页、紧凑布局,直接作为插件资源嵌入,不依赖 CDN、外部前端框架或独立构建服务。
## 页面结构
| 页面 | 主要用途 |
| --- | --- |
| 用户 Key | 管理用户、访问策略、路由、额度和并发,查看用户汇总与账目 |
| 请求明细 | 分页查看请求结果、上游、Token、性能和成本,执行组合筛选 |
| 价格配置 | 维护模型基础价格、长上下文价格和 Fast 倍率 |
页面顶部统一提供实时/测试模式切换和 CPA 管理密钥输入。
## 用户 Key 页面
页面顶部展示今日请求、今日 Token、今日成本、各用户今日用量以及近 7 日 Token 趋势。
Key 列表展示:
- 用户名称和完整 Key
- 启用、禁用或归档状态;
- 当前余额和额度;
- 活跃并发与并发上限;
- 自动或严格上游路由;
- 允许的模型规则。
管理员可以创建 Key、显示已归档项、刷新列表,并通过侧边抽屉完成以下操作:
- 修改名称和状态;
- 选择自动路由或指定上游账号;
- 允许全部模型或填写逗号分隔的模型规则;
- 设置额度、并发上限、重置周期和下一次重置时间;
- 立即重置额度;
- 查看最近计费账目;
- 永久归档 Key
- 查看该用户累计、今日和最近请求。
业务规则和拒绝条件分别由“用户与访问管理”“额度与计费”模块执行,管理台只负责提交和呈现。
## 请求明细页面
请求明细默认每页显示 100 条,页码、上一页、下一页、选择列和刷新操作位于同一顶部工具区。
当前筛选项包括:
- 开始和结束时间;
- 用户;
- 模型;
- 成功、失败、拒绝或取消;
- 实际上游;
- Responses、Compact 或 Chat 端点;
- 完整 Request ID。
筛选和分页由服务端执行。应用新筛选会返回第一页;刷新保持当前页和筛选条件。只有页面可见、位于请求明细且处于第一页时,实时模式才每三秒自动刷新,避免用户查看历史页时列表自行跳动。
“选择列”用于控制明细表可见字段,不改变服务端保存的数据。
## 价格配置页面
价格页面采用左侧模型列表、右侧编辑区:
- 新增或选择一个精确模型名称;
- 设置输入、缓存读取、缓存写入和输出的基础价格;
- 可选启用长上下文价格;
- 设置长上下文输入门槛及“大于/大于等于”比较方式;
- 可选启用 Fast 价格并设置倍率;
- 保存或删除模型价格。
价格单位统一显示为 `$ / 1M Token`。保存前由管理接口完成严格字段校验,页面不会自行推断缺失价格。
## 实时模式
实时模式连接当前 CLIProxyAPI 实例:
- 需要输入 CPA Management Key
- 所有读取来自真实管理接口;
- 创建、编辑、归档、重置和价格保存会修改真实数据;
- 请求明细和汇总反映真实请求事实。
管理台资源本身可以被 CPA 加载,但敏感管理接口仍由 CLIProxyAPI 的管理认证保护。
## 测试模式
测试模式用于管理员熟悉页面和验证交互,与真实数据完全隔离:
- 不需要管理密钥;
- 不访问任何真实 cpa-ext 管理接口;
- 使用浏览器本地的模拟 Key、上游、请求、价格和账目;
- 创建、编辑、归档、重置和删除只修改本地模拟状态;
- 提供放大的请求记录量,便于测试分页、筛选和表格布局;
- 可以一键恢复初始测试数据。
测试数据保存在浏览器本地存储中,当前选择的实时/测试模式保存在当前会话。切换模式不会把测试数据导入真实数据库,也不会用真实数据覆盖测试样例。
## 管理接口
管理接口统一挂载在:
```text
/v0/management/plugins/cpa-ext
```
| 路径 | 方法 | 用途 |
| --- | --- | --- |
| `/keys` | GET、POST、PATCH、DELETE | 查询、创建、更新和归档 Key |
| `/key-stats` | GET | 查询单个 Key 的统计和最近请求 |
| `/upstreams` | GET | 同步并查询 CPA 上游账号 |
| `/model-suggestions` | GET | 查询已知模型名称建议 |
| `/billing-reset` | POST | 立即重置指定 Key 的额度 |
| `/billing-ledger` | GET | 查询指定 Key 的计费账目 |
| `/usage` | GET | 查询分页请求明细 |
| `/usage-summary` | GET | 查询今日、用户和每日汇总 |
| `/prices` | GET、PUT、DELETE | 查询、保存和删除模型价格 |
管理台 HTML 由以下插件资源提供:
```text
/v0/resource/plugins/cpa-ext/ui
```
管理接口返回结构化 JSON 和明确的 HTTP 状态码;未知路径返回 `not_found`,数据库不可用、请求字段错误等情况返回对应错误码和消息。
## 界面与数据原则
- 管理台不直接操作 SQLite,只调用公开管理接口。
- 统计卡片和图表使用服务端汇总,不从当前明细页推算。
- 业务校验由服务端完成,前端校验只用于尽早提示。
- 完整 Key 仅在受管理认证保护的 Key 接口和页面中显示。
- 上游 Token、Cookie 和原始凭证不进入管理台。
- 界面保持单个嵌入资源,避免运行时依赖外部 CDN。
- 窄屏下表单和工具栏自动重排,明细表保留横向滚动能力。
## 模块边界
本模块负责:
- 提供统一管理页面;
- 调用并呈现 cpa-ext Management API
- 管理实时和测试数据模式;
- 提供紧凑、可筛选、可分页的操作界面。
本模块不负责:
- 绕过 CLIProxyAPI 管理认证;
- 在浏览器中直接执行业务扣费或访问控制;
- 保存真实业务数据;
- 提供普通用户自助页面;
- 提供登录、角色和多管理员权限体系。
+166
View File
@@ -0,0 +1,166 @@
# 额度与计费
## 模块定位
额度与计费负责回答三个问题:一次请求是否还可以开始、请求实际产生了多少成本、该用户当前还剩多少可用额度。
每个用户 Key 拥有独立的美元额度账户、重置周期和并发上限。系统没有套餐、订阅或充值订单,管理员直接分配额度。
## 当前能力
| 能力 | 当前实现 |
| --- | --- |
| 用户额度 | 每个 Key 独立设置本周期美元额度 |
| 请求扣费 | 根据最终 Token Usage 和模型价格结算 |
| 自动重置 | 支持不重置、每日、每周和每月 |
| 手动重置 | 管理员可立即开始新额度周期 |
| 并发限制 | 每个 Key 独立限制同时执行的请求数 |
| 价格规则 | 支持基础价格、长上下文价格和 Fast 倍率 |
| 计费账目 | 永久记录扣费、额度调整和周期重置 |
| 请求拦截 | 余额、并发或价格不满足时在上游调用前拒绝 |
## 额度账户
每个 Key 创建时同时创建一个额度账户,默认值为:
| 属性 | 默认值 |
| --- | --- |
| 本周期额度 | `$0` |
| 已用金额 | `$0` |
| 可用余额 | `$0` |
| 自动重置 | 不重置 |
| 并发上限 | 4 |
三项金额的关系始终为:
```text
可用余额 = 本周期额度 - 本周期已用金额
```
金额在数据库中以微美元整数保存,管理接口使用最多六位小数的美元字符串,避免浮点累计误差。
修改额度只改变本周期额度,不会清空已经产生的消费。例如额度为 `$10`、已用 `$3` 时,将额度改为 `$5`,余额会变为 `$2`
## 请求准入与结算
计费采用“请求前准入、请求后结算”的软限制:
1. 请求开始前读取当前额度周期。
2. 如果已经到达重置时间,先执行周期重置。
3. 余额必须大于零。
4. 当前并发必须小于用户并发上限。
5. 为 Request ID 创建并发占用后放行请求。
6. 请求终态到达时释放并发占用。
7. 最终 Usage 到达后计算成本、增加已用金额并写入扣费账目。
系统不会在请求开始前估算并冻结最大费用,因此最后一个或多个并发请求可能让余额变成负数。负余额会被保留,之后的新请求不再放行,直到管理员提高额度或开始新周期。
同一个 Request ID 的重复准入不会重复占用并发;同一条 Usage 的重复回调也不会重复扣费。插件重新启动时会释放上次进程遗留的未关闭并发占用。
## 并发限制
并发上限可以设置为 1–64。计数基于已经准入且尚未收到请求终态的 Request ID。
- 达到上限时,新请求返回 HTTP 429 和 `billing_concurrency_exceeded`
- 成功、失败、拒绝或取消的请求进入终态后都会释放名额。
- 重复或迟到的终态回调不会重复释放或破坏计数。
并发限制只控制同时执行数量,不限制单位时间请求次数或 Token 数量。
## 额度重置
| 重置方式 | 行为 |
| --- | --- |
| `none` | 永不自动重置 |
| `daily` | 按天开始新周期 |
| `weekly` | 每七天开始新周期 |
| `monthly` | 按月开始新周期 |
| 手动重置 | 立即结束当前周期并开始新周期 |
未指定首次重置时间时,系统以 Key 创建时间作为周期锚点计算下一次重置。周期计算使用 `Asia/Shanghai` 时区;月度锚点在较短月份不存在时使用该月最后一天。
重置后:
- 本周期已用金额归零;
- 新周期额度沿用当前额度设置;
- 可用余额恢复为完整额度;
- 旧周期余额不结转;
- 历史周期和账目继续保留。
自动重置在读取额度状态或执行请求准入时检查,不依赖常驻定时任务。
## 模型价格
每个模型使用精确模型名称维护一套价格策略,价格单位为 `$ / 1M Token`
### 基础价格
| 价格项 | 计费对象 |
| --- | --- |
| 输入 | 排除缓存读取和缓存写入后的普通输入 Token |
| 缓存读取 | Cache Read Token |
| 缓存写入 | Cache Write/Creation Token |
| 输出 | Output Token |
普通输入 Token 的计算方式为:
```text
普通输入 = 输入 Token - 缓存读取 Token - 缓存写入 Token
```
### 长上下文价格
价格策略可以设置输入 Token 门槛,并选择“大于”或“大于等于”。请求达到门槛时,输入、缓存读取、缓存写入和输出四项价格整体切换到长上下文价格,不与基础价格混用。
### Fast 价格
当请求标记为 Fast、Priority 或同等快速服务档位,并且该模型启用 Fast 计价时,系统对完整请求成本应用一次倍率。倍率以精确分数保存,默认界面值为 `2.5`
系统先选择基础或长上下文档位,再应用 Fast 倍率,最后对整次请求执行一次四舍五入。
## 价格缺失
允许访问的模型必须存在价格配置。系统在 CPA 已经选择上游后、真正访问模型服务前再次检查实际模型价格。
价格不存在时返回 HTTP 503 和 `billing_price_unavailable`,不会把未知成本的请求发送到上游。历史迁移数据仍可能因为当时没有价格而显示为成本不可用。
## 不可变账目
| 账目类型 | 含义 | 金额方向 |
| --- | --- | --- |
| `charge` | 一次最终 Usage 产生的扣费 | 负数 |
| `quota_change` | 管理员修改本周期额度 | 增加为正,减少为负 |
| `cycle_reset` | 自动或手动开始新周期 | 新周期完整额度 |
每条账目保存用户 Key、额度周期、变动金额、变动后余额和发生时间。请求扣费还会保存 Request ID、Execution ID 和模型。
账目只追加、不修改、不删除,并通过唯一事件标识避免重复写入。额度状态用于快速读取当前余额,账目用于解释余额变化过程。
## 拒绝结果
| 条件 | HTTP 状态 | 错误码 |
| --- | --- | --- |
| 余额小于或等于零 | 429 | `billing_quota_exhausted` |
| 并发达到上限 | 429 | `billing_concurrency_exceeded` |
| 额度数据库不可用 | 503 | `billing_unavailable` |
| 模型没有价格 | 503 | `billing_price_unavailable` |
这些拒绝发生在访问实际模型服务之前,并进入请求终态记录。
## 模块边界
本模块负责:
- 模型价格和确定性成本计算;
- 用户额度、余额和额度周期;
- 并发请求准入;
- 请求结束后的实际扣费;
- 不可变计费账目。
本模块不负责:
- 套餐、订阅、充值、支付和退款;
- 按分钟、按日或按月的额外速率限制;
- 请求开始前的费用预估或资金冻结;
- 用户 Key 的身份认证和模型权限;
- 上游服务本身的账单对账。
+137
View File
@@ -0,0 +1,137 @@
# 用量与统计
## 模块定位
用量与统计负责记录一次请求发生了什么,并将请求结果、实际使用的上游、Token、性能和成本整理成可查询的请求明细与汇总数据。
该模块以 CLIProxyAPI 的请求终态和最终 Usage 为事实来源,不解析客户端响应内容,也不依赖管理页面当前加载的记录。
## 当前能力
| 能力 | 当前实现 |
| --- | --- |
| 请求终态 | 记录成功、失败、拒绝和取消 |
| Token 用量 | 记录输入、输出、推理、缓存读取和缓存写入 |
| 实际执行 | 记录模型、上游 Auth ID、端点和执行信息 |
| 性能指标 | 记录首字延迟、总延迟、生成速度和缓存率 |
| 成本事实 | 保存计算结果、价格档位和 Fast 倍率 |
| 请求归并 | 将请求终态与 Usage 整理为一条可读明细 |
| 查询 | 支持服务端分页、数字页码和多条件筛选 |
| 汇总 | 提供今日指标、各用户用量和近 7 日 Token |
## 两类事实
CLIProxyAPI 会通过两个独立回调提供请求信息:
| 事实 | 来源 | 主要内容 |
| --- | --- | --- |
| 请求终态 | `request.complete` | Request ID、开始与结束时间、成功/失败/拒绝/取消、状态码和错误 |
| 最终用量 | `usage.handle` | Execution ID、实际上游、模型、Token、延迟和 Usage 结果 |
这两个回调可能乱序、重复或只到达其中一个,因此数据库分别保存原始事实,再建立请求明细查询投影。管理台看到的一行是查询结果,不会为了合并展示而修改原始事实或计费账目。
## 请求与重试
- Request ID 用于关联一次下游请求的生命周期。
- Execution ID 用于区分该请求的具体上游执行。
- 同一次请求发生上游重试时,每次真实执行继续分别展示,不会把多个执行的 Token 或成本错误相加为一次执行。
- 没有 Usage 的拒绝、取消或失败请求仍然显示请求终态。
- 只有 Usage、暂时没有终态的记录也可以单独显示,终态到达后投影会自动更新。
部分旧版回调可能缺少 Request ID。系统仅在请求时间足够接近且匹配关系唯一时,将 Usage 与终态合并;存在并发歧义时宁可保留为两条,也不会错误关联到其他用户的请求。
## 请求结果
| 结果 | 含义 |
| --- | --- |
| `succeeded` | 请求正常完成 |
| `failed` | 执行失败或上游返回错误 |
| `rejected` | 请求在认证、权限、额度、并发、价格或路由阶段被拒绝 |
| `canceled` | 客户端断开或请求被取消 |
如果终态尚未到达,界面根据现有 Usage 事实展示当前可确定的结果;终态到达后以请求生命周期结果补全。
## 明细字段
请求明细当前可以展示:
- 请求时间、Request ID、Execution ID、Trace ID
- 用户 Key 名称;
- 客户端请求模型和实际计费模型;
- 推理强度、服务档位和速度模式;
- 请求结果、HTTP 状态码和错误;
- 请求类型与端点;
- 实际上游 Auth ID、Auth Index 和认证类型;
- 首字延迟、生成速度;
- 输入、输出、推理、缓存读取、缓存写入和总 Token;
- 缓存率、成本、价格档位和 Fast 计价结果;
- 客户端 IP。
并非每种端点都能提供所有字段。字段无法由 CPA 回调可靠获得时保留为空,不使用猜测值。一次性 JSON/Compact 响应不展示不可比较的首字延迟和生成速度。
## 服务端分页
请求明细由 SQLite 分页查询,而不是先把全部历史加载到浏览器。
- 默认每页 100 条,单页上限也是 100 条。
- 默认按照请求时间和稳定记录 ID 倒序排列。
- 数字页码用于直接跳转。
- 连续上一页、下一页使用游标保持翻页稳定。
- 游标与当前全部筛选条件绑定,修改筛选后不能继续使用旧游标。
- 新请求写入时,已经打开的连续翻页不会因为列表头部变化而重复或遗漏原有记录。
当前支持的筛选条件为:
| 条件 | 说明 |
| --- | --- |
| 开始、结束时间 | 使用 RFC3339 时间范围 |
| 用户 Key | 按稳定 Key ID 查询 |
| 模型 | 按模型名称查询 |
| 结果 | 成功、失败、拒绝或取消 |
| 上游 | 按实际 Auth ID 查询 |
| 端点 | 例如 Responses、Compact 或 Chat |
| Request ID | 使用完整 Request ID 精确定位 |
## 汇总统计
汇总由数据库独立计算,不受请求明细当前页或筛选条件影响。
| 汇总 | 当前内容 |
| --- | --- |
| 今日总览 | 请求数、输入 Token、输出 Token、总 Token 和成本 |
| 用户汇总 | 各用户今日请求、Token、成本和最近使用时间 |
| 近 7 日趋势 | 每个自然日的总 Token |
| 单用户统计 | 累计、今日指标和最近 50 条请求 |
“今日”按照 `Asia/Shanghai` 自然日计算。成本只汇总已经得到有效价格计算结果的 Usage。
## 持久化与规模
原始请求、Usage 和轻量查询投影均保存在 SQLite。升级旧数据库时,插件会自动创建投影、回填历史数据并建立分页和筛选索引。
查询投影只保存明细检索所需的关联和排序字段,Token、成本、生命周期和账目仍以原始事实表为准。当前分页与组合筛选已按百万级记录场景设计,不要求将全部记录读入内存。
## 数据一致性
- Usage 插入使用稳定事件标识,重复回调不会重复记录或扣费。
- 请求终态按 Request ID 幂等更新。
- 回调乱序时,后到达的事实会重新同步查询投影。
- 失败、取消和孤立 Usage 不会为了界面整齐而被删除。
- 历史迁移只建立查询关系,不改写既有用量和计费事实。
## 模块边界
本模块负责:
- 请求终态与 Usage 持久化;
- 请求明细归并、分页和筛选;
- Token、成本、上游和性能展示;
- 今日、用户和每日趋势汇总。
本模块不负责:
- 用户认证、模型权限和上游选择;
- 模型价格的维护规则;
- 额度准入和余额扣减;
- 修改或重放历史请求;
- 替代上游服务提供商的正式账单。
+145
View File
@@ -0,0 +1,145 @@
# 用户与访问管理
## 模块定位
用户与访问管理负责识别调用者,并决定该调用者可以使用哪些模型、请求应由哪个上游账号处理。
本项目不建立独立的用户账号体系,而是采用最小模型:
> 一个 Key 代表一个用户。
管理员直接管理 Key;Key 的稳定 ID 用于关联用量、额度和历史记录,Key 名称用于界面识别,Key 值用于请求认证。
## 当前能力
| 能力 | 当前实现 |
| --- | --- |
| Key 创建 | 支持自动生成或手动指定 Key 值 |
| Key 状态 | 支持启用、禁用和归档 |
| 下游认证 | 支持 `Authorization: Bearer <key>``X-Api-Key` |
| 模型权限 | 支持允许全部模型、精确模型名和 `*` 通配符 |
| 上游路由 | 支持 CPA 自动选择或严格绑定一个上游账号 |
| 默认迁移 | 首次启动自动创建 `default` Key,兼容现有调用配置 |
| 历史关联 | Key 的请求、用量、额度和账目均按稳定 ID 关联 |
## Key 数据模型
每个 Key 包含以下访问属性:
| 属性 | 说明 |
| --- | --- |
| ID | 系统生成的稳定标识,用于内部关联,不随名称变化 |
| 名称 | 管理员可读的用户名称,长度为 1–64 个字符 |
| Key 值 | 下游请求凭证;创建后不可修改 |
| 状态 | `active``disabled``archived` |
| 路由模式 | `auto``strict` |
| 上游账号 | 严格路由时绑定的 CPA 上游账号 |
| 模型规则 | 允许全部模型,或一组模型匹配规则 |
Key 值允许 1–256 个非空白、非控制字符。未手动填写时,系统生成以 `cpa_` 开头的随机值。
## 状态规则
| 状态 | 是否可以调用 | 是否可以编辑 | 是否保留历史 | 是否可以恢复 |
| --- | --- | --- | --- | --- |
| `active` | 是 | 是 | 是 | 不适用 |
| `disabled` | 否 | 是 | 是 | 可以重新启用 |
| `archived` | 否 | 否 | 是 | 不可以 |
禁用用于临时停止用户访问;归档用于永久退出管理。归档不会删除请求、用量、额度或计费账目,默认 Key 列表不再显示已归档项。
## 模型权限
模型匹配不区分大小写,并忽略规则首尾空白。
- “允许全部模型”开启时,不再读取单独的模型规则。
- “允许全部模型”关闭时,至少需要一条模型规则。
- 不含 `*` 的规则执行精确匹配,例如 `gpt-5.6-sol`
- `*` 可以匹配任意长度的文本,例如 `deepseek-*``*-flash``gpt-*-codex`
- 空模型名不能通过模型准入。
请求模型不符合规则时,请求在到达上游前被拒绝,返回 HTTP 403 和错误码 `model_not_allowed`
## 上游路由
### 自动路由
`auto` 模式不绑定具体账号,由 CLIProxyAPI 根据当前可用候选、优先级和自身调度规则选择上游。
切换到自动路由后,Key 原有的上游绑定会被清空。
### 严格路由
`strict` 模式必须选择一个已经由 CLIProxyAPI 发现的上游账号。插件在调度阶段只选择该账号,不允许静默回退到其他账号。
出现以下情况时,请求返回 HTTP 503 和错误码 `bound_upstream_unavailable`
- 绑定的账号已经不存在;
- 绑定的账号被禁用或处于不可用状态;
- 绑定账号不在本次请求的可用候选中;
- 调度完成后的实际上游与绑定账号不一致。
上游账号信息来自 CLIProxyAPI 的账号列表和实际调度候选,插件只保存路由所需的账号标识、提供商、显示名称和状态,不读取或保存上游 Token、Cookie 等凭证内容。
## 默认 Key 与新建 Key
首次启动且数据库中没有任何 Key 时,插件根据配置创建第一个 Key:
- 默认名称:`default`
- 默认 Key 值:`000000`
- 默认状态:启用
- 默认路由:自动
- 默认模型权限:允许全部模型
该行为用于让已有 Codex/CLIProxyAPI 调用配置无需修改即可迁移到插件管理。
之后创建新 Key 时,系统先复制 `default` 当时的模型权限和上游路由,再应用管理员本次明确填写的设置。复制只发生在创建时,后续修改 `default` 不会影响已经创建的 Key。
如果数据库中已经存在 Key,启动配置不会覆盖或重新创建 `default`
## 请求处理流程
| 阶段 | 模块行为 |
| --- | --- |
| 1. 提取凭证 | 从 Bearer Token 或 `X-Api-Key` 读取 Key |
| 2. 身份认证 | 查找 Key,并确认状态为 `active` |
| 3. 建立调用身份 | 使用稳定 Key ID 作为下游调用者身份 |
| 4. 模型准入 | 使用请求模型匹配该 Key 的模型规则 |
| 5. 上游调度 | 自动委托 CPA,或选择严格绑定的账号 |
| 6. 路由复核 | 严格模式下确认实际选择的账号与绑定一致 |
认证失败不会进入后续访问判断。Key 在请求过程中被停用时,后续拦截仍会再次检查状态,避免仅依赖认证阶段的旧状态。
额度、并发和价格检查发生在同一条请求准入链路中,但分别属于“额度与计费”和“价格配置”模块,不在本文展开。
## 管理操作
管理员页面当前支持:
- 查看有效 Key,按需包含已归档 Key;
- 创建并复制 Key
- 修改名称、启用状态、模型规则和上游路由;
- 临时禁用或重新启用 Key
- 永久归档 Key
- 同步并选择 CLIProxyAPI 当前可见的上游账号;
- 根据历史请求和价格配置获得模型名称建议;
- 查看该 Key 的累计、今日和最近使用记录。
管理操作通过受 CLIProxyAPI Management Key 保护的管理接口完成。测试模式使用独立模拟数据,不读取或修改这里描述的真实 Key 和路由配置。
## 模块边界
本模块负责:
- Key 身份与生命周期;
- 下游请求认证;
- 模型访问规则;
- 上游账号选择策略。
本模块不负责:
- 用户注册、密码、登录会话和角色权限;
- 套餐、充值、支付和订单;
- 额度扣减、周期重置和并发计数;
- 模型价格维护与成本计算;
- CLIProxyAPI 上游账号本身的登录、刷新或凭证维护。