From 88c0066b06fe78a8a1355f0cac6a246c74e10c69 Mon Sep 17 00:00:00 2001 From: WangCham <651122857@qq.com> Date: Wed, 16 Jul 2025 17:20:13 +0800 Subject: [PATCH 1/4] feat: add topk --- .../knowledge/components/kb-card/KBCardVO.ts | 3 ++ .../knowledge/components/kb-form/KBForm.tsx | 29 +++++++++++++++++++ web/src/app/home/knowledge/page.tsx | 1 + web/src/app/infra/entities/api/index.ts | 1 + web/src/i18n/locales/en-US.ts | 1 + web/src/i18n/locales/ja-JP.ts | 1 + web/src/i18n/locales/zh-Hans.ts | 1 + 7 files changed, 37 insertions(+) diff --git a/web/src/app/home/knowledge/components/kb-card/KBCardVO.ts b/web/src/app/home/knowledge/components/kb-card/KBCardVO.ts index bfbc2adb..b13d2c24 100644 --- a/web/src/app/home/knowledge/components/kb-card/KBCardVO.ts +++ b/web/src/app/home/knowledge/components/kb-card/KBCardVO.ts @@ -3,6 +3,7 @@ export interface IKnowledgeBaseVO { name: string; description: string; embeddingModelUUID: string; + top_k: number; lastUpdatedTimeAgo: string; } @@ -11,6 +12,7 @@ export class KnowledgeBaseVO implements IKnowledgeBaseVO { name: string; description: string; embeddingModelUUID: string; + top_k: number; lastUpdatedTimeAgo: string; constructor(props: IKnowledgeBaseVO) { @@ -18,6 +20,7 @@ export class KnowledgeBaseVO implements IKnowledgeBaseVO { this.name = props.name; this.description = props.description; this.embeddingModelUUID = props.embeddingModelUUID; + this.top_k = props.top_k; this.lastUpdatedTimeAgo = props.lastUpdatedTimeAgo; } } diff --git a/web/src/app/home/knowledge/components/kb-form/KBForm.tsx b/web/src/app/home/knowledge/components/kb-form/KBForm.tsx index b56c327b..7ca885f4 100644 --- a/web/src/app/home/knowledge/components/kb-form/KBForm.tsx +++ b/web/src/app/home/knowledge/components/kb-form/KBForm.tsx @@ -34,6 +34,10 @@ const getFormSchema = (t: (key: string) => string) => embeddingModelUUID: z .string() .min(1, { message: t('knowledge.embeddingModelUUIDRequired') }), + top_k: z + .number() + .min(1, { message: t('knowledge.topKRequired') }) + .max(30, { message: t('knowledge.topKMax') }), }); export default function KBForm({ @@ -59,6 +63,7 @@ export default function KBForm({ name: '', description: t('knowledge.defaultDescription'), embeddingModelUUID: '', + top_k: 5, }, }); @@ -73,6 +78,7 @@ export default function KBForm({ form.setValue('name', val.name); form.setValue('description', val.description); form.setValue('embeddingModelUUID', val.embeddingModelUUID); + form.setValue('top_k', val.top_k || 5); }); } }); @@ -87,6 +93,7 @@ export default function KBForm({ name: res.base.name, description: res.base.description, embeddingModelUUID: res.base.embedding_model_uuid, + top_k: res.base.top_k || 5, }); }); }); @@ -113,6 +120,7 @@ export default function KBForm({ name: data.name, description: data.description, embedding_model_uuid: data.embeddingModelUUID, + top_k: data.top_k, }; } else { // create knowledge base @@ -120,6 +128,7 @@ export default function KBForm({ name: data.name, description: data.description, embedding_model_uuid: data.embeddingModelUUID, + top_k: data.top_k, }; httpClient .createKnowledgeBase(newKb) @@ -216,6 +225,26 @@ export default function KBForm({ )} /> + ( + + + {t('knowledge.topK')} + * + + + field.onChange(Number(e.target.value))} + /> + + + + )} + /> diff --git a/web/src/app/home/knowledge/page.tsx b/web/src/app/home/knowledge/page.tsx index 99de73d8..a2841b24 100644 --- a/web/src/app/home/knowledge/page.tsx +++ b/web/src/app/home/knowledge/page.tsx @@ -46,6 +46,7 @@ export default function KnowledgePage() { name: kb.name, description: kb.description, embeddingModelUUID: kb.embedding_model_uuid, + top_k: kb.top_k, lastUpdatedTimeAgo: lastUpdatedTimeAgoText, }); }), diff --git a/web/src/app/infra/entities/api/index.ts b/web/src/app/infra/entities/api/index.ts index 46d007d8..77dfff05 100644 --- a/web/src/app/infra/entities/api/index.ts +++ b/web/src/app/infra/entities/api/index.ts @@ -146,6 +146,7 @@ export interface KnowledgeBase { name: string; description: string; embedding_model_uuid: string; + top_k: number; created_at?: string; updated_at?: string; } diff --git a/web/src/i18n/locales/en-US.ts b/web/src/i18n/locales/en-US.ts index 8e6d7b49..43110f19 100644 --- a/web/src/i18n/locales/en-US.ts +++ b/web/src/i18n/locales/en-US.ts @@ -245,6 +245,7 @@ const enUS = { today: 'Today', kbName: 'Knowledge Base Name', kbDescription: 'Knowledge Base Description', + topK: 'Top K', defaultDescription: 'A knowledge base', embeddingModelUUID: 'Embedding Model', selectEmbeddingModel: 'Select Embedding Model', diff --git a/web/src/i18n/locales/ja-JP.ts b/web/src/i18n/locales/ja-JP.ts index c0e70806..ad0bf56f 100644 --- a/web/src/i18n/locales/ja-JP.ts +++ b/web/src/i18n/locales/ja-JP.ts @@ -247,6 +247,7 @@ const jaJP = { today: '今日', kbName: '知識ベース名', kbDescription: '知識ベースの説明', + topK: '上位K件', defaultDescription: '知識ベース', embeddingModelUUID: '埋め込みモデル', selectEmbeddingModel: '埋め込みモデルを選択', diff --git a/web/src/i18n/locales/zh-Hans.ts b/web/src/i18n/locales/zh-Hans.ts index 28574fdf..f64fc570 100644 --- a/web/src/i18n/locales/zh-Hans.ts +++ b/web/src/i18n/locales/zh-Hans.ts @@ -240,6 +240,7 @@ const zhHans = { today: '今天', kbName: '知识库名称', kbDescription: '知识库描述', + topK: '召回数量', defaultDescription: '一个知识库', embeddingModelUUID: '嵌入模型', selectEmbeddingModel: '选择嵌入模型', From e31883547d8a3aa006a4358a54ae27dfa71fcb61 Mon Sep 17 00:00:00 2001 From: WangCham <651122857@qq.com> Date: Wed, 16 Jul 2025 18:15:27 +0800 Subject: [PATCH 2/4] feat: add description for topk --- web/src/app/home/knowledge/components/kb-form/KBForm.tsx | 7 +++++++ web/src/i18n/locales/en-US.ts | 3 +++ web/src/i18n/locales/ja-JP.ts | 3 +++ web/src/i18n/locales/zh-Hans.ts | 3 +++ 4 files changed, 16 insertions(+) diff --git a/web/src/app/home/knowledge/components/kb-form/KBForm.tsx b/web/src/app/home/knowledge/components/kb-form/KBForm.tsx index 7ca885f4..16db601e 100644 --- a/web/src/app/home/knowledge/components/kb-form/KBForm.tsx +++ b/web/src/app/home/knowledge/components/kb-form/KBForm.tsx @@ -239,8 +239,15 @@ export default function KBForm({ type="number" {...field} onChange={(e) => field.onChange(Number(e.target.value))} + className="w-[180px] h-10 text-base appearance-none" + min={1} + max={30} + defaultValue={5} /> + + {t('knowledge.topKdescription')} + )} diff --git a/web/src/i18n/locales/en-US.ts b/web/src/i18n/locales/en-US.ts index 43110f19..ddf7ad0c 100644 --- a/web/src/i18n/locales/en-US.ts +++ b/web/src/i18n/locales/en-US.ts @@ -246,6 +246,9 @@ const enUS = { kbName: 'Knowledge Base Name', kbDescription: 'Knowledge Base Description', topK: 'Top K', + topKRequired: 'Top K cannot be empty', + topKMax: 'Top K maximum value is 30', + topKdescription: 'Used to specify the number of relevant documents to retrieve, ranging from 1 to 30.', defaultDescription: 'A knowledge base', embeddingModelUUID: 'Embedding Model', selectEmbeddingModel: 'Select Embedding Model', diff --git a/web/src/i18n/locales/ja-JP.ts b/web/src/i18n/locales/ja-JP.ts index ad0bf56f..69357cb9 100644 --- a/web/src/i18n/locales/ja-JP.ts +++ b/web/src/i18n/locales/ja-JP.ts @@ -248,6 +248,9 @@ const jaJP = { kbName: '知識ベース名', kbDescription: '知識ベースの説明', topK: '上位K件', + topKRequired: '上位K件は必須です', + topKMax: '上位K件の最大値は30です', + topKdescription: '関連ドキュメントを取得するための上位K件の数。1〜30の範囲で設定可能です', defaultDescription: '知識ベース', embeddingModelUUID: '埋め込みモデル', selectEmbeddingModel: '埋め込みモデルを選択', diff --git a/web/src/i18n/locales/zh-Hans.ts b/web/src/i18n/locales/zh-Hans.ts index f64fc570..a0ea2b8e 100644 --- a/web/src/i18n/locales/zh-Hans.ts +++ b/web/src/i18n/locales/zh-Hans.ts @@ -241,6 +241,9 @@ const zhHans = { kbName: '知识库名称', kbDescription: '知识库描述', topK: '召回数量', + topKRequired: '召回数量不能为空', + topKMax: '召回数量最大值为 30', + topKdescription: '用于召回相关文档的数量,取值范围为 1-30', defaultDescription: '一个知识库', embeddingModelUUID: '嵌入模型', selectEmbeddingModel: '选择嵌入模型', From e986a0acaf49bd0d744da34d93eda1982a2b3e75 Mon Sep 17 00:00:00 2001 From: WangCham <651122857@qq.com> Date: Wed, 16 Jul 2025 22:50:17 +0800 Subject: [PATCH 3/4] fix: kb form --- web/src/app/home/knowledge/components/kb-form/KBForm.tsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/web/src/app/home/knowledge/components/kb-form/KBForm.tsx b/web/src/app/home/knowledge/components/kb-form/KBForm.tsx index 16db601e..6d0b42f9 100644 --- a/web/src/app/home/knowledge/components/kb-form/KBForm.tsx +++ b/web/src/app/home/knowledge/components/kb-form/KBForm.tsx @@ -240,9 +240,6 @@ export default function KBForm({ {...field} onChange={(e) => field.onChange(Number(e.target.value))} className="w-[180px] h-10 text-base appearance-none" - min={1} - max={30} - defaultValue={5} /> From 3fa38f71f126585d6b231785c6ccaf2851a4e0de Mon Sep 17 00:00:00 2001 From: WangCham <651122857@qq.com> Date: Wed, 23 Jul 2025 17:29:36 +0800 Subject: [PATCH 4/4] feat: add topk --- pkg/api/http/service/knowledge.py | 2 +- pkg/provider/runners/localagent.py | 2 +- pkg/rag/knowledge/kbmgr.py | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/api/http/service/knowledge.py b/pkg/api/http/service/knowledge.py index 27506ec9..ed4ab008 100644 --- a/pkg/api/http/service/knowledge.py +++ b/pkg/api/http/service/knowledge.py @@ -78,7 +78,7 @@ class KnowledgeService: runtime_kb = await self.ap.rag_mgr.get_knowledge_base_by_uuid(kb_uuid) if runtime_kb is None: raise Exception('Knowledge base not found') - return [result.model_dump() for result in await runtime_kb.retrieve(query)] + return [result.model_dump() for result in await runtime_kb.retrieve(query,runtime_kb.knowledge_base_entity.top_k)] async def get_files_by_knowledge_base(self, kb_uuid: str) -> list[dict]: """获取知识库文件""" diff --git a/pkg/provider/runners/localagent.py b/pkg/provider/runners/localagent.py index 1d3e88ac..3ccb5573 100644 --- a/pkg/provider/runners/localagent.py +++ b/pkg/provider/runners/localagent.py @@ -56,7 +56,7 @@ class LocalAgentRunner(runner.RequestRunner): self.ap.logger.warning(f'Knowledge base {kb_uuid} not found') raise ValueError(f'Knowledge base {kb_uuid} not found') - result = await kb.retrieve(user_message_text) + result = await kb.retrieve(user_message_text,kb.knowledge_base_entity.top_k) final_user_message_text = '' diff --git a/pkg/rag/knowledge/kbmgr.py b/pkg/rag/knowledge/kbmgr.py index a9e7e57a..1cdef361 100644 --- a/pkg/rag/knowledge/kbmgr.py +++ b/pkg/rag/knowledge/kbmgr.py @@ -123,11 +123,11 @@ class RuntimeKnowledgeBase: ) return wrapper.id - async def retrieve(self, query: str) -> list[retriever_entities.RetrieveResultEntry]: + async def retrieve(self, query: str, top_k: int) -> list[retriever_entities.RetrieveResultEntry]: embedding_model = await self.ap.model_mgr.get_embedding_model_by_uuid( self.knowledge_base_entity.embedding_model_uuid ) - return await self.retriever.retrieve(self.knowledge_base_entity.uuid, query, embedding_model) + return await self.retriever.retrieve(self.knowledge_base_entity.uuid, query, embedding_model, top_k) async def delete_file(self, file_id: str): # delete vector