indexer

package
v2.0.13 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 26, 2026 License: MIT Imports: 19 Imported by: 0

Documentation

Overview

Package indexer 定义索引器的接口与实现。

本文件实现 GraphIndexer:图索引器,职责单一化为「图结构化」。

设计要点:

  • 不做分块(Chunker 由 HyperIndexer 调用;独立使用时 AddFile 内部调用 Chunker)
  • 不做向量化(SemanticIndexer 负责)
  • 只持有 GraphStore,从 doc.Nodes()/Edges() 读取实体/关系并写入
  • Chunk 不作为 Node 写入 GraphStore
  • 不实现 IndexerAdmin(Chunk 管理由 SemanticIndexer 通过 VectorStore 负责)

Package indexer 定义索引器的接口与实现。

本文件定义 indexer 包对外的 6 个核心接口(参考 io 包的小接口组合风格):

  • Indexer 核心接口:Name / AddFile / Search / NewQuery(所有索引器必实现)
  • IndexerStore 存储接口:Save(各 Indexer 实现自动路由到各自存储)
  • IndexerAdmin 管理接口:List / GetChunks / Count / Remove / Clear
  • IndexerCloser 资源管理接口:Close
  • TreeViewBuilder 导航接口:Tree(仅 HyperIndexer 实现)
  • GraphSearcher 图查询接口:SearchGraph(仅 GraphIndexer 实现)

设计要点:

  • 接口分离原则(ISP):调用方按需 type-assert,不依赖不需要的方法
  • 组合优于继承:HyperIndexer 通过组合 SemanticIndexer + GraphIndexer 实现双线协同
  • 只支持文件输入:Indexer 职责单一化为「索引文件」,所有内容必须通过 AddFile 索引
  • Hit 与 StructuredDoc 对称:StructuredDoc 是索引过程容器,Hit 是检索过程容器
  • StructuredDoc 类型定义在 core 包,indexer 包不依赖 structurizer 包

Index

Constants

View Source
const (
	StrategyRecursive = "recursive"
	StrategyParagraph = "paragraph"
	StrategySentence  = "sentence"
	StrategyCode      = "code"
	StrategyParentDoc = "parent_doc"
)

分块策略常量。

Variables

This section is empty.

Functions

func GetChunks

func GetChunks(content string, opts ...ChunkOption) ([]*core.Chunk, error)

GetChunks 根据文本内容进行结构化和分块。 如果没有指定策略,会根据内容自动选择最佳分块策略,返回完整的分块数组。

func GetFileChunks

func GetFileChunks(file string, opts ...ChunkOption) ([]*core.Chunk, error)

GetFileChunks 根据文件路径进行结构化和分块。 如果没有指定策略,会根据内容自动选择最佳分块策略,返回完整的分块数组。

func RegionIDFromContext added in v2.0.3

func RegionIDFromContext(ctx context.Context) string

RegionIDFromContext 从 context 中提取 region ID,未设置时返回空字符串。

func WithRegionID added in v2.0.3

func WithRegionID(ctx context.Context, regionID string) context.Context

WithRegionID 将 region ID 附加到 context。 传递给 AddFile / Save 时,相关元数据会携带此 region_id。

Types

type ChunkOption

type ChunkOption func(*chunkOption)

ChunkOption 分块选项

func WithChunkLogger

func WithChunkLogger(logger logging.Logger) ChunkOption

WithChunkLogger attaches a logger to the chunking operation. The chunker emits a "chunker.parse" log when the source has been loaded and a "chunker.chunked" log when the chunk array is produced.

func WithChunkStrategy

func WithChunkStrategy(strategy string) ChunkOption

WithChunkStrategy 设置分块策略

type FileExplorer added in v2.0.13

type FileExplorer interface {
	// ExploreFile 以文件 Document 为中心探索实体和关系。
	// filePath 应为绝对路径;depth 默认 2 即可包含实体间关系。
	ExploreFile(ctx context.Context, filePath string, depth, limit int) (*RegionGraphView, error)
}

FileExplorer 文件级图探索扩展接口:以文件 Document 为中心查询实体和关系。

GraphIndexer 直接实现;HyperIndexer 委托给内部 graph。

type GraphExplorer added in v2.0.13

type GraphExplorer interface {
	// ExploreRegion 从指定目录的 Region 节点出发,遍历 depth 跳邻居。
	// dir 应为绝对路径;limit 限制返回节点数量。
	ExploreRegion(ctx context.Context, dir string, depth, limit int) (*RegionGraphView, error)
}

GraphExplorer 图探索扩展接口:以目录为起点查询 Region 及其多跳邻居。

GraphIndexer 直接实现;HyperIndexer 委托给内部 graph。

type GraphIndexer

type GraphIndexer struct {
	// contains filtered or unexported fields
}

GraphIndexer 图索引器:职责单一化为「图结构化」。

设计要点:

  • 不做分块(Chunker 由 HyperIndexer 调用,独立使用时 AddFile 内部调用 Chunker)
  • 不做向量化(SemanticIndexer 负责)
  • 只持有 GraphStore,从 doc.Nodes()/Edges() 读取实体/关系并写入
  • Chunk 不作为 Node 写入 GraphStore
  • 不实现 IndexerAdmin(Chunk 管理由 SemanticIndexer 通过 VectorStore 负责)

独立使用模式(纯图谱模式):

  • AddFile 内部调用 Chunker 分块,构造 StructuredDoc,调用 Save
  • Search 只走图遍历(不走向量检索)

HyperIndexer 编排模式:

  • HyperIndexer 完成分块后,通过 Save(ctx, doc) 注入已分块的 StructuredDoc
  • GraphIndexer 只负责写入实体/关系 + 维护 Region→Document 的 CONTAINS 边

func (*GraphIndexer) AddFile

func (idx *GraphIndexer) AddFile(ctx context.Context, filePath string) ([]*core.Chunk, error)

AddFile 索引一个文件,返回产生的 Chunks。

独立使用模式:内部用 Chunker 分块,构造 StructuredDoc,调用 Save。 HyperIndexer 编排模式下不应直接调用 AddFile,应由 HyperIndexer 负责协调。

流程:

  1. document.Open(filePath) → rawDoc
  2. core.NewStructuredDoc(rawDoc) → doc
  3. chunker.New(rawDoc) → chunkerImpl
  4. chunkerImpl.Chunk(rawDoc) → result (含 Chunks/Nodes/Edges)
  5. doc.SetChunks/SetNodes/SetEdges
  6. idx.Save(ctx, doc)
  7. 返回 result.Chunks 转换为 []*core.Chunk

func (*GraphIndexer) CheckReady added in v2.0.8

func (idx *GraphIndexer) CheckReady() error

CheckReady 检查 GraphIndexer 的核心存储组件是否已就绪。

func (*GraphIndexer) Close

func (idx *GraphIndexer) Close(ctx context.Context) error

Close 关闭底层图存储。

func (*GraphIndexer) CountByRegion added in v2.0.5

func (idx *GraphIndexer) CountByRegion(ctx context.Context, path string) (int, error)

CountByRegion 返回指定路径下(source_file 前缀匹配)的 Document 节点总数。 Document 节点的 source_file 属性由 Save 方法在写入时填充。

func (*GraphIndexer) CypherQuery

func (idx *GraphIndexer) CypherQuery(ctx context.Context, q string, params map[string]any) ([]map[string]any, error)

CypherQuery 执行原始的 Cypher 查询,供外部 Agent/LLM 生成高级图查询。 参数 params 为 Cypher 查询的命名参数映射。

func (*GraphIndexer) EntityStats

func (idx *GraphIndexer) EntityStats() (entities, rels int)

EntityStats 返回自上次 ResetEntityStats 以来累计创建的实体和关系数量。

func (*GraphIndexer) ExploreFile added in v2.0.13

func (idx *GraphIndexer) ExploreFile(ctx context.Context, filePath string, depth, limit int) (*RegionGraphView, error)

ExploreFile 以文件 Document 为中心探索实体和关系。

流程:

  1. 通过 Cypher 查询 exact match source_file 的 Document 节点
  2. 从 Document 出发遍历 depth 跳邻居实体
  3. 返回实体节点与关系边

filePath 应为绝对路径;depth 默认 2 即可包含实体间关系。

func (*GraphIndexer) ExploreRegion added in v2.0.13

func (idx *GraphIndexer) ExploreRegion(ctx context.Context, dir string, depth, limit int) (*RegionGraphView, error)

ExploreRegion 实现 GraphExplorer 接口:探索指定目录的图结构。

流程:

  1. 通过目录路径生成 Region 节点 ID,获取 Region 节点
  2. 从 Region 节点出发,遍历 depth 跳邻居
  3. 通过 Cypher 查询所有 source_file 以 dir 为前缀的 Document 节点, 从这些 Document 出发获取 entity 子节点(解决子目录 Region 独立导致的实体不可达问题)
  4. 合并全部节点与边并去重

func (*GraphIndexer) GetNode added in v2.0.13

func (idx *GraphIndexer) GetNode(ctx context.Context, nodeID string) (*core.Node, error)

GetNode 实现 GraphNavigator 接口:按 ID 获取单个节点。

func (*GraphIndexer) GraphDB

func (idx *GraphIndexer) GraphDB() core.GraphStore

GraphDB 返回 GraphIndexer 持有的图数据库实例。 外部可通过此方法直接操作图存储(如自定义 Cypher 查询、图分析等)。

func (*GraphIndexer) Name

func (idx *GraphIndexer) Name() string

Name 返回索引器名称。

func (*GraphIndexer) Neighbors added in v2.0.13

func (idx *GraphIndexer) Neighbors(ctx context.Context, nodeID string, depth, limit int) ([]*core.Node, []*core.Edge, error)

Neighbors 实现 GraphNavigator 接口:从 nodeID 出发遍历 depth 跳邻居。 返回邻居节点与关联边;depth=1 表示直接邻居。

func (*GraphIndexer) NewQuery

func (idx *GraphIndexer) NewQuery(terms string) core.Query

NewQuery 构造查询对象,默认查询类型为 semantic。 调用方可在查询前优化阶段通过 SetType 识别并修改为 graph / hybrid / keyword。

func (*GraphIndexer) ResetEntityStats

func (idx *GraphIndexer) ResetEntityStats()

ResetEntityStats 将实体/关系计数器归零(通常在每次 Sync 开始前调用)。

func (*GraphIndexer) Save added in v2.0.13

func (idx *GraphIndexer) Save(ctx context.Context, doc core.StructuredDoc) error

Save 实现 IndexerStore 接口:保存已结构化的文档到 GraphStore。

  • 从 doc.Nodes() 读取实体,写入 graphDB.UpsertNodes
  • 从 doc.Edges() 读取关系,写入 graphDB.UpsertEdges
  • 调用 writeContainsEdges 维护 Region→Document 的 CONTAINS 边
  • 不写 Chunk 节点到 GraphStore
  • 不写 Document→Chunk 的 CONTAINS 边(由 TreeViewBuilder 在视图层组装)

与 SemanticIndexer.Save 的差异:

  • SemanticIndexer.Save 写 VectorStore(向量化)
  • GraphIndexer.Save 写 GraphStore(实体 + Region→Document 边,不向量化)

func (*GraphIndexer) Search

func (idx *GraphIndexer) Search(ctx context.Context, qry core.Query) (*core.Hit, error)

Search 实现 Indexer 接口:执行图遍历检索,返回 *core.Hit 容器。

GraphIndexer 独立使用时不持有 VectorStore/Embedder,无法走向量检索。 Search 只走图遍历(searchGraphOnly),返回的 Hit 仅包含 Nodes/Edges。 生产场景应通过 HyperIndexer 使用,由 SemanticIndexer 提供向量检索能力。

func (*GraphIndexer) SearchGraph added in v2.0.13

func (idx *GraphIndexer) SearchGraph(ctx context.Context, q core.Query) (*core.Hit, error)

SearchGraph 实现 GraphSearcher 接口:执行图查询,返回 *Hit(仅 Nodes/Edges,Chunks 为空)。

与 Search 的区别:

  • Search 在 HyperIndexer 编排下可能融合多源结果
  • SearchGraph 明确只走图遍历,返回的 Hit 仅包含 Nodes/Edges

客户端可对 Search 和 SearchGraph 的结果直接做 Fusion 融合。

type GraphNavigator added in v2.0.13

type GraphNavigator interface {
	// Neighbors 从 nodeID 出发遍历 depth 跳邻居,返回邻居节点与关联边。
	// depth=1 表示直接邻居;limit 限制返回节点数量。
	Neighbors(ctx context.Context, nodeID string, depth, limit int) ([]*core.Node, []*core.Edge, error)

	// GetNode 按 ID 获取单个节点,用于补全路径起点(如 Region 节点本身)。
	GetNode(ctx context.Context, nodeID string) (*core.Node, error)
}

GraphNavigator 图导航扩展接口:从指定节点出发进行多跳邻居遍历。

仅 GraphIndexer / HyperIndexer 实现,用于 `grag nodes` 这类目录级图探索命令。

type GraphOption

type GraphOption func(*GraphIndexer)

GraphOption 配置 GraphIndexer 的可选参数。

func WithLogger

func WithLogger(logger logging.Logger) GraphOption

WithLogger 为 GraphIndexer 附加日志记录器。

type GraphSearcher added in v2.0.13

type GraphSearcher interface {
	// SearchGraph 执行图查询,返回 Hit(Nodes / Edges 填充,Chunks 为空)。
	SearchGraph(ctx context.Context, query core.Query) (*core.Hit, error)
}

GraphSearcher 图查询扩展接口:执行图检索,返回 *Hit(Nodes / Edges 填充)。

仅 GraphIndexer 实现,SemanticIndexer 不维护 GraphStore。 调用方按需 type-assert:

if g, ok := idx.(GraphSearcher); ok { hit, err := g.SearchGraph(ctx, q) }

与 Indexer.Search 统一返回 *Hit,便于 Fusion 融合:

  • SearchGraph 返回的 Hit 中 Chunks 为空,仅填充 Nodes / Edges
  • 客户端可对 Search 和 SearchGraph 的结果直接做 Fusion 融合
  • GraphResult 类型已删除,统一用 *core.Hit 表达检索结果

type HyperIndexer added in v2.0.13

type HyperIndexer struct {
	// contains filtered or unexported fields
}

===================================================================== HyperIndexer 复合索引器 =====================================================================

HyperIndexer 是双线结合的契机——协调 SemanticIndexer(语义线)和 GraphIndexer(关系线)。

核心设计:

  • GraphIndexer 职责独立,不做分块+向量化
  • SemanticIndexer 职责独立,不做实体提取+图结构化
  • HyperIndexer 编排双线:读文件→结构化→分块→分流到 SemanticIndexer + GraphIndexer

工作流(AddFile):

  1. document.Open(path) → RawDoc(读文件 + 归一化)
  2. core.NewStructuredDoc(raw) → StructuredDoc(结构化容器)
  3. 路由 Chunker(注入的或 chunker.New(raw));chunkerImpl.Chunk(raw) → ChunkResult(含 Chunks/Nodes/Edges)
  4. doc.SetChunks/SetNodes/SetEdges(把三类产物分别存入 StructuredDoc)
  5. semantic.Save(doc)(语义线:向量化+写入 VectorStore)
  6. graph.Save(doc)(关系线:实体+CONTAINS 边+写入 GraphStore,若 graph 存在)

工作流(Search):

  1. semantic.Search(q) → semHit(Chunks 填充)
  2. graph.SearchGraph(q) → graphHit(Nodes/Edges 填充,若 graph 存在)
  3. result.RRF(semHit, graphHit) → 融合 Hit(三类齐全)

扩展能力(通过 type-assert):

  • hyper.(IndexerAdmin) → 委托 semantic(语义线持有 VectorStore)
  • hyper.(IndexerCloser) → 双线联动关闭
  • hyper.(TreeViewBuilder)→ HyperIndexer 自身实现(先取 Region→Document,再补齐 Chunk)
  • hyper.(GraphSearcher) → 委托 graph

func (*HyperIndexer) AddFile added in v2.0.13

func (h *HyperIndexer) AddFile(ctx context.Context, filePath string) ([]*core.Chunk, error)

AddFile 实现 Indexer 接口:对外统一入口,编排双线索引。

工作流(完整):

  1. document.Open(filePath) → RawDoc [1a] OnFileOpenedHook:文件类型白名单、前置过滤
  2. core.NewStructuredDoc(raw) → StructuredDoc 容器
  3. 路由 Chunker → chunkerImpl.Chunk(raw) → ChunkResult
  4. doc.SetChunks/SetNodes/SetEdges [4a] OnChunkHook:对每个 Chunk 执行敏感词过滤、补充标签 4.5 [语义线加工] 若注入了 Summarizer,对文档类分片批量摘要 [4b] OnBeforeSemanticSaveHook:批量审核、外部 API 增强
  5. semantic.Save(doc)(向量化 + 写入 VectorStore) 5.5 [关系线加工] 若注入了 Refiller + 已注册 Schema,调用 Refiller 提取实体和关系
  6. graph.Save(doc)(实体 + CONTAINS 边 + 写入 GraphStore,若 graph 存在) [6a] OnIndexCompleteHook:通知下游、审计日志

返回本次索引生成的 Chunks(用于调用方追踪)。 关系线失败不阻塞语义线,仅记录警告。

func (*HyperIndexer) AddSchemas added in v2.0.13

func (h *HyperIndexer) AddSchemas(path string, schemas []llm.EntitySchema)

AddSchemas 注册外部实体 Schema 到 HyperIndexer。

path 是文件系统路径,指向该组 Schema 的源目录(如 "schemas/general"), 保留溯源语义——调用方可追踪这些 Schema 来自哪个配置文件目录。 schemas 使用 llm/schema.go 中已定义的 EntitySchema 类型, 可经由 llm.LoadEntitySchemasFromDir 或自定义加载函数解析后传入。

path 不用于文件读取(schemas 已经是解析好的),仅作为注册标识。 HyperIndexer 将 path 作为 key 存储在内部注册表中,供 Refiller 消费时合并。

func (*HyperIndexer) Clear added in v2.0.13

func (h *HyperIndexer) Clear(ctx context.Context) error

Clear 实现 IndexerAdmin 接口:双线联动清空。

func (*HyperIndexer) Close added in v2.0.13

func (h *HyperIndexer) Close(ctx context.Context) error

Close 实现 IndexerCloser 接口:双线联动关闭。 任何一线关闭失败都返回 error,但会尝试关闭所有线后再返回。

func (*HyperIndexer) Count added in v2.0.13

func (h *HyperIndexer) Count(ctx context.Context) (int, error)

Count 实现 IndexerAdmin 接口:委托语义线。

func (*HyperIndexer) CypherQuery added in v2.0.13

func (h *HyperIndexer) CypherQuery(ctx context.Context, q string, params map[string]any) ([]map[string]any, error)

CypherQuery 执行原始 Cypher 查询,委托给关系线的 GraphIndexer。 仅当索引器支持图存储时可用。

func (*HyperIndexer) ExploreFile added in v2.0.13

func (h *HyperIndexer) ExploreFile(ctx context.Context, filePath string, depth, limit int) (*RegionGraphView, error)

ExploreFile 实现 FileExplorer 接口:委托关系线执行文件级图探索。

func (*HyperIndexer) ExploreRegion added in v2.0.13

func (h *HyperIndexer) ExploreRegion(ctx context.Context, dir string, depth, limit int) (*RegionGraphView, error)

ExploreRegion 实现 GraphExplorer 接口:委托关系线执行目录级图探索。

func (*HyperIndexer) GetChunks added in v2.0.13

func (h *HyperIndexer) GetChunks(ctx context.Context, docID string) ([]*core.Chunk, error)

GetChunks 实现 IndexerAdmin 接口:委托语义线。

func (*HyperIndexer) GetNode added in v2.0.13

func (h *HyperIndexer) GetNode(ctx context.Context, nodeID string) (*core.Node, error)

GetNode 实现 GraphNavigator 接口:委托关系线按 ID 获取单个节点。

func (*HyperIndexer) List added in v2.0.13

func (h *HyperIndexer) List(ctx context.Context, offset, limit int, filters []core.FilterCondition) ([]core.Chunk, int, error)

List 实现 IndexerAdmin 接口:委托语义线(VectorStore 持有全部 Chunk 数据)。

func (*HyperIndexer) Name added in v2.0.13

func (h *HyperIndexer) Name() string

Name 返回索引器名称

func (*HyperIndexer) Neighbors added in v2.0.13

func (h *HyperIndexer) Neighbors(ctx context.Context, nodeID string, depth, limit int) ([]*core.Node, []*core.Edge, error)

Neighbors 实现 GraphNavigator 接口:委托关系线执行多跳邻居遍历。 若关系线未启用或未实现 GraphNavigator,返回错误。

func (*HyperIndexer) NewQuery added in v2.0.13

func (h *HyperIndexer) NewQuery(terms string) core.Query

NewQuery 实现 Indexer 接口:委托语义线构造查询。

func (*HyperIndexer) ProcessChunks added in v2.0.13

func (h *HyperIndexer) ProcessChunks(ctx context.Context, chunks []core.Chunk) (processedChunks []core.Chunk, addedNodes []core.Node, addedEdges []core.Edge, summarizeCompleted, refillCompleted bool, err error)

ProcessChunks 对指定分片执行增量 LLM 处理(摘要 + 实体提取)。

流程:

  1. [摘要] 若注入了 Summarizer,对所有内容足够长的分片调用 Summarizer
  2. [向量更新] 摘要后的分片重新向量化并写入 VectorStore
  3. [实体提取] 若注入了 Refiller + 已注册 Schema,对所有分片调用 Refiller
  4. [图更新] 新提取的 Nodes/Edges 写入 GraphStore

参数:

  • ctx: 上下文
  • chunks: 需要处理的分片(必须已从 VectorStore 或其他来源加载完整数据)

返回值:

  • processedChunks: 处理后的分片列表(Summary/Title 已更新)
  • addedNodes: 新提取的实体节点
  • addedEdges: 新提取的关系边
  • summarizeCompleted: Summarizer 阶段是否已完成(未注入或已调用)
  • refillCompleted: Refiller 阶段是否已完成(未注入、无 Schema 或已调用)
  • error: 整体错误(单个阶段失败不阻塞后续阶段,仅记录警告)

典型调用方:IndexingService.Update,从 meta.db 查询需要 LLM 处理的分片, 从 VectorStore 加载完整数据后传给此方法。

func (*HyperIndexer) Remove added in v2.0.13

func (h *HyperIndexer) Remove(ctx context.Context, chunkID string) error

Remove 实现 IndexerAdmin 接口:双线联动删除。 语义线和关系线都需要按 chunkID 删除关联数据。 关系线删除失败不阻塞语义线,仅记录警告。

func (*HyperIndexer) Search added in v2.0.13

func (h *HyperIndexer) Search(ctx context.Context, q core.Query) (*core.Hit, error)

Search 实现 Indexer 接口:双线融合检索。

工作流:

  1. semantic.Search(q) → semHit(Chunks 填充)
  2. graph.SearchGraph(q) → graphHit(Nodes/Edges 填充,若 graph 存在)
  3. result.RRF(semHit, graphHit) → 融合 Hit(三类齐全)

设计要点:

  • graph 为 nil 时跳过图检索,直接返回 semHit
  • graphHit 为 nil 时 RRF 内部自动跳过,不影响融合
  • 融合后 Hit.Score = topChunkScore + topNodeScore + topEdgeScore

func (*HyperIndexer) SearchGraph added in v2.0.13

func (h *HyperIndexer) SearchGraph(ctx context.Context, q core.Query) (*core.Hit, error)

SearchGraph 实现 GraphSearcher 接口:委托关系线。 graph 为 nil 或未实现 GraphSearcher 时返回 error。

func (*HyperIndexer) SetLogger added in v2.0.13

func (h *HyperIndexer) SetLogger(logger logging.Logger)

SetLogger 在运行时设置日志记录器。

func (*HyperIndexer) SetRefiller added in v2.0.13

func (h *HyperIndexer) SetRefiller(r llm.Refiller)

SetRefiller 在运行时注入或替换 Refiller。 若传入 nil,则禁用 Refiller 功能。

func (*HyperIndexer) SetSummarizer added in v2.0.13

func (h *HyperIndexer) SetSummarizer(s llm.Summarizer)

SetSummarizer 在运行时注入或替换 Summarizer。 若传入 nil,则禁用 Summarizer 功能。

func (*HyperIndexer) Tree added in v2.0.13

func (h *HyperIndexer) Tree(ctx context.Context, regionID string) (*core.TreeNode, error)

Tree 实现 TreeViewBuilder 接口:构建 Region → Document → Chunk 三层知识树。

实现流程:

  1. 从 GraphIndexer 取 Region→Document 树(通过未导出方法 regionTree)
  2. 对每个 Document 节点,通过 semantic.(IndexerAdmin).GetChunks 从 VectorStore 读取 Chunk 列表
  3. 将 Chunk 挂载为对应 Document 的子节点
  4. 返回完整的 Region→Document→Chunk 树

设计要点:

  • 仅 HyperIndexer 实现此接口——它需要同时访问 GraphStore 和 VectorStore
  • GraphIndexer 不实现 TreeViewBuilder,仅暴露未导出的 regionTree 供 HyperIndexer 调用
  • Chunk 不写入 GraphStore,而是在视图层通过 VectorStore.Metadata[core.VecMetaDocID] 动态组装

graph 为 nil 或非 *GraphIndexer 时返回 error。

type HyperOption added in v2.0.13

type HyperOption func(*HyperIndexer)

HyperOption HyperIndexer 配置选项

func WithHooks added in v2.0.13

func WithHooks(hooksList ...any) HyperOption

WithHooks 注入事件扩展 Hook。

可传入任意数量的 Hook(OnFileOpenedHook、OnChunkHook、OnBeforeSemanticSaveHook、 OnIndexCompleteHook),WithHooks 按类型自动归入对应切片。 单一类型可注册多个 Hook,按注册顺序执行。

func WithHyperChunker added in v2.0.13

func WithHyperChunker(c chunker.Chunker) HyperOption

WithHyperChunker 设置自定义分块器(默认按 RawDoc.Type 自动路由)

func WithHyperLogger added in v2.0.13

func WithHyperLogger(logger logging.Logger) HyperOption

WithHyperLogger 设置日志记录器

func WithHyperRefiller added in v2.0.13

func WithHyperRefiller(r llm.Refiller) HyperOption

WithHyperRefiller 注入实体提取兜底,在语义线保存后对分片执行 LLM 实体提取。 提取结果追加到 doc.Nodes/Edges,再写入 GraphStore。 不传则不执行实体提取,关系线只走 Chunker 代码解析器产出的 Nodes/Edges。

func WithHyperSummarizer added in v2.0.13

func WithHyperSummarizer(s llm.Summarizer) HyperOption

WithHyperSummarizer 注入批量摘要器,在分块后为文档类分片批量生成 title/summary。 不传则不调用 Summarizer,title/summary 由 Chunker 默认策略产出。 若注入的 llm.Summarizer 同时实现了 SummarizeBatch 方法,优先使用批量模式; 否则回退到逐分片 Summarize 模式。

type IndexError

type IndexError struct {
	DocID     string        // 文档 ID
	Err       error         // 原始错误
	ErrorType string        // 错误分类: network | timeout | rate_limit | auth | api | unknown
	Attempts  int           // 重试次数
	Duration  time.Duration // 总耗时
}

IndexError 包含索引失败的详细信息,供外部错误处理使用。

type Indexer added in v2.0.13

type Indexer interface {
	// Name 返回索引器名称(如 "semantic" / "graph" / "hyper")。
	Name() string

	// AddFile 从文件读取内容后执行索引全流程。
	// filePath 必须为绝对路径,内部通过 document.Open 归一化后分块、向量化、写入存储。
	// 返回本次索引生成的 Chunks(调用方可用于追踪或后续处理)。
	AddFile(ctx context.Context, filePath string) ([]*core.Chunk, error)

	// Search 执行检索,返回命中的 Hit 容器(持有 Chunks/Nodes/Edges)。
	// Hit 与 StructuredDoc 对称——StructuredDoc 是存,Hit 是取。
	Search(ctx context.Context, query core.Query) (*core.Hit, error)

	// NewQuery 构造查询对象,承载查询前优化与查询类型识别。
	NewQuery(terms string) core.Query
}

Indexer 索引器核心接口:负责文件索引和检索。 所有索引器必须实现此接口。

设计要点:

  • 只支持文件输入(AddFile),不支持字符串输入
  • 所有内容必须先落盘为文件,通过 document.Open 归一化
  • source_file / region_id 等元数据依赖文件路径
  • Search 返回 *core.Hit 容器(持有 Chunks/Nodes/Edges),与 StructuredDoc 对称

实现类型:

  • SemanticIndexer:分块 + 向量化 + 语义检索
  • GraphIndexer:分块 + 图结构化(独立使用为纯图谱模式)
  • HyperIndexer:双线协同(语义线 + 关系线)

func New

func New(
	graphDB core.GraphStore,
	opts ...GraphOption,
) (Indexer, error)

New 创建 GraphIndexer,返回 Indexer 接口。

参数:

  • graphDB: 图存储(写入实体/关系,用于知识图谱检索)
  • opts: 可选配置(WithLogger、WithSchemas、WithSchemasFromFS 等)

func NewHyperIndexer added in v2.0.13

func NewHyperIndexer(semantic Indexer, graph Indexer, opts ...HyperOption) (Indexer, error)

NewHyperIndexer 创建复合索引器,返回 Indexer 接口。

参数:

  • semantic: 语义线索引器(必传,通常由 NewSemanticIndexer 创建)
  • graph: 关系线索引器(可选,传 nil 则不启用图功能;通常由 New(GraphIndexer)创建)
  • opts: 可选配置(WithHyperLogger、WithHyperChunker、WithHyperSummarizer、WithHyperRefiller)

设计要点:

  • semantic 为 nil 时返回 error(语义线是必传的核心能力)
  • graph 为 nil 时降级为纯语义模式(Search 只返回 Chunks)
  • 默认分块器按需懒创建(每次 AddFile 时根据 RawDoc.Type 路由)

func NewSemanticIndexer

func NewSemanticIndexer(db core.VectorStore, embedder core.Embedder, opts ...SemanticOption) (Indexer, error)

NewSemanticIndexer 创建语义索引器,返回 Indexer 接口。

必传参数:

  • db:向量存储,nil 返回 error
  • embedder:向量计算器,nil 返回 error

可选参数通过 WithSemanticLogger / WithSemanticChunker 注入。

type IndexerAdmin added in v2.0.13

type IndexerAdmin interface {
	// List 分页浏览已索引的 Chunk。
	// filters 为 nil 时返回全部,非 nil 时按条件过滤(多个条件之间为 AND 语义)。
	// 返回当前页的 Chunk 切片与过滤前总数。
	List(ctx context.Context, offset, limit int, filters []core.FilterCondition) ([]core.Chunk, int, error)

	// GetChunks 按 docID 获取该文档的所有 Chunk。
	GetChunks(ctx context.Context, docID string) ([]*core.Chunk, error)

	// Count 返回已索引的 Chunk 总数。
	Count(ctx context.Context) (int, error)

	// Remove 按 chunkID 移除索引项(连带删除关联的 Nodes / Edges)。
	Remove(ctx context.Context, chunkID string) error

	// Clear 清空索引。
	Clear(ctx context.Context) error
}

IndexerAdmin 索引器管理接口:浏览、统计、维护。

调用方按需 type-assert:

if a, ok := idx.(IndexerAdmin); ok { ... }

type IndexerCloser added in v2.0.13

type IndexerCloser interface {
	// Close 释放底层资源(数据库连接、文件句柄等)。
	Close(ctx context.Context) error
}

IndexerCloser 资源管理接口:释放底层存储资源。

调用方按需 type-assert:

if c, ok := idx.(IndexerCloser); ok { defer c.Close(ctx) }

type IndexerStore added in v2.0.13

type IndexerStore interface {
	// Save 保存已结构化的文档到各自存储。
	// 不返回 Chunks——Chunks 已在 doc 中,各 Indexer 只负责保存。
	Save(ctx context.Context, doc core.StructuredDoc) error
}

IndexerStore 存储接口:保存 StructuredDoc 到各自存储。

各 Indexer 的 Save 实现自动路由到各自存储:

  • SemanticIndexer.Save → 从 doc.Chunks() 读取,按 Title/Summary/Content 生成多维度向量,写入 VectorStore
  • GraphIndexer.Save → 从 doc.Nodes()/Edges() 读取实体/关系,维护 Region→Document 的 CONTAINS 边,写入 GraphStore

语义:

  • Save 接收的 StructuredDoc 已完成「读文件 + 归一化 + 分块 + 结构化」
  • Chunks/Nodes/Edges 已由 HyperIndexer 调用 Chunker 填充到 doc 中
  • 各 Indexer 从 doc 读取各自需要的数据(向量化 / 图结构化)
  • Save 只负责「保存各自需要的数据」,不返回 Chunks

HyperIndexer 不实现此接口——它是组合器,通过调用 semantic.Save + graph.Save 实现存储路由。

type OnBeforeSemanticSaveHook added in v2.0.13

type OnBeforeSemanticSaveHook interface {
	OnBeforeSemanticSave(ctx context.Context, doc core.StructuredDoc) (core.StructuredDoc, error)
}

OnBeforeSemanticSaveHook 修改型 Hook。 在 Summarizer 之后、semantic.Save 之前触发,可修改 StructuredDoc 的 Chunks。

type OnChunkHook added in v2.0.13

type OnChunkHook interface {
	OnChunk(ctx context.Context, chunk *core.Chunk) (*core.Chunk, error)
}

OnChunkHook 修改型 Hook。 在 Chunker 产出每个 Chunk 后触发,可修改 *core.Chunk。

type OnFileOpenedHook added in v2.0.13

type OnFileOpenedHook interface {
	OnFileOpened(ctx context.Context, doc document.RawDoc) (document.RawDoc, error)
}

OnFileOpenedHook 修改型 Hook。 在 document.Open 之后、Chunker 之前触发,可修改 RawDoc。

type OnIndexCompleteHook added in v2.0.13

type OnIndexCompleteHook interface {
	OnIndexComplete(ctx context.Context, result []*core.Chunk) error
}

OnIndexCompleteHook 通知型 Hook。 在 AddFile 所有步骤完成后触发,仅通知,不阻塞返回。

type RegionGraphView added in v2.0.13

type RegionGraphView struct {
	RegionID   string
	RegionName string
	Region     *core.Node
	Nodes      []*core.Node
	Edges      []*core.Edge
}

RegionGraphView 是 GraphIndexer 返回的目录级图视图。

type SemanticOption

type SemanticOption func(*semanticIndexer)

SemanticOption 配置 semanticIndexer 的可选参数。

func WithSemanticChunker added in v2.0.13

func WithSemanticChunker(c chunker.Chunker) SemanticOption

WithSemanticChunker 注入自定义 Chunker,覆盖默认的 chunker.New 路由。 不传则 AddFile 内部按 RawDoc.Type 调用 chunker.New 选择实现。

func WithSemanticLogger

func WithSemanticLogger(logger logging.Logger) SemanticOption

WithSemanticLogger 为语义索引器附加日志记录器。

type TreeViewBuilder added in v2.0.13

type TreeViewBuilder interface {
	// Tree 输出基于 Region 层级的知识树。
	// regionID 为空时返回整棵树;非空时返回该 Region 子树。
	// 实现流程:先从 GraphIndexer 取 Region→Document 树,
	// 再通过 SemanticIndexer 为每个 Document 补齐 Chunk 子节点。
	Tree(ctx context.Context, regionID string) (*core.TreeNode, error)
}

TreeViewBuilder 知识库导航接口:构建 Region → Document → Chunk 层级树。

仅 HyperIndexer 实现,因为它需要同时访问 GraphStore 的 Region→Document 层级 和 VectorStore 的 Document→Chunk 数据。 调用方按需 type-assert:

if t, ok := idx.(TreeViewBuilder); ok { tree, err := t.Tree(ctx, "") }

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL