从 0 到 1 实战 LangChain4j RAG:让大模型秒懂你的私域知识
从 0 到 1 实战 LangChain4j RAG:让大模型秒懂你的私域知识
·
关键词:RAG、LangChain4j、向量检索、Embedding、AI 应用
一、为什么要 RAG?一张图看懂痛点
场景 | 仅 LLM | LLM + RAG |
---|---|---|
时效性 | 停留在训练数据截止时间 | 实时检索最新文档 |
领域知识 | 通用语料,答非所问 | 私域文档精确回答 |
幻觉问题 | 一本正经地胡说 | 基于检索内容作答,可溯源 |
数据安全 | 上传云端训练 | 本地索引,完全隔离 |
一句话:RAG = 用搜索引擎给大模型开外挂。下面 30 分钟带你跑通“Easy RAG → Naive RAG → Advanced RAG”全链路。
二、Easy RAG:3 行代码跑通“Hello RAG”
2.1 引入依赖(Gradle 同理)
<!-- 一站式 Easy RAG,连 embedding 模型都打包好了 -->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-easy-rag</artifactId>
<version>1.1.0-beta7</version>
</dependency>
<!-- OpenAI 客户端 -->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-open-ai</artifactId>
<version>1.1.0-beta7</version>
</dependency>
2.2 3 行代码完成索引
// 1. 递归加载本地文档
List<Document> docs = FileSystemDocumentLoader.loadDocumentsRecursively("/data/docs");
// 2. 内存向量库(上线可换 PgVector/Milvus)
InMemoryEmbeddingStore<TextSegment> store = new InMemoryEmbeddingStore<>();
// 3. 一键入库:自动分段 + embedding + 存储
EmbeddingStoreIngestor.ingest(docs, store);
背后帮你做了啥?
- Apache Tika 解析 PDF/Word/Markdown
- bge-small-en-v1.5 量化模型本地跑,24 MB 不占内存
- 300 token/段,重叠 30 token,科学分块不踩坑
2.3 开聊!
interface Assistant {
String chat(String question);
}
Assistant assistant = AiServices.builder(Assistant.class)
.chatModel(OpenAiChatModel.withApiKey(System.getenv("OPENAI_API_KEY")))
.chatMemory(MessageWindowChatMemory.withMaxMessages(10))
.contentRetriever(EmbeddingStoreContentRetriever.from(store))
.build();
String answer = assistant.chat("新人入职流程怎么走?");
System.out.println(answer);
输出示例:
请参照《新员工入职指引_v3.2.pdf》第 4 页:
- HR 系统提交入职申请
- IT 分配账号
- 领取工牌 …
三、Naive RAG:把方向盘握在自己手里
Easy RAG 是自动挡,Naive RAG 给你手动挡的快乐。核心 4 件套:
组件 | 自由配置点 |
---|---|
DocumentLoader | 指定解析器、过滤文件 |
DocumentSplitter | 按段落/句子/正则切块 |
EmbeddingModel | 自选 OpenAI、BGE、Onnx 等 |
EmbeddingStore | 本地内存、PgVector、Chroma、Milvus |
示例代码片段:
DocumentSplitter splitter = DocumentSplitters.recursive(1000, 200, new OpenAiTokenCountEstimator("gpt-4o-mini"));
EmbeddingStoreIngestor ingestor = EmbeddingStoreIngestor.builder()
.documentLoader(FileSystemDocumentLoader.builder()
.documentParser(new ApachePdfBoxDocumentParser()) // PDF 专用
.pathMatcher(FileSystems.getDefault().getPathMatcher("glob:**.pdf"))
.build())
.documentSplitter(splitter)
.embeddingModel(new BgeSmallEnV15EmbeddingModel()) // 本地模型
.embeddingStore(PgVectorEmbeddingStore.builder()
.host("localhost")
.port(5432)
.database("rag")
.user("postgres")
.password("123456")
.dimension(384) // 与模型一致
.build())
.build();
ingestor.ingest(docs);
四、Advanced RAG:企业级检索的 6 大杀器
场景:百万级文档、多租户、权限隔离、Web + 内部知识联合检索
4.1 架构全景图
UserMessage → Query → QueryTransformer → QueryRouter → 多路Retriever → ContentAggregator → ContentInjector → LLM
4.2 代码级示例
// 1. 查询改写(压缩历史对话)
QueryTransformer compressor = new CompressingQueryTransformer(chatModel);
// 2. 路由:技术文档走向量库,实时信息走 Google
QueryRouter router = new LanguageModelQueryRouter(chatModel, Map.of(
"tech-docs", EmbeddingStoreContentRetriever.from(pgVectorStore),
"web", WebSearchContentRetriever.builder()
.webSearchEngine(GoogleCustomWebSearchEngine.builder()
.apiKey(System.getenv("GOOGLE_API_KEY"))
.csi(System.getenv("GOOGLE_CSI"))
.build())
.maxResults(3)
.build()
));
// 3. 重排序:Cohere 交叉编码器提升精度
ContentAggregator reRanker = new ReRankingContentAggregator(
CohereScoringModel.withApiKey(System.getenv("COHERE_API_KEY")));
// 4. 组装
RetrievalAugmentor augmentor = DefaultRetrievalAugmentor.builder()
.queryTransformer(compressor)
.queryRouter(router)
.contentAggregator(reRanker)
.executor(Executors.newFixedThreadPool(8)) // 并行提速
.build();
Assistant assistant = AiServices.builder(Assistant.class)
.chatModel(chatModel)
.retrievalAugmentor(augmentor)
.build();
4.3 元数据过滤(权限隔离)
ContentRetriever retriever = EmbeddingStoreContentRetriever.builder()
.embeddingStore(store)
.filter(metadataKey("userId").isEqualTo("12345")
.and(metadataKey("department").isIn(Set.of("IT", "HR"))))
.build();
五、与 Spring Boot 整合最佳实践
直接贴生产级片段,CV 即可用
@Configuration
public class RagConfig {
@Bean
public EmbeddingStore<TextSegment> embeddingStore() {
return PgVectorEmbeddingStore.builder()
.host(pgHost).port(pgPort).database(pgDb)
.user(pgUser).password(pgPwd)
.table("embeddings").dimension(384).build();
}
@Bean
public EmbeddingModel embeddingModel() {
return new BgeSmallEnV15EmbeddingModel();
}
@Bean
public RetrievalAugmentor retrievalAugmentor(EmbeddingStore<TextSegment> store,
EmbeddingModel model) {
ContentRetriever retriever = EmbeddingStoreContentRetriever.builder()
.embeddingStore(store)
.embeddingModel(model)
.dynamicFilter(query -> { // 根据登录用户动态过滤
String userId = SecurityContextHolder.getUserId();
return metadataKey("userId").isEqualTo(userId);
})
.build();
return DefaultRetrievalAugmentor.builder()
.queryTransformer(new CompressingQueryTransformer(chatModel()))
.queryRouter(new DefaultQueryRouter(retriever))
.build();
}
@Bean
public Assistant assistant(RetrievalAugmentor augmentor) {
return AiServices.builder(Assistant.class)
.chatModel(chatModel())
.retrievalAugmentor(augmentor)
.build();
}
}
六、避坑 & 性能调优清单
问题 | 症状 | 解法 |
---|---|---|
检索为空 | embedding 维度不一致 | 检查模型 & 库维度 |
回答截断 | 分块过大导致超 token | 降低 maxResults 或 chunk size |
速度慢 | 单线程 | 并行 Executor + 索引并发写 |
幻觉仍在 | 无上下文重叠 | 增加 overlap token 或 sentence-window |
权限泄露 | 元数据过滤缺失 | 务必加 Filter 并审计日志 |
七、一键源码 & 线上体验
- 完整 Demo:https://github.com/langchain4j/langchain4j-examples/tree/main/rag-examples
- 在线文档:https://docs.langchain4j.dev/tutorials/rag
如果本文帮到你,欢迎点赞 + 收藏!评论区聊聊你在落地 RAG 时遇到的奇葩需求,一起交流~
更多推荐
所有评论(0)