资讯详情

LiteLLM统一模型调用:标准化接口与多厂商路由实战

📅 2026/10/14 9:02:29 | 华诺云谱 👁 阅读
LiteLLM统一模型调用:标准化接口与多厂商路由实战
1. 从“调用大模型像调用API一样简单”说起LiteLLM到底在解决什么真问题你有没有过这样的时刻手头有个业务需求想快速接入一个大模型能力——比如让客服对话更自然、让内部文档自动摘要、或者给销售话术加点智能润色。你打开某云厂商的控制台复制API Key翻出官方SDK文档照着示例写了几行Python代码……结果卡在了认证失败、参数格式报错、流式响应解析崩溃、或者换家模型比如从gpt-3.5-turbo切到claude-3-haiku就得重写半套逻辑上。这不是技术不行是基础设施层的“适配税”太高了。LiteLLM就是为砍掉这笔税而生的。它不是另一个大模型也不是训练框架而是一个统一抽象层Unified Abstraction Layer——你可以把它理解成数据库领域的ORM但对象不是MySQL或PostgreSQL而是OpenAI、Anthropic、Google Vertex AI、Ollama、甚至本地运行的Llama.cpp、vLLM等几十个后端。它的核心价值一句话就能说清让你用完全相同的Python函数调用litellm.completion()无缝切换任意支持的模型提供商且自动处理鉴权、请求格式转换、响应结构归一化、流式传输封装、重试策略、超时熔断等所有底层脏活。这听起来像“胶水代码”但实际落地中它直接决定了一个AI功能从Demo到上线的速度。我参与过的一个内部知识助手项目初期只对接了OpenAI两周就跑通了原型但当法务要求必须支持国产模型做数据隔离时团队原计划用三天重写所有调用链路——最后发现把openai.ChatCompletion.create()替换成litellm.completion()改两行配置加一个环境变量指定OLLAMA_API_BASE整个服务就切到了本地部署的Qwen2-7B连前端流式渲染逻辑都不用动。这种“零侵入迁移”的能力才是LiteLLM在真实工程场景里不可替代的锚点。它解决的从来不是“能不能调用模型”的问题而是“能不能以最小认知成本、最低维护代价、最高可扩展性把模型能力当成一种可编排的基础设施来使用”的问题。关键词不是“轻量”虽然它确实很轻而是“标准化接口”和“供应商无关性”。当你开始思考“未来三个月要接入5家不同模型服务商”或者“同一个提示词需要在3种模型上做A/B测试”LiteLLM就不再是可选项而是架构设计的起点。2. 不是SDK胜似SDKLiteLLM的三层架构与工作原理拆解很多人第一次接触LiteLLM会下意识把它当成OpenAI SDK的“增强版”这是个危险的误解。它的工作机制远比“封装一层调用”复杂得多。要真正用好它必须看清它的三层结构协议适配层 → 路由调度层 → 运行时治理层。这三层共同构成了它“一次编码、多端运行”的底气。2.1 协议适配层把千差万别的模型API“翻译”成同一套语言想象一下OpenAI的请求体长这样{ model: gpt-3.5-turbo, messages: [{role: user, content: 你好}], stream: true }而Anthropic的Claude要求{ model: claude-3-haiku-20240307, messages: [{role: user, content: 你好}], stream: true, max_tokens: 1024 }表面看只是多了一个max_tokens字段但深层差异巨大OpenAI用temperature控制随机性Anthropic用temperaturetop_p组合Google Gemini则用temperaturetop_ktop_p三参数OpenAI的system角色需放在messages[0]Anthropic强制要求system作为独立字段Ollama本地部署时base_url指向http://localhost:11434/api/chat而vLLM可能指向http://localhost:8000/v1/chat/completions……这些差异如果靠人肉if-else处理代码会迅速腐化。LiteLLM的协议适配层本质是一套动态协议映射引擎。它内置了对每个后端的“协议方言”解析器。当你调用response litellm.completion( modelanthropic/claude-3-haiku-20240307, messages[{role: user, content: 你好}], temperature0.3 )LiteLLM会先根据model字符串前缀anthropic/识别出目标后端然后触发Anthropic专用适配器。这个适配器会自动补全max_tokens默认设为4096避免因缺失必填项导致400错误将temperature0.3原样透传但若你传了top_p0.9它会检查Anthropic是否支持并合法化把messages中的system消息提取出来塞进独立的system字段将响应体中Anthropic特有的content数组含type、text字段重新组装成OpenAI风格的choices[0].message.content。提示LiteLLM的适配不是静态JSON模板替换而是带语义校验的动态转换。比如你传modelazure/gpt-35-turbo它会自动从环境变量读取AZURE_API_BASE、AZURE_API_VERSION并构造符合Azure OpenAI Service规范的URL和Header连api-key和api-version都帮你拼好。这种“知道你要什么更知道对方要什么”的智能才是它稳定性的根基。2.2 路由调度层让模型选择从硬编码变成可配置策略协议适配解决了“怎么调”路由调度则解决了“调谁”。LiteLLM内置了强大的**模型路由Model Routing**能力这远超简单的“字符串匹配”。它支持三种核心模式第一种静态路由Static Routing最常用通过litellm.set_verbose(True)开启调试后你能看到它如何将modelgpt-3.5-turbo映射到真实的openai/gpt-3.5-turbo。但关键在于这个映射可以自定义# 把所有对gpt-35-turbo的请求路由到我们私有部署的vLLM集群 litellm.model_alias_map { gpt-35-turbo: vllm/your-vllm-endpoint }这样业务代码里永远写modelgpt-35-turbo运维只需改配置就能把流量切走——这是灰度发布的理想载体。第二种权重路由Weighted Routing适用于A/B测试或负载均衡from litellm import Router router Router( model_list[ { model_name: gpt-35-turbo, litellm_params: { model: azure/gpt-35-turbo, api_key: os.getenv(AZURE_API_KEY), api_base: os.getenv(AZURE_API_BASE) }, weight: 0.7 # 70%流量 }, { model_name: qwen2-7b, litellm_params: { model: ollama/qwen2:7b, api_base: http://localhost:11434 }, weight: 0.3 # 30%流量 } ] ) # 后续所有调用都走router.completion(...)Router会按权重概率分发请求并自动处理下游故障如Ollama宕机时自动降级到Azure路径。第三种规则路由Rule-Based Routing基于上下文动态决策比如按用户等级、请求长度、敏感词检测结果路由def route_rule(kwargs): # 如果提示词含财务报表强制走高精度模型 if 财务报表 in str(kwargs.get(messages, [])): return gpt-4-turbo # 如果是移动端小屏设备用轻量模型保速度 if kwargs.get(metadata, {}).get(device) mobile: return claude-3-haiku return gpt-3.5-turbo router Router(model_list[...], routing_strategyusage-based, num_retries3) router.route_rule route_rule # 注入自定义规则注意路由层不是简单的“if-else开关”它内置了实时用量统计token消耗、延迟监控、健康检查。当你配置了num_retries3它会在某个后端连续失败后自动标记其为“不健康”并在一段时间内跳过它直到心跳检测恢复——这种生产级的韧性是手写路由代码极难覆盖的。2.3 运行时治理层让每一次调用都可控、可观测、可审计很多团队踩过的坑是模型调用看似成功但返回内容质量波动大、延迟忽高忽低、错误日志全是500 Internal Server Error无法定位。LiteLLM的运行时治理层正是为解决这些“黑盒”问题而设计。它默认开启结构化日志Structured Logging。开启litellm.success_callback [langfuse]后每一次成功调用都会记录完整请求参数脱敏后的API Key响应耗时、输入/输出token数模型实际使用的后端如azure/gpt-35-turbo响应内容摘要前100字符调用堆栈精确到哪一行代码发起更关键的是错误分类与重试策略。LiteLLM将HTTP错误码做了语义分组429 Too Many Requests→ 触发指数退避重试默认3次间隔1s, 2s, 4s500,502,503,504→ 标记为“后端不稳定”触发路由层的健康检查降级400 Bad Request→ 直接抛出BadRequestError附带原始错误信息如Anthropic的InvalidRequestError: max_tokens must be 0方便快速定位参数问题我还见过一个经典案例某团队用LiteLLM对接多个国产模型发现某家API在temperature0时会返回空响应。他们没去改业务代码而是在LiteLLM的failure_callback里加了一行def on_failure(exception, kwargs): if isinstance(exception, litellm.exceptions.BadRequestError) and temperature0 in str(exception): # 自动修正并重试 kwargs[temperature] 0.01 litellm.completion(**kwargs) litellm.failure_callback [on_failure]这种在运行时动态修复的能力让LiteLLM从“调用工具”升级为“智能代理”。3. 从零到生产一个可直接复用的LiteLLM集成实战流程光讲原理不够得给你一套能立刻上手、经受过真实流量考验的集成方案。下面是我为某跨平台内容生成系统搭建LiteLLM服务的完整流程所有步骤均来自线上环境已去除任何敏感信息可直接“抄作业”。3.1 环境准备最小依赖与安全加固别急着pip install litellm。生产环境的第一步永远是依赖收敛与权限最小化。首先创建专用虚拟环境并安装核心包python -m venv .venv-litellm source .venv-litellm/bin/activate # Windows用 .venv-litellm\Scripts\activate pip install --upgrade pip pip install litellm1.45.1 # 锁定小版本避免API变更 pip install python-dotenv # 环境变量管理 pip install prometheus-client # 后续指标暴露为什么锁死1.45.1因为LiteLLM在1.46.0版本中调整了Router的初始化参数而我们的监控脚本强依赖旧接口。这是血泪教训大模型生态迭代太快生产环境必须严格锁定次要版本号。接着建立安全的环境变量管理。创建.env文件# 主要模型后端 OPENAI_API_KEYsk-xxx AZURE_API_KEYxxx ANTHROPIC_API_KEYxxx # 本地模型 OLLAMA_API_BASEhttp://localhost:11434 # 关键配置 LITELLM_LOG_LEVELINFO LITELLM_MAX_RETRIES3 LITELLM_TIMEOUT60提示绝对不要把API Key写死在代码里LiteLLM会自动从.env或系统环境变量读取。更进一步我们用HashiCorp Vault动态注入这些密钥.env只存Vault地址和Token但这属于进阶运维此处略过。3.2 配置中心化用YAML定义你的模型“交通网”把所有模型配置写在代码里是反模式。LiteLLM支持从YAML文件加载model_list这才是可维护的姿势。创建config/model_config.yamlmodel_list: # Azure OpenAI主力 - model_name: gpt-35-turbo litellm_params: model: azure/gpt-35-turbo api_key: ${AZURE_API_KEY} api_base: ${AZURE_API_BASE} api_version: 2023-12-01-preview timeout: 45 max_retries: 2 # Anthropic创意生成 - model_name: claude-3-haiku litellm_params: model: anthropic/claude-3-haiku-20240307 api_key: ${ANTHROPIC_API_KEY} timeout: 60 # Ollama本地研发测试 - model_name: qwen2-7b litellm_params: model: ollama/qwen2:7b api_base: ${OLLAMA_API_BASE} timeout: 120 # 故障转移兜底必须有 - model_name: fallback-model litellm_params: model: gpt-35-turbo api_key: ${AZURE_API_KEY} api_base: ${AZURE_API_BASE} api_version: 2023-12-01-preview fallbacks: [claude-3-haiku, qwen2-7b]注意几个关键点fallbacks字段定义了当主模型失败时的降级链路LiteLLM会按顺序尝试timeout值按模型特性差异化设置本地Ollama慢设120秒Azure快设45秒所有密钥用${VAR}语法引用由python-dotenv自动替换。3.3 初始化Router构建你的智能流量调度器现在用配置文件初始化Router。创建core/litellm_router.pyimport litellm from litellm import Router from dotenv import load_dotenv import yaml import os # 加载环境变量 load_dotenv() # 读取YAML配置 with open(config/model_config.yaml, r) as f: config yaml.safe_load(f) # 初始化Router启用高级特性 router Router( model_listconfig[model_list], num_retries3, # 全局重试 timeout60, # 全局超时 set_verboseTrue, # 开发期开启生产关掉 allowed_fails2, # 同一后端允许2次失败才标记不健康 health_check_interval30, # 每30秒检查一次后端健康 ) # 注册回调实现可观测性 def log_success(kwargs, response, start_time, end_time): # 记录到Prometheus from prometheus_client import Counter, Histogram REQUESTS_TOTAL.labels( modelkwargs.get(model, unknown), statussuccess ).inc() LATENCY_SECONDS.labels(modelkwargs.get(model, unknown)).observe( (end_time - start_time).total_seconds() ) def log_failure(exception, kwargs): REQUESTS_TOTAL.labels( modelkwargs.get(model, unknown), statusfailure ).inc() print(fLiteLLM调用失败: {exception}, 请求参数: {kwargs}) litellm.success_callback [log_success] litellm.failure_callback [log_failure] # 导出供其他模块使用 __all__ [router]这个router实例就是你整个系统的“模型中枢”。所有业务模块只需导入它调用router.completion(...)即可。3.4 业务层封装提供统一、健壮的AI服务接口最后在业务层封装一个干净的Service类。创建services/ai_service.pyfrom core.litellm_router import router import litellm from typing import List, Dict, Any, Optional class AIService: staticmethod def generate_text( prompt: str, model: str gpt-35-turbo, temperature: float 0.7, max_tokens: int 1024, stream: bool False, metadata: Optional[Dict[str, Any]] None ) - Dict[str, Any]: 统一文本生成接口 :param prompt: 用户输入提示词 :param model: 目标模型名必须在model_config.yaml中定义 :param temperature: 创意控制参数 :param max_tokens: 最大输出长度 :param stream: 是否流式响应 :param metadata: 附加元数据用于路由规则 :return: 标准化响应字典 try: # 构造标准messages格式 messages [{role: user, content: prompt}] # 调用Router response router.completion( modelmodel, messagesmessages, temperaturetemperature, max_tokensmax_tokens, streamstream, metadatametadata or {} ) # 归一化响应结构 if stream: # 流式响应需特殊处理返回生成器 return { status: streaming, generator: response # 直接返回LiteLLM的流式迭代器 } else: # 非流式提取核心内容 content response.choices[0].message.content usage response.usage.dict() if response.usage else {} return { status: success, content: content, usage: usage, model_used: response._hidden_params.get(model, model) } except litellm.exceptions.Timeout as e: return {status: error, message: 请求超时请重试, code: TIMEOUT} except litellm.exceptions.RateLimitError as e: return {status: error, message: 调用频率超限, code: RATE_LIMIT} except Exception as e: # 捕获所有未预期异常 return {status: error, message: f服务异常: {str(e)}, code: UNKNOWN} # 快捷函数方便快速调用 def quick_generate(prompt: str, **kwargs) - str: result AIService.generate_text(prompt, **kwargs) return result.get(content, ) if result[status] success else 这个AIService类的价值在于屏蔽了LiteLLM的细节业务方不用关心Router、completion等概念提供了清晰的错误契约所有异常都转化为标准{status: error, code: XXX}结构内置了流式支持streamTrue时返回生成器前端可逐字渲染预留了扩展点metadata参数可被路由规则读取未来加AB测试、用户分级等逻辑无需改调用方。实测心得上线前务必用stress-test验证。我们曾用locust模拟100并发请求发现Ollama节点在max_tokens2048时CPU飙升到95%于是果断在model_config.yaml里给它加了max_tokens: 1024的硬限制。LiteLLM的fallbacks在此刻发挥了作用——当Ollama超时流量自动切到Azure用户无感知。这种“故障即常态”的设计哲学才是生产级AI服务的基石。4. 那些官方文档不会写的坑LiteLLM实战避坑指南LiteLLM文档写得清晰但真实世界比文档复杂得多。以下是我和团队踩过的7个典型坑每一个都附带根因分析和可落地的解决方案全是血换来的经验。4.1 坑一modelgpt-3.5-turbo在Azure上404但modelazure/gpt-3.5-turbo却正常现象本地开发用OpenAI Key一切正常部署到Azure环境后所有请求返回404 Not Found。根因分析LiteLLM的模型解析逻辑是“前缀匹配”。当你传modelgpt-3.5-turbo它默认认为这是OpenAI模型会向https://api.openai.com/v1/chat/completions发请求。但Azure的Endpoint是https://YOUR-RESOURCE.openai.azure.com/openai/deployments/YOUR-DEPLOYMENT/chat/completions?api-version2023-12-01-preview。两者域名、路径、参数完全不同。解决方案必须显式声明后端类型。有两种方式方式一推荐在model_config.yaml中定义model_name: gpt-35-turbolitellm_params.model: azure/gpt-35-turbo业务代码永远用modelgpt-35-turbo方式二代码中强制指定modelazure/gpt-35-turbo但这样失去了“供应商无关”的初衷。经验永远不要在业务代码里写modelgpt-3.5-turbo这种裸字符串。它应该是一个配置项由运维控制。我们后来在CI/CD流水线里加了检查grep -r gpt-3.5-turbo --include*.py . | grep -v model_config一旦发现就阻断发布。4.2 坑二流式响应streamTrue在FastAPI中卡住前端收不到chunk现象调用router.completion(..., streamTrue)返回一个generator object ...但在FastAPI的StreamingResponse中前端始终等待直到超时才收到全部内容。根因分析LiteLLM的流式生成器是同步的而FastAPI的StreamingResponse期望一个异步生成器。直接传入会导致事件循环阻塞。解决方案用async_generator桥接。创建utils/stream_utils.pyimport asyncio from typing import AsyncGenerator, Any async def to_async_generator(sync_gen) - AsyncGenerator[Any, None]: 将同步生成器转为异步生成器 loop asyncio.get_event_loop() # 在线程池中运行同步生成器避免阻塞事件循环 def _gen(): for item in sync_gen: yield item sync_iter iter(_gen()) while True: try: # 在线程池中获取下一个item item await loop.run_in_executor(None, lambda: next(sync_iter)) yield item except StopIteration: break # FastAPI路由示例 app.post(/chat/stream) async def chat_stream(request: ChatRequest): response router.completion( modelrequest.model, messages[{role: user, content: request.prompt}], streamTrue ) return StreamingResponse( to_async_generator(response), media_typetext/event-stream )4.3 坑三fallbacks不生效主模型失败后没切到备选现象配置了fallbacks: [claude-3-haiku]但当gpt-35-turbo返回500时日志显示仍在重试主模型从未尝试Claude。根因分析LiteLLM的fallback机制只对特定错误码触发。默认情况下500被归类为InternalServerError而fallback只对RateLimitError、Timeout、BadRequestError等明确异常生效。500被视为“未知错误”进入全局重试逻辑。解决方案在failure_callback中手动触发fallbackdef custom_fallback(exception, kwargs): if hasattr(exception, status_code) and exception.status_code 500: # 强制使用Router的fallback逻辑 from litellm.router import retry_request try: # 获取当前模型的fallback列表 model_info router.get_model_info(kwargs.get(model)) fallback_models model_info.get(fallbacks, []) if fallback_models: # 用第一个fallback模型重试 kwargs[model] fallback_models[0] return router.completion(**kwargs) except Exception as e: print(fFallback失败: {e}) # 其他错误走默认逻辑 litellm.default_callback_handler(exception, kwargs) litellm.failure_callback [custom_fallback]4.4 坑四Ollama模型加载慢首次请求超时现象Ollama首次调用/api/chat时响应时间长达15秒远超配置的timeout120但LiteLLM仍判定为超时失败。根因分析Ollama的/api/chat端点在模型未加载时会先执行ollama pull和ollama run这个过程是阻塞的。LiteLLM的timeout计时从请求发出开始不区分“网络等待”和“模型加载”。解决方案预热Warm-up所有Ollama模型。在服务启动时主动触发一次空请求# 在app启动时执行 def warmup_ollama_models(): ollama_models [ qwen2:7b, llama3:8b, phi3:3.8b ] for model in ollama_models: try: litellm.completion( modelfollama/{model}, messages[{role: user, content: ping}], timeout180 # 首次预热给足时间 ) print(fOllama模型 {model} 预热成功) except Exception as e: print(fOllama模型 {model} 预热失败: {e}) # 在FastAPI的startup事件中调用 app.on_event(startup) async def startup_event(): warmup_ollama_models()4.5 坑五litellm.token_counter计算不准导致用量统计偏差现象用litellm.token_counter(modelgpt-3.5-turbo, texthello world)返回3但实际API返回的usage.prompt_tokens是4。根因分析LiteLLM的token_counter是基于tiktoken库的简化实现它假设所有模型都用cl100k_base编码。但Ollama的Qwen2用的是qwen2tokenizerClaude用的是anthropictokenizer它们的分词规则完全不同。token_counter无法动态识别模型的真实tokenizer。解决方案永远以API返回的usage字段为准。在success_callback中记录def log_usage(kwargs, response, start_time, end_time): # 只取response.usage忽略token_counter if response.usage: prompt_tokens response.usage.prompt_tokens completion_tokens response.usage.completion_tokens total_tokens response.usage.total_tokens # 记录到数据库或监控系统重要提醒litellm.token_counter只适合做“估算”和“本地开发调试”绝不能用于计费或配额控制。生产环境必须依赖模型提供商返回的usage。4.6 坑六Router在高并发下内存泄漏服务OOM现象服务运行24小时后内存占用从500MB涨到4GBps aux显示Python进程占满内存最终被OOM Killer杀死。根因分析LiteLLM的Router默认启用了cache_responsesTrue它会把每次成功的响应缓存到内存中用于/health检查和get_model_info。在高频调用场景下缓存不断累积且没有LRU淘汰策略。解决方案关闭响应缓存改用外部缓存router Router( model_listconfig[model_list], cache_responsesFalse, # 关键禁用内存缓存 redis_hostos.getenv(REDIS_HOST, localhost), redis_portint(os.getenv(REDIS_PORT, 6379)), redis_passwordos.getenv(REDIS_PASSWORD, ), )LiteLLM支持Redis作为外部缓存后端这样既保留了缓存收益又避免了内存泄漏。4.7 坑七set_verboseTrue开启后日志刷屏磁盘爆满现象开启详细日志后/var/log/app.log每小时增长2GB一周后磁盘100%。根因分析set_verboseTrue会打印每一行请求/响应的完整body包括base64图片、长文本等日志体积爆炸。解决方案分级日志 敏感信息过滤。创建utils/safe_logger.pyimport logging import json from litellm import verbose_logger # 创建专用Logger safe_logger logging.getLogger(litellm_safe) safe_logger.setLevel(logging.INFO) handler logging.FileHandler(/var/log/litellm_safe.log) formatter logging.Formatter(%(asctime)s - %(name)s - %(levelname)s - %(message)s) handler.setFormatter(formatter) safe_logger.addHandler(handler) # 替换LiteLLM的verbose_logger litellm.verbose_logger safe_logger # 重写日志方法过滤敏感内容 def safe_log_request(kwargs): # 移除API Key、长文本等 safe_kwargs kwargs.copy() safe_kwargs.pop(api_key, None) safe_kwargs.pop(api_base, None) if messages in safe_kwargs: for msg in safe_kwargs[messages]: if len(msg.get(content, )) 200: msg[content] msg[content][:100] ...(TRUNCATED) safe_logger.info(fRequest: {json.dumps(safe_kwargs, ensure_asciiFalse)}) litellm.success_callback [lambda *args: safe_log_request(args[1])]这套方案让日志体积下降90%同时保留了关键诊断信息。5. 超越调用LiteLLM在AI工程化中的延伸价值LiteLLM常被当作“API调用工具”但它真正的战略价值在于成为AI工程化MLOps for LLM的基础设施底座。它正在悄然改变我们构建AI应用的方式。5.1 模型即服务MaaS的实践基石过去一个“AI功能”意味着选模型→写调用→测效果→上线→监控→迭代。每个环节都耦合在具体模型上。LiteLLM把“模型”抽象成了一个可插拔的服务单元。我们现在定义一个新功能流程变成了在model_config.yaml中注册新模型如groq/llama3-70b-8192写一个路由规则如“当用户选择‘极致性能’时路由到Groq”更新前端下拉菜单选项发布。整个过程无需修改一行业务逻辑代码。这实现了真正的模型即服务Model-as-a-Service。运维同学可以在Kubernetes里独立扩缩容Groq的代理Pod而业务服务完全无感。这种解耦让AI能力的交付周期从“周级”压缩到“小时级”。5.2 提示工程Prompt Engineering的工业化流水线提示词Prompt的质量直接决定AI输出的效果。但提示词优化长期停留在“人工试错”阶段。LiteLLM的统一接口让我们能把提示工程变成可编程、可测试、可版本化的工程实践。我们构建了一个PromptTester工具from litellm import Router import pandas as pd class PromptTester: def __init__(self, router: Router): self.router router def run_ab_test(self, prompts: List[str], models: List[str], test_cases: List[str]) - pd.DataFrame: 对同一组测试用例在多个promptmodel组合上跑A/B测试 results [] for prompt in prompts: for model in models: for case in test_cases: try: response self.router.completion( modelmodel, messages[{role: user, content: prompt.format(inputcase)}], temperature0.1 ) results.append({ prompt: prompt[:50] ..., model: model, input: case[:30] ..., output: response.choices[0].message.content[:100] ..., latency: response._response_ms, tokens: response.usage.total_tokens if response.usage else 0 }) except Exception as e: results.append({ prompt: prompt[:50
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑