
DB-GPT 关键词检索 RAG 实战基于 Elasticsearch 全文检索构建知识库问答【免费下载链接】DB-GPTopen-source agentic AI data assistant for the next generation of AI Data products.项目地址: https://gitcode.com/GitHub_Trending/db/DB-GPT本篇技术文章以 DB-GPT 仓库中的关键词检索 RAG 用户手册keyword_rag_app_develop.md为核心完整讲解如何用传统全文检索Elasticsearch替代向量检索来构建 RAG 知识库从安装依赖、配置连接、创建全文索引到把文档加载入库并按关键词召回相关片段最后在 Web 界面完成基于关键词检索的知识问答。读完后你将掌握一套可复制的“关键词 RAG”落地方案并能对照仓库源码理解其 BM25 索引、分块持久化与检索器装配的底层实现。一、为什么选择关键词检索向量检索的局限性DB-GPT 的 RAG 框架中向量检索Vector Retrieve虽然优势明显但技术层面存在一些固有约束这也是 DB-GPT 提供关键词检索 RAG 路线的原因。原文档归纳了三点计算开销大Computationally Intensive为整个文档语料库生成向量、再基于向量相似度做查询比关键词索引与匹配需要多得多的算力。若系统未做针对性优化延迟会成为实际问题。依赖海量训练数据Requires Massive Training DataBERT 这类模型的语义关联能力依赖于在大规模、多样化数据集上长期训练。对专业领域语料而言这样的训练数据未必可得会限制向量质量。对精确关键词查询效果有限Less Effective for Precise Keyword Queries当查询本身包含明确、精确的关键词和意图时向量检索收益很小。例如搜索 “apple fruit” 往往不如直接搜 “apple”因为向量关注的是整体语义而非关键词本身。用全文检索实现 RAG在一定程度上可以缓解向量数据库检索带来的不确定性与可解释性问题命中的是真实存在的词项与文档片段检索结果可追溯、可解释。二、选型指南什么时候用向量检索什么时候用关键词检索原文档给出了两者的适用场景对照核心原则是向量检索用于探索exploration关键词检索用于精确precision。适合向量检索的场景早期研究阶段查询意图模糊或宽泛需要理解概念与主题而不是匹配关键词信息需求松散的主题探索用户查询更偏向对话式表达。向量检索的语义能力在这些场景下表现突出即使关键词有限或对主题了解不深也能把用户引向正确方向。适合关键词检索的场景目标非常具体且已经了解该主题研究聚焦、目标明确查询中包含品牌名等独特专有名词更看重快速出结果而非穷尽式的相关性覆盖。对精确或时效性强的查询关键词检索能高效命中确切词项向量检索反而可能因为不必要的语义扩展而“跑偏”。检索方式应当与用户的意图和精确度需求对齐——两者都可用时用户可以获得两者的最佳效果。三、安装依赖与全文检索引擎准备3.1 安装 dbgpt 库首先安装带 RAG 依赖组的dbgpt库pip install dbgpt[rag]0.5.8该依赖组会安装dbgpt核心包与dbgpt-ext扩展包其中dbgpt_ext.rag、dbgpt_ext.storage.full_text等模块是本文所有代码示例的入口。3.2 准备 ElasticsearchElasticsearch是 Elastic Stack 核心中的分布式搜索与分析引擎索引、搜索与分析都在这里完成Logstash 与 Beats 负责数据收集、聚合与增强Kibana 负责交互式探索与可视化更完整的介绍可参考 Elasticsearch 官方文档。本文只关心 Elasticsearch 本身按官方安装文档部署一个可用实例即可注意官方文档链接请以 Elasticsearch 官网为准本文不再列出。3.3 配置全文检索引擎连接变量在.env文件中设置以下变量让 DB-GPT 知道如何连接全文检索引擎存储ELASTICSEARCH_URLlocalhost ELASTICSEARCH_PORT9200 ELASTICSEARCH_USERNAMEelastic ELASTICSEARCH_PASSWORDdbgpt从源码可以确认这四个环境变量的确被全文存储实现读取elasticsearch.py 中ElasticsearchDocumentStore的构造逻辑会按“显式配置优先、环境变量兜底”的方式取连接信息——uri回落到ELASTICSEARCH_URL默认localhost、port回落到ELASTICSEARCH_PORT默认9200、用户名回落到ELASTICSEARCH_USER默认elastic、密码回落到ELASTICSEARCH_PASSWORD默认dbgpt。也就是说即使不显式传连接参数只要.env配置正确ElasticDocumentStore也能自动连上。若账号密码缺失则构造不带basic_auth的匿名客户端。四、源码实现ElasticDocumentStore 与 BM25 索引当使用Elasticsearch全文引擎作为底层知识存储平台时需要构建文档倒排索引以支持文档的归档与检索。elasticsearch.py 中的ElasticDocumentStore封装了这件事几个关键实现细节值得理解默认索引名与中文处理name参数如keyword_rag_test经小写化后作为 ES 索引名若名字包含中文string_utils.contains_chinese判断会自动转换为dbgpt_ UTF-8 十六进制串避免索引名出现非法字符。自定义 BM25 相似度索引 settings 中定义了名为custom_bm25的 BM25 相似度两个可调参数及其默认值k1默认2.0控制词频的非线性饱和term frequency saturationb默认0.75控制文档长度归一化对 tf 值的影响程度。 注释中引用了 Elasticsearch BM25 相似度的说明基于 TF/IDF、内置词频归一化对短字段表现更好。字段映射mappingscontent字段为text类型并应用custom_bm25相似度metadata字段为object类型且dynamic: True注释明确其目的是让 metadata 字段保持可查询以支持元数据过滤。自动建索引构造函数会检查目标索引是否存在不存在则按上述 settings 与 mappings 自动创建并在内部使用ThreadPoolExecutor将阻塞 IO 转为可并发的加载。全文检索能力声明重写的is_support_full_text_search()返回True使上层检索器可以走full_text_search路径而非向量相似度路径。此外同目录下的 opensearch.py 提供了 OpenSearch 版本的全文存储接口形态类似可按部署环境选择。五、创建 Elasticsearch 连接可运行的完整代码原始手册给出的连接创建代码如下注意其引用的ElasticDocumentConfig为文档写作时的类名当前仓库示例文件已统一使用ElasticsearchStoreConfig建议以仓库示例为准from dbgpt_ext.storage.full_text.elasticsearch import ElasticDocumentStore def _create_es_connector(): Create es connector. config ElasticsearchStoreConfig( urilocalhost, port9200, userelastic, passworddbgpt, ) return ElasticDocumentStore(config, namekeyword_rag_test)上面代码与仓库中的真实示例 keyword_rag_example.py 完全一致ElasticsearchStoreConfig携带连接信息ElasticDocumentStore的namekeyword_rag_test决定 ES 索引名。该示例文件顶部还注明了前置条件pre-requirements: set your Elasticsearch environment. Examples: ..code-block:: shell python examples/rag/keyword_rag_example.py即运行前提是先准备好 Elasticsearch 环境然后直接执行python examples/rag/keyword_rag_example.py即可。六、从文档加载到关键词检索完整流程解析关键词检索Keyword Retrieve是一种从大量文档中召回相关信息的高效方式。以下示例演示如何把文档知识加载并持久化到全文存储随后通过关键词搜索召回与问题最相关的知识。完整代码见 keyword_rag_example.pyimport os from dbgpt.configs.model_config import ROOT_PATH from dbgpt_ext.rag import ChunkParameters from dbgpt_ext.rag.assembler import EmbeddingAssembler from dbgpt_ext.rag.knowledge import KnowledgeFactory async def main(): file_path os.path.join(ROOT_PATH, docs/docs/awel/awel.md) knowledge KnowledgeFactory.from_file_path(file_path) keyword_store _create_es_connector() chunk_parameters ChunkParameters(chunk_strategyCHUNK_BY_SIZE) # get embedding assembler assembler EmbeddingAssembler.load_from_knowledge( knowledgeknowledge, chunk_parameterschunk_parameters, index_storekeyword_store, ) assembler.persist() # get embeddings retriever retriever assembler.as_retriever(3) chunks await retriever.aretrieve_with_scores(what is awel talk about, 0.3) print(fkeyword rag example results:{chunks})逐步拆解这条调用链并对照源码说明每个环节的作用6.1 加载文档KnowledgeFactory.from_file_pathKnowledgeFactory.from_file_path(file_path)从文件路径构建知识源。示例取仓库自带的 awel.md 作为演示文档ROOT_PATH来自 model_config保证相对仓库根目录定位。6.2 分块策略ChunkParametersChunkParameters(chunk_strategyCHUNK_BY_SIZE)声明按大小切块。分块参数定义在 chunk_manager.py实际的分块、去重与元数据附加由BaseAssembler初始化时完成assembler 持有knowledge、index_store与chunk_parameters并在构建时把切分后的chunks准备好供持久化。6.3 装配与持久化EmbeddingAssembler persistEmbeddingAssembler.load_from_knowledge(...)是 embedding.py 中的装配器。虽然名字带 “Embedding”但它是 RAG 的通用装配入口index_store传什么就装配到什么存储后端——本例传入的是ElasticDocumentStore全文存储因此整条链路走的是关键词路径。assembler.persist()的实现非常直白def persist(self, **kwargs) - List[str]: max_chunks_once_load kwargs.get(max_chunks_once_load) max_threads kwargs.get(max_threads) return self._index_store.load_document_with_limit( self._chunks, max_chunks_once_load, max_threads )即把切好的 chunks 批量写入index_store并支持max_chunks_once_load单次批量条数与max_threads并发线程数两个可选限流参数还有对应的异步版本apersist()可额外传file_id。对全文存储而言这一步就是在 Elasticsearch 中建立倒排索引文档。6.4 创建检索器as_retriever(top_k)assembler.as_retriever(3)创建一个top_k3的检索器。源码中该方法的签名为as_retriever(self, top_k: int 4, **kwargs) - BaseRetriever默认top_k为 4示例里显式指定为 3。检索器拿到的是同一个index_store检索时由存储后端的类型决定走向量相似度还是全文匹配。6.5 关键词召回aretrieve_with_scoreschunks await retriever.aretrieve_with_scores(what is awel talk about, 0.3)aretrieve_with_scores以问题为查询串返回带分数的 top-k 片段列表第二个参数0.3是相似度/得分阈值低于该分数的结果会被过滤。对 Elasticsearch 后端底层最终落到 elasticsearch.py 中基于 BM25 的搜索实现命中依据是词项匹配与 BM25 打分而非向量距离——这正是关键词 RAG “可解释、可精确命中”的底层来源。七、Web 页面基于关键词 RAG 的知识库问答除代码方式外DB-GPT 的 Web 界面也支持关键词 RAG 问答操作步骤创建 Full Text 类型知识库在知识库管理界面新建知识库时选择Full Text全文检索类型——这一步决定了底层使用全文检索存储而非向量存储上传知识文档上传后等待系统完成切片slicing与入库切片完成即代表倒排索引已就绪发起问答选择该知识库开始对话系统按关键词检索召回片段并生成回答。界面效果见文章开头两张截图第一张展示用Full Text类型创建知识库并上传文档第二张展示基于关键词 RAG 的问答过程。八、延伸阅读轻量替代与相关原理本地 BM25 检索器若不想部署 Elasticsearch仓库在 bm25.py 提供了BM25Retriever及配套的本地 BM25 assemblerbm25.py assembler同样提供as_retriever(top_k4)接口对应示例为 bm25_retriever_example.py适合单机、小语料场景快速体验关键词检索 RAG。知识库索引原理kb_index_principles.md 讲解一份文档如何变成可检索内容结构化索引 / 知识图谱含代码图谱/ 向量索引 / 关键词索引四类索引。Agentic RAG 对话原理agentic_rag_principles.md 讲解一个问题如何经由 agentic 检索循环变成带引用的回答。RAG 模块参考rag.md 提供 RAG 模块的完整 API 参考。小结关键词检索 RAG 在 DB-GPT 中的落地路径是——ElasticDocumentStore负责 BM25 倒排索引的创建与维护EmbeddingAssembler负责文档分块与持久化persist以及检索器装配as_retriever检索阶段由aretrieve_with_scores按关键词与得分阈值召回片段。对于专有名词多、查询意图精确、追求低延迟与可解释性的场景这条不依赖向量模型与向量库的路线是一个务实的选择。【免费下载链接】DB-GPTopen-source agentic AI data assistant for the next generation of AI Data products.项目地址: https://gitcode.com/GitHub_Trending/db/DB-GPT创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考