Help us shape the future of Go! Take the 2026 Go Developer Survey

rag

package
v1.7.0 Latest Latest
Warning

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

Go to latest
Published: Oct 13, 2026 License: AGPL-3.0 Imports: 21 Imported by: 0

Documentation

Index

Constants

View Source
const (
	DefaultChunkSize = 420 // tokens,为 overlap 和边界效应留 92 token 余量
	DefaultOverlap   = 50
	BriefPreviewLen  = 280
)

Variables

This section is empty.

Functions

func InitEmbedder

func InitEmbedder(modelsDir string, log *slog.Logger)

InitEmbedder 加载 tokenizer(同步)后异步加载 ONNX 模型,不阻塞调用方。 main 启动时尽早调用,模型在后台加载,GUI 可先行渲染。 调用后 GetTokenizer() 即可使用,无需等待模型就绪。

func InitRefreshQueue

func InitRefreshQueue(vs *VectorStore, chStore *chapter.Store, novelStore *novel.Store, logger *slog.Logger)

InitRefreshQueue 初始化全局 RefreshQueue。多次调用只生效一次。

func InitVectorStore

func InitVectorStore(db *sql.DB, embedder Embedder, log *slog.Logger)

InitVectorStore 初始化全局 VectorStore,多次调用只生效一次。

func SplitText

func SplitText(text string, chunkSize, overlap int, t *Tokenizer) ([]string, []int)

SplitText 将文本分割成指定大小的重叠块,优先在段落/句子边界切分。 chunkSize 为 token 数上限,tokenizer 用于精确 BERT token 计数。 overlap 字符从上一块的末尾复制到下一块的开头,防止语义在块边界被切断。 返回每个块及其第一个内容段落在原文中的 rune 偏移。

func SubmitRefresh

func SubmitRefresh(novelID, chapterID int64, content string)

SubmitRefresh 提交异步向量刷新任务。若 RefreshQueue 未初始化则静默跳过。

Types

type ChapterChunkParams

type ChapterChunkParams struct {
	ChapterID     int64 // chapters.id,填入 Chunk.ChapterID
	ReadingNumber int   // 调用方从 chapter.Store 计算;仅在标题为空时用于展示
	ChapterTitle  string
	Content       string
	Summary       string
}

ChapterChunkParams 是 BuildChapterChunks 的输入参数。

type Chunk

type Chunk struct {
	ID           string
	Content      string
	ChapterID    int64  // chapters.id 外键,写入 vec 表 chapter_id 列
	ChunkType    string // "summary" / "chapter_brief" / "content"
	ChunkIndex   int
	StartRunePos int // chunk 在原始正文中的 rune 偏移
	Metadata     map[string]any
}

Chunk 是待索引的文本块,携带来源元数据。

func BuildChapterChunks

func BuildChapterChunks(params ChapterChunkParams, t *Tokenizer) []Chunk

BuildChapterChunks 为章节构建多层记忆块:summary、chapter_brief、正文分块。 tokenizer 用于按 token 数精确分块。

type Embedder

type Embedder interface {
	Embed(ctx context.Context, text string) ([]float32, error)
	EmbedBatch(ctx context.Context, texts []string) ([][]float32, error)
	Compact(ctx context.Context) error
	Dim() int
	Close() error
}

Embedder 将文本转换为向量。

type OnnxEmbedder

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

OnnxEmbedder 使用 ONNX Runtime 加载 bge-small-zh-v1.5 (int8) 模型生成 embedding。 全局仅一个实例,通过 InitEmbedder 异步初始化。

func GetEmbedder

func GetEmbedder() (*OnnxEmbedder, error)

GetEmbedder 返回全局 embedder 实例。若尚未加载完成则阻塞等待。

func TryGetEmbedder

func TryGetEmbedder() *OnnxEmbedder

TryGetEmbedder 非阻塞获取全局 embedder 实例。 若尚未初始化完成则返回 nil,不会阻塞。适用于 shutdown 等不能阻塞的场景。

func (*OnnxEmbedder) Close

func (e *OnnxEmbedder) Close() error

func (*OnnxEmbedder) Compact added in v1.6.0

func (e *OnnxEmbedder) Compact(ctx context.Context) error

Compact 在一次极小推理结束时触发 ONNX Runtime CPU arena shrink。 用于完整索引重建后的任务级收尾;普通查询和增量刷新不应逐次调用。

func (*OnnxEmbedder) Dim

func (e *OnnxEmbedder) Dim() int

func (*OnnxEmbedder) Embed

func (e *OnnxEmbedder) Embed(ctx context.Context, text string) ([]float32, error)

func (*OnnxEmbedder) EmbedBatch

func (e *OnnxEmbedder) EmbedBatch(ctx context.Context, texts []string) ([][]float32, error)

type RefreshQueue

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

RefreshQueue 异步管理向量刷新,支持去重和限速。

func GetRefreshQueue

func GetRefreshQueue() *RefreshQueue

GetRefreshQueue 返回全局 RefreshQueue,未初始化时返回 nil。

func (*RefreshQueue) RebuildAll

func (q *RefreshQueue) RebuildAll(ctx context.Context) error

RebuildAll 遍历全部小说,保证每部小说的向量索引完整:

  • vec 表全空 → RebuildNovel 首次全量重建
  • 有缺失章节 → 对缺失章节逐个增量补建(已索引章节不动)
  • 有孤儿 chunk(章节已删除的残留 / chapter_id=0)→ 批量清理

覆盖度依据:vec 表 DISTINCT chapter_id 集合 vs chapters 表实际 id 集合。 幂等且可中断续跑:重建到一半被关闭,下次启动覆盖度检查发现缺失章节继续补建。

func (*RefreshQueue) RebuildNovel

func (q *RefreshQueue) RebuildNovel(ctx context.Context, novelID int64) error

RebuildNovel 无条件全量重建一部小说的向量索引,并在任务结束后整理推理内存。

func (*RefreshQueue) Start

func (q *RefreshQueue) Start()

Start 启动后台消费者 goroutine。

func (*RefreshQueue) Stop

func (q *RefreshQueue) Stop()

Stop 取消后台消费者并等待完成。

func (*RefreshQueue) Submit

func (q *RefreshQueue) Submit(task RefreshTask)

Submit 非阻塞提交刷新任务。队列满时丢弃并记警告。

type RefreshTask

type RefreshTask struct {
	NovelID   int64
	ChapterID int64
	Content   string
}

RefreshTask 是一次向量刷新任务,以 chapters.id 稳定定位章节。

type SearchFilter

type SearchFilter struct {
	ChapterIDs []int64 // 按 chapters.id 过滤
	ChunkTypes []string
}

SearchFilter 限定检索范围。

type SearchResult

type SearchResult struct {
	ChunkID      string
	Content      string
	SourceType   string
	ChapterID    int64 // 从 vec 表 chapter_id 列读出
	StartRunePos int   // chunk 在原始正文中的 rune 偏移
	Distance     float64
	Relevance    float64
	Embedding    []float32 // 512维向量,用于MMR多样性计算
}

SearchResult 是单条检索结果。

func MMRRerank

func MMRRerank(query string, candidates []SearchResult, k int, lambda float64) []SearchResult

MMRRerank 对检索结果进行最大边际相关性重排序。 lambda 控制相关性(λ)和多样性(1-λ)的权重,通常取 0.7。 使用向量余弦相似度衡量文本间的多样性,对中文友好。 返回最多 k 个结果。candidates 不会被修改。

type Tokenizer

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

Tokenizer 是 BERT WordPiece tokenizer,仅依赖词表文件(~107KB), 不依赖 ONNX Runtime,可在模型加载前使用。

func GetTokenizer

func GetTokenizer() *Tokenizer

GetTokenizer 返回全局 tokenizer 实例。InitEmbedder 调用后即可使用, 未调用 InitEmbedder 时返回 nil。

func NewTokenizer

func NewTokenizer(vocabPath string) (*Tokenizer, error)

NewTokenizer 从 vocab.txt 加载词表。若缺失 [UNK] 则报错。

func (*Tokenizer) TokenCount

func (t *Tokenizer) TokenCount(text string) int

TokenCount 返回文本的 token 数量,供分块使用。

func (*Tokenizer) Tokenize

func (t *Tokenizer) Tokenize(text string) []int

Tokenize 将文本转换为 token ID 序列。不含特殊 token,不做长度截断。

type VectorStore

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

VectorStore 使用 sqlite-vec 管理向量索引,每部小说一张 vec0 虚拟表。

func GetVectorStore

func GetVectorStore() *VectorStore

GetVectorStore 返回全局 VectorStore,未初始化时返回 nil。

func NewVectorStore

func NewVectorStore(db *sql.DB, embedder Embedder, log *slog.Logger) *VectorStore

NewVectorStore 创建向量存储。db 应为已启用 sqlite-vec 扩展的 SQLite 连接。

func (*VectorStore) CompactEmbeddingMemory added in v1.6.0

func (s *VectorStore) CompactEmbeddingMemory(ctx context.Context) error

CompactEmbeddingMemory 释放完整重建留下的 ONNX CPU arena 扩展块。 普通查询和增量索引不应逐次调用,以免反复释放和重新分配推理内存。

func (*VectorStore) CountChunks

func (s *VectorStore) CountChunks(ctx context.Context, novelID int64) (int, error)

CountChunks 返回指定小说的向量块总数。表不存在时自动创建后返回 0。

func (*VectorStore) DeleteChapterChunks

func (s *VectorStore) DeleteChapterChunks(ctx context.Context, novelID int64, chapterID int64) error

DeleteChapterChunks 删除指定章节的所有向量块。 参数 chapterID 为 chapters.id。

func (*VectorStore) DeleteNovel

func (s *VectorStore) DeleteNovel(ctx context.Context, novelID int64) error

DeleteNovel 删除整部小说的向量表。

func (*VectorStore) DeleteOrphanChunks added in v1.6.0

func (s *VectorStore) DeleteOrphanChunks(ctx context.Context, novelID int64, validChapterIDs []int64) error

DeleteOrphanChunks 删除向量表中 chapter_id 不在有效列表内的行(孤儿 chunk)。 典型场景:章节被删除后其向量残留,或迁移期写入的 chapter_id=0 未知归属行。 不触发 DROP/CREATE,直接 DELETE;validChapterIDs 为空时清空整表。

func (*VectorStore) DistinctChapterIDs added in v1.6.0

func (s *VectorStore) DistinctChapterIDs(ctx context.Context, novelID int64) ([]int64, error)

DistinctChapterIDs 返回向量表中已索引的去重章节 id 集合。 供 RebuildAll 覆盖度检查使用:与 chapters 表实际 id 对比, 找出缺失章节(增量补建)和孤儿 chunk(清理)。

func (*VectorStore) IndexChunks

func (s *VectorStore) IndexChunks(ctx context.Context, novelID int64, chunks []Chunk) error

IndexChunks 将文本块批量生成 embedding 并在事务中写入向量表。

func (*VectorStore) Search

func (s *VectorStore) Search(ctx context.Context, novelID int64, query string, topK int, filter *SearchFilter) ([]SearchResult, error)

Search 在指定小说的向量索引中执行语义检索。

Jump to

Keyboard shortcuts

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