← Back to skills
extension
Category: Development & EngineeringAPI key requirement unconfirmed

seekdb 混合检索知识库

用 seekdb 一个数据库完成向量召回 + 全文召回 + RRF 融合的本地知识库 Skill,面向 Agent 的文档问答与长期记忆。含单文件 CLI、实测 SQL 速查、6 类报错修复与端到端示例。

personAuthor: mydayunhubOpenAPI

seekdb 混合检索知识库(Hybrid RAG)

用 seekdb 一个数据库同时存放「原文 + 向量 + 全文索引」,一条 SQL 完成语义召回、关键词召回与 RRF 融合排序。 不需要额外部署向量库/搜索引擎,pip install seekdb 后即为嵌入式模式,数据库就是一个目录。

什么时候用

  • 给 Agent / RAG 应用做本地知识库或长期记忆,要求离线可用、无需运维。
  • 检索同时需要语义相似(近义词、改写)和精确关键词(错误码、产品名、专有名词)。
  • 需要 WHERE 标量过滤(租户、时间、类型)和检索结果在同一事务/同一张表里。
  • 不适用:千万级以上向量 + 多副本高可用集群(那需要服务器模式与专门运维)。

前置条件

pip install seekdb          # 官方嵌入式 Python 包(wheel 内置 seekdb 内核,约 54MB)
  • 支持 Linux x86_64 / macOS arm64;CPython 3.11+(wheel 提供 cp311 与 cp312-abi3)。
  • 嵌入式模式默认数据目录 ./seekdb.db,启动毫秒级,不需要端口和账号。
  • 需要真实语义向量时,再准备一个 OpenAI 兼容的 /embeddings 服务(本地 vLLM、ModelScope/百炼等平台均可), 通过环境变量注入:EMBEDDING_API_BASE、EMBEDDING_API_KEY、EMBEDDING_MODEL。

快速开始(3 步)

# 0) 准备知识库目录(.md / .txt);包内已带 5 篇示例文档 assets/demo-docs/ 可直接跑

# 1) 初始化(dim 必须与嵌入模型维度一致;演示用 256)
python scripts/seekdb_kb.py init   --db ./kb --dim 256

# 2) 建索引:切块 → 嵌入 → 写入(向量索引 + 全文索引随表创建)
python scripts/seekdb_kb.py ingest --db ./kb --docs assets/demo-docs --dim 256 --embed hash

# 3) 混合检索
python scripts/seekdb_kb.py search --db ./kb --query "混合检索 RRF 怎么融合" --mode hybrid --topk 5

输出为 JSON:hits[] 含 id / title / content / _score / _keyword_score / _semantic_score, _score 是 RRF 融合分(sum(1/(rank_constant+rank))),越大越相关。

把 --embed hash 换成 --embed api 即使用真实嵌入模型(同一批文档与查询必须用同一个模型和维度)。

工作流

  1. 确认知识源:一个目录下的 .md/.txt;单文件也行。中文文档无需预处理,全文索引用 ngram 分词器。
  2. 定维度:--dim 与嵌入模型输出维度一致(如 1024)。向量列类型 vector(DIM) 固定,改维度请换数据库目录或删表。
  3. 建库 + 入库:脚本按 --chunk(默认 400 字符,按字符切,适合中英混合)与 --overlap 切块; 同一文件重复入库会先 DELETE 旧块,可反复增量更新。
  4. 检索:三选一——
    • --mode hybrid(默认,推荐):向量 + 全文两路召回,RRF 融合;
    • --mode vector:只要语义相似;
    • --mode keyword:只要关键词命中(BM25 相关度排序)。
  5. 接生成:把 hits[].content 按 token 预算拼进提示词,交给大模型回答;需要时再加 AI_RERANK/外部 rerank 精排。

三路召回怎么选

| 场景 | 推荐模式 | 原因 | |---|---|---| | 自然语言提问、同义改写多 | hybrid | 语义召回兜底,关键词召回补精度 | | 精确名词、错误码、编号、版本号 | hybrid 或 keyword | 全文索引精确命中,向量模型不稳定 | | 文档语义相似度排序 / 聚类预览 | vector | HNSW 余弦距离快且直观 | | 关键词必须命中(强约束) | keyword + WHERE | BM25 打分 + 标量过滤 |

直接写 SQL(不经过脚本)

嵌入式模式下用 Python 直连即可(完整语法见 references/sql-cheatsheet.md):

import seekdb
inst = seekdb.open("./kb")          # 打开数据库目录
conn = seekdb.connect("test")
cur = conn.cursor()
cur.execute("select id, title from kb_chunks "
            "order by cosine_distance(embedding, '[...]') approximate limit 5")
conn.close(); inst.close()

混合检索用 JSON DSL:

SET @p = '{"query":{"match":{"content":"混合检索"}},
           "knn":{"field":"embedding","k":10,"query_vector":[...]},
           "rank":{"rrf":{"rank_constant":60,"rank_window_size":20}},
           "_source":["id","title","_keyword_score","_semantic_score"],"size":5}';
SELECT json_pretty(DBMS_HYBRID_SEARCH.SEARCH('kb_chunks', @p));

已验证的行为(seekdb 1.4 嵌入式实测)

  • 建表:vector vector(N) + vector index ... with (distance=cosine, type=hnsw, lib=vsag) + fulltext ... with parser ngram 同时存在,DDL 一次成功。
  • 写入:向量按字符串字面量 '[0.12,0.34,...]' 插入,select count(*) 正常。
  • 纯向量查询 ORDER BY cosine_distance(...) APPROXIMATE LIMIT k 返回结果,距离单调。
  • 纯全文查询 MATCH(content) AGAINST('关键词') 命中并给出 BM25 分数。
  • 混合查询 DBMS_HYBRID_SEARCH.SEARCH 返回 _score/_keyword_score/_semantic_score,RRF 融合排序正确。
  • DBMS_HYBRID_SEARCH.GET_SQL 可看到生成的 SQL(调优/排错时很有用)。

常见坑(都踩过)

  1. 混合检索表不能显式建主键:id int primary key 会报 table with user provided primary key not supported (1235),改成普通列。
  2. 向量排序必须直接在 ORDER BY 里写距离函数:order by round(cosine_distance(...),4) 会报 Using vector index without vector_sort_expr is not supported (1235);不要在排序表达式外面套函数或改用别名。
  3. MATCH 的列集合必须与某个全文索引的列完全一致:索引建在 (title, content) 上就 MATCH(title, content); 只建了复合索引时不要 MATCH(title);本 Skill 的做法是把标题拼进 content,只建 fulltext kb_ft(content)。
  4. 分词器只有 space / ngram / ik / beng:WITH PARSER simple 会报 Function simple is not defined。中文用 ngram(最稳)或 ik。
  5. 服务器模式建大向量索引前先调 ob_vector_memory_limit_percentage(嵌入式默认可用,无需设置)。
  6. 同进程重复 seekdb.open(同一个目录) 会复用实例;进程退出前调用 inst.close() 释放锁。

目录结构

seekdb-hybrid-rag/
├── SKILL.md                     # 本文件
├── scripts/seekdb_kb.py         # 单文件 CLI:init / ingest / search / stats
├── references/sql-cheatsheet.md # 实测可用的 seekdb 向量/全文/混合检索 SQL
├── references/troubleshooting.md# 报错码与修复
├── examples/demo.md             # 端到端跑通示例(含真实输出)
├── assets/demo-docs/            # 5 篇示例文档,可直接复现示例
└── LICENSE                      # Apache-2.0

生产化建议

  • 嵌入质量决定上限:hash 后端只用于冒烟与离线降级;正式使用请换真实嵌入模型(--embed api)。
  • 切块 400~800 字符、overlap 10%~20% 起步;长文先用标题/段落切分再按长度兜底。
  • 融合不一定优于单路:先用 hybrid,再用评测集(Recall@K / MRR)对比 vector、keyword,按数据分布定 rank_constant(常用 60)。
  • 需要更强精度时把候选集交给 rerank(seekdb 的 AI_RERANK 或外部 rerank 服务),召回阶段只负责覆盖率。
  • 数据量增长后:analyze table kb_chunks + optimize 类维护,必要时换服务器模式与专用向量索引参数。
<!-- OB-S:bgduPuYJjq_M09wx8zRPsw -->