OGX 架构深度解析:统一 API 协议层、Provider 解析与自动路由的完整技术内幕
【免费下载链接】ogxOpen GenAI Stack项目地址: https://gitcode.com/GitHub_Trending/ll/ogx
OGX(Open GenAI Stack)是一个面向 AI 能力统一暴露的服务器:它以一套稳定的 API 同时提供推理(inference)、响应编排(responses)、向量存储(vector IO)、工具执行(tool runtime)、评测(evaluation)等能力,并对底层后端完全"供应商无关"——同一份 API 无论背后是 Ollama、OpenAI、vLLM 还是 Fireworks 都保持一致。本文以仓库根目录的 ARCHITECTURE.md 为骨架,结合 src/ogx/core、src/ogx_api 等源码实现,完整拆解 OGX 的模块边界、请求流转、Provider 体系、存储与租户隔离、配置模型以及录制回放测试系统。读完本文,你将掌握 OGX 的核心架构设计,能够快速定位各功能模块源码、理解 run config 的每个关键字段,并清楚一个 HTTP 请求是如何被路由到正确的 Provider 的。
系统概览:三个包的职责边界
OGX 代码库被拆分为三个独立包,职责划分非常清晰:
| 包 | 路径 | 职责 |
|---|---|---|
ogx-api | src/ogx_api | 轻量级 API 协议定义包:PythonProtocol类、Pydantic 数据类型、Provider 规格定义。不含任何服务端代码,不含任何 Provider 实现。第三方 Provider 只依赖这一个包 |
ogx | src/ogx | 服务端实现:Provider 解析、路由(routing)、存储、CLI,以及全部内置 Provider |
ogx-ui | src/ogx_ui | 可选 Web UI:聊天游乐场(chat playground)与管理员界面,基于 Next.js 构建 |
这种拆分的直接收益是依赖隔离:第三方 Provider 作者只需安装ogx-api即可编写自己的 Provider,不需要拉入整套服务端代码;而ogx作为宿主按需加载 Provider。在 src/ogx/core/stack.py 中,OGX是一个复合协议类,它一次性继承Providers、Inference、Responses、Batches、VectorIO、Models、Inspect、Files、Prompts、Conversations、Connectors等全部 API 接口,把整个服务端"组合"成一个实现了所有协议的完整对象——这正是"一套 API 覆盖所有能力"在类型层面的落地。
请求流转:从 HTTP 请求到 Provider 的完整链路
中间件链与路由分发
OGX 服务端构建在 FastAPI 之上。请求进入后依次经过多层中间件,再进入路由分发。整体流转如下:
Client (ogx-client SDK or raw HTTP) | v FastAPI Server (src/ogx/core/server/server.py) | |-- AuthenticationMiddleware (token validation, user + tenant_id extraction) |-- TenancyMiddleware (enforces tenancy mode: disabled/single/multi) |-- RouteAuthorizationMiddleware (route-level access policies) | v Route Dispatch | |-- FastAPI Router routes (auto-discovered via fastapi_router_registry.py) | v Router (src/ogx/core/routers/) | |-- Looks up the resource (model, vector store, tool group, etc.) in the RoutingTable |-- Resolves which provider handles this resource |-- Enforces access control policies | v Provider Implementation | |-- Inline provider (runs in-process, e.g. meta-reference, sqlite-vec) |-- Remote provider (calls external service, e.g. ollama, openai, fireworks) | v External Service or Local Computation从源码看,src/ogx/core/server/server.py 明确导入了三个认证/租户中间件:AuthenticationMiddleware(令牌校验、提取 user 与 tenant_id)、TenancyMiddleware(强制执行 tenancy 模式:disabled / single / multi)、RouteAuthorizationMiddleware(路由级访问策略)。此外还有RequestMetricsMiddleware(请求指标采集)、HSTSMiddleware(HTTPS 严格传输安全头)、ClientVersionMiddleware(基于x-ogx-client-version请求头做 major.minor 版本兼容性校验,不兼容时返回 426 Upgrade Required)以及ProviderDataMiddleware(为所有路由建立请求上下文),共同构成完整的服务端中间件栈。
路由注册的时机也值得注意:StackApp 是 FastAPI 的包装类,持有一个Stack实例;在 FastAPI 的 lifespan 上下文管理器(server.py)中,先执行app.stack.initialize()完成所有 Provider 的初始化,然后才调用build_fastapi_router(api, impl)为每个启用的 API 构建并注册路由器——因为 impl 在Stack.initialize()完成前尚不可用,所以路由器注册被有意推迟到 lifespan 阶段。启动时还会创建 registry 刷新后台任务(create_registry_refresh_task()),配合 stack.py 中的REGISTRY_REFRESH_INTERVAL_SECONDS = 300(每 5 分钟刷新一次资源注册表)。
详细流程示例:一次 Chat Completion
以POST /v1/chat/completions、请求体model: "ollama/llama3.2:3b-instruct-fp16"为例,完整链路如下:
- 客户端发送请求,
server.py将请求分发到 inference 的 FastAPI 路由器; InferenceRouter(src/ogx/core/routers/inference.py)调用routing_table.get_provider_impl(model_id);CommonRoutingTableImpl(src/ogx/core/routing_tables/common.py)在DistributionRegistry中查找该模型,确认它归属于ollamaProvider;- 路由器委托给
ollamaProvider 的openai_chat_completion()方法; - Ollama Provider 继承
OpenAIMixin(src/ogx/providers/utils/inference/openai_mixin.py),创建一个指向 Ollama 服务的AsyncOpenAI客户端并转发请求; - 响应以 SSE 事件流的形式经路由器流式返回客户端。
这条链路中"模型 ID 即路由键"的设计(provider/model前缀)是 OGX 多 Provider 并存的基石:同一个 API、同一份协议,通过模型名即可精确落到不同的后端。
Provider 架构
Provider 类型:Inline 与 Remote
OGX 将 Provider 划分为两大类型:
Provider | |-- InlineProviderSpec (runs in-process) | provider_type: "inline::builtin" | module: "ogx.providers.inline.inference.builtin" | |-- RemoteProviderSpec (adapts an external service) provider_type: "remote::ollama" module: "ogx.providers.remote.inference.ollama"- Inline Provider:进程内运行,例如 meta-reference 推理、sqlite-vec 向量检索,实现在 src/ogx/providers/inline;
- Remote Provider:适配外部服务,例如 ollama、openai、fireworks 等,实现在 src/ogx/providers/remote。
每个 Provider 规格(ProviderSpec)声明以下字段:
| 字段 | 含义 | 示例 |
|---|---|---|
api | 实现的 API 类型 | Api.inference |
provider_type | 唯一标识符 | "remote::openai" |
module | 提供get_adapter_impl()或get_provider_impl()工厂函数的 Python 模块 | ogx.providers.remote.inference.ollama |
config_class | Provider 的 Pydantic 配置模型 | OllamaConfig |
pip_packages | 运行时需要的额外依赖 | ollama |
Provider Registry:按 API 注册全部可用 Provider
src/ogx/providers/registry 目录下每个 API 对应一个文件(如inference.py、responses.py)。每个文件定义available_providers()函数,返回该 API 下的全部ProviderSpec对象。启动时由 core/distribution.py 的get_provider_registry()统一加载。
从 distribution.py 的源码看,INTERNAL_APIS(inspect、providers、prompts、conversations、connectors、admin、containers)由内置实现直接服务,不属于可配置 Provider;providable_apis()会排除内部 API 与自动路由表 API,只对剩余 API 加载外部可配置 Provider。值得一提的是,OGX 还支持通过providers.d/目录以 YAML 文件声明外部 Provider(支持remote/<api>/xxx.yaml与inline/<api>/xxx.yaml两级结构),get_provider_registry()会一并加载,这为第三方扩展提供了声明式入口。
Provider 解析:resolve_impls()四步走
启动时,core/resolver.py 的resolve_impls()按以下顺序完成 Provider 装配:
- 校验:
validate_and_prepare_providers()将 run config 中声明的 Provider 与注册表比对。特别地,若试图为自动路由表 API(如Api.models)显式配置 Provider,会直接抛出ValueError: Provider for '{api_str}' is automatically provided and cannot be overridden(见 resolver.py);同时处理弃用(deprecation_error直接拒绝、deprecation_warning打警告); - 排序:
sort_providers_by_deps()基于api_dependencies与optional_api_dependencies做依赖排序(如 agents 依赖 inference),缺依赖时给出明确的RuntimeError提示; - 实例化:
instantiate_providers()逐个导入模块并调用工厂函数,把实现按Api存入impls字典; - 自动路由装配:为 inference 等 API 创建
RoutingTable+Router组合,使多个 Provider 可以通过同一 API 服务不同模型。
instantiate_providers()还有两个值得关注的"后处理"细节(resolver.py):一是若同时启用了vector_io与vector_stores,会把VectorIORouter注入VectorStoresRoutingTable(用于查询改写);二是通过set_sibling_providers()把同 API 下的其他 Provider 实现注入当前实例,实现 Provider 间的协作。
自动路由(Auto-Routing)
许多 API 采用自动路由模式。以Api.inference与其配对的Api.models为例:
Api.models (RoutingTable) <--> Api.inference (Router) | | |-- ModelsRoutingTable |-- InferenceRouter | tracks which provider | delegates to correct | owns which model | provider per request自动路由配对清单由 core/distribution.py 的builtin_automatically_routed_apis()定义:
| Routing Table API | Router API |
|---|---|
Api.models | Api.inference |
Api.tool_groups | Api.tool_runtime |
Api.vector_stores | Api.vector_io |
从 resolver.py 的specs_for_autorouted_apis()可以看到:路由表 API 会被注册为provider_type="__routing_table__"的内置 Provider,路由器 API 则注册为provider_type="__autorouted__";并且vector_io路由器把Api.inference声明为可选依赖——只有 inference 同时启用时,向量查询才会具备查询改写能力。这就是"同一套 API、多个 Provider 并存"的底层机制:路由表负责登记"哪个 Provider 拥有哪个资源",路由器负责按请求把调用分发到正确的 Provider。
API 层(ogx_api):协议即契约
ogx_api包定义了全部对外公开的类型与协议,包含四类核心内容:
- Protocols:
Inference、Responses、Skills等 PythonProtocol类定义了 API 契约;HTTP 路由由各fastapi_routes.py模块中的 FastAPI 路由器承载; - Data Types:请求、响应与资源的 Pydantic 模型(如
Model、VectorStore、ChatCompletionRequest); - Provider Specs:
InlineProviderSpec、RemoteProviderSpec及相关类型,定义 Provider 的声明方式; - Internal utilities:
KVStore与SqlStore的抽象接口放在此包中,使得第三方 Provider 无需依赖完整服务端即可使用存储能力。
Provider 实现方的依赖关系非常干净:从ogx_api导入类型定义,从ogx.providers.utils导入共享功能(见 src/ogx/providers/utils)。这也意味着只要实现ogx_api中声明的Protocol,任何第三方代码都能作为 OGX 的 Provider 被加载。
存储层:KVStore、SqlStore 与租户隔离
存储配置
存储配置位于 run config 的storage段(StackConfig.storage),定义 Provider 与核心服务使用的后端引用:
storage: type: sqlite db_path: ${env.SQLITE_STORE_DIR}/registry.db stores: kvstore: type: kv_sqlite db_path: ${env.SQLITE_STORE_DIR}/kvstore.db inference: type: sql_sqlite db_path: ${env.SQLITE_STORE_DIR}/inference_store.dbKVStore:键值存储抽象
src/ogx/core/storage/kvstore 提供键值存储抽象(KVStore),支持多后端:
| 后端 | 配置类 | 典型用途 |
|---|---|---|
| SQLite | SqliteKVStoreConfig | 默认,单节点 |
| Redis | RedisKVStoreConfig | 多节点、缓存 |
| PostgreSQL | PostgresKVStoreConfig | 生产环境部署 |
| MongoDB | MongoDBKVStoreConfig | 文档型数据 |
使用方包括:distribution registry、配额跟踪(quota tracking)、Provider 状态、skills 元数据。
SqlStore:SQL 存储抽象
src/ogx/core/storage/sqlstore 提供基于 SQLAlchemy 的 SQL 存储抽象(SqlStore):
| 后端 | 配置类 | 典型用途 |
|---|---|---|
| SQLite | SqliteSqlStoreConfig | 默认,单节点 |
| PostgreSQL | PostgresSqlStoreConfig | 生产环境部署 |
使用方包括:inference store(聊天补全日志)、conversations(对话)、prompts(提示词)。
AuthorizedSqlStore 与租户隔离
AuthorizedSqlStore(src/ogx/core/storage/sqlstore/authorized_sqlstore.py)在SqlStore之上叠加两层相互独立的强制机制:
- 租户隔离(Tenant Isolation):在任何访问控制检查之前,先施加一个不可绕过的
WHERE tenant_id = ?过滤。当启用租户模式(single或multi)时,每张表都会获得tenant_id列:写入时盖上已认证用户的 tenant_id,读取与变更都被限定在该租户范围内。在multi模式下若缺少租户上下文,则生成1=0子句——即默认拒绝(什么都看不到),防止跨租户数据泄露; - ABAC(基于属性的访问控制):
owner_principal与access_attributes列支撑诸如"user is owner"的策略规则。它工作在租户内部,不跨租户。
租户模式在Stack.initialize()期间通过set_default_tenancy_mode()进程级设置,因此现有使用authorized_sqlstore()工厂的调用点无需任何改动即可自动获得租户隔离能力。
Distribution Registry:资源注册中心
src/ogx/core/store/registry.py 实现DistributionRegistry,跟踪所有已注册资源(模型、向量存储、工具组、提示词等)归属于哪个 Provider。它持久化到配置的 KVStore,因此资源注册信息在服务重启后依然存活。从 stack.py 的RESOURCES列表可以看到,models与vector_stores是核心的自动注册资源,注册时会附带RegisterModelRequest请求模型以支持配置对象到请求类的自动转换。
配置模型:Run Config、环境变量与 Distributions
Run Config(StackConfig)
Run Config 是一个 YAML 文件,定义了一个运行中的 OGX 实例的全部信息:
version: 2 distro_name: starter apis: - inference - responses - vector_io # ... providers: inference: - provider_id: ollama provider_type: remote::ollama config: base_url: ${env.OLLAMA_URL:=http://localhost:11434/v1} storage: type: sqlite db_path: ...关键特性:
- 环境变量替换:
${env.VAR_NAME:=default}语法为配置值提供默认值兜底(上例中OLLAMA_URL未设置时回退到http://localhost:11434/v1); - 条件 Provider:
${env.API_KEY:+provider_id}语法——仅当变量被设置时才启用对应 Provider; - 每 API 多 Provider:例如
ollama与openai可同时为 inference 服务,各自处理不同模型(这正是自动路由发挥作用的场景)。
配置解析由 src/ogx/core/utils/config_resolution.py 承担(resolve_config_or_distro()),它决定从显式配置文件还是从发行版(distro)解析出最终的StackConfig。条件变量未命中时,对应资源的 ID 字段会解析为空并被跳过——stack.py 的RESOURCE_ID_FIELDS(vector_store_id、model_id)专门处理这一情况。
Distributions:预置发行版
Distribution 是为特定目标环境预构建的配置,捆绑了具体的 Provider 集合。可以类比 Kubernetes 发行版(AKS、EKS、GKE):核心 API 保持一致,但每个发行版接入了不同的后端。src/ogx/distributions 存放这些配置(例如starter、nvidia、oci、watsonx、open-benchmark)。每个发行版目录包含:
config.yaml——run config;- 通过
template.py提供的模板与代码生成支持。
Build Config
Build Config 由ogx build命令用于构建容器镜像:声明要包含哪些 Provider、安装哪些包,它与 run config分开独立版本管理。
录制回放测试系统(Record/Replay)
集成测试使用一套录制/回放系统(src/ogx/testing/api_recorder.py):先拦截 OpenAI 客户端的调用录制真实 API 响应,再在 CI 中回放,从而获得快速、确定性的测试运行。
工作原理
- 录制(Recording):测试针对真实服务器运行。
APIRecordermonkey-patchOpenAI客户端方法,捕获每一对请求/响应,响应以 JSON 文件存储在tests/integration/recordings/下; - 回放(Replay):CI 中以回放模式运行。记录器通过对请求参数做哈希来匹配存储的响应,直接返回缓存响应,不再发起真实 API 调用;
- 模式(Modes):由
--inference-mode或环境变量OGX_TEST_INFERENCE_MODE控制:replay(默认)——使用缓存响应;record——强制录制所有交互;record-if-missing——仅在无缓存响应时录制;live——完全绕过录制,发起真实调用;
- 确定性 ID:回放期间记录器通过
set_id_override()覆盖 ID 生成,使文件、向量存储等资源 ID 在多次运行间可复现。
录制存储
录制文件存放在tests/integration/recordings/,按 Provider 与测试组织。每条录制是一个 JSON 文件,包含序列化的请求参数与响应;另有一个 SQLite 索引负责把请求映射到响应文件。更多细节可参考 tests/README.md 与 tests/integration/README.md。
这套机制的价值在于:把"对真实外部服务的依赖"转化为"对本地录制数据的确定性回放",既保证了集成测试的真实性,又让 CI 跑得快、跑得稳。
关键类与入口速查表
| 组件 | 位置 | 用途 |
|---|---|---|
OGX | core/stack.py | 实现全部 API 协议的复合类 |
Stack | core/stack.py | 初始化、资源注册、生命周期 |
StackApp | core/server/server.py | FastAPI 应用包装类 |
resolve_impls() | core/resolver.py | Provider 实例化与依赖解析 |
CommonRoutingTableImpl | core/routing_tables/common.py | 所有自动路由 API 的基类路由表 |
InferenceRouter | core/routers/inference.py | 将推理调用路由到正确 Provider |
OpenAIMixin | providers/utils/inference/openai_mixin.py | 共享的 OpenAI 兼容客户端逻辑 |
get_provider_registry() | core/distribution.py | 加载全部可用 Provider 规格 |
APIRecorder | testing/api_recorder.py | 录制/回放测试基础设施 |
目录地图:一张图定位所有代码
src/ ogx_api/ # API 定义包(独立 pip 包) inference/ # Inference 协议、模型、FastAPI 路由 responses/ # Responses API 协议与路由 datatypes.py # 共享数据类型 providers/ # Provider 规格类型 internal/ # KVStore/SqlStore 接口 ogx/ # 服务端实现 core/ server/ # FastAPI 服务端、认证、路由 routers/ # API 专属路由器(inference、responses 等) routing_tables/ # 资源到 Provider 的映射 storage/ # KVStore 与 SqlStore 后端 store/ # Distribution registry resolver.py # Provider 解析引擎 distribution.py # Provider 注册表加载 stack.py # Stack 初始化与生命周期 providers/ inline/ # 进程内 Provider 实现 remote/ # 远程服务适配器 registry/ # Provider 规格声明 utils/ # 共享 Provider 工具 distributions/ # 预置发行版配置 cli/ # CLI 命令(ogx stack run、build 等) testing/ # 测试基础设施(api_recorder) tests/ unit/ # 快速、隔离的单元测试 integration/ # 录制/回放的端到端测试 recordings/ # 缓存的 API 响应对于希望深入代码库的贡献者或 AI Agent,建议按此路径阅读:先看 ARCHITECTURE.md 建立全局认知,再依次阅读core/stack.py(生命周期与组合)、core/resolver.py(Provider 装配)、core/routers/inference.py与core/routing_tables/common.py(自动路由机制),最后用 tests/integration 的录制回放测试验证对请求链路的理解。OGX 的架构核心可以浓缩为一句话:协议在ogx_api,装配在ogx.core,执行在 Provider,而这一切通过自动路由这张"资源所有权表"统一起来——理解了这一条主线,其余细节皆可顺藤摸瓜。
【免费下载链接】ogxOpen GenAI Stack项目地址: https://gitcode.com/GitHub_Trending/ll/ogx
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考