快速结论:这个问题在 LiteLLM 1.94.x/1.95.x 版本中,开启 turn_off_message_logging: true 且启用数据库 spend logs 时触发。升级后引入的 _redact_tool_calls 会把工具参数替换成 redacted-by-litellm 占位符,而 spend-log 路径随后试图用 json.loads 解析这个自我写入的占位符,导致刷屏警告。优先排查方向是确认是否可升级到包含修复 PR(#36658)的版本,或临时回退到 1.93.x。
适用环境:LiteLLM v1.94.x 至 v1.95.x(报告出现于 v1.95.0,评论中提到从 1.92.2 或 1.93 升级到 1.94.3/1.95 后出现);使用数据库 spend logs 的代理环境;面向 Claude Code、opencode 等 agentic 客户端的部署场景。
最快修复方案:暂无确认的一步修复方案。Issue 提到有 PR(#36658)通过跳过对已编辑参数的解析来解决,但在该 PR 合并前,最干净的办法是固定 LiteLLM 版本到 1.93.x(即升级前未引入 _redact_tool_calls 的版本)。如果必须保持当前版本,可以过滤来自 factory.py:5380 的 WARNING 级日志。
注意事项:回退版本可能涉及其他功能变更,需评估兼容性;过滤日志只是掩盖问题而非修复;general_settings.disable_spend_logs 虽然能静默其中一个调用点,但会同时禁用 spend 日志,对需要计费网关的用户不可接受。
问题场景
LiteLLM 代理在 litellm_settings.turn_off_message_logging: true 且启用数据库 spend logs 时,每个包含工具调用的流式响应都会在每个工具调用后输出一条 WARNING 日志。面向 Claude Code、opencode 等编码代理时,几乎所有响应都带工具调用,导致该警告反复刷屏——实测在约 12 分钟内,1773 个 /v1/messages 请求产生 958 条警告,按 2.6 req/s 推算每天约产生 12 万行此类警告。
报错原文
{"message": "Failed to parse tool call arguments: Failed to parse tool call arguments for tool 'Read' (chat completions). Error: Expecting value: line 1 column 1 (char 0). Arguments: redacted-by-litellm", "level": "WARNING", "component": "LiteLLM", "logger": "factory.py:5380"}
原因分析
问题根源在于 LiteLLM 1.94.x 引入的 _redact_tool_calls(位于 redact_messages.py)。该函数在消息日志关闭时,会把工具调用的 arguments 替换为 redacted-by-litellm 占位符。随后 spend-log 路径上的 response_tool_call_names 会尝试对每个调用执行 json.loads 解析参数。解析占位符字符串必然失败(无任何括号或花括号),从而产生 WARNING。
关键因素:
- v1.94.x 重写了 spend-log 模块,将响应工具调用的处理统一路由到共享的
get_tool_calls_from_response,该辅助函数会为所有调用者(包括只需名称的调用者)急切解析arguments。 - 同一请求有两个独立调用点(
db_spend_update_writer.py:185的_enqueue_tool_usage_transaction和db_spend_update_writer.py:340的_enqueue_tool_registry_upsert)都执行response_tool_call_names,因此每个工具调用会解析两次、警告两次。 _attempt_json_repair无法修复占位符——输入没有任何未匹配的开括号/花括号时会返回None,因此全部走 raise 路径。
此问题不影响 Anthropic Messages 分支(tool_use 块的 input 是已解析的字典,直接跳过解析器),但 /v1/messages 仍会命中 chat 分支,因为透传日志处理器在回调运行前把 SSE 流重建成了 chat-completions 的 ModelResponse。
功能上并没有实际损坏:_parse_tool_call_arguments 会吞掉 ValueError 并返回 {},唯一消费方只读取 redaction 未触碰的 tool_call["name"],因此工具使用跟踪、LiteLLM_SpendLogToolIndex 和 LiteLLM_DailyToolSpend 都保持正确。问题纯粹在于一个正常的、预期的、自我引发的条件在热路径上以 WARNING 级别被报告。
环境排查
- 确认 LiteLLM 版本是否在 v1.94.x 至 v1.95.x 范围(v1.93.x 及更早版本无
_redact_tool_calls,不触发此问题)。 - 确认
litellm_settings.turn_off_message_logging是否为true。 - 确认是否启用了数据库 spend logs(DB spend logs)。
- 检查部署是否使用代理模式(database-backed proxy)。
- 客户端是否为 Claude Code、opencode 等频繁产生工具调用的 agentic 工具。
解决步骤
- 优先尝试:关注并等待 PR #36658 合并。该 PR 通过跳过对已编辑(redacted)参数的解析来解决问题。合并后升级到包含该修复的版本即可。
- 在修复版本可用前,最干净的规避方案是将 LiteLLM 固定回 v1.93.x(或升级前未引入
_redact_tool_calls的版本)。 - 如果必须保持当前版本,可过滤来自
factory.py:5380的 WARNING 级日志。注意:LITELLM_LOG环境变量只作用于导入时创建的 handler,且json_logs: true会重置所有 logger 的 handler 并丢弃该配置;目前没有代码路径会把verbose_logger提升到 WARNING 以上。 - 不要使用
general_settings.disable_spend_logs来压制此问题——它只静默两个调用点之一并禁用整个 spend 日志功能,对需要计费网关的场景不可接受。
验证方法
升级或回退版本后,在 turn_off_message_logging: true 和 DB spend logs 开启的情况下,发送包含工具调用的流式请求,观察日志中不再出现 Failed to parse tool call arguments 且包含 redacted-by-litellm 的 WARNING。同时确认工具使用跟踪(tool-usage tracking)和 spend 日志统计仍正常写入数据库。
参考来源
AI 工具推荐
想把多个 AI 模型放在一个入口?
GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。
推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。
这个方案解决了吗?
可以继续搜索完整报错,或查看同一工具的其他排查指南。
![[Bug]: Current main Docker compose fails to start with v0.25.6 image](https://www.chat-gpts.plus/wp-content/uploads/2026/08/15692-ba3ab69e-768x403.jpg)
![[Bug]: Dataflow pipeline crashes with KeyError: 'path' when stored DSL lacks the path key](https://www.chat-gpts.plus/wp-content/uploads/2026/08/18746-a051003b-768x403.jpg)
