Documentation
¶
Index ¶
- Constants
- func InitEmbedder(modelsDir string, log *slog.Logger)
- func InitRefreshQueue(vs *VectorStore, chStore *chapter.Store, novelStore *novel.Store, ...)
- func InitVectorStore(db *sql.DB, embedder Embedder, log *slog.Logger)
- func SplitText(text string, chunkSize, overlap int, t *Tokenizer) ([]string, []int)
- func SubmitRefresh(novelID, chapterID int64, content string)
- type ChapterChunkParams
- type Chunk
- type Embedder
- type OnnxEmbedder
- func (e *OnnxEmbedder) Close() error
- func (e *OnnxEmbedder) Compact(ctx context.Context) error
- func (e *OnnxEmbedder) Dim() int
- func (e *OnnxEmbedder) Embed(ctx context.Context, text string) ([]float32, error)
- func (e *OnnxEmbedder) EmbedBatch(ctx context.Context, texts []string) ([][]float32, error)
- type RefreshQueue
- type RefreshTask
- type SearchFilter
- type SearchResult
- type Tokenizer
- type VectorStore
- func (s *VectorStore) CompactEmbeddingMemory(ctx context.Context) error
- func (s *VectorStore) CountChunks(ctx context.Context, novelID int64) (int, error)
- func (s *VectorStore) DeleteChapterChunks(ctx context.Context, novelID int64, chapterID int64) error
- func (s *VectorStore) DeleteNovel(ctx context.Context, novelID int64) error
- func (s *VectorStore) DeleteOrphanChunks(ctx context.Context, novelID int64, validChapterIDs []int64) error
- func (s *VectorStore) DistinctChapterIDs(ctx context.Context, novelID int64) ([]int64, error)
- func (s *VectorStore) IndexChunks(ctx context.Context, novelID int64, chunks []Chunk) error
- func (s *VectorStore) Search(ctx context.Context, novelID int64, query string, topK int, ...) ([]SearchResult, error)
Constants ¶
const ( DefaultChunkSize = 420 // tokens,为 overlap 和边界效应留 92 token 余量 DefaultOverlap = 50 BriefPreviewLen = 280 )
Variables ¶
This section is empty.
Functions ¶
func InitEmbedder ¶
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 ¶
InitVectorStore 初始化全局 VectorStore,多次调用只生效一次。
func SplitText ¶
SplitText 将文本分割成指定大小的重叠块,优先在段落/句子边界切分。 chunkSize 为 token 数上限,tokenizer 用于精确 BERT token 计数。 overlap 字符从上一块的末尾复制到下一块的开头,防止语义在块边界被切断。 返回每个块及其第一个内容段落在原文中的 rune 偏移。
func SubmitRefresh ¶
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) EmbedBatch ¶
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) Submit ¶
func (q *RefreshQueue) Submit(task RefreshTask)
Submit 非阻塞提交刷新任务。队列满时丢弃并记警告。
type RefreshTask ¶
RefreshTask 是一次向量刷新任务,以 chapters.id 稳定定位章节。
type SearchFilter ¶
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 ¶
NewTokenizer 从 vocab.txt 加载词表。若缺失 [UNK] 则报错。
func (*Tokenizer) TokenCount ¶
TokenCount 返回文本的 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 ¶
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 ¶
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
DistinctChapterIDs 返回向量表中已索引的去重章节 id 集合。 供 RebuildAll 覆盖度检查使用:与 chapters 表实际 id 对比, 找出缺失章节(增量补建)和孤儿 chunk(清理)。
func (*VectorStore) IndexChunks ¶
IndexChunks 将文本块批量生成 embedding 并在事务中写入向量表。
func (*VectorStore) Search ¶
func (s *VectorStore) Search(ctx context.Context, novelID int64, query string, topK int, filter *SearchFilter) ([]SearchResult, error)
Search 在指定小说的向量索引中执行语义检索。