ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

从零构建AI网关:Python实战多模型统一接口与路由

从零构建AI网关:Python实战多模型统一接口与路由 最近在关注AI应用开发的朋友们可能都注意到了支付巨头Stripe计划以超过70亿美元收购AI网关初创公司OpenRouter的新闻。这不仅是金融科技领域的一笔重磅交易更是一个强烈的信号AI应用的基础设施特别是连接开发者与众多大模型的“网关”层正成为技术栈中至关重要的一环。无论你是正在探索如何将ChatGPT、Claude等模型集成到自己的应用中还是对AI Agent、AI编程等前沿方向感兴趣理解“AI网关”这个概念及其背后的技术逻辑都将为你打开一扇新的大门。本文将从一个开发者的视角深入拆解AI网关的核心价值、技术原理并手把手带你从零搭建一个简易但功能完整的AI网关服务。我们将使用Python和FastAPI实现模型路由、负载均衡、统一接口等关键功能。通过这篇实战指南你将不仅能理解Stripe为何重金布局此领域更能掌握构建自己AI中间件的能力为未来的AI应用开发打下坚实基础。1. AI网关大模型时代的“智能路由器”在深入代码之前我们首先要厘清一个核心概念AI网关AI Gateway到底是什么1.1 从网络网关到AI网关传统的网络网关Gateway负责在不同网络协议或架构之间进行转换和路由是数据流通的“交通枢纽”。类比到AI世界AI网关扮演着类似的角色。随着OpenAI、Anthropic、Google、Meta以及众多开源模型百花齐放开发者面临一个现实问题我的应用应该调用哪个模型如何管理不同模型的API密钥、计费、速率限制和异构的接口AI网关应运而生。它作为一个中间层位于你的应用程序和底层众多AI模型提供商之间。开发者只需面向AI网关这一套统一的API进行编程而网关则负责将请求智能地路由到后端的OpenAI、Claude、Gemini或本地部署的Llama等模型并处理认证、限流、日志、降级等一切非业务逻辑。1.2 为什么需要AI网关解决开发者的四大痛点模型供应商锁定Vendor Lock-in如果你直接调用OpenAI的API那么业务逻辑将与OpenAI深度耦合。一旦需要切换或增加Claude作为备选就需要重构大量代码。AI网关通过抽象层让你可以无缝切换后端模型只需修改配置即可。复杂的配置与管理每个AI服务商都有各自的API端点、认证方式API Key格式、请求/响应格式、计费单元和速率限制。手动管理这些差异点繁琐且易出错。提升可用性与弹性当某个模型服务出现故障或响应缓慢时AI网关可以自动将请求故障转移Failover到健康的备用模型上保障应用的SLA。统一监控与成本控制网关可以集中收集所有模型调用的日志、延迟和费用数据提供统一的监控看板并实现基于预算或策略的调用限制避免意外的高额账单。OpenRouter正是这个赛道的明星初创公司。它提供了一个商业化的AI网关服务聚合了数十个主流大模型让开发者通过一个API和一套密钥就能访问所有模型。Stripe的收购意向无疑看中了其作为未来AI经济“支付基础设施”关键节点的战略价值。2. 环境准备与项目规划在开始构建我们自己的AI网关之前需要准备好开发环境并明确项目目标。2.1 技术栈与工具编程语言Python 3.8。因其在AI和Web开发领域的丰富生态而被选用。Web框架FastAPI。现代、高性能能自动生成API文档非常适合构建此类API服务。HTTP客户端httpx。支持异步请求性能优于requests更适合代理转发场景。配置管理pydantic-settings。用于管理API密钥等敏感配置。异步处理asyncio。利用Python的异步IO提升网关的并发处理能力。开发工具建议使用PyCharm或VS Code。2.2 项目目标与功能清单我们将构建一个具备以下核心功能的简易AI网关统一聊天接口对外提供类似OpenAI ChatCompletion格式的标准化API。多模型路由支持配置多个后端模型如OpenAI, Anthropic Claude。负载均衡与故障转移对同一模型的不同API密钥或端点进行简单的负载均衡并在一个失败时尝试另一个。请求转发与适配将标准化请求转换为不同模型提供商所需的特定格式。响应标准化将不同模型的响应统一为固定格式返回给客户端。基础的API密钥验证对调用方进行简单的认证。2.3 项目结构预览在开始编码前我们先规划好目录结构这有助于保持代码清晰。my_ai_gateway/ ├── app/ │ ├── __init__.py │ ├── main.py # FastAPI应用主入口 │ ├── config.py # 配置管理 │ ├── models.py # Pydantic数据模型 │ ├── routers/ │ │ ├── __init__.py │ │ └── chat.py # 聊天接口路由 │ ├── core/ │ │ ├── __init__.py │ │ ├── gateway.py # 网关核心路由逻辑 │ │ └── clients.py # 各模型客户端适配器 │ └── utils.py # 工具函数 ├── requirements.txt # 项目依赖 └── .env.example # 环境变量示例文件3. 项目搭建与核心代码实现现在让我们从零开始一步步实现这个AI网关。3.1 初始化项目与安装依赖首先创建项目目录并初始化虚拟环境。mkdir my_ai_gateway cd my_ai_gateway python -m venv venv # Windows: venv\Scripts\activate # Linux/Mac: source venv/bin/activate创建requirements.txt文件并安装依赖。fastapi0.104.1 uvicorn[standard]0.24.0 httpx0.25.1 pydantic-settings2.1.0 python-dotenv1.0.0 pydantic2.5.0使用pip安装pip install -r requirements.txt3.2 配置管理创建.env文件请勿提交到版本控制和.env.example文件用于存储敏感信息。.env.example:# 后端模型API密钥配置 OPENAI_API_KEYsk-your_openai_key_here OPENAI_API_BASEhttps://api.openai.com/v1 # 可选可用于配置代理 ANTHROPIC_API_KEYsk-ant-your_anthropic_key_here # 网关自身的安全密钥可选用于验证调用方 GATEWAY_API_KEYgateway_secret_key_123 # 模型配置模型名:提供商多个用逗号分隔 ENABLED_MODELSgpt-3.5-turbo:openai, gpt-4:openai, claude-3-haiku:anthropicapp/config.py:我们使用pydantic-settings来优雅地管理这些配置。from pydantic_settings import BaseSettings from typing import List, Dict import os class Settings(BaseSettings): # OpenAI 配置 openai_api_key: str openai_api_base: str https://api.openai.com/v1 # Anthropic 配置 anthropic_api_key: str # 网关配置 gateway_api_key: str default_gateway_key # 生产环境务必修改 # 启用的模型列表格式模型名:提供商 enabled_models: str gpt-3.5-turbo:openai # 解析 enabled_models 字符串为字典 property def model_provider_map(self) - Dict[str, str]: 将配置的字符串解析为 {模型名: 提供商} 的字典 model_map {} if self.enabled_models: for item in self.enabled_models.split(,): item item.strip() if : in item: model_name, provider item.split(:, 1) model_map[model_name.strip()] provider.strip() return model_map class Config: env_file .env case_sensitive False # 创建全局配置实例 settings Settings()3.3 定义数据模型为了统一请求和响应我们需要定义标准的数据结构。创建app/models.py。from pydantic import BaseModel, Field from typing import List, Optional, Literal, Dict, Any # 标准化的消息格式 (遵循OpenAI风格) class ChatMessage(BaseModel): role: Literal[system, user, assistant, function] content: str name: Optional[str] None # 可选参与者的名称 # 网关接收的聊天请求 class ChatCompletionRequest(BaseModel): model: str # 请求的模型如 gpt-3.5-turbo, claude-3-haiku messages: List[ChatMessage] temperature: Optional[float] Field(default0.7, ge0.0, le2.0) max_tokens: Optional[int] None stream: Optional[bool] False # 可以添加更多通用参数... # 网关返回的标准化响应 class ChatCompletionResponse(BaseModel): id: str # 本次调用的唯一ID object: str chat.completion created: int # 时间戳 model: str # 实际使用的模型 choices: List[Dict[str, Any]] # 标准化后的选择列表 usage: Optional[Dict[str, int]] None # token使用情况 # 错误响应 class ErrorResponse(BaseModel): error: Dict[str, Any]3.4 实现模型客户端适配器这是网关的核心之一负责与不同的AI服务商通信。创建app/core/clients.py。import httpx import uuid import time from typing import AsyncGenerator, Dict, Any, Optional from app.config import settings from app.models import ChatCompletionRequest, ChatCompletionResponse class BaseAIClient: 所有模型客户端的基类 provider_name: str base def __init__(self): self.client httpx.AsyncClient(timeout30.0) async def close(self): await self.client.aclose() async def create_chat_completion(self, request: ChatCompletionRequest, **kwargs) - ChatCompletionResponse: 创建聊天补全子类必须实现 raise NotImplementedError def _format_standard_response(self, model: str, content: str, **extra) - ChatCompletionResponse: 将不同模型的响应格式化为网关标准响应 standard_choice { index: 0, message: { role: assistant, content: content, }, finish_reason: stop } return ChatCompletionResponse( idfchatcmpl-{uuid.uuid4().hex}, createdint(time.time()), modelmodel, choices[standard_choice], usageextra.get(usage) # 如果有使用量信息则传入 ) class OpenAIClient(BaseAIClient): provider_name openai def __init__(self): super().__init__() self.api_key settings.openai_api_key self.base_url settings.openai_api_base.rstrip(/) if not self.api_key: raise ValueError(OpenAI API key is not configured.) async def create_chat_completion(self, request: ChatCompletionRequest, **kwargs): 调用OpenAI兼容的API url f{self.base_url}/chat/completions headers { Authorization: fBearer {self.api_key}, Content-Type: application/json } # 构造OpenAI格式的请求体 openai_payload { model: request.model, messages: [msg.dict(exclude_noneTrue) for msg in request.messages], temperature: request.temperature, } if request.max_tokens is not None: openai_payload[max_tokens] request.max_tokens if request.stream: openai_payload[stream] request.stream try: resp await self.client.post(url, headersheaders, jsonopenai_payload) resp.raise_for_status() openai_data resp.json() # 将OpenAI响应适配为标准格式 return self._format_standard_response( modelrequest.model, contentopenai_data[choices][0][message][content], usageopenai_data.get(usage) ) except httpx.HTTPStatusError as e: # 处理HTTP错误 error_detail fOpenAI API error: {e.response.status_code} - {e.response.text} raise Exception(error_detail) class AnthropicClient(BaseAIClient): provider_name anthropic def __init__(self): super().__init__() self.api_key settings.anthropic_api_key self.base_url https://api.anthropic.com/v1 if not self.api_key: raise ValueError(Anthropic API key is not configured.) async def create_chat_completion(self, request: ChatCompletionRequest, **kwargs): 调用Anthropic Claude API (需要适配其独特格式) url f{self.base_url}/messages headers { x-api-key: self.api_key, anthropic-version: 2023-06-01, Content-Type: application/json } # Anthropic API 格式与OpenAI不同需要转换 # 注意这是一个简化示例实际转换更复杂需处理system消息等 anthropic_messages [] for msg in request.messages: if msg.role system: # Claude 的system消息在单独字段 system_content msg.content continue anthropic_messages.append({ role: msg.role if msg.role ! function else user, content: msg.content }) anthropic_payload { model: request.model, # 例如 claude-3-haiku-20240307 messages: anthropic_messages, max_tokens: request.max_tokens or 1024, temperature: request.temperature, } # 如果有system消息加入 if system_content in locals(): anthropic_payload[system] system_content try: resp await self.client.post(url, headersheaders, jsonanthropic_payload) resp.raise_for_status() anthropic_data resp.json() # 将Anthropic响应适配为标准格式 content_block anthropic_data.get(content, [{}])[0] return self._format_standard_response( modelrequest.model, contentcontent_block.get(text, ), usage{prompt_tokens: anthropic_data.get(usage, {}).get(input_tokens, 0), completion_tokens: anthropic_data.get(usage, {}).get(output_tokens, 0)} ) except httpx.HTTPStatusError as e: error_detail fAnthropic API error: {e.response.status_code} - {e.response.text} raise Exception(error_detail) # 客户端工厂根据提供商名称返回对应的客户端实例 def get_ai_client(provider: str) - BaseAIClient: 工厂函数根据提供商获取客户端 clients { openai: OpenAIClient, anthropic: AnthropicClient, } client_class clients.get(provider.lower()) if not client_class: raise ValueError(fUnsupported AI provider: {provider}) return client_class()3.5 实现网关核心路由逻辑创建app/core/gateway.py这里将实现请求路由、负载均衡等核心逻辑。from typing import Dict, List, Optional import random from app.config import settings from app.core.clients import get_ai_client, BaseAIClient from app.models import ChatCompletionRequest, ChatCompletionResponse class AIGateway: AI网关核心类负责路由和负载均衡 def __init__(self): # 从配置加载模型与提供商的映射 self.model_provider_map settings.model_provider_map # 客户端缓存 {provider: client_instance} self._client_cache: Dict[str, BaseAIClient] {} print(fGateway initialized with models: {self.model_provider_map}) def _get_client(self, provider: str) - BaseAIClient: 获取或创建客户端实例简单缓存 if provider not in self._client_cache: self._client_cache[provider] get_ai_client(provider) return self._client_cache[provider] def get_provider_for_model(self, model_name: str) - str: 根据模型名称获取配置的提供商 provider self.model_provider_map.get(model_name) if not provider: # 如果未精确匹配尝试查找前缀匹配例如配置了 gpt-3.5-turbo请求是 gpt-3.5-turbo-0613 for key, val in self.model_provider_map.items(): if model_name.startswith(key): return val raise ValueError(fModel {model_name} is not enabled or configured in ENABLED_MODELS.) return provider async def create_chat_completion(self, request: ChatCompletionRequest) - ChatCompletionResponse: 处理聊天补全请求的主方法。 1. 根据请求的model字段查找对应的提供商。 2. 获取该提供商的客户端。 3. 转发请求并获取响应。 4. 返回标准化响应。 # 1. 路由到正确的提供商 provider self.get_provider_for_model(request.model) # 2. 获取客户端 client self._get_client(provider) # 3. 转发请求 (这里可以扩展负载均衡、故障转移、重试逻辑等) try: response await client.create_chat_completion(request) return response except Exception as e: # 此处可以添加重试逻辑例如切换到同一提供商的备用API密钥或端点 # 或者故障转移到另一个支持该模型的提供商如果配置了多个 raise e # 暂时直接抛出异常 async def close_all_clients(self): 关闭所有客户端连接用于优雅关闭 for client in self._client_cache.values(): await client.close() self._client_cache.clear() # 创建全局网关实例 gateway AIGateway()3.6 创建API路由现在我们来创建对外暴露的HTTP API。创建app/routers/chat.py。from fastapi import APIRouter, HTTPException, Header, Depends from typing import Optional from app.models import ChatCompletionRequest, ChatCompletionResponse, ErrorResponse from app.core.gateway import gateway from app.config import settings router APIRouter(prefix/v1, tags[chat]) def verify_api_key(x_api_key: Optional[str] Header(None, aliasX-API-Key)): 简单的API Key验证依赖项 if settings.gateway_api_key and settings.gateway_api_key ! default_gateway_key: if not x_api_key or x_api_key ! settings.gateway_api_key: raise HTTPException(status_code401, detailInvalid or missing API Key) # 如果未设置网关密钥或为默认值则跳过验证仅用于开发 return True router.post(/chat/completions, response_modelChatCompletionResponse) async def create_chat_completion( request: ChatCompletionRequest, verified: bool Depends(verify_api_key) ): 统一的AI聊天补全接口。 请求格式与OpenAI ChatCompletion API基本兼容。 try: response await gateway.create_chat_completion(request) return response except ValueError as e: # 模型未找到等配置错误 raise HTTPException(status_code400, detailstr(e)) except Exception as e: # 后端API调用错误 # 在实际项目中这里应该记录更详细的日志 raise HTTPException(status_code502, detailfGateway error: {str(e)}) router.get(/models) async def list_models(verified: bool Depends(verify_api_key)): 列出网关支持的所有模型 models_list [] for model_name, provider in gateway.model_provider_map.items(): models_list.append({ id: model_name, object: model, owned_by: provider, permission: [] # 简化处理 }) return {object: list, data: models_list}3.7 组装主应用最后创建app/main.py文件将路由和网关组装起来。from fastapi import FastAPI from contextlib import asynccontextmanager from app.routers import chat from app.core.gateway import gateway # 使用 lifespan 管理网关客户端的生命周期 asynccontextmanager async def lifespan(app: FastAPI): # 启动时 print(AI Gateway starting up...) yield # 关闭时 print(AI Gateway shutting down...) await gateway.close_all_clients() # 创建FastAPI应用实例 app FastAPI( titleMy AI Gateway, description一个简易的、统一的多模型AI网关服务, version0.1.0, lifespanlifespan ) # 包含路由 app.include_router(chat.router) app.get(/) async def root(): return { message: Welcome to My AI Gateway, docs: /docs, health: /health } app.get(/health) async def health_check(): 健康检查端点 return {status: healthy}4. 运行与测试网关服务4.1 启动服务在项目根目录下使用uvicorn启动开发服务器。uvicorn app.main:app --reload --host 0.0.0.0 --port 8000如果一切顺利你将看到类似输出INFO: Will watch for changes in these directories: [/path/to/my_ai_gateway] INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRLC to quit) INFO: Started reloader process [12345] using WatchFiles AI Gateway starting up... Gateway initialized with models: {gpt-3.5-turbo: openai, gpt-4: openai, claude-3-haiku: anthropic} INFO: Started server process [12346] INFO: Waiting for application startup. INFO: Application startup complete.4.2 测试API打开浏览器访问http://localhost:8000/docs你将看到自动生成的Swagger UI界面。1. 获取支持的模型列表在/docs页面找到GET /v1/models点击“Try it out”然后“Execute”。你应该能看到在.env中配置的模型列表。2. 发送一个聊天请求找到POST /v1/chat/completions点击“Try it out”。在请求体中填入以下JSON确保你的.env中已配置正确的API密钥{ model: gpt-3.5-turbo, messages: [ { role: user, content: 你好请用一句话介绍你自己。 } ], temperature: 0.7 }点击“Execute”。如果配置正确网关会将请求转发给OpenAI并将标准化的响应返回。响应示例{ id: chatcmpl-abc123def456, object: chat.completion, created: 1681234567, model: gpt-3.5-turbo, choices: [ { index: 0, message: { role: assistant, content: 我是由OpenAI创造的AI助手致力于为您提供信息和帮助。 }, finish_reason: stop } ], usage: { prompt_tokens: 20, completion_tokens: 15, total_tokens: 35 } }3. 测试Claude模型将请求体中的model字段改为claude-3-haiku再次执行。网关会自动将请求路由到Anthropic的API。4.3 使用curl命令行测试你也可以使用curl进行测试# 1. 获取模型列表 curl -X GET http://localhost:8000/v1/models -H X-API-Key: gateway_secret_key_123 # 2. 发送聊天请求 curl -X POST http://localhost:8000/v1/chat/completions \ -H Content-Type: application/json \ -H X-API-Key: gateway_secret_key_123 \ -d { model: gpt-3.5-turbo, messages: [{role: user, content: Hello, world!}] }5. 进阶功能与优化方向我们实现了一个基础可用的AI网关。但在生产环境中还需要考虑更多因素。以下是几个关键的进阶方向和优化建议5.1 负载均衡与故障转移当前的网关只是简单路由。一个健壮的网关应该支持多API密钥负载均衡对于一个提供商如OpenAI配置多个API密钥网关在请求时轮询或随机选择避免单个密钥的速率限制。故障转移Failover当主提供商或密钥请求失败时自动重试或切换到备用的提供商例如GPT-4请求失败时尝试切换到Claude 3 Opus如果业务逻辑允许。实现思路在AIGateway类中维护一个更复杂的路由表记录每个模型对应的多个“端点”包括提供商、API密钥、基础URL等。在create_chat_completion方法中实现重试逻辑。5.2 速率限制与配额管理防止滥用和成本失控。基于用户/应用的限流根据调用方的API Key限制其每分钟/每天的请求次数或Token消耗。全局预算控制为整个网关或特定模型设置月度预算接近阈值时告警或拒绝请求。实现方案可以使用像slowapi这样的库或者集成Redis来分布式计数。5.3 日志、监控与审计所有经过网关的请求都应被记录用于调试、分析和计费。结构化日志记录请求ID、模型、提供商、用户标识、Token用量、延迟、状态码、费用估算等。集成监控系统将指标请求量、延迟、错误率发送到Prometheus、Datadog等。审计追踪确保可追溯谁在什么时间调用了什么模型。5.4 响应缓存对于某些重复性高的请求例如常见的系统提示词可以缓存响应以降低延迟和成本。缓存策略基于请求参数模型、消息内容、温度等生成哈希键。缓存存储使用Redis或Memcached。注意事项注意缓存失效和隐私问题对于包含用户敏感信息的请求不应缓存。5.5 支持流式响应Streaming许多大模型支持流式输出SSE。网关需要能够透明地转发流式响应。技术挑战需要处理Server-Sent Events (SSE)并可能需要在转发过程中进行格式转换。FastAPI实现可以使用StreamingResponse在网关端以流的方式从后端模型读取数据并即时转发给客户端。5.6 配置热更新目前模型配置写在.env中重启才能生效。可以设计一个管理API动态添加/移除模型配置。6. 常见问题与排查思路在开发和部署过程中你可能会遇到以下问题问题现象可能原因排查步骤与解决方案启动服务时报错ValueError: OpenAI API key is not configured..env文件未创建或其中的OPENAI_API_KEY为空。1. 检查项目根目录下是否存在.env文件。2. 检查.env文件中OPENAI_API_KEY等密钥是否已正确填写。3. 确保虚拟环境已激活且应用能读取到环境变量。调用/v1/chat/completions返回400错误提示模型未找到。请求的model字段值未在ENABLED_MODELS配置中。1. 检查请求体中的model字段拼写是否正确如gpt-3.5-turbo。2. 检查.env中ENABLED_MODELS配置确保包含了该模型格式为模型名:提供商。调用接口返回502 Bad Gateway或超时。1. 后端AI服务商API故障或网络不通。2. 网关到服务商的网络问题。3. API密钥无效或余额不足。1. 首先直接使用curl或httpx测试后端API是否可用。2. 检查网关服务器的网络连接。3. 登录对应AI服务商的控制台检查API密钥状态和余额。请求Claude模型失败返回格式解析错误。Anthropic API的请求/响应格式与OpenAI不同适配器逻辑可能有误。1. 查看网关应用的错误日志定位是请求构造问题还是响应解析问题。2. 对比 Anthropic官方API文档 检查app/core/clients.py中AnthropicClient的转换逻辑。接口响应慢。1. 后端模型本身响应慢。2. 网关服务器资源不足。3. 网络延迟高。1. 在网关日志中记录每个请求的耗时区分是网关处理时间还是后端API时间。2. 监控网关服务器的CPU、内存和网络。3. 考虑将网关部署在离后端API服务商网络较近的区域。如何增加对新模型如Google Gemini的支持需要为该模型提供商编写新的客户端适配器。1. 在app/core/clients.py中创建一个新的GeminiClient类继承BaseAIClient。2. 实现create_chat_completion方法处理Gemini特有的API格式。3. 在get_ai_client工厂函数中注册这个新类。4. 在.env的ENABLED_MODELS中添加新模型如gemini-pro:google。7. 生产环境部署与安全建议如果你计划将这个小项目用于生产或更严肃的开发环境请务必考虑以下几点安全性强化认证本文示例的API Key验证非常基础。生产环境应使用JWT、OAuth 2.0等更安全的机制。保护后端密钥确保.env文件不被提交到代码仓库。使用安全的密钥管理服务如AWS Secrets Manager, HashiCorp Vault。输入验证与清理对用户传入的messages内容进行基本的清理和检查防止注入攻击。HTTPS务必使用HTTPS对外暴露服务。性能与可扩展性异步客户端我们已经使用了httpx.AsyncClient确保它是复用的而不是为每个请求创建新客户端。连接池调整HTTP客户端的连接池大小以适应并发量。无状态设计确保网关本身是无状态的便于水平扩展。可以将限流、缓存等状态存储在外部Redis中。高可用部署多个网关实例前面用Nginx或云负载均衡器做负载均衡。为关键的后端AI服务如OpenAI配置多个备用API端点或密钥。可观测性集成完整的日志系统如ELK Stack。添加Metrics端点方便被Prometheus抓取。设置关键指标错误率、P99延迟、Token消耗的告警。成本与治理在网关层面实现细粒度的成本分摊和报告功能。为不同团队或项目设置预算和配额。通过构建这样一个AI网关你不仅深入理解了Stripe收购OpenRouter这类公司背后的技术逻辑也亲手搭建了一个能够解耦应用与具体AI模型、提升系统弹性和可维护性的核心中间件。这个项目可以作为你探索AI工程化、LLMOps的起点。你可以在此基础上继续集成模型性能评估、A/B测试、影子模式等高级功能逐步构建起适应自身业务需求的、强大的AI能力中台。
返回列表