高级RAG解决的痛点:
解决基础 RAG(Naive RAG)在面对复杂业务场景时暴露出的“找不到、找不准、用不好”等核心痛点,我们可以把基础 RAG 的痛点归纳为三个阶段:检索前(提问阶段)、检索中(寻找阶段)和检索后(生成阶段)。高级 RAG 正是通过引入更复杂的机制,精准干预了这三个阶段。
Advanced RAG流程(高级 RAG 流程):

RetrievalAugmentor 检索增强器
实现高级RAG的核心就是配置RetrievalAugmentor(检索增强器)
在配置AiServices的时候,官方包里有对应的获取retrievalAugmentor方法
package dev.langchain4j.service;
public abstract class AiServices<T> {
...
public AiServices<T> retrievalAugmentor(RetrievalAugmentor retrievalAugmentor) {
if (this.contentRetrieverSet) {
throw IllegalConfigurationException.illegalConfiguration("Only one out of [retriever, contentRetriever, retrievalAugmentor] can be set");
} else {
this.retrievalAugmentorSet = true;
this.context.retrievalAugmentor = (RetrievalAugmentor)ValidationUtils.ensureNotNull(retrievalAugmentor, "retrievalAugmentor");
return this;
}
}
...
}
所以可以直接注入AIservice:
注意:这里“MyAiService”必须是接口,LangChain4j 内部使用了 Java 的动态代理
当你调用 AiServices.builder(MyService.class).build() 时,自动为你生成了一个代理实现类。
/**
LangChain4j 的 AiServices 原生支持响应式流。
如果返回值是 Flux<String>,
LangChain4j 会自动将其识别为流式传输(Streaming)
*/
public interface MyAiService{
public Flux<String> streamChat(自定义参数);
public String chat(自定义参数);
}
===============================================================================
MyAiService aiService = AiServices.builder(MyAiService.class)
....
.retrievalAugmentor(retrievalAugmentor)//放到这里
.build();
如何配置 RetrievalAugmentor?
RetrievalAugmentor主要组件:
可以通过 LangChain4j 配合以下核心组件实现
| QueryTransformer | 优化检索词 | 解决“用户不会提问”问题 |
| QueryRouter | 查询路由 | 允许同一个系统同时向不同的介质(向量库、关系型数据库、Web 搜索引擎)发起检索 |
| ContentRetriever | 检索器 | |
| ContentAggregator | 聚合检索结果(重排序 | 对这些杂乱的数据进行合并、去重、筛选和重新排序。 |
| ContentInjector | 将检索到的内容注入 prompt | “高质量上下文” |
代码实现:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package dev.langchain4j.rag;
public interface RetrievalAugmentor {
AugmentationResult augment(AugmentationRequest var1);
}
|
V
public class DefaultRetrievalAugmentor implements RetrievalAugmentor{...}
===============================上面是源码==========================================
|
V
RetrievalAugmentor retrievalAugmentor = DefaultRetrievalAugmentor.builder()
.queryRouter(...)
.queryTransformer(...)
.contentAggregator(...)
.contentInjector(...)
.build();
1.QueryTransformer(优化检索词)
langchain4j包中实现查询转换的接口
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package dev.langchain4j.rag.query.transformer;
import dev.langchain4j.rag.query.Query;
import java.util.Collection;
public interface QueryTransformer {
Collection<Query> transform(Query var1);
}
支持多种场景:
- 查询改写(Query Rewriting)- 把一个查询改写成另一个更好的形式
- 查询扩展(Query Expansion)- 把一个查询扩展成多个相关查询
- 查询压缩(Query Compression)- 从对话历史中提取核心查询
- 查询分解(Query Decomposition)- 把复杂查询拆分成多个子查询
代码实现:
//核心就是编写个专门用来优化检索词的prompt
//核心就是编写个专门用来优化检索词的prompt
private static final PromptTemplate LG_AGENT_PROMPT = PromptTemplate.from("""
编写优化检索词的提示词
""");
public class MyQueryTransformer implements QueryTransformer {
@Override
public Collection<Query> transform(Query query) {
// 你的转换逻辑
...
}
}
MyQueryTransformer queryTransformer = new MyQueryTransformer();
RetrievalAugmentor retrievalAugmentor = DefaultRetrievalAugmentor.builder()
.queryRouter(...)
.queryTransformer(queryTransformer) // 这里
.contentAggregator(...)
.contentInjector(...)
.build();
放进去后,当用AIservice调用接口中的方法时: 自动调用 queryTransformer.transform(query)
2、QueryRouter(查询路由)
langchain4j包里的queryRouter方法:
package dev.langchain4j.rag;
public class DefaultRetrievalAugmentor implements RetrievalAugmentor {
...
public static class DefaultRetrievalAugmentorBuilder {
...
public DefaultRetrievalAugmentorBuilder queryRouter(QueryRouter queryRouter) {
this.queryRouter = queryRouter;
return this;
}
...
}
}
接收的是QueryRouter类型的参数,这是个接口:
package dev.langchain4j.rag.query.router;
public interface QueryRouter {
Collection<ContentRetriever> route(Query var1);
}
直接实现这个接口:
核心:构建prompt,让llm返回该问题属于哪种场景:
常见的 RAG 查询路由场景:
1. 向量检索:语义相似性、模糊匹配、概念理解
2. 关键词检索:精确匹配、专有名词、编号、错误码
3. 结构化查询:聚合、统计、范围查询、排序
4. 图查询(Graph/Neo4j)
根据返回的场景从所有检索器(Collection<ContentRetriever>)中筛选出 对应的 检索器
代码实现:
public class MyQueryRouter implements QueryRouter {
private static final PromptTemplate QUERY_ROUTE_PROMPT = PromptTemplate.from(...)
@Override
public Collection<ContentRetriever> route(Query query) {
//路由问题,获取结果
//判断执行哪个检索器
}
}
RetrievalAugmentor retrievalAugmentor = DefaultRetrievalAugmentor.builder()
.queryRouter(new MyQueryRouter(检索器集合...))
.queryTransformer(queryTransformer)
.contentAggregator(...)
.contentInjector(...)
.build();
3.ContentAggregator(聚合检索结果(去重、重排序))
核心是:RAG重排序
什么是重排序?
重排序(Reranking)是在通过混合检索(或其他方式)获得初步检索结果(候选文本块)后,再通过更強的模型(通常是Cross-Encoder或专用Reranker模型)对这些候选文本块进行重新打分和排序,将真正最相关、最有价值的内容排在前面。
重排序作用:
过滤噪声:初步检索往往会召回数十条文档,其中可能混杂着相关性较低的"噪声"内容。
提升答案精度,
优化上下文窗口利用率:把最相关的放前面
实现方式:
| 原理 | 使用 | |
| RRF(Reciprocal Rank Fusion,倒数排名融合) |
不看各个检索模型给出的绝对评分(Score),只看文档在各个检索结果列表中的相对排名(Rank),并通过倒数求和的方式进行多路召回结果的融合。 | 当向 DefaultContentAggregator 传入多个检索器或使用了QueryTransformer 导致产生了多个查询时,LangChain4j 内部就会自动触发 RRF 算法为你融合排名 |
| ReRank模型 |
基于语义模型重新打分使用深度学习模型计算相关性 |
三种实现方式: 1.用云服务API eg:Cohere 2.去Hugging Face下载到本地 3.将重排模型独立部署(Hugging Face的TEI) |
用哪个?
| 只用RRF |
DefaultContentAggregator(内置RRF) |
| 只用ReRank | 自己实现聚合器,调用scoringModel |
| 二者兼得 |
ReRankingContentAggregator |
项目里先用 RRF 将多路检索(如向量+全文)的结果融合成一路,再用 ReRank 模型进行高精度的深度打分。
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package dev.langchain4j.rag.content.aggregator;
public interface ContentAggregator {
List<Content> aggregate(Map<Query, Collection<List<Content>>> var1);
}
package dev.langchain4j.rag.content.aggregator;
public class ReRankingContentAggregator implements ContentAggregator {
...
}
LangChain4j 官方已经内置了 ReRankingContentAggregator。 只需要直接通过 ReRankingContentAggregator.builder().scoringModel(...).build() 就能实现重排序。
// 聚合器
ContentAggregator contentAggregator = new ProgressAwareContentAggregator(
ReRankingContentAggregator.builder()
.scoringModel(scoringModel)//ReRank模型
.maxResults(5)
.build());
RetrievalAugmentor retrievalAugmentor = DefaultRetrievalAugmentor.builder()
.queryRouter(new MyQueryRouter(检索器集合...))
.queryTransformer(queryTransformer)
.contentAggregator(contentAggregator)
.contentInjector(...)
.build();
4、ContentInjector (将检索到的内容注入 prompt)
直接用的 LangChain4j 的 DefaultContentInjector。
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package dev.langchain4j.rag.content.injector;
public class DefaultContentInjector implements ContentInjector {
....
public DefaultContentInjector() {
this(DEFAULT_PROMPT_TEMPLATE, (List)null);
}
public DefaultContentInjector(PromptTemplate promptTemplate, List<String> metadataKeysToInclude) {
this.promptTemplate = (PromptTemplate)Utils.getOrDefault(promptTemplate, DEFAULT_PROMPT_TEMPLATE);
this.metadataKeysToInclude = Utils.copy(metadataKeysToInclude);
}
}
只需要:放进RetrievalAugmentor 里就行,底层自动完成,内容注入
//将检索到的内容注入到 LLM 的 Prompt 中
ContentInjector contentInjector = new DefaultContentInjector();
RetrievalAugmentor retrievalAugmentor = DefaultRetrievalAugmentor.builder()
.queryRouter(new MyQueryRouter(检索器集合...))
.queryTransformer(queryTransformer)
.contentAggregator(contentAggregator)
.contentInjector(contentInjector)
.build();
// 注入到 AI Service 中
MyAiService aiService = AiServices.builder(MyAiService.class)
...
.retrievalAugmentor(retrievalAugmentor)
.build();

645

被折叠的 条评论
为什么被折叠?



