feat: 完成全量功能开发,包括前端管理后台与后端服务优化
此提交实现了完整的知识库管理系统: 1. 新增Vue3 + Antd Vue前端管理后台,包含登录、文档管理、检索、类目设置等完整页面 2. 重构后端LLM调用抽象层,支持Ollama与OpenAI兼容服务动态切换 3. 调整默认嵌入模型配置为本地bge-m3模式 4. 优化入库任务去重逻辑与缓存清理机制 5. 完善Docker镜像构建与docker-compose部署配置 6. 修复多项测试用例与兼容性问题 7. 新增运行时配置API,支持动态调整系统参数
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
"""query 解析与分类路由模块
|
||||
|
||||
分层 RAG 在线侧第一步:用 Ollama 小模型将用户 query 解析为结构化 JSON
|
||||
分层 RAG 在线侧第一步:用 LLM(Ollama 或 OpenAI 兼容服务,由
|
||||
runtime_settings.models.query 决定)将用户 query 解析为结构化 JSON
|
||||
(命中类目+置信度、rewrite 后 query、关键词),再由纯函数做路由决策:
|
||||
- 高置信且命中类目数 <= 上限 → 按类目过滤检索
|
||||
- 低置信 / 解析失败 / 命中类目过多 → 全库兜底(不丢召回)
|
||||
@@ -16,8 +17,8 @@ import structlog
|
||||
from pydantic import BaseModel, Field, ValidationError
|
||||
|
||||
from app.config import settings
|
||||
from app.models.knowledge import UNCATEGORIZED, TaxonomyCategory
|
||||
from app.services.ollama import OllamaClient
|
||||
from app.models.knowledge import UNCATEGORIZED, TaxonomyCategory, load_taxonomy
|
||||
from app.services.llm import LLMClient, create_llm_client
|
||||
from app.services.redis import RedisCache, get_cache
|
||||
|
||||
logger = structlog.get_logger()
|
||||
@@ -106,17 +107,22 @@ def decide_route(parsed: ParsedQuery, threshold: float, max_categories: int) ->
|
||||
|
||||
|
||||
class QueryParser:
|
||||
"""query 解析器:调用 Ollama 小模型将 query 解析为结构化 JSON"""
|
||||
"""query 解析器:调用 LLM 将 query 解析为结构化 JSON"""
|
||||
|
||||
def __init__(
|
||||
self, ollama: OllamaClient, taxonomy: list[TaxonomyCategory], cache: RedisCache | None = None
|
||||
self,
|
||||
ollama: LLMClient | None = None,
|
||||
taxonomy: list[TaxonomyCategory] | None = None,
|
||||
cache: RedisCache | None = None,
|
||||
) -> None:
|
||||
self.ollama = ollama
|
||||
self.taxonomy = taxonomy
|
||||
# 默认按 runtime_settings.models.query 选择 LLM 实现;
|
||||
# 测试可通过 ollama 参数注入替身。
|
||||
self.ollama = ollama or create_llm_client("query")
|
||||
self.taxonomy = taxonomy if taxonomy is not None else load_taxonomy()
|
||||
# 解析结果缓存,缺省用全局单例;RedisCache 全操作容错,缓存不可用时退化为无缓存行为
|
||||
self.cache = cache if cache is not None else get_cache()
|
||||
# 可作为路由命中类目的名字集合(uncategorized 不可作为路由命中类目)
|
||||
self._routable_names = {c.name for c in taxonomy if c.name != UNCATEGORIZED}
|
||||
self._routable_names = {c.name for c in self.taxonomy if c.name != UNCATEGORIZED}
|
||||
|
||||
async def parse(self, query: str) -> ParsedQuery:
|
||||
"""调用 LLM 将 query 解析为结构化结果
|
||||
|
||||
Reference in New Issue
Block a user