LiteLLM Rust 核心五 Crate 架构与路由模块规范:深入 litellm-rust 工作区
本文基于仓库中的 litellm-rust/AGENTS.md 及其配套文档,系统讲解 LiteLLM Rust 实现(litellm-rust)的五 crate 工作区划分、无环依赖方向、顶层路由(route)模块的目录组织规范、新增 crate 的约束机制,以及 Rust 风格约定。读完本文,你可以准确理解 litellm-rust 的分层设计意图,知道一个顶层 LiteLLM 调用在 Rust 侧由哪些文件承接、新 provider/路由应放在哪里,以及如何通过内置的 workspace 校验测试与 CI 检查约束代码结构。
工作区总览:五个 Crate,各司其职
litellm-rust 是 LiteLLM 的 Rust 核心实现工作区。litellm-rust/AGENTS.md 开宗明义地定义了一条核心原则:
一个 crate 是一个"层"(layer)或"共享基础"(shared foundation),而不是一条路由(route)。
路由(如 ocr、realtime、chat)和 provider(如 mistral、openai)都是层内部的模块,不是独立的 crate。工作区恰好由以下五个 crate 组成(该表格为原文档的核心内容,逐条继承):
| Crate | 角色 |
|---|---|
litellm-core |
Rust 版 LiteLLM SDK。每个顶层调用一个公开入口(如 messages::messages()),拥有类型定义、请求/响应转换、provider 解析、鉴权以及 provider HTTP 调用本身。"调用它,拿到类型化响应。" |
litellm-config |
配置加载边界(config-loading boundary)。返回解析后的核心部署数据,可选地把加载过程委托给 Python。 |
litellm-ai-gateway |
axum 服务器(位于 server feature 之后)加 WebSocket hosts。负责把 HTTP/WS 请求翻译为 core 入口调用;不拥有任何 provider 逻辑,也不持有 handler。 |
litellm-python-interop |
领域无关(domain-neutral)的 PyO3 基础层,负责 GIL 处理与类型化的 Python/Serde 转换。 |
litellm-python-bridge |
暴露 LiteLLM Rust API 给 Python SDK 的 PyO3 cdylib。拥有 API 注册、领域接线和 Python 异常映射。 |
无环依赖方向
原文档明确了五个 crate 之间的依赖方向,且保证无环(acyclic):
litellm-config ──依赖──▶ litellm-core
litellm-ai-gateway ──依赖──▶ litellm-config + litellm-core
litellm-python-bridge ──依赖──▶ 领域层(core/config/ai-gateway) + litellm-python-interop
litellm-python-interop 不依赖任何 LiteLLM 领域 crate
这一点可以从 litellm-rust/Cargo.toml 中得到直接印证:workspace 的 members 恰好列出 crates/core、crates/config、crates/ai-gateway、crates/python-interop、crates/python-bridge 五项(resolver = "2")。各 crate 的实际依赖声明与上述方向完全一致:
- litellm-rust/crates/config/Cargo.toml:
litellm-config依赖litellm-core,并通过可选 featurepython = ["dep:pyo3"]支持把配置加载委托给嵌入式 Python 解释器; - litellm-rust/crates/ai-gateway/Cargo.toml:
litellm-ai-gateway同时依赖litellm-core(开启bedrock-authfeature)与litellm-config,axum 0.7 是可选依赖(featureserver),二进制litellm-ai-gateway声明了required-features = ["server"]——即"服务器代码藏在 feature 之后"在构建系统层面就得到了强制; - litellm-rust/crates/python-bridge/Cargo.toml:
crate-type = ["cdylib"]、库名_native,依赖三个领域层与litellm-python-interop,pyo3 0.29 并默认启用abi3-py310,印证其"cdylib 边界"定位; - litellm-rust/crates/python-interop/Cargo.toml:仅依赖
pyo3、pythonize、serde,不含任何 LiteLLM 领域 crate,满足"interop 不依赖领域层"的约束。
此外,workspace 级配置值得注意:litellm-rust/Cargo.toml 声明 edition = "2024"、rust-version = "1.88",网络栈统一为 reqwest 0.12(default-features = false 并显式启用 rustls-tls),release profile 采用 opt-level = 3、lto = "thin"、codegen-units = 1 与 strip = "symbols"——这是一套面向发布轮子(portable wheels)与 Linux 镜像的完整构建优化。
路由(Route)在哪里:core/src/<route>/ 参考结构
litellm-rust 中,一个顶层 LiteLLM 调用对应 crates/core/src/<route>/ 下的一个模块,原文档以 messages(Anthropic Messages 调用,即 Python litellm.messages() 的 Rust 等价物)为参考样板,规定了如下文件布局:
core/src/messages/
mod.rs # pub async fn messages(..) -> CoreResult<..> (+ messages_stream for SSE)
types.rs # 请求/响应类型,如 MessagesRequest
transformation.rs # provider 模板 trait
prepare.rs # provider 解析、鉴权头、URL
handler.rs # provider 调用
client.rs # 共享的 reqwest 客户端
从 litellm-rust/crates/core/src/messages/ 的实际文件列表可以看到,真实目录与规范完全吻合(另有一个 tests.rs 单元测试文件),并额外多出一个 common_utils.rs。入口函数在 litellm-rust/crates/core/src/messages/mod.rs 中一目了然:
pub async fn messages(request: MessagesRequest<'_>) -> Result<AnthropicMessagesResponse, Error> {
execute_messages_provider_call(request).await
}
pub async fn messages_stream(request: MessagesRequest<'_>) -> Result<reqwest::Response, Error> {
execute_messages_provider_stream(request).await
}
两个要点与原文档呼应:
- 同步/流式成对出现:非流式的
messages()返回类型化响应;messages_stream()返回上游的reqwest::Response原始流,由 host(网关)自行拼接(splice)到其调用者——这正是"core 拥有整个调用、host 只做翻译"的边界在 API 形状上的体现; - 入口即语义:模块的公开函数与路由同名(
messages、messages_stream),与配套文档 litellm-rust/CLAUDE.md 中"route 级结构与 Python 侧职责镜像"的描述一致。
原文档还说明:handlers never live in ai-gateway。历史遗留的 ocr、audio_transcription、realtime 路由此前仍托管在 ai-gateway 中,规则是"每次触碰它们时就将其搬入 core"。从 litellm-rust/crates/core/src/ 的当前目录结构可以看到迁移已在推进:audio_transcription/ 已完整落入 core(含 client.rs、handler.rs、mod.rs、prepare.rs、tests.rs、transformation.rs、types.rs),而 ocr/、realtime/ 也已存在于 core 下(目前文件较少,可推断迁移仍在进行中)。
provider 侧的组织则镜像 Python 的 provider 树:core/src/providers/<provider>/<route>/transformation.rs。例如 litellm-rust/crates/core/src/providers/anthropic/messages/transformation.rs 承接 Anthropic Messages 的 provider 专属转换,azure_ai、bedrock、mistral、openai、reducto、vertex_ai 等 provider 目录均按同一形状组织(详见 litellm-rust/README.md 的 Layout 一节)。
新增 Crate 的约束:默认加模块,加 crate 必须"过审"
原文档给出了两条硬性规则:
-
默认加模块。新增 crate 必须有真实触发条件,且只能是以下四类之一:
- 独立的构建产物(binary / cdylib);
- proc-macro crate;
- 共享基础层(shared foundation);
- 可独立发布的 standalone crate。
"一个新的 provider 或路由"不属于任何一类触发条件。
-
机制兜底:allowlist 测试。原文档明确写道:
Adding a crate fails
crates/core/tests/workspace_crate_allowlist.rsuntil you update its allowlist and this file — intentional.即:一旦有人擅自新增 crate,测试 litellm-rust/crates/core/tests/workspace_crate_allowlist.rs 会立即失败,迫使其同时更新该测试的 allowlist 与
AGENTS.md,并在评审中为"为什么要新 crate"给出正当理由——这是一个刻意为之的结构性防呆设计。从该测试源码可以确认其实现方式(workspace_crate_allowlist.rs):
const EXPECTED_MEMBERS: &[&str] = &[ "crates/core", "crates/config", "crates/ai-gateway", "crates/python-interop", "crates/python-bridge", ];它包含两个测试函数:
workspace_members_match_allowlist手工解析 workspaceCargo.toml的members = [...]数组(刻意只用 std、不引入 toml crate)与期望集合比对;crates_directory_matches_allowlist扫描crates/目录,仅把"内含Cargo.toml的子目录"计为 crate,因此crates/CODING_STANDARDS/这类纯文档目录不会触发误报。失败信息中直接写明了整改要求:"update this allowlist AND litellm-rust/AGENTS.md, and justify the crate"。
core 的职责边界:允许与禁止
litellm-core "拥有整个调用"这一条规则,在 litellm-rust/CLAUDE.md 的 Core Boundary 一节被展开为允许/禁止清单,是理解 AGENTS.md 中 crate 分工的直接依据:
允许出现在 core 中:
- 顶层 LiteLLM 调用的公开入口函数;
- 请求/响应转换与流 chunk 归一化;
- provider 解析、鉴权头构建、URL 拼接;
- 通过共享复用客户端(带 connect 与请求超时)执行 provider HTTP 调用本身;
- 共享数据类型与校验错误;
- 确定性的 token/成本辅助逻辑。
禁止出现在 core 中:
- 提供 HTTP 服务(axum 路由、extractor、传输层关注点归 host);
- 文件系统访问、数据库访问;
- 配置文件读取与 rollout 状态;
- 日志回调、花费(spend)写入或自定义回调;
- 全局可变运行时状态。
一个细节值得注意:core 中被允许的唯一环境变量读取,是各路由 prepare.rs 中的凭据兜底(env_lookup 闭包)——镜像 Python SDK 在未传入 key 时从环境变量取 key 的行为;其余一切配置形态的东西都由 host 解析后传入。
此外,AGENTS.md 与 CLAUDE.md 共同界定了 rollout 策略:在 Rust 逐步引入期间,rollout 状态与 fallback 由 Python 持有,Rust 路径默认关闭,直到 parity 测试证明与 Python 等价;新 provider/路由也允许选择 rust-only 实现(无 Python 参照),但必须在 PR 中显式声明。
风格规范:rustfmt 默认风格 + 官方 Rust Style Guide
原文档 Style 一节的规则可以归纳为三点:
- litellm-rust/ 下所有 Rust 代码遵循官方 Rust Style Guide。
rustfmt默认实现的就是该指南的格式化规则,因此提交前必须运行cargo fmt,且 CI 对每个 PR 执行cargo fmt --check门禁; - 禁止与 rustfmt 对着干:不要手工格式化出与 rustfmt 不同的结果,也不要添加偏离默认风格的
rustfmt.toml——"默认风格就是指南本身"; - rustfmt 无法自动应用的命名与习惯约定需人工遵循:
snake_case:项、函数、模块;UpperCamelCase:类型、trait、枚举变体;SCREAMING_SNAKE_CASE:常量与静态变量;缩写按一个单词处理,例如HttpClient而非HTTPClient;- 遵循指南规定的 import 分组(std / 外部 / 本 crate)与 item 排序;
- 对过长的表达式,优先重构结构而非强行丑陋换行。
配套的 litellm-rust/CLAUDE.md 给出完整的 Checks 清单,与 GitHub Actions 对 litellm-rust/ 变更执行的检查一致,推送前应在本地运行:
cd litellm-rust
cargo fmt --check
cargo clippy --workspace --all-targets -- -D warnings
cargo clippy -p litellm-core --all-targets --features bedrock-auth -- -D warnings
# ai-gateway 的二进制与服务端代码在 `server` feature 之后
cargo clippy -p litellm-ai-gateway --all-targets --all-features -- -D warnings
cargo test --workspace
cargo test -p litellm-core --features bedrock-auth
# `auth`、`routes`、`state`、`realtime` 测试仅存在于 `server` feature 下
cargo test -p litellm-ai-gateway --features server
这套命令本身也再次印证了 feature 划分:bedrock-auth 是 core 的可选 feature(引入 aws-sigv4 等依赖做 SigV4 签名),server 是 ai-gateway 的可选 feature(引入 axum、subtle、sha2),测试必须与 feature 配套运行。
小结:从文档到代码的设计闭环
litellm-rust 的结构规范形成了一个完整的"文档—代码—测试"闭环:
- AGENTS.md 声明意图:五 crate、无环依赖、route 目录形状、crate 触发条件、风格规则;
- Cargo.toml 固化结构:workspace members、feature 门控(
server、bedrock-auth、python)在构建层面落实分层; - 测试强制守门:workspace_crate_allowlist.rs 用零依赖的 std 扫描,把"crate 集合恰好是五个"变成一条可执行的测试断言;
- CI 收敛风格:
cargo fmt --check与 clippy-D warnings对所有 PR 生效,消除格式化与 lint 上的自由度。
对于要在这个工作区中新增 provider、路由或接口的开发者,操作路径因此非常明确:先在 core/src/providers/<provider>/<route>/transformation.rs 与路由模块中按 messages 样板落模块(而非新 crate),遵守 Core Boundary 的允许/禁止清单,然后跑完上述 Checks 清单再推送。这正是该仓库"crate 是层、模块才是增长单位"这一核心设计原则在日常开发中的落地方式。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0624
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00