@ssmeo/mcp-local-rag 0.18.14 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.de.md +248 -215
- package/README.es.md +241 -215
- package/README.fr.md +249 -215
- package/README.md +207 -297
- package/README.pt-BR.md +236 -215
- package/README.zh-CN.md +133 -206
- package/dist/chunker/semantic-chunker.d.ts +23 -5
- package/dist/chunker/semantic-chunker.d.ts.map +1 -1
- package/dist/chunker/semantic-chunker.js +13 -5
- package/dist/chunker/semantic-chunker.js.map +1 -1
- package/dist/cli/common.d.ts +7 -0
- package/dist/cli/common.d.ts.map +1 -1
- package/dist/cli/common.js +26 -2
- package/dist/cli/common.js.map +1 -1
- package/dist/cli/delete.d.ts.map +1 -1
- package/dist/cli/delete.js +2 -0
- package/dist/cli/delete.js.map +1 -1
- package/dist/cli/file-collection.d.ts +2 -1
- package/dist/cli/file-collection.d.ts.map +1 -1
- package/dist/cli/file-collection.js +2 -2
- package/dist/cli/file-collection.js.map +1 -1
- package/dist/cli/ingest.d.ts +1 -0
- package/dist/cli/ingest.d.ts.map +1 -1
- package/dist/cli/ingest.js +45 -25
- package/dist/cli/ingest.js.map +1 -1
- package/dist/cli/list.d.ts.map +1 -1
- package/dist/cli/list.js +9 -13
- package/dist/cli/list.js.map +1 -1
- package/dist/cli/options.d.ts +8 -0
- package/dist/cli/options.d.ts.map +1 -1
- package/dist/cli/options.js +21 -0
- package/dist/cli/options.js.map +1 -1
- package/dist/cli/query.d.ts.map +1 -1
- package/dist/cli/query.js +2 -1
- package/dist/cli/query.js.map +1 -1
- package/dist/cli/read-neighbors.d.ts.map +1 -1
- package/dist/cli/read-neighbors.js +1 -0
- package/dist/cli/read-neighbors.js.map +1 -1
- package/dist/cli/relocate.d.ts +3 -0
- package/dist/cli/relocate.d.ts.map +1 -0
- package/dist/cli/relocate.js +135 -0
- package/dist/cli/relocate.js.map +1 -0
- package/dist/cli/sync.d.ts.map +1 -1
- package/dist/cli/sync.js +17 -8
- package/dist/cli/sync.js.map +1 -1
- package/dist/cli-main.d.ts +1 -1
- package/dist/cli-main.d.ts.map +1 -1
- package/dist/cli-main.js +5 -0
- package/dist/cli-main.js.map +1 -1
- package/dist/embedder/embedding-snapshot.d.ts +52 -0
- package/dist/embedder/embedding-snapshot.d.ts.map +1 -0
- package/dist/embedder/embedding-snapshot.js +413 -0
- package/dist/embedder/embedding-snapshot.js.map +1 -0
- package/dist/embedder/index.d.ts +36 -5
- package/dist/embedder/index.d.ts.map +1 -1
- package/dist/embedder/index.js +346 -23
- package/dist/embedder/index.js.map +1 -1
- package/dist/embedder/remote.d.ts +16 -2
- package/dist/embedder/remote.d.ts.map +1 -1
- package/dist/embedder/remote.js +48 -11
- package/dist/embedder/remote.js.map +1 -1
- package/dist/embedder/sentence-transformers-config.d.ts +24 -0
- package/dist/embedder/sentence-transformers-config.d.ts.map +1 -0
- package/dist/embedder/sentence-transformers-config.js +93 -0
- package/dist/embedder/sentence-transformers-config.js.map +1 -0
- package/dist/features/sync.js +1 -1
- package/dist/features/sync.js.map +1 -1
- package/dist/ingest/compute.d.ts +15 -7
- package/dist/ingest/compute.d.ts.map +1 -1
- package/dist/ingest/compute.js +74 -14
- package/dist/ingest/compute.js.map +1 -1
- package/dist/ingest/file.d.ts +3 -3
- package/dist/ingest/file.d.ts.map +1 -1
- package/dist/ingest/file.js +0 -5
- package/dist/ingest/file.js.map +1 -1
- package/dist/ingest/visual.d.ts +6 -2
- package/dist/ingest/visual.d.ts.map +1 -1
- package/dist/ingest/visual.js +20 -4
- package/dist/ingest/visual.js.map +1 -1
- package/dist/parser/docx-parser.d.ts +2 -0
- package/dist/parser/docx-parser.d.ts.map +1 -1
- package/dist/parser/docx-parser.js +12 -3
- package/dist/parser/docx-parser.js.map +1 -1
- package/dist/parser/index.d.ts +11 -1
- package/dist/parser/index.d.ts.map +1 -1
- package/dist/parser/index.js +27 -11
- package/dist/parser/index.js.map +1 -1
- package/dist/parser/pdf-extract.d.ts +2 -0
- package/dist/parser/pdf-extract.d.ts.map +1 -1
- package/dist/parser/pdf-extract.js +3 -0
- package/dist/parser/pdf-extract.js.map +1 -1
- package/dist/parser/pdf-filter.d.ts +2 -9
- package/dist/parser/pdf-filter.d.ts.map +1 -1
- package/dist/parser/pdf-filter.js +110 -144
- package/dist/parser/pdf-filter.js.map +1 -1
- package/dist/parser/pdf-headings.d.ts +6 -0
- package/dist/parser/pdf-headings.d.ts.map +1 -0
- package/dist/parser/pdf-headings.js +166 -0
- package/dist/parser/pdf-headings.js.map +1 -0
- package/dist/parser/text-source-map.d.ts +3 -0
- package/dist/parser/text-source-map.d.ts.map +1 -0
- package/dist/parser/text-source-map.js +33 -0
- package/dist/parser/text-source-map.js.map +1 -0
- package/dist/pdf-visual/detector.js +3 -3
- package/dist/pdf-visual/detector.js.map +1 -1
- package/dist/rerank/command.d.ts +10 -7
- package/dist/rerank/command.d.ts.map +1 -1
- package/dist/rerank/command.js +51 -10
- package/dist/rerank/command.js.map +1 -1
- package/dist/rerank/index.d.ts +3 -3
- package/dist/rerank/index.d.ts.map +1 -1
- package/dist/rerank/index.js +3 -3
- package/dist/rerank/index.js.map +1 -1
- package/dist/server/index.d.ts +4 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +114 -79
- package/dist/server/index.js.map +1 -1
- package/dist/server/list-scanner.d.ts +2 -1
- package/dist/server/list-scanner.d.ts.map +1 -1
- package/dist/server/list-scanner.js +2 -2
- package/dist/server/list-scanner.js.map +1 -1
- package/dist/server/tool-definitions.js +2 -2
- package/dist/server/tool-definitions.js.map +1 -1
- package/dist/server/types.d.ts +9 -0
- package/dist/server/types.d.ts.map +1 -1
- package/dist/server-main.d.ts +2 -2
- package/dist/server-main.d.ts.map +1 -1
- package/dist/server-main.js +22 -20
- package/dist/server-main.js.map +1 -1
- package/dist/utils/base-dirs.d.ts +9 -10
- package/dist/utils/base-dirs.d.ts.map +1 -1
- package/dist/utils/base-dirs.js +28 -30
- package/dist/utils/base-dirs.js.map +1 -1
- package/dist/utils/scan.d.ts +25 -5
- package/dist/utils/scan.d.ts.map +1 -1
- package/dist/utils/scan.js +40 -10
- package/dist/utils/scan.js.map +1 -1
- package/dist/utils/source-context.d.ts +29 -0
- package/dist/utils/source-context.d.ts.map +1 -0
- package/dist/utils/source-context.js +86 -0
- package/dist/utils/source-context.js.map +1 -0
- package/dist/utils/sync-path-key.d.ts +1 -1
- package/dist/utils/sync-path-key.d.ts.map +1 -1
- package/dist/utils/sync-path-key.js +1 -1
- package/dist/utils/sync-path-key.js.map +1 -1
- package/dist/vectordb/index.d.ts +4 -2
- package/dist/vectordb/index.d.ts.map +1 -1
- package/dist/vectordb/index.js +30 -7
- package/dist/vectordb/index.js.map +1 -1
- package/dist/vectordb/relocate.d.ts +18 -0
- package/dist/vectordb/relocate.d.ts.map +1 -0
- package/dist/vectordb/relocate.js +179 -0
- package/dist/vectordb/relocate.js.map +1 -0
- package/dist/vectordb/types.d.ts +10 -23
- package/dist/vectordb/types.d.ts.map +1 -1
- package/dist/vectordb/types.js +14 -23
- package/dist/vectordb/types.js.map +1 -1
- package/package.json +14 -14
package/README.zh-CN.md
CHANGED
|
@@ -4,10 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
# MCP Local RAG
|
|
6
6
|
|
|
7
|
-
[](https://github.com/shinpr/mcp-local-rag)
|
|
8
|
-
[](https://www.npmjs.com/package/mcp-local-rag)
|
|
9
|
-
[](https://opensource.org/licenses/MIT)
|
|
10
|
-
[](https://registry.modelcontextprotocol.io/)
|
|
7
|
+
[](https://github.com/shinpr/mcp-local-rag) [](https://www.npmjs.com/package/mcp-local-rag) [](https://opensource.org/licenses/MIT) [](https://registry.modelcontextprotocol.io/)
|
|
11
8
|
|
|
12
9
|
<p align="center">
|
|
13
10
|
<a href="README.md">English</a> |
|
|
@@ -20,39 +17,39 @@
|
|
|
20
17
|
|
|
21
18
|
通过 MCP 客户端或终端搜索私有文档,无需将内容发送给嵌入 API。
|
|
22
19
|
|
|
23
|
-
mcp-local-rag 在本机为 PDF、DOCX、Markdown
|
|
20
|
+
mcp-local-rag 在本机为 PDF、DOCX、Markdown 和文本文件建立索引。搜索结合语义相似度与关键词匹配,既能检索语义相关的内容,也支持 API 名称、类名和错误代码等技术术语的精确匹配。搜索结果包含原文片段,并在可获取时附上章节标题、行号或页码,方便核对和引用原文。
|
|
24
21
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
- **本地运行:** 文档解析、嵌入、存储和搜索全部在本机完成。首次下载模型后,文本导入和搜索均可离线使用。
|
|
28
|
-
- **混合搜索:** 语义检索负责查找相关概念,关键词匹配则提高精确技术术语的排名。
|
|
29
|
-
- **可配置嵌入模型:** 可根据文档的语言和领域选择合适的 Hugging Face 嵌入模型。
|
|
30
|
-
- **语义分块:** 按主题边界而非固定字符数拆分文档,并保持 Markdown 代码块完整。
|
|
31
|
-
- **MCP 和 CLI:** AI 编程工具与终端可使用同一份索引。
|
|
32
|
-
|
|
33
|
-
无需 API 密钥、Docker、Python 或外部数据库。
|
|
22
|
+
无需 API 密钥、Docker、Python 或外部数据库。首次下载模型后,文本导入与搜索均可离线运行。
|
|
34
23
|
|
|
35
24
|
## 快速开始
|
|
36
25
|
|
|
37
26
|
### 使用要求
|
|
38
27
|
|
|
39
|
-
- Node.js 22 或更高版本
|
|
28
|
+
- Node.js 22.20 或更高版本
|
|
40
29
|
- 首次使用时需要联网下载 npm 包和嵌入模型
|
|
41
30
|
- 一个包含待搜索文档的目录
|
|
42
31
|
|
|
43
32
|
将 `BASE_DIR` 设置为该目录。它同时也是文件操作的安全边界。请将下方的 `/absolute/path/to/your/documents` 替换为该目录的绝对路径。
|
|
44
33
|
|
|
45
|
-
mcp-local-rag 通过本地 stdio 服务器使用标准 MCP 协议,因此可与支持本地 MCP 服务器的 AI 编程工具及其他 MCP 宿主配合使用。
|
|
46
|
-
|
|
47
34
|
可直接使用以下示例,也可以按照客户端的 MCP 配置格式注册 `npx -y mcp-local-rag` 并设置 `BASE_DIR`。
|
|
48
35
|
|
|
49
|
-
|
|
36
|
+
请同时将 `DB_PATH` 和 `CACHE_DIR` 设为绝对路径。相对路径以服务器的工作目录为基准,从不同项目目录启动服务器时,会在各目录中分别创建索引和模型缓存。
|
|
37
|
+
|
|
38
|
+
<details>
|
|
39
|
+
<summary>Claude Code</summary>
|
|
40
|
+
|
|
41
|
+
运行以下命令:
|
|
50
42
|
|
|
51
43
|
```bash
|
|
52
44
|
claude mcp add local-rag --scope user --env BASE_DIR=/absolute/path/to/your/documents -- npx -y mcp-local-rag
|
|
53
45
|
```
|
|
54
46
|
|
|
55
|
-
|
|
47
|
+
</details>
|
|
48
|
+
|
|
49
|
+
<details>
|
|
50
|
+
<summary>Codex</summary>
|
|
51
|
+
|
|
52
|
+
在 `~/.codex/config.toml` 中添加:
|
|
56
53
|
|
|
57
54
|
```toml
|
|
58
55
|
[mcp_servers.local-rag]
|
|
@@ -63,7 +60,12 @@ args = ["-y", "mcp-local-rag"]
|
|
|
63
60
|
BASE_DIR = "/absolute/path/to/your/documents"
|
|
64
61
|
```
|
|
65
62
|
|
|
66
|
-
|
|
63
|
+
</details>
|
|
64
|
+
|
|
65
|
+
<details>
|
|
66
|
+
<summary>OpenCode</summary>
|
|
67
|
+
|
|
68
|
+
在 `~/.config/opencode/opencode.json`(或 `opencode.jsonc`)中添加:
|
|
67
69
|
|
|
68
70
|
```json
|
|
69
71
|
{
|
|
@@ -80,7 +82,12 @@ BASE_DIR = "/absolute/path/to/your/documents"
|
|
|
80
82
|
}
|
|
81
83
|
```
|
|
82
84
|
|
|
83
|
-
|
|
85
|
+
</details>
|
|
86
|
+
|
|
87
|
+
<details>
|
|
88
|
+
<summary>Cursor</summary>
|
|
89
|
+
|
|
90
|
+
在 `~/.cursor/mcp.json` 中添加:
|
|
84
91
|
|
|
85
92
|
```json
|
|
86
93
|
{
|
|
@@ -96,6 +103,8 @@ BASE_DIR = "/absolute/path/to/your/documents"
|
|
|
96
103
|
}
|
|
97
104
|
```
|
|
98
105
|
|
|
106
|
+
</details>
|
|
107
|
+
|
|
99
108
|
重启客户端,然后让它创建索引:
|
|
100
109
|
|
|
101
110
|
```text
|
|
@@ -121,25 +130,33 @@ npx mcp-local-rag query "身份验证 API"
|
|
|
121
130
|
|
|
122
131
|
CLI 默认将当前目录作为文档根目录。请在同一目录中运行这两条命令,以便共用默认索引;也可以显式设置 `BASE_DIR` 和 `DB_PATH`。
|
|
123
132
|
|
|
124
|
-
## 为什么开发它
|
|
125
|
-
|
|
126
|
-
出于保密要求或组织政策,有些文档不能发送给托管式嵌入服务。将索引保留在本机,既能搜索这些文档,也不会产生按查询计费的 API 成本。
|
|
127
|
-
|
|
128
|
-
单纯依赖语义搜索,可能会漏掉技术文档中重要的精确标识符。关键词重排可以保留这些精确匹配,同时继续利用自然语言检索。
|
|
129
|
-
|
|
130
133
|
## 支持的内容
|
|
131
134
|
|
|
132
135
|
| 输入 | 导入方式 |
|
|
133
136
|
|---|---|
|
|
134
137
|
| PDF、DOCX、TXT、Markdown | 导入文件或同步目录 |
|
|
135
|
-
| 客户端已获取的 HTML |
|
|
138
|
+
| 客户端已获取的 HTML | `ingest_data` |
|
|
136
139
|
| 内存中的纯文本或 Markdown | 使用 `ingest_data`,并提供稳定的来源标识符 |
|
|
137
140
|
|
|
138
141
|
服务器本身不负责获取 HTML。MCP 客户端可以先获取网页,再将 HTML 传给 `ingest_data`。
|
|
139
142
|
|
|
140
143
|
文件导入不支持 Excel、PowerPoint、独立图片和源代码文件扩展名。PDF 可以选择使用本地视觉模型描述图像内容,但该功能不属于 OCR 或图片搜索。
|
|
141
144
|
|
|
142
|
-
##
|
|
145
|
+
## 使用索引
|
|
146
|
+
|
|
147
|
+
添加、修改或删除文档后,请同步索引。搜索和补充上下文时,可以这样向 MCP 客户端提问:
|
|
148
|
+
|
|
149
|
+
```text
|
|
150
|
+
查找文档中对 ERR_CONNECTION_REFUSED 的说明。
|
|
151
|
+
再读取这条结果前后的片段。
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
也可以导入单个文件,或客户端已经获取的 HTML。如需刷新已有条目,请用相同路径或来源标识重新导入;`sync` 会跳过未更改的文件。MCP 文件路径必须是绝对路径,且位于已配置的文档根目录内。
|
|
155
|
+
|
|
156
|
+
PDF 的章节标题可能识别不准。需要准确的标题时,请核对原文所在页。
|
|
157
|
+
|
|
158
|
+
<details>
|
|
159
|
+
<summary>MCP 工具</summary>
|
|
143
160
|
|
|
144
161
|
| 工具 | 用途 |
|
|
145
162
|
|---|---|
|
|
@@ -153,108 +170,14 @@ CLI 默认将当前目录作为文档根目录。请在同一目录中运行这
|
|
|
153
170
|
| `delete_file` | 删除已建立索引的文件或 `ingest_data` 条目 |
|
|
154
171
|
| `status` | 显示索引和搜索状态 |
|
|
155
172
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
`sync_start` 会导入新增和已修改的文件,跳过字节完全相同的文件,并删除已不存在文件的索引记录:
|
|
159
|
-
|
|
160
|
-
```text
|
|
161
|
-
同步已配置文档根目录中的所有内容,并等待完成。
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
该工具会立即返回 `jobId`。客户端应持续查询 `sync_status`,直到状态变为 `succeeded` 或 `failed`。发生变化的 PDF 会沿用索引时所用的模式重新导入;索引时未使用视觉模式的 PDF 仍按纯文本处理。`sync_start` 无法更改该模式。
|
|
165
|
-
|
|
166
|
-
服务器进程只保留一个同步任务记录。新任务会替换已经结束的记录,服务器重启后该记录也会丢失。
|
|
167
|
-
|
|
168
|
-
### 导入单个文件
|
|
169
|
-
|
|
170
|
-
`ingest_file` 支持 PDF、DOCX、TXT 和 Markdown。通过 MCP 传入的文件路径必须是绝对路径,并且必须位于已配置的文档根目录内:
|
|
171
|
-
|
|
172
|
-
```text
|
|
173
|
-
导入 /Users/me/docs/api-spec.pdf。
|
|
174
|
-
```
|
|
175
|
-
|
|
176
|
-
再次导入同一路径会替换原有文本块。
|
|
177
|
-
|
|
178
|
-
### 搜索并读取更多上下文
|
|
179
|
-
|
|
180
|
-
```text
|
|
181
|
-
API 文档如何说明身份验证?
|
|
182
|
-
查找 ERR_CONNECTION_REFUSED 的文档说明。
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
搜索结果包含文本、来源路径、标题、文本块编号和相关度分数。需要更多上下文时,将结果中的 `chunkIndex` 以及 `filePath` 或 `source` 传给 `read_chunk_neighbors`:
|
|
186
|
-
|
|
187
|
-
```text
|
|
188
|
-
读取该身份验证结果前后的文本块。
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
`query_documents` 和 `list_files` 都接受可选的绝对 `scope` 路径前缀或前缀列表。前缀会匹配指定路径及其全部子路径。
|
|
192
|
-
|
|
193
|
-
### 导入 HTML
|
|
194
|
-
|
|
195
|
-
由 MCP 客户端获取网页后,再使用 `ingest_data`:
|
|
196
|
-
|
|
197
|
-
```text
|
|
198
|
-
获取 https://example.com/docs 并导入其中的 HTML。
|
|
199
|
-
```
|
|
200
|
-
|
|
201
|
-
服务器会提取正文、转换为 Markdown,并使用提供的来源标识符保存。再次使用同一来源会更新已有内容。
|
|
202
|
-
|
|
203
|
-
为外部内容建立索引时,请遵守来源网站的条款和版权规定。
|
|
204
|
-
|
|
205
|
-
### PDF 图像
|
|
206
|
-
|
|
207
|
-
视觉模式会为图像内容较多的 PDF 页面生成说明文字。该功能需要主动开启,常规导入不会加载视觉模型。
|
|
208
|
-
|
|
209
|
-
```text
|
|
210
|
-
使用 visual: true 导入 /Users/me/docs/research-paper.pdf。
|
|
211
|
-
```
|
|
212
|
-
|
|
213
|
-
```bash
|
|
214
|
-
npx mcp-local-rag ingest ./docs/research-paper.pdf --visual
|
|
215
|
-
```
|
|
216
|
-
|
|
217
|
-
| 模式 | 模型缓存 | 适用场景 |
|
|
218
|
-
|---|---:|---|
|
|
219
|
-
| `fast`(默认) | 约 250 MB | 轻量视觉索引 |
|
|
220
|
-
| `quality` | 约 1.7 GB | 包含标签、标注或其他图中文字的图像 |
|
|
221
|
-
|
|
222
|
-
通过 MCP 使用 `visualQuality: "quality"`,或通过 CLI 使用 `--visual-quality quality`,即可选择较大的模型。实测 CPU 推理耗时约为 `fast` 的三倍,但实际结果取决于硬件和模型更新。
|
|
223
|
-
|
|
224
|
-
#### 更新已索引的 `quality` 说明文字
|
|
225
|
-
|
|
226
|
-
从 0.18.4 起,`quality` 使用 Qwen3.5-2B,旧版本使用 Qwen2.5-VL-3B。已索引的说明文字仍是旧模型生成的内容,`sync` 不会重新生成,需要更新的文件请重新导入:
|
|
227
|
-
|
|
228
|
-
```bash
|
|
229
|
-
npx mcp-local-rag ingest ./docs/research-paper.pdf --visual --visual-quality quality
|
|
230
|
-
```
|
|
231
|
-
|
|
232
|
-
如果该文件当初是带 `--images` 导入的,请一并加上该选项,否则本次导入会替换已保存的图像。旧模型仍留在磁盘上。确认不再使用后,可删除模型缓存目录(`<cache-dir>`,默认为 `./models/`)下的 `onnx-community/Qwen2.5-VL-3B-Instruct-ONNX/`。
|
|
233
|
-
|
|
234
|
-
#### 跨同步的视觉模式
|
|
235
|
-
|
|
236
|
-
PDF 索引时所用的模式会被记录下来,`sync` 会沿用它:以 `fast` 或 `quality` 索引的 PDF 会按同一模式重新导入,没有记录模式的 PDF 按文本导入。
|
|
237
|
-
|
|
238
|
-
```bash
|
|
239
|
-
npx mcp-local-rag sync ./docs/ # 沿用每个 PDF 记录的模式
|
|
240
|
-
npx mcp-local-rag sync ./docs/ --visual # 为范围内所有 PDF 请求 fast
|
|
241
|
-
npx mcp-local-rag sync ./docs/ --visual --visual-quality quality
|
|
242
|
-
```
|
|
243
|
-
|
|
244
|
-
`--visual` 会覆盖已记录的模式,因此也会为按文本索引的 PDF 生成说明文字。更换模式后,即使文件本身没有变化,该 PDF 也会重新导入;再次执行同一命令则不做任何处理,也不加载模型。
|
|
245
|
-
|
|
246
|
-
要关闭某个路径的说明文字,请对它执行 `ingest`:一次成功的常规导入会清除已记录的模式。要重试生成失败的页面,请执行 `ingest <路径> --visual --visual-quality <模式>` 并指定所需模式——只用 `ingest` 反而会清除它。如果一个 PDF 的索引记录中模式不一致,`sync` 会在做出任何更改前停止并指出该文件;使用 `--visual` 重新运行即可确定模式。
|
|
247
|
-
|
|
248
|
-
生成的说明文字只是辅助文本,并非忠实的逐字转录。检索到的说明文字和文档文本都应视为不可信输入,而不是操作指令。
|
|
173
|
+
</details>
|
|
249
174
|
|
|
250
175
|
## CLI
|
|
251
176
|
|
|
252
|
-
CLI
|
|
177
|
+
使用 CLI 更新索引、缩小搜索范围或删除已索引的内容:
|
|
253
178
|
|
|
254
179
|
```bash
|
|
255
|
-
npx mcp-local-rag ingest ./docs/
|
|
256
180
|
npx mcp-local-rag sync ./docs/
|
|
257
|
-
npx mcp-local-rag query "身份验证 API"
|
|
258
181
|
npx mcp-local-rag query "身份验证" --scope /docs/api --scope /docs/guide
|
|
259
182
|
npx mcp-local-rag read-neighbors --file-path /abs/path.md --chunk-index 5
|
|
260
183
|
npx mcp-local-rag list
|
|
@@ -263,6 +186,8 @@ npx mcp-local-rag delete ./docs/old.pdf
|
|
|
263
186
|
npx mcp-local-rag delete --source "https://example.com/docs"
|
|
264
187
|
```
|
|
265
188
|
|
|
189
|
+
`ingest` 导入选定的文件;`sync` 还会从索引中移除已删除的文件,并跳过未更改的文件。`--scope` 按路径前缀限定搜索范围,重复传入可包含多个前缀。
|
|
190
|
+
|
|
266
191
|
`--db-path`、`--cache-dir` 和 `--model-name` 等全局选项应放在子命令之前,子命令选项则放在子命令之后:
|
|
267
192
|
|
|
268
193
|
```bash
|
|
@@ -271,66 +196,15 @@ npx mcp-local-rag --db-path ./my-db query "身份验证"
|
|
|
271
196
|
|
|
272
197
|
运行 `npx mcp-local-rag --help` 可查看完整命令说明。
|
|
273
198
|
|
|
274
|
-
CLI 不读取 MCP 客户端配置。如果两个接口需要共用索引,请设置相同的环境变量或命令行参数。特别是共享同一数据库时,`MODEL_NAME` 必须与 CLI 的 `--model-name` 一致。
|
|
275
|
-
|
|
276
199
|
`query` 会以 JSON 格式将结果写入 stdout,最匹配的结果排在最前,因此可以通过管道传给其他工具。各字段的定义见 [`docs/schema/query-output.schema.json`](docs/schema/query-output.schema.json)。
|
|
277
200
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
关键词加权默认开启。对于需要更严格筛选结果的语料库,还可以使用相关度间隔分组、距离过滤和文件数量限制。这四项对 MCP 服务器和 CLI 的 `query` 同样生效。
|
|
281
|
-
|
|
282
|
-
| 变量 | 默认值 | 说明 |
|
|
283
|
-
|----------|---------|-------------|
|
|
284
|
-
| `RAG_HYBRID_WEIGHT` | `0.6` | 关键词加权系数(0.0–1.0)。0 表示禁用关键词重排,1 表示使用最大加权。 |
|
|
285
|
-
| `RAG_GROUPING` | 未设置 | `similar` 保留第一个相关度分组;`related` 最多保留两个分组,并以明显的向量距离间隔为边界。 |
|
|
286
|
-
| `RAG_MAX_DISTANCE` | 未设置 | 过滤相关度较低的结果(例如 `0.5`)。 |
|
|
287
|
-
| `RAG_MAX_FILES` | 未设置 | 将结果限制在排名最靠前的 N 个文件中(例如 `1` 表示只保留最佳文件)。 |
|
|
288
|
-
| `RAG_RERANK_CMD` | 未设置 | 仅 MCP 服务器:用于重排结果的外部命令。查询与命中片段的文本会发送给它。 |
|
|
289
|
-
| `RAG_RERANK_TIMEOUT_MS` | `10000` | 单次重排的超时时间,单位为毫秒(100–600000)。 |
|
|
290
|
-
|
|
291
|
-
对于包含大量标识符的 API 规范及类似文档,提高关键词权重可以改善精确术语的排名:
|
|
292
|
-
|
|
293
|
-
```json
|
|
294
|
-
"env": {
|
|
295
|
-
"RAG_HYBRID_WEIGHT": "0.7"
|
|
296
|
-
}
|
|
297
|
-
```
|
|
298
|
-
|
|
299
|
-
- `0.7`:比默认值稍强的精确术语重排
|
|
300
|
-
- `1.0`:最大关键词加权
|
|
301
|
-
|
|
302
|
-
### 外部重排(`RAG_RERANK_CMD`)
|
|
303
|
-
|
|
304
|
-
在此指定一个命令,服务器会把每一批搜索结果连同查询和命中片段的文本交给它重新排序。调用远程服务的命令会把这些内容发送到本机之外。
|
|
305
|
-
|
|
306
|
-
填写命令及其参数,以空格分隔。它必须是可执行文件:服务器不经过 shell 启动它,因此 Windows 上由 npm 安装的 `.cmd` 包装脚本无法启动。
|
|
201
|
+
如果要迁移项目并保留现有索引,请先停止 MCP 服务器和其他写入进程,将文件和数据库一起移到新位置,保持目录结构不变,然后运行:
|
|
307
202
|
|
|
308
|
-
```
|
|
309
|
-
|
|
310
|
-
"RAG_RERANK_CMD": "/path/to/reranker",
|
|
311
|
-
"RAG_RERANK_TIMEOUT_MS": "10000"
|
|
312
|
-
}
|
|
203
|
+
```bash
|
|
204
|
+
npx mcp-local-rag --db-path /new/project/lancedb relocate --from /old/project --to /new/project
|
|
313
205
|
```
|
|
314
206
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
命令失败、超时,或返回的内容不符合该形式时,结果保持原有顺序。
|
|
318
|
-
|
|
319
|
-
## 工作原理
|
|
320
|
-
|
|
321
|
-
导入时:
|
|
322
|
-
|
|
323
|
-
1. 解析器从输入格式中提取文本。
|
|
324
|
-
2. 语义分块器识别主题边界,并保持 Markdown 代码块完整。
|
|
325
|
-
3. Transformers.js 在本地生成嵌入向量。
|
|
326
|
-
4. LanceDB 保存文本块、元数据、向量和全文索引。
|
|
327
|
-
|
|
328
|
-
搜索时:
|
|
329
|
-
|
|
330
|
-
1. 使用同一模型为查询生成嵌入向量。
|
|
331
|
-
2. 向量搜索检索语义相关的文本块。
|
|
332
|
-
3. 配置后,可使用距离过滤和相关度分组进一步缩小候选范围。
|
|
333
|
-
4. 全文匹配会提高精确查询词的排名。
|
|
207
|
+
在 MCP 配置中更新 `BASE_DIR`/`BASE_DIRS`、`DB_PATH` 及其他受影响的路径,再重启客户端。
|
|
334
208
|
|
|
335
209
|
## Agent Skills
|
|
336
210
|
|
|
@@ -344,66 +218,119 @@ npx mcp-local-rag skills install --codex
|
|
|
344
218
|
|
|
345
219
|
安装的技能涵盖查询写法、结果优化和 HTML 导入。如果技能没有自动启用,请明确要求助手使用 mcp-local-rag 技能。
|
|
346
220
|
|
|
347
|
-
##
|
|
221
|
+
## 进阶选项
|
|
222
|
+
|
|
223
|
+
先使用默认设置即可。需要多个文档根目录、调整检索效果或搜索 PDF 图表时,再展开下面的相应章节。
|
|
224
|
+
|
|
225
|
+
<details>
|
|
226
|
+
<summary>存储与文档根目录</summary>
|
|
348
227
|
|
|
349
|
-
MCP
|
|
228
|
+
MCP 服务器读取环境变量,CLI 支持下表中的变量和参数。需要共用索引时,请使用相同的 `DB_PATH`。
|
|
350
229
|
|
|
351
230
|
| 环境变量 | CLI 参数 | 默认值 | 说明 |
|
|
352
231
|
|---------------------|----------|---------|-------------|
|
|
353
232
|
| `BASE_DIR` | `--base-dir` | 当前目录 | 一个文档根目录;`ingest`、`list` 和 `sync` 可重复使用该 CLI 参数 |
|
|
354
233
|
| `BASE_DIRS` | 不适用 | 未设置 | 文档根目录的 JSON 数组;优先于 `BASE_DIR` |
|
|
234
|
+
| `IGNORE_PATHS` | 不适用 | 未设置 | 不建立索引的文件的 glob 模式 JSON 数组 |
|
|
355
235
|
| `DB_PATH` | `--db-path` | `./lancedb/` | 向量数据库位置 |
|
|
356
236
|
| `CACHE_DIR` | `--cache-dir` | `./models/` | 模型缓存目录 |
|
|
357
237
|
| `HF_ENDPOINT` | 不适用 | `https://huggingface.co` | Hugging Face 模型下载地址;无法直接下载时使用镜像地址 |
|
|
358
|
-
| `MODEL_NAME` | `--model-name` | `Xenova/all-MiniLM-L6-v2` | Hugging Face 嵌入模型 |
|
|
359
238
|
| `MAX_FILE_SIZE` | `--max-file-size` | `104857600`(100 MB) | 最大文件大小(字节) |
|
|
239
|
+
|
|
240
|
+
文件操作仅限已配置的根目录。多个目录可用 `BASE_DIRS='["/absolute/docs","/absolute/specs"]'`,或在 CLI 中重复传入 `--base-dir`。优先级依次为 CLI 根目录、`BASE_DIRS`、`BASE_DIR`、当前目录。只采用优先级最高的配置来源,不会合并不同来源的根目录。无效的 `BASE_DIRS` 会报错。相对的 `DB_PATH` 和 `CACHE_DIR` 以进程工作目录为起点。
|
|
241
|
+
|
|
242
|
+
如需让某些文件不进入索引,可将 `IGNORE_PATHS` 设为 glob 模式的 JSON 数组,例如 `IGNORE_PATHS='["plugs/**","**/*.draft.md"]'`。每个模式与文件相对于其所在文档根目录的路径进行匹配,在所有操作系统上都用 `/` 书写。`*` 和 `**` 不匹配以 `.` 开头的名称,这类目录需要写全,例如 `".obsidian/**"`。`ingest`、`list` 和 `sync` 扫描目录时会跳过匹配的文件,`sync` 还会从索引中移除已建立索引的匹配文件。无效的 `IGNORE_PATHS` 会报错。
|
|
243
|
+
|
|
244
|
+
</details>
|
|
245
|
+
|
|
246
|
+
<details>
|
|
247
|
+
<summary>模型与搜索调优</summary>
|
|
248
|
+
|
|
249
|
+
根据文档的语言和主题选择嵌入模型。用实际会问的问题比较设置,检查返回的原文是否符合需求。本工具使用平均池化(mean pooling)和 L2 归一化生成嵌入向量,请选择兼容这两种处理方式的模型。
|
|
250
|
+
|
|
251
|
+
| 环境变量 | CLI 参数 | 默认值 | 说明 |
|
|
252
|
+
|---------------------|----------|---------|-------------|
|
|
253
|
+
| `MODEL_NAME` | `--model-name` | `Xenova/all-MiniLM-L6-v2` | Hugging Face 嵌入模型 |
|
|
360
254
|
| `CHUNK_MIN_LENGTH` | `--chunk-min-length` | `50` | 普通文本块的最小字符数(1–10000);为适配模型词元上限而切分出的片段可以更短 |
|
|
255
|
+
| `EMBED_TITLE_PREFIX` | 不适用 | `false` | 将文档标题加入每个文本块的嵌入输入 |
|
|
256
|
+
| `EMBED_HEADING_PREFIX` | 不适用 | `false` | 在词元上限允许的情况下,将章节标题层级加入每个文本块的嵌入输入 |
|
|
361
257
|
| `RAG_DEVICE` | 不适用 | `cpu` | ONNX Runtime 执行设备 |
|
|
362
258
|
| `RAG_DTYPE` | 不适用 | `fp32` | 传给所选模型的嵌入数据类型 |
|
|
363
259
|
|
|
364
|
-
|
|
260
|
+
两个前缀选项默认均为 `false`,可独立使用。文本块缺少文档整体主题时,可尝试 `EMBED_TITLE_PREFIX`;缺少所在章节的主题时,可尝试 `EMBED_HEADING_PREFIX`。同时启用两项不一定更好。它们影响嵌入,不改变返回的文本或关键词索引;章节上下文超出输入预算时会被省略。
|
|
365
261
|
|
|
366
|
-
|
|
262
|
+
更换嵌入模型时,请使用新的 `DB_PATH` 重建索引。不同模型生成的向量无法直接比较,即使维度相同也是如此。更改 `RAG_DTYPE` 或任一前缀选项后,请先重新导入所有已建立索引的文档,再进行搜索。`sync` 会跳过未更改的文件。
|
|
367
263
|
|
|
368
|
-
|
|
369
|
-
|
|
264
|
+
CLI 不读取 MCP 客户端配置。共用索引时,导入和搜索必须使用相同的模型、`RAG_DTYPE` 和前缀设置。仅更改 `RAG_DEVICE` 不需要重建索引。
|
|
265
|
+
|
|
266
|
+
### 搜索调优
|
|
267
|
+
|
|
268
|
+
表中前四项设置同时适用于 MCP 和 CLI。若希望更看重精确术语匹配,可以尝试提高 `RAG_HYBRID_WEIGHT`,并用自己的问题比较结果。外部重排仅适用于 MCP。
|
|
269
|
+
|
|
270
|
+
| 变量 | 默认值 | 说明 |
|
|
271
|
+
|----------|---------|-------------|
|
|
272
|
+
| `RAG_HYBRID_WEIGHT` | `0.6` | 关键词加权系数(0.0–1.0)。0 表示禁用关键词重排,1 表示使用最大加权。|
|
|
273
|
+
| `RAG_GROUPING` | 未设置 | `similar` 保留第一个相关度分组;`related` 最多保留两个分组,并以明显的向量距离间隔为边界。|
|
|
274
|
+
| `RAG_MAX_DISTANCE` | 未设置 | 过滤相关度较低的结果(例如 `0.5`)。|
|
|
275
|
+
| `RAG_MAX_FILES` | 未设置 | 将结果限制在排名最靠前的 N 个文件中(例如 `1` 表示只保留最佳文件)。|
|
|
276
|
+
| `RAG_RERANK_CMD` | 未设置 | 仅 MCP:外部命令;`{query}` 传入查询,`{top}` 传入请求的结果数量。|
|
|
277
|
+
| `RAG_RERANK_TIMEOUT_MS` | `10000` | 单次重排的超时时间,单位为毫秒(100–600000)。|
|
|
278
|
+
|
|
279
|
+
### 外部重排(`RAG_RERANK_CMD`)
|
|
280
|
+
|
|
281
|
+
命令通过标准输入接收搜索结果及命中文本。如果命令调用远程服务,这些文本可能会被发送到本机之外。
|
|
282
|
+
|
|
283
|
+
填写可执行文件及完整的参数模板,在命令需要查询和结果数量的位置使用 `{query}` 和 `{top}`。单引号或双引号可将含空格的路径或参数组合在一起,反斜杠按字面保留。服务器不经过 shell 启动命令,因此 Windows 上由 npm 安装的 `.cmd` 包装脚本无法启动。
|
|
284
|
+
|
|
285
|
+
```json
|
|
286
|
+
{
|
|
287
|
+
"env": {
|
|
288
|
+
"RAG_RERANK_CMD": "/path/to/reranker --query {query} --top {top}",
|
|
289
|
+
"RAG_RERANK_TIMEOUT_MS": "10000"
|
|
290
|
+
}
|
|
291
|
+
}
|
|
370
292
|
```
|
|
371
293
|
|
|
372
|
-
|
|
294
|
+
命令必须按[输出 schema](docs/schema/query-output.schema.json) 规定的格式读取和返回结果。它可以删除结果、调整顺序或修改文本,服务器会返回命令的输出。
|
|
373
295
|
|
|
374
|
-
|
|
375
|
-
2. `BASE_DIRS`
|
|
376
|
-
3. `BASE_DIR`
|
|
377
|
-
4. 当前目录
|
|
296
|
+
如果命令失败、超时或返回的数据不符合 schema,结果将保留原有顺序。
|
|
378
297
|
|
|
379
|
-
|
|
298
|
+
</details>
|
|
299
|
+
|
|
300
|
+
<details>
|
|
301
|
+
<summary>PDF 图表与图片存储</summary>
|
|
302
|
+
|
|
303
|
+
默认情况下,导入只为文本建立索引。如需搜索 PDF 图表内容,可在 MCP 中设置 `visual: true`,或在 CLI 中使用 `--visual`,由本地模型生成描述。描述不等同于 OCR 或逐字转录。
|
|
304
|
+
|
|
305
|
+
`fast`(默认)首次使用需下载约 250 MB。图表中有标签或文字时,可选择 `quality`;首次需下载约 1.7 GB,处理也更慢。
|
|
306
|
+
|
|
307
|
+
MCP 使用 `visualQuality: "quality"` 选择配置,CLI 使用 `--visual-quality quality`。
|
|
380
308
|
|
|
381
309
|
```bash
|
|
382
|
-
npx mcp-local-rag ingest
|
|
383
|
-
npx mcp-local-rag list --base-dir /Users/me/work --base-dir /Users/me/specs
|
|
384
|
-
npx mcp-local-rag sync --base-dir /Users/me/work --base-dir /Users/me/specs
|
|
385
|
-
BASE_DIRS='["/Users/me/work","/Users/me/specs"]' npx mcp-local-rag list
|
|
310
|
+
npx mcp-local-rag ingest ./docs/paper.pdf --visual --visual-quality quality
|
|
386
311
|
```
|
|
387
312
|
|
|
388
|
-
|
|
313
|
+
如需在文本结果中同时返回图片,在 MCP 中设置 `STORE_IMAGES=true`,或在 CLI 的 `ingest` 和 `sync` 中使用 `--images`。图片存储与描述生成相互独立,支持识别出的 PDF 图表区域,以及 DOCX 中受支持的 PNG/JPEG 图片。
|
|
389
314
|
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
315
|
+
```bash
|
|
316
|
+
npx mcp-local-rag ingest ./docs/paper.pdf --images
|
|
317
|
+
```
|
|
393
318
|
|
|
394
|
-
|
|
319
|
+
同步会沿用各 PDF 已有的描述配置。CLI 的 `sync --visual --visual-quality quality` 会更改配置,即使 PDF 本身未变;MCP 同步则沿用原配置。普通导入会关闭描述功能;要重试生成失败的描述,请使用所需的视觉配置重新导入。
|
|
395
320
|
|
|
396
|
-
|
|
321
|
+
每次实际处理文件的导入或同步都需要启用图片存储。仅更改图片设置不会更新未变的文件,需要重新导入才会生效。
|
|
397
322
|
|
|
398
|
-
|
|
323
|
+
</details>
|
|
399
324
|
|
|
400
325
|
## 安全与运行
|
|
401
326
|
|
|
327
|
+
- 请将描述和检索到的文本作为参考资料,而不是操作指令。
|
|
402
328
|
- 文件访问仅限 `BASE_DIR`、`BASE_DIRS` 或 CLI 的 `--base-dir` 所指定的根目录。
|
|
403
329
|
- 指向所有已配置根目录之外的符号链接会被拒绝。
|
|
404
330
|
- 所需模型缓存完成后,文档处理和搜索不会再发起网络请求;如果 `RAG_RERANK_CMD` 指定的命令会发起网络请求,则不在此列。
|
|
405
331
|
- 服务器面向单个本地用户设计,不提供身份验证或访问控制。
|
|
406
332
|
- 不要让多个 CLI 或 MCP 写入进程同时操作同一个 `DB_PATH`。同步进行时仍可执行只读查询。
|
|
333
|
+
- 重新导入时,如果模型和设置一致,可复用内容未变部分的已有嵌入向量,省去重复计算。缓存位于 `DB_PATH/embedding-cache`。删除缓存不会影响现有索引的搜索,但之后导入时会重新计算这些向量。
|
|
407
334
|
- 没有写入进程运行时,可以复制 `DB_PATH` 目录来备份索引。
|
|
408
335
|
|
|
409
336
|
<details>
|
|
@@ -411,7 +338,7 @@ mcp-local-rag 使用平均池化和 L2 归一化生成嵌入。选择模型时
|
|
|
411
338
|
|
|
412
339
|
### "No results found"
|
|
413
340
|
|
|
414
|
-
必须先导入文档。运行 `"列出所有已导入的文件"`
|
|
341
|
+
必须先导入文档。运行 `"列出所有已导入的文件"` 检查导入状态。如果同步后仍没有结果,请检查导入和搜索是否使用相同的绝对 `DB_PATH`。相对路径可能指向另一个索引。
|
|
415
342
|
|
|
416
343
|
### 模型下载失败
|
|
417
344
|
|
|
@@ -455,7 +382,7 @@ MIT 许可证,可免费用于个人和商业用途。
|
|
|
455
382
|
|
|
456
383
|
## 博客文章
|
|
457
384
|
|
|
458
|
-
- [
|
|
385
|
+
- [Building a Local RAG for Agentic Coding(英文)](https://www.norsica.jp/blog/local-rag-agentic-coding):深入介绍语义分块与混合搜索的技术设计。
|
|
459
386
|
|
|
460
387
|
## 致谢
|
|
461
388
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { AtomicTextRange, TextChunk } from './index.js';
|
|
2
|
+
import { type ContainmentBudget } from './token-containment.js';
|
|
2
3
|
/**
|
|
3
4
|
* Semantic Chunker configuration
|
|
4
5
|
* Based on paper recommendations: hardThreshold=0.6, initConst=1.5, c=0.9
|
|
@@ -20,11 +21,18 @@ export interface SemanticChunkerConfig {
|
|
|
20
21
|
* skips token containment.
|
|
21
22
|
*/
|
|
22
23
|
export interface EmbedderInterface {
|
|
23
|
-
|
|
24
|
+
/** `'document'` embeds behind the model's document prompt; omitted, its default prompt. */
|
|
25
|
+
embedBatch(texts: string[], role?: 'document'): Promise<number[][]>;
|
|
24
26
|
/** Resolved token cap, or `null` when no limit could be resolved. */
|
|
25
27
|
getTokenLimit?(): Promise<number | null>;
|
|
26
|
-
/** True, unclamped token lengths of each text. */
|
|
27
|
-
countTokens?(texts: string[]): Promise<number[]>;
|
|
28
|
+
/** True, unclamped token lengths of each text, prompt included. */
|
|
29
|
+
countTokens?(texts: string[], role?: 'document'): Promise<number[]>;
|
|
30
|
+
/** The model's document prompt, or `''`. */
|
|
31
|
+
getDocumentPrompt?(): Promise<string>;
|
|
32
|
+
/** Whether ingestion embeds chunks behind their document title. */
|
|
33
|
+
readonly titlePrefix?: boolean;
|
|
34
|
+
/** Whether ingestion adds section paths to the final embedding input. */
|
|
35
|
+
readonly headingPrefix?: boolean;
|
|
28
36
|
}
|
|
29
37
|
/**
|
|
30
38
|
* Garbage chunks, language-agnostically: empty after trimming, only decoration
|
|
@@ -34,6 +42,14 @@ export interface EmbedderInterface {
|
|
|
34
42
|
export declare function isGarbageChunk(text: string): boolean;
|
|
35
43
|
/** Default minimum chunk length in characters */
|
|
36
44
|
export declare const DEFAULT_MIN_CHUNK_LENGTH = 50;
|
|
45
|
+
/**
|
|
46
|
+
* The embedder's token budget, or `null` when the optional members are absent
|
|
47
|
+
* or no limit could be resolved. Containment is then skipped entirely.
|
|
48
|
+
*
|
|
49
|
+
* Every measurement is taken with `textPrefix` prepended and the document
|
|
50
|
+
* prompt applied, since the caller embeds each chunk behind both.
|
|
51
|
+
*/
|
|
52
|
+
export declare function resolveContainmentBudget(embedder: EmbedderInterface, textPrefix: string): Promise<ContainmentBudget | null>;
|
|
37
53
|
/**
|
|
38
54
|
* Semantic chunker using the Max-Min algorithm: a sentence joins the current
|
|
39
55
|
* chunk when its maximum similarity to any member exceeds the minimum
|
|
@@ -43,9 +59,11 @@ export declare class SemanticChunker {
|
|
|
43
59
|
private readonly config;
|
|
44
60
|
constructor(config?: Partial<SemanticChunkerConfig>);
|
|
45
61
|
/**
|
|
46
|
-
* Split text into semantically coherent chunks
|
|
62
|
+
* Split text into semantically coherent chunks. `textPrefix` is the text the
|
|
63
|
+
* caller will prepend to each chunk before embedding; it is not added to the
|
|
64
|
+
* returned chunks, but token containment budgets for it.
|
|
47
65
|
*/
|
|
48
|
-
chunkText(text: string, embedder: EmbedderInterface, atomicRanges?: readonly AtomicTextRange[]): Promise<TextChunk[]>;
|
|
66
|
+
chunkText(text: string, embedder: EmbedderInterface, atomicRanges?: readonly AtomicTextRange[], textPrefix?: string): Promise<TextChunk[]>;
|
|
49
67
|
/**
|
|
50
68
|
* Whether a sentence group becomes stored chunks. A group holding a
|
|
51
69
|
* containment piece is already admitted, judged before the split, so neither
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"semantic-chunker.d.ts","sourceRoot":"","sources":["../../src/chunker/semantic-chunker.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"semantic-chunker.d.ts","sourceRoot":"","sources":["../../src/chunker/semantic-chunker.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAE5D,OAAO,EACL,KAAK,iBAAiB,EAGvB,MAAM,wBAAwB,CAAA;AAM/B;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IACpC,2DAA2D;IAC3D,aAAa,EAAE,MAAM,CAAA;IACrB,8DAA8D;IAC9D,SAAS,EAAE,MAAM,CAAA;IACjB,gEAAgE;IAChE,CAAC,EAAE,MAAM,CAAA;IACT,uDAAuD;IACvD,cAAc,EAAE,MAAM,CAAA;CACvB;AAED;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IAChC,2FAA2F;IAC3F,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,IAAI,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;IACnE,qEAAqE;IACrE,aAAa,CAAC,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAA;IACxC,mEAAmE;IACnE,WAAW,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,IAAI,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAA;IACnE,4CAA4C;IAC5C,iBAAiB,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,CAAA;IACrC,mEAAmE;IACnE,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAA;IAC9B,yEAAyE;IACzE,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAA;CACjC;AAoBD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CA2BpD;AAMD,iDAAiD;AACjD,eAAO,MAAM,wBAAwB,KAAK,CAAA;AAW1C;;;;;;GAMG;AACH,wBAAsB,wBAAwB,CAC5C,QAAQ,EAAE,iBAAiB,EAC3B,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAkBnC;AAkGD;;;;GAIG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuB;IAE9C,YAAY,MAAM,GAAE,OAAO,CAAC,qBAAqB,CAAM,EAEtD;IAED;;;;OAIG;IACG,SAAS,CACb,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,iBAAiB,EAC3B,YAAY,GAAE,SAAS,eAAe,EAAO,EAC7C,UAAU,SAAK,GACd,OAAO,CAAC,SAAS,EAAE,CAAC,CA8BtB;IAED;;;;;OAKG;IACH,OAAO,CAAC,WAAW;IAWnB;;OAEG;IACH;;;;OAIG;IACH,OAAO,CAAC,cAAc;IAetB,OAAO,CAAC,cAAc;IAgDtB;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAaxB;;;;OAIG;IACH,OAAO,CAAC,gBAAgB;IA2BxB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAWxB;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IAM1B;;OAEG;IACH,OAAO,CAAC,OAAO;IAIf;;;OAGG;IACH,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAuBvD;CACF"}
|
|
@@ -61,8 +61,11 @@ function joinUnits(units) {
|
|
|
61
61
|
/**
|
|
62
62
|
* The embedder's token budget, or `null` when the optional members are absent
|
|
63
63
|
* or no limit could be resolved. Containment is then skipped entirely.
|
|
64
|
+
*
|
|
65
|
+
* Every measurement is taken with `textPrefix` prepended and the document
|
|
66
|
+
* prompt applied, since the caller embeds each chunk behind both.
|
|
64
67
|
*/
|
|
65
|
-
async function resolveContainmentBudget(embedder) {
|
|
68
|
+
export async function resolveContainmentBudget(embedder, textPrefix) {
|
|
66
69
|
const { getTokenLimit, countTokens } = embedder;
|
|
67
70
|
if (!getTokenLimit || !countTokens) {
|
|
68
71
|
return null;
|
|
@@ -71,7 +74,10 @@ async function resolveContainmentBudget(embedder) {
|
|
|
71
74
|
if (cap === null) {
|
|
72
75
|
return null;
|
|
73
76
|
}
|
|
74
|
-
return {
|
|
77
|
+
return {
|
|
78
|
+
cap,
|
|
79
|
+
countTokens: (texts) => countTokens.call(embedder, texts.map((text) => textPrefix + text), 'document'),
|
|
80
|
+
};
|
|
75
81
|
}
|
|
76
82
|
/** One measurement pass over `texts`, rejecting a counter that drops inputs. */
|
|
77
83
|
async function measureAll(texts, budget) {
|
|
@@ -161,9 +167,11 @@ export class SemanticChunker {
|
|
|
161
167
|
this.config = { ...DEFAULT_SEMANTIC_CHUNKER_CONFIG, ...config };
|
|
162
168
|
}
|
|
163
169
|
/**
|
|
164
|
-
* Split text into semantically coherent chunks
|
|
170
|
+
* Split text into semantically coherent chunks. `textPrefix` is the text the
|
|
171
|
+
* caller will prepend to each chunk before embedding; it is not added to the
|
|
172
|
+
* returned chunks, but token containment budgets for it.
|
|
165
173
|
*/
|
|
166
|
-
async chunkText(text, embedder, atomicRanges = []) {
|
|
174
|
+
async chunkText(text, embedder, atomicRanges = [], textPrefix = '') {
|
|
167
175
|
// Handle empty input
|
|
168
176
|
if (!text || text.trim().length === 0) {
|
|
169
177
|
// Supplied ranges are programmer contracts and must fail fast even when
|
|
@@ -178,7 +186,7 @@ export class SemanticChunker {
|
|
|
178
186
|
if (sentenceUnits.length === 0) {
|
|
179
187
|
return [];
|
|
180
188
|
}
|
|
181
|
-
const budget = await resolveContainmentBudget(embedder);
|
|
189
|
+
const budget = await resolveContainmentBudget(embedder, textPrefix);
|
|
182
190
|
const units = budget ? await containUnits(sentenceUnits, budget) : sentenceUnits;
|
|
183
191
|
// Generate embeddings for all sentences
|
|
184
192
|
const embeddings = await embedder.embedBatch(units.map((unit) => unit.text));
|