[RAG] 彻底改回同步上传(模型已换v3足够快),删除异步后台线程代码

This commit is contained in:
2026-04-02 16:45:27 +08:00
parent 46428b7936
commit ee7c4a73ed

View File

@@ -270,75 +270,6 @@ def upload_docs(
return BaseResponse(code=200, msg="文件上传与向量化完成", data={"failed_files": failed_files}) return BaseResponse(code=200, msg="文件上传与向量化完成", data={"failed_files": failed_files})
def _background_llm_and_vectorize(
knowledge_base_name: str,
file_names: List[str],
chunk_size: int,
chunk_overlap: int,
zh_title_enhance: bool,
docs: dict,
not_refresh_vs_cache: bool,
embedding_ids: dict,
):
"""后台线程LLM 导读 + 向量化,完成后直连 MySQL 更新结果。"""
import time
import pymysql
start_time = time.time()
kb = KBServiceFactory.get_service_by_name(knowledge_base_name)
for filename in file_names:
try:
knowledge_file = KnowledgeFile(filename=filename, knowledge_base_name=knowledge_base_name)
new_loop = asyncio.new_event_loop()
asyncio.set_event_loop(new_loop)
try:
llm_result = new_loop.run_until_complete(knowledge_file.get_llm_result())
finally:
new_loop.close()
# 直连 MySQL 更新导读结果
embedding_id = embedding_ids.get(filename, filename)
try:
conn = pymysql.connect(**ck_mysql_config)
with conn.cursor() as cursor:
cursor.execute(
"UPDATE gpt_upload_file SET article_abstract=%s, article_keywords=%s, article_paragraph=%s WHERE embedding_id=%s",
(
str(llm_result.get("article_abstract", "生成摘要失败")),
str(llm_result.get("article_keywords", "生成关键词失败")),
str(llm_result.get("article_paragraph", "生成章节速览失败")),
embedding_id
)
)
conn.commit()
conn.close()
logger.info(f"[后台] LLM 导读已更新到数据库: {filename}")
except Exception as db_e:
logger.error(f"[后台] MySQL 更新失败 {filename}: {db_e}")
except Exception as e:
logger.error(f"[后台] LLM 导读生成失败 {filename}: {e}")
# 向量化
try:
_update_docs_impl(
knowledge_base_name=knowledge_base_name,
file_names=file_names,
override_custom_docs=True,
chunk_size=chunk_size,
chunk_overlap=chunk_overlap,
zh_title_enhance=zh_title_enhance,
docs=docs,
not_refresh_vs_cache=True,
)
if kb and not not_refresh_vs_cache:
kb.save_vector_store()
except Exception as e:
logger.error(f"[后台] 向量化失败: {e}")
logger.info(f"[后台] 总耗时: {time.time() - start_time:.2f}s")
def upload_docs_new( def upload_docs_new(
files: List[UploadFile] = File(..., description="上传文件,支持多文件"), files: List[UploadFile] = File(..., description="上传文件,支持多文件"),
knowledge_base_name: str = Form(..., description="知识库名称", examples=["samples"]), knowledge_base_name: str = Form(..., description="知识库名称", examples=["samples"]),
@@ -352,7 +283,7 @@ def upload_docs_new(
not_refresh_vs_cache: bool = Form(False, description="暂不保存向量库用于FAISS"), not_refresh_vs_cache: bool = Form(False, description="暂不保存向量库用于FAISS"),
) -> BaseResponse: ) -> BaseResponse:
""" """
API接口上传文件提取全文后快速返回LLM导读+向量化后台异步执行并直连MySQL更新结果 API接口上传文件同步生成导读模型已优化为deepseek-v3然后向量化
""" """
import time import time
start_time = time.time() start_time = time.time()
@@ -373,51 +304,61 @@ def upload_docs_new(
failed_files = {} failed_files = {}
file_names = list(docs.keys()) file_names = list(docs.keys())
llm_results = {} llm_results = {}
embedding_ids = {}
# 保存文件到磁盘 + 提取全文(快速)
for result in _save_files_in_thread(files, knowledge_base_name=knowledge_base_name, override=override): for result in _save_files_in_thread(files, knowledge_base_name=knowledge_base_name, override=override):
filename = result["data"]["file_name"] filename = result["data"]["file_name"]
if result["code"] != 200: if result["code"] != 200:
failed_files[filename] = result["msg"] failed_files[filename] = result["msg"]
if filename not in file_names: if filename not in file_names:
file_names.append(filename) file_names.append(filename)
embedding_ids[filename] = filename
try: try:
knowledge_file = KnowledgeFile(filename=filename, knowledge_base_name=knowledge_base_name) knowledge_file = KnowledgeFile(filename=filename, knowledge_base_name=knowledge_base_name)
full_text_data = knowledge_file.get_full_text() import concurrent.futures
import json as _json def run_async_in_thread():
try: new_loop = asyncio.new_event_loop()
full_text = _json.loads(full_text_data).get("full_text", "") asyncio.set_event_loop(new_loop)
except: try:
full_text = "" return new_loop.run_until_complete(knowledge_file.get_llm_result())
finally:
new_loop.close()
with concurrent.futures.ThreadPoolExecutor(max_workers=1) as executor:
future = executor.submit(run_async_in_thread)
llm_result = future.result()
llm_results[filename] = { llm_results[filename] = {
"full_text": full_text, "full_text": llm_result.get("full_text", "获取全文失败"),
"article_abstract": "导读生成中,请稍后刷新查看...", "article_abstract": llm_result.get("article_abstract", "生成摘要失败"),
"article_keywords": "导读生成中,请稍后刷新查看...", "article_keywords": llm_result.get("article_keywords", "生成关键词失败"),
"article_paragraph": "导读生成中,请稍后刷新查看..." "article_paragraph": llm_result.get("article_paragraph", "生成章节速览失败")
} }
except Exception as e: except Exception as e:
logger.error(f"提取全文失败 {filename}: {e}") logger.error(f"生成LLM结果时出错{e}", exc_info=e if log_verbose else None)
llm_results[filename] = { llm_results[filename] = {
"full_text": "", "article_abstract": "生成摘要失败",
"article_abstract": "导读生成中,请稍后刷新查看...", "article_keywords": "生成关键词失败",
"article_keywords": "导读生成中,请稍后刷新查看...", "article_paragraph": "生成章节速览失败"
"article_paragraph": "导读生成中,请稍后刷新查看..."
} }
# 后台异步LLM 导读 + 向量化,完成后直连 MySQL 更新 if to_vector_store:
import threading update_st = time.time()
threading.Thread( result = _update_docs_impl(
target=_background_llm_and_vectorize, knowledge_base_name=knowledge_base_name,
args=(knowledge_base_name, file_names, chunk_size, chunk_overlap, file_names=file_names,
zh_title_enhance, docs, not_refresh_vs_cache, embedding_ids), override_custom_docs=True,
daemon=True chunk_size=chunk_size,
).start() chunk_overlap=chunk_overlap,
zh_title_enhance=zh_title_enhance,
logger.info(f"文件上传+全文提取: {time.time() - start_time:.2f}sLLM+向量化转后台") docs=docs,
return BaseResponse(code=200, msg="文件上传完成,导读生成中", data={ not_refresh_vs_cache=True,
)
failed_files.update(result.data["failed_files"])
if not not_refresh_vs_cache:
kb.save_vector_store()
logger.info(f'向量化用时:{time.time() - update_st}')
logger.info(f"总执行时间: {time.time() - start_time:.2f}s")
return BaseResponse(code=200, msg="文件上传与向量化完成", data={
"failed_files": failed_files, "failed_files": failed_files,
"llm_results": llm_results "llm_results": llm_results
}) })