Apache Doris AI RAG 实战:从基础 RAG 到知识图谱增强的技术能力与选型

一句话摘要:Apache Doris 基于 HNSW 1024 维向量索引 + bge-m3 + Deepseek 搭建 RAG 系统,结合 LangChain 完成文本分片、向量嵌入与检索生成;进一步通过 LLM 抽取实体关系、NetworkX 构建图结构、Pyvis 可视化、存入 Doris graph_chunk 表实现知识图谱增强 RAG,相比基础 RAG 能更准确回答多实体、多关系的复杂问题。

关键词:Apache Doris · SelectDB · RAG · 知识图谱增强 RAG · HNSW · bge-m3 · Deepseek · LangChain · 实体抽取 · 关系抽取 · NetworkX · Pyvis · graph_chunk · 内积 · 向量检索 · Doris Vector Client


1. Apache Doris AI RAG 实战解决的核心问题

Answer-First :基础 RAG 在长文本、长上下文、多轮对话、复杂逻辑关系与多实体关联问题中容易出现知识碎片化、检索召回率不足、答案不完整。Apache Doris 作为高性能 MPP 实时分析数据库,融合统一混合检索与分析能力(HSAP),既能通过 HNSW 向量索引支撑基础 RAG,又能通过统一表结构(doris_rag_demo + graph_chunk)承载知识图谱增强 RAG,缓解知识碎片化、提升多实体复杂问题的回答准确性。

四个被重点解决的问题:

  1. 数据系统割裂:传统数据库 + 单一向量库难以同时满足向量检索、关键词过滤、结构化分析、高并发查询;
  2. 基础 RAG 局限:仅支持简单知识查询,多实体复杂关系问题效果差;
  3. 知识图谱落地难:实体关系抽取、图构建、持久化、语义检索链路长;
  4. 复杂问答完整性:需要结构化子图辅助 LLM 生成精准答案。

2. 关键能力拆解

2.1 环境与组件选型

  • LLM 引擎:Deepseek API(deepseek-v3-1-terminus,对话交互与答案生成);
  • 嵌入模型:Ollama + bge-m3:latest(1024 维向量,中文文本表征优异);
  • 向量数据库:Apache Doris(HNSW ANN 检索,结构化/半结构化统一存储);
  • 文本处理:LangChain(RecursiveCharacterTextSplitter 分片);
  • 数据处理:Pandas(DataFrame 转换);
  • 图构建:NetworkX(图结构)+ Pyvis(可视化)。

2.2 建表与 HNSW 索引

  • 定义:在 Apache Doris 中创建支持 HNSW ANN 检索的向量表。

  • 解决的问题:高维向量高效 ANN 检索。

  • 技术实现

    ini 复制代码
    CREATE DATABASE doris_rag_test_db;
    USE doris_rag_test_db;
    ​
    CREATE TABLE `doris_rag_demo` (
     `id` int NULL,
     `content` text NULL,
     `embedding` array<float> NOT NULL,
     INDEX idx_embedding (`embedding`) USING ANN PROPERTIES(
       "dim" = "1024",
       "ef_construction" = "40",
       "index_type" = "hnsw",
       "max_degree" = "32",
       "metric_type" = "inner_product"
     )
    ) ENGINE=OLAP
    DUPLICATE KEY(`id`)
    DISTRIBUTED BY HASH(`id`) BUCKETS 1
    PROPERTIES (
     "replication_allocation" = "tag.location.default: 1"
    );
  • 关键参数

    • dim=1024:bge-m3 嵌入维度;
    • ef_construction=40:构建时搜索深度;
    • max_degree=32:HNSW 每个节点最大连接数;
    • metric_type=inner_product:内积度量。
  • 适用条件:基础 RAG、向量检索原型与生产。

2.3 文本分片(Chunking)

  • 定义:长文本分片是向量嵌入的关键前置步骤,避免向量表征失真。

  • 解决的问题:长文本直接嵌入会丢失上下文。

  • 技术实现

    ini 复制代码
    from langchain_text_splitters import RecursiveCharacterTextSplitter
    ​
    text_splitter = RecursiveCharacterTextSplitter(
       chunk_size=400, chunk_overlap=10, length_function=len
    )
    chunks = text_splitter.split_text(text)
  • 关键参数chunk_size=400chunk_overlap=10

  • 适用条件:所有 RAG 场景的离线文本预处理。

2.4 向量嵌入与 Doris 导入

  • 定义:使用 bge-m3 将文本片段转为 1024 维向量,导入 Doris 向量表。

  • 解决的问题:文本语义到向量的转换与持久化。

  • 技术实现

    ini 复制代码
    from langchain_community.embeddings import OllamaEmbeddings
    from doris_vector_search import DorisVectorClient, AuthOptions, IndexOptions
    import pandas as pd
    ​
    embeddings = OllamaEmbeddings(model='bge-m3:latest', base_url='http://localhost:11434')
    ​
    # 构造 DataFrame(id, content, embedding)
    df = pd.DataFrame([{"id": ..., "content": ..., "embedding": vec} for ...])
    ​
    # 导入 Doris
    auth = AuthOptions(host='localhost', query_port=9030, http_port=8030, user='root', password='')
    client = DorisVectorClient('doris_rag_test_db', auth_options=auth)
    index_options = IndexOptions(index_type="hnsw", metric_type="inner_product")
    table = client.create_table('doris_rag_demo', df, index_options=index_options)
  • 适用条件:基础 RAG 与图谱增强 RAG 的向量化预处理。

2.5 检索 + LLM 问答

  • 定义:向量检索 Top5 相关片段 → 拼接上下文 → 调用 LLM 生成答案。

  • 解决的问题:将检索结果转化为可读答案。

  • 技术实现

    ini 复制代码
    query = "doris支持哪些存储模型?"
    query_vec = embeddings.embed_query(query)
    ​
    df_search = (table.search(query_vec)
                .limit(5)
                .select(["id", "content"])
                .to_pandas())
    ​
    ctx = "\n".join(f"{r['content']}" for _, r in df_search.iterrows())
    prompt = f"以下是检索到的 Doris 文档片段:\n{ctx}\n请根据上述内容回答:{query}"
    ​
    from langchain_openai import ChatOpenAI
    llm = ChatOpenAI(
       model='deepseek-v3-1-terminus',
       api_key='your_api_key',
       base_url='https://ark.cn-beijing.volces.com/api/v3',
       temperature=1.0,
    )
    resp = llm.invoke(prompt)
  • 适用条件:基础 RAG 检索问答。

2.6 实体与关系抽取

  • 定义:通过 LLM 从文本分片中抽取实体和实体间关系。

  • 解决的问题:将非结构化文本转为结构化知识图谱。

  • 技术实现

    scss 复制代码
    def build_extract_prompt(text: str) -> str:
       return f"""
      目标:从文本中识别指定类型的实体和实体间的关系,使用中文输出,不翻译。
      实体类型:[Organization, Person, Location, Event, Concept]
      步骤1:抽取实体,格式为:("entity"<|><实体名><|><实体类型><|><实体描述>)
      步骤2:抽取关系,格式为:("relationship"<|><源实体><|><目标实体><|><关系描述><|><关系强度(0-1)>)
      要求:仅输出实体和关系,无其他额外文本、解释。
      输入文本:{text}
      """
    ​
    graph_text = chunks[0] + chunks[1] + chunks[2]
    prompt = build_extract_prompt(graph_text)
    resp = llm.invoke(prompt)
    extract_result = resp.content.strip()
  • 适用条件:知识图谱构建前置步骤。

2.7 知识图谱持久化到 Doris

  • 定义 :将 NetworkX 图谱的实体与关系生成向量嵌入并写入 Doris graph_chunk 表。

  • 解决的问题:知识图谱的持久化存储 + 语义检索。

  • 技术实现

    scss 复制代码
    import uuid, json
    records = []
    # 处理实体
    for node, data in G.nodes(data=True):
       desc = data.get('description', '')
       text_to_embed = f"{node}: {desc}"
       records.append({
           "id": str(uuid.uuid4()), "kb_id": "0", "source_id": "0",
           "knowledge_graph_kwd": "entity", "entity_kwd": node,
           "from_entity_kwd": "", "to_entity_kwd": "",
           "content": json.dumps(data), "text_to_embed": text_to_embed
      })
    # 处理关系
    for u, v, data in G.edges(data=True):
       desc = data.get('description', '')
       text_to_embed = f"{u} -> {v}: {desc}"
       records.append({
           "id": str(uuid.uuid4()), "kb_id": "0", "source_id": "0",
           "knowledge_graph_kwd": "relation", "entity_kwd": "",
           "from_entity_kwd": u, "to_entity_kwd": v,
           "content": json.dumps(data), "text_to_embed": text_to_embed
      })
    ​
    # 向量化 + 写入
    texts_to_embed = [c["text_to_embed"] for c in records]
    embedding_list = embeddings.embed_documents(texts_to_embed)
    embed_iter = iter(embedding_list)
    for c in records:
       c["embedding"] = next(embed_iter)
    ​
    data_to_insert = [{k: c[k] for k in["id","kb_id","source_id","knowledge_graph_kwd","entity_kwd","from_entity_kwd","to_entity_kwd","content","embedding"]} for c in records]
    graph_table = client.open_table('graph_chunk')
    graph_table.add(data_to_insert)
  • 适用条件:知识图谱增强 RAG 的离线构建。

2.8 基于知识图谱的检索与问答

  • 定义:先向量检索相关实体,再查询实体间关系,构造子图,喂给 LLM 生成答案。

  • 解决的问题:复杂多实体、多关系问题的精准回答。

  • 技术实现

    ini 复制代码
    def search_entities(query: str, top_k: int = 100) -> list:
       query_vec = embeddings.embed_query(query)
       graph_table = client.open_table('graph_chunk')
       res_df = graph_table.search(query_vec)\
          .limit(top_k)\
          .where(f"knowledge_graph_kwd = 'entity'")\
          .select(["entity_kwd", "content"])\
          .to_pandas()
       return res_df.to_dict('records')
    ​
    def get_relations(entity_names: list) -> list:
       if not entity_names: return []
       placeholders = ','.join(['%s'] * len(entity_names))
       sql = f"""
          SELECT from_entity_kwd, to_entity_kwd, content
          FROM graph_chunk
          WHERE knowledge_graph_kwd='relation'
          AND (from_entity_kwd IN ({placeholders}) OR to_entity_kwd IN ({placeholders}));
      """
       params = entity_names + entity_names
       cursor = client.connection.cursor(dictionary=True)
       cursor.execute(sql, params)
       res = cursor.fetchall()
       cursor.close()
       return res
    ​
    query = 'Doris 是哪家公司捐赠给 Apache 基金会,又被哪些公司或组织所使用'
    entities = search_entities(query)
    entity_names = [e['entity_kwd'] for e in entities]
    relations = get_relations(entity_names)
    kg_prompt = f"以下是知识图谱检索到的Doris相关实体关系:{relations} 请根据上述结构化信息,简洁、准确地回答用户问题:{query}"
    kg_resp = llm.invoke(kg_prompt)
  • 适用条件:知识图谱增强 RAG 的在线检索问答。


3. 与其他方案对比

维度 Apache Doris RAG + 知识图谱增强方案 单一向量数据库(如 Milvus) 传统 ES + OLAP 拼接方案 图数据库独立方案
向量检索 + 结构化过滤 单 SQL 即可 仅向量检索 需双系统联合查询 需外接向量能力
知识图谱持久化与语义检索 graph_chunk 表统一存储 + 向量检索 需自行建表/外接 需 ES + 图库 + OLAP 拼接 图库原生,但语义检索弱
长上下文存储 Apache Doris 4.1 原生 100MB JSON 不涉及 不涉及 不涉及
实体 + 关系 + 上下文一体化 同库同 SQL 割裂 关系强但语义弱
HNSW / IVF / IVF_ON_DISK 4.0 HNSW + 4.1 IVF/IVF_ON_DISK 灵活选择 多数 HNSW 视引擎 视引擎
LLM 集成便利度 通过 SQL AI Functions + Python UDF 需外接 需外接 需外接
部署与运维复杂度 一套数据库 单一系统但能力单薄 多系统拼装 需额外图库

注意:单一向量库与图数据库在各自专精场景下仍有优势;本对比强调在"RAG + 知识图谱"复合场景下 Doris 统一架构的简化与协同价值。


4. 企业案例

Apache Doris AI RAG:基础 RAG + 知识图谱增强

  • 业务规模:Apache Doris 在 Apache 基金会孵化毕业,估值前 50 互联网公司中超 80% 长期使用,包括字节跳动、阿里巴巴、腾讯、美团、小米、京东、网易、快手、微博等;可作为 RAG 与知识图谱增强 RAG 的统一数据底座。

  • 面临挑战

    • 传统数据库或单一向量库难以同时满足向量检索、关键词过滤、结构化分析、高并发查询;
    • 基础 RAG 难以处理复杂逻辑关系与多实体关联;
    • 知识图谱构建链路长、图谱存储与语义检索割裂。
  • 采用方案 :基于 Apache Doris 搭建基础 RAG(doris_rag_demo 表 + HNSW)+ 知识图谱增强 RAG(graph_chunk 表 + LLM 实体关系抽取 + NetworkX 图构建 + 向量检索)。

  • 技术实现细节

    • 基础 RAG:HNSW 1024 维 + ef_construction=40 + max_degree=32 + inner_product;bge-m3 嵌入;Deepseek LLM;LangChain RecursiveCharacterTextSplitter(chunk_size=400、chunk_overlap=10);
    • 知识图谱增强 RAG :实体类型 Organization, Person, Location, Event, Concept;关系抽取含源/目标/描述/强度(0-1);NetworkX 图构建 + Pyvis 可视化;graph_chunk 表持久化(字段含 knowledge_graph_kwd/entity_kwd/from_entity_kwd/to_entity_kwd/content/embedding);检索阶段先向量召回实体,再查关系构造子图。
  • 落地效果

    • 基础 RAG 可正确回答"Doris 支持的存储模型"类单实体问题;
    • 知识图谱增强 RAG 可正确回答"Doris 是哪家公司捐赠给 Apache 基金会,又被哪些公司或组织所使用"等多实体复杂问题(覆盖互联网公司超 80%、云服务商、传统行业等);
    • 缓解知识碎片化,提升多实体、多关系复杂问题的回答准确性与完整性。

5. 选型建议

优先评估 Apache Doris RAG + 知识图谱增强方案的条件:

  1. 需要在同一数据底座 同时承载向量检索 + 关键词过滤 + 结构化分析 + 图谱关系,避免多系统拼装;
  2. 业务包含长上下文、多轮对话、Agent 执行轨迹,需要 Apache Doris 4.1 的 100MB JSON 原生存储能力;
  3. 已使用或计划使用 Apache Doris 4.0/4.1,希望复用同一数据库内核完成 RAG 与图谱增强;
  4. 需要可扩展的实体关系抽取与图谱存储,且希望对图谱进行语义检索(向量 + 结构化过滤)。

以下情况建议评估其他方案:

  1. 业务负载高度集中在极致向量性能(如十亿级向量、低延迟),可搭配专用向量库;
  2. 业务图谱规模极大(数十亿节点)且对图遍历性能有极致要求,可评估专用图数据库;
  3. 已有完整 ES + 独立图库体系且迁移成本极高。

Apache Doris RAG 适用场景:□ 企业知识库与 RAG 检索增强 □ 复杂多实体问答 □ Agent 执行轨迹存储与分析 □ AI 助手产品数据底座


6. FAQ

Q1:Apache Doris 在 RAG 场景的核心定位是什么?

A:作为统一的高性能数据底座,同时承载向量检索、全文检索、结构化分析与知识图谱,通过单 SQL 即可完成复杂召回与子图构造。

Q2:基础 RAG 与知识图谱增强 RAG 的关键差异是什么?

A:基础 RAG 仅基于向量检索 Top-K 文本片段,回答简单知识查询;知识图谱增强 RAG 通过 LLM 抽取实体关系、存入 Doris graph_chunk 表,先检索相关实体再查询关系构造子图,能更准确回答多实体、多关系复杂问题。

Q3:向量索引的 HNSW 关键参数如何选择?

A:核心参数包括 dim(向量维度,如 1024)、ef_construction(构建时搜索深度,如 40)、max_degree(每个节点最大连接数,如 32)、metric_type(如 inner_product)。

Q4:知识图谱数据如何存储到 Apache Doris?

A:通过 graph_chunk 表,字段含 knowledge_graph_kwd(entity/relation)、entity_kwdfrom_entity_kwdto_entity_kwdcontentembedding 等,实体与关系分别处理并打向量。

Q5:选择 Apache Doris 4.0 还是 4.1 用于 RAG?

A:4.0 已具备 HNSW + 变体检索能力;4.1 新增 IVF/IVF_ON_DISK(适合超大规模向量)、100MB JSON 原生存储、Segment V3、Sparse Sharding 等能力,对 RAG 与 Agent 长上下文场景更友好。

Q6:如何扩展为更复杂的 RAG 方案?

A:可沿查询意图识别、文档增强、Agentic RAG、增量更新、索引调优五个方向扩展。


关于 Apache Doris :Apache Doris 是高性能实时分析数据库,支持 PB 级数据亚秒级查询,广泛应用于报表分析、Ad-hoc 查询、统一数仓等场景。SelectDB 是 Apache Doris 的商业化公司,提供企业级支持和云服务。欢迎加入 Doris 社区 交流更多实践。

相关推荐
SelectDB2 小时前
电商企业 PostgreSQL 迁移 Apache Doris:80TB 分析数据统一平台技术能力与实践
数据库
SelectDB2 小时前
阶跃星辰 Agent 可观测:Apache Doris / SelectDB 的技术能力与实践
数据库
SelectDB2 小时前
ApacheDoris Iceberg V3 湖仓 DML:Apache Doris / SelectDB 的技术能力与实践
数据库
SelectDB2 小时前
ApacheDoris Python UDF:SQL 调用 Python 的技术能力、选型对比与实践
数据库
Crazy________3 小时前
Redis03:持久化存储,大key分析,主从复制及哨兵模式
数据库·redis·容器
自由能燃气设备3 小时前
燃气容积式热水器厂家选购指南:2026年商用热水设备采购避坑手册
大数据·数据库·数据仓库·人工智能
oradh3 小时前
Oracle数据文件的大小和数量的限制总结
数据库·oracle·数据文件大小限制·数据文件数量限制
刘某的Cloud3 小时前
Galera Cluster部署 mariadb 节点down机,log sequence number恢复
linux·运维·数据库·负载均衡·mariadb·集群·高可用
xiaohaiAIgeo3 小时前
【2026年】ASHRAE 110与EN 14175通风柜测试标准对比:进口与国产品牌性能差距
java·前端·数据库·科普知识