Skip to content

[Bug]伪造工具调用(fake tool call)消息对在 OpenAI provider 中时序错乱 #9450

Description

@Rail1bc

What happened / 发生了什么

通过向 req.contexts 尾部注入 assistant(tool_calls) → tool(result) 消息对,可以强制 LLM 认为自己已经调用了某个工具并拿到了结果,从而:

  • 跳过 LLM 自身的工具调用决策,节省 token
  • 降低延迟(不需要等 LLM 生成工具调用)
  • 增加确定性(固定或规则触发,不受模型输出波动影响,增强确定性)

这是一种通用手法,已在 LivingMemory 插件中长期记忆注入中使用,未来可能被更多插件用于各种确定性工具调用场景。

但在 OpenAI_Provider._prepare_chat_payload() 中,处理顺序是:

  1. deepcopy(contexts) —— 此时尾部已含伪造工具调用对
  2. append(new_record) —— 追加当前用户消息

最终发给 LLM API 的 messages 序列为:

... assistant(tool_calls=...), tool(result), user("...")

LLM 视角下,assistant 在用户提问之前就"预知"了查询内容。正确顺序应为:

... user("..."), assistant(tool_calls=...), tool(result)

该问题影响所有使用该手法的插件,以及所有走 OpenAI_Provider 的 LLM 路径

Reproduce / 如何复现?

  1. 任何插件在 on_llm_request 钩子中向 req.contexts 尾部追加 assistant(tool_calls=...) + tool(result) 消息对
  2. 使用 OpenAI-compatible provider
  3. 观察实际发送给 LLM API 的 messages 尾部顺序

AstrBot version, deployment method (e.g., Windows Docker Desktop deployment), provider used, and messaging platform used. / AstrBot 版本、部署方式(如 Windows Docker Desktop 部署)、使用的提供商、使用的消息平台适配器

  • AstrBot 版本:4.26.8
  • 部署方式不限
  • 提供商:所有包含工具调用功能的api

OS

Linux

Logs / 报错日志

该issue描述的问题不存在明确的报错日志

Are you willing to submit a PR? / 你愿意提交 PR 吗?

  • Yes!

Code of Conduct

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:providerThe bug / feature is about AI Provider, Models, LLM Agent, LLM Agent Runner.bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions