diff --git a/server/routers/knowledge_router.py b/server/routers/knowledge_router.py index 0ddbd930..60d96025 100644 --- a/server/routers/knowledge_router.py +++ b/server/routers/knowledge_router.py @@ -1284,6 +1284,7 @@ async def get_all_embedding_models_status(current_user: User = Depends(get_admin async def generate_description( name: str = Body(..., description="知识库名称"), current_description: str = Body("", description="当前描述(可选,用于优化)"), + file_list: list[str] = Body([], description="文件列表"), current_user: User = Depends(get_admin_user), ): """使用 LLM 生成或优化知识库描述 @@ -1292,40 +1293,35 @@ async def generate_description( """ from src.models import select_model - logger.debug(f"Generating description for knowledge base: {name}") + logger.debug(f"Generating description for knowledge base: {name}, files: {len(file_list)}") + + # 构建文件列表文本 + if file_list: + # 限制文件数量,避免 prompt 过长 + display_files = file_list[:50] + files_str = "\n".join([f"- {f}" for f in display_files]) + more_text = f"\n... (还有 {len(file_list) - 50} 个文件)" if len(file_list) > 50 else "" + current_description += f"\n\n知识库包含的文件:\n{files_str}{more_text}" + + current_description = current_description or "暂无描述" # 构建提示词 - if current_description.strip(): - prompt = textwrap.dedent(f""" - 请帮我优化以下知识库的描述。 + prompt = textwrap.dedent(f""" + 请帮我优化以下知识库的描述。 - 知识库名称: {name} - 当前描述: {current_description} + 知识库名称: {name} + 当前描述: {current_description} - 要求: - 1. 这个描述将作为智能体工具的描述使用 - 2. 智能体会根据知识库的标题和描述来选择合适的工具 - 3. 所以描述需要清晰、具体,说明该知识库包含什么内容、适合解答什么类型的问题 - 4. 描述应该简洁有力,通常 2-4 句话即可 - 5. 不要使用 Markdown 格式 + 要求: + 1. 这个描述将作为智能体工具的描述使用 + 2. 智能体会根据知识库的标题和描述来选择合适的工具 + 3. 所以描述需要清晰、具体,说明该知识库包含什么内容、适合解答什么类型的问题 + 4. 描述应该简洁有力,通常 2-4 句话即可 + 5. 不要使用 Markdown 格式 + {"6. 请参考提供的文件列表来准确概括知识库内容" if file_list else ""} - 请直接输出优化后的描述,不要有任何前缀说明。 - """).strip() - else: - prompt = textwrap.dedent(f""" - 请为以下知识库生成一个描述。 - - 知识库名称: {name} - - 要求: - 1. 这个描述将作为智能体工具的描述使用 - 2. 智能体会根据知识库的标题和描述来选择合适的工具 - 3. 所以描述需要清晰、具体,说明该知识库可能包含什么内容、适合解答什么类型的问题 - 4. 描述应该简洁有力,通常 2-4 句话即可 - 5. 不要使用 Markdown 格式 - - 请直接输出描述,不要有任何前缀说明。 - """).strip() + 请直接输出优化后的描述,不要有任何前缀说明。 + """).strip() try: model = select_model() diff --git a/src/knowledge/services/upload_graph_service.py b/src/knowledge/services/upload_graph_service.py index 361a7b69..b654e554 100644 --- a/src/knowledge/services/upload_graph_service.py +++ b/src/knowledge/services/upload_graph_service.py @@ -102,6 +102,7 @@ class UploadGraphService: async with minio_client.temp_file_from_url( file_path, allowed_extensions=[".jsonl"] ) as actual_file_path: + def read_triples(file_path): with open(file_path, encoding="utf-8") as file: for line in file: @@ -114,9 +115,7 @@ class UploadGraphService: else: # 本地文件路径 - 拒绝不安全的本地路径 - raise ValueError( - "不支持本地文件路径,只允许 MinIO URL。请先通过文件上传接口上传文件。" - ) + raise ValueError("不支持本地文件路径,只允许 MinIO URL。请先通过文件上传接口上传文件。") except Exception as e: logger.error(f"处理文件失败: {e}") diff --git a/web/src/apis/knowledge_api.js b/web/src/apis/knowledge_api.js index df074946..f366e193 100644 --- a/web/src/apis/knowledge_api.js +++ b/web/src/apis/knowledge_api.js @@ -59,12 +59,14 @@ export const databaseApi = { * 使用 AI 生成或优化知识库描述 * @param {string} name - 知识库名称 * @param {string} currentDescription - 当前描述(可选) + * @param {Array} fileList - 文件列表(可选) * @returns {Promise} - 生成结果 */ - generateDescription: async (name, currentDescription = '') => { + generateDescription: async (name, currentDescription = '', fileList = []) => { return apiAdminPost('/api/knowledge/generate-description', { name, - current_description: currentDescription + current_description: currentDescription, + file_list: fileList }) } } diff --git a/web/src/components/AiTextarea.vue b/web/src/components/AiTextarea.vue index 422355fd..4b70e281 100644 --- a/web/src/components/AiTextarea.vue +++ b/web/src/components/AiTextarea.vue @@ -50,6 +50,10 @@ const props = defineProps({ autoSize: { type: [Boolean, Object], default: false + }, + files: { + type: Array, + default: () => [] } }) @@ -65,7 +69,7 @@ const generateDescription = async () => { loading.value = true try { - const result = await databaseApi.generateDescription(props.name, props.modelValue) + const result = await databaseApi.generateDescription(props.name, props.modelValue, props.files) if (result.status === 'success' && result.description) { emit('update:modelValue', result.description) message.success('描述生成成功') diff --git a/web/src/components/KnowledgeBaseCard.vue b/web/src/components/KnowledgeBaseCard.vue index 47cd4bf6..9516d41a 100644 --- a/web/src/components/KnowledgeBaseCard.vue +++ b/web/src/components/KnowledgeBaseCard.vue @@ -77,6 +77,7 @@ @@ -120,6 +121,11 @@ const store = useDatabaseStore(); const database = computed(() => store.database); +const fileList = computed(() => { + if (!database.value?.files) return []; + return Object.values(database.value.files).map(f => f.filename).filter(Boolean); +}); + // 复制数据库ID const copyDatabaseId = async () => { if (!database.value.db_id) {