What happened / 发生了什么
通过向 req.contexts 尾部注入 assistant(tool_calls) → tool(result) 消息对,可以强制 LLM 认为自己已经调用了某个工具并拿到了结果,从而:
- 跳过 LLM 自身的工具调用决策,节省 token
- 降低延迟(不需要等 LLM 生成工具调用)
- 增加确定性(固定或规则触发,不受模型输出波动影响,增强确定性)
这是一种通用手法,已在 LivingMemory 插件中长期记忆注入中使用,未来可能被更多插件用于各种确定性工具调用场景。
但在 OpenAI_Provider._prepare_chat_payload() 中,处理顺序是:
deepcopy(contexts) —— 此时尾部已含伪造工具调用对
append(new_record) —— 追加当前用户消息
最终发给 LLM API 的 messages 序列为:
... assistant(tool_calls=...), tool(result), user("...")
LLM 视角下,assistant 在用户提问之前就"预知"了查询内容。正确顺序应为:
... user("..."), assistant(tool_calls=...), tool(result)
该问题影响所有使用该手法的插件,以及所有走 OpenAI_Provider 的 LLM 路径
Reproduce / 如何复现?
- 任何插件在
on_llm_request 钩子中向 req.contexts 尾部追加 assistant(tool_calls=...) + tool(result) 消息对
- 使用 OpenAI-compatible provider
- 观察实际发送给 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 吗?
Code of Conduct
What happened / 发生了什么
通过向
req.contexts尾部注入assistant(tool_calls) → tool(result)消息对,可以强制 LLM 认为自己已经调用了某个工具并拿到了结果,从而:这是一种通用手法,已在 LivingMemory 插件中长期记忆注入中使用,未来可能被更多插件用于各种确定性工具调用场景。
但在
OpenAI_Provider._prepare_chat_payload()中,处理顺序是:deepcopy(contexts)—— 此时尾部已含伪造工具调用对append(new_record)—— 追加当前用户消息最终发给 LLM API 的 messages 序列为:
LLM 视角下,assistant 在用户提问之前就"预知"了查询内容。正确顺序应为:
该问题影响所有使用该手法的插件,以及所有走
OpenAI_Provider的 LLM 路径Reproduce / 如何复现?
on_llm_request钩子中向req.contexts尾部追加assistant(tool_calls=...)+tool(result)消息对AstrBot version, deployment method (e.g., Windows Docker Desktop deployment), provider used, and messaging platform used. / AstrBot 版本、部署方式(如 Windows Docker Desktop 部署)、使用的提供商、使用的消息平台适配器
OS
Linux
Logs / 报错日志
该issue描述的问题不存在明确的报错日志
Are you willing to submit a PR? / 你愿意提交 PR 吗?
Code of Conduct