ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

LiteLLM Rust 工作区开发规范:crate 分层、core 边界与生产级质量标准

LiteLLM Rust 工作区开发规范:crate 分层、core 边界与生产级质量标准 LiteLLM Rust 工作区开发规范crate 分层、core 边界与生产级质量标准【免费下载链接】litellmThe fastest, litest AI Gateway. Rust core with Python SDK. Call 100 LLM APIs in OpenAI (or native) format with cost tracking, guardrails, load balancing, and logging [Bedrock, Azure, OpenAI, Anthropic, OpenAI, VertexAI, vLLM, Nvidia NIM]项目地址: https://gitcode.com/GitHub_Trending/li/litellm本篇技术指南围绕 litellm-rust/CLAUDE.md 这一规则文件展开系统讲解 LiteLLM 项目中 Rust 侧的代码组织方式litellm-core/litellm-ai-gateway/litellm-python-bridge/litellm-python-interop四个 crate 的职责划分、路由模块的标准目录结构、core层的准入与禁入清单、生产级测试与健壮性要求、网络 I/O 规范、常量管理与风格约定以及提交前必须通过的完整检查命令。读完后你将能够按照该项目的规范理解或参与 Rust 调用链路如messages()的开发并知道如何在 Rust 与 Python 双栈之间正确地分配逻辑与测试责任。这份规则文件在 LiteLLM 中的定位LiteLLM 的官方定位是 The fastest, litest AI Gateway——以 Rust 核心加 Python SDK 的形式用 OpenAI或原生格式调用 100 多家 LLM API并附带成本追踪、护栏、负载均衡与日志能力。在这一架构中Rust 代码集中在 litellm-rust 目录而 litellm-rust/CLAUDE.md 开篇即明确它的性质这是 LiteLLM 中 Rust 工作的规则定义文件This file defines the rules for Rust work in LiteLLM它面向的是在本仓库中写 Rust 代码的工程师以及 AI Agent。文件的核心内容可以分为六块Provider Coding Standards——如何扩展已有的 provider 抽象禁止复制粘贴Crates——四个 crate 的角色与依赖方向详见 litellm-rust/AGENTS.mdCore Boundary——litellm-core拥有整次调用明确列出允许/禁止放入 core 的能力清单Production Bar——从第一个 PR 起就执行的 parity 与健壮性标准Network I/O Rules——所有执行网络 I/O 模块的统一规则Rust Style Guide / Constants / Checks——风格、常量管理与提交前检查命令。以下逐节展开并结合仓库中的实际源码印证这些规则如何落地。Provider 编码标准先找基类禁止复制实现文档的第一节给出的原则非常直接写新逻辑之前先找可以扩展的既有基类。文档原文列举了 Rust 与 Python 两侧共用的共享抽象位置provider 的BaseConfig转换类位于litellm/llms/base_llm/共享辅助函数位于litellm_core_utils/带类型的 request/response 模型工厂函数。标准操作流程是先用搜索找到基类然后通过继承或组合来添加新变体只覆盖真正有差异的部分模型名、参数映射、鉴权方式。文档对此有两条硬性禁令绝不把现有实现复制一份再就地修改绝不手工为基类已提供的逻辑另写一个平行版本。文档还给出了一个判断抽象是否合格的可操作标准If you catch yourself writing a second copy of a pattern that exists twice already, stop and extract a base instead... The test for a good abstraction is that adding the next provider is a few declarative lines, not a new file of duplicated flow.即当你发现自己写了第二个重复模式时停下来做提取——把共享形态收敛到一处让两个调用点都变成它的薄变体。一个好的抽象意味着新增一个 provider 只需几行声明式代码而不是一个新文件的流程复制。若行为确实不同而必须偏离基类必须在 PR 中显式说明。这个原则在 Rust 侧有直接对应物。litellm-rust/crates/core/src/messages/transformation.rs 中定义了 provider 模板 traitAnthropicMessagesProviderConfigcomplete_url、resolve_api_key、auth_strategy、default_headers、transform_request、transform_response全部带有默认实现例如default_headers默认返回anthropic-version: 2023-06-01和content-type: application/jsontransform_request/transform_response默认原样透传。这正是文档所倡导的形态——新增一个 provider 时只需实现真正差异化的 URL 构造或鉴权策略其余走默认值。crate 布局crate 是分层不是路由文档的 Crates 一节交叉引用 litellm-rust/AGENTS.md定义了四个 crate 及其职责Crate角色litellm-coreRust 版的 LiteLLM SDK真正发起 LLM 调用litellm-ai-gateway位于其前的 HTTP/WebSocket 服务器litellm-python-bridge向 Python SDK 暴露 Rust 能力的 PyO3 桥接层litellm-python-interop存放被 Python 面向的 Rust 代码共享的领域中立 PyO3 基础原语关键设计判断是这句A crate is a layer or shared foundation, not a route; add modules, not crates.crate 代表分层或共享基础而不是某个具体路由。新增 provider 或路由时默认加模块而不是新建 crate。AGENTS.md 对依赖方向做了补充依赖图必须无环——litellm-python-bridge依赖领域层与litellm-python-interop而 interop 基础层不依赖任何 LiteLLM 领域 crate。AGENTS.md 还指出随意新增 crate 会被crates/core/tests/workspace_crate_allowlist.rs测试直接拦截除非同步更新其白名单与文档——这是用测试强制架构约束的务实做法。从 litellm-rust/crates 目录结构可以看到这四个 crate 物理对应为core/、ai-gateway/、python-bridge/、python-interop/与规则文件描述完全一致。Core 边界litellm-core拥有整次调用公开入口messages()是 Rust 版litellm.messages()文档给出了一条最重要的边界声明litellm-coreowns the whole call。Rust 中与 Pythonlitellm.messages()等价的入口就是litellm_core::messages::messages(request).await——你调用它它完成 provider 调用你拿回一个带类型的非流式响应。litellm-rust/crates/core/src/messages/mod.rs 的实现与文档描述逐字对应pub async fn messages(request: MessagesRequest_) - ResultAnthropicMessagesResponse, Error { execute_messages_provider_call(request).await } pub async fn messages_stream(request: MessagesRequest_) - Resultreqwest::Response, Error { execute_messages_provider_stream(request).await }模块头部的注释也复述了同样的契约入口负责解析 provider、转换请求、调用 provider、返回带类型的非流式响应流式变体messages_stream则把上游原始响应交还给宿主host由宿主把事件流拼接给自己的调用方。路由模块的标准目录结构文档规定路由级的 Rust 结构镜像 Python 侧 LiteLLM 的职责划分。core/src/route/端到端拥有一个路由包含以下固定文件core/src/messages/ # 参考实现 mod.rs # 以路由命名的公开入口函数 route_stream 流式变体 types.rs # 请求/响应类型 transformation.rs # provider 模板 trait prepare.rs # provider 解析、鉴权头、URL 构造 handler.rs # 真正执行 provider 调用的 handler client.rs # 共享的 HTTP 客户端实际的 litellm-rust/crates/core/src/messages 目录mod.rs、types.rs、transformation.rs、prepare.rs、handler.rs、client.rs另加common_utils.rs与tests.rs正是这一结构的范本。文档同时点名provider 专属转换逻辑位于core/src/providers/provider/route/transformation.rsAnthropic Messages 的对应文件就是core/src/providers/anthropic/messages/transformation.rs——该路径在 litellm-rust/crates/core/src/providers 下可见anthropic/、openai/、bedrock/、vertex_ai/、mistral/、azure_ai/、reducto/等目录均遵循provider/route/两级布局。Handler 归属规则宿主永远不碰 provider文档对三个 crate 的分工画了硬线handler 只存在于core。ai-gateway不得包含任何与 provider 对话的路由 handler——它的 axum 路由只做三件事读 HTTP 请求、挑选部署、调用core的入口函数python-bridge只负责 marshal Python 对象并调用同一个 core 入口流式场景保持同样形态路由入口在core中提供route_stream变体返回上游响应以便宿主拼接宿主依然不持有任何 provider 逻辑调用钩子与生命周期埋点阶段计时、usage 累计、回调 payload 构造一律在core宿主把观测到的事件喂给 core再把完成的 payload 通过自己的 I/O logger 分发宿主不得拥有回调编排。文档还披露了迁移现状ocr、audio_transcription、realtime三个路由仍暂驻ai-gateway属于该规则生效前的遗留正在逐步搬入 core 的路由模块——规则要求不要在那里新增且触碰一个就优先搬一个。从 litellm-rust/crates/core/src 目录可见audio_transcription/、ocr/、realtime/模块已经出现在 core 下印证了这场搬迁正在进行。core 的准入与禁入清单文档把 core 的边界写成了两张明确的清单允许出现在core顶层 LiteLLM 调用的公开入口请求/响应转换与流式 chunk 规范化provider 解析、鉴权头构造、URL 构造通过共享复用客户端带 connect 与请求超时发起的 provider HTTP 调用本身共享数据类型与验证错误确定性的 token/cost 辅助逻辑禁止出现在coreHTTP 服务本身axum 路由、extractor、传输层关注点留在宿主文件系统访问数据库访问配置文件读取与 rollout 状态日志回调、spend 写入、自定义回调全局可变运行时状态对于读环境变量这个灰色地带文档给出了一条精确的豁免core中读环境变量的唯一合法场景是路由prepare.rs内的凭证兜底即env_lookup闭包与 Python SDK 在调用方没有传 key 时的行为保持一致其余一切配置形态的东西都由宿主解析后传入。litellm-rust/crates/core/src/messages/prepare.rs 是这条规则的教科书式落地let config messages_provider_config(provider) .ok_or_else(|| Error::InvalidProvider(provider.to_string()))?; let env_lookup |key: str| std::env::var(key).ok(); let headers validate_environment(config, request.extra_headers, request.api_key, env_lookup)?; // ... transform_request - serialize - complete_url let url config.complete_url(request.api_base, model, env_lookup)?;prepare_provider_request完整走完了文档描述的职责链provider 解析get_custom_llm_provider→ 取 provider 配置 → 用env_lookup闭包做鉴权头校验validate_environment中若调用方已通过authorization或 provider 指定的 header 完成鉴权则跳过否则走config.resolve_api_key支持Bearer与自定义 header 两种策略→ 类型化请求转换 → 序列化 →complete_url。环境变量的读取被收敛在一个闭包里注入配置对象而不是散落在各处直接std::env::var。Python 拥有 rollout 状态Rust 路径默认关闭关于 Rust 引入期间的责任划分文档的规则是rollout 状态与 fallback 归 Python 所有在 Rust 引入过程中如此Rust 路径必须默认关闭直到 parity 测试证明与 Python 等价例外通道新的 provider/路由可以直接以 rust-only 实现没有 Python 参考实现此时 Python 接口是一个无 fallback 的薄分发且必须在 PR 中显式声明这是 rust-only 选择无论哪条路Python 侧都保持最小化只做输入 marshal 与调用 Rust 接口绝不按路由加 feature flag绝不把 provider 分发推进litellm/main.py而是放在litellm/llms/provider/route/下的薄分发类里。生产标准Production Bar从第一个 PR 起就执行文档的 Production Bar 一节列出了 Rust 代码的 parity 与健壮性硬性标准正确性 parity 用测试证明。镜像 Python 行为的移植不得依赖 README 声称或人工目检每个 provider 转换都必须有单元测试覆盖五个维度受支持参数的过滤、请求体形状、响应规范化、缺失/null 字段、坏输入错误当 Rust 通过 Python 暴露时必须补充 Python 测试证明三种行为disabled、enabled、bridge 不可用时的 fallback避免对用户/provider 输入 panic——返回类型化错误由宿主负责映射成 Python 异常或 HTTP 响应OCR 会处理含个人数据的文档不得记录文档内容、base64 payload、provider 响应体或 secret错误信息要有用但数据最小化任何上游响应体在跨越宿主边界前先截断或清洗空串或纯空白凭证、URL、配置值在宿主/配置解析层一律视为缺失有意识地保持 Python 输出形状若某字段为了与 Python 对齐而总是序列化为null要留一行简短注释解释这个 parity 选择。这些要求在源码中都能找到对应物。例如数据最小化litellm-rust/crates/core/src/constants.rs 中定义了UPSTREAM_ERROR_BODY_MAX_CHARS: usize 256注释明确写道上游错误体回显跨越调用边界前截断到多少字符使 provider body 有界且数据最小化——与 Production Bar 中truncate or sanitize any upstream body before it crosses a host boundary逐句对应空凭证视为缺失prepare.rs 的validate_environment先检查调用方是否已携带鉴权头未携带才走resolve_api_key把空值处理收敛在配置解析层保持 Python 输出形状constants.rs 中的EMPTY_TEXT_PLACEHOLDER常量注释直接引用了 Python 侧的出处litellm/litellm_core_utils/prompt_templates/factory.py中的_EMPTY_TEXT_PLACEHOLDER说明这是为了与 Python 行为保持一致而保留的占位符——正是文档要求留注释解释 parity 选择的实例类型化错误而非 panicmessages模块的公共 API 全部返回Result_, Error见 mod.rs错误类型由 core 定义宿主负责映射。网络 I/O 规则对所有发起网络请求的模块生效文档明确这些规则适用于每一个执行网络 I/O 的模块——无论是core的路由 handler还是ai-gateway这类宿主必须设置 connect 超时和整请求超时不允许无限等待复用 HTTP 客户端不得每请求新建客户端优先 rustls TLS以获得可移植的 Python wheel 与 Linux 镜像除非有文档记录的相反理由在宿主层添加请求 ID 与结构化 tracing同时不记录 OCR 文档内容或 secret不得向调用方回显原始上游响应体必须清洗并设置上界避免在服务启动路径和请求路径上使用expect/unwrap除非可以证明该 panic 在构造上不可能且已文档化。超时规则在源码中的落点是 constants.rsAnthropic Messages 与 chat completions 各有 600 秒整请求超时上限MESSAGES_TIMEOUT_SECS、CHAT_COMPLETIONS_TIMEOUT_SECS注释注明镜像 Python 侧默认值调用方的 per-request 超时在请求构建器上仍可覆盖与 10 秒连接超时*_CONNECT_TIMEOUT_SECS。而client.rs按路由模块内聚——messages的共享客户端就放在 messages/client.rs呼应 AGENTS.md 中路由模块自带client.rs共享 reqwest client的目录模板。风格规范与常量管理Rust Style Guide文档规定litellm-rust/下所有 Rust 代码遵循官方 Rust Style Guide并强调rustfmt的默认格式就是该指南的机械化执行提交前运行cargo fmtCI 对每个 PR 以cargo fmt --check把关。不要手写反 rustfmt 的格式也不要添加偏离默认风格的rustfmt.toml——默认风格即指南。指南中 rustfmt 无法自动处理的部分同样要遵守命名item/函数/模块用snake_case类型/trait/枚举变体用UpperCamelCase常量与 static 用SCREAMING_SNAKE_CASE缩写词按一个单词处理HttpClient而非HTTPClient排序与分组import 按 std / 外部 / crate 内分组derive 放在其他属性之前item 顺序一致惯用法优先重构过长的表达式而不是逼着格式器做别扭的换行。常量constants.rs是 Pythonlitellm/constants.py的 Rust 镜像文档的 Constants 一节规定魔数与固定字符串进入 crate 级src/constants.rs绝不内联硬编码每个需要常量的 crate 都有自己的src/constants.rs通过mod constants;声明使用时use crate::constants::...导入不要把const散落在各功能模块顶部可由环境变量覆盖的可调参数其DEFAULT_*值仍放在constants.rs实际的环境变量读取带默认值兜底发生在宿主/配置解析层而不是core/providers——这与前文 core 中读 env 仅限prepare.rs凭证兜底 的规则互相咬合例外纯粹局部于单个函数、在别处没有意义的值可以内联但拿不准时优先放constants.rs。core 的 constants.rs 全文就是这一规范的样本从OPENAI_DEFAULT_API_BASE这样的固定 URL到ANTHROPIC_OAUTH_TOKEN_PREFIX sk-ant-oat注释说明它镜像 Python 的ANTHROPIC_OAUTH_TOKEN_PREFIX用于validate_environment改用authorization头并丢弃x-api-key每个常量都带用途注释。提交前检查Checks文档给出了一段提交前必须执行的命令清单litellm-rust/目录下的变更在 CI 中跑同一套检查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 # the ai-gateway binary server code is behind the 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 # the auth, routes, state and realtime tests only exist under server cargo test -p litellm-ai-gateway --features server从命令结构可以读出该工作区的 feature 划分bedrock-auth是litellm-core的可选 featureBedrock 鉴权相关代码只有启用该 feature 时才参与 clippy 与测试litellm-ai-gateway的binary 与服务器代码整体位于serverfeature 之后因此 clippy 需要--all-features才能覆盖到auth、routes、state、realtime这几组测试也只在该 feature 下存在clippy 一律-D warnings即警告即失败。最后一条规则衔接 Python 侧当 Rust 路径通过 Python 暴露时补充 Python parity 测试把既有 Python 输出与 Rust 支撑的输出做对比——这正是 Production Bar 中 parity 条款在提交动作上的具体体现。小结规则文件如何约束一个双栈项目CLAUDE.md 的价值在于它把如何在这个双栈项目里写 Rust固化成了可检查的约束而不是散落的口头约定抽象纪律扩展基类、禁止第二份拷贝新增 provider 应是几行声明式代码结构纪律crate 是层、路由是模块handler 与钩子只在core宿主只做传输与部署选择边界纪律core 允许/禁止清单 env_lookup单点豁免让纯调用核心保持可移植、可测试质量纪律parity 用测试证明、五个维度的转换单测、无 panic、数据最小化工程纪律rustfmt 默认风格、constants.rs集中管理、六条网络 I/O 规则、一套可复制的cargo fmt/clippy/test检查命令。仓库内的messages路由mod.rs、transformation.rs、prepare.rs、constants.rs是目前最完整的参考实现阅读它可以把这份规则文件中的每一条要求对应到具体代码行上而 litellm-rust/AGENTS.md 则补充了 crate 角色表、路由目录模板与新增 crate 会被白名单测试拦截等配套机制两者可对照阅读。【免费下载链接】litellmThe fastest, litest AI Gateway. Rust core with Python SDK. Call 100 LLM APIs in OpenAI (or native) format with cost tracking, guardrails, load balancing, and logging [Bedrock, Azure, OpenAI, Anthropic, OpenAI, VertexAI, vLLM, Nvidia NIM]项目地址: https://gitcode.com/GitHub_Trending/li/litellm创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表