问题描述
使用非 search 模型(如 deepseek-chat)且未启用 web_search 时,若模型回答中的单词 search / Search / SEARCH 正好出现在某个 SSE 内容片段的开头,会被正则无条件剥离,导致回答内容丢失。该行为会影响到ClaudeCode的search功能。
复现步骤
- 使用
deepseek-chat 模型(禁用 web search)
- 发送消息:
你能输出search这个单词吗
- 模型回复:当然可以,这个单词就是:("search" 被剥离)
根因
src/main/proxy/adapters/deepseek-stream.ts 在以下 5 个位置使用正则 /^(SEARCH|WEB_SEARCH|SEARCHING)\s*/i 过滤内容片段开头的控制标记,未加任何条件守卫:
| # |
方法 |
行号(原) |
触发条件 |
| 1 |
sendContent |
243 |
每个内容片段 |
| 2 |
handleNonStream |
389 |
片段类型 fragment |
| 3 |
handleNonStream |
403 |
response/fragments |
| 4 |
handleNonStream |
440 |
数组内嵌内容 |
| 5 |
handleNonStream |
452 |
字符串内容 |
这些 SEARCH / WEB_SEARCH / SEARCHING 是 DeepSeek 启用联网搜索后 在响应中插入的状态标记。当不使用联网搜索时,这些标记从不出现,正则不应执行。
正则的 i 标志导致大小写不敏感匹配,因此自然语言中的 search Search SEARCH 如果恰好在一个内容片段开头,就会被误判为控制标记而剥离。
修复方案
在过滤前增加条件判断:仅在实际启用了联网搜索时才执行 SEARCH 标记过滤。
条件
this.webSearchEnabled || this.model.includes('search')
修改要点
sendContent 方法(第 243 行):
// Before:
const filteredForSearch = cleanedValue.replace(/^(SEARCH|WEB_SEARCH|SEARCHING)\s*/i, '')
// After:
const shouldFilterSearch = this.webSearchEnabled || this.model.includes('search')
const filteredForSearch = shouldFilterSearch
? cleanedValue.replace(/^(SEARCH|WEB_SEARCH|SEARCHING)\s*/i, '')
: cleanedValue
handleNonStream 方法(第 358 行新增标志):
const isSearchModel = this.model.includes('search') || this.webSearchEnabled
handleNonStream 中其余 4 处过滤(第 389、403、440、452 行):
// Before:
cleanedFragment = cleanedFragment.replace(/^(SEARCH|WEB_SEARCH|SEARCHING)\s*/i, '')
// After:
if (isSearchModel) {
cleanedFragment = cleanedFragment.replace(/^(SEARCH|WEB_SEARCH|SEARCHING)\s*/i, '')
}
问题描述
使用非 search 模型(如
deepseek-chat)且未启用web_search时,若模型回答中的单词search/Search/SEARCH正好出现在某个 SSE 内容片段的开头,会被正则无条件剥离,导致回答内容丢失。该行为会影响到ClaudeCode的search功能。复现步骤
deepseek-chat模型(禁用 web search)你能输出search这个单词吗根因
src/main/proxy/adapters/deepseek-stream.ts在以下 5 个位置使用正则/^(SEARCH|WEB_SEARCH|SEARCHING)\s*/i过滤内容片段开头的控制标记,未加任何条件守卫:sendContenthandleNonStreamhandleNonStreamhandleNonStreamhandleNonStream这些
SEARCH/WEB_SEARCH/SEARCHING是 DeepSeek 启用联网搜索后 在响应中插入的状态标记。当不使用联网搜索时,这些标记从不出现,正则不应执行。正则的
i标志导致大小写不敏感匹配,因此自然语言中的searchSearchSEARCH如果恰好在一个内容片段开头,就会被误判为控制标记而剥离。修复方案
在过滤前增加条件判断:仅在实际启用了联网搜索时才执行 SEARCH 标记过滤。
条件
修复提交:309c1d2
PR:#141