agentic_huge_data_base / wiki
页面 Graphiti · 4.3 检索与召回系统·DeepWiki 中文全文译文

4.3 · 检索与召回系统(Search and Retrieval System)

时序知识图谱与动态事实记忆 · 聚焦本章的模块关系、源码依据与实现要点。

项目Graphiti 章节4.3 状态全文译文 模块检索、召回与索引、图谱与关系、测试、发布与运维、模型调用与提供方适配
源码线索
  • examples/podcast/podcast_runner.py
  • graphiti_core/prompts/prompt_helpers.py
  • graphiti_core/search/search.py
  • graphiti_core/search/search_config.py
  • graphiti_core/search/search_config_recipes.py
  • graphiti_core/search/search_filters.py
  • graphiti_core/search/search_helpers.py
  • graphiti_core/search/search_utils.py
  • tests/test_graphiti_int.py
模块标签
  • 检索、召回与索引
  • 图谱与关系
  • 测试、发布与运维
  • 模型调用与提供方适配
  • 配置治理

章节正文

检索与召回系统

搜索与检索系统

相关源文件

以下文件为本 Wiki 页面的上下文来源:

  • examples/podcast/podcast_runner.py
  • graphiti_core/prompts/prompt_helpers.py
  • graphiti_core/search/search.py
  • graphiti_core/search/search_config.py
  • graphiti_core/search/search_config_recipes.py
  • graphiti_core/search/search_filters.py
  • graphiti_core/search/search_helpers.py
  • graphiti_core/search/search_utils.py
  • tests/test_graphiti_int.py

目的与范围

本文档介绍 Graphiti 的混合搜索与检索系统,该系统结合了多种搜索方法和重排序策略,能够高效查询时序知识图谱。系统会并发执行 BM25 全文搜索、向量相似度搜索和图遍历方法,然后使用倒数排名融合(RRF)和可选的重排序来融合结果。关于如何从 Graphiti 主客户端调用搜索功能,请参见 Graphiti 核心客户端。关于搜索返回的数据模型详情,请参见 数据模型与模式

高层架构

搜索系统实现了三阶段管线:(1)在不同范围(节点、边、片段、社区)内并发执行多种搜索方法;(2)使用 RRF 或 MMR 进行结果融合;(3)使用交叉编码器或基于图的指标进行可选的重排序。

搜索流程与代码实体映射

下图将逻辑搜索流程映射到代码库中的具体类和函数。

Graphiti · 搜索流程与代码实体映射 · 图 1
Graphiti · 搜索流程与代码实体映射 · 图 1

来源:graphiti_core/search/search.py:98-219, graphiti_core/search/search_utils.py:1-1070, graphiti_core/search/search_config.py:112-119

搜索入口点

主搜索函数是 search(),位于 graphiti_core/search/search.py:98-183。它接受一个查询字符串、可选的组 ID、一个 SearchConfigSearchFilters,以及用于中心搜索(center_node_uuid)和 BFS 起始节点(bfs_origin_node_uuids)的可选参数。

该函数通过 semaphore_gather() 协调并行搜索操作 graphiti_core/search/search.py:173-219

搜索范围函数用途
边搜索edge_search()查找匹配查询的关系 graphiti_core/search/search.py:222
节点搜索node_search()查找匹配查询的实体 graphiti_core/search/search.py:344
片段搜索episode_search()查找匹配查询的片段节点 graphiti_core/search/search.py:452
社区搜索community_search()查找匹配查询的社区集群 graphiti_core/search/search.py:511

如果任何搜索方法需要向量相似度(余弦相似度或 MMR),系统会自动使用配置的 embedder 生成查询嵌入向量 graphiti_core/search/search.py:120-152

来源:graphiti_core/search/search.py:98-219, graphiti_core/search/search_utils.py:1-1070

搜索方法

BM25 全文搜索

BM25 利用数据库原生的全文索引。系统通过 fulltext_query() 构建特定于提供商的查询 graphiti_core/search/search_utils.py:85-113

  • Neo4j:使用 Lucene 语法。需要通过 lucene_sanitize 进行消毒,以防止语法错误 graphiti_core/search/search_utils.py:106-111
  • Kuzu:支持简单的空格分隔查询,且 MAX_QUERY_LENGTH 严格限制为 128 graphiti_core/search/search_utils.py:88-92
  • FalkorDB:使用通过 driver.build_fulltext_query() 构建的 RedisSearch 语法 graphiti_core/search/search_utils.py:93-94

边全文搜索 graphiti_core/search/search_utils.py:185-294 针对 EntityEdge 关系的 fact 属性。 节点全文搜索 graphiti_core/search/search_utils.py:576-666 针对 EntityNodenamesummary 属性。

来源:graphiti_core/search/search_utils.py:85-113, graphiti_core/search/search_utils.py:185-294, graphiti_core/search/search_utils.py:576-666

向量相似度搜索

向量搜索执行查询嵌入向量与存储嵌入向量之间的余弦相似度比较。

  • 节点相似度:搜索 name_embedding graphiti_core/search/search_utils.py:669-793
  • 边相似度:搜索 fact_embedding graphiti_core/search/search_utils.py:297-442

实现方式因 GraphProvider 而异:

  • Neo4j/FalkorDB:在 Cypher 中使用原生向量相似度查询。
  • Kuzu:需要显式类型转换:CAST($search_vector AS FLOAT[1536]) graphiti_core/search/search_utils.py:365-373
  • Neptune:使用 Amazon OpenSearch Serverless(AOSS)进行向量索引,通过 driver.run_aoss_query 实现 graphiti_core/search/search_utils.py:326-340

来源:graphiti_core/search/search_utils.py:297-442, graphiti_core/search/search_utils.py:669-793, graphiti_core/search/search_utils.py:365-373

图广度优先搜索(BFS)

BFS 遍历从特定节点开始探索图结构。

  • 边 BFS:遍历 RELATES_TO 路径,深度不超过 bfs_max_depth graphiti_core/search/search_utils.py:445-573
  • 节点 BFS:检索遍历范围内的所有实体 graphiti_core/search/search_utils.py:796-877

node_search() 中,如果未提供起始节点,系统会执行"两遍"搜索:首先通过 BM25/相似度查找节点,然后将这些节点作为 BFS 的起始点,查找相关上下文 graphiti_core/search/search.py:393-405

来源:graphiti_core/search/search_utils.py:445-573, graphiti_core/search/search_utils.py:796-877, graphiti_core/search/search.py:393-405

结果融合与重排序

倒数排名融合(RRF)

RRF 通过将排名的倒数相加,将多个排名列表合并为一个排名。它是混合搜索的默认融合策略。 实现位置:graphiti_core/search/search_utils.py:903-928

最大边际相关性(MMR)

MMR 在相关性与多样性之间取得平衡,以避免检索上下文中出现冗余结果。它使用 search_vector 和候选结果的嵌入向量,对与已选项目过于相似的项目进行惩罚。 实现位置:graphiti_core/search/search_utils.py:931-984

交叉编码器重排序

交叉编码器通过将查询和文档文本一起输入模型,对候选结果进行高精度重新评分。这种方法计算成本更高,但比仅使用嵌入向量的搜索更准确。

  • 边重排序graphiti_core/search/search.py:304-310
  • 节点重排序graphiti_core/search/search.py:425-434
专用重排序器
  • 节点距离:根据结果到 center_node_uuid 的最短路径距离进行排名 graphiti_core/search/search_utils.py:987-1030
  • 片段提及:根据实体或边出现在多少个不同片段中进行排名 graphiti_core/search/search_utils.py:1033-1070

来源:graphiti_core/search/search_utils.py:903-1070, graphiti_core/search/search.py:304-434

搜索过滤器

SearchFiltersgraphiti_core/search/search_filters.py:55-67 支持复杂的布尔逻辑和时间约束。

过滤逻辑实现

下图展示了 SearchFilters 如何转换为数据库特定的查询组件。

Graphiti · 过滤逻辑实现 · 图 2
Graphiti · 过滤逻辑实现 · 图 2

来源:graphiti_core/search/search_filters.py:27-120, graphiti_core/search/search_filters.py:120-262

时间过滤

时间过滤器使用 DateFilter graphiti_core/search/search_filters.py:38-43 对 Graphiti 的双时态模型进行查询:

  • created_at:按数据入库时间过滤 graphiti_core/search/search_filters.py:65
  • valid_at:按事实在"现实世界"中成立的时间过滤 graphiti_core/search/search_filters.py:62
  • invalid_at:按事实不再成立的时间过滤 graphiti_core/search/search_filters.py:63
  • expired_at:按事实被逻辑删除/取代的时间过滤 graphiti_core/search/search_filters.py:65
属性过滤

PropertyFilter graphiti_core/search/search_filters.py:45-53 允许使用 ComparisonOperator graphiti_core/search/search_filters.py:27-35 中定义的标准比较运算符,对存储在节点或边上的自定义属性进行过滤。

来源:graphiti_core/search/search_filters.py:27-67, graphiti_core/search/search_filters.py:120-262

搜索配置配方

Graphiti 在 search_config_recipes.py 中为常见用例提供了预定义的搜索配方:

配方描述
COMBINED_HYBRID_SEARCH_RRF对所有类型使用 BM25 + 相似度,通过 RRF 融合 graphiti_core/search/search_config_recipes.py:34-53
COMBINED_HYBRID_SEARCH_MMRBM25 + 相似度,通过 MMR 融合以实现多样性 graphiti_core/search/search_config_recipes.py:56-78
COMBINED_HYBRID_SEARCH_CROSS_ENCODERBM25 + 相似度 + BFS,通过交叉编码器重排序 graphiti_core/search/search_config_recipes.py:81-108
NODE_HYBRID_SEARCH_RRF专门针对节点的混合搜索 graphiti_core/search/search_config_recipes.py:156-161

来源:graphiti_core/search/search_config_recipes.py:34-206

搜索结果与上下文

搜索结果以 SearchResults Pydantic 模型返回 graphiti_core/search/search_config.py:121-130。要将这些结果用于大语言模型(LLM)提示,search_results_to_context_string() 辅助函数会将节点、边和社区转换为结构化字符串 graphiti_core/search/search_helpers.py:27-72

上下文格式化

上下文字符串包括:

  • FACTS:带有 valid_atinvalid_at 日期的事实关系 graphiti_core/search/search_helpers.py:29-36
  • ENTITIES:实体名称及其摘要 graphiti_core/search/search_helpers.py:37-39
  • EPISODES:片段内容和来源描述 graphiti_core/search/search_helpers.py:40-46
  • COMMUNITIES:社区名称和摘要 graphiti_core/search/search_helpers.py:47-50

格式化过程使用 to_prompt_json graphiti_core/prompts/prompt_helpers.py:23-40 确保数据安全序列化以供大语言模型(LLM)使用,同时保留非 ASCII 字符。

来源:graphiti_core/search/search_config.py:121-130, graphiti_core/search/search_helpers.py:27-72, graphiti_core/prompts/prompt_helpers.py:23-40