[Bug]: AGUIChatWorkflow.aggregate_tool_calls only appends ToolMessages for backend tools, orphaning frontend tool_call_ids

使用 AGUIChatWorkflow ( llama-index-protocols-ag-ui )时触发。典型场景:Agent 在同一轮中同时调用了后端工具(如计算函数)和前端工具(如 UI 渲染)。用户可能使用 MockFunctionCallingLLM 进行测试,或在实际 AG-UI 流程

[Bug]: AGUIChatWorkflow.aggregate_tool_calls only appends ToolMessages for backend tools, orphaning frontend tool_call_ids

[Bug]: AGUIChatWorkflow.aggregate_tool_calls only appends ToolMessages for backend tools, orphaning frontend tool_call_ids

快速结论:当 LLM 在同一轮中同时选择后端工具和前端工具时(即典型的 AG-UI 场景),chat_history 中缺少前端工具对应的 ChatMessage(role="tool"),导致 LLM 调用时出现 tool_use_id ... has no matching tool_result 错误。

问题场景

使用 AGUIChatWorkflowllama-index-protocols-ag-ui)时触发。典型场景:Agent 在同一轮中同时调用了后端工具(如计算函数)和前端工具(如 UI 渲染)。用户可能使用 MockFunctionCallingLLM 进行测试,或在实际 AG-UI 流程中遇到 HTTP 400 错误。

报错原文

HTTP 400: tool_use_id ... has no matching tool_result

注:此错误由 LLM 提供方(如 OpenAI)返回,表明 chat_history 中的 AIMessage 包含的 tool_call_id 没有对应的 ToolMessage

原因分析

AGUIChatWorkflow.aggregate_tool_calls 方法在 llama-index-protocols-ag-ui/llama_index/protocols/ag_ui/agent.py 中收集并行工具调用的结果(ToolCallResultEvent),并将其分为 frontend_tool_callsbackend_tool_calls。问题在于,它仅基于 backend_tool_calls 构建 new_tool_messages(即添加 ChatMessage(role="tool")),然后将其追加到 chat_history 并持久化。如果存在 frontend_tool_calls,方法直接返回 StopEvent() 为前端工具的 tool_call_id 写入对应的 ToolMessage。这导致 chat_history 中包含了带有两个 tool_call_id 的 assistant 消息,但只有一个后端工具的 ToolMessage,违反了 LLM 提供方的“每个 tool_call_id 都必须有匹配 ToolMessage”的约定。

环境排查

  • 版本llama-index-protocols-ag-ui==0.3.1(问题版本),其他版本可能也存在此问题。
  • 相关包llama-index-core(特别是 MockFunctionCallingLLM)、llama-index-protocols-ag-ui
  • LLM 提供方:任何要求 tool_call_idToolMessage 配对的服务(如 OpenAI、Anthropic 等)。
  • 工作流AGUIChatWorkflow,它使用 chat_history channel 跨 ctx.store.set 边界持久化状态。

解决步骤

  1. 定位代码:打开 llama-index-integrations/protocols/llama-index-protocols-ag-ui/llama_index/protocols/ag_ui/agent.py,找到 aggregate_tool_calls 方法(约第 286–321 行)。
  2. 修改逻辑:在构建 new_tool_messages 的后端循环后,添加类似以下代码,为前端工具调用也生成对应的 ChatMessage(role="tool")
for tool_result in frontend_tool_calls:
    new_tool_messages.append(
        ChatMessage(
            role="tool",
            content=tool_result.tool_output.content,  # 或空字符串作为占位符
            additional_kwargs={
                "tool_call_id": tool_result.tool_call_id,
            },
        )
    )

注意:此修复基于 Issue 评论中的建议,尚未经过官方验证。尽管逻辑上正确,但请在实际应用前进行充分测试。

  1. 确保修改后的代码在 chat_history 扩展和 StopEvent() 返回之前运行,使历史记录保持配对合法性。

验证方法

使用 Issue 中提供的 Python 重现脚本(使用 MockFunctionCallingLLM 生成同时包含后端和前端工具调用的 assistant 消息)运行后,检查 chat_history 中的消息列表。确认在 StopEvent() 返回前,frontend_tool_calls 中的每个 tool_call_id 都已有一个对应的 ChatMessage(role="tool")。如果没有此配对,则问题仍然存在。另外,可以尝试在实际 AG-UI 环境中发起混合工具调用请求,观察是否还会出现 HTTP 400 错误。

参考来源

run-llama/llama_index #22066 — Issue 正文及 Dosu 机器人对问题的确认和修复建议。

GamsGo AI

AI 工具推荐

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

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

了解 GamsGo AI

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

celebrityanime
celebrityanime
文章: 14539

发表回复

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