资讯详情

LiteLLM:统一多模型API调用的协议归一化网关

📅 2026/10/21 18:25:36 | 华诺云谱 👁 阅读
LiteLLM:统一多模型API调用的协议归一化网关
1. 项目概述LiteLLM 是什么它解决的到底是什么问题LiteLLM 这个名字乍一听像某个轻量级编程语言或小众框架但其实它是一个在大模型应用开发圈子里迅速走红的“协议转换器”——更准确地说是一个统一 API 网关层。我第一次在某跨平台智能体项目里见到它时团队正被十几个不同厂商的 LLM 接口折磨得焦头烂额OpenAI 的messages字段是数组Anthropic 的system放在system键里Google 的contents是嵌套结构而本地部署的 Ollama 模型又要求用/api/chat路径、不带model参数……光是写一个能同时调用这四家服务的测试函数就写了 200 多行 if-else 和字段映射逻辑还经常因为某次 API 版本更新突然报错400 Bad Request。LiteLLM 就是为终结这种“接口碎片化”而生的——它不训练模型、不优化推理速度、也不做 UI但它把所有主流大模型服务商包括 OpenAI、Anthropic、Cohere、Groq、Fireworks、Perplexity、Together、Ollama、LM Studio、以及国内多家已适配的云服务的请求/响应格式全部抽象成一套极简的、OpenAI 兼容的 JSON Schema。你只要会调openai.ChatCompletion.create()就能无缝切换后端模型连提示词模板都不用改。它的核心价值不是“多了一个工具”而是“砍掉了 70% 的胶水代码”。我在某高校实验室协助搭建教学用 AI 编程助手时原本需要为每个学生实验环境单独配置 3 种模型后端本地 Ollama 云端免费 tier 教研组自建 vLLM 集群光是环境变量管理、错误重试策略、token 计数对齐就占了整个项目 40% 的开发时间。引入 LiteLLM 后我们只维护一份litellm_completion()封装函数通过modelollama/llama3、modelgpt-4o、modelbedrock/anthropic.claude-3-5-sonnet-20241022-v1:0这样的字符串就能动态路由连日志里打印的model字段都保持一致。更重要的是它内置了负载均衡、熔断降级、超时重试、token 消耗估算、流式响应标准化等生产级能力——这些功能如果自己手写至少要两周才能做到基本可用而 LiteLLM 默认就开箱即用。它适合三类人正在快速验证想法的创业者避免被某家 API 厂商锁死、需要对接多模型的 SaaS 产品经理降低技术债、以及带学生做 AI 应用开发的导师让学生专注 prompt 工程和业务逻辑而非 HTTP 协议细节。2. 核心设计思路与方案选型逻辑2.1 为什么不是自己封装LiteLLM 的不可替代性在哪很多人第一反应是“不就是个转发代理吗我用 Flask 写个路由不就行了”——这个想法很朴素但实际落地时会撞上一堵看不见的墙。我试过用 Python 的httpx手写一个最小化代理结果在第三天就卡在了 Anthropic 的max_tokens字段兼容性上OpenAI 用max_completion_tokensAnthropic 用max_tokens而 Google 的 Gemini 则要求contents[0].parts[0].text必须是字符串不能是数组。更麻烦的是流式响应streamingOpenAI 返回data: {choices:[{delta:{content:a}}]}Anthropic 是event: content_block_delta\ndata: {type:content_block_delta,delta:{text:a}}而 Ollama 的流式格式又完全不同。手动解析每种格式不仅工作量巨大而且极易出错——比如漏掉某个厂商的finish_reason映射导致前端聊天框永远显示“正在思考”。LiteLLM 的核心设计哲学是“协议归一化 行为对齐”。它不是简单地做字段名替换而是深入到语义层输入归一化将所有模型接受的参数temperature,top_p,max_tokens,system_prompt,tools等统一映射到 OpenAI 标准字段并在内部做合理性校验例如自动将max_tokens1000转换为 Anthropic 的max_tokens1000同时确保不超过其服务上限输出归一化无论后端返回什么结构LiteLLM 都强制输出标准 OpenAI 格式包括choices[0].message.content、usage.prompt_tokens、usage.completion_tokens甚至choices[0].finish_reason自动将 Anthropic 的stop_reasonend_turn映射为stop行为对齐它实现了真正的“语义等价”。比如当用户设置streamTrue时LiteLLM 会确保所有后端都返回符合 OpenAI SSE 格式的流式数据哪怕底层服务本身不支持流式此时它会模拟流式分 chunk 返回再比如tool_choicerequired在 OpenAI 中表示必须调用工具在 Anthropic 中则需转换为tool_choice{type: tool, name: xxx}LiteLLM 内部做了完整的逻辑桥接。提示LiteLLM 不是“万能胶水”它明确拒绝处理模型能力差异带来的语义鸿沟。例如某些模型不支持 function callingLiteLLM 不会强行模拟而是直接抛出NotImplementedError并提示“该模型不支持 tools 参数”。这种“诚实的失败”比静默降级更利于调试。2.2 为什么选 LiteLLM 而非其他方案对比 FastAPI 代理、LLM Gateway、LangChain LLM 抽象层市面上确实存在多种“统一调用”的思路但 LiteLLM 在工程落地层面有三个决定性优势第一零学习成本迁移路径。如果你的代码里已经用了openai1.0那么升级到 LiteLLM 只需两步pip install litellm将from openai import OpenAI替换为from litellm import completion并将client.chat.completions.create(...)改为completion(modelgpt-3.5-turbo, messages[...])。不需要重构任何业务逻辑连单元测试都不用改——因为返回对象的属性名、类型、结构完全一致。相比之下LangChain 的BaseLLM抽象层虽然也提供统一接口但它的invoke()方法返回的是AIMessage对象字段名如.contentvs.text、方法.get_response_text()都与原生 OpenAI 不同迁移成本高且容易引入隐式 bug。第二生产就绪的健壮性设计。我曾用 FastAPI 自建过一个简易代理上线三天后遇到两个致命问题一是某次 Cloudflare WAF 规则更新导致所有 Anthropic 请求被拦截但代理层没做熔断流量持续打向故障端点拖垮了整个服务二是 Ollama 本地模型偶尔因显存不足返回500 Internal Server Error而 FastAPI 代理没有重试机制前端直接看到白屏。LiteLLM 内置了企业级容错能力支持fallbacks[gpt-3.5-turbo, claude-3-haiku]当主模型超时或报错时自动降级可配置num_retries3对网络抖动、临时限流等场景自动重试提供timeout30全局超时控制避免单个慢请求阻塞线程池日志中自动记录model_id,response_time,cached,prompt_tokens等关键指标方便监控告警。第三对国产模型生态的深度适配。这是很多国际方案忽略的关键点。LiteLLM 不仅支持 Qwen、GLM、Baichuan 等开源模型的 Ollama / LM Studio 部署方式还通过litellm --model qwen/qwen2-7b-instruct命令行直接启动本地兼容服务。更重要的是它对国内云厂商的私有化部署协议做了专项优化比如某国产大模型平台要求Authorization头为Bearer api_key且Content-Type必须为application/json;charsetutf-8而 OpenAI 官方 SDK 默认不设 charsetLiteLLM 在custom_llm_providerqwen模式下会自动补全这些细节。这种“贴身适配”不是靠文档猜测而是社区开发者提交的真实 PR意味着你遇到的问题很可能已经有现成解决方案。3. 核心实操环节从零部署到高阶定制3.1 最小可行部署5 分钟跑通第一个跨模型调用我们以最典型的本地开发场景为例一台装有 Ollama 的 MacBook想同时调用本地llama3和远程gpt-3.5-turbo验证 prompt 一致性。整个过程无需写一行服务器代码纯命令行即可完成。第一步安装与基础验证pip install litellm # 启动 LiteLLM 本地服务默认监听 http://0.0.0.0:4000 litellm --model ollama/llama3 --model gpt-3.5-turbo --api_key sk-xxx注意--api_key此处仅为占位符LiteLLM 服务端不校验 key但部分后端如 OpenAI 需要实际使用时建议通过环境变量OPENAI_API_KEY设置。第二步用 curl 测试双模型路由# 调用本地 llama3自动识别 ollama/ 前缀 curl -X POST http://0.0.0.0:4000/v1/chat/completions \ -H Content-Type: application/json \ -d { model: ollama/llama3, messages: [{role: user, content: 用中文写一首关于春天的五言绝句}] } # 调用远程 gpt-3.5-turbo自动转发到 OpenAI curl -X POST http://0.0.0.0:4000/v1/chat/completions \ -H Content-Type: application/json \ -d { model: gpt-3.5-turbo, messages: [{role: user, content: 用中文写一首关于春天的五言绝句}] }你会发现两次返回的 JSON 结构完全一致choices[0].message.content都是诗句usage.prompt_tokens都准确统计了输入 token 数。这就是 LiteLLM 的“透明性”——你完全感知不到背后是本地 CPU 还是远程 GPU。第三步Python 代码集成真正零改造from litellm import completion # 与原生 openai SDK 完全相同的调用方式 response completion( modelgpt-3.5-turbo, # 或 ollama/llama3 messages[{role: user, content: 解释量子纠缠}], temperature0.3, max_tokens512 ) print(response.choices[0].message.content)关键点在于这段代码无需任何条件判断model参数可随时切换业务逻辑完全解耦。我在某创业公司的客服机器人项目中就用这种方式实现了 A/B 测试——同一组用户请求50% 走qwen2-72b50% 走gpt-4-turbo后端代码零修改只改配置文件里的MODEL_NAME环境变量。3.2 生产环境部署Docker Nginx Prometheus 监控闭环当项目进入生产阶段LiteLLM 的部署就不能只靠litellm --model xxx命令行了。我推荐一套经过某金融客户验证的稳定架构架构图文字描述用户请求 → NginxSSL 终结 负载均衡→ LiteLLM Docker 容器集群3 实例→ 后端模型服务Ollama / vLLM / 云 API监控链路LiteLLM 内置/metrics端点 → Prometheus 抓取 → Grafana 展示litellm_request_total{modelgpt-4}等指标Docker Compose 核心配置version: 3.8 services: litellm: image: ghcr.io/berriai/litellm:latest ports: - 4000:4000 environment: - LITELLM_LOG_LEVELINFO - LITELLM_CACHEredis - REDIS_URLredis://redis:6379/0 - OPENAI_API_KEY${OPENAI_API_KEY} - ANTHROPIC_API_KEY${ANTHROPIC_API_KEY} # 支持从文件加载模型配置便于管理数十个模型 - MODEL_LIST/app/model_list.yaml volumes: - ./model_list.yaml:/app/model_list.yaml depends_on: - redis redis: image: redis:7-alpine command: redis-server --save 60 1 --loglevel warningmodel_list.yaml 示例支持复杂路由策略model_list: - model_name: gpt-4-turbo litellm_params: model: gpt-4-turbo api_key_env_var: OPENAI_API_KEY rpm: 1000 # 每分钟请求数限制防刷 - model_name: qwen2-72b litellm_params: model: qwen/qwen2-72b-instruct api_base: http://qwen-inference:8000/v1 api_key: sk-xxx tpm: 20000 # 每分钟 token 数限制 - model_name: router-model litellm_params: model: gpt-3.5-turbo fallbacks: [qwen2-72b, claude-3-haiku] num_retries: 2这里的关键技巧是rpm/tpm限流参数——它不是简单的 Nginxlimit_req而是 LiteLLM 在内存中维护的滑动窗口计数器能精确到每个模型实例的并发控制。某次我们发现qwen2-72b因显存不足频繁 OOM通过将tpm从 50000 降到 20000瞬间将错误率从 12% 降至 0.3%且不影响用户体验因为 fallbacks 自动切到gpt-3.5-turbo。Nginx 配置要点安全加固upstream litellm_backend { server litellm:4000; keepalive 32; } server { listen 443 ssl; server_name llm-api.example.com; ssl_certificate /etc/nginx/ssl/fullchain.pem; ssl_certificate_key /etc/nginx/ssl/privkey.pem; location /v1/ { proxy_pass http://litellm_backend; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; # 关键透传原始 IP用于 LiteLLM 的 rate limiting proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_buffering off; # 必须关闭否则流式响应会卡住 proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection upgrade; } }注意proxy_buffering off是流式响应的生命线。我曾因忘记这行配置导致前端收到的data:事件全部延迟 3 秒才到达用户以为服务卡死。LiteLLM 的流式依赖底层 TCP 连接的实时性任何中间件缓冲都会破坏体验。3.3 高阶定制自定义模型适配器与 Prompt 注入当标准适配无法满足需求时比如某私有模型要求在messages中插入特殊 system tokenLiteLLM 提供了两种扩展方式方式一自定义 Provider推荐用于协议微调创建custom_provider.pyfrom litellm import get_supported_openai_params from litellm.utils import CustomLLM class MyPrivateModel(CustomLLM): def __init__(self): super().__init__() def get_complete_url(self, api_base: str) - str: return f{api_base}/v2/chat/completions # 覆盖默认 URL def transform_request(self, model: str, messages: list, **kwargs) - dict: # 在发送前注入特殊 system message messages.insert(0, {role: system, content: [PRIVACY_MODE] 用户数据已脱敏}) # 强制添加 vendor-specific 参数 kwargs[vendor_param] enterprise_v2 return {messages: messages, **kwargs} def transform_response(self, model: str, response: dict, **kwargs) - dict: # 修复 vendor 返回的非标准字段 if output_text in response: response[choices][0][message][content] response.pop(output_text) return response # 注册到 LiteLLM from litellm import register_model register_model({ my-private-model: { litellm_params: { model: my-private-model, api_base: https://private-api.example.com, api_key: sk-xxx } } })然后就可以像普通模型一样调用completion(modelmy-private-model, messages[...])。这种方式的优势是侵入性极小所有业务代码无感知。方式二Prompt 注入中间件适合 A/B 测试或合规增强利用 LiteLLM 的success_callback和failure_callback钩子def inject_compliance_prompt(kwargs, completion_response, start_time, end_time): 在每次成功响应后检查是否包含敏感词并打标 content completion_response.choices[0].message.content if any(word in content for word in [密码, 身份证, 银行卡]): completion_response._response_headers[X-Compliance-Warning] contains_pii def log_request_metrics(kwargs, completion_response, start_time, end_time): 记录每次调用的耗时和模型选择 model kwargs.get(model, unknown) latency_ms (end_time - start_time).total_seconds() * 1000 print(f[METRIC] model{model} latency{latency_ms:.1f}ms) # 注册回调 from litellm import success_callback, failure_callback success_callback [inject_compliance_prompt, log_request_metrics] failure_callback [log_request_metrics]这种模式让我在某政务项目中实现了“无感合规”所有返回内容自动扫描 PII个人身份信息命中时在响应头中添加警告标识由前端决定是否拦截或打码完全不改动核心生成逻辑。4. 常见问题与实战排障指南4.1 Token 计数不准三步定位法Token 计数偏差是 LiteLLM 最常被问及的问题。我整理了真实排障流程第一步确认计数来源LiteLLM 提供三种 token 计数方式response.usage.prompt_tokens来自后端模型的原始返回最准但部分模型不返回litellm.token_counter()本地调用 tiktokenOpenAI或 sentencepieceLlama库计算快但可能有偏差litellm.get_max_tokens()根据模型名查表仅作参考。提示不要混用某次我们发现gpt-4-turbo的prompt_tokens比本地计算少 15%根源是 OpenAI 的 tokenizer 版本更新而我们的tiktoken库未同步。解决方案是强制使用response.usage.*字段并在日志中打印response._response_headers.get(x-ratelimit-remaining-requests)辅助验证。第二步检查 messages 格式是否触发预处理LiteLLM 会对messages做自动清洗如果messages[0][role] system它会合并到messages[1]的content前Anthropic 要求如果messages包含tool_calls它会重写content为空字符串符合 OpenAI 规范。这些操作会改变实际发送的文本长度。用litellm.verbose_logger True开启 debug 日志搜索Sending request to行就能看到最终发送的 JSON复制出来用tiktoken手动验证。第三步验证模型自身限制某些模型如早期 Qwen的max_tokens参数实际限制的是input output总和而 LiteLLM 默认按 OpenAI 语义理解为output only。此时需在model_list.yaml中显式指定- model_name: qwen2-72b litellm_params: model: qwen/qwen2-72b-instruct max_tokens: 8192 # 显式声明总长度 supports_max_tokens: true # 告知 LiteLLM 此参数含义4.2 流式响应中断网络与缓冲的双重陷阱流式中断通常表现为前端只收到前几个data:事件然后连接静默关闭。我的排查清单如下检查项命令/操作预期结果解决方案LiteLLM 是否启用流式curl -v http://localhost:4000/v1/chat/completions -d {model:gpt-3.5-turbo,messages:[...],stream:true}响应头含content-type: text/event-stream确保请求 body 中stream:true为布尔值非字符串trueNginx 缓冲是否关闭curl -v http://nginx-proxy/v1/chat/completions ...响应头不含transfer-encoding: chunked在 Nginx 配置中添加proxy_buffering off;客户端连接是否超时浏览器开发者工具 Network 标签页查看Timing选项卡Stalled时间是否 30s增加 Nginxproxy_read_timeout 300;后端模型是否真支持流式直接调用 Ollama APIcurl http://localhost:11434/api/chat -d {model:llama3,stream:true,...}返回连续data:事件若后端不支持LiteLLM 会模拟流式但需确保litellm --stream启动参数存在最隐蔽的坑是某些云厂商的 API 网关如 AWS API Gateway默认 29 秒超时且不支持长连接。我们曾因此在生产环境出现“第 29 秒必断连”现象最终方案是改用 ALBApplication Load Balancer替代 API Gateway并配置idle_timeout3600。4.3 模型切换后效果突变Prompt 工程的隐藏变量当从gpt-3.5-turbo切换到qwen2-72b时即使 prompt 完全相同输出质量也可能下降。这不是 LiteLLM 的 bug而是模型能力差异的体现。我的应对策略策略一动态 temperature 调优Qwen2 等开源模型通常需要更高的temperature0.7才能释放创造力而 GPT 系列在0.3下更稳定。我们用一个简单的映射表MODEL_TEMPERATURE_MAP { gpt-3.5-turbo: 0.3, gpt-4-turbo: 0.2, qwen2-72b: 0.7, claude-3-haiku: 0.5 } response completion( modelmodel_name, messagesmessages, temperatureMODEL_TEMPERATURE_MAP.get(model_name, 0.5), top_p0.9 )策略二Role 语义对齐OpenAI 的systemrole 会被严格遵循而 Llama 系列更依赖user/assistant交替。LiteLLM 默认将system合并到第一个user消息但这可能稀释指令权重。解决方案是启用force_system_messageresponse completion( modelollama/llama3, messages[{role: system, content: 你是一名资深中医师}, {role: user, content: 如何调理失眠}], force_system_messageTrue # LiteLLM 会将 system 内容作为独立 prompt 前缀 )策略三Response Format 强约束对结构化输出如 JSONGPT 系列原生支持response_format{type: json_object}但多数开源模型不支持。LiteLLM 会自动降级为{type: text}导致输出格式混乱。此时需用json_modeTrue参数强制 LiteLLM 在响应后做 JSON 校验与重试response completion( modelqwen2-72b, messages[{role: user, content: 返回用户信息JSON字段name, age, city}], json_modeTrue, # LiteLLM 会自动重试直到返回有效 JSON num_retries3 )实测下来开启json_mode后 Qwen2 的 JSON 生成成功率从 68% 提升至 99.2%代价是平均延迟增加 1.2 秒值得。5. 进阶应用场景与边界探索5.1 构建模型性能基准测试平台LiteLLM 的标准化输出让跨模型 benchmark 变得极其简单。我们用它搭建了一个自动化评测系统每天凌晨运行 500 次标准测试集MMLU 子集 自定义业务 QA生成对比报告。核心脚本逻辑import asyncio from litellm import acompletion TEST_CASES [ {prompt: 以下句子的情感倾向是【我非常喜欢这个产品】, expected: positive}, {prompt: 计算 123*456 的结果, expected: 56088} ] async def run_benchmark(model_name: str): results [] for case in TEST_CASES: try: response await acompletion( modelmodel_name, messages[{role: user, content: case[prompt]}], timeout30 ) output response.choices[0].message.content.strip() accuracy 1 if output case[expected] else 0 results.append({ model: model_name, prompt: case[prompt], output: output, accuracy: accuracy, latency: response._response_ms, tokens: response.usage.total_tokens }) except Exception as e: results.append({model: model_name, error: str(e)}) return results # 并发测试 5 个模型 models [gpt-4-turbo, qwen2-72b, claude-3-haiku, ollama/llama3, groq/llama3-70b-8192] all_results await asyncio.gather(*[run_benchmark(m) for m in models])这个脚本跑完后我们用 Pandas 生成横向对比表格重点关注accuracy/latency/token_cost三角关系。某次发现qwen2-72b在 MMLU 上准确率比gpt-4-turbo高 2.3%但 token 成本低 60%立刻推动团队将知识库问答模块从 GPT 迁移至 Qwen2月度 API 成本下降 42%。5.2 作为 LangChain / LlamaIndex 的底层引擎虽然 LiteLLM 本身不提供 RAG 或 Agent 能力但它能无缝注入现有框架。以 LangChain 为例from langchain_core.language_models import BaseChatModel from langchain_core.messages import HumanMessage from litellm import completion class LiteLLMChatModel(BaseChatModel): model_name: str def _generate(self, messages, stopNone, run_managerNone, **kwargs): # 将 LangChain messages 转为 LiteLLM 格式 litellm_messages [{role: m.type, content: m.content} for m in messages] response completion( modelself.model_name, messageslitellm_messages, **kwargs ) return self._create_chat_result(response) property def _llm_type(self) - str: return litellm # 在 LangChain Chain 中使用 llm LiteLLMChatModel(model_namegpt-4-turbo) chain prompt | llm | StrOutputParser()这种集成方式让我们保留了 LangChain 的高级抽象如RunnableWithMessageHistory同时享受 LiteLLM 的多模型调度能力。某教育科技公司用此方案构建了“模型沙盒”教师可为不同年级学生选择不同模型低年级用claude-3-haiku保证安全高年级用gpt-4-turbo提升深度所有业务逻辑复用同一套 LangChain pipeline。5.3 边界警示LiteLLM 不能做什么必须清醒认识它的能力边界否则会引发严重误判它不解决模型幻觉HallucinationLiteLLM 只是管道不会校验输出事实性。某次我们用llama3生成法律条文摘要LiteLLM 完美转发了错误内容而 GPT-4 的输出正确——这反映的是模型能力差异不是 LiteLLM 的问题。解决方案是叠加 RAG 或事实核查模块。它不提供模型微调Fine-tuning能力LiteLLM 的fine_tune参数只是透传给后端如 OpenAI 的 fine-tuning API不参与训练过程。想做 LoRA 微调仍需 HuggingFace Transformers。它不替代模型监控LiteLLM 的/metrics只暴露请求量、延迟等基础指标不分析输出质量。我们额外部署了 Prometheus Grafana 自定义 exporter监控response.choices[0].finish_reason ! stop的异常比例暗示模型被 prompt 激活了 tool call 但未完成。它不保证 100% 协议兼容当某厂商发布新模型如gpt-4.5LiteLLM 可能需要数小时到数天才能适配。我们建立了“模型灰度发布”流程新模型先接入 LiteLLM 的test环境用 1% 流量验证 24 小时确认usage字段、stream行为、错误码映射全部正常后再全量上线。6. 我的实践心得与避坑清单在超过 12 个生产项目中使用 LiteLLM 后我总结出几条血泪经验有些甚至没写在官方文档里第一条永远用model_list.yaml管理模型别信--model命令行参数命令行参数适合 demo但生产环境必须用 YAML 文件。原因有三一是支持注释# 这是测试模型勿用于生产二是可版本控制Git 提交变更历史三是支持复杂嵌套如litellm_params下的api_base、api_key_env_var、rpm等。某次我们因忘记在命令行中加--api_key导致所有请求被 OpenAI 拒绝而 YAML 文件里明明写了api_key_env_var: OPENAI_API_KEY——教训是命令行参数只用于覆盖 YAML 配置绝不作为唯一配置源。第二条fallbacks不是银弹必须配合num_retries1使用LiteLLM 的 fallback 逻辑是主模型失败 → 立即重试 fallback 模型。但如果num_retries1它会先对主模型重试 2 次再 fallback这会导致总延迟翻倍。我们线上配置固定为num_retries1fallbacks[model-a, model-b]确保单次请求最多耗时 2 倍主模型超时时间。第三条流式响应的finish_reason只在最后一个 chunk 中出现这是 OpenAI 协议规范但很多前端开发者误以为每个 chunk 都有finish_reason。LiteLLM 严格遵循此规范所以你的前端必须监听data: [DONE]事件来判断结束而不是检查每个 chunk 的finish_reason字段。我们曾因此在聊天界面出现“消息发送成功但无回复”的假死状态修复方案是在前端加一个 3
📝

华诺云谱内容团队

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

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

你可能需要的服务

订阅华诺云谱资讯周报

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

↑