跳转到内容

架构

ProxAI 是一个小型本地兼容代理:接收本地 OpenAI 兼容或 Anthropic 风格请求,做协议归一化与必要的跨协议翻译,然后转发到配置好的上游 provider,再把上游响应翻译回客户端期望的协议形态。

理解整个仓库前,先建立两条独立的轴。

Phase 轴描述数据在代理链路里的位置:

  • inbound_request —— 客户端发给 ProxAI 的原始请求
  • provider_request —— ProxAI 准备发给上游 provider 的请求
  • upstream_response —— 上游 provider 返回给 ProxAI 的响应
  • outbound_response —— ProxAI 返回给客户端的响应

Protocol 轴描述某个 phase 使用的线上协议:

  • openai_responses
  • openai_chat_completions
  • anthropic_messages

每个 phase 都有自己的 protocol:

  • inbound_request.protocol = 客户端发的是什么
  • provider_request.protocol = ProxAI 发上游用的是什么,由选中 provider 的 protocol 决定
  • upstream_response.protocol = provider 返回的是什么
  • outbound_response.protocol = ProxAI 返回给客户端的是什么

Provider 名字只是用户标签,不是语义协议标识。

  • 文件夹src/
    • main.rs — 入口,仅转调 cli::main
    • lib.rs AppState、axum Router、proxy handler
    • 文件夹cli/ — 命令行解析与启动流程
    • config.rs config.toml schema 与加载
    • 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 控制面

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).await

run_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_support
  1. 1
    inbound_request
    主要模块
    pipeline/inbound.rsingress/
    职责

    读取 body、检测协议、归一化请求形态、构造 InboundHttpFlow

  2. 2
    路由
    主要模块
    pipeline/inbound.rsrouting/
    职责

    按协议和模型匹配 route,解析默认 provider。

  3. 3
    provider_request
    主要模块
    pipeline/provider_request.rsprovider/requesttranslation/request
    职责

    转换请求 payload、provider 模型重写、body 序列化。

  4. 4
    发送上游
    主要模块
    pipeline/provider_request.rsprovider/transport
    职责

    构造认证 header、拼接上游 URL、通过 reqwest 发送。

  5. 5
    upstream_response
    主要模块
    pipeline/upstream_response.rsupstream/
    职责

    读取状态码、header、非流式 body 或流式 body。

  6. 6
    outbound_response
    主要模块
    pipeline/provider_response.rstranslation/responsetranslation/streaming
    职责

    将响应翻译回入站协议并重建 HTTP 响应。

pipeline/ 使用类型状态 ProxyFlow<S> 串联阶段。每个阶段消费当前 flow state 并返回下一个 state,使阶段顺序显式化。

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,不接收 HTTP Response/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/ 不依赖 HTTP Response/Body 或 provider 私有类型。
  • observe/ 横切 pipeline,但不参与协议或路由决策。

翻译路径由两个 protocol 值决定:

  • ingress/ 检测出的 inbound request_protocol
  • 选中 provider 配置的 protocol

规则:

  • 协议相同:不做协议转换,直接通过。
  • 协议不同:进入 translation/<inbound_protocol>/to_<provider_protocol>/
  • 未实现的协议对显式失败。
  • 协议特定请求/响应数据优先用按 protocol 区分的顶层 enum 包装。
  • 避免平行 protocol / payload / projection / summary 字段漂移成不可能状态。
  • 流跨过 HTTP 载体边界后保持为 ByteStream
  • provider 名字与 protocol 名字保持分离。