Day 16 混合检索 --- 字段/名词/配置速查手册
本文档是 Day 16 day16-hybrid-rag 项目中所有字段名、配置项、实体 DTO、技术术语的集中索引。
每项按 英文名 / 中文名 / 解释 三栏组织。
一、实体 DTO
1.1 HybridSearchResult --- 检索结果
| 字段 |
类型 |
中文名 |
解释 |
id |
String |
文档唯一标识 |
PGVector 表中的 embedding_id,UUID 格式 |
text |
String |
文档原文片段 |
向量库中存储的文档文本内容 |
metadata |
String |
元数据 |
JSON 字符串,含 source、page、filename 等附加信息 |
score |
double |
相关性分数 |
0, 1 区间,1 表示最相关。向量阶段是余弦相似度,Reranker 阶段是 relevance_score |
source |
String |
来源标识 |
取值:"vector"(向量检索)/ "keyword"(关键词检索)/ "rrf"(RRF 融合)/ "rerank"(Reranker 精排) |
1.2 ApiResult<T> --- 统一 API 响应体
| 字段 |
类型 |
中文名 |
解释 |
code |
int |
状态码 |
200 = 成功,500 = 失败 |
message |
String |
提示信息 |
成功时为 "success",失败时为错误描述 |
data |
T |
响应数据 |
泛型,具体类型由接口决定 |
静态工厂方法:
| 方法 |
解释 |
ApiResult.ok(data) |
创建成功响应(code=200, message="success") |
ApiResult.fail(message) |
创建失败响应(code=500, data=null) |
二、配置项(application.yml)
2.1 硅基流动 API 配置
| 配置键 |
类型 |
中文名 |
取值 |
解释 |
siliconflow.api-key |
String |
API 密钥 |
sk-xxx... |
硅基流动平台认证密钥 |
siliconflow.base-url |
String |
API 基础地址 |
https://api.siliconflow.cn/v1 |
兼容 OpenAI 接口格式 |
siliconflow.model-name |
String |
对话模型 |
deepseek-ai/DeepSeek-V3 |
用于普通对话和流式对话的大语言模型 |
siliconflow.embedding-model |
String |
Embedding 模型 |
BAAI/bge-large-zh-v1.5 |
将文本转为 1024 维向量的模型 |
siliconflow.rerank-model |
String |
Reranker 模型 |
BAAI/bge-reranker-v2-m3 |
Cross-Encoder 重排序模型 |
2.2 数据库配置
| 配置键 |
类型 |
中文名 |
取值 |
解释 |
server.port |
int |
服务端口 |
8088 |
Spring Boot 嵌入式 Tomcat 监听端口 |
spring.datasource.url |
String |
数据库连接地址 |
jdbc:postgresql://localhost:5432/aidb |
PostgreSQL 连接串 |
spring.datasource.username |
String |
数据库用户名 |
ai |
|
spring.datasource.password |
String |
数据库密码 |
password |
|
spring.datasource.driver-class-name |
String |
JDBC 驱动类 |
org.postgresql.Driver |
PostgreSQL 驱动 |
spring.datasource.hikari.maximum-pool-size |
int |
连接池最大连接数 |
10 |
HikariCP 配置 |
spring.datasource.hikari.minimum-idle |
int |
连接池最小空闲连接 |
5 |
HikariCP 配置 |
spring.datasource.hikari.idle-timeout |
int |
空闲超时(毫秒) |
300000 |
5 分钟,超时空闲连接被回收 |
spring.datasource.hikari.connection-timeout |
int |
连接超时(毫秒) |
10000 |
10 秒,等待连接池的最大时间 |
三、服务层常量与参数
3.1 HybridSearchService 参数
| 常量 |
值 |
中文名 |
解释 |
RRF_K |
60 |
RRF 平滑常数 |
Reciprocal Rank Fusion 的 k 值;k 越大曲线越平坦,排名差异影响越小 |
RECALL_TOP |
20 |
单路召回上限 |
向量检索和关键词检索各自最多返回的条数 |
FINAL_TOP |
5 |
最终输出条数 |
Reranker 精排后输出的文档数 |
NGRAM_MIN |
2 |
N-gram 最小长度 |
中文单字无意义,2 字起步 |
NGRAM_MAX |
4 |
N-gram 最大长度 |
4-gram 已覆盖绝大多数中文词组 |
NGRAM_TOP |
8 |
N-gram 词条上限 |
控制 SQL CASE WHEN 数量,同时覆盖问句关键词 |
3.2 HybridSearchService 方法
| 方法名 |
可见性 |
中文名 |
解释 |
search(query, tableName) |
public |
混合检索入口 |
执行完整三阶段流水线,返回 Top-5 |
vectorSearch(query, tableName) |
private |
向量检索 |
PGVector <=> 余弦距离查询,Top-20 |
keywordSearch(query, tableName) |
private |
关键词检索 |
N-gram + ILIKE 模糊匹配,Top-20 |
cleanQuery(query) |
private |
查询清理 |
去标点、英文、数字、停用单字 |
generateNgrams(text) |
private |
N-gram 生成 |
滑动窗口 2-4 字,去重取前 8 个 |
rrfFusion(listA, listB) |
private |
RRF 融合 |
双路排名→RRF 分数→合并排序 |
accumulateRrf(scores, list) |
private |
RRF 累加 |
逐条累加 1/(k+排名) |
executeQuery(sql, source) |
private |
SQL 执行 |
JDBC 查询 + ResultSet→HybridSearchResult 映射 |
embeddingToPgVector(vec) |
private |
向量转换 |
List<Float> → PGVector 字面量字符串 |
nvl(s, def) |
private |
空值处理 |
字符串为空时返回默认值 |
truncate(s, max) |
private |
日志截断 |
截断长字符串,尾部加 "..." |
3.3 RerankService 方法
| 方法名 |
可见性 |
中文名 |
解释 |
rerank(query, candidates, topN) |
public |
重排序入口 |
调硅基流动 API,失败时降级 |
parseResponse(candidates, body) |
private |
响应解析 |
JSON → RerankResponse DTO → HybridSearchResult 列表 |
truncate(s, max) |
private |
日志截断 |
同 HybridSearchService 的工具方法 |
3.4 RerankService 内部 DTO
| 类名 |
字段 |
类型 |
中文名 |
解释 |
RerankResponse |
results |
List<RerankResult> |
重排结果列表 |
API 返回的顶层对象 |
RerankResult |
index |
int |
索引 |
0 起始,对应请求中 documents 数组的位置 |
RerankResult |
relevanceScore |
double |
相关性分数 |
Cross-Encoder 输出,区间 0, 1 |
四、API 端点
4.1 GET /search --- 纯检索
| 参数 |
类型 |
必填 |
默认值 |
解释 |
query |
String |
✅ |
--- |
用户问题文本 |
table |
String |
❌ |
day4_rag_store |
PGVector 表名 |
返回 :ApiResult<List<HybridSearchResult>>,Top-5 文档含 score 和 source。
4.2 GET /rag/chat --- RAG 对话
| 参数 |
类型 |
必填 |
默认值 |
解释 |
message |
String |
✅ |
--- |
用户问题文本 |
table |
String |
❌ |
day4_rag_store |
PGVector 表名 |
返回 :ApiResult<Map<String, Object>>,含 4 个键:
query --- 用户原始问题
documents --- HybridSearchResult 数组
prompt --- 组装好的 RAG Prompt
hint --- 使用提示文字
五、ChatModelConfig Bean 定义
| Bean 名称 |
类型 |
中文名 |
解释 |
openAiChatModel |
OpenAiChatModel |
普通对话模型 |
同步阻塞式,temperature=0.3,超时 60s,重试 2 次 |
openAiStreamingChatModel |
OpenAiStreamingChatModel |
流式对话模型 |
SSE 逐 Token 输出,temperature=0.3,超时 60s |
openAiEmbeddingModel |
EmbeddingModel |
Embedding 模型 |
文本 → 1024 维向量,重试 2 次 |
参数说明:
| 参数 |
值 |
解释 |
temperature |
0.3 |
温度系数,越低输出越确定,适合事实性问答 |
timeout |
60s |
请求超时,防止线程长期阻塞 |
maxRetries |
2 |
失败自动重试次数(流式模型不设此值) |
六、Maven 依赖清单
| groupId |
artifactId |
version |
作用 |
org.springframework.boot |
spring-boot-starter-parent |
3.4.3 |
Spring Boot 父 POM,统一版本管理 |
org.springframework.boot |
spring-boot-starter-web |
(继承自 parent) |
MVC + 嵌入式 Tomcat 10.1 |
org.springframework.boot |
spring-boot-starter-jdbc |
(继承自 parent) |
JDBC + HikariCP 连接池 |
org.springframework.boot |
spring-boot-starter-test |
(继承自 parent) |
JUnit 5 + Mockito 测试框架 |
dev.langchain4j |
langchain4j |
1.13.1 |
LangChain4j 核心库 |
dev.langchain4j |
langchain4j-open-ai |
1.13.1 |
OpenAI 兼容接口适配(硅基流动用此) |
dev.langchain4j |
langchain4j-pgvector |
1.13.1-beta23 |
PGVector 集成支持 |
org.postgresql |
postgresql |
(继承自 parent) |
PostgreSQL JDBC 驱动 |
org.projectlombok |
lombok |
(由 SB 3.4.3 管理) |
编译期注解(@Data/@Builder/@Slf4j 等) |
org.apache.httpcomponents |
httpclient |
4.5.14 |
HTTP 客户端(Reranker API 直调用) |
com.github.ulisesbocchio |
jasypt-spring-boot-starter |
3.0.5 |
配置文件加密 |
七、SQL 表与列
7.1 day4_rag_store(PGVector 表)
| 列名 |
类型 |
解释 |
embedding_id |
text / uuid |
主键,文档唯一标识 |
text |
text |
文档原文片段 |
metadata |
text / jsonb |
元数据 JSON(source, page, filename 等) |
embedding |
vector(1024) |
1024 维向量(BGE-large-zh-v1.5 输出维度) |
7.2 SQL 关键技术点
| SQL 写法 |
解释 |
embedding <=> '[...]'::vector |
PGVector 余弦距离运算符,返回值 0, 2,0 = 完全相同,2 = 完全相反 |
1 - (embedding <=> '...') |
将余弦距离转为相似度,0 = 不相关,1 = 完全相同 |
text ILIKE '%关键词%' |
PostgreSQL 不区分大小写的模糊匹配 |
CASE WHEN ... THEN 1 ELSE 0 END |
条件打分:命中关键词 +1 分 |
1.0 / (1 + length(text) / 500.0) |
长度惩罚:长文档得分打折,短精确片段得分更高 |
八、技术术语速查
8.1 检索相关
| 术语 |
英文全称 |
解释 |
| 混合检索 |
Hybrid Search |
向量语义检索 + 关键词精确匹配双路召回,互补短板 |
| 双路召回 |
Dual Recall |
同时跑向量检索和关键词检索,各自返回 Top-20 |
| RRF |
Reciprocal Rank Fusion |
排名融合算法,不看绝对值只看排名:score = Σ 1/(k+rank) |
| RRF_K |
RRF Smoothing Constant |
RRF 平滑常数,k=60 是 TREC 论文经典取值 |
| Reranker |
Cross-Encoder Reranker |
联合编码问句+文档的二次排序模型,精度远高于双塔模型 |
| Cross-Encoder |
--- |
将 (query, document) 成对输入,通过自注意力交互打分 |
| 双塔模型 |
Bi-Encoder / Dual Encoder |
分别编码问句和文档再算余弦相似度,速度快但精度低于 Cross-Encoder |
| relevance_score |
--- |
Reranker 输出的相关性分数,区间 0, 1,越高越相关 |
8.2 向量相关
| 术语 |
英文全称 |
解释 |
| Embedding |
--- |
将文本映射为高维向量的过程/结果 |
| 向量检索 |
Vector Search |
计算问句向量与文档向量的余弦距离,按相似度排序 |
| PGVector |
--- |
PostgreSQL 的向量扩展插件,支持向量存储和相似度查询 |
| 余弦距离 |
Cosine Distance |
<=> 运算符返回值,0=完全相同,2=完全相反 |
| 余弦相似度 |
Cosine Similarity |
1 - 余弦距离,1=完全相同,0=不相关 |
| BGE |
BAAI General Embedding |
北京智源研究院(BAAI)发布的 Embedding/Reranker 模型系列 |
| bge-large-zh-v1.5 |
--- |
BGE 中文 Embedding 模型,输出 1024 维向量 |
| bge-reranker-v2-m3 |
--- |
BGE 多语言 Cross-Encoder Reranker 模型 |
8.3 关键词检索相关
| 术语 |
英文全称 |
解释 |
| N-gram |
--- |
滑动窗口将文本切为连续 n 个字符的片段,如 2-gram、3-gram |
| ILIKE |
--- |
PostgreSQL 的不区分大小写 LIKE,用于模糊匹配 |
| CASE WHEN |
--- |
SQL 条件表达式,用于构建打分逻辑 |
| 长度惩罚 |
Length Penalty |
1/(1+len/500),短精确片段得分更高 |
| 停用词 |
Stop Words |
检索中无意义的中文单字,如"的""了""是",检索前过滤掉 |
8.4 AI 平台相关
| 术语 |
解释 |
| 硅基流动 |
SiliconFlow,国内 AI 模型服务商,提供 OpenAI 兼容接口 |
| DeepSeek-V3 |
深度求索大语言模型,通过硅基流动调用 |
| BAAI |
北京智源人工智能研究院,BGE 系列模型的发布方 |
| OpenAI 兼容接口 |
硅基流动的 API 格式兼容 OpenAI,LangChain4j 的 OpenAiChatModel 可直接对接 |
8.5 框架与中间件
| 术语 |
解释 |
| Spring Boot 3.4.3 |
Java 企业级应用框架 |
| LangChain4j 1.13.1 |
Java 版 LangChain,LLM 应用开发框架 |
| HikariCP |
Spring Boot 默认 JDBC 连接池,高性能 |
| Apache HttpClient 4.5.14 |
直接调 Reranker API 用的 HTTP 客户端(绕过 LangChain4j 限制) |
| Lombok |
Java 编译期注解处理器,版本由 SB 3.4.3 管理 |
| Jackson |
JSON 序列化/反序列化库,Spring Boot 默认集成 |
| Tomcat 10.1 |
Spring Boot 3.x 内置的 Servlet 容器 |
8.6 容错与降级
| 术语 |
解释 |
| 降级策略 |
Reranker API 调用失败时不抛异常,返回 RRF 融合后的原始结果 |
| 优雅降级 |
Graceful Degradation,部分功能不可用时整体服务仍可用 |
| try-with-resources |
Java 7+ 语法,自动关闭 Connection / PreparedStatement / ResultSet |
| 重试机制 |
ChatModel 配 maxRetries=2,覆盖网络抖动导致的瞬时失败 |
九、项目目录结构速查
day16-hybrid-rag/
├── pom.xml # Maven 依赖管理(JDK 17, SB 3.4.3, LC4j 1.13.1)
├── README.md # 项目文档
└── src/
├── main/
│ ├── java/com/day16/demo/
│ │ ├── Day16Application.java # @SpringBootApplication 启动入口
│ │ ├── config/
│ │ │ ├── ChatModelConfig.java # 3 个 Bean 定义
│ │ │ └── DataInitializer.java # 启动时自动向量化知识库文档
│ │ ├── controller/
│ │ │ └── SearchController.java # /search + /rag/chat
│ │ ├── core/
│ │ │ └── HybridSearchResult.java # 检索结果实体
│ │ ├── dto/
│ │ │ └── ApiResult.java # 统一响应体
│ │ └── rag/
│ │ ├── HybridSearchService.java # 三阶段编排
│ │ └── RerankService.java # Reranker API 调用
│ └── resources/
│ ├── application.yml # 配置(端口/API Key/数据源)
│ ├── schema.sql # 建表 DDL
│ ├── data.sql # 示例 SQL
│ ├── docs/ # 知识库种子文档
│ └── static/
│ └── index.html # 检索前端
└── test/ # (未使用)
十、三阶段流水线示意
用户 Query
│
├──→ [阶段 1: 双路召回]
│ ├── 向量检索:Embedding → PGVector <=> → 余弦相似度排序 → Top-20
│ └── 关键词检索:cleanQuery → N-gram 2-4 → ILIKE 打分 → Top-20
│
├──→ [阶段 2: RRF 融合]
│ 公式:score = 1/(60+向量排名) + 1/(60+关键词排名)
│ 输出:去重后的候选集
│
└──→ [阶段 3: Reranker 精排]
POST /v1/rerank → Cross-Encoder 联合编码 → relevance_score 排序 → Top-5
文档版本:v1.1 | 更新日期:2026-06-26 | 对应代码:day16-hybrid-rag