Files
openteam/PLANNING.md
T
SakurasanandClaude ec4de8d913 M0-M4: 推倒重来基线(基建+用户/密钥/核心代理+前端+管理后台+三协议互转)
- 后端 Go+Gin+GORM: 配置(OT_ env)/SQLite/Postgres 双驱动、用户体系(argon2id+JWT access/refresh)、
  API Key(sk- 48位, 仅存 SHA-256 哈希)
- 代理网关: /v1/chat/completions、/v1/responses、/v1/messages、/v1/models;错误按客户端协议返回
- 三协议互转(convert 包): Chat↔Messages↔Responses 请求/响应 + 流式 SSE 逐事件转换(直通优先)
- 用量计费: 异步批量记账、余额扣减、balance_logs、usage_daily 日聚合
- 管理 API: 用户/渠道 CRUD+测试+模型导入/模型定价+绑定/统计/系统配置
- 前端 Vue3+TS+Tailwind(taste-skill 设计 tokens): Landing/登录注册/控制台/管理后台,
  自建组件+Phosphor 图标+自建 SVG 趋势图, 已过 web-design-guidelines 复查
- mock 上游: OpenAI+Anthropic 双协议模拟(含流式)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-15 15:34:06 +08:00

533 lines
28 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 大模型中转站(OpenRouter-like)规划文档
> 版本:v0.3 · 2026-08-15 · 状态:规划(决策已定:推倒重来)
>
> 技术栈:**Go + Vue3 + Tailwind CSS**,前端按 **taste-skill** 定义设计方向。
> 本文档是项目蓝图。编码前先与团队对齐;旧实现仅作参考(§2)。
---
## 1. 项目概述
### 1.1 定位
一个自托管的 **LLM API 中转网关**,功能对标 OpenRouter / one-api:
- 对下游用户暴露**统一的、OpenAI 兼容的 API 入口**,背后接入多个上游渠道(OpenAI、Anthropic、兼容第三方等)。
- 对外提供三套协议入口:**OpenAI Responses API、OpenAI Chat Completions、Anthropic Messages**,覆盖两大生态的 SDK 与客户端。
- 内置用户体系、API Key 管理、用量统计与计费(充值暂缓,见 §5.5)。
### 1.2 三大板块(对应用户的诉求)
| 板块 | 面向 | 核心功能 |
| --- | --- | --- |
| **大模型代理** | 下游开发者 | 三套协议入口 + 协议互转 + 渠道接入 + 负载均衡/健康检查/故障转移 + `/v1/models` |
| **后台管理** | 管理员面板 / 普通用户 | 注册登录、角色(admin/user)、API Key、渠道管理、用户管理、充值审核 |
| **用量计费** | 管理员 / 普通用户 | token 统计、计价、余额、请求流水、日聚合报表 |
> MVP 顺序即此三板块的骨架:**先把"代理 + 用户 + 记账"跑通**,再补管理后台与渠道体系,最后是协议转换与充值。
### 1.3 核心价值
| 对用户 | 对管理员 |
| --- | --- |
| 一个 Key 访问多家模型,OpenAI/Anthropic 生态格式互通 | 统一管理多个上游渠道,做模型定价 |
| 查询用量、成本明细 | 管理用户、审核充值、看全局营收 |
| 配额/余额控制 | 渠道健康检查、负载均衡、故障转移 |
### 1.4 对外协议(明确范围)
| 端点 | 协议 | 说明 |
| --- | --- | --- |
| `POST /v1/responses` | OpenAI Responses API | OpenAI 新生态(SDK/Agents)首选,含流式、工具调用、结构化输出 |
| `POST /v1/chat/completions` | OpenAI Chat Completions | 兼容面最广的格式,含流式(SSE)与工具调用 |
| `POST /v1/messages` | Anthropic Messages | Claude 生态原生格式,含流式与工具调用 |
| `GET /v1/models` | OpenAI 风格模型列表 | 对外列出可用模型;也用于渠道侧自动导入模型列表 |
> 三套协议之间可**互相转换**:例如客户端按 Responses 调用 `claude-sonnet-5`,网关会转换成 Anthropic 协议打给 Anthropic 渠道,再以 Responses 流式返回;同理可反向。协议与渠道匹配时走**直通**(见 §5.1.3)。
### 1.5 首版范围(MVP)
| 纳入(按序) | 暂缓 |
| --- | --- |
| M1 核心代理(chat/completions + responses + models,直通) | 充值(**待定**,见 §5.5) |
| M2 用户体系 + API Key + 记账 | 在线支付、审计报表、多实例 |
| M3 管理后台(渠道/用户/模型/用量) | 邀请码(配置开关预留) |
| M4 协议转换(messages 端点 + 三协议互转) | 组织/团队(多租户) |
| M5 渠道体系完善(LB/健康/重试/模型导入) | viewer 只读角色 |
---
## 2. 当前状态(已定:推倒重来)
> git 历史 `HEAD`(b25e9ec)中有一份旧 M0+M1 实现,但**当前工作区已清空**(仅剩 `.env`、`.env.example`、`.gitignore`)。已确认**推倒重来**:旧实现只作参考,不直接恢复使用。
### 2.1 旧实现可参考点(不复用代码,参考设计)
| 模块 | 值得借鉴的设计 |
| --- | --- |
| 数据模型 | `store/models.go` 已覆盖 §6 全部表结构,字段命名/类型可直接照搬 |
| 代理直通 | 直通模式实现(鉴权 → 余额 → 选渠道 → 透传 → 记账)的链路划分 |
| 记账 | `usage.Recorder` 异步批量落库 + 队列满同步兜底的模式 |
| API Key | SHA-256 哈希存储 + 前缀展示 + 明文一次性展示 |
| 前端 | 页面清单与路由结构可参考;视觉按 taste-skill 重做 |
### 2.2 重做范围(按 §10 里程碑)
- M0 基建、M1 用户+密钥+核心代理:**重做**(可参考旧实现,不复用)
- 其余里程碑(M2–M6):按规划新增
### 2.3 决策记录
| 决策项 | 结论 |
| --- | --- |
| 工作区恢复方式 | **推倒重来**(2026-08-15 确认) |
---
## 3. 技术选型
### 3.1 后端(Go)
| 项 | 选型 | 理由 |
| --- | --- | --- |
| 语言/运行时 | Go 1.23+ | 高并发流式转发、低内存、单二进制部署 |
| Web 框架 | Gin | 生态成熟、中间件丰富;代理层用标准库 `net/http` 做流式读写 |
| ORM | GORM | 简单、迁移内建;模型已按 v0.3 建好 |
| 数据库 | PostgreSQL 15+(开发可 SQLite 起步) | JSON/数组、numeric 精度对计费友好;单存储 |
| 缓存/限流 | Redis 7(起步可内存计数降级) | token bucket 限流、热点、分布式计数器 |
| 认证 | JWT access(2h)+ refresh cookie(7d) | 见 §5.3 |
| 密码 | argon2id | 现代 KDF |
| 配置 | viper + `.env`(`OT_` 前缀) | 密钥进环境变量 |
| 日志 | zap | 结构化日志 + request_id |
| 渠道密钥加密 | AES-GCM(主密钥环境变量) | 落库前加密 |
### 3.2 前端(Vue 3 + Tailwind)
| 项 | 选型 | 理由 |
| --- | --- | --- |
| 框架 | Vue 3 + TypeScript + Vite | 团队栈、构建快 |
| 状态 | Pinia | 官方推荐 |
| 路由 | Vue Router | 标准 |
| 样式 | **Tailwind CSS** + taste-skill 产出的设计 tokens | 见 §8;自建设计系统,不套模板 |
| 组件 | **自建基础组件**(Button/Input/Table/Modal/Toast…)+ 必要 headless 原语 | 贴合设计 tokens,避免重型 UI 库的"模板感" |
| 图表 | ECharts(vue-echarts) | 用量/营收图表,暗色对齐 tokens |
| HTTP | axios + TanStack Query | 缓存、重试、请求状态 |
### 3.3 部署
- Docker Compose 起步:`nginx`(静态资源 + 反代)+ `api`(Go)+ `postgres` + `redis`。
- 单实例起步(记账时序简单),需要时再做多实例(见 §9 风险)。
---
## 4. 系统架构
### 4.1 模块划分
```
┌─────────────────────────────────────────────────────────────┐
│ 前端 web (Vue3 + Tailwind) │
│ Landing / 登录注册 / 控制台(密钥·用量) / 管理后台(渠道·用户·) │
└──────────────────────────┬──────────────────────────────────┘
│ HTTP/JSON(管理 API)
┌──────────────────────────▼──────────────────────────────────┐
│ Go API 服务 │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌────────────────┐ │
│ │ 认证/用户 │ │ API Key │ │ 用量/计费 │ │ 充值(待定) │ │
│ └──────────┘ └──────────┘ └──────────┘ └────────────────┘ │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ API 网关(代理核心) │ │
│ │ Auth/Ratelimit → 余额检查 → 模型解析 → 渠道选择 │ │
│ │ → 格式转换 → 上游调用 → 流式转发 → 记账 │ │
│ └────────────────────────────────────────────────────────┘ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌───────────────┐ │
│ │ 渠道管理 │ │ 负载均衡 │ │ 健康检查 │ │ 重试/故障转移 │ │
│ └──────────┘ └──────────┘ └──────────┘ └───────────────┘ │
└──────────┬──────────────────────────────┬───────────────────┘
│ │
┌───────▼────────┐ ┌────────▼────────┐
│ PostgreSQL │ │ Redis │
│ 用户/密钥/渠道/ │ │ 限流/配额/热点 │
│ 模型/用量/订单 │ │ │
└────────────────┘ └─────────────────┘
```
### 4.2 一次代理请求的完整链路
```
Client Go 网关 上游渠道(如 Anthropic)
│ POST /v1/chat/completions (sk-xxx) │
├──────────────────────────────▶│ │
│ │ 1. 取 Bearer,哈希查 API Key │
│ │ 2. 限流检查(Redis) │
│ │ 3. 余额检查 │
│ │ 4. 解析请求 → 标准中间模型 │
│ │ 5. 按模型选渠道(LB/健康) │
│ │ 6. 转换请求为 Claude 格式 │
│ ├───────────────────────────▶ │
│ │ ◀────────────────────────── │
│ │ 7. 流式/非流式转发+格式转回 │
│ ◀──────────────────────────────│ │
│ │ 8. 异步记账(token→价格→扣费)│
```
关键点:
- **记账异步**:请求完成后写 `usage_logs`,批量落库,不阻塞响应。
- **流式不整体缓冲**:`io.Pipe` 边读上游边写客户端;Token 计数取流结束时的 usage(OpenAI 末块 / Claude `message_delta`)。
- **只转发必要体/头**:`Authorization` 一律替换为渠道 key,不向客户端暴露上游信息。
---
## 5. 核心功能设计
### 5.1 API 网关 / 协议转换
#### 5.1.1 内部统一格式(标准模型)
网关内部使用 **OpenAI Chat Completions 形状**作为"标准中间模型",三套协议都先转成它、再转成目标协议:
```
OpenAI /v1/responses ──┐
OpenAI /v1/chat/completions ─┼──▶ 标准模型(OpenAI chat 形状) ──▶ 各渠道原生格式
Anthropic /v1/messages ──┘
```
新增上游渠道(如 Gemini)只需写**一对**转换器(标准模型 ↔ 渠道格式),而非为每个协议组合写转换器。
#### 5.1.2 转换映射要点
**Chat ↔ Claude Messages**
| 维度 | OpenAI chat ↔ Claude messages |
| --- | --- |
| system | `messages[role=system]` ↔ Claude `system` 参数(支持数组/文本) |
| 消息 | `assistant.tool_calls` ↔ `content` 的 `tool_use` 块;`role=tool` ↔ `tool_result` 块 |
| 工具 | `tools[{type:function,name,description,parameters}]` ↔ `tools[{name,description,input_schema}]` |
| 采样 | `temperature`(OpenAI 0–2,Claude 0–1,按目标协议 clamp)、`top_p` |
| 长度 | `max_tokens` ↔ `max_tokens`(Claude 必填,缺失给默认值) |
| 停止 | `stop` ↔ `stop_sequences`(数组对齐) |
| 流式 | OpenAI SSE `data: {chunk}` + `[DONE]` ↔ Claude 事件流 `message_start / content_block_delta / message_delta / message_stop`,逐事件互转 |
| 用量 | `usage.prompt_tokens/completion_tokens` ↔ `usage.input_tokens/output_tokens`,映射 Claude 缓存 token |
**Responses ↔ Chat**
| Responses 字段 | Chat 对应 |
| --- | --- |
| `instructions` | `messages[0].system` |
| `input[]`(`input_text`/`input_image`/`input_file`) | `messages[]`(user 多模态 content 数组) |
| `input[]` 中 `function_call`/`function_call_output` | `assistant.tool_calls` / `role=tool` |
| `output[]`(`message`/`function_call`/`reasoning`) | `choices[].message` / `tool_calls`(reasoning 跨协议丢弃) |
| `tools[{type:function,...}]` | 结构相同 |
| `output_format`/`text.format` | `response_format` |
| `max_output_tokens` | `max_tokens` |
| `previous_response_id` | 仅直通 OpenAI 可用;跨协议降级(见 5.1.3) |
| `reasoning.effort` | 仅直通或特定渠道,跨协议丢弃 |
| 流式事件 `response.created/output_text.delta/function_call_arguments.delta/response.completed` | chat SSE `data: {delta}` + `[DONE]` |
#### 5.1.3 直通与转换策略
- **直通优先**:客户端协议 = 渠道原生协议时直接透传(仅鉴权/限额/记账),不转格式——保证 Responses 的 `previous_response_id`、`reasoning`、结构化输出零损失。
- **转换路径**:协议不匹配时才经标准模型转换。
- **有损边界(文档明示)**:
- `previous_response_id`、`reasoning.effort` 跨协议降级/丢弃,错误响应中提示。
- Anthropic 渠道不接收 `response_format` 类约束,降级为 prompt 或丢弃。
- Claude thinking 块在 OpenAI 协议侧丢弃。
- **转换标记**:转换过的请求/响应加 `x-converted: true` 头,便于排查。
#### 5.1.4 错误响应统一
按**客户端请求的协议**返回错误体:
- OpenAI:`{"error":{"message","type","param","code"}}` + 映射过的状态码。
- Claude:`{"type":"error","error":{"type","message"}}`。
- 状态码映射:上游 `429` → `429`(附 `retry-after`);上游 `5xx` → 重试后 `502/504`;`400`(含 context 超限)→ 原样;余额不足 → `402`。
### 5.2 渠道系统
| 能力 | 设计 |
| --- | --- |
| 渠道 CRUD | 管理员增删改:名称、**API 类型**(openai/anthropic/compatible)、base_url、上游 key(AES-GCM 加密)、超时、并发上限 |
| API 类型 | 决定原生协议(直通 or 转换)与模型导入方式 |
| 模型导入 | 渠道支持 `GET /v1/models` 时"拉取模型列表"自动导入并绑定;否则手动录入 |
| 模型绑定 | 模型(全局) ↔ 渠道(多个) 多对多,绑定记录 `upstream_model`、权重 |
| 负载均衡 | 权重 + 优先级 + 健康状态选渠道 |
| 健康检查 | 定时用最廉价模型发测试请求,连续失败 N 次进 cooldown,恢复后放回 |
| 重试/故障转移 | 仅对可安全重试的失败(网络错误、429、5xx、超时、上游断开**且未写出响应头**);流式已写出首字节即放弃重试 |
| 并发控制 | 每渠道信号量限最大并发,超限排队或溢出到其他渠道 |
### 5.3 认证与用户
#### 5.3.1 角色
| 角色 | 权限 |
| --- | --- |
| `admin` | 全部;渠道管理、模型定价、用户管理、余额调整、充值审核、全局用量 |
| `user` | 创建/管理自己的 API Key、查询用量、查看余额 |
> 预留 `viewer`(只读运营)角色,首版不做。
#### 5.3.2 会话
- 登录:用户名/邮箱 + 密码(argon2id 校验)。
- 颁发:短时 access(JWT,2h,内存)+ refresh(HttpOnly cookie,7d)。
- 注册:默认 `open`,配置 `registration.mode=invite` 启用邀请码(管理员后台生成)。
#### 5.3.3 API Key
- 格式:`sk-` + 48 位随机 base62,**创建时仅展示一次**。
- 存储:仅 SHA-256 哈希 + 展示前缀(如 `sk-aB3c…`);请求时哈希后查表。
- 附加能力:密钥级配额(每日 token / 请求数)、模型白名单、过期时间、启停。
- 限额检查用 Redis 计数,与用户级限流叠加。
### 5.4 用量与计费
#### 5.4.1 Token 统计
- 优先取上游 usage(OpenAI `usage` / Claude `message_delta.usage`)。
- 缺失时 fallback:本地近似计数(字符/字节估算,或 tiktoken-go 按模型分词)。
- Claude 渠道额外记录 `cache_read_input_tokens`/`cache_creation_input_tokens`。
#### 5.4.2 计价
- 模型注册表(`models`):`input_price`、`output_price`、`cache_read_price`(**每百万 token**)。
- 单次成本 = `in×in_price + out×out_price + cache_read×cache_read_price`(USD 记账,前端按汇率显示)。
- 调价不影响历史:用量表冗余快照价格。
#### 5.4.3 余额与扣费
- 预充值余额制:请求结束后异步扣费并写 `balance_logs`。
- 扣费前检查:余额 ≤ 0 → `402`。可选开关:按模型估算成本超余额即拦截。
- 流式请求进行中不中断(流中途无法停),后续请求被拒。
#### 5.4.4 用量查询
- `usage_logs`:请求级明细(用户/密钥/模型/渠道/token/成本/耗时/状态)。
- 聚合:日粒度预聚合 `usage_daily` 支撑 Dashboard 图表,避免实时扫明细表。
### 5.5 充值(待定,暂缓开发)
> 首版不做,先交付"代理 + 用户 + 计费"。数据模型与订单状态机**先行建好**,方案确定后接入不影响结构。
订单状态机(预留):
```
pending(待审核) ──approve──▶ credited(已入账)
│ │
└──reject──▶ rejected └─(错误入账→adjust 冲正)
```
管理员侧保留"查询充值 / 审核"接口占位。
### 5.6 管理后台
- 渠道管理:增删改、模型绑定、手动测试连接、健康状态查看。
- 模型管理:全局清单、多渠道绑定、价格设置、启停。
- 用户管理:列表/搜索、改角色/状态、调整余额、重置密码。
- 充值审核:待审订单、通过/驳回、流水留痕(后置)。
- 全局用量:跨用户查询、按模型/渠道/天聚合、营收统计。
- 系统配置:开放注册、邀请码、汇率、限流阈值、维护开关。
---
## 6. 数据模型
> 统一 `id` bigint 自增;时间 UTC;金额/价格 `numeric(20,8)`;token `bigint`。以下模型与 git HEAD 中 `store/models.go` 一致(已落地),字段名以代码为准。
### 6.1 users
`id, username UNIQUE, email UNIQUE, password_hash(argon2id), role(user|admin), balance numeric(20,8), status(active|disabled), invite_code?, last_login_at?, created_at, updated_at`
### 6.2 api_keys
`id, user_id FK, name, key_hash UNIQUE(SHA-256), key_prefix, quota_tokens_per_day?, quota_requests_per_day?, allowed_models jsonb?, expires_at?, status(active|revoked), last_used_at?, created_at`
### 6.3 channels
`id, name, provider(openai|anthropic|compatible), base_url, api_key_enc(AES-GCM), weight, priority, timeout_ms, max_concurrency, health_status(healthy|degraded|cooldown), enabled, created_at, updated_at`
### 6.4 models + channel_model_bindings
- `models`:`id, name(全局名如 claude-sonnet-5), display_name, input_price, output_price, cache_read_price(每百万token), enabled, sort`
- `channel_model_bindings`:`id, channel_id FK, model_id FK, upstream_model, weight`
### 6.5 usage_logs(请求级明细,索引 `(user_id, created_at)`)
`id, request_id(上游id), user_id FK, key_id FK, channel_id FK, model_id FK, input_tokens, output_tokens, cache_read_tokens, cache_creation_tokens, input_price, output_price, cache_read_price(快照), cost, latency_ms, status(success|error|canceled), error_code?, created_at`
### 6.6 usage_daily(日聚合)
`id, user_id FK, model_id FK, date, requests, input_tokens, output_tokens, cache_read_tokens, cost`
### 6.7 recharge_orders(预留)
`id, user_id FK, amount, status(pending|credited|rejected), method(manual|online), transaction_id?, reviewed_by FK?, reviewed_at?, remark?, created_at`
### 6.8 balance_logs(余额流水)
`id, user_id FK, change, balance_after, type(recharge|usage|refund|admin_adjust), ref_id?, created_at`
### 6.9 system_configs
`key text PK, value jsonb`
---
## 7. API 设计
### 7.1 代理端点(对外,Bearer API Key 认证)
| 方法 | 路径 | 说明 |
| --- | --- | --- |
| POST | `/v1/responses` | OpenAI Responses API |
| POST | `/v1/chat/completions` | OpenAI Chat 格式 |
| POST | `/v1/messages` | Anthropic Messages(M4 上) |
| GET | `/v1/models` | 可用模型列表(OpenAI 风格) |
### 7.2 管理 API(`/api/v1`,会话认证)
**认证/用户**:`POST auth/register|login|logout|refresh` · `GET auth/me` · `GET user/profile|balance|models`
**API Key**:`GET|POST /keys` · `PATCH|DELETE /keys/:id`
**用量**:`GET /usage/summary` · `GET /usage/stats?from&to&group=day|model` · `GET /usage/logs?from&to&page&model&keyId`
**充值(预留)**:`POST /recharges` · `GET /recharges`
**管理后台(`/api/v1/admin`,仅 admin)**
- `GET|POST|PUT|DELETE /channels` · `POST /channels/:id/test`
- `GET|POST|PUT /models` · `PUT /models/:id/price`
- `GET /users` · `PATCH /users/:id` · `POST /users/:id/balance`
- `GET /recharges` · `POST /recharges/:id/approve|reject`(预留)
- `GET /usage` · `GET /stats/overview`
- `GET|PUT /config`
---
## 8. 前端设计(taste-skill)
### 8.1 设计流程
1. 前端阶段启动时**调用 taste-skill**:传入产品 brief 与页面清单,由它推断设计方向,产出:
- 设计 tokens:色板(含暗/亮色)、字体系统、间距、圆角、阴影、栅格。
- 3–5 个代表页的高保真方向(不一次铺开)。
2. 以 tokens 建立 Tailwind 主题(`tailwind.config` + CSS variables)与基础组件(Button/Table/Form/Modal/Nav)。
3. 按页面清单逐组实现,每阶段结束用 **web-design-guidelines** 复查(对比度、可访问性、交互细节)。
4. 设计评审迭代,**不套模板**。
### 8.2 预期设计方向(taste-skill 最终决定,此处为倾向)
开发者工具 / API 网关类产品:
- 深色优先、仪表盘质感;等宽字体点缀 token、端点、代码片段。
- 数据密度高的表格(用量、密钥、订单),克制的中性色 + 单一强调色。
- Landing 简洁可信:产品价值、端点示例、模型列表预览。
### 8.3 页面清单
| 区域 | 页面 |
| --- | --- |
| 公开 | Landing · 登录 · 注册 |
| 用户 | Dashboard(余额/今日用量/最近请求/图表)· API Keys · 用量查询 · 个人设置 |
| 管理 | 运营总览 · 渠道管理(API 类型 + 模型导入)· 模型与定价 · 用户管理 · 充值审核(后置)· 全局用量 · 系统配置 |
### 8.4 前端工程注意点
- 流式调试体验:控制台页提供"curl / 请求编辑器"快速验证 key 与模型(可选,v2)。
- 图表统一 ECharts,暗色主题对齐 tokens。
- 表格/表单为自建组件,行为一致性优先,可沉淀为内部组件库。
---
## 9. 非功能需求
| 类别 | 要求 |
| --- | --- |
| 安全 | API Key 仅存哈希;渠道密钥加密;密码 argon2id;JWT refresh HttpOnly;日志/错误脱敏(不泄渠道 key、完整 key);CORS 白名单;管理接口二次鉴权 |
| 限流 | Redis token bucket:用户级 + 密钥级 + 全局并发保护 |
| 稳定性 | 渠道 cooldown + 重试;流式 client 断连即取消上游(ctx cancel);上游超时兜底 |
| 可观测 | zap 结构化日志 + request_id;Prometheus 指标(请求数/延迟/错误率/成本);管理后台健康概览 |
| 性能 | 流式零缓冲转发;记账异步批量落库;聚合走预聚合表 |
| 合规 | 用户协议与数据留存说明;退款/冲正流程可追溯 |
---
## 10. 里程碑与任务分解
> 目标:**MVP(M0–M3)先交付**;M4/M5 按需后置。每阶段含验收点。
### M0 基建(◻ 重做,参考旧实现)
配置、启动、DB 迁移、日志、CORS、健康检查、mock 上游。
**验收**:`make run` + `make mock-upstream` 起服务,`/healthz` OK。
### M1 用户 + 密钥 + 核心代理(◻ 重做,参考旧实现)
注册/登录/JWT、API Key、chat/responses/models 直通、基础记账扣费。
**验收**:curl 冒烟(注册→登录→建 key→对话→查用量)。
### M2 前端 MVP + 管理后台基础(✅ 已完成)
- 前端:taste-skill 定 tokens → Tailwind 主题 → 自建组件 → Landing/登录/注册/控制台(Dashboard/Keys/Usage)→ 管理后台(运营总览/渠道/模型/用户/配置)。
- 后端:渠道 CRUD + 测试 + 模型导入、模型管理 + 定价 + 绑定、全局用量/统计接口。
- 已过 web-design-guidelines 复查并修复(移动端侧栏、表格横向滚动、模态框焦点/滚动锁、focus-visible、aria 等)。
**验收**:用户在控制台建 key、发请求、看用量;管理员能加渠道、调价、看统计。
### M3 管理后台前端 + 计费完善(◻ 部分完成)
渠道/模型/用户/总览/配置页面已完成;`usage_daily` 趋势图已内建(自建 SVG)。待做:限流接入、加载骨架屏、按模型聚合报表增强。
### M4 协议转换(✅ 已完成)
- `convert` 包:Chat↔Messages↔Responses 请求/响应 JSON 转换 + 流式 SSE 逐行状态机转换器(含单测)。
- `/v1/messages` 端点;网关按"客户端协议 × 渠道 provider"自动转换,协议匹配直通。
- 流式 usage 合并记账(message_start input + message_delta output);错误体按协议返回。
- mock 上游新增 Anthropic Messages 端点,端到端验证 8 种组合(三协议 × 直通/转换 × 流式/非流式)。
**验收**:chat 调 Claude、messages 调 OpenAI、responses 调 Claude 均正确,流式逐事件转换,usage 记账准确。
### M5 渠道体系完善(◻ 规划)
健康检查、负载均衡、重试/故障转移、并发控制、模型自动导入。
**验收**:杀一个渠道自动切换;连续失败进 cooldown 并恢复。
### M6 充值 + 审核(◻ 待定,接口/模型已预留)
充值订单、人工审核、流水留痕、前端页面。
**验收**:管理员审核充值→余额到账→流水可查。
---
## 11. 仓库结构(规划)
```
openteam/
├── server/ # Go 后端
│ ├── cmd/server/main.go
│ ├── internal/
│ │ ├── config/ # viper + env
│ │ ├── user/ # 认证/角色/用户
│ │ ├── apikey/
│ │ ├── proxy/ # 网关核心
│ │ │ ├── responses/ # OpenAI Responses 格式编解码
│ │ │ ├── openai/ # OpenAI Chat 格式编解码
│ │ │ ├── claude/ # Anthropic Messages 格式编解码
│ │ │ ├── convert/ # 标准模型 ↔ 各协议转换
│ │ │ └── stream/ # SSE/事件流双向转发
│ │ ├── channel/ # 渠道、LB、健康检查、重试
│ │ ├── billing/ # 计价、余额、流水
│ │ ├── usage/ # 记账、聚合
│ │ ├── recharge/ # 订单(待定)
│ │ ├── admin/ # 管理 API
│ │ ├── store/ # GORM models + repositories
│ │ └── pkg/ # jwt, crypto, ratelimit, tiktoken
├── web/ # Vue3 前端
│ ├── src/styles/ # taste-skill 设计 tokens
│ ├── src/components/ # 基础组件
│ ├── src/views/ # 页面(含 admin/)
│ ├── src/stores/ · src/api/ · src/router/
├── deploy/ # docker-compose, nginx, Dockerfile
├── scripts/mockupstream/ # mock 上游(联调)
└── docs/
```
---
## 12. 开放决策项(编码前需确认)
| # | 决策 | 选项 | 结论/倾向 |
| --- | --- | --- | --- |
| 1 | **工作区恢复方式**(§2.3) | 从 git 恢复 / 推倒重来 | ✅ **推倒重来**(已定) |
| 2 | 限流起步 | Redis / 内存计数降级 | MVP 内存起步,Redis 后置 |
| 3 | Token 计数 fallback | 近似估算 / tiktoken-go | 起步近似,精确化后置 |
| 4 | 计费币种 | USD 记账 + 前端汇率 / 人民币 | USD 记账 |
| 5 | 充值方案(M6) | 人工审核 / 在线支付 | 人工审核起步 |
| 6 | 组件基座 | 纯自建 / headless 原语(Ark UI 等) | 纯自建起步 |
---
*本文档 v0.3 由 v0.2 修订:明确 Tailwind + taste-skill 选型、标注 M0+M1 状态、里程碑按"代理/管理/计费"三板块组织、补开放决策项;并已确认**推倒重来**(旧实现仅作参考)。*