快速结论:当 LiteLLM Router 开启 enable_pre_call_checks,且使用带 int 型 max_input_tokens 的 embedding 部署处理 list 形式的 input(批量文本、token id 或 token id 列表)时,预调用 token 计数会把 embedding 输入错误地送进 Responses API 输入转换逻辑,触发 AttributeError: 'str' object has no attribute 'get'。请求本身通常仍会成功,但上下文窗口检查被跳过,需要优先排查 Router 的预检查逻辑与版本。
适用环境:Issue 中已验证:LiteLLM 1.106.0 及 upstream main(commit d8c0e2c7153d82234ec46f0231bf9b9714e7d52a,2026-10-08 UTC)、Python 脚本直接运行、Docker 部署方式;评论反馈同样出现在 v1.104.0 与 main,并称 1.94.x、1.95.x 受影响,Azure embedding 部署亦复现。复现不需要代理 YAML 或 provider 凭据。
最快修复方案:升级到包含 PR #49851 的 LiteLLM 版本(该修复已合并)。暂无其他经 Issue 验证的一步配置修复方案。
注意事项:PR #49851 之后,没有 OpenAI tokenizer 的模型分组中,list[str] 输入不再报错,但其长度“目前仍不做检查”,即这类分组不会因单条超长输入被提前拦截。另外评论指出 embedding 限制是按单条 input 计算,直接对整批求和会得到错误结果,因此修复方式是比较最长的那条 input,而不是累加。
问题场景
使用 LiteLLM Router 做 embedding 负载均衡时,配置 enable_pre_call_checks=True,并通过 /embeddings 接口(或直接调用 Router 的预检查方法)传入 input 为字符串列表的批量请求。单条字符串输入(如 "first document")可以正常计数;传入 ["first document", "second document"] 时,Router 在 token 计数阶段抛出 AttributeError,日志提示 “failed to count tokens. Returning initial list of deployments”,随后直接返回原始部署列表并跳过上下文窗口检查。评论反馈在 Azure 上使用 base_model: azure/text-embedding-3-large 时,每次带 list input 的 /embeddings 请求都会出现该错误(24 小时内 356 次请求中约 344 次报错)。
报错原文
LiteLLM Router:ERROR: router.py:12911 - litellm.router.py::_pre_call_checks: failed to count tokens. Returning initial list of deployments. Got - 'str' object has no attribute 'get'
AttributeError: 'str' object has no attribute 'get'
异步路径下的变体(评论中提到):
LiteLLM Router:ERROR: router.py - litellm.router.py::_acount_pre_call_check_tokens: failed to count tokens. Got - 'str' object has no attribute 'get'
token id 形式的输入会报 'int' 或 'list' 版本的同名错误。
原因分析
最可能的原因是:Router._count_pre_call_check_tokens 会把 embedding 的 input 交给 LiteLLMCompletionResponsesConfig.transform_responses_api_input_to_messages 处理,而该函数会对每个条目调用 .get("type")。embedding 批量输入中的元素是字符串(或 int / list),没有 .get 方法,于是抛出 AttributeError。异常被捕获后,Router 只记录日志并回退到原始部署列表,导致 context check 静默失效。
评论补充的另一条件:只有当部署实际解析出 int 型 max_input_tokens(例如通过 Azure 部署的 base_model 解析)时才会走到 token 计数器;不在 cost map 中的 embedding 模型不会到达该逻辑,这可能是该问题此前较少被报告的原因。
环境排查
- 确认 LiteLLM 版本:1.106.0、1.104.0、1.94.x、1.95.x 及对应 upstream main 均被报告受影响;
_count_pre_call_check_tokens在 1.92.0 不存在、1.94.0 已存在。 - 确认 Router 配置中
enable_pre_call_checks是否为true。 - 确认 embedding 部署是否能解析出 int 型
max_input_tokens(例如是否配置了base_model,如azure/text-embedding-3-large)。 - 确认调用方式:
/embeddings的input是单个字符串还是 list;list 中元素是文本、token id 还是 token id 列表。 - 确认部署方式(Issue 中为 Docker)与是否配置了多 worker / Redis 等运行环境。
解决步骤
- 先复现并确认:在未修改的上游代码上,用 Issue 提供的
repro.py运行LITELLM_LOCAL_MODEL_COST_MAP=true PYTHONPATH=. python repro.py,观察单条输入返回 token 数、批量输入是否抛 AttributeError、以及_pre_call_checks后部署数量是否仍为 1。 - 检查当前 LiteLLM 版本是否已包含 PR #49851 的修复(维护者已确认合并),未包含则升级到该修复之后的版本。
- 若暂时无法升级,可参考评论中的补丁思路(非官方验证路径):在
_count_pre_call_check_tokens中先判断 embedding 输入,对文本用litellm.encode计数、对 token id 列表取其长度、对 int 列表取元素个数,并取整批中的最大值(而非求和)与max_input_tokens比较。注意这只是评论给出的 patch,需自行验证。 - 升级后在多 worker + Redis 的真实 embedding 部署上回归测试,确认批量请求不再产生该日志,且单条超长输入会在调用 provider 前被拦截(返回 400)。
验证方法
重跑 Issue 的复现脚本:单条输入应返回正常 token 数,批量 list[str] 输入不再抛 AttributeError: 'str' object has no attribute 'get',并且 _pre_call_checks 能根据最长单条输入执行上下文检查;发送一条超过 max_input_tokens 的单条 embedding 输入,应看到 ContextWindowExceededError 或接口返回 400,而不是静默通过。生产环境中可观察 Router 日志是否不再出现 “failed to count tokens” 的 embedding 相关记录。
参考来源
AI 工具推荐
想把多个 AI 模型放在一个入口?
GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。
推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。
这个方案解决了吗?
可以继续搜索完整报错,或查看同一工具的其他排查指南。
![[Bug]: Reservation reseed marks actual cost applied without incrementing it](https://www.chat-gpts.plus/wp-content/uploads/2026/11/35570-cb9f3004-768x403.jpg)
![[Bug]: Azure AI Claude Mythos 5.1 has no cost-map entry and records zero spend](https://www.chat-gpts.plus/wp-content/uploads/2026/11/49865-d8be4142-768x403.jpg)
