架构
ProxAI 是一个小型本地兼容代理:接收本地 OpenAI 兼容或 Anthropic 风格请求,做协议归一化与必要的跨协议翻译,然后转发到配置好的上游 provider,再把上游响应翻译回客户端期望的协议形态。
理解整个仓库前,先建立两条独立的轴。
Phase 轴
Section titled “Phase 轴”Phase 轴描述数据在代理链路里的位置:
inbound_request—— 客户端发给 ProxAI 的原始请求provider_request—— ProxAI 准备发给上游 provider 的请求upstream_response—— 上游 provider 返回给 ProxAI 的响应outbound_response—— ProxAI 返回给客户端的响应
Protocol 轴
Section titled “Protocol 轴”Protocol 轴描述某个 phase 使用的线上协议:
openai_responsesopenai_chat_completionsanthropic_messages
每个 phase 都有自己的 protocol:
inbound_request.protocol= 客户端发的是什么provider_request.protocol= ProxAI 发上游用的是什么,由选中 provider 的protocol决定upstream_response.protocol= provider 返回的是什么outbound_response.protocol= ProxAI 返回给客户端的是什么
Provider 名字只是用户标签,不是语义协议标识。
顶层源码结构
Section titled “顶层源码结构”文件夹src/
- main.rs — 入口,仅转调
cli::main - lib.rs —
AppState、axumRouter、proxy handler 文件夹cli/ — 命令行解析与启动流程
- …
- config.rs —
config.tomlschema 与加载 - paths.rs — 应用目录解析
- request.rs — 共享请求载体类型
- sse.rs — SSE 基础工具
- formatting.rs — 通用格式化工具
文件夹error/ — 领域错误类型与渲染
- …
文件夹http_support/ — HTTP 载体工具
- …
文件夹ingress/ — 入站协议解析与归一化
- …
文件夹protocol/ — 各协议 wire 类型与协议枚举
- …
文件夹routing/ — 路由匹配
- …
文件夹provider/ — provider 请求构造与 HTTP transport
- …
文件夹upstream/ — 上游响应读回
- …
文件夹translation/ — 跨协议转换
- …
文件夹pipeline/ — 类型化代理 pipeline
- …
文件夹observe/ — 捕获、日志、诊断
- …
文件夹mcp/ — MCP 控制面
- …
- main.rs — 入口,仅转调
请求生命周期
Section titled “请求生命周期”src/lib.rs 注册这些路由,并统一进入同一个 proxy handler:
/v1/responses /responses/v1/chat/completions /chat/completions/v1/messages /messages入站侧简化流程:
let prepared_provider = inbound_http .prepare_inbound()? // ingress: 解析 + 归一化 .route_to_provider(...)? // routing: 选择 provider .prepare_provider_request()?; // provider/request + translation
run_provider_flow(prepared_provider).awaitrun_provider_flow 串联 provider 侧流程:
let provider_http = prepared_provider .send_to_upstream().await? // provider/transport + upstream .handle_upstream_response().await?; // upstream: 读取 body / stream
provider_http.translate_to_outbound().await? // translation + http_supportPipeline 阶段
Section titled “Pipeline 阶段”- 1
inbound_request主要模块pipeline/inbound.rsingress/职责读取 body、检测协议、归一化请求形态、构造
InboundHttpFlow。 - 2路由主要模块
pipeline/inbound.rsrouting/职责按协议和模型匹配 route,解析默认 provider。
- 3
provider_request主要模块pipeline/provider_request.rsprovider/requesttranslation/request职责转换请求 payload、provider 模型重写、body 序列化。
- 4发送上游主要模块
pipeline/provider_request.rsprovider/transport职责构造认证 header、拼接上游 URL、通过
reqwest发送。 - 5
upstream_response主要模块pipeline/upstream_response.rsupstream/职责读取状态码、header、非流式 body 或流式 body。
- 6
outbound_response主要模块pipeline/provider_response.rstranslation/responsetranslation/streaming职责将响应翻译回入站协议并重建 HTTP 响应。
pipeline/ 使用类型状态 ProxyFlow<S> 串联阶段。每个阶段消费当前 flow state 并返回下一个 state,使阶段顺序显式化。
模块职责地图
Section titled “模块职责地图”protocol/协议 wire shape 与共享协议枚举。只建模 JSON,不做转换,不依赖 HTTP 载体。
ingress/入站协议检测、解析与归一化,发生在 routing 和 translation 之前。
routing/根据请求协议、模型模式、默认值和 route 配置选择 provider。
translation/在显式协议 pair 之间做纯请求、响应与流式转换。
provider/Provider 请求渲染、模型改写、认证 header、上游 URL 构造和 transport。
upstream/读取上游状态码、headers、完整 body 或流式 byte carrier。
http_support/协议无关的 HTTP 工具,例如 content-type 检测、响应重建和 boxed stream。
observe/Capture artifact、结构化日志、request hints 和隐私友好的诊断。
error/领域错误类型与面向客户端的响应渲染。
protocol/是底层 wire 建模:只描述 JSON shape,不做转换。pipeline/协调完整请求生命周期,并保持 phase 顺序显式。translation/在 HTTP 载体边界保持纯粹:接收 protocol 值和 payload/stream carrier,不接收 HTTPResponse/Body或 provider 私有结构。provider/负责 provider 请求渲染和 transport 细节,例如认证 header、上游 URL 和 idle-read timeout。observe/横切 pipeline 做诊断,但不参与 routing 或 protocol 决策。- 语义层 stream/HTTP 错误应使用领域错误,不要隐藏进
std::io::Error。
flowchart TD cli[cli/] --> lib[lib.rs AppState] config[config.rs] --> lib paths[paths.rs] --> cli lib --> pipeline[pipeline/]
pipeline --> ingress[ingress/] pipeline --> routing[routing/] pipeline --> provider[provider/] pipeline --> upstream[upstream/] pipeline --> translation[translation/] pipeline --> observe[observe/] pipeline --> http_support[http_support/] pipeline --> error[error/]
ingress --> protocol[protocol/] translation --> protocol provider --> protocol upstream --> http_support provider --> http_support translation --> http_support ingress --> sse[sse.rs] upstream --> sse translation --> sse observe --> error lib --> observe lib --> error关键规则:
protocol/是底层 wire 建模。pipeline/是知道完整请求生命周期的协调者。translation/不依赖 HTTPResponse/Body或 provider 私有类型。observe/横切 pipeline,但不参与协议或路由决策。
翻译路径选择
Section titled “翻译路径选择”翻译路径由两个 protocol 值决定:
ingress/检测出的 inboundrequest_protocol- 选中 provider 配置的
protocol
规则:
- 协议相同:不做协议转换,直接通过。
- 协议不同:进入
translation/<inbound_protocol>/to_<provider_protocol>/。 - 未实现的协议对显式失败。
数据类型约定
Section titled “数据类型约定”- 协议特定请求/响应数据优先用按 protocol 区分的顶层 enum 包装。
- 避免平行
protocol/payload/projection/summary字段漂移成不可能状态。 - 流跨过 HTTP 载体边界后保持为
ByteStream。 - provider 名字与 protocol 名字保持分离。