AttributeError: ‘str’ object has no attribute ‘get’

当 LiteLLM Router 开启 enable_pre_call_checks ,且使用带 int 型 max_input_tokens 的 embedding 部署处理 list 形式的 input (批量文本、token id 或 token id 列表)时,预调用 token 计数会把

快速结论:当 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 等运行环境。

解决步骤

  1. 先复现并确认:在未修改的上游代码上,用 Issue 提供的 repro.py 运行 LITELLM_LOCAL_MODEL_COST_MAP=true PYTHONPATH=. python repro.py,观察单条输入返回 token 数、批量输入是否抛 AttributeError、以及 _pre_call_checks 后部署数量是否仍为 1。
  2. 检查当前 LiteLLM 版本是否已包含 PR #49851 的修复(维护者已确认合并),未包含则升级到该修复之后的版本。
  3. 若暂时无法升级,可参考评论中的补丁思路(非官方验证路径):在 _count_pre_call_check_tokens 中先判断 embedding 输入,对文本用 litellm.encode 计数、对 token id 列表取其长度、对 int 列表取元素个数,并取整批中的最大值(而非求和)与 max_input_tokens 比较。注意这只是评论给出的 patch,需自行验证。
  4. 升级后在多 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 相关记录。

参考来源

BerriAI/litellm #35626

BerriAI/litellm PR #49851

GamsGo AI

AI 工具推荐

想把多个 AI 模型放在一个入口?

GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。

了解 GamsGo AI

推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 33292

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注