feat(知识库): 在生成描述时支持传入文件列表

在知识库描述生成功能中增加文件列表参数,使AI能参考文件内容生成更准确的描述
前端组件传递文件列表至API,后端处理时将其包含在提示词中
This commit is contained in:
Wenjie Zhang 2026-01-03 19:02:08 +08:00
parent 6a94b0626c
commit fffe237780
5 changed files with 42 additions and 35 deletions

View File

@ -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()

View File

@ -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}")

View File

@ -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
})
}
}

View File

@ -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('描述生成成功')

View File

@ -77,6 +77,7 @@
<AiTextarea
v-model="editForm.description"
:name="editForm.name"
:files="fileList"
placeholder="请输入知识库描述"
:rows="4"
/>
@ -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) {