03 第3周D17 项目立项
D17 项目立项:Mini LLM 网关 + 计费系统
D17 项目立项:Mini LLM 网关 + 计费系统
精讲(第 4 周开战动员)。四个学员组成一个"团队",每人一个模块,用 Claude Code 开发,做一个复刻 sub2api 核心逻辑的迷你项目。今天只做一件事:定分工、定接口契约、定数据模型。
教学目标(学完能做什么)
- 明确自己负责的模块、职责边界、依赖关系
- 能读懂并共同评审接口契约文档(前后端/上下游的对接口头)
- 定稿数据模型,理解"契约先行"的开发协作方式
前置要求
- D7-D16 全部(项目是综合演练)
本模块在业务中的位置
- 这就是"小号 sub2api":A=网关代理、B=计费引擎、C=管理面板、D=部署。四人各自交付一个模块再合起来跑通,就是一次真实的工程协作演习。
内容分段
1. 项目目标与验收
- 目标:用 Python/FastAPI + Postgres + Vue3 + Docker 复刻"网关代理 + token 计费"核心链路。
- 整体验收:客户用一个 API key 调
POST /v1/chat/completions→ 正常返回 → 计费扣款 → 面板能看到余额变化与流水。D23 答辩演示这条链路。 - 范围克制:不做生产级(安全/高并发可简化),正确性与协作完整优先。
2. 四模块分工与依赖
| 学员 | 模块 | 职责 | 依赖 | 关键产出 |
|---|---|---|---|---|
| A | 代理服务 (FastAPI) | OpenAI 兼容 /v1/chat/completions;Bearer 鉴权;转发上游 Claude(流式);调用 B 计费 | 调 B | proxy/ 服务 |
| B | 计费引擎 (FastAPI+Postgres) | 用户/Key/定价表;verify 与 deduct 接口(幂等);流水;RPM 限流 | — | billing/ 服务 |
| C | 管理面板 (Vue3) | 用户/充值/余额/流水/用量 页面 | 调 B(admin) | panel/ 前端 |
| D | 部署与 CI/CD (Docker) | 三服务 Dockerfile + compose;一键启动;联调脚本;集成部署 | A/B/C | deploy/ + README |
- 依赖关系一句话:
A → B(业务)、C → B(管理)、D把三者打包。
3. 接口契约(今天定稿,开发期就是"法律")
B 提供给 A 的内部接口(A 必需)
POST /internal/verify
body: { "api_key": "sk-..." }
resp: { "valid": true, "user_id": 1, "group": "default",
"balance": 9.87000000 }
POST /internal/deduct # 幂等!按 request_id 去重
body: { "request_id": "abc123", "user_id": 1,
"model": "claude-sonnet-5",
"input_tokens": 120, "output_tokens": 45 }
resp: { "ok": true, "cost": 0.00018, "balance_after": 9.86982000 }B 提供给 C 的管理接口(C 必需)
GET /admin/users → 用户列表(含余额)
POST /admin/users { "name": "alice" } → 创建(生成 api_key)
POST /admin/users/{uid}/recharge { "amount": 10 } → 充值
GET /admin/bills?user_id=1 → 流水
GET /admin/models → 模型定价表A 对外暴露(D 联调时用)
POST /v1/chat/completions
headers: { "Authorization": "Bearer <api_key>" }
body: OpenAI 兼容格式(model/messages/max_tokens/stream)
resp: OpenAI 兼容格式 + usage- 契约评审规则:字段名/类型/状态码/幂等性/错误结构,今天逐条过;有分歧当场定,之后改契约要全体同意。
4. 数据模型定稿(B 的 Postgres)
CREATE TABLE users (
id BIGSERIAL PRIMARY KEY,
name TEXT NOT NULL,
api_key TEXT NOT NULL UNIQUE,
balance NUMERIC(20,8) NOT NULL DEFAULT 0, -- 金额必须 NUMERIC
group_name TEXT NOT NULL DEFAULT 'default',
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE TABLE models (
id BIGSERIAL PRIMARY KEY,
name TEXT NOT NULL UNIQUE,
input_price NUMERIC(20,10) NOT NULL, -- $ / 1K input tokens
output_price NUMERIC(20,10) NOT NULL
);
CREATE TABLE bills (
id BIGSERIAL PRIMARY KEY,
request_id TEXT NOT NULL UNIQUE, -- 幂等去重键
user_id BIGINT NOT NULL REFERENCES users(id),
model TEXT NOT NULL,
input_tokens BIGINT NOT NULL,
output_tokens BIGINT NOT NULL,
amount NUMERIC(20,8) NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX idx_bills_user ON bills(user_id);- 设计要点回顾(D11/D15):金额 NUMERIC、request_id 幂等、流水原始凭证、索引。
5. 模块启动清单(今天下午各人做)
- A:读 D13/D14,明确转发用哪个练习端点;画 A→B 调用时序。
- B:把数据模型 SQL 写出来;设计 verify/deduct 的幂等逻辑。
- C:列页面清单与要调的 B 接口字段。
- D:搭三服务目录骨架 + compose 草稿;写联调脚本思路。
- 产出统一放
docs/training/项目/下,PR 提交设计文档。
6. 协作规则(第 4 周生效)
- 每天早上站会(5 分钟):昨天做了什么 / 今天做什么 / 卡在哪。
- 分支:每人自己的 feature 分支;联调合入
project-main(由 D 指挥)。 - 契约变更必须群里@全员 + 更新契约文档。
- 全用 Claude Code 开发,遵守 D16 方法论:生成→看懂→验证→提交。
讲解节奏建议(约 90 分钟)
| 时段 | 内容 |
|---|---|
| 09:00-09:20 | 项目目标与验收(演示 D23 要跑通的长什么样) |
| 09:20-09:45 | 四模块分工与依赖(白板画) |
| 09:45-10:40 | 接口契约逐条过(重点,全员评审) |
| 10:40-11:00 | 数据模型定稿 |
| 11:00-11:30 | 各人认领 + 模块启动清单 |
| 11:30-12:00 | 评审与答疑 |
常见误区汇总
| 误区 | 正确理解 |
|---|---|
| 各自闷头开发最后再对接 | 契约先行,今天定稿,开发期按契约走 |
| 扣费接口不考虑重试 | deduct 必须幂等(request_id 去重),否则重试双重扣费 |
| 金额用 float 无所谓 | NUMERIC,项目里同样要守住 |
| 改契约随意 | 改契约要全体同意 + 更新文档 |
| 项目要做得像生产系统 | 范围克制,正确性与协作完整优先 |