跳转到内容

架构

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 解析与编码基础工具
    • sse_translation.rs — SSE bytes 与结构化 translation events 之间的应用层适配器
    • formatting.rs — 通用格式化工具
    • 文件夹error/ — 领域错误类型与渲染
      • …
    • 文件夹http_support/ — HTTP 载体工具
      • …
    • 文件夹provider/ — provider request projection/序列化、响应观测与 HTTP transport
      • …
    • 文件夹upstream/ — 上游响应读回
      • …
    • 文件夹pipeline/ — 类型化代理 pipeline,包含 HTTP ingress 适配
      • …
    • 文件夹observe/ — 捕获、日志、诊断
      • …
    • 文件夹mcp/ — MCP 控制面
      • …
  • 文件夹crates/
    • 文件夹proxai-core/
      • 文件夹src/
        • 文件夹ingress/ — 与 carrier 无关的入站归一化与校验
          • …
        • 文件夹pipeline/ — 组合 ingress、routing、translation 与 provider adaptation 的 carrier-independent façade
          • …
        • 文件夹protocol/ — 各协议 wire 类型与协议枚举
          • …
        • 文件夹routing/ — 编译后的协议/模型路由与 provider 标签选择
          • …
        • 文件夹provider/ — 与 carrier 无关的 provider request preparation 与响应/错误归一化
          • …
        • 文件夹translation/ — 与 carrier 无关的跨协议转换
          • …

HTTP ingress、provider projection/序列化、transport lookup 和 SSE carrier adaptation 留在 src/。proxai-core::pipeline 把结构化 ingress、provider 标签路由、provider request/response adaptation 与 translation 组合成可复用的 Value/StreamEvent façade。

src/lib.rs 注册这些路由,并统一进入同一个 proxy handler:

/v1/responses /responses
/v1/chat/completions /chat/completions
/v1/messages /messages

入站侧简化流程:

let prepared_provider = inbound_http
.parse_inbound()? // 应用:path + JSON bytes
.prepare_provider_request( // core:ingress + route + translate + adapt
&state.core_pipeline,
&state.providers,
)?;
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
    主要模块
    src/pipeline/inbound.rsproxai-core/pipeline/proxai-core/ingress/
    职责

    应用层读取 body bytes、检测协议并解析 JSON;core pipeline 归一化和校验结构化请求。

  2. 2
    路由
    主要模块
    pipeline/provider_request.rsproxai-core/pipeline/proxai-core/routing/
    职责

    Core 解析 provider 标签、协议、compatibility policy 与 upstream model,再选择应用层 transport。

  3. 3
    provider_request
    主要模块
    pipeline/provider_request.rsproxai-core/pipeline/proxai-core/translation/requestproxai-core/provider/requestprovider/request
    职责

    Core 返回准备好的 provider value 和匹配的 response pipeline,再由应用层提取诊断 projection 并序列化 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.rssse_translation.rsproxai-core/pipeline/proxai-core/translation/responseproxai-core/translation/stream
    职责

    通过 ResponsePipeline 执行结构化响应 normalization 与 translation,在事件和 SSE bytes 之间适配、观测失败并重建 HTTP。

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

proxai-core/protocol/

Core crate 的协议 wire shape 与共享协议枚举。只建模 JSON,不做转换,不依赖 HTTP 载体。

src/pipeline/inbound.rs

HTTP path 检测、JSON bytes 解析,以及结构化 core preparation 前的 carrier 错误映射。

proxai-core/ingress/

与 carrier 无关的结构化请求归一化、校验、模型提取和类型化 ingress observations。

proxai-core/pipeline/

组合 ingress、routing、request preparation、response normalization 与 translation 的可复用结构化 façade。

proxai-core/observe/

共享 `Observer` contract、封闭的 `Observation` variants 和 no-op 默认实现;不包含具体 sink。

proxai-core/routing/

根据请求协议、模型模式、默认值和 route 配置选择 provider 标签,不依赖 carrier。

proxai-core/provider/

与 carrier 无关的 provider request value preparation、响应 compatibility policy、结构化 response/event 与 error-payload normalization 和类型化 adaptation observations。

proxai-core/translation/

Core crate 在显式协议 pair 之间做请求、响应与结构化事件转换,暴露 `Translator` façade,并通过共享 `Observer` 发出类型化 observations。

provider/

Provider projection/summary 提取、request 序列化、响应观测、认证 header、上游 URL 构造和 transport。

upstream/

读取上游状态码、headers、完整 body 或流式 byte carrier。

sse_translation.rs

应用层 carrier 适配器:把 SSE bytes 解析成 `StreamTranslationInput`,调用 core `ResponsePipeline`,保留原始失败现场,再编码回 SSE。

http_support/

协议无关的 HTTP 工具,例如 content-type 检测、响应重建和 boxed byte stream。

observe/

Capture artifact、结构化日志、request hints 和隐私友好的诊断。

error/

领域错误类型与面向客户端的响应渲染。

  • proxai-core/protocol/ 是底层 wire 建模:只描述 JSON shape,不做转换。
  • proxai-core/ingress/ 接收结构化 JSON value,负责协议归一化和校验,绝不接收 HTTP body bytes。
  • src/pipeline/inbound.rs 是负责 path 检测和 JSON bytes 解析的应用 adapter。
  • proxai-core/pipeline/ 组合完整结构化 request/response 路径并绑定 request-scoped core observer,但不拥有 transport。
  • src/pipeline/ 围绕 core façade 协调 HTTP carrier 与 transport,并保持 phase 顺序显式。
  • proxai-core/provider/ 负责与 carrier 无关的 provider request value preparation、响应 compatibility policy、结构化 response/event 与 error-payload normalization 和类型化 adaptation observations。
  • proxai-core/translation/ 与 carrier 无关:Translator 只接收 JSON Value 或结构化 StreamEvent,不接收 HTTP response/body、SSE bytes 或 provider 私有结构。
  • sse_translation.rs 是 upstream byte stream 与 core provider/translation API 之间的应用层适配器,负责保留触发失败的原始 frame 和 SSE 输出编码。
  • provider/ 负责应用侧 provider projection/summary、request 序列化、响应观测和 transport 细节,例如认证 header、上游 URL 和 idle-read timeout。
  • proxai-core/observe/ 定义共享 Observer contract 和封闭的 Observation enum。Core ingress、provider normalization 与 translation 发出类型化 variants;src/observe/ 提供下游实现,并负责日志、诊断和 capture。
  • 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 --> core_pipeline[proxai-core/pipeline/]
core_pipeline --> core_ingress[proxai-core/ingress/]
core_pipeline --> core_provider[proxai-core/provider/]
core_pipeline --> routing[proxai-core/routing/]
pipeline --> provider[provider/]
pipeline --> upstream[upstream/]
pipeline --> sse_translation[sse_translation.rs]
core_pipeline --> translation[proxai-core/translation/]
pipeline --> observe[observe/]
pipeline --> http_support[http_support/]
pipeline --> error[error/]
core_ingress --> protocol[proxai-core/protocol/]
core_provider --> protocol
translation --> protocol
provider --> protocol
upstream --> http_support
provider --> http_support
sse_translation --> http_support
sse_translation --> sse[sse.rs]
sse_translation --> core_pipeline
upstream --> sse
observe --> error
lib --> observe
lib --> error

关键规则:

  • proxai-core/protocol/ 是底层 wire 建模。
  • proxai-core/ingress/ 是入站归一化与校验的结构化 value 边界;src/pipeline/inbound.rs 适配 HTTP bytes 和应用诊断。
  • proxai-core/provider/ 是 provider 响应 compatibility 的结构化边界。
  • proxai-core/pipeline/ 是 carrier-independent composition root;src/pipeline/ 协调 HTTP 生命周期并把选中的 provider 标签映射到 transport。
  • proxai-core/translation/ 只依赖协议模型、结构化 value/event 和 core observation contract,不依赖 HTTP、SSE bytes、provider transport 或具体应用观测实现。
  • sse_translation.rs 把 byte carrier 适配到 core ResponsePipeline;应用 pipeline 负责诊断和客户端错误渲染。
  • observe/ 实现核心 observation trait,但不参与协议或路由决策。

Translator 根据两个 protocol 值选择翻译路径:

  • pipeline/inbound.rs 检测出的 inbound request_protocol
  • 选中 provider 配置的 protocol

规则:

  • 协议相同:不做协议转换,直接通过。
  • 协议不同:进入 crates/proxai-core/src/translation/<inbound_protocol>/to_<provider_protocol>/。
  • 未实现的协议对显式失败。

Translator 是唯一公开的 façade,直接持有所选 route 与 observation hook。每个入口会派生一个绑定 phase 的 TranslationScope:request、non-streaming response 或 streaming response。Scope 是显式、operation-local 的依赖,禁止做成全局、thread-local 或 task-local 状态;只有可能发出 adapted / dropped 的语义投影路径才接收它,纯转换和 outbound constructor 保持 scope-free。Pair code 因此无需在 observation 调用中单独传 phase,也就不可能把一次操作的遥测误记到其他 pipeline phase。Value translation 借用派生出的 scope;structured stream translation 消费 Translator,把 streaming-response scope 移入返回的 stream,并在其中惰性创建私有、封闭的 PairStreamingState,其恰好包含六种跨协议状态机之一,或 identity 路径。这样 value-only translation 不会分配无用流状态,同时 pair state 也不可能被跨 stream 复用。TranslationRoute 与 TranslationScope 定义位于 façade 下层的 translation/context.rs;顶层分发和 pair code 只接收 &TranslationScope,因此 dispatch、phase 与 observation 不可能对当前操作产生分歧。协议无关的 event、error、terminal、identity 与 lifecycle 类型集中在无外部依赖的 translation/stream.rs。Pair 只依赖 context.rs 与 stream.rs,Translator 再依赖这些底层和 pair state,所有依赖边保持单向。Carrier adapter 只调用 Translator::translate_stream,不再直接驱动 pair event 或 terminal handling。

  • 协议特定请求/响应数据优先用按 protocol 区分的顶层 enum 包装。
  • 避免平行 protocol / payload / projection / summary 字段漂移成不可能状态。
  • 核心 streaming API 保持 StreamEvent in/out;ByteStream 只存在于应用 carrier 层。
  • provider 名字与 protocol 名字保持分离。