本文系统讲解 RAG 知识库的架构设计、五大扩展实现及实战接入方法。
一、为什么需要 RAG?
大语言模型(LLM)虽然能力强大,但存在两个核心短板:知识截止(训练数据有截止日期)和幻觉(可能编造不存在的事实)。RAG(Retrieval-Augmented Generation,检索增强生成)通过在推理前检索外部知识库中的相关文档片段,将其作为上下文注入 Prompt,从而让模型的输出更准确、更可控、更具时效性。
在 AgentScope Java 中,RAG 能力通过 io.agentscope.core.rag.Knowledge 接口统一抽象。Agent 在推理时通过该接口检索文档片段,再交给模型用于生成。agentscope-extensions-* 仓库下提供了 5 种开箱即用的实现,覆盖从自建向量库到主流第三方 RAG 平台的全部场景。
二、架构设计:检索与管控分离
2.1 核心设计原则
AgentScope 的 RAG 架构遵循一个关键原则:除 Simple 外,所有第三方集成仅负责检索(Retrieve),文档导入/更新走对应平台的控制台或服务端 API。
这种"管控分离"的设计带来三大好处:
| 好处 | 说明 |
|---|---|
| 职责单一 Agent 侧只关心"查什么、怎么查",不关心"数据怎么入库" | |
| 状态一致 避免双侧索引状态不一致的问题 | |
| 无缝替换 多个 Knowledge 实现在使用侧完全可替换,切换引擎零改动 |
2.2 统一接入方式
无论选择哪种 Knowledge 实现,接入 Agent 的方式都是同一套代码:
ReActAgentagent=ReActAgent.builder().name("Assistant").model(model).knowledge(knowledge)// 任选一种 Knowledge 实现.ragMode(RAGMode.AGENTIC)// 或 STATIC、NONE.build();也可以将 Knowledge 包装为工具,供 Agent 自主选择是否检索:
KnowledgeRetrievalToolstools=newKnowledgeRetrievalTools(knowledge);Toolkittoolkit=newToolkit();toolkit.registerObject(tools);三、五大扩展详解
3.1 Simple Knowledge —— 全链路自建
Maven 坐标:
<dependency><groupId>io.agentscope</groupId><artifactId>agentscope-extensions-rag-simple</artifactId><version>${agentscope.version}</version></dependency>适用场景: 你愿意自己跑 embedding + 向量库,不想接入第三方 RAG 平台,需要完全掌控数据链路。
完整示例:
importio.agentscope.core.embedding.dashscope.DashScopeTextEmbedding;importio.agentscope.core.rag.knowledge.SimpleKnowledge;importio.agentscope.core.rag.store.InMemoryStore;importio.agentscope.core.rag.model.RetrieveConfig;// 1) Embedding 模型EmbeddingModelembeddings=DashScopeTextEmbedding.builder().apiKey(System.getenv("DASHSCOPE_API_KEY")).modelName("text-embedding-v3").dimensions(1024).build();// 2) 向量库(这里用进程内的实现)VDBStoreBasestore=InMemoryStore.builder().dimensions(1024).build();// 3) 组装 KnowledgeSimpleKnowledgeknowledge=SimpleKnowledge.builder().embeddingModel(embeddings).embeddingStore(store).build();// 4) 写入文档List<Document>docs=newTikaReader().read(input).block();knowledge.addDocuments(docs).block();// 5) 检索List<Document>hits=knowledge.retrieve("什么是 AgentScope?",RetrieveConfig.builder().limit(5).scoreThreshold(0.5).build()).block();3.1.1 内置文档读取器
io.agentscope.core.rag.reader 包提供了一组常见格式的 Reader,全部产出 List:
| Reader | 输入 |
|---|---|
| TextReader | 纯文本 |
| PDFReader | PDF(基于 PDFBox) |
| WordReader | Word 文档 |
| ImageReader | 图片,配合多模态 embedding 使用 |
| TikaReader | Apache Tika 通用解析(兜底) |
| ExternalApiReader | 调外部 API 解析(OCR / 自定义流水线) |
读取出来的 Document 已经带有元数据,配合 TextChunker 与 SplitStrategy 做分块。
3.1.2 内置 Embedding 提供方
| 类 | 服务 | 模式 |
|---|---|---|
| DashScopeTextEmbedding | 阿里云百炼 DashScope | 文本 |
| DashScopeMultiModalEmbedding | 阿里云百炼 DashScope | 多模态(文本/图像) |
| OpenAITextEmbedding | OpenAI 兼容接口 | 文本 |
| OllamaTextEmbedding | Ollama 本地 | 文本 |
也可以实现 EmbeddingModel 接口自行扩展。
3.1.3 内置向量库适配
| 实现 | 部署 |
|---|---|
| InMemoryStore | 进程内(开发/测试用) |
| PgVectorStore | PostgreSQL + pgvector |
| MilvusStore | Milvus |
| QdrantStore | Qdrant |
| ElasticsearchStore | Elasticsearch(dense_vector) |
切换向量库只需要换一个 VDBStoreBase 实现,传给 SimpleKnowledge.builder().embeddingStore(…)。
3.1.4 检索参数
RetrieveConfig 控制检索行为:
| 字段 | 说明 |
|---|---|
| limit | TopK,返回的最大文档数 |
| scoreThreshold | 最低分数阈值(0~1) |
| metadata | 按文档 metadata 做过滤 |
3.2 Bailian Knowledge —— 阿里云百炼托管
Maven 坐标:
<dependency><groupId>io.agentscope</groupId><artifactId>agentscope-extensions-rag-bailian</artifactId><version>${agentscope.version}</version></dependency>适用场景:
- 文档已经在百炼控制台上传/解析完成
- 想要企业级特性:rerank、过滤、结构化/非结构化/图片三类知识库
- 不想自维护向量库
完整示例:
importio.agentscope.core.rag.integration.bailian.BailianConfig;importio.agentscope.core.rag.integration.bailian.BailianKnowledge;importio.agentscope.core.rag.model.RetrieveConfig;BailianConfigconfig=BailianConfig.builder().accessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID")).accessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")).workspaceId("llm-xxxxxx").indexId("kb-xxxxxx").build();BailianKnowledgeknowledge=BailianKnowledge.builder().config(config).build();List<Document>hits=knowledge.retrieve("如何申请发票?",RetrieveConfig.builder().limit(5).scoreThreshold(0.5).build()).block();Rerank / Rewrite 配置
百炼支持在原始召回之上做重排和 Query 改写,进一步提升相关性:
BailianConfigconfig=BailianConfig.builder().accessKeyId(ak).accessKeySecret(sk).workspaceId("llm-xxx").indexId("kb-xxx").rerankConfig(RerankConfig.builder().enable(true).topN(5).build()).rewriteConfig(RewriteConfig.builder().enable(true).build()).build();⚠️ 启用后延迟和费用会上升,按需打开。
配置参数一览
| 配置 | 说明 |
|---|---|
| accessKeyId / accessKeySecret | 阿里云访问凭证(必填) |
| workspaceId | 百炼业务空间 ID(必填) |
| indexId | 知识库索引 ID(必填) |
| rerankConfig r | erank 开关与参数 |
| rewriteConfig | query rewrite 开关与参数 |
📌 注意: BailianKnowledge.addDocuments(…) 不可用——文档管理请通过百炼控制台或百炼平台 SDK 完成。
3.3 Dify Knowledge —— 复用 Dify 数据集
Maven 坐标:
<dependency><groupId>io.agentscope</groupId><artifactId>agentscope-extensions-rag-dify</artifactId><version>${agentscope.version}</version></dependency>适用场景:
- 团队已经在 Dify 上做内容运营和文档管理
- 想直接复用 Dify 的多种检索模式(关键词 / 语义 / 混合 / 全文)
完整示例:
importio.agentscope.core.rag.integration.dify.DifyKnowledge;importio.agentscope.core.rag.integration.dify.DifyRAGConfig;importio.agentscope.core.rag.integration.dify.RetrievalMode;importio.agentscope.core.rag.model.RetrieveConfig;DifyRAGConfigconfig=DifyRAGConfig.builder().apiKey(System.getenv("DIFY_RAG_API_KEY")).datasetId("your-dataset-id").retrievalMode(RetrievalMode.HYBRID_SEARCH).enableRerank(true).build();DifyKnowledgeknowledge=DifyKnowledge.builder().config(config).build();List<Document>hits=knowledge.retrieve("如何续费会员?",RetrieveConfig.builder().limit(5).scoreThreshold(0.5).build()).block();四种检索模式
RetrievalMode 决定 Dify 在数据集上的检索方式:
| 枚举 | 说明 |
|---|---|
| KEYWORD_SEARCH | 仅关键词检索 |
| SEMANTIC_SEARCH | 仅向量语义检索 |
| HYBRID_SEARCH | 关键词 + 向量混合(推荐) |
| FULL_TEXT_SEARCH | 全文检索 |
自托管 Dify
如果你部署了自己的 Dify,把 baseUrl 指过去:
DifyRAGConfigconfig=DifyRAGConfig.builder().apiKey("dataset-xxx").baseUrl("https://dify.mycompany.com").datasetId("ds-xxxx").retrievalMode(RetrievalMode.HYBRID_SEARCH).build();Metadata 过滤
通过 MetadataFilter 可以按 Dify 上配置的元数据字段过滤:
DifyRAGConfigconfig=DifyRAGConfig.builder().apiKey(apiKey).datasetId(datasetId).retrievalMode(RetrievalMode.HYBRID_SEARCH).metadataFilter(MetadataFilter.builder().conditions(List.of(MetadataFilterCondition.builder().name("category").comparisonOperator("=").value(List.of("faq")).build())).logicalOperator("and").build()).build();关键参数
| 字段 | 说明 |
|---|---|
| apiKey | Dify 数据集 API Key(必填) |
| datasetId | 数据集 ID(必填) |
| baseUrl | 默认 https://api.dify.ai/v1,自托管时改为你的地址 |
| retrievalMode | 见上表 |
| enableRerank | 是否启用 rerank |
| metadataFilter | 元数据过滤条件 |
3.4 HayStack Knowledge —— 自托管检索流水线
Maven 坐标:
<dependency><groupId>io.agentscope</groupId><artifactId>agentscope-extensions-rag-haystack</artifactId><version>${agentscope.version}</version></dependency>适用场景:
- 已经在 HayStack 上落地 RAG(包括索引流水线、ChromaDB、Reranker 等)
- 想要直接复用 HayStack 的端到端检索能力
完整示例:
importio.agentscope.core.rag.integration.haystack.HayStackConfig;importio.agentscope.core.rag.integration.haystack.HayStackKnowledge;importio.agentscope.core.rag.model.RetrieveConfig;HayStackConfigconfig=HayStackConfig.builder().baseUrl("http://localhost:8080")// 你的 HayStack 服务.topK(10).build();HayStackKnowledgeknowledge=HayStackKnowledge.builder().config(config).build();List<Document>hits=knowledge.retrieve("What is AI?",RetrieveConfig.builder().limit(5).build()).block();文档管理说明
addDocuments(…) 抛 UnsupportedOperationException。要新增/更新文档,请:
- 准备好原始数据放入 HayStack 流水线的 source 目录
- 触发/重新执行 HayStack 的索引流水线
- 索引完成后,本插件即可检索到新文档
这种"管控分离"避免了双侧索引状态不一致。
关键参数
| 字段 | 说明 |
|---|---|
| baseUrl | HayStack 服务地址(必填) |
| topK | 默认返回的最大条数 |
| filterPolicy | 过滤策略(见 FilterPolicy) |
HayStackConfig 还提供超时、自定义 header、API Key 等扩展项,按 HayStack 部署侧的鉴权方案配置即可。
3.5 RAGFlow Knowledge —— 复杂文档解析利器
Maven 坐标:
<dependency><groupId>io.agentscope</groupId><artifactId>agentscope-extensions-rag-ragflow</artifactId><version>${agentscope.version}</version></dependency>适用场景:
- 知识库以扫描件、复杂排版 PDF、含图片表格为主
- 希望使用 RAGFlow 的 chunk 切分策略与重排能力
- 需要 OCR、知识图谱增强
完整示例:
importio.agentscope.core.rag.integration.ragflow.RAGFlowConfig;importio.agentscope.core.rag.integration.ragflow.RAGFlowKnowledge;importio.agentscope.core.rag.model.RetrieveConfig;RAGFlowConfigconfig=RAGFlowConfig.builder().apiKey("ragflow-xxxxxxxx").baseUrl("http://localhost:9380").knowledgeBaseId("kb-xxxxx").topK(10).similarityThreshold(0.5).enableRerank(true).build();RAGFlowKnowledgeknowledge=RAGFlowKnowledge.builder().config(config).build();List<Document>hits=knowledge.retrieve("AI 是什么?",RetrieveConfig.builder().limit(5).build()).block();工作机制
底层调用 RAGFlow 的 POST /api/v1/datasets/{dataset_id}/retrieve-chunks 接口:
- 向量相似度搜索 + 可配置 topK
- 服务端 similarityThreshold 过滤
- 通过 RAGFlowConfig 中的 metadata 字段做过滤
- 可选启用 RAGFlow 的 rerank
⚠️ 注意: 当前 RAGFlow 的 retrieve-chunks API 不支持把对话历史传过去做上下文感知检索;如果你需要这种能力,请自己在 query 拼接前置指令。
关键参数
| 字段 | 说明 |
|---|---|
| apiKey | RAGFlow API Key(必填) |
| baseUrl | RAGFlow 服务地址(必填) |
| knowledgeBaseId | 数据集/知识库 ID(必填) |
| topK | 服务端 TopK |
| similarityThreshold | 服务端最低相似度阈值 |
| enableRerank | 是否启用 rerank |
四、选型决策指南
面对五种实现,如何快速做出选择?
| 你的需求 | 推荐方案 | 理由 |
|---|---|---|
| 自己掌控全部链路(embedding + 向量库) | Simple | 全链路可控,支持 5 种向量库 |
| 阿里云生态、企业级托管 | Bailian | 免运维,支持 rerank/rewrite |
| 团队已经在用 Dify 编排 | Dify | 直接复用已有数据集,4 种检索模式 |
| 需要复杂 ETL(PDF 表格、图片 OCR、知识图谱) | RAGFlow | 文档解析能力最强 |
| 已基于 HayStack 落地 RAG 流水线 | HayStack | 无缝对接已有流水线 |
决策流程图
是否需要完全自建? ├── 是 → Simple └── 否 → 是否使用阿里云? ├── 是 → Bailian └── 否 → 是否已使用 Dify? ├── 是 → Dify └── 否 → 文档是否复杂(扫描件/表格/OCR)? ├── 是 → RAGFlow └── 否 → HayStack五、RAG Mode 详解
Agent 支持三种 RAG 模式,通过 .ragMode() 配置:
| 模式 | 行为 | 适用场景 |
|---|---|---|
| AGENTIC | Agent 自行决定何时检索、检索什么 | 开放式问答,Agent 自主判断 |
| STATIC | 每次对话前自动检索并注入上下文 | 固定领域专属助手 |
| NONE | 关闭 RAG | 纯 LLM 对话,不需要外部知识 |
六、最佳实践总结
6.1 开发阶段
- 使用 Simple + InMemoryStore 快速验证 RAG 效果
- 用 TikaReader 兜底解析各种格式文档
- 调整 scoreThreshold 和 limit 找到最佳召回参数
6.2 生产阶段
- 向量库切换为 PgVectorStore 或 MilvusStore
- 考虑接入百炼获得企业级 rerank 能力
- 复杂文档场景优先选择 RAGFlow
6.3 架构建议
- 单一数据源原则:文档管理统一在一个平台完成,避免双侧维护
- 渐进式演进:先用 Simple 验证效果,再根据需求迁移到托管平台
- 可观测性:结合 AgentScope 的 Observability 模块监控检索延迟和召回质量
七、总结
AgentScope Java 的 RAG 模块通过 Knowledge 接口实现了优雅的抽象层,让开发者可以:
- ✅ 用同一套代码接入 5 种不同的知识库后端
- ✅ 在自建与托管之间自由切换
- ✅ 通过 RAG Mode 灵活控制检索时机
- ✅ 将检索能力封装为工具,赋予 Agent 自主决策能力