- Home
- Plugins
- Tools & Capabilities
- dsh-folder-search
dsh-folder-search
voyager77twt/dsh-folder-search
Search local Word, PDF, PPT, and Excel folders for exam questions and export selected questions to a Word paper.
Install
dsh plugin --profile web add github:voyager77twt/dsh-folder-searchREADME
本地文件夹检索模式(实验)
给 DSH 新建会话增加一个「本地文件夹检索模式」:在本地 Word / PDF / PPT / Excel 文件夹里按关键词找内容,回答哪些文件、哪些位置有命中;也可以把库里的题组一套新卷。
- 包名:
dsh-folder-search - 版本:
0.5.31 - 作者:七七(Voyager77Twt)
- 许可:MIT
- 兼容:DSH
>= 0.2.0-rc.2,Node>= 22.19 .doc/.ppt/.rtf转换需要 Windows + 本机 Office
解析和检索都在插件内部完成,只把命中片段和位置送进模型上下文,不把整份文件塞给模型。
快速开始
- 打开 设置 → 本地搜索设置;
- 在「数据库与索引库位置」填写题库文件夹的绝对路径;
- 保存后插件自动开始建索引,可在「索引库状态」查看进度;
- 新建会话,模式选「本地文件夹检索模式」;
- 直接提问,例如:
搜索“侯氏制碱法”相关的题目,给文件和位置。
设置页只在第一次需要填路径。之后新会话会直接从设置读取题库位置,不再先问。
数据库与索引库位置
| 设置 | 默认 | 说明 |
|---|---|---|
| 题库位置 | 空 | 题库文件夹绝对路径。填好后新会话直接使用;为空时才会在对话里询问。 |
| 索引库位置 | 空 | 索引缓存目录;留空使用 %LOCALAPPDATA%\dsh-library-search。保存时会把旧索引复制到新位置,成功后删除旧目录。 |
| 建库并发数 | 3 | .docx / .pdf / .xlsx 等并行抽取的数量,1–8。.doc / .ppt / .rtf 仍走 Word/PowerPoint,串行,避免 Office 冲突。 |
| 单文件上限(MB) | 200 | 超过此大小的文件直接跳过。大型图片汇编 docx 可调到 200–500,内存峰值也会增加。 |
保存路径后:
- 修改题库位置:重新建库;
- 修改索引库位置:自动迁移索引;
- 修改单文件上限:也会触发一次建库,重新尝试之前因大小被跳过的文件。
索引状态接口:/api/dsh-folder-search/index(GET 查进度,POST action=build 开始/继续)。
四类结果与兜底
检索结果可能来自四条路径,分开统计和输出:
| 类型 | 含义 | 使用哪组输出上限 |
|---|---|---|
| 直接命中(原词) | 用户原词在文件中出现 | 原词检索·输出上限 |
| 自动扩展命中 | 内置词表或自定义词表把关键词扩成关联词后命中 | 自动扩展输出 |
| 强关联命中 | 只命中了模型给的强关联词 | 强关联输出 |
| 一般关联命中 | 模型补充的一般关联词;默认只补段落,开启设置后才可带文件 | 与自动扩展共用文件数;位置/片段用关联词输出 |
零命中兜底
如果:
直接命中 = 0 且 强关联命中 = 0
那么即使「允许一般关联词带入文件」是关闭的,也会自动启用兜底:
- 自动扩展和一般关联都可以带入文件;
- 文件上限 =
强关联输出·最多文件数 + 自动扩展输出·最多文件数; all按 5000 处理;- 先输出自动词表文件,再输出一般关联文件;
- 最终仍受「最终输出文件数」限制。
输出会显示:
兜底关联命中:自动词表 N + 一般关联 M 个文件
兜底命中·自动词表
兜底命中·一般关联
这解决的是“空气除硫”这类原词没有、但标准词是“脱硫”的问题,避免模型为了换词连续搜索。
搜索结果的分段顺序
最终输出顺序固定为:
直接命中 → 自动扩展 → 强关联 → 一般关联
兜底时:
自动扩展 → 一般关联
最终输出文件数 在各类别自身上限之后统一截断,所以直接命中会优先占用名额。
设置项逐项说明
1. 原词输出
| 设置 | 默认 | 详细作用与建议 |
|---|---|---|
| 原词检索·输出文件数 | 全部 | 直接命中的文件最多列多少个。“全部”最全也最贵;想压费用先改这一项。 |
| 原词检索·每文件位置数 | 4 | 每个直接命中文件最多列几处命中;总数仍会显示“另有 N 处”。想看得全可调到 10–50,想省 token 调到 2。 |
| 原词检索·片段长度 | 90 | 每处命中截取多少字符。45–60 更省,但可能看不全题干。 |
2. 自动词表与自定义词表
| 设置 | 默认 | 详细作用与建议 |
|---|---|---|
| 自动关联词扩展 | 开 | 是否使用内置词表和自定义词表扩词。关闭后仍可使用模型给的强关联/一般关联词。 |
| 关联词数量上限 | 4 | 每个关键词最多几个扩展词(不含原词),自动词表和一般关联共用这个数量。 |
| 自定义词表 | 空 | 每行 关键词=关联词1,关联词2。同一个关键词:自定义词优先,剩余名额用内置词表补齐;无关条目不会参与检索。 |
| 自动扩展输出·最多文件数 | 全部 | 仅自动扩展命中的文件上限。注意:普通输出文件数为“全部”时,这里也建议设数字,否则容易一次列很多。 |
| 自动扩展输出·每文件位置数 | 2 | 自动扩展文件每文件最多几处。 |
| 自动扩展输出·片段长度 | 45 | 自动扩展文件每处片段字符数。 |
自定义词表示例:
空气除硫=脱硫
沉淀溶解平衡=Ksp,溶度积
3. 强关联词
强关联词由模型在第一次检索前自检后给出。允许:
- 人物、旧称、别名、英文缩写、简称;
- 近义词、标准术语(例如把“脱硫”作为“空气除硫”的强关联词)。
不允许父类/领域词。工具仍会做广度闸门。
| 设置 | 默认 | 详细作用与建议 |
|---|---|---|
| 强关联词 | 开 | 是否接受模型给出的 strongTerms。关闭后完全忽略。 |
| 强关联词上限 | 1 | 每次最多使用几个强关联词。默认 1;不建议一次放很多宽泛词。 |
| 强关联降级判定 | all | 可选:factor(直接命中倍数)、files(固定文件数)、ratio(全库占比)、domain(领域词)、all(任一,默认)。 |
| 强关联倍数阈值 | 2 | 直接命中文件数 >5 时,强关联词单独命中超过“直接命中数 × 倍数”就降级。 |
| 强关联固定文件数 | 50 | 仅在 files 模式下生效:超过这个文件数降级。 |
| 强关联占比阈值(%) | 20 | 直接命中文件数 >5 时,强关联词命中文件占全库比例超过该值就降级。 |
| 强关联输出·最多文件数 | 全部 | 仅强关联命中的文件上限。兜底时也参与“强关联上限 + 自动扩展上限”的计算。 |
| 强关联输出·每文件位置数 | 2 | 强关联文件每文件最多几处。 |
| 强关联输出·片段长度 | 45 | 强关联文件每处片段字符数。 |
| 降级后重复搜索 | 关 | 强关联词被降级时,是否用剩余强关联词再搜一次;仍在本工具调用内。 |
| 最多重复次数 | 1 | 重复搜索最多几遍,0–5。 |
闸门规则:
- 直接命中文件数 ≤ 5:2 倍规则和 20% 规则不启用;
- 领域词结尾规则仍生效;
- 只保留最窄的 1 个强关联词;
- 被降级的词不再带入新文件,已命中原词的文件保留;
- 结果顶部会注明降级词。
领域词后缀:
工业 / 产业 / 行业 / 领域 / 技术 / 方法 / 工艺 / 生产 / 应用 / 研究 /
化学 / 反应 / 原理 / 实验 / 流程 / 装置 / 设备 / 材料 / 物质 / 题目 / 试题
4. 一般关联词
| 设置 | 默认 | 详细作用与建议 |
|---|---|---|
| 一般关联词 | 开 | 是否接受模型给出的 generalTerms。关闭后模型补充的一般关联词不参与检索。 |
| 允许一般关联词带入文件 | 关 | 开启后:自动词表文件名额未满时,一般关联词可以补文件,和自动扩展共用文件上限,优先自动词表。零命中兜底时即使关闭也自动带入。 |
一般关联词默认是“段落补充器”,不是“文件发现器”,所以“纯碱”这类泛词不会单独带出大量无关文件。只有开启或零命中兜底时才会带文件。
5. 搜索步骤与其他
| 设置 | 默认 | 详细作用与建议 |
|---|---|---|
| 自动补索引 | 开 | 检索前检查题库更新并补缓存;关闭后只用旧缓存,新文件不会出现。 |
| 匹配范围 | 同文件 | 同文件=关键词在同一个文件里出现即可;同段/页=必须同一段、同一页、同一幻灯片或同一单元格。越严越省,但可能漏掉分散在不同页的关键词。 |
| 显示命中片段 | 开 | 关闭后只给文件和位置,不回传片段,最省 token。 |
| 显示题号 | 开 | 在位置后标“题号 N(文中编号)”。汇编卷题号可能重排,以文件和片段为准。 |
| 合并重复文件 | 关 | 合并命中内容完全相同的文件;会少列文件,但跨格式副本(doc/pdf)通常不会被合并。 |
| 最终输出文件数 | 全部 | 所有类别合计最多输出多少个文件;有上限时按直接→自动→强关联→一般关联顺序保留。 |
| 目录默认文件数 | 60 | library_outline 一次列多少文件,只影响目录输出。 |
6. 搜索步骤执行顺序
一次工具调用内按顺序执行:
| 步骤 | 执行次数 | 作用 |
|---|---|---|
| 1. 自动补索引 | 1 次(可关) | 检查题库更新并补缓存 |
| 2. 原词检索 | 1 次(必开) | 用用户原词搜索 |
| 3. 强关联词 | 1 次,与第 2 步合并 | 模型自检后填 1 个专名/近义词/标准术语 |
| 4. 自动关联词扩展 | 1 次,与第 2 步合并 | 内置词表 + 自定义词表;自定义优先 |
| 5. 一般关联词 | 1 次,与第 2 步合并 | 默认只补段落;开启/兜底时可补文件 |
| 6. 匹配范围 | 1 次 | 同文件 / 同段页 |
| 7. 显示片段 | 1 次 | 关闭后只给位置 |
| 8. 显示题号 | 1 次 | 标“题号 N(文中编号)” |
| 9. 合并重复文件 | 1 次 | 合并相同内容文件 |
| 10. 降级后重复搜索 | 0–5 次 | 强关联被降级时用剩余强关联词再搜 |
每个启用的步骤只执行 1 次(第 10 步按设置次数),不会自动无限重搜。
文本缓存与索引库
缓存位置:
%LOCALAPPDATA%\dsh-library-search\lib-<hash>\
├── manifest.json
└── docs\ ← 每个文档一个 .txt
- 每个题库根目录生成一个
lib-<hash>; - 目录名保留旧名
dsh-library-search,避免已有索引失效; - 文本缓存约为原题库的 0.4%(本机 4.5 GB → 约 20 MB);
- 缓存上限 250 MB 只统计 docs + manifest;
- 建库中的
legacy-pdf-*临时 PDF 不计入 250 MB,建库结束会删除;它们会占磁盘,但不是索引正文; - 删除
lib-*只会让下次重新抽,不会动原文件。
建库流程
- 扫描文件;
.doc/.rtf先批量转 PDF(每批 20 个),批量失败后逐文件单独转换;- 转换出的文本按段/页/幻灯片/单元格写入
docs; - 建库
sync会重试之前失败的条目,转换成功的旧版文档会从failed变成ready。
当前题库的已知失败
本机题库 1767 个文件中 1760 个已索引,剩余 7 个:
| 文件 | 原因 |
|---|---|
模拟试题/2022/一模/朝阳/朝阳区第二学期高三化学质量检测一试卷.docx | docx 损坏(invalid zip) |
期末考试/2020期中期末/2020选择.docx | docx 损坏 |
期末考试/2019期末/东城期末/18题.pptx | pptx 损坏 |
期末考试/2013期末/成绩/王莹.xlsx | 文件有密码 |
模拟试题/2020/西城一模05/2020.5西城高三化学诊断性测试试卷.doc | Word 转换失败 |
模拟试题/2013/2013房山高三一模化学试题.doc | Word 转换失败 |
模拟试题/2010一模/通州区高三年级模拟考试(一).doc | Word 转换失败 |
损坏 zip 和加密 Excel 只能修原文件;3 个 .doc 已尝试单文件 Word 转换,仍失败,通常是本机 Word 打不开。
支持范围
| 类型 | 支持 |
|---|---|
.docx | 全文(段落 + 标题路径) |
.pdf | 全文(页码;扫描件无文本会标注) |
.doc / .rtf | 本机 Word 转 PDF 后全文 |
.pptx | 全文(第 N 张) |
.ppt | 本机 PowerPoint 转 PDF 后全文 |
.xlsx / .xls | 单元格文本(Sheet!B12) |
.txt / .md / .csv | 逐行 |
.rar / .zip / 图片 / 视频 | 仅文件名 |
工具
| 工具 | 用途 |
|---|---|
library_search | 关键词检索;返回文件、位置、片段、四类统计 |
library_outline | 目录、大题/题号位置 |
library_read | 读完整题目(可用 question 限定) |
library_export | 组卷并导出 .docx |
library_status | 检查索引状态 |
library_index | 批量建索引 |
library_index_export | 导出索引包 zip |
library_index_import | 导入索引包,按大小/时间校验 |
缓存会不会导致搜索不全?
缓存本身不会丢命中:它是抽取文本的完整副本,检索时逐行扫描,没有采样、摘要或截断。
| 对照 | 样本 | 结果 |
|---|---|---|
| 缓存检索 vs 每次直接解析原文件 | 2019年 70 个文件,3 个关键词 | 命中文件集合完全一致,missing=0 |
| 缓存检索 vs Word 自身文本 | 20 个 .docx,3 个关键词 | missing=0,extra=0 |
仍可能搜不全的情况:
- 索引还没建完;
- Word 页眉/页脚/脚注/公式、PPT 备注、Excel 公式与批注、扫描 PDF 的图片文字;
- 压缩包/图片/视频只索引文件名;
- 缓存上限到了;
- 文件改动但 mtime 与大小都没变(可用
refresh: "force"重建)。
限制
- 扫描 PDF、图片文字不索引;
.doc/.ppt转换依赖本机 Office,可能较慢;- 去重只比较已显示的前几条 block,Word/PDF 跨格式副本通常不会互相合并;
- 强关联词闸门和兜底是启发式规则,不能保证模型一定想到正确专名;
- 组卷是实验功能,导出前要自己核对题目和答案;
- 一般关联词兜底可能一次带出较多文件,建议同时给「强关联输出·最多文件数」和「最终输出文件数」设数字。
开发
node tests/_static-audit.mjs # 语法、清单、设置键、路由、分类/上限/兜底
pnpm pack # 生成 dsh-folder-search-<version>.tgz
目录:
lib/index.js 工具注册、配置
lib/search.js 检索、分类、强关联闸门、兜底、渲染
lib/indexer.js 增量索引、缓存、并发
lib/extract.js docx/pdf/pptx/xlsx/文本抽取
lib/legacy-batch.js 旧版 Office 批量/单文件转换
lib/outline.js 目录
lib/docx-writer.js 组卷导出
lib/client.js 设置页
lib/settings-store.js 设置默认值与持久化
lib/settings-host.js 设置接口、建库任务、迁移
cordis.patch.yml 模式预设
Related plugins
archify (deepseek-harness)
tt-a1i/archify
WeKnora (dsh-weknora)
tencent/weknora
weknora
tencent/weknora
BrowserSkill (dsh-plugin-browserskill)
tencent/browserskill