fix(aibox): 修复工具调用配对缺失导致的 insufficient tool messages 400
当 assistant 携带 tool_calls 但对应 tool 响应缺失(工具被中断/压缩丢弃)时, 下一次请求报 400。新增 _repair_tool_pairs 在构建请求前补齐缺失的 tool 响应。
This commit is contained in:
1 parent
d24066369b
commit
02904f711e
1 file changed
+46
@@ -7003,6 +7003,10 @@ class DeepSeekChat:
|
||||
if self.history_manager:
|
||||
self.history_manager.add_message("user", enhanced_input, "用户")
|
||||
|
||||
# 修复工具调用配对:确保每个 assistant 的 tool_calls 都有对应 tool 响应,
|
||||
# 防止因工具被中断/压缩导致 "insufficient tool messages" 报 400
|
||||
self._repair_tool_pairs()
|
||||
|
||||
# 构建消息列表,确保包含 reasoning_content
|
||||
enhanced_messages = []
|
||||
|
||||
@@ -7296,6 +7300,48 @@ class DeepSeekChat:
|
||||
except Exception as e:
|
||||
self.logger.error(f"消息回滚失败: {e}")
|
||||
|
||||
def _repair_tool_pairs(self):
|
||||
"""修复消息历史中的工具调用配对,保证 API 消息结构合法。
|
||||
|
||||
场景:assistant 消息携带 tool_calls,但对应的 tool 响应缺失(工具被中断、
|
||||
压缩算法丢弃、端对话提前 break 等),下一次请求会因
|
||||
"insufficient tool messages following tool_calls" 返回 400。
|
||||
修复策略:为每个缺失响应的 tool_call_id 补一条占位 tool 消息,使其配对完整。
|
||||
"""
|
||||
if not self.messages:
|
||||
return
|
||||
repaired = []
|
||||
i = 0
|
||||
n = len(self.messages)
|
||||
while i < n:
|
||||
msg = self.messages[i]
|
||||
role = msg.get("role")
|
||||
tool_calls = msg.get("tool_calls") if role == "assistant" else None
|
||||
if not tool_calls:
|
||||
repaired.append(msg)
|
||||
i += 1
|
||||
continue
|
||||
# 收集紧随其后的 tool 消息
|
||||
needed = [tc.get("id") for tc in tool_calls if tc.get("id")]
|
||||
j = i + 1
|
||||
tool_msgs = []
|
||||
while j < n and self.messages[j].get("role") == "tool":
|
||||
tool_msgs.append(self.messages[j])
|
||||
j += 1
|
||||
have = {tm.get("tool_call_id") for tm in tool_msgs if tm.get("tool_call_id")}
|
||||
# 补齐缺失的 tool 响应
|
||||
for tid in needed:
|
||||
if tid not in have:
|
||||
tool_msgs.append({
|
||||
"role": "tool",
|
||||
"tool_call_id": tid,
|
||||
"content": "⚠️ 该工具调用未返回结果(可能被中断)。",
|
||||
})
|
||||
repaired.append(msg) # 保留 assistant 消息本身
|
||||
repaired.extend(tool_msgs)
|
||||
i = j
|
||||
self.messages = repaired
|
||||
|
||||
def reset_conversation(self, reload_prompts: bool = True):
|
||||
"""
|
||||
重置对话状态 - 清除所有对话记忆,可选择是否重新加载系统提示词
|
||||
|
||||
Reference in new issue
Block a user