本文对 ModelScope 开源项目 Sirchmunk 进行系统性的架构分析,重点剖析其"无索引检索"与"自进化知识图谱"两大核心设计理念的技术实现。
一、引言:RAG 的瓶颈与 Sirchmunk 的破局
检索增强生成(Retrieval-Augmented Generation, RAG)已成为大语言模型应用的主流范式。然而,传统 RAG 管线存在若干结构性瓶颈:向量嵌入的离线构建周期长,数据更新后需要批量重建索引,向量近似匹配不可避免地引入信息损失,且 VectorDB、GraphDB 等基础设施的搭建与维护成本高昂。
Sirchmunk 是由 ModelScope 团队开源的一款智能搜索引擎(Apache 2.0 协议),其核心主张是完全绕过向量数据库与预索引流程,直接面向原始数据进行检索与推理。该项目自 2026 年 1 月发布以来,历经多个版本迭代,已形成一套完整的检索-推理-进化闭环体系。本文将从工程架构视角对其进行深入分析。
二、系统总览:核心模块与分层架构
Sirchmunk 的代码库采用 Python 实现(后端),配合 Next.js 14 构建前端界面,整体技术栈包括 FastAPI、DuckDB、ripgrep-all 等。其源码组织呈现清晰的分层结构:
bash
src/sirchmunk/
├── search.py # 搜索编排器(AgenticSearch)
├── agentic/ # ReAct 智能体模块
├── learnings/ # LENS 框架核心组件
│ ├── evidence_processor.py # 蒙特卡洛证据采样
│ ├── multi_arm_navigator.py # 多臂导航器
│ ├── knowledge_base.py # 知识构建器
│ ├── statistical_stop_decider.py # 统计停止决策
│ └── lens_config.py # LENS 配置中心
├── retrieve/ # 底层检索层(ripgrep-all 封装)
├── scheduler/ # 知识进化调度器
├── schema/ # 数据模型定义
├── storage/ # DuckDB 持久化层
└── api/ # FastAPI 服务层
该架构可以归纳为三层设计:
| 层次 | 职责 | 关键组件 |
|---|---|---|
| 检索层 | 无索引的原始文件检索 | GrepRetriever(ripgrep-all 封装) |
| 推理层 | 预算约束证据探索与答案合成 | AgenticSearch、ReActSearchAgent、LENS 框架 |
| 知识层 | 自进化知识聚类管理 | KnowledgeBase、KnowledgeStorage、KnowledgeEvolver |
三、检索层:GrepRetriever 的无索引检索设计
3.1 设计哲学
传统 RAG 系统在数据入库前需要经过文档解析、分块(Chunking)、向量嵌入、索引写入等多道预处理工序。Sirchmunk 的检索层则选择了一条截然不同的路线:直接基于 ripgrep-all(rga)和 ripgrep(rg)对原始文件执行正则匹配检索。
GrepRetriever 作为检索层的核心实现,封装了 rga 的异步调用能力,支持 AND/OR/NOT 多种逻辑组合检索,并提供基于 TF-IDF 思想的结果重排序。该设计的工程优势包括:
- 零预处理延迟:文件放入搜索路径即可被检索,无需等待索引构建
- 数据零损失:检索直接面向原始文件内容,不存在向量近似导致的信息丢失
- 格式广泛兼容:依赖 rga 的多格式转换能力(PDF、DOCX、XLSX 等),辅以 Kreuzberg 文本提取作为回退
3.2 多层检索策略
在 v0.2.0 版本中,Sirchmunk 引入了多路 DEEP 检索(Multi-path Retrieval)架构,并行融合多条检索路径:
- 词法检索路径(Lexical):基于关键词的 rga/rg 文本匹配
- 精确实体路径(Exact Entity):针对专有名词、编号等进行精确匹配
- 目录扫描路径(Directory):基于文件名和目录结构进行路由
- 文档结构路径(Structure):利用文档树索引(Document Tree Index)进行层次化导航
- 跨文档主题图路径(Topic Map):基于编译产物中的主题映射进行跨文件关联
这些路径的结果通过置信度加权的 RRF(Reciprocal Rank Fusion)进行融合。当高置信度的单文件查询被识别时,系统会触发"软路由收缩"(Soft Route Collapse)快通道,在不损失答案质量的前提下减少延迟与 Token 开销。
3.3 鲁棒性工程
为应对大规模语料场景,GrepRetriever 实现了一系列成本控制机制:
- 分层检索:优先使用轻量级的 rg 进行纯文本检索,仅在涉及富格式文件时调用 rga
- 单文件大小上限 :通过
GREP_MAX_FILESIZE_MB跳过过大的文件 - 单文件匹配上限 :通过
GREP_MAX_MATCHES_PER_FILE防止单文件匹配膨胀 - rga 断路器:rga 超时或失败后自动回退到 rg,并设置退避窗口(Backoff)
- 并发控制:通过信号量(Semaphore)控制 rga 和 rg 的并发进程数
四、推理层:LENS 框架与智能体搜索
4.1 LENS 框架概述
LENS(Latent Evidence Navigation and Search)是 Sirchmunk 在 v0.1.0 版本中引入的核心检索框架,其核心思想是将证据发现建模为一个预算约束的序贯决策问题。
与传统 RAG 的"分块-嵌入-检索-拼接"流水线不同,LENS 将相关证据视为由查询条件决定的隐式对象:系统先用低成本信号形成候选证据区域的先验,再将 LLM 调用预算投入到信息量最大的观测位置。
其工作流程分为三层:
markdown
低成本先验(词法锚点 + 目录结构 + 历史知识 + 编译摘要)
↓
预算约束序贯推断(候选区域提出 → LLM Oracle 观测 → Belief State 更新 → 停止判断)
↓
证据整合与答案合成(源可追溯证据集 → 答案生成 → 知识持久化)
4.2 蒙特卡洛证据采样(MonteCarloEvidenceSampling)
LENS 的证据发现过程本质上是一个多轮蒙特卡洛采样过程,由 LensEvidenceSampler(别名 MonteCarloEvidenceSampling)实现。
第一轮(探索阶段):
- 使用 RapidFuzz 进行模糊锚点定位(Fuzzy Anchor),基于滑动窗口计算查询与文档片段的相似度
- 辅以分层随机采样(Stratified Supplement),防止关键词匹配盲区
后续轮次(利用阶段):
- 以上一轮高分样本为种子,执行高斯重要性采样(Gaussian Importance Sampling)
- Sigma 参数逐轮衰减,搜索范围逐步收敛
每个采样窗口由 LLM 评估其相关性(0-10 分),最终取 Top-K 高分区域进行上下文扩展和摘要生成。
4.3 多臂导航器(MultiArmNavigator)
当 LENS 的 enable_multi_arm 特性开启时,文档空间被划分为 K 个独立探索臂(Arm),采用 Information-Directed Sampling(IDS)策略进行预算分配。
每个臂维护一个简化的 Normal-Normal 共轭后验模型:
- 后验均值:观测分数的均值
- 后验方差:样本方差加先验正则项
- 置信区间:正态近似的分位数区间
预算分配策略采用 softmax(posterior_variance) 加权,高不确定性的臂获得更多采样预算。当两个臂的置信区间重叠度超过阈值且中心距离小于 2σ 时,触发臂合并(Arm Merge),将弱臂的观测合并到强臂中。
4.4 统计停止决策(StatisticalStopDecider)
LENS 的采样循环何时终止是一个关键决策。StatisticalStopDecider 实现了基于贝叶斯后验置信区间的四条件停止规则(按优先级排列):
- 统计置信度:Normal-Normal 共轭更新后的后验置信区间下界 > 阈值
- 多源完备性:对于多跳查询,检查年份维度覆盖和位置多样性
- 信息价值衰减:Top-5 分数的样本方差 + 轮次衰减因子 < 阈值
- 预算耗尽:剩余 Token 预算不足
其贝叶斯后验更新遵循标准的共轭正态-正态模型:
scss
精度_后验 = 精度_先验 + n × 精度_观测
均值_后验 = (精度_先验 × 均值_先验 + 精度_观测 × Σ(scores)) / 精度_后验
方差_后验 = 1 / 精度_后验
4.5 ReAct 智能体搜索
在 DEEP 搜索模式下,Sirchmunk 采用 ReAct(Reasoning + Acting)范式实现迭代式搜索。ReActSearchAgent 维护一个状态化的对话会话,在每次迭代中:
- LLM 推理当前需要什么信息
- 选择并调用检索工具(keyword_search、read_file_content、dir_scan 等)
- 观测工具返回结果
- 决定继续搜索或输出最终答案
该智能体支持"先验预热"(Prior-Warmed)启动:LENS 的并行先验(Phase 1-3)预检索的证据作为首条观测注入对话上下文,使答案合成从高质量证据起步,而非从空白开始。
五、知识层:自进化知识聚类体系
5.1 KnowledgeCluster 数据模型
每次搜索完成后,系统不会丢弃检索结果,而是将其凝练为一个 KnowledgeCluster------一个结构化、可复用的知识单元。其核心字段包括:
| 字段 | 用途 |
|---|---|
evidences |
源可追溯的证据单元列表,包含文件路径、摘要和原始文本片段 |
content |
LLM 合成的结构化 Markdown 分析 |
patterns |
3-5 条从证据中提炼的设计原则或核心机制 |
confidence |
共识评分 0, 1 |
queries |
贡献或复用该聚类的历史查询(FIFO,最多 5 条) |
hotness |
反映查询频率和时效性的活跃度评分 |
embedding |
基于累积查询生成的嵌入向量,用于语义检索 |
lifecycle |
生命周期状态:EMERGING / STABLE / CONTESTED / DEPRECATED / META |
聚类 ID 采用确定性的 SHA256 哈希生成(C{sha256[:10]}),确保相同内容的聚类具有全局唯一且可重现的标识。
5.2 知识复用机制
在每次搜索开始前,系统会将当前查询嵌入为向量,并与所有已存储聚类进行余弦相似度比对。若发现相似度 ≥ 0.85 的匹配,直接返回已有聚类并更新其元数据:
- 将新查询追加到查询历史(FIFO,最多 5 条)
- 提升热度(+0.1,上限 1.0)
- 基于更新后的查询集重新计算嵌入向量
- 更新版本号和时间戳
这种查询驱动的嵌入策略确保聚类的语义覆盖范围与用户的实际提问方式对齐,而非文档的书写方式。
5.3 KnowledgeEvolver:四阶段进化引擎
KnowledgeEvolver 是知识自进化的核心调度器,在每次搜索完成后以 fire-and-forget 方式异步触发,不阻塞搜索返回。它执行四个进化阶段:
Phase 1:Connect & Merge(连接与合并)
- 触发条件:新增聚类数 ≥ 5
- 为每个新聚类寻找嵌入相似度最高的已有聚类
- 相似度 ≥ 0.90:合并两个聚类(合并查询集、重算嵌入)
- 相似度 ≥ 0.60:建立弱语义边(WeakSemanticEdge)
Phase 2:Refresh Edges(边刷新)
- 触发条件:嵌入已刷新的聚类数 ≥ 20
- 为每个嵌入已更新的聚类重新评估其与相邻聚类的语义边
Phase 3:Detect Meta Clusters(元聚类发现)
- 触发条件:步数间隔 ≥ 10 且非 META 聚类数变化 ≥ 100
- 基于 Leiden 社区检测算法在知识图谱上检测社区结构
- 为每个社区生成 META 级别的聚类,作为粗筛索引
Phase 4:Global Update(全局更新)
- 触发条件:步数间隔 ≥ 10 且非 META 聚类数变化 ≥ 500
- 重新计算所有语义边权重,移除低于阈值的失效边
- 精炼低热度、低置信度的聚类
- 重新执行 Phase 1-3 进行全局同步
进化状态通过 EvolveManifest 持久化到磁盘,支持增量恢复。锁和信号量机制保证并发安全。
六、数据持久化设计
Sirchmunk 采用 DuckDB 作为知识聚类的存储引擎,这一选择与其"轻量级、零外部依赖"的设计哲学一脉相承:
- 内存计算:DuckDB 以内存模式运行,查询延迟极低
- Parquet 持久化:定期将内存数据刷写为 Parquet 文件,实现磁盘持久化
- 原子写入:基于文件修改时间的重载机制确保多进程安全
- 嵌入向量存储:聚类嵌入向量与文本哈希一同存储,支持增量更新
bash
{SIRCHMUNK_WORK_PATH}/
├── .cache/
│ ├── history/ # 聊天会话历史
│ │ └── chat_history.db
│ ├── knowledge/ # 知识聚类
│ │ └── knowledge_clusters.parquet
│ └── evolve/ # 进化状态
│ └── manifest.json
七、部署架构
Sirchmunk 支持多种部署模式:
- Python SDK :直接通过
AgenticSearch类调用搜索能力 - CLI 命令行 :
sirchmunk search、sirchmunk serve等完整命令集 - HTTP API:基于 FastAPI 的 RESTful 接口,支持 SSE 流式输出
- MCP Server:兼容 Model Context Protocol,可与 Claude Desktop、Cursor IDE 等 AI 工具集成
- Docker:提供预构建镜像,支持 amd64/arm64 双架构
- Web UI:Next.js 14 构建的前端,集成对话、知识图谱可视化与系统监控
八、总结
Sirchmunk 的架构设计体现了对 RAG 范式的一次深层反思。它不是在传统流水线上做增量优化,而是从根本上质疑了"向量索引是检索的必要前提"这一假设。通过将检索重心从"预计算的静态索引"转移到"运行时的动态证据探索",Sirchmunk 在以下维度展现了差异化的技术路线:
- 零搭建成本:无需 VectorDB、GraphDB 等外部基础设施
- 实时数据感知:文件变更即刻生效,无需重建索引
- 源可追溯性:最终答案绑定可定位的证据区域
- 预算可控性:LLM 调用自适应投入到高价值区域,Token 开销透明可追踪
- 自进化能力:知识聚类随使用自动演化,相似查询加速响应
该项目已发布配套论文(arXiv: 2608.16185),并提供了完整的 ResearchOps 基准评测框架,包含 HotpotQA 评测、LENS 消融实验、生命周期成本核算等可复现实验流程。
本文基于 Sirchmunk v0.2.0 源码分析撰写。项目仓库:github.com/modelscope/...