diff --git a/core/prompts/templates/system_prompt.md b/core/prompts/templates/system_prompt.md
index 29319a1..f19256f 100644
--- a/core/prompts/templates/system_prompt.md
+++ b/core/prompts/templates/system_prompt.md
@@ -102,7 +102,7 @@ subject, relation, object 每个字段必须是一个**短关键字**(1~5个
| `memory_archive` | 信息过期需保留历史 | 将旧记忆归档而非删除,保留历史轨迹 |
| `memory_cleanup` | 确认数据异常 | 清理冗余/孤立节点(dry_run可预览) |
| `memory_query_archived` | 回顾归档历史 | 查询已归档的原始关系记录(status=archived),支持天数/关键词过滤 |
-| `context_rewrite` | 单轮调用了 5 次及以上查询类工具 | 压缩本轮工具调用的 JSON 参数和返回结果,剔除工具噪声,节省上下文 token。**必须是回复前的最后一步** |
+| `context_rewrite` | 单轮调用了 5 次及以上查询类工具 | 压缩本轮工具调用的 JSON 参数和返回结果,剔除工具噪声,节省上下文 token。**⚠️ 必须单独调用**:先调完其他所有工具并收到结果 → 再单独调 context_rewrite。不要和其他工具一起调 |
### 人设工具
| 工具 | 时机 | 说明 |
diff --git a/core/server.py b/core/server.py
index 21eff89..f356e72 100644
--- a/core/server.py
+++ b/core/server.py
@@ -345,6 +345,8 @@ class BackendServer:
messages_history.append(assistant_msg)
current_tool_results = []
+ deferred_rewrite = None # 延迟处理 context_rewrite
+
for tool_call in message.tool_calls:
args = json.loads(tool_call.function.arguments)
@@ -364,26 +366,9 @@ class BackendServer:
self._tool_limiter.record_call(tool_call.function.name, args)
if tool_call.function.name == "context_rewrite":
- result = execute_tool(self._graph, tool_call.function.name, args)
- result_data = json.loads(result)
-
- # 记录到 tool_calls,让 TUI 显示这个工具调用
- tool_calls.append({
- "name": tool_call.function.name,
- "arguments": args,
- "result": result
- })
-
- if result_data.get("status") == "success":
- user_msg = messages_history[0]
- # 添加特殊标记,让 AI 知道这是上下文压缩的结果
- compressed_content = f"\n{result_data['summary']}\n"
- messages_history[:] = [
- user_msg,
- {"role": "assistant", "content": compressed_content}
- ]
- # context_rewrite 压缩上下文后,不需要添加 tool 结果消息
- # 因为 messages_history 已经被重写为压缩后的状态
+ # 延迟执行 context_rewrite:先处理完其他所有工具
+ # 避免在迭代中途重写 messages_history 导致 tool 结果丢失对应的 tool_calls
+ deferred_rewrite = (tool_call.id, args)
continue
result = execute_tool(self._graph, tool_call.function.name, args)
@@ -400,8 +385,30 @@ class BackendServer:
}
current_tool_results.append(tool_result_msg)
+ # 先添加所有非 context_rewrite 工具的结果到消息历史
messages_history.extend(current_tool_results)
+ # 再处理延迟的 context_rewrite(作为本轮最后一步)
+ if deferred_rewrite:
+ tool_call_id, args = deferred_rewrite
+ result = execute_tool(self._graph, "context_rewrite", args)
+ result_data = json.loads(result)
+
+ tool_calls.append({
+ "name": "context_rewrite",
+ "arguments": args,
+ "result": result
+ })
+
+ if result_data.get("status") == "success":
+ user_msg = messages_history[0]
+ compressed_content = f"\n{result_data['summary']}\n"
+ messages_history[:] = [
+ user_msg,
+ {"role": "assistant", "content": compressed_content}
+ ]
+ # 不添加 context_rewrite 的 tool 结果到历史(压缩后的历史已替代)
+
response = self._client.send_message_with_history(messages_history)
message = response.choices[0].message
diff --git a/core/tools/memory_tools.py b/core/tools/memory_tools.py
index 5919ea4..61d7187 100644
--- a/core/tools/memory_tools.py
+++ b/core/tools/memory_tools.py
@@ -299,11 +299,16 @@ memory_query_archived({"days": 30, "keyword": "配置"})
"description": """压缩本轮对话的工具调用上下文。将冗长的JSON工具结果提炼为简洁摘要。
【使用场景】
-- 已执行多次工具调用,JSON细节已理解,不再需要原始格式
+- 本轮已执行 ≥5 次查询类工具调用,JSON细节已理解,不再需要原始格式
- 但需保留"我调用了什么工具、得到了什么结论"的元认知
- 继续携带原始JSON会干扰后续推理
-【⚠️ 强制格式要求】
+【⚠️ 强制要求】
+**context_rewrite 必须单独调用,不能和其他工具在同一轮一起调!**
+- 正确方式:先调其他所有工具 → 收到工具结果 → 单独调 context_rewrite
+- 错误方式:和其他工具一起调(会破坏对话历史结构)
+
+【格式要求】
1. 必须标注调用了哪些工具
2. 必须标注是对几次工具调用的总结
3. 必须保留关键语义信息
@@ -316,7 +321,7 @@ memory_query_archived({"days": 30, "keyword": "配置"})
【注意事项】
- 不可删除用户原始消息
- 不可歪曲工具返回的关键事实
-- 仅在工具调用 ≥ 2 次后使用""",
+- 仅在调用 ≥5 次查询类工具后使用""",
"parameters": {
"type": "object",
"properties": {