# Issue #56: 异步上下文压缩中的关键工具调用破坏和多个可靠性问题

## 概述
本文档汇总了 [GitHub Issue #56](https://github.com/Fu-Jie/openwebui-extensions/issues/56) 中所有关于异步上下文压缩过滤器的已报告问题。

---

## 问题列表

### 1. 🔴 关键：原生工具调用历史可能被破坏

**严重级别**: 关键  
**影响范围**: 对话完整性

#### 描述
压缩逻辑逐条删除消息，而不是把原生工具调用结构作为原子整体保留。这可能会破坏 assistant `tool_calls` 与其对应 `tool` 结果消息的关系。

#### 症状
```
No tool call found for function call output with call_id ...
```

#### 根本原因
- 包含 `tool_calls` 的 assistant 消息可能被删除，但其对应的 `tool` 结果消息仍保留
- 这会产生孤立的工具输出，引用不存在的 `tool_call_id`
- 模型/API 提供商会拒绝该请求，因为 `call_id` 不再匹配历史中的任何工具调用

#### 期望行为
压缩必须把工具调用块当作原子整体对待：
- `assistant(tool_calls)` 消息
- 对应的 `tool` 结果消息
- 可选的 assistant 跟进消息（消费工具结果）

这些消息的任何部分都不应被分割或部分删除。

---

### 2. 🟠 高优先级：压缩进度混淆了原始历史和压缩视图语义

**严重级别**: 高  
**影响范围**: 摘要进度一致性

#### 描述
插件将 `compressed_message_count` 存储为原始对话历史的进度，但稍后从已压缩的对话视图重新计算。这混淆了同一字段的两个不同坐标系。

#### 问题
- 原始历史进度（压缩前）
- 压缩视图进度（压缩后）

这两个含义不一致，造成：
- 摘要进度变得不一致
- 摘要已存在后进度可能停滞
- 后续更新用不同于存储值的坐标系测量

#### 期望行为
进度跟踪必须在对话整个生命周期中使用单一、一致的坐标系。

---

### 3. 🟡 中等优先级：异步摘要生成没有每聊天锁

**严重级别**: 中等  
**影响范围**: 令牌使用、竞态条件

#### 描述
每个响应都可能为同一聊天启动新的后台摘要任务，即使已有任务在进行中。

#### 问题
- 摘要工作重复
- 令牌使用增加
- 已保存摘要状态出现竞态条件
- 数据一致性问题

#### 期望行为
使用每聊天锁机制确保每次只有一个摘要任务在该聊天中运行。

---

### 4. 🟡 中等优先级：原生工具输出裁剪太激进

**严重级别**: 中等  
**影响范围**: 技术对话的内容准确性

#### 描述
工具输出裁剪启发式方法会重写或裁剪普通 assistant 消息，如果包含诸如以下模式：
- 代码围栏（三个反引号）
- `Arguments:` 文本
- `<tool_code>` 标签

#### 问题
这在技术对话中存在风险，可能无意中更改有效的 assistant 内容。

#### 期望行为
裁剪逻辑应更保守，避免修改非工具输出摘要的 assistant 消息。

---

### 5. 🟡 中等优先级：`max_context_tokens = 0` 语义不一致

**严重级别**: 中等  
**影响范围**: 确定性、配置清晰度

#### 描述
设置 `max_context_tokens = 0` 在不同代码路径中行为不一致：
- 在某些路径中：像"无阈值"一样（特殊模式，无压缩）
- 在其他路径中：仍然触发缩减/截断逻辑

#### 问题
非确定性行为使设置变得不可预测和令人困惑。

#### 期望行为
- 为 `max_context_tokens = 0` 定义清晰语义
- 在所有代码路径中一致应用
- 清楚地记录预期行为

---

### 6. 🔵 低优先级：破损的韩文 i18n 字符串

**严重级别**: 低  
**影响范围**: 韩文使用者的用户体验

#### 描述
一个翻译字符串包含破损的混合语言文本。

#### 期望行为
清理韩文翻译字符串，使其格式正确和语法正确。

---

## 相关/更广泛的上下文

**问题报告者附注**：关键错误不仅限于工具调用字段。由于压缩删除或替换整个消息对象，它还可能丢弃其他每消息字段，例如：
- 消息级 `id`
- `metadata`
- `name`
- 其他每消息属性

因此问题范围广于原生工具调用：任何依赖每消息元数据的集成在消息被裁剪或替换时也可能受影响。

---

## 复现步骤

1. 使用原生工具调用启动与模型的聊天
2. 启用异步上下文压缩过滤器
3. 发送足够长的对话以触发压缩/摘要生成
4. 让模型在几个回合中执行多个工具调用
5. 在过滤器已压缩部分历史后继续同一聊天

**期望**: 聊天继续正常运行  
**实际**: 聊天可能变得不同步并失败，出现错误如 `No tool call found for function call output with call_id ...`

**对照测试**:
- 禁用过滤器：不出现失败
- 启用过滤器：可靠地复现失败

---

## 建议的修复方向

### 高优先级（阻止 Issue #56）

1. **保护工具调用原子性**：以不分割 `assistant(tool_calls)` 与其对应 `tool` 消息的方式压缩历史
2. **统一进度跟踪**：在整个过程中使用单一、一致的坐标系统追踪 `compressed_message_count`
3. **添加每聊天锁**：确保每次只有一个后台摘要任务在该聊天中运行

### 中等优先级

4. **保守的裁剪**：精化工具输出裁剪启发式方法，避免更改有效 assistant 内容
5. **定义 `max_context_tokens = 0` 语义**：使行为一致且可预测
6. **修复 i18n**：清理破损的韩文翻译字符串

---

## 环境

- **插件**: async-context-compression
- **OpenWebUI 版本**: 0.8.9
- **操作系统**: Ubuntu 24.04 LTS ARM64
- **报告者**: @dhaern
- **问题日期**: [最近提交]

---

## 参考资源

- [GitHub Issue #56](https://github.com/Fu-Jie/openwebui-extensions/issues/56)
- 插件: `plugins/filters/async-context-compression/async_context_compression.py`
