agentscope-ai / agentscope-ai/QwenPaw

[Feature]: Support GPT-5.6 prompt caching parameters in Responses API provider

Open
#6,649 13 comments 0 reactions 0 assignees View on GitHub
enhancement
Dominant language
Python
Stars
34.9k
Forks
3.1k
Avg merge
1d 15h
Merged PRs (30d)
225

Description

## Summary

支持 GPT-5.6 模型的 prompt caching 参数(`prompt_cache_key`、`prompt_cache_options`、`prompt_cache_breakpoint`),使 Agent 循环中的多轮对话能够复用缓存前缀,降低延迟和成本。

## Component(s) Affected

- [x] Core / Backend (app, agents, config, providers, utils, local_models)
- [ ] Console (frontend web UI)
- [ ] Channels (DingTalk, Feishu, QQ, Discord, iMessage, etc.)
- [ ] Skills
- [ ] CLI
- [ ] Documentation (website)
- [ ] Tests
- [ ] CI/CD
- [ ] Scripts / Deploy

## Problem / Motivation

### 问题描述

当使用 GPT-5.6 模型通过 Responses API 提供商时,prompt caching 功能基本失效:

- `cache_write_tokens`(缓存写入)非常少或几乎没有
- `cached_tokens`(缓存读取)在多轮 Agent 对话中持续接近 0
- 无法观察到 prompt caching 带来的成本/延迟收益

### 根因分析

通过检查 QwenPaw 源码,发现问题在于 Responses API 提供商没有传递 GPT-5.6 特有的缓存控制参数:

1. **`providers/openai_response_provider.py`**:`OpenAIResponseModelCompat._call_api()` 仅转发 `extra_generate_kwargs` 和标准 `generate_kwargs`,没有对以下参数做特殊处理:
- `prompt_cache_key`(注:顶层参数,实际可经 `generate_kwargs` 透传,但无专门配置入口/文档)
- `prompt_cache_options`(注:顶层参数,实际可经 `generate_kwargs` 透传,但无专门配置入口/文档)
- `prompt_cache_breakpoint`(无法经 `generate_kwargs` 透传:需附加到 input 内 content block)
- `previous_response_id`(无法静态配置:每轮响应 id 不同,需框架自动追踪注入)

2. **GPT-5.6 缓存行为变更**:根据 OpenAI 官方文档,GPT-5.6 模型与早期模型的行为不同:
> GPT-5.6 模型在缓存断点处缓存精确的 prompt 前缀。默认情况下,服务在**最新的 user 或 tool 消息**处放置隐式断点。与早期模型不同,它**不会**自动回退到该断点之前最长的匹配未标记前缀。

3. **Agent 循环场景**:在 QwenPaw 的 Agent 循环中,每一轮都会在对话末尾追加新的工具调用和工具结果。因此隐式断点落在**每轮都变化**的内容上,导致缓存前缀实际上永远不会被复用。

### 受益用户

- 使用 GPT-5.6 系列模型的用户
- 运行多轮 Agent 对话(包含工具调用)的用户
- 关注 API 成本和响应延迟的用户

## Proposed Solution

### A. 提供商/模型级别的 `prompt_cache_key`

在提供商或模型配置中添加 `prompt_cache_key` 字段(类似于现有的 `generate_kwargs`)。将其作为 `responses.create()` 的顶层参数传递。

```json
{
"provider_id": "openai-response",
"model": "gpt-5.6",
"prompt_cache_key": "qwenpaw-agent-default-v1"
}
```

### B. 显式缓存断点注入

在构建 `OpenAIResponseModel` 的 `input` 数组的格式化器中,识别"稳定前缀"的最后一个 content block(例如最后一个系统消息或最后一个工具定义 block),并附加:

```json
{
"prompt_cache_breakpoint": { "mode": "explicit" }
}
```

这应该是可选的,由配置标志控制,例如 `enable_prompt_cache_breakpoint: true`。

### C. `prompt_cache_options` 透传

允许在 `generate_kwargs` 或专用配置字段中指定 `prompt_cache_options`:

```json
{
"prompt_cache_options": {
"mode": "explicit",
"ttl": "30m"
}
}
```

### D. `previous_response_id` 追踪(远期目标)

在单个 Agent 会话内,存储每轮的 `response.id`,并在下一轮作为 `previous_response_id` 传递。这将允许服务端复用完整的先前上下文,而无需重新传输。

## Alternatives Considered

1. **手动修改源码**:用户直接修改 `openai_response_provider.py` 添加参数传递——不可维护,每次升级会被覆盖
2. **通过 `generate_kwargs` 传递**:`prompt_cache_key` 和 `prompt_cache_options` 是请求**顶层参数**,可以通过 `generate_kwargs` 直接透传(`OpenAIResponseModelCompat._call_api()` 只过滤 `modalities`/`audio` 两个键,其余键会 `api_kwargs.update(...)` 原样透传到 `client.responses.create()`);但 `prompt_cache_breakpoint` **无法**通过顶层参数实现——它必须附加到 `input` 数组内的特定 content block(如 `input_text` block)上,需要修改 formatter 层
3. **提供商特定配置字段**:为每个缓存参数添加独立配置项——过于僵化,不如通用方案灵活

## Additional Context

### 相关 Issue

- #1003 - Performance bottleneck in distributed self-hosted providers: cache miss amplification without session-sticky routing(提到"需要显式 cache breakpoints")

### OpenAI 官方文档

- [Prompt Caching Guide](https://platform.openai.com/docs/guides/prompt-caching)
- [Conversation State](https://platform.openai.com/docs/guides/conversation-state)
- [Responses API Reference](https://platform.openai.com/docs/api-reference/responses)

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.