mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2026-01-10 23:59:45 +08:00
fix: websearch rag concurrency (#10107)
* fix(WebSearchService): serialize rag operations * refactor: improve a hint in websearch settings
This commit is contained in:
parent
4714442d6e
commit
4c4cc52c07
@ -11,7 +11,7 @@ import { SettingDivider, SettingGroup, SettingRow, SettingRowTitle, SettingTitle
|
|||||||
|
|
||||||
const BasicSettings: FC = () => {
|
const BasicSettings: FC = () => {
|
||||||
const { theme } = useTheme()
|
const { theme } = useTheme()
|
||||||
const { searchWithTime, maxResults } = useWebSearchSettings()
|
const { searchWithTime, maxResults, compressionConfig } = useWebSearchSettings()
|
||||||
|
|
||||||
const dispatch = useAppDispatch()
|
const dispatch = useAppDispatch()
|
||||||
|
|
||||||
@ -28,7 +28,7 @@ const BasicSettings: FC = () => {
|
|||||||
<SettingRow style={{ height: 40 }}>
|
<SettingRow style={{ height: 40 }}>
|
||||||
<SettingRowTitle style={{ minWidth: 120 }}>
|
<SettingRowTitle style={{ minWidth: 120 }}>
|
||||||
{t('settings.tool.websearch.search_max_result.label')}
|
{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">
|
<Tooltip title={t('settings.tool.websearch.search_max_result.tooltip')} placement="top">
|
||||||
<Info size={16} color="var(--color-icon)" style={{ marginLeft: 5, cursor: 'pointer' }} />
|
<Info size={16} color="var(--color-icon)" style={{ marginLeft: 5, cursor: 'pointer' }} />
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|||||||
@ -283,6 +283,8 @@ class WebSearchService {
|
|||||||
// 2. 合并所有结果并按分数排序
|
// 2. 合并所有结果并按分数排序
|
||||||
const flatResults = allResults.flat().sort((a, b) => b.score - a.score)
|
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. 去重,保留最高分的重复内容
|
// 3. 去重,保留最高分的重复内容
|
||||||
const seen = new Set<string>()
|
const seen = new Set<string>()
|
||||||
const uniqueResults = flatResults.filter((item) => {
|
const uniqueResults = flatResults.filter((item) => {
|
||||||
@ -293,6 +295,8 @@ class WebSearchService {
|
|||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
|
|
||||||
|
logger.debug(`Found ${uniqueResults.length} unique result(s) from search base after sorting and deduplication`)
|
||||||
|
|
||||||
// 4. 转换为引用格式
|
// 4. 转换为引用格式
|
||||||
return await Promise.all(
|
return await Promise.all(
|
||||||
uniqueResults.map(async (result, index) => ({
|
uniqueResults.map(async (result, index) => ({
|
||||||
@ -327,12 +331,17 @@ class WebSearchService {
|
|||||||
Math.max(0, rawResults.length) * (config.documentCount ?? DEFAULT_WEBSEARCH_RAG_DOCUMENT_COUNT)
|
Math.max(0, rawResults.length) * (config.documentCount ?? DEFAULT_WEBSEARCH_RAG_DOCUMENT_COUNT)
|
||||||
|
|
||||||
const searchBase = await this.ensureSearchBase(config, totalDocumentCount, requestId)
|
const searchBase = await this.ensureSearchBase(config, totalDocumentCount, requestId)
|
||||||
|
logger.debug('Search base for RAG compression: ', searchBase)
|
||||||
|
|
||||||
// 1. 清空知识库
|
// 1. 清空知识库
|
||||||
await window.api.knowledgeBase.reset(getKnowledgeBaseParams(searchBase))
|
const baseParams = getKnowledgeBaseParams(searchBase)
|
||||||
|
await window.api.knowledgeBase.reset(baseParams)
|
||||||
|
|
||||||
// 2. 一次性添加所有搜索结果到知识库
|
logger.debug('Search base parameters for RAG compression: ', baseParams)
|
||||||
const addPromises = rawResults.map(async (result) => {
|
|
||||||
|
// 2. 顺序添加所有搜索结果到知识库
|
||||||
|
// FIXME: 目前的知识库 add 不支持并发
|
||||||
|
for (const result of rawResults) {
|
||||||
const item: KnowledgeItem & { sourceUrl?: string } = {
|
const item: KnowledgeItem & { sourceUrl?: string } = {
|
||||||
id: uuid(),
|
id: uuid(),
|
||||||
type: 'note',
|
type: 'note',
|
||||||
@ -347,10 +356,7 @@ class WebSearchService {
|
|||||||
base: getKnowledgeBaseParams(searchBase),
|
base: getKnowledgeBaseParams(searchBase),
|
||||||
item
|
item
|
||||||
})
|
})
|
||||||
})
|
}
|
||||||
|
|
||||||
// 等待所有结果添加完成
|
|
||||||
await Promise.all(addPromises)
|
|
||||||
|
|
||||||
// 3. 对知识库执行多问题搜索获取压缩结果
|
// 3. 对知识库执行多问题搜索获取压缩结果
|
||||||
const references = await this.querySearchBase(questions, searchBase)
|
const references = await this.querySearchBase(questions, searchBase)
|
||||||
@ -475,6 +481,7 @@ class WebSearchService {
|
|||||||
|
|
||||||
// 统计成功完成的搜索数量
|
// 统计成功完成的搜索数量
|
||||||
const successfulSearchCount = searchResults.filter((result) => result.status === 'fulfilled').length
|
const successfulSearchCount = searchResults.filter((result) => result.status === 'fulfilled').length
|
||||||
|
logger.verbose(`Successful search count: ${successfulSearchCount}`)
|
||||||
if (successfulSearchCount > 1) {
|
if (successfulSearchCount > 1) {
|
||||||
await this.setWebSearchStatus(
|
await this.setWebSearchStatus(
|
||||||
requestId,
|
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) {
|
if (finalResults.length === 0) {
|
||||||
await this.setWebSearchStatus(requestId, { phase: 'default' })
|
await this.setWebSearchStatus(requestId, { phase: 'default' })
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user