Hyperresearch FTS5全文搜索实现详解:状态感知的排序策略让检索更聪明
【免费下载链接】hyperresearchAgent-driven research knowledge base. Agents collect, search, and synthesize web research into a persistent, searchable wiki.项目地址: https://gitcode.com/GitHub_Trending/hy/hyperresearch
Hyperresearch是一个由 AI Agent 驱动的研究知识库:Agent 负责收集、抓取并综合网络研究资料,沉淀为持久化、可全文搜索的 Wiki。它的核心检索能力建立在 SQLite 的FTS5 全文搜索引擎之上——但真正让它与众不同的是状态感知的排序策略:同一个关键词,"常青笔记"会被加权置顶,"已弃用"的内容则自动沉底。本文带你无需深入代码,也能看懂这套搜索是怎么工作的。
📐 索引层:一张表管住全部笔记
Hyperresearch 在初始化数据库时创建了一张 FTS5 虚拟表notes_fts(见 core/db.py),它把每篇笔记拆成 5 个字段分别建索引:
| 字段 | 内容 | 是否参与排序权重 |
|---|---|---|
id | 笔记 ID | 否(仅用于关联主表) |
title | 标题 | ✅ 权重最高 |
body_plain | 正文纯文本 | ✅ 权重最低 |
tags | 标签 | ✅ |
aliases | 别名 | ✅ |
分词器选用porter unicode61:既支持中文等 Unicode 字符,又能做英文词干还原——搜 "running" 能匹配到 "run"。笔记内容每次同步都会增量刷新这张索引表(见 core/sync.py),保证搜索永远是"所见即所存"。
🔍 查询预处理:让"随手一搜"变成合法搜索
用户输入往往很随意,preprocess_query函数(search/fts.py)在查询送入 FTS5 前做了三件贴心事:
- 前缀匹配:搜
python自动变成python*,能同时命中 Python、Pythonic、pythonic 等词形,不必拼完整单词; - 字母数字粘合拆分:
gpt4o会被拆成gpt 4 o,mamba3拆成mamba 3——这对搜模型名、版本号特别有用; - 短语与操作符保护:双引号短语保持精确匹配,
AND / OR / NOT / NEAR等 FTS5 原生操作符则原样直通,高级用户不被"好心办坏事"。
所有裸词还会被剥掉* ( ) { } "等会破坏 FTS5 语法的特殊字符——这意味着普通用户随便打什么,都不会把搜索引擎打崩。
⚖️ 状态感知排序:本文的核心
单纯的全文搜索只回答"哪里提到了这个词",而研究知识库还需要回答"哪个结果现在仍然可信"。Hyperresearch 的排序分三层,前两层由 SQL 直接完成:
第一层:BM25 字段加权
SQLite FTS5 内置的bm25()打分函数按字段加权(权重可在配置中调整,默认值见 core/config.py):
标题 ×10 > 标签 ×5 > 别名 ×3 > 正文 ×1
直觉很简单:标题命中比正文命中"更相关",一篇笔记标题就写着你要找的关键词,理应排在只在正文角落提了一嘴的笔记前面。
第二层:status 状态调整(状态感知的灵魂)
每篇笔记都有生命周期状态,取出 BM25 排序后的结果集,再按状态对分数做乘性调整(search/fts.py):
| 笔记状态 | 含义 | 分数调整(默认) |
|---|---|---|
🌲evergreen | 常青内容,长期有效 | ×1.5 加权 |
⚠️stale | 可能过时 | ×0.7 轻微惩罚 |
🗑deprecated | 已弃用 | ×0.3 大幅惩罚 |
也就是说,一篇弃用笔记哪怕 BM25 相关性再高,分数也会被压到只有常青笔记的三分之一左右,自动沉到结果列表底部。这正是"状态感知"四个字的含义:排序策略感知了知识的新鲜度与可信度,而不只是字面匹配。
第三层:来源质量重排(可选)
加上--ranked参数后,再叠加一层"来源质量分"重排:分数乘以0.5 + quality_score。设计很克制——没有质量分的笔记按中性 1.0 倍处理,保证它们不会被冤枉;而顶级权威来源(≈1.0 分)的笔记得分约为被撤稿来源(≈0.05 分)的近三倍。相关性是入场券,权威性决定最终名次。
🛡️ 错误处理设计:坏查询绝不伪装成"没有结果"
这是实现里一个容易被忽略但很关键的细节。传统写法中,查询语法错误、索引损坏都会被吞掉、返回空列表——用户看到"无结果",根本分不清是"库里没有"还是"系统坏了"。
Hyperresearch 明确区分了三种情况(配套测试见 tests/test_search/test_fts.py):
- 无可搜索词(如
***、空查询)→ 抛出SearchQueryError,提示"请至少提供一个词"; - 合法查询但无命中→ 正常返回空列表,这才是真正的"没搜到";
- FTS 索引损坏/缺失→ 直接向上抛出底层错误,绝不伪装成空结果。
对"知识必须可信"的研究工具来说,"查无结果"和"系统坏了"是两种性质完全不同的信号,这个设计保证了前者的语义永远干净。
🧰 过滤组合拳:从全文搜索到精确定位
全文匹配之外,search/filters.py 提供了结构化过滤器,与 FTS 查询叠加成WHERE条件:
- 属性过滤:标签、状态、笔记类型、认知层级(
tier)、内容种类(content_type)、时间范围、路径通配符、字数区间; - 图谱过滤:
linked_from/linked_to沿双向链接找笔记、min_inbound找被引用次数达标的"枢纽笔记"、has_backlinks只留有反链的内容——这让搜索从"文字平面"延伸到了知识图谱维度。
🚀 快速上手
安装后,在任何包含 vault 的目录下:
# 基础全文搜索(默认 20 条,自动应用状态感知排序) hyper search python async # 叠加标签与状态过滤 hyper search memory --tag rust --status evergreen # 启用来源质量重排 + JSON 输出(Agent 常用) hyper search transformer --ranked --json命令行入口在 cli/search.py,还支持--semantic语义混合搜索(用 RRF 把向量相似度与 FTS 排名融合)以及--max-tokens按 Token 预算截断结果,专为 Agent 消费场景设计。
📂 相关文件导航
- 核心搜索实现:src/hyperresearch/search/fts.py
- 结构化过滤器:src/hyperresearch/search/filters.py
- FTS5 索引表定义:src/hyperresearch/core/db.py
- 排序权重默认配置:src/hyperresearch/core/config.py
- 搜索命令行入口:src/hyperresearch/cli/search.py
- 行为测试用例:tests/test_search/test_fts.py
总结
Hyperresearch 的 FTS5 全文搜索 =宽进严出的查询预处理+BM25 字段加权+状态感知的生命周期调整+可选的来源质量重排,再配上"错误绝不伪装成空结果"的严谨语义。四层排序层层递进,让研究知识库的每一次搜索都同时回答"哪里提到了"与"哪个结果值得信"——这就是状态感知排序策略的全部价值。
【免费下载链接】hyperresearchAgent-driven research knowledge base. Agents collect, search, and synthesize web research into a persistent, searchable wiki.项目地址: https://gitcode.com/GitHub_Trending/hy/hyperresearch
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考