智能知识系统 — 数据检索与查询策略
版本: 1.1.0 · 更新: 2026-04-13 · 技术栈: Python 3.12 · FastAPI · AsyncPG · PostgreSQL 16 + pgvector · Redis 7
目录
- 系统架构总览
- 数据规模与存储
- 检索性能基准
- 检索层(Retrieval)
- 4.1 向量检索
- 4.2 BM25 关键词检索
- 4.3 全文检索
- 4.4 混合检索(核心)
- 4.5 重排序
- 推理层(Reasoning)
- 5.1 Chain-of-Thought 推理
- 5.2 ReAct 推理
- 5.3 GraphRAG 知识图谱推理
- 5.4 自动模式选择
- 路由层(Gateway)
- 6.1 域名路由策略
- 6.2 十大领域
- 缓存层(Cache)
- 反馈闭环
- API 端点一览
- 关键参数速查表
- 容量预期与扩展规划
1. 系统架构总览
┌─────────────────────────────────────────────────────────────┐
│ API Layer │
│ /search /hybrid /ask │ /reason /graph/* │ /gateway │
└──────────┬───────────────┴──────────┬───────────┴─────┬─────┘
│ │ │
┌─────▼──────┐ ┌────────▼───────┐ ┌──────▼──────┐
│ APIGateway │ │ Reasoning API │ │DomainRegistry│
│(domain_match)│ │ (cot/react/ │ │ (10 domains) │
└─────┬──────┘ │ graph_rag) │ └──────┬──────┘
│ └────────┬───────┘ │
│ │ │
┌─────▼──────────────────────────▼─────────────────▼─────┐
│ 混合检索引擎 HybridRetriever │
│ ┌─────────────┐ ┌────────────┐ ┌──────────────────┐ │
│ │VectorRetriever│ │BM25Retriever│ │FullTextRetriever │ │
│ │(BGE+pgvector)│ │(jieba+BM25)│ │(tsvector+GIN) │ │
│ └──────┬──────┘ └──────┬─────┘ └────────┬─────────┘ │
│ └───────────────┼────────────────┘ │
│ ┌───────▼────────┐ │
│ │ RRF 融合排序 │ │
│ │ (w=0.6/0.4) │ │
│ └───────┬────────┘ │
│ ┌───────▼────────┐ │
│ │ 反馈质量加权 │ │
│ └───────┬────────┘ │
│ ┌───────▼────────┐ │
│ │ Cross-Encoder │ │
│ │ 重排序 │ │
│ └───────┬────────┘ │
└─────────────────────────┼───────────────────────────────┘
│
┌─────────▼─────────┐
│ CacheManager │
│ L1: Memory Cache │
│ L2: Redis Cache │
└───────────────────┘
2. 数据规模与存储
核心数据表
| 数据表 | 总行数 | 嵌入覆盖 | 表+索引大小 | 说明 |
|---|---|---|---|---|
documents |
109,406 | 100% (109,406) | 5,114 MB | 九域知识文档 |
guoxue_content |
263,767 | 100% (263,767) | 6,384 MB | 国学经典内容 |
guji_documents |
— | — | 5,060 MB | 古籍文档 |
sys_books |
— | — | 3,052 MB | 系统书籍 |
audio_segments |
0 | — | 1,104 MB | 音频段落(预留) |
数据库总大小: 20 GB
九域文档分布(documents 表)
| 领域 | 文档数 | 占比 |
|---|---|---|
| 中医 | 68,749 | 62.8% |
| 儒家 | 20,610 | 18.8% |
| 气功 | 15,432 | 14.1% |
| 佛家 | 3,942 | 3.6% |
| 科学 | 364 | 0.3% |
| 哲学 | 227 | 0.2% |
| 道家 | 53 | <0.1% |
| 心理学 | 21 | <0.1% |
| 武术 | 8 | <0.1% |
索引规模
| 索引 | 表 | 类型 | 大小 |
|---|---|---|---|
idx_documents_content_gin |
documents | GIN (tsvector) | 1,048 MB |
idx_documents_search_vector |
documents | GIN (tsvector) | 1,049 MB |
idx_guoxue_content_embedding_hnsw |
guoxue_content | HNSW (vector) | 655 MB |
idx_guoxune_body_head_trgm |
guoxue_content | GIN (trigram) | 566 MB |
idx_documents_embedding_hnsw |
documents | HNSW (vector) | 285 MB |
idx_documents_category_title |
documents | B-tree | 12 MB |
| 其他 12 个索引 | — | B-tree / GIN / HNSW | <10 MB |
| 索引总计 | — | — | ~3,625 MB |
硬件环境
| 组件 | 规格 | 用途 |
|---|---|---|
| CPU | — | API 服务 + 模型推理 |
| GPU | NVIDIA GTX 1660 Ti 6GB (CUDA 13.1) | 嵌入编码 + 重排序 |
| NVMe SSD | 477GB(71GB 可用) | 系统盘 + 表空间 |
| HDD | 932GB(742GB 可用) | PostgreSQL 数据目录 |
| 内存 | — | API + 缓存 + 模型加载 |
| Redis | 1.02 MB(空) | L2 缓存(冷启动) |
存储布局
NVMe SSD (/home/ai) HDD (/data)
├── 系统和服务 ├── PostgreSQL 数据目录
├── NVMe 表空间 (pg_tablespace) │ ├── documents: 5,114 MB
│ └── 嵌入暂存表(快速写入) │ ├── guoxue_content: 6,384 MB
└── GPU 模型缓存 │ ├── guji_documents: 5,060 MB
│ └── sys_books: 3,052 MB
└── Docker Volumes
3. 检索性能基准
测试环境: PostgreSQL 16 · pgvector 0.7.x · VACUUM ANALYZE 后 · HDD 存储后端 测试时间: 2026-04-13 · 数据量: documents 109K + guoxue 263K
单路检索性能
| 检索方式 | 数据表 | 数据量 | 延迟 (p50) | 说明 |
|---|---|---|---|---|
| HNSW 向量检索 | documents | 109K | 1.9 ms | top-10,余弦距离 |
| HNSW 向量检索(带类别过滤) | documents | 109K | 1.6 ms | category='中医' + top-10 |
| HNSW 向量检索 | guoxue_content | 264K | 2.1 ms | top-10,余弦距离 |
| GIN 全文检索 (chinese) | documents | 109K | 486 ms | to_tsquery('经络 & 穴位') |
| GIN 全文检索 (chinese) | documents | 109K | 550 ms | to_tsquery('气功 & 养生') |
| GIN search_vector | documents | 109K | 15,240 ms | ⚠️ simple 分词器,无索引命中 |
| GIN trigram | guoxue_content | 264K | 0.7 ms | ILIKE '%道德经%' |
| B-tree 类别过滤 | documents | 109K | 50 ms | category='气功' + ORDER BY |
| B-tree 类别+标题 | documents | 109K | 21 ms | category + ILIKE 复合 |
| JSONB qigong_dims | documents | 15K (气功) | 64 ms | ? 'discipline' |
混合检索端到端性能(估算)
| 阶段 | 预估延迟 | 说明 |
|---|---|---|
| 查询编码 | ~100 ms | BGE-small-zh CPU 推理 |
| 向量检索 | ~2 ms | HNSW 索引 |
| 全文检索 | ~7 ms | jieba + GIN 索引 |
| BM25 检索 | ~500 ms | 内存计算(200K 文档上限) |
| 音频检索 | ~5 ms | 目前无数据 |
| RRF 融合 | <1 ms | 内存计算 |
| Cross-Encoder 重排序 | ~200-500 ms | bge-reranker-v2-m3(GPU) |
| 总计(含重排序) | ~300-600 ms | — |
| 总计(无重排序) | ~110 ms | — |
性能瓶颈分析
| 瓶颈 | 影响 | 严重度 |
|---|---|---|
| BM25 全表扫描 | 200K 文档内存计算 ~500ms | 🟡 中 |
| GPU 显存(6GB) | 模型加载后余量有限 | 🟡 中 |
| HDD 存储 | 随机读写慢,影响 bulk UPDATE | 🟡 中 |
| Redis 冷启动 | 启动时无缓存数据(已实现预热) | 🟢 低 |
关键优化记录
| 优化措施 | 效果 | 日期 |
|---|---|---|
| VACUUM ANALYZE documents | HNSW: 2,802ms → 1.9ms(1466x) | 2026-04-13 |
| VACUUM ANALYZE guoxue_content | HNSW: 8,401ms → 2.1ms(4000x) | 2026-04-13 |
| NVMe 表空间写入嵌入 | 写入: 0.5/s → 55/s(110x) | 2026-04-13 |
| 删除 GIN 索引后批量 UPDATE | 28s/行 → 83 行/s(2340x) | 2026-04-13 |
| tsv_content GIN 索引 | 全文检索: 9,737ms → 4.2ms(2318x) | 2026-04-13 |
| jieba 预分词 + GIN 索引 | 全文检索: 486ms → 6.6ms(74x) | 2026-04-13 |
| BM25 覆盖率提升 | 50K → 200K(46% → 183%) | 2026-04-13 |
| FullTextRetriever 代码优化 | 运行时 to_tsvector() → 预计算列 |
2026-04-13 |
| 缓存预热 | 启动时预加载 categories/stats/domain_stats | 2026-04-13 |
4. 检索层(Retrieval)
2.1 向量检索(VectorRetriever)
语义相似度搜索,通过嵌入模型将文本转化为向量,在 pgvector 中进行近邻搜索。
嵌入模型
| 参数 | 值 |
|---|---|
| 模型 | BAAI/bge-small-zh-v1.5 |
| 维度 | 512 |
| 批量大小 | 32 |
| 设备 | CPU(默认),支持 GPU |
| 距离度量 | 余弦距离(<=>) |
检索流程
SQL 查询
SELECT id, title, content, category,
1 - (embedding <=> $1::vector) AS similarity
FROM documents
WHERE embedding IS NOT NULL
[AND category = $2]
ORDER BY embedding <=> $1::vector
LIMIT $3;
关键特性
- 单例模型加载,带 asyncio.Lock 双重检查
- 设置 TRANSFORMERS_OFFLINE=1 避免网络请求
- 空文本输入抛出 ValueError
- 批量更新时逐条容错,失败记录日志
源码:
backend/services/retrieval/vector.py
2.2 BM25 关键词检索(BM25Retriever)
经典 BM25 算法,适合精确关键词匹配场景。
算法参数
| 参数 | 值 | 说明 |
|---|---|---|
| k1 | 1.2 | 词频饱和参数 |
| b | 0.75 | 长度归一化参数 |
| 最大文档数 | 50,000 | 初始化加载上限 |
分词策略
BM25 评分公式
IDF(word) = log((N - df + 0.5) / (df + 0.5) + 1.0)
score = Σ IDF(w) × (tf × (k1 + 1)) / (tf + k1 × (1 - b + b × (dl / avgdl)))
其中 N = 文档总数,df = 包含该词的文档数,tf = 词频,dl = 文档长度,avgdl = 平均文档长度。
关键特性
- jieba 不可用时自动降级为正则分词
- 文档数为 0 时自动调用 initialize()
- 空查询返回空列表
源码:
backend/services/retrieval/bm25.py
2.3 全文检索(FullTextRetriever)
基于 PostgreSQL tsvector + GIN 索引的全文搜索。
检索流程
SQL 查询
SELECT id, title, content, category,
ts_rank(to_tsvector('chinese', content), to_tsquery('chinese', $1)) AS rank
FROM documents
WHERE to_tsvector('chinese', content) @@ to_tsquery('chinese', $1)
[AND category = $2]
ORDER BY rank DESC
LIMIT $3;
降级策略
- 中文分词器不可用 → LIKE '%query%' 模糊匹配(固定分 0.5)
GIN 索引
| 索引名 | 大小 | 目标 |
|---|---|---|
idx_documents_content_gin |
1,048 MB | to_tsvector('chinese', content) |
idx_documents_search_vector |
1,049 MB | search_vector (tsvector 列) |
idx_guoxune_body_head_trgm |
566 MB | substring(body, 1, 200) trigram |
源码:
backend/services/hybrid_retrieval.py→FullTextRetriever
2.4 混合检索(HybridRetriever)— 核心
融合多种检索方式,通过 RRF 算法合并结果,再经重排序优化。
完整检索流水线
查询 query
│
├── 1. 并行检索
│ ├── VectorRetriever.search(query, top_k × 2) ← 向量检索
│ ├── BM25Retriever.search(query, top_k × 2) ← 关键词检索
│ └── _search_audio(query, top_k) ← 音频段落检索
│
├── 2. RRF 融合排序
│ score[doc] = Σ (weight_i / (k + rank_i))
│ vector_weight = 0.6, bm25_weight = 0.4, k = 60
│
├── 3. 反馈质量加权
│ if helpful_ratio > 0.5:
│ score *= (1 + 0.1 × helpful_ratio)
│
├── 4. Cross-Encoder 重排序
│ bge-reranker-v2-m3 → rerank_score
│
├── 5. 知识缺口记录
│ if best_score < 0.3 or result_count == 0:
│ record_gap()
│
└── 6. 返回 top_k 结果
RRF(Reciprocal Rank Fusion)公式
| 参数 | 值 |
|---|---|
| vector_weight | 0.6 |
| bm25_weight | 0.4 |
| k | 60 |
音频检索
SELECT s.*, af.original_name, af.category,
1 - (s.embedding <=> $1::vector) AS similarity
FROM audio_segments s
JOIN audio_files af ON af.id = s.audio_file_id
WHERE s.embedding IS NOT NULL AND af.status = 'transcribed'
ORDER BY s.embedding <=> $1::vector
LIMIT $2;
容错机制
| 阶段 | 失败行为 |
|---|---|
| 向量检索 | 返回空结果 |
| BM25 检索 | 返回空结果 |
| 音频检索 | 跳过,仅记录警告 |
| 质量加权 | 跳过,仅记录调试日志 |
| 重排序 | 使用 RRF 原始排序 |
| 缺口记录 | 跳过,仅记录调试日志 |
源码:
backend/services/retrieval/hybrid.py
2.5 重排序(Reranker)
使用 Cross-Encoder 模型对初步结果进行精排。
模型配置
| 参数 | 值 |
|---|---|
| 模型 | BAAI/bge-reranker-v2-m3 |
| max_length | 512 |
| GPU top_n | 20 |
| CPU top_n | 10 |
| 文本截断 | 500 字符 |
重排序流程
容错
- 预测失败 → 返回原始排序前 top_k 条
- 候选 ≤ 1 条 → 直接返回
- 单例模型加载,带 asyncio.Lock
源码:
backend/services/retrieval/reranker.py
5. 推理层(Reasoning)
5.1 Chain-of-Thought 推理(CoTReasoner)
逐步推理模式,按查询类型选用不同 prompt 模板。
LLM 配置
| 参数 | 值 |
|---|---|
| 模型 | deepseek-chat |
| temperature | 0.7 |
| max_tokens | 2000 |
| 超时 | 60 秒 |
查询类型与 Prompt 模板
| QueryType | 策略 | 适用场景 |
|---|---|---|
FACTUAL |
直接回答 | 事实性问题 |
EXPLANATION |
核心概念 → 解释 → 总结 | 解释性问题 |
COMPARISON |
识别对象 → 多维比较 → 总结 | 比较性问题 |
MULTI_HOP |
分解 → 链式推理 → 结论 | 多步推理 |
REASONING |
要点 → 逐步分析 → 结论 | 通用推理(默认) |
置信度公式
step_score = min(len(steps) × 0.15, 0.5)
answer_score = min(len(answer) / 500, 0.5)
confidence = min(step_score + answer_score, 1.0)
LLM 调用链
源码:
backend/services/reasoning/cot.py
5.2 ReAct 推理(ReActReasoner)
Reasoning + Acting 模式,通过工具调用迭代推理。
参数
| 参数 | 值 |
|---|---|
| max_iterations | 5 |
| temperature | 0.7 |
| max_tokens | 1000(每轮) |
内置工具
| 工具 | 说明 |
|---|---|
search |
在上下文文档中按关键词搜索(返回 top 3) |
lookup |
按标题精确查找特定主题 |
Think-Act-Observe 循环
迭代 1: 思考 → 行动(search/lookup) → 观察结果
迭代 2: 思考 → 行动(search/lookup) → 观察结果
...
迭代 N: 思考 → 行动(finish) → 最终答案
输出格式
置信度公式
completed_actions = sum(1 for s in steps if s.action and s.action != "finish")
base_confidence = min(len(steps) × 0.1, 0.5)
action_bonus = min(completed_actions × 0.15, 0.3)
confidence = min(base_confidence + action_bonus, 1.0)
# 无步骤时返回 0.3
源码:
backend/services/reasoning/react.py
5.3 GraphRAG 知识图谱推理(GraphRAGReasoner)
基于知识图谱的多跳推理,适合关系型查询。
实体类型
| 类型 | 示例 |
|---|---|
| 功法 | 八段锦、五禽戏、太极拳、六字诀、易筋经 |
| 穴位 | 百会、膻中、气海、关元、命门、涌泉、足三里 |
| 概念 | 气、丹田、经络、气血、阴阳、虚实、寒热 |
| 动作 | 站桩、打坐、吐纳、导引、行气、采气 |
| 脏腑 | 心、肝、脾、肺、肾、胃、胆、膀胱、三焦 |
关系抽取规则
推理流程
参数
| 参数 | 值 |
|---|---|
| max_depth(路径查找) | 3 |
| 子图扩展 | 2-hop |
| temperature | 0.7 |
| max_tokens | 1500 |
置信度公式
entity_coverage = count(查询实体 in 子图)
base_confidence = min(entity_coverage × 0.2, 0.4)
relation_bonus = min(len(subgraph.relations) × 0.05, 0.4)
confidence = min(base_confidence + relation_bonus, 1.0)
源码:
backend/services/reasoning/graph_rag.py
5.4 自动模式选择
if "关系" in question or "区别" in question:
mode = "graph_rag"
elif "如何" in question or "步骤" in question:
mode = "react"
else:
mode = "cot"
推荐场景
| 模式 | 最佳场景 | 示例问题 |
|---|---|---|
| CoT | 通用问答 | "什么是气功?" |
| ReAct | 操作步骤类 | "如何练习八段锦?" |
| GraphRAG | 关系比较类 | "八段锦和五禽戏有什么区别?" |
6. 路由层(Gateway)
6.1 域名路由策略
| 策略 | 说明 |
|---|---|
DOMAIN_MATCH |
默认 — 关键词评分匹配 |
PRIORITY |
按优先级排序 |
ROUND_ROBIN |
轮询 |
LEAST_CONNECTIONS |
最少连接数 |
域名匹配评分公式
score = 0
for keyword in domain.keywords:
if keyword in question: score += 0.3
for category in domain.categories:
if category in question: score += 0.2
return min(score, 1.0)
路由流程
源码:
backend/gateway/router.py
6.2 十大领域
| 领域 | 类别 | DomainType | 优先级 | 关键词示例 |
|---|---|---|---|---|
| 气功 | 气功 | QIGONG | 10 | 气功、八段锦、五禽戏、太极拳、功法、养生、呼吸 |
| 中医 | 中医 | TCM | 9 | 中医、中药、针灸、经络、穴位、方剂、辨证 |
| 儒家 | 儒家 | CONFUCIAN | 8 | 儒家、孔子、论语、孟子、仁义、礼智 |
| 佛家 | 佛家 | BUDDHIST | 7 | 佛家、佛教、禅宗 |
| 道家 | 道家 | DAOIST | 6 | 道家、老子、道德经、庄子 |
| 武术 | 武术 | MARTIAL | 5 | 武术、功夫、拳法 |
| 哲学 | 哲学 | PHILOSOPHY | 4 | 哲学、思想、辩证 |
| 科学 | 科学 | SCIENCE | 3 | 科学、研究、实验 |
| 心理学 | 心理学 | PSYCHOLOGY | 2 | 心理学、心理、情绪 |
| 通用 | — | GENERAL | 0 | — (兜底) |
多域查询: 可并行查询多个领域,结果按 confidence > 0.3 过滤后降序排列。
源码:
backend/domains/registry.py·backend/domains/base.py
7. 缓存层(Cache)
两级缓存架构
TTL 配置
| 资源类型 | TTL | 说明 |
|---|---|---|
query_result |
1 小时 | 查询结果 |
vector_search |
30 分钟 | 向量搜索 |
llm_response |
2 小时 | LLM 响应 |
document |
1 天 | 文档数据 |
embedding |
7 天 | 嵌入向量 |
bm25_index |
1 天 | BM25 索引 |
domain_stats |
5 分钟 | 域名统计 |
health_check |
1 分钟 | 健康检查 |
api_search |
5 分钟 | API 搜索 |
api_categories |
30 分钟 | 类别列表 |
写入策略
| 策略 | 行为 |
|---|---|
WRITE_THROUGH |
同步写 L1 + L2 |
WRITE_BACK |
先写 L1,异步写 L2 |
WRITE_AROUND |
不写入缓存 |
缓存装饰器
| 装饰器 | 命名空间 | TTL |
|---|---|---|
@cached_query() |
query_result | 3600s |
@cached_vector_search() |
vector_search | 1800s |
@cached_llm() |
llm_response | 7200s |
@cached_document() |
document | 86400s |
@cached_stats() |
domain_stats | 300s |
@cached_api_search() |
api_search | 300s |
@cached_api_categories() |
api_categories | 1800s |
@cached_api_domain_stats() |
api_domain_stats | 600s |
@cached_api_stats() |
api_stats | 300s |
其他特性
- 热键追踪: 访问 ≥ 10 次的键标记为热键,支持预热
- 键策略: SIMPLE(拼接)、HASH(MD5 前16位)、JSON(序列化后 MD5)
- 降级: Redis 不可用时自动降级为 L1 纯内存模式
- 缓存旁路: 请求参数
skip_cache=True可跳过缓存
源码:
backend/cache/manager.py·backend/cache/decorators.py
8. 反馈闭环
用户反馈系统
反馈类型
| 类型 | 说明 |
|---|---|
helpful |
有帮助 |
not_helpful |
无帮助 |
wrong |
错误 |
irrelevant |
不相关 |
partial |
部分正确 |
质量评分计算
SELECT doc_id,
COUNT(*) AS total_feedback,
SUM(CASE WHEN feedback_type = 'helpful' THEN 1 ELSE 0 END) AS helpful_count,
ROUND(AVG(rating)::numeric, 2) AS avg_rating
FROM search_feedback
WHERE doc_id = ANY($1)
GROUP BY doc_id;
质量加权: helpful_ratio > 0.5 的文档在检索时获得 +10% × helpful_ratio 的分数提升。
知识缺口检测
检索结果 → if (best_score < 0.3) or (result_count == 0):
→ 记录为知识缺口
→ 7 天内相同查询 → hit_count++
→ hit_count ≥ 3 → 触发 LingMessage 告警
| 参数 | 值 |
|---|---|
| 分数阈值 | 0.3 |
| 告警阈值 | 2 次 |
| 去重窗口 | 7 天 |
源码:
backend/services/retrieval/feedback.py·backend/services/retrieval/gap_tracker.py
9. API 端点一览
9.1 搜索相关
| 方法 | 路径 | 说明 | 缓存 |
|---|---|---|---|
GET |
/api/v1/search |
基础关键词搜索 | 5 分钟 |
POST |
/api/v1/search/hybrid |
混合检索(向量+BM25+重排序) | 无 |
POST |
/api/v1/ask |
简单问答 | 无 |
GET |
/api/v1/categories |
文档类别列表 | 30 分钟 |
GET |
/api/v1/stats |
系统统计 | 5 分钟 |
POST |
/api/v1/search/embeddings/update |
更新文档嵌入 | 无 |
GET |
/api/v1/search/retrieval/status |
检索服务状态 | 无 |
9.2 推理相关
| 方法 | 路径 | 说明 |
|---|---|---|
POST |
/api/v1/reason |
多模式推理(cot/react/graph_rag/auto) |
POST |
/api/v1/graph/query |
知识图谱路径查询 |
GET |
/api/v1/graph/data |
知识图谱可视化数据 |
POST |
/api/v1/graph/build |
从文档构建知识图谱 |
GET |
/api/v1/reasoning/status |
推理服务状态 |
9.3 网关相关
| 方法 | 路径 | 说明 | 缓存 |
|---|---|---|---|
POST |
/api/v1/gateway/query |
统一网关查询(自动路由) | 无 |
GET |
/api/v1/domains |
列出所有领域 | 无 |
GET |
/api/v1/domains/{name}/stats |
领域统计 | 10 分钟 |
POST |
/api/v1/domains/{name}/query |
直接领域查询 | 无 |
GET |
/api/v1/metrics |
系统指标 | 无 |
GET |
/api/v1/gateway/stats |
网关路由统计 | 无 |
10. 关键参数速查表
检索参数
| 参数 | 值 | 位置 |
|---|---|---|
| 嵌入模型 | BAAI/bge-small-zh-v1.5 | vector.py |
| 嵌入维度 | 512 | vector.py |
| BM25 k1 | 1.2 | bm25.py |
| BM25 b | 0.75 | bm25.py |
| RRF vector_weight | 0.6 | hybrid.py |
| RRF bm25_weight | 0.4 | hybrid.py |
| RRF k | 60 | hybrid.py |
| 质量加权阈值 | helpful_ratio > 0.5 | hybrid.py |
| 质量加权幅度 | +10% × ratio | hybrid.py |
| 重排序模型 | bge-reranker-v2-m3 | reranker.py |
| 重排序 top_n | GPU=20 / CPU=10 | reranker.py |
推理参数
| 参数 | 值 | 位置 |
|---|---|---|
| LLM 模型 | deepseek-chat | cot.py / react.py / graph_rag.py |
| CoT temperature | 0.7 | cot.py |
| CoT max_tokens | 2000 | cot.py |
| ReAct 最大迭代 | 5 | react.py |
| ReAct max_tokens | 1000/轮 | react.py |
| GraphRAG 路径深度 | 3 | graph_rag.py |
| GraphRAG 子图扩展 | 2-hop | graph_rag.py |
| 缺口检测阈值 | score < 0.3 | gap_tracker.py |
| 缺口告警阈值 | 2 次 | gap_tracker.py |
缓存参数
| 参数 | 值 | 位置 |
|---|---|---|
| 默认 TTL | 3600s | manager.py |
| L1 最大条目 | 1000 | manager.py |
| 键前缀 | zhineng_kb: |
manager.py |
| 热键阈值 | 10 次访问 | manager.py |
| 默认写入策略 | WRITE_THROUGH | manager.py |
11. 容量预期与扩展规划
当前负载能力估算
| 指标 | 当前值 | 基于基准 |
|---|---|---|
| 向量检索 QPS | ~500 QPS | 1.9ms/query,单连接串行 |
| 全文检索 QPS | ~150 QPS | 6.6ms/query,jieba + GIN |
| 混合检索(含重排序)QPS | ~3 QPS | ~300ms/query |
| 混合检索(无重排序)QPS | ~3 QPS | ~300ms/query |
| GPU 嵌入编码吞吐 | 55 行/秒 | BGE-small-zh + GTX 1660 Ti |
| GPU 重排序吞吐 | ~20 对/秒 | bge-reranker-v2-m3 |
数据增长预测
documents 表(九域知识)
| 场景 | 预期年增量 | 预期总行数(1年) | 预期表大小 |
|---|---|---|---|
| 保守 | +10,000 | ~120K | ~5.6 GB |
| 中等 | +50,000 | ~160K | ~7.4 GB |
| 激进 | +100,000 | ~210K | ~9.8 GB |
guoxue_content 表(国学经典)
| 场景 | 预期年增量 | 预期总行数(1年) | 预期表大小 |
|---|---|---|---|
| 保守 | +5,000 | ~269K | ~6.5 GB |
| 中等 | +20,000 | ~284K | ~6.9 GB |
| 激进 | +50,000 | ~314K | ~7.6 GB |
数据库总大小预测
| 场景 | 1 年后 | 3 年后 |
|---|---|---|
| 保守 | ~25 GB | ~35 GB |
| 中等 | ~35 GB | ~65 GB |
| 激进 | ~45 GB | ~100 GB |
索引增长预测
| 索引 | 当前大小 | 增长系数 | 预期 1 年(中等) |
|---|---|---|---|
| HNSW (documents) | 285 MB | 线性 | ~420 MB |
| HNSW (guoxue) | 655 MB | 线性 | ~705 MB |
| GIN content (documents) | 1,048 MB | 近线性 | ~1,530 MB |
| GIN search_vector (documents) | 1,049 MB | 近线性 | ~1,530 MB |
| GIN trigram (guoxue) | 566 MB | 近线性 | ~610 MB |
| 索引总计 | ~3,625 MB | — | ~4,800 MB |
扩展瓶颈与对策
短期(0-6 个月)
| 瓶颈 | 风险 | 对策 | 状态 |
|---|---|---|---|
| ~~GIN 全文检索慢(486ms)~~ | ~~混合检索延迟高~~ | jieba 预分词 + GIN 索引 → 6.6ms | ✓ 已解决 |
~~search_vector 列无有效索引~~ |
~~15 秒查询~~ | jieba 重建 + GIN 索引 | ✓ 已解决 |
| ~~BM25 内存上限(50K)~~ | ~~46% 文档无法被 BM25 索引~~ | _MAX_INIT_DOCS 50K → 200K |
✓ 已解决 |
| ~~Redis 冷启动~~ | ~~首批请求慢~~ | CacheWarmer 预加载 categories/stats | ✓ 已解决 |
| HDD 随机 I/O | 写入慢、VACUUM 慢 | 将 default_tablespace 迁移至 NVMe,HDD 仅做归档 |
P2 |
中期(6-12 个月)
| 瓶颈 | 风险 | 对策 |
|---|---|---|
| 数据量 > 50 万行 | HNSW 索引构建时间 > 30 分钟 | 预建索引 +增量更新;或切换到 IVFFlat |
| GPU 显存不足(6GB) | 重排序 batch size 受限 | 升级至 RTX 4060 16GB 或使用 API 重排序 |
| 单实例 PostgreSQL | 无高可用 | 引入 PG 主从复制 + PgBouncer 连接池 |
| BM25 全表扫描 | 20 万+ 文档时 > 1 秒 | 引入 Elasticsearch / Meilisearch 做关键词检索 |
长期(1-3 年)
| 瓶颈 | 风险 | 对策 |
|---|---|---|
| 数据量 > 100 万行 | HNSW 查询 > 10ms | 升级嵌入模型至 1024 维 + 量化索引(PQ/SQ) |
| 多用户并发 | 单连接瓶颈 | PgBouncer + 读写分离 + 缓存层扩展 |
| LLM API 延迟/成本 | 推理端到端 > 5 秒 | 本地部署 Qwen2.5-7B / DeepSeek-7B 做推理 |
| 存储空间 | HDD 容量不足 | 迁移全量至 NVMe / 云存储 + 冷热分层 |
性能优化路线图
当前状态 3 个月目标 12 个月目标
───────── ────────── ──────────
向量检索: 1.9ms 向量检索: <2ms 向量检索: <5ms (100万行)
全文检索: 6.6ms →→→ 全文检索: <5ms →→→ 全文检索: <20ms (ES)
混合检索: 110ms 混合检索: <100ms 混合检索: <100ms
BM25 覆盖: 183% BM25 覆盖: 100% 关键词: Elasticsearch
GPU 编码: 55/s GPU 编码: 55/s GPU 编码: 200/s (新GPU)
数据库: 20GB 数据库: ~35GB 数据库: ~65GB
监控指标建议
| 指标 | 采集方式 | 告警阈值 |
|---|---|---|
| 向量检索延迟 P99 | Prometheus /metrics |
> 50 ms |
| 全文检索延迟 P99 | Prometheus /metrics |
> 50 ms |
| 混合检索端到端 P99 | API 中间件 | > 3,000 ms |
| HNSW 索引大小 | pg_relation_size() |
> 2 GB |
| 缓存命中率 | CacheManager metrics | < 60% |
| GPU 显存占用 | torch.cuda.memory_allocated() |
> 5 GB |
| 磁盘使用率 | df -h |
> 80% |
| 死元组比例 | pg_stat_user_tables |
> 10% |
本文档基于代码库自动提取生成,最后更新: 2026-04-13