agentscope-ai / agentscope-ai/agentscope-java

[Bug]:AnthropicChatModel 将 ThinkingBlock 作为普通 text 传回 API,导致 400 错误

Aperta
#2,400 2 commenti 0 reazioni 1 assegnatario Rivendicata da @logicwu0 Vedi su GitHub
area/build area/core/agent area/core/memory area/core/model bug help wanted
Lingua principale
Java
Stelle
5.6k
Fork
1.3k
Merge medio
4g 12h
PR unite (30g)
77

Descrizione

先撤销刚才的源码修改:

已撤销。以下是你可以提 issue 的完整描述:

---

## Issue:

### 环境信息
- AgentScope v2.0.0
- 模型:deepseek-v4-pro(通过 Anthropic 协议接入的第三方模型)
- 场景:多轮对话,ReActAgent

### 问题现象

多轮对话时,Anthropic API 报 400 错误:
```
The `content[].thinking` in the thinking mode must be passed back to the API.
```

### 根因

`AnthropicMessageConverter.java` 第131-137行,将 `ThinkingBlock` 转换为**普通 `TextBlockParam`** 传回 API:

```java
} else if (block instanceof ThinkingBlock thinkingBlock) {
contentBlocks.add(
ContentBlockParam.ofText(
TextBlockParam.builder()
.text(thinkingBlock.getThinking())
.build()));
}
```

问题在于:
1. 模型上一轮回复产生了 thinking 块,AgentScope 存入对话历史
2. 下一轮请求时,thinking 块被转成**普通 `text` 类型**传回 API
3. 但 Anthropic API 要求 thinking 内容必须用** `thinking` content type** 原样传回(包含 `thinking`、`signature` 等字段),不能用 `text` 类型
4. 如果对话经过 CompactionMiddleware 压缩,thinking 块可能被截断或丢失,传回不完整内容,API 直接报 400

### 触发条件

1. 使用 Anthropic 协议的模型(Claude / 第三方如 deepseek-v4-pro)
2. 开启了 thinking 模式(`enableThinking: true` 或 `thinkingBudget` 设了值)
3. 多轮对话(第二轮起),或对话历史经过 compaction 压缩后

### 建议修复

**方案A(推荐)**:ThinkingBlock 应该用 Anthropic 的 `thinking` content type 传回,包含 `thinking` 和 `signature` 字段,而不是转成 `text`:

```java
} else if (block instanceof ThinkingBlock thinkingBlock) {
// 用 Anthropic 原生的 thinking content type 传回
contentBlocks.add(ContentBlockParam.ofThinking(
ThinkingBlockParam.builder()
.type("thinking")
.thinking(thinkingBlock.getThinking())
.signature(thinkingBlock.getSignature()) // 需要在 ThinkingBlock 中保存 signature
.build()));
}
```

**方案B(兜底)**:如果无法保证 thinking 块的完整性(如 compaction 后),应该**跳过** ThinkingBlock,不传回 API:

```java
} else if (block instanceof ThinkingBlock) {
// Skip: thinking 块不完整时传回会导致 400
continue;
}
```

### 补充说明

- CompactionMiddleware 压缩后也会丢失 thinking 块的 `signature`,即使转成正确的 thinking type 也会失败
- 对于第三方模型(非 Claude 原生),thinking 的 signature 机制可能不适用
- 建议增加一个配置项:`stripThinkingBlocks=true`,在发送前移除所有 thinking 块

---

Guida per i contributori

Apri la guida per i contributori

Valutazione

Questa issue non è ancora stata valutata.

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.