diff --git a/README.md b/README.md index 143d403..06c57a6 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,8 @@ EZ-API 是“控制平面”,负责管理事实来源 (Source of Truth)。 ## API 端点 +> 补充文档(中文):[`docs/api.md`](docs/api.md) + ### 基础 - `GET /health` - `GET /api/status/test` diff --git a/docs/api.md b/docs/api.md index 2484640..cf8b72b 100644 --- a/docs/api.md +++ b/docs/api.md @@ -1,276 +1,243 @@ -# EZ-API 控制平面 API 文档(中文补充版) +# EZ-API 控制平面 (Control Plane) 业务文档 -> 本文补充 Swagger 中未详细说明的业务字段与配置含义,便于前端/运维快速理解。 -> Swagger 入口:`GET /swagger/index.html` +> 本文档作为 Swagger 接口定义的补充,旨在详细说明 EZ-API 的业务逻辑、核心模型关系及配置含义,帮助前端开发与运维人员快速上手。 +> **Swagger 入口**:`GET /swagger/index.html` --- -## 1. 基础信息 +## 1. 快速入门 -### 1.1 Base URL +### 1.1 服务地址 (Base URL) +默认地址:`http://{host}:8080` -默认:`http://{host}:8080` +### 1.2 鉴权体系 +系统采用三级鉴权机制,分别对应不同的操作权限: -### 1.2 鉴权方式 +| 角色 | 鉴权方式 | 配置来源 | 说明 | +| :--- | :--- | :--- | :--- | +| **Admin** | `Authorization: Bearer ` | 环境变量 `EZ_ADMIN_TOKEN` | 全局管理权限,可管理所有租户、供应商和模型。 | +| **Master** | `Authorization: Bearer ` | 创建 Master 时返回 | 租户级权限,仅能管理所属的子 Key、查看自身统计和日志。 | +| **Internal** | `X-Internal-Token: ` | 环境变量 `EZ_INTERNAL_STATS_TOKEN` | 内部组件(如 Data Plane)同步指标使用。 | -- **Admin**:`Authorization: Bearer ` - - 由环境变量 `EZ_ADMIN_TOKEN` 配置 -- **Master**:`Authorization: Bearer ` - - 由 `/admin/masters` 创建时返回,仅显示一次 -- **Internal**:`X-Internal-Token: ` - - 由环境变量 `EZ_INTERNAL_STATS_TOKEN` 配置 - -### 1.3 通用参数 - -- 列表分页(多数 `GET /admin/*`): - - `page`:从 1 开始 - - `limit`:默认 50,最大 200 - - `search`:模糊匹配(具体字段见各端点) -- 日志列表分页: - - `limit` / `offset` -- 时间范围: - - `since` / `until`:**Unix 秒**(日志查询、统计) - - 删除日志使用 `before`:**RFC3339 字符串** - -### 1.4 状态字段约定 - -- `master.status`:`active` / `suspended` -- `key.status`:`active` / `suspended` -- `provider.status`:`active` / `auto_disabled` / `manual_disabled` -- `namespace.status`:`active` / `suspended` +### 1.3 通用约定 +- **分页处理**: + - 管理端列表 (`GET /admin/*`):使用 `page` (从 1 开始) 和 `limit` (默认 50,最大 200)。 + - 日志列表:使用 `limit` 和 `offset`。 +- **时间格式**: + - 查询参数 (`since`/`until`):使用 **Unix 秒**(整数)。 + - 日志清理 (`before`):使用 **RFC3339 字符串** (例如 `2025-01-01T00:00:00Z`)。 +- **模糊搜索**:`search` 参数通常匹配名称、描述或关键标识符。 --- -## 2. 核心数据模型速览 +## 2. 核心业务模型 -### 2.1 Master +EZ-API 的核心逻辑围绕“租户-令牌-路由-供应商”展开。 -- `name`:租户名称 -- `group`:路由分组(影响 DP 选路) -- `max_child_keys`:可签发子 Key 数上限 -- `global_qps`:Master 级 QPS,**默认 0 表示关闭限流** -- `default_namespace` / `namespaces`:命名空间访问控制 -- `epoch`:用于撤销/轮换的版本号 - -### 2.2 Key(子 Key) - -- `scopes`:权限/用途描述(字符串) -- `model_limits`:允许使用的模型(逗号分隔) -- `model_limits_enabled`:是否启用模型限制 -- `expires_at`:过期时间(可选) -- `allow_ips` / `deny_ips`:CIDR 列表 -- `quota_limit` / `quota_used` / `quota_reset_at` / `quota_reset_type`:额度控制 - -### 2.3 Provider - -- `type`:上游类型(openai / anthropic / gemini 等) -- `base_url`:上游地址 -- `api_key`:上游 Key -- `group`:路由分组 -- `models`:支持模型列表(逗号分隔) -- `weight`:负载权重 -- `auto_ban` / `ban_until`:自动禁用控制 - -### 2.4 Model - -- `name`:模型名 -- `kind`:`chat` / `embedding` / `other` -- `context_window`:最大上下文 -- `max_output_tokens`:默认最大输出 -- `supports_vision` / `supports_functions` / `supports_tool_choice` / `supports_fim` - -### 2.5 Binding & Namespace - -- **Namespace**:逻辑命名空间(面向用户) -- **Binding**:`namespace.public_model` → `route_group` 规则 - - `selector_type`:`exact` 等 - - `selector_value`:匹配值 - ---- - -## 3. Feature Flags(重点补充) - -Feature 存储在 Redis `meta:features`。 - -### 3.1 常用开关 - -| Key | 类型 | 说明 | 默认 | -|---|---|---|---| -| `dp_state_store_backend` | string | DP 状态存储后端:`memory` / `redis` | `memory` | -| `dp_claude_cross_upstream` | bool | 允许 Claude 请求路由到 OpenAI 兼容上游 | `true` | -| `dp_context_preflight_enabled` | bool | DP 上下文预校验开关 | `true` | -| `log_request_body_enabled` | bool | 记录请求体 | `true` | - -### 3.2 日志清理覆盖项(特殊存储) - -这两项不是写入 `meta:features`,而是写入独立 Redis key: - -| Key | 说明 | Redis Key | 规则 | -|---|---|---|---| -| `log_retention_days` | 日志保留天数 | `meta:log:retention_days` | `0`/空表示清除覆盖,恢复默认配置 | -| `log_max_records` | 最大日志条数 | `meta:log:max_records` | `0`/空表示清除覆盖 | - -### 3.3 更新 Feature 示例 - -`PUT /admin/features` - -```json -{ - "dp_context_preflight_enabled": false, - "log_request_body_enabled": true, - "log_retention_days": 30, - "log_max_records": 1000000 -} +### 2.1 资源关系图 +```mermaid +graph TD + Admin[Admin 管理员] -- 创建 --> Master[Master 租户] + Master -- 签发 --> Key[Key 子令牌] + Master -- 关联 --> Namespace[Namespace 命名空间] + Namespace -- 定义 --> Binding[Binding 路由规则] + Binding -- 映射 --> Provider[Provider 上游供应商] + Provider -- 包含 --> Model[Model 模型能力] ``` ---- +### 2.2 身份与权限模型 +- **Master (租户)**:系统的顶级账户单位。 + - `group`:路由分组,决定该租户默认使用哪一组供应商。 + - `epoch`:版本号。当 Master 被删除或重置时,Epoch 增加,所有旧的子 Key 将立即失效。 + - `global_qps`:租户级总限流,`0` 表示不限流。 +- **Key (子令牌)**:由 Master 签发给最终用户使用的 API Key。 + - `scopes`:权限描述,仅用于业务标识。 + - `quota_limit`:总额度限制(Token 数),`-1` 表示无限额。 + - `quota_reset_type`:额度重置周期(如 `daily`, `monthly`)。 + - `allow_ips`/`deny_ips`:支持 CIDR 格式的 IP 白名单/黑名单。 -## 4. Admin API(管理端) +### 2.3 路由与供应商模型 +- **Provider (供应商)**:上游 AI 服务商(如 OpenAI, Anthropic)。 + - `weight`:在同一分组内的负载均衡权重。 + - `auto_ban`:若开启,当上游持续报错时,系统会自动暂时禁用该供应商。 +- **Model (模型能力)**:定义模型的基础属性(上下文长度、功能支持等)。 +- **Namespace (命名空间)**:逻辑隔离单位,用于组织 Binding 规则。 +- **Binding (路由规则)**:核心路由逻辑。 + - 将 `namespace.public_model`(用户请求的模型名)映射到特定的 `route_group`。 + - `selector_type`:匹配模式(目前主要为 `exact` 精确匹配)。 -### 4.1 Master 管理 - -- `POST /admin/masters`:创建 master - - `global_qps` 默认 0(关闭限流) -- `GET /admin/masters`:分页/搜索列表 -- `GET /admin/masters/:id`:详情(含 `realtime` 字段) -- `PUT /admin/masters/:id`:更新字段 -- `POST /admin/masters/:id/manage`:`freeze` / `unfreeze` -- `POST /admin/masters/batch`:批量 `delete` / `status` -- `POST /admin/masters/:id/keys`:为 master 签发子 Key(仅此处返回 `key_secret`) -- `GET /admin/masters/:id/realtime`:实时统计(QPS/限流状态等) -- `GET /admin/masters/:id/access` / `PUT /admin/masters/:id/access` - - 更新 `default_namespace` / `namespaces`,可 `propagate_to_keys` - -### 4.2 Key 访问控制 - -- `GET /admin/keys/:id/access` -- `PUT /admin/keys/:id/access` - -### 4.3 Provider 管理 - -- `POST /admin/providers`:创建 provider -- `POST /admin/providers/preset`:从预设模板创建 -- `POST /admin/providers/custom`:自定义创建 -- `POST /admin/providers/google`:Google Provider -- `GET /admin/providers` / `GET /admin/providers/:id` -- `PUT /admin/providers/:id` / `DELETE /admin/providers/:id` -- `POST /admin/providers/:id/test`:测试连通性 -- `POST /admin/providers/:id/fetch-models`:拉取模型 -- `POST /admin/providers/batch`:批量 `delete` / `status` - -### 4.4 Model 管理 - -- `POST /admin/models` -- `GET /admin/models` -- `PUT /admin/models/:id` -- `DELETE /admin/models/:id` -- `POST /admin/models/batch`:批量删除 - -### 4.5 Binding 管理 - -- `POST /admin/bindings` -- `GET /admin/bindings` -- `GET /admin/bindings/:id` -- `PUT /admin/bindings/:id` -- `DELETE /admin/bindings/:id` -- `POST /admin/bindings/batch`:批量 `delete` / `status` - -### 4.6 Namespace 管理 - -- `POST /admin/namespaces` -- `GET /admin/namespaces` -- `GET /admin/namespaces/:id` -- `PUT /admin/namespaces/:id` -- `DELETE /admin/namespaces/:id` - -### 4.7 日志与统计 - -- `GET /admin/logs`:筛选条件 - - `limit` / `offset` / `since` / `until` / `key_id` / `group` / `model` / `status_code` -- `DELETE /admin/logs`:删除日志 - - body: `{ "before": "2025-01-01T00:00:00Z", "key_id": 1, "model": "gpt-4" }` -- `GET /admin/logs/stats`:日志统计 -- `GET /admin/logs/webhook` / `PUT /admin/logs/webhook` - - `enabled`, `url`, `secret`, `threshold`, `window_seconds`, `cooldown_seconds`, `status_code_threshold` -- `GET /admin/stats`:全站用量统计 -- `GET /admin/operation-logs`:操作日志(支持 `page/limit/search`) - -### 4.8 模型注册表 - -- `GET /admin/model-registry/status` -- `POST /admin/model-registry/check` -- `POST /admin/model-registry/refresh` -- `POST /admin/model-registry/rollback` - -### 4.9 其他 - -- `GET /admin/features` / `PUT /admin/features` -- `POST /admin/sync/snapshot` +### 2.4 状态机约定 +| 状态值 | 适用对象 | 含义 | +| :--- | :--- | :--- | +| `active` | 所有 | 正常可用。 | +| `suspended` | Master, Key, Namespace | 已停用,请求将被拦截。 | +| `auto_disabled` | Provider | 因故障被系统自动熔断。 | +| `manual_disabled` | Provider | 被管理员手动禁用。 | --- -## 5. Master API(租户端) +## 3. 功能开关 (Feature Flags) -- `GET /v1/self` -- `POST /v1/tokens`:签发子 Key -- `GET /v1/tokens` -- `GET /v1/tokens/:id` -- `PUT /v1/tokens/:id` -- `DELETE /v1/tokens/:id` -- `GET /v1/logs` -- `GET /v1/logs/stats` -- `GET /v1/stats`:按时间范围统计 -- `GET /v1/realtime`:实时统计(含 QPS/限流状态) +系统支持通过 API 动态调整运行时行为。 + +### 3.1 存储逻辑 +- **常规开关**:存储在 Redis Hash `meta:features` 中。 +- **日志策略**:由于涉及清理逻辑,存储在独立 Key 中。 + +### 3.2 常用配置项 +| 配置项 | 类型 | 说明 | 默认值 | +| :--- | :--- | :--- | :--- | +| `dp_state_store_backend` | string | 状态存储后端:`memory` (单机) / `redis` (集群)。 | `memory` | +| `dp_claude_cross_upstream` | bool | 是否允许将 Claude 协议请求路由到 OpenAI 兼容上游。 | `true` | +| `log_request_body_enabled` | bool | 是否在日志中记录请求体(注意隐私风险)。 | `true` | +| `log_retention_days` | int | 日志保留天数。写入 Redis `meta:log:retention_days`。 | `30` | +| `log_max_records` | int | 最大日志保留条数。写入 Redis `meta:log:max_records`。 | `1000000` | + +> **注意**:更新 Feature 后,Data Plane (DP) 会在下一个同步周期(通常为秒级)自动加载新配置。 --- -## 6. Internal API(仅内部使用) +## 4. API 模块概览 -- `POST /internal/stats/flush` - - body: +### 4.1 管理端 (Admin API) - 需 Admin Token +- **租户管理**:创建 Master、签发子 Key、实时 QPS 监控、冻结/解冻。 +- **供应商管理**:支持从预设模板创建、测试连通性、自动拉取上游模型列表。 +- **模型注册表**:管理全局模型能力,支持从远程 `models.dev` 刷新和回滚。 +- **日志审计**:全站请求日志查询、按条件批量删除日志、配置 Webhook 告警。 -```json -{ - "keys": [ - {"token_hash":"...","requests":10,"tokens":120,"last_accessed_at":1700000000} - ] -} -``` +### 4.2 租户端 (Master API) - 需 Master Key +- **自服务**:查看租户信息、管理自己的子 Key。 +- **数据分析**:查看所属租户的请求日志、用量统计、实时 QPS。 -- `GET /internal/metrics`(内部指标) +### 4.3 内部接口 (Internal API) - 需 Internal Token +- **指标回传**:Data Plane 定期调用 `/internal/stats/flush` 同步 Token 消耗和请求数。 --- -## 7. 常见用法示例 +## 5. 典型操作示例 -### 7.1 创建 Master 并签发子 Key +### 5.1 租户与令牌管理 +1. **创建 Master 租户**: + ```bash + curl -X POST http://localhost:8080/admin/masters \ + -H "Authorization: Bearer " \ + -H "Content-Type: application/json" \ + -d '{ + "name": "研发团队", + "group": "default", + "max_child_keys": 10, + "global_qps": 50 + }' + ``` +2. **为 Master 签发子 Key**(注意:`key_secret` 仅在此处返回一次): + ```bash + curl -X POST http://localhost:8080/admin/masters/{master_id}/keys \ + -H "Authorization: Bearer " \ + -H "Content-Type: application/json" \ + -d '{ + "scopes": "chat,embedding", + "quota_limit": 5000000, + "quota_reset_type": "monthly", + "model_limits_enabled": true, + "model_limits": "gpt-4,claude-3-opus" + }' + ``` -```bash -# 创建 Master -curl -H 'Authorization: Bearer ' \ - -H 'Content-Type: application/json' \ - -d '{"name":"team-a","group":"default","max_child_keys":5}' \ - http://localhost:8080/admin/masters +### 5.2 供应商与路由配置 +1. **添加 OpenAI 供应商**: + ```bash + curl -X POST http://localhost:8080/admin/providers/custom \ + -H "Authorization: Bearer " \ + -H "Content-Type: application/json" \ + -d '{ + "name": "openai-primary", + "base_url": "https://api.openai.com/v1", + "api_key": "sk-...", + "group": "default", + "models": ["gpt-4", "gpt-3.5-turbo"], + "weight": 10 + }' + ``` +2. **创建模型路由 (Binding)**: + ```bash + curl -X POST http://localhost:8080/admin/bindings \ + -H "Authorization: Bearer " \ + -H "Content-Type: application/json" \ + -d '{ + "namespace": "default", + "public_model": "gpt-4-latest", + "route_group": "default", + "selector_type": "exact", + "selector_value": "gpt-4" + }' + ``` -# 为 Master 签发子 Key -curl -H 'Authorization: Bearer ' \ - -H 'Content-Type: application/json' \ - -d '{"scopes":"chat:write"}' \ - http://localhost:8080/admin/masters/{id}/keys -``` +### 5.3 系统运维与监控 +1. **调整全局日志保留策略**: + ```bash + curl -X PUT http://localhost:8080/admin/features \ + -H "Authorization: Bearer " \ + -H "Content-Type: application/json" \ + -d '{ + "log_retention_days": 15, + "log_max_records": 2000000 + }' + ``` +2. **查询特定 Key 的请求日志**: + ```bash + curl "http://localhost:8080/admin/logs?key_id=123&limit=20&status_code=200" \ + -H "Authorization: Bearer " + ``` +3. **查看租户实时统计**: + ```bash + curl http://localhost:8080/admin/masters/{id}/realtime \ + -H "Authorization: Bearer " + ``` -### 7.2 更新 Feature 开关 +### 5.4 租户自服务 (Master API) +1. **租户签发子 Key**: + ```bash + curl -X POST http://localhost:8080/v1/tokens \ + -H "Authorization: Bearer " \ + -H "Content-Type: application/json" \ + -d '{ + "scopes": "app-1", + "quota_limit": 100000 + }' + ``` +2. **租户查看自身用量统计**: + ```bash + curl "http://localhost:8080/v1/stats?period=today" \ + -H "Authorization: Bearer " + ``` -```bash -curl -H 'Authorization: Bearer ' \ - -H 'Content-Type: application/json' \ - -d '{"log_request_body_enabled":false}' \ - http://localhost:8080/admin/features -``` +### 5.5 内部与高级操作 +1. **手动刷新模型注册表**: + ```bash + curl -X POST http://localhost:8080/admin/model-registry/refresh \ + -H "Authorization: Bearer " \ + -H "Content-Type: application/json" \ + -d '{"ref": "main"}' + ``` +2. **内部指标回传 (Internal)**: + ```bash + curl -X POST http://localhost:8080/internal/stats/flush \ + -H "X-Internal-Token: " \ + -H "Content-Type: application/json" \ + -d '{ + "keys": [ + { + "token_hash": "...", + "requests": 100, + "tokens": 5000, + "last_accessed_at": 1734849600 + } + ] + }' + ``` --- -## 8. 备注 - -- Swagger 是接口字段“准确定义”,本文是业务含义“补充说明”。 -- 任何功能开关更新后,DP 会在下一次 Redis 刷新周期生效。 +## 6. 备注 +- **数据一致性**:控制平面 (CP) 修改配置后,数据平面 (DP) 通过 Redis Pub/Sub 或定期轮询实现最终一致性。 +- **安全性**:请务必妥善保管 `EZ_ADMIN_TOKEN`。Master Key 和子 Key Secret 在数据库中均以哈希形式存储,丢失无法找回,只能重置。 diff --git a/docs/管理关系图.png b/docs/管理关系图.png new file mode 100644 index 0000000..93b18e6 Binary files /dev/null and b/docs/管理关系图.png differ