Restore provider-owned identity profiles, credential refresh, cache routing, model catalogs, and runtime configuration across OpenAI and xAI without compatibility paths. Keep deployment configuration, frontend visibility, and architecture documentation aligned with the finalized multi-provider boundary. Co-authored-by: Codex <noreply@openai.com>
11 KiB
Codex Proxy RS 架构
本文是仓库唯一架构文档,只描述当前架构。
1. 系统边界
Codex Proxy RS 是单进程、可多副本部署的多 Provider AI 网关:
- 客户端面提供 OpenAI Responses 兼容的 JSON、SSE、WebSocket 与模型目录协议。
- 管理面提供
/api/admin/*和 Vue 静态管理端。 - 当前 Provider 为 OpenAI 与 xAI;账号 credential 均由所属 Provider 独占解释。
- OpenAI 行为以重构前正式实现为语义基准;xAI/Grok 行为以
grok2api验证结果为基准。 - 两个 Provider 的请求画像都由启动配置提供基线,并通过进程级共享状态向每次新请求发布一致快照。OpenAI CLI、OpenAI Desktop 与 xAI CLI 的官方版本检查会分别原子更新自己负责的版本字段。
- OpenAI CLI 使用官方 npm 包
@openai/codex,OpenAI Desktop 使用官方 appcast,xAI CLI 使用官方 npm 包@xai-official/grok。检查失败保留上一份成功画像;检查成功后 OAuth、catalog、quota/billing、inference 与 Dashboard 自动采用最新版本。 - PostgreSQL 是业务与配置事实的唯一权威存储。
- Redis 只保存可丢失、可重建或有自然过期时间的协调状态。
Gateway Engine 不识别具体 Provider 协议;Provider 不拥有客户端 admission、跨 instance 路由或业务重试预算。
2. Workspace 与依赖方向
backend/
├── apps/gateway/ composition root、HTTP server、后台任务
├── crates/gateway-core/ operation、routing、engine、policy、accounting
├── crates/gateway-protocol/ 可共享 wire contract 与 canonical event
├── crates/gateway-admin/ 管理领域、用例与抽象端口
├── crates/gateway-store/ PostgreSQL、Redis adapter
├── crates/gateway-api/ OpenAI Responses 与 Admin HTTP adapter
├── crates/gateway-host/ host/update/system 能力
├── crates/providers/openai/ OpenAI credential、catalog、transport
├── crates/providers/xai/ xAI/Grok credential、catalog、transport
└── migrations/0001_initial.sql 唯一终态初始迁移
依赖规则:
gateway-core不依赖 HTTP、数据库、Redis 或具体 Provider。gateway-protocol不依赖其他 workspace crate。- Provider crate 之间禁止互相依赖。
gateway-api只面向 Admin/Core/Protocol 抽象,不导入具体 Provider。gateway-store实现 Admin/Core 端口,但不拥有业务策略。- 只有
apps/gateway组合具体实现。
各 crate 的 architecture 测试强制验证 crate 集合、依赖 DAG、生产源码边界与测试树。
3. 请求执行链
API decode/auth
-> freeze RuntimeSnapshot
-> compile RoutePlan
-> admission
-> persist model_request
-> select Provider instance/account
-> persist attempt facts in model_request
-> cross upstream send barrier
-> canonical stream
-> persist downstream delivery barrier
-> terminal observation and accounting
核心不变量:
- 每个客户端请求只有一条
model_requests;attempt 明细保存在其 JSON 事实中,不另建 attempt 表。 - 任何可能到达上游的调用都必须先有持久请求事实。
not_sent、sent、ambiguous是不同的上游发送边界;ambiguous不自动重放。downstream_committed_at表示网关已作出不可撤回的交付承诺,从该时刻禁止 retry/fallback;它在实际首字节写出前持久化,不宣称字节已经到达客户端。- Provider 每次
execute只能选择一个 credential 并准备一个 cold stream,不得隐藏换号或业务 retry。 - 下游 commit 前,Core 可按冻结策略处理同 instance 账号 fallback 和同 Provider kind 的 instance fallback;禁止跨 Provider kind fallback。
- 本架构不通过隐式连接复用承载业务身份。HTTP client 可安全复用 transport 连接,但账号、credential revision、cookie/session binding 必须显式绑定到本次调用。
4. 路由、fallback 与错误处理
RuntimeSnapshot 冻结 Provider instance、模型能力、账号候选、运行时策略和全局 config_revision。一次请求始终使用同一快照,不在执行中拼接新旧配置。
Fallback 层级固定为:
- 同一 Provider instance 内更换可用账号。
- 同一 Provider kind 内切换 instance。
- 不跨 Provider kind。
明确的上游认证、封禁、额度或 cooldown 错误会更新对应账号状态,使下一次选择排除该账号;满足重放安全条件且尚未 downstream commit 时,可以换号。传输结果不明确时不得假定请求未到达上游。
重试矩阵属于独立策略,本次终态迁移保持 OpenAI 原正式行为与 xAI 参考行为,不在 Provider transport 内增加额外重试。
5. Continuation
系统只保存已被上游确认的安全外部 ID:model_requests.upstream_response_id,不新增 conversation、transcript、continuation 或 claim 表。
store=true:使用 Provider 持久化的 native handle。store=false:opaque replay state 仅存在于活连接内,不落 PostgreSQL。- OpenAI continuation 顺序为 native、replay owner、replay any。
- xAI 使用客户端提交的完整历史作为已验证 continuation 路径。
- continuation 失败仍受 send barrier、downstream commit 和 Provider kind 边界约束。
6. Provider 与 credential owner
Provider 接收 canonical Operation + ProviderCandidate + AttemptContext,返回携带冻结 metadata 的 canonical cold stream。Registry 使用稳定 ProviderKind 查找实现。
Provider 独占以下职责:
- credential 文档的编码、解码与校验;
- OAuth 登录、导入、刷新与轮换;
- 账号选择所需的 Provider 私有事实;
- catalog 查询与能力编译;
- HTTP/WebSocket transport 和错误分类;
- quota 投影与 Provider 私有观测字段。
credential 更新使用 credential_revision CAS。认证永久失败、封禁、额度耗尽和带截止时间的 cooldown 是账号运行时事实。cooldown 到期后,Core 的有效调度谓词会自然允许账号重新参与选择;Redis cooldown 只是热缓存。成功调用后才可把账号状态重新观测为 ready。
refresh_token_expires_at 不是公共 SQL 列或 Core 权威状态。xAI 可在 provider_credentials_json 内保存它作为 Provider 私有提示;真正失效以 refresh endpoint 返回的永久错误为准。
7. 控制面与 revision
管理写入使用 expected_config_revision 做全局乐观并发控制。会改变调度快照或安全配置的写入,必须在同一 PostgreSQL 事务中:
- 校验 expected revision;
- 执行业务 mutation;
- 推进
runtime_settings.config_revision; - 写入脱敏
admin_audit_events。
推进全局 revision 的 mutation 包括 runtime settings、Provider instance、客户端 Key、账号导入/创建/删除、管理员显式启停和管理员 credential rotation。
不推进全局 revision 的运行时观测包括 quota、cooldown、catalog generation、请求统计以及自动 credential refresh;自动 refresh 只推进 credential_revision。提交后 Redis 通知只负责缩短其他副本的收敛延迟,周期性 PostgreSQL 对账才是正确性基础。
8. PostgreSQL 终态
backend/migrations/0001_initial.sql 创建且只创建八张业务表:
| 表 | 权威事实 |
|---|---|
admin_users |
管理员身份与密码摘要 |
admin_audit_events |
管理 mutation 审计 |
client_api_keys |
客户端鉴权、限额与授权范围 |
runtime_settings |
全局配置与 config_revision |
provider_instances |
Provider endpoint 与公开配置 |
provider_accounts |
账号资料、加密 credential、revision、quota、cooldown |
model_requests |
请求、attempt、计费、交付与恢复事实 |
ops_events |
脱敏运行事件 |
设计规则:
- 一个事实只存一次;可表达关系使用真实 FK 与支持索引。
- Provider 差异只进入受 schema/version 校验的 JSONB 边界。
- secret 只保存加密 envelope;日志、Debug、API 和 audit 不输出 secret。
- stale recovery 只把超时
running请求收敛为incomplete,不重放业务请求。 ops_events当前逐条同步持久化,occurrence_count=1;OpsFlush 可禁用,不存在隐藏内存聚合权威。- retention 只删除已满足保留规则的历史事实,不改变运行中请求。
业务 schema 由唯一初始迁移 0001_initial.sql 定义。
9. Redis 终态
Redis 保存 admission、lease、circuit/cooldown 热状态、OAuth pending flow 与 runtime change 通知。Redis 丢失后必须从 PostgreSQL 或 Provider 事实恢复;恢复完成前需要保护的 acquire 路径 fail closed。
OAuth pending key:
codex-proxy-rs:oauth-pending:v1:{provider_kind}:{flow_fingerprint}
flow_fingerprint = SHA-256(provider_kind || 0x00 || raw_flow_binding)
Hash 字段恰好为:
owner_fingerprintexpires_at_epoch_secondsprovider_payload
create/take 使用 Lua 原子执行。owner mismatch 不删除记录;匹配 owner 的 take 返回 payload 并一次性删除。OpenAI TTL 为 10 分钟,xAI TTL 为 30 分钟。
10. 后台任务与恢复
后台任务由 Provider bundle 和 host bundle 显式贡献,bootstrap 统一启动:
- RuntimeSnapshot revision 对账与 Redis change wake-up;
- credential refresh、catalog、quota 等 Provider worker;
- stale execution recovery;
- retention 与必要的 Redis 热状态重建;
- host update/system worker。
worker 不得通过导入 Admin use case 绕过边界,也不得维护第二份业务状态。
11. 测试与验收
- 生产
src禁止#[cfg(test)]、#[path]和include!测试挂载。 - 测试位于各 package 的
tests/,目录镜像生产模块。 - Core 规则使用确定性测试;Provider 使用 contract/fixture 测试。
- FK、CAS、revision、recovery 使用真实 PostgreSQL 测试。
- admission、lease、cooldown、OAuth pending 使用真实 Redis 测试。
- 真实账号测试只从仓库外部文件读取,不打印、复制或提交凭证。
真实对话测试是显式 ignored 的生产边界测试,必须依次穿过 Provider 导入/必要刷新、实时 catalog、账号 selector、生产 HTTP/SSE transport、canonical 解码、usage 与 completed 终态。xAI 用例允许 OAuth refresh token 轮换,因此必须额外显式授权:
CODEX_REAL_ACCOUNT_FIXTURE=/outside/cpr-accounts.json \
cargo test -p provider-openai --test main \
admin::real_openai_conversation_crosses_production_provider_boundaries \
-- --ignored --exact
XAI_REAL_ACCOUNT_FIXTURE=/outside/grok-accounts.json \
XAI_ALLOW_DESTRUCTIVE_FIXTURE_REFRESH=1 \
cargo test -p provider-xai --test main \
admin::real_xai_conversation_crosses_production_provider_boundaries \
-- --ignored --exact
终态门禁:
cd backend
cargo fmt --all -- --check
cargo test --workspace --all-targets