fix: websearch rag concurrency (#10107)

* fix(WebSearchService): serialize rag operations

* refactor: improve a hint in websearch settings
This commit is contained in:
one 2025-09-11 19:05:17 +08:00 committed by GitHub
parent 4714442d6e
commit 4c4cc52c07
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 22 additions and 9 deletions

View File

@ -11,7 +11,7 @@ import { SettingDivider, SettingGroup, SettingRow, SettingRowTitle, SettingTitle
const BasicSettings: FC = () => {
const { theme } = useTheme()
const { searchWithTime, maxResults } = useWebSearchSettings()
const { searchWithTime, maxResults, compressionConfig } = useWebSearchSettings()
const dispatch = useAppDispatch()
@ -28,7 +28,7 @@ const BasicSettings: FC = () => {
<SettingRow style={{ height: 40 }}>
<SettingRowTitle style={{ minWidth: 120 }}>
{t('settings.tool.websearch.search_max_result.label')}
{maxResults > 20 && (
{maxResults > 20 && compressionConfig?.method === 'none' && (
<Tooltip title={t('settings.tool.websearch.search_max_result.tooltip')} placement="top">
<Info size={16} color="var(--color-icon)" style={{ marginLeft: 5, cursor: 'pointer' }} />
</Tooltip>

View File

@ -283,6 +283,8 @@ class WebSearchService {
// 2. 合并所有结果并按分数排序
const flatResults = allResults.flat().sort((a, b) => b.score - a.score)
logger.debug(`Found ${flatResults.length} result(s) in search base related to question(s): `, questions)
// 3. 去重,保留最高分的重复内容
const seen = new Set<string>()
const uniqueResults = flatResults.filter((item) => {
@ -293,6 +295,8 @@ class WebSearchService {
return true
})
logger.debug(`Found ${uniqueResults.length} unique result(s) from search base after sorting and deduplication`)
// 4. 转换为引用格式
return await Promise.all(
uniqueResults.map(async (result, index) => ({
@ -327,12 +331,17 @@ class WebSearchService {
Math.max(0, rawResults.length) * (config.documentCount ?? DEFAULT_WEBSEARCH_RAG_DOCUMENT_COUNT)
const searchBase = await this.ensureSearchBase(config, totalDocumentCount, requestId)
logger.debug('Search base for RAG compression: ', searchBase)
// 1. 清空知识库
await window.api.knowledgeBase.reset(getKnowledgeBaseParams(searchBase))
const baseParams = getKnowledgeBaseParams(searchBase)
await window.api.knowledgeBase.reset(baseParams)
// 2. 一次性添加所有搜索结果到知识库
const addPromises = rawResults.map(async (result) => {
logger.debug('Search base parameters for RAG compression: ', baseParams)
// 2. 顺序添加所有搜索结果到知识库
// FIXME: 目前的知识库 add 不支持并发
for (const result of rawResults) {
const item: KnowledgeItem & { sourceUrl?: string } = {
id: uuid(),
type: 'note',
@ -347,10 +356,7 @@ class WebSearchService {
base: getKnowledgeBaseParams(searchBase),
item
})
})
// 等待所有结果添加完成
await Promise.all(addPromises)
}
// 3. 对知识库执行多问题搜索获取压缩结果
const references = await this.querySearchBase(questions, searchBase)
@ -475,6 +481,7 @@ class WebSearchService {
// 统计成功完成的搜索数量
const successfulSearchCount = searchResults.filter((result) => result.status === 'fulfilled').length
logger.verbose(`Successful search count: ${successfulSearchCount}`)
if (successfulSearchCount > 1) {
await this.setWebSearchStatus(
requestId,
@ -498,6 +505,12 @@ class WebSearchService {
}
})
logger.verbose(`FulFilled search result count: ${finalResults.length}`)
logger.verbose(
'FulFilled search result: ',
finalResults.map(({ title, url }) => ({ title, url }))
)
// 如果没有搜索结果,直接返回空结果
if (finalResults.length === 0) {
await this.setWebSearchStatus(requestId, { phase: 'default' })