feat: 新增多格式文件上传入库与认证体系

- 新增 JWT 认证模块,支持登录/注册/用户管理
- 新增文件上传接口,支持 .txt/.md/.html/.pdf/.docx 等格式解析入库
- 新增检索结果 AI 总结功能
- 新增文本去重缓存机制
- 新增全局认证夹具简化测试
- 新增配置项与环境变量支持
- 完善文档与测试覆盖
This commit is contained in:
2026-07-30 10:30:15 +08:00
parent 51dc8dc4f6
commit dce9e31bde
31 changed files with 3021 additions and 45 deletions
+28 -3
View File
@@ -40,6 +40,9 @@ class ParsedQuery(BaseModel):
rewrite: str = Field(description="rewrite 后的 query")
keywords: list[str] = Field(default_factory=list, description="提取的关键词")
categories: list[CategoryHit] = Field(default_factory=list, description="命中类目列表")
entities: list[str] = Field(default_factory=list, description="提取的实体(人名/产品/技术等)")
intent: str = Field(default="", description="查询意图分类(如 查询/对比/操作/定义/排查)")
time_range: str = Field(default="", description="时间范围(如 '2023年''最近一个月'),空表示无")
parse_failed: bool = Field(default=False, description="LLM 输出解析是否失败")
@@ -136,11 +139,28 @@ class QueryParser:
logger.warning("query 解析失败:JSON 必填字段缺失或类型错误", query=query, output=raw[:200])
return ParsedQuery(raw_query=query, rewrite=query, parse_failed=True)
# 扩展字段:实体/意图/时间范围(缺失或类型错误时降级为默认值,不触发 parse_failed
entities = data.get("entities", [])
if not isinstance(entities, list):
logger.warning("query 解析 entities 非列表,置空", query=query)
entities = []
intent = data.get("intent", "")
if not isinstance(intent, str):
logger.warning("query 解析 intent 非字符串,置空", query=query)
intent = ""
time_range = data.get("time_range", "")
if not isinstance(time_range, str):
logger.warning("query 解析 time_range 非字符串,置空", query=query)
time_range = ""
return ParsedQuery(
raw_query=query,
rewrite=rewrite,
keywords=[str(k) for k in keywords],
categories=self._validate_categories(categories, query),
entities=[str(e) for e in entities],
intent=intent,
time_range=time_range,
)
async def parse_and_route(self, query: str) -> RouteDecision:
@@ -178,17 +198,22 @@ class QueryParser:
category_lines = [f"- {c.name}: {c.description}" for c in self.taxonomy if c.name != UNCATEGORIZED]
category_block = "\n".join(category_lines)
return (
"你是搜索查询分析助手。请分析用户 query,完成三件事\n"
"你是搜索查询分析助手。请分析用户 query,完成以下事项\n"
"1. 判断 query 意图命中以下哪些知识类目,并给出每个类目的置信度(0~1 之间的小数);\n"
"2. 将 query 改写为更适合检索的形式;\n"
"3. 提取 query 的关键词\n\n"
"3. 提取 query 的关键词\n"
"4. 提取 query 中的实体(人名、产品名、技术名词、组织机构等);\n"
"5. 判断 query 的查询意图,从 [查询, 对比, 操作, 定义, 排查] 中选最接近的一个;\n"
"6. 提取 query 中的时间范围(如 '2023年''上个月''Q1'),无则留空字符串。\n\n"
f"可选类目:\n{category_block}\n\n"
"要求:\n"
"- categories 中的 name 只能从上面的类目名中选择,不要输出其他名称;\n"
"- 若没有明显命中的类目,categories 返回空列表;\n"
"- entities 没有则返回空数组;\n"
"- 只输出 JSON,不要输出任何其他内容。\n\n"
'输出格式:{"categories": [{"name": "类目名", "confidence": 0.0}], '
'"rewrite": "改写后的 query", "keywords": ["关键词"]}\n\n'
'"rewrite": "改写后的 query", "keywords": ["关键词"], '
'"entities": ["实体"], "intent": "查询", "time_range": ""}\n\n'
f"用户 query{query}"
)