当前位置: 首页 > news >正文

实现高级RAG(Advanced RAG)--RetrievalAugmentor--LangChain4j

高级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); }
支持多种场景:
  1. 查询改写(Query Rewriting)- 把一个查询改写成另一个更好的形式
  2. 查询扩展(Query Expansion)- 把一个查询扩展成多个相关查询
  3. 查询压缩(Query Compression)- 从对话历史中提取核心查询
  4. 查询分解(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();
http://www.gsyq.cn/news/1514507.html

相关文章:

  • 当传统PID不够用:聊聊MFAC无模型控制在工业过程控制里的实战调参经验
  • 2026宜宾装修公司怎么选?本地6家机构实力横评,附真实案例与报价参考 - 优质品牌商家
  • 2026年AI API中转站选型指南:在技术透明度与成本控制之间寻找平衡
  • CT重建速度大比拼:OS-SART vs SART,在GPU上到底能快多少?(附PyTorch代码)
  • 常州、江阴这些地方买ECO棉床垫,我的亲身对比 - 深圳市民HLL
  • HarmonyOS PC 订单卡片设计——数据驱动多态样式的实战指南
  • 从‘椅子旋转’到代码:图解神经网络中的等变(Equivariant)与不变(Invariant),附向量神经元实例
  • 组织架构调整为何频频收效不佳?避开重组常见误区
  • League Akari:英雄联盟玩家的智能助手,告别繁琐操作提升游戏体验
  • 2026年济南合同纠纷律师怎么挑?5个关键标准防踩雷 - 本地品牌推荐
  • 时间戳的学习,参照案例学习,一目了然
  • Git冲突实战:模拟多人协作修改同一行代码,并教你用Beyond Compare做三方合并
  • Python 高手编程系列八十四:测试环境与依赖兼容性
  • 从引脚到PCB:用UC3843设计一个12V/2A开关电源的保姆级实战教程
  • 2026年当下,重庆家长如何联系正规的中考体育培训机构? - 品牌鉴赏官2026
  • 说到常州ECO棉床垫,我踩过的坑你们别踩 - 深圳市民HLL
  • 保姆级教程:用TransCAD 6.0搞定公交线路动态分段与站点定位(附实验数据)
  • 保姆级教程:用Deeplabcut从零标注小鼠行为视频(附完整配置文件修改指南)
  • LLM驱动的人力资源能力建模技术演进与实践
  • 百度网盘提取码智能获取:如何用3秒解决传统搜索的5分钟难题?
  • 2026年青岛发电机出租公司哪家可靠?实测6家服务商表现,附避坑指南 - 优质品牌商家
  • 用FreeRTOS和裸机代码两种方式理解STM32平衡小车PID控制逻辑
  • 2026年高杆桂花苗木基地评价解析:从品种到工程应用的多维观察 - 优质品牌商家
  • 从‘为什么拒贷我’到‘AI医生怎么看片’:可解释性AI(XAI)如何重塑我们与算法的信任关系
  • 电赛备赛笔记:用STM32驱动AD9959信号发生器模块,从接线到出波保姆级教程
  • 自适应系统中的运行时伦理挑战与解决方案
  • 2026年近期,选择诚信的平板除雾器品牌为何成为企业的关键决策? - 品牌鉴赏官2026
  • shell作业
  • 保姆级教程:从零集成华为ScanKit到你的Android项目(含权限、依赖、回调全流程)
  • Win11 专属部署教程,OpenClaw 智能体稳定运行方案【包含安装包】