summaryrefslogtreecommitdiff
path: root/README.md
diff options
context:
space:
mode:
Diffstat (limited to 'README.md')
-rw-r--r--README.md66
1 files changed, 60 insertions, 6 deletions
diff --git a/README.md b/README.md
index 96d2540..50be52b 100644
--- a/README.md
+++ b/README.md
@@ -15,6 +15,11 @@ AIGW 是一个轻量、无状态的 AI API 中转后端。当前阶段聚焦上
- `Authorization: Bearer` 和 `x-api-key` 客户鉴权
- 统一 JSON 错误、`X-AIGW-Request-ID`、Prometheus 文本指标
- 非阻塞用量事件,包含租户、项目、模型、上游、尝试次数、耗时和 token 用量
+- PostgreSQL 预付余额、请求额度冻结、实际 token 结算和不可变账本
+- Stripe 托管 Checkout 充值、签名 Webhook 与事件/订单双重幂等
+- PostgreSQL Usage Ledger、月度项目汇总和单请求成本追溯
+- 平台/租户控制台令牌、六种 RBAC 角色和管理 API 审计日志
+- 项目级 RPM、估算 TPM、并发限制和月度消费配额
## 快速运行
@@ -83,12 +88,13 @@ curl http://127.0.0.1:8080/anthropic/v1/messages \
## 生产边界
-当前版本可以作为第一阶段的数据面,但还不是完整商业计费平台:
+当前版本可以作为带预付计费的数据面,但上线前仍需完成业务侧对账:
-- 用量事件写到结构化日志,队列满时会丢弃并增加 `aigw_usage_events_dropped_total`。正式扣费前必须替换为持久、幂等的账本写入或消息队列。
+- 控制面计费模式会把 UsageEvent、冻结记录和扣费流水同步、幂等写入 PostgreSQL;异步结构化日志只是可观测副本,丢弃不会影响账本。
- 客户密钥和模型目录在控制面模式下从 PostgreSQL 载入到原子内存快照;Redis 只是可选的变更广播加速层,故障时通过 PostgreSQL generation 轮询收敛。
- 当前只把 OpenAI 入口发给 OpenAI 兼容上游、Anthropic 入口发给 Anthropic 兼容上游,不做跨协议转换。
- 自动故障转移可能在极少数网络错误下造成上游重复执行。正式计费时需要上游幂等能力、请求去重策略和重复成本对账。
+- 上游必须返回 usage 才能按 token 结算;未返回 usage 的成功响应当前记为零费用,应在上生产前为每个供应商做账单对账或补充 token 计算器。
- `/metrics` 应仅在内网暴露;公网 TLS、WAF 和连接层限速应放在负载均衡器或边缘代理。
## PostgreSQL + Redis 控制面
@@ -100,12 +106,60 @@ curl http://127.0.0.1:8080/anthropic/v1/messages \
开发环境可以直接启动:
```bash
-export AIGW_CREDENTIAL_KEY="$(openssl rand -base64 32)"
-export AIGW_ADMIN_TOKEN="$(openssl rand -hex 32)"
+./scripts/start-debug.sh
+```
+
+脚本会首次生成仅当前用户可读的 `.env.debug`,构建并等待 PostgreSQL、Redis 和网关健康,然后打印后台地址和管理员 token。关闭调试服务:
+
+```bash
+./scripts/stop-debug.sh
+```
+
+关闭脚本保留 PostgreSQL/Redis 数据卷,下一次启动仍可继续使用已有控制面数据。需要测试 Stripe Checkout 时,先把 `.env.debug` 中两个 Stripe 占位值替换成测试环境 restricted key 和 Webhook signing secret。
+
+源码未变化时可跳过镜像构建以快速重启:`AIGW_DEBUG_SKIP_BUILD=1 ./scripts/start-debug.sh`。默认构建使用 Docker host network;特殊环境可以通过 `AIGW_DOCKER_BUILD_NETWORK=default` 覆盖。
+
+然后打开 `http://127.0.0.1:8080/admin/`,输入脚本打印的 `AIGW_ADMIN_TOKEN`。这个 token 是平台管理员的 bootstrap/break-glass 凭证;日常操作应在 Team 页面签发数据库控制台令牌。第一套资源的创建顺序是:Tenant → Project → API key → Provider → Model route。客户 API Key 和控制台令牌的明文都只在创建成功时返回一次。
+
+控制台角色分为:`platform_admin`、`platform_viewer`、`tenant_admin`、`tenant_billing`、`tenant_developer`、`tenant_viewer`。租户角色的查询条件在服务端下推到 PostgreSQL,不能读取其他租户的项目、密钥、余额、Usage 或审计事件;供应商凭证和路由管理只对平台角色开放。
+
+## Usage、配额与限流
+
+每个完成上游尝试的请求都会按 `request_id` 幂等写入 `usage_events`,并更新 `usage_monthly_rollups`。Usage 持久化独立于预付费冻结记录,因此关闭计费也不会关闭用量账本。Admin WebUI 提供本月汇总、单请求状态、模型、token、成本、未收金额和延迟查询。
+
+Limits 页面按项目配置:
+
+- `requests_per_minute`:固定分钟窗口请求数,`0` 表示不限。
+- `tokens_per_minute`:请求体约算输入 token 加显式/默认最大输出 token,`0` 表示不限。
+- `concurrent_requests`:从进入上游前到响应复制完成的并发 lease,`0` 表示不限。
+- `monthly_spend_micros`:PG 事务内检查当月已计成本和未结冻结,`0` 表示不限。
+
+Redis 可用时,RPM/TPM/并发通过 Lua 原子执行并在多实例间共享;Redis 故障时自动退回本机计数,服务继续可用,但降级期间限制是“每实例”而不是“全局”。Redis 恢复后新请求会自动重新使用分布式计数。启用预付计费时,月度消费配额和余额由 PostgreSQL 保证,不依赖 Redis。
+
+## 余额与 Stripe 充值
+
+模型价格在后台按“币种单位 / 100 万 token”配置,数据库使用 `amount_micros` 固定精度整数保存金额。推理请求会先按请求体字节数和 `max_tokens`/`max_completion_tokens` 保守冻结额度;成功响应按上游返回的输入、输出和缓存 token 结算,失败请求释放冻结。`request_id` 是用量与扣费幂等键。
+
+Stripe 使用托管 Checkout,服务端不会接触卡号,也没有硬编码支付方式;支付方式由 Stripe Dashboard 动态配置。充值只在签名校验通过的 Webhook 确认 `payment_status=paid` 后入账,成功跳转页不会直接修改余额。
+
+配置 Stripe 测试环境:
+
+```bash
+cp .env.control.example .env
+# 将 AIGW_STRIPE_API_KEY 设为最小权限的 rk_test_ restricted key
+# 本地转发会显示 whsec_...,填入 AIGW_STRIPE_WEBHOOK_SECRET
+stripe listen --forward-to http://127.0.0.1:8080/billing/stripe/webhook
docker compose up --build
```
-然后打开 `http://127.0.0.1:8080/admin/`,输入 `AIGW_ADMIN_TOKEN`。第一套资源的创建顺序是:Tenant → Project → API key → Provider → Model route。创建客户 API Key 时,明文只在成功响应中出现一次。
+Webhook 至少订阅:
+
+- `checkout.session.completed`
+- `checkout.session.async_payment_succeeded`
+- `checkout.session.async_payment_failed`
+- `checkout.session.expired`
+
+当前没有默认启用 Stripe Tax,因为是否有有效税务注册不能由代码推断。确认注册和税务处理方案后再显式加入 `automatic_tax`。生产环境应把 Stripe restricted key 和 Webhook signing secret 放入云平台的密钥管理服务,并限制密钥权限和来源 IP,不要放进镜像或仓库。
生产环境建议把 `auto_migrate` 改为 `false`,先执行:
@@ -113,7 +167,7 @@ docker compose up --build
AIGW_DATABASE_URL="postgres://..." go run ./cmd/migrate
```
-管理 API 仅使用一个 bootstrap token,应该放在内网、VPN 或反向代理后。下一阶段需要把它替换为管理员用户、角色和审计日志。
+管理 API 支持 bootstrap token 和数据库控制台令牌。即使已经启用 RBAC,管理监听端口仍应放在内网、VPN 或身份感知反向代理后;bootstrap token 应只用于首次建号和故障恢复。
完整的扩展边界见 [架构说明](docs/architecture.md)。