feat: 新增多格式文件上传入库与认证体系
- 新增 JWT 认证模块,支持登录/注册/用户管理 - 新增文件上传接口,支持 .txt/.md/.html/.pdf/.docx 等格式解析入库 - 新增检索结果 AI 总结功能 - 新增文本去重缓存机制 - 新增全局认证夹具简化测试 - 新增配置项与环境变量支持 - 完善文档与测试覆盖
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
"""检索结果 AI 总结
|
||||
|
||||
对检索返回的 chunk 命中结果,调用 Ollama 本地模型生成一段针对用户 query 的总结回答。
|
||||
仅基于检索结果内容,不编造未提及的信息。
|
||||
"""
|
||||
|
||||
import structlog
|
||||
|
||||
from app.config import settings
|
||||
from app.models.search import SearchHit
|
||||
from app.services.ollama import OllamaClient
|
||||
|
||||
logger = structlog.get_logger()
|
||||
|
||||
|
||||
class ResultSummarizer:
|
||||
"""检索结果总结器"""
|
||||
|
||||
def __init__(self, ollama: OllamaClient | None = None) -> None:
|
||||
self.ollama = ollama or OllamaClient()
|
||||
|
||||
async def summarize(self, query: str, hits: list[SearchHit]) -> str:
|
||||
"""对检索结果生成针对 query 的总结
|
||||
|
||||
取前 settings.result_summary_max_hits 条命中拼接为上下文,
|
||||
无命中时返回空字符串(不调 LLM)。
|
||||
"""
|
||||
if not hits:
|
||||
return ""
|
||||
max_hits = settings.result_summary_max_hits
|
||||
selected = hits[:max_hits]
|
||||
context = self._build_context(selected)
|
||||
prompt = self._build_prompt(query, context)
|
||||
try:
|
||||
summary = await self.ollama.generate(prompt)
|
||||
except Exception:
|
||||
logger.warning("检索结果总结生成失败,返回空字符串", exc_info=True)
|
||||
return ""
|
||||
logger.info("检索结果总结完成", query=query, hits_count=len(selected), summary_len=len(summary))
|
||||
return summary.strip()
|
||||
|
||||
@staticmethod
|
||||
def _build_context(hits: list[SearchHit]) -> str:
|
||||
"""拼接命中结果为带编号的上下文"""
|
||||
blocks: list[str] = []
|
||||
for i, hit in enumerate(hits, start=1):
|
||||
header_parts = [f"[{i}]"]
|
||||
if hit.title:
|
||||
header_parts.append(hit.title)
|
||||
if hit.section_path:
|
||||
header_parts.append(hit.section_path)
|
||||
header = " / ".join(header_parts)
|
||||
blocks.append(f"{header}\n{hit.text}")
|
||||
return "\n\n---\n\n".join(blocks)
|
||||
|
||||
@staticmethod
|
||||
def _build_prompt(query: str, context: str) -> str:
|
||||
return (
|
||||
"请根据以下检索结果,针对用户问题生成一段简洁的总结回答。\n"
|
||||
"要求:\n"
|
||||
"- 综合多条结果信息,不要简单逐条罗列;\n"
|
||||
"- 只基于检索结果内容,不编造未提及的信息;\n"
|
||||
"- 用中文回答,简洁明了。\n\n"
|
||||
f"用户问题:{query}\n\n"
|
||||
f"检索结果:\n{context}"
|
||||
)
|
||||
Reference in New Issue
Block a user