@huyooo/ai-search 0.2.17 → 0.2.19

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.
Files changed (2) hide show
  1. package/package.json +2 -2
  2. package/README.md +0 -431
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@huyooo/ai-search",
3
- "version": "0.2.17",
3
+ "version": "0.2.19",
4
4
  "description": "本地文档语义搜索引擎 - 支持 Word、PDF、Excel、TXT、MD",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -91,7 +91,7 @@
91
91
  "embedding"
92
92
  ],
93
93
  "author": "huyooo",
94
- "license": "MIT",
94
+ "license": "SEE LICENSE IN LICENSE",
95
95
  "publishConfig": {
96
96
  "access": "public"
97
97
  }
package/README.md DELETED
@@ -1,431 +0,0 @@
1
- # @huyooo/ai-search
2
-
3
- 本地文档语义搜索引擎,支持 Word、PDF、Excel、TXT、MD 等文档格式。
4
-
5
- ## 特性
6
-
7
- - 🔍 **语义搜索**:基于向量的语义理解,不仅仅是关键词匹配
8
- - 📄 **多格式支持**:Word (.docx/.doc)、PDF、Excel (.xlsx/.xls)、PPT (.pptx/.ppt)、TXT、MD
9
- - 🏠 **本地优先**:所有数据存储在本地,保护隐私
10
- - ⚡ **高性能**:LanceDB 向量搜索 + FlexSearch 全文检索
11
- - 🤖 **AI 集成**:可作为 AI Agent 工具使用
12
- - 🔗 **兼容 file-explorer**:搜索结果兼容 FileItem 数据结构
13
-
14
- ## 安装
15
-
16
- ```bash
17
- npm install @huyooo/ai-search
18
- ```
19
-
20
- ## 快速开始
21
-
22
- ### 环境变量
23
-
24
- 使用前需要设置豆包 API Key:
25
-
26
- ```bash
27
- export ARK_API_KEY=your_api_key_here
28
- ```
29
-
30
- ### 基础使用
31
-
32
- ```typescript
33
- import { DocumentSearch } from '@huyooo/ai-search'
34
-
35
- // 创建搜索引擎
36
- const search = new DocumentSearch({
37
- dataDir: './search-data', // 索引数据存储目录
38
- // arkApiKey: 'your_key', // 也可以直接传入,默认从环境变量读取
39
- // embeddingDimension: 1024, // 向量维度(可选,默认 1024)
40
- })
41
-
42
- // 初始化
43
- await search.init()
44
-
45
- // 索引目录
46
- await search.indexDirectory('~/Documents')
47
-
48
- // 搜索
49
- const results = await search.search('去年的采购合同')
50
-
51
- console.log(results)
52
- // [
53
- // {
54
- // id: '/Users/xxx/Documents/采购合同.docx',
55
- // name: '采购合同.docx',
56
- // type: 'document',
57
- // size: '1.2 MB',
58
- // dateModified: '2024-03-15',
59
- // score: 0.92,
60
- // snippet: '...甲方与乙方就采购事宜...',
61
- // },
62
- // ...
63
- // ]
64
- ```
65
-
66
- ### 作为 AI Agent 工具(推荐)
67
-
68
- ```typescript
69
- import { searchPlugin } from '@huyooo/ai-search'
70
-
71
- // Vite 插件风格 API
72
- const plugin = await searchPlugin({
73
- dataDir: './search-data',
74
- workspace: '~/Documents', // 可选:初始工作空间
75
- })
76
-
77
- // 注册工具到 Agent
78
- agent.registerTools(plugin.tools)
79
-
80
- // Agent 现在可以使用所有工具,包括:
81
- // - search_local_documents: 搜索文档
82
- // - index_document_file: 索引单个文件
83
- // - index_document_directory: 索引目录
84
- // - index_document_files: 批量索引文件
85
- // - watch_document_directory: 监听目录变化
86
- // - export_document_index: 导出索引
87
- // - optimize_document_index: 优化索引
88
- // ... 等 20+ 个工具
89
- ```
90
-
91
- ### 搜索选项
92
-
93
- ```typescript
94
- const results = await search.search('合同', {
95
- limit: 20, // 返回数量
96
- mode: 'hybrid', // semantic | keyword | hybrid
97
- fileTypes: ['document', 'pdf'], // 文件类型过滤
98
- dateRange: { // 时间范围
99
- start: new Date('2024-01-01'),
100
- end: new Date('2024-12-31'),
101
- },
102
- directories: ['/path/to/docs'], // 目录过滤
103
- sizeRange: { // 文件大小过滤
104
- min: 1024, // 最小 1KB
105
- max: 10 * 1024 * 1024, // 最大 10MB
106
- },
107
- fileNamePattern: '*.pdf', // 文件名模式(通配符)
108
- titleContains: '合同', // 标题包含
109
- combineMode: 'AND', // 组合条件模式
110
- })
111
- ```
112
-
113
- ### 文件监听和自动更新
114
-
115
- ```typescript
116
- // 监听目录变化,自动更新索引
117
- search.watchDirectory('/path/to/documents', {
118
- ignoreInitial: true, // 忽略初始扫描
119
- debounce: 1000, // 防抖延迟(毫秒)
120
- onEvent: (event) => {
121
- console.log('文件变化:', event.type, event.path)
122
- },
123
- })
124
-
125
- // 停止监听
126
- search.unwatchDirectory('/path/to/documents')
127
-
128
- // 获取正在监听的目录
129
- const watched = search.getWatchedDirectories()
130
- ```
131
-
132
- ### 批量操作
133
-
134
- ```typescript
135
- // 批量索引文件
136
- const result = await search.indexFiles([
137
- '/path/to/file1.pdf',
138
- '/path/to/file2.docx',
139
- ], (progress) => {
140
- console.log(`进度: ${progress.indexed}/${progress.total}`)
141
- })
142
-
143
- // 批量删除索引
144
- await search.removeFiles(['/path/to/file1.pdf', '/path/to/file2.docx'])
145
-
146
- // 批量更新索引(重新索引)
147
- await search.updateFiles(['/path/to/file1.pdf'])
148
- ```
149
-
150
- ### 索引导出和导入
151
-
152
- ```typescript
153
- // 导出索引(备份)
154
- const exportInfo = await search.exportIndex('./backup/search-index')
155
-
156
- // 导入索引(恢复)
157
- await search.importIndex('./backup/search-index')
158
-
159
- // 列出备份
160
- const backups = await search.listBackups('./backup')
161
- ```
162
-
163
- ### 索引优化和维护
164
-
165
- ```typescript
166
- // 清理无效索引(文件已删除但索引还在)
167
- const result = await search.cleanup()
168
- console.log(`清理了 ${result.removed} 个无效索引`)
169
-
170
- // 优化索引(压缩、碎片整理)
171
- await search.optimize()
172
-
173
- // 健康检查
174
- const health = await search.healthCheck()
175
- if (!health.healthy) {
176
- console.log('索引存在问题,建议执行 optimize')
177
- }
178
-
179
- // 获取索引错误
180
- const errors = search.getIndexErrors()
181
-
182
- // 重试失败的索引
183
- await search.retryFailedIndexes()
184
- ```
185
-
186
- ## API
187
-
188
- ### DocumentSearch
189
-
190
- ```typescript
191
- class DocumentSearch {
192
- constructor(config: SearchConfig)
193
-
194
- // ========== 初始化 ==========
195
- init(): Promise<void>
196
-
197
- // ========== 索引 ==========
198
- // 单文件索引
199
- indexFile(filePath: string, retryCount?: number): Promise<void>
200
-
201
- // 目录索引
202
- indexDirectory(
203
- dir: string,
204
- onProgress?: (p: IndexProgress) => void
205
- ): Promise<void>
206
-
207
- // 索引默认目录
208
- indexDefaultDirectories(
209
- onProgress?: (p: IndexProgress) => void
210
- ): Promise<void>
211
-
212
- // 批量索引
213
- indexFiles(
214
- filePaths: string[],
215
- onProgress?: (p: IndexProgress) => void
216
- ): Promise<BatchOperationResult>
217
-
218
- // ========== 搜索 ==========
219
- search(query: string, options?: SearchOptions): Promise<SearchResult[]>
220
-
221
- // ========== 文件监听 ==========
222
- watchDirectory(directory: string, options?: WatchOptions): void
223
- unwatchDirectory(directory: string): void
224
- unwatchAll(): void
225
- getWatchedDirectories(): string[]
226
-
227
- // ========== 批量操作 ==========
228
- removeFiles(filePaths: string[]): Promise<BatchOperationResult>
229
- updateFiles(
230
- filePaths: string[],
231
- onProgress?: (p: IndexProgress) => void
232
- ): Promise<BatchOperationResult>
233
-
234
- // ========== 索引管理 ==========
235
- removeFile(filePath: string): Promise<void>
236
- getStats(): IndexStats
237
- clear(): Promise<void>
238
- save(): Promise<void>
239
-
240
- // ========== 索引优化 ==========
241
- cleanup(): Promise<{ removed: number; updated: number }>
242
- optimize(): Promise<void>
243
- healthCheck(): Promise<HealthCheckResult>
244
-
245
- // ========== 错误处理 ==========
246
- getIndexErrors(): IndexError[]
247
- retryFailedIndexes(): Promise<BatchOperationResult>
248
-
249
- // ========== 导出/导入 ==========
250
- exportIndex(outputPath: string): Promise<ExportInfo>
251
- importIndex(inputPath: string): Promise<void>
252
- listBackups(backupDir: string): Promise<BackupInfo[]>
253
-
254
- // ========== 资源清理 ==========
255
- destroy(): Promise<void>
256
- }
257
- ```
258
-
259
- ### SearchResult(兼容 FileItem)
260
-
261
- ```typescript
262
- interface SearchResult {
263
- // 与 file-explorer FileItem 兼容
264
- id: string // 文件路径
265
- name: string // 文件名
266
- type: FileType // 文件类型
267
- size?: string // 格式化大小
268
- dateModified?: string// 格式化日期
269
- url?: string // file:// URL
270
-
271
- // 搜索特有字段
272
- score: number // 相关度分数 (0-1)
273
- snippet?: string // 匹配摘要
274
- matchType: 'semantic' | 'keyword' | 'hybrid'
275
- }
276
- ```
277
-
278
- ### SearchOptions
279
-
280
- ```typescript
281
- interface SearchOptions {
282
- limit?: number // 返回数量限制
283
- mode?: 'semantic' | 'keyword' | 'hybrid' // 搜索模式
284
- fileTypes?: FileType[] // 文件类型过滤
285
- dateRange?: { // 时间范围过滤
286
- start?: Date
287
- end?: Date
288
- }
289
- directories?: string[] // 目录过滤
290
- sizeRange?: { // 文件大小过滤
291
- min?: number // 字节
292
- max?: number // 字节
293
- }
294
- fileNamePattern?: string // 文件名模式(通配符 * ?)
295
- titleContains?: string // 文档标题包含
296
- combineMode?: 'AND' | 'OR' // 组合条件模式
297
- }
298
- ```
299
-
300
- ### SearchConfig
301
-
302
- ```typescript
303
- interface SearchConfig {
304
- dataDir: string // 索引数据存储目录
305
- indexDirectories?: string[] // 索引目录列表
306
- excludeDirs?: string[] // 排除目录
307
- extensions?: string[] // 支持的扩展名
308
- maxFileSize?: number // 最大文件大小(字节)
309
- embeddingModel?: string // Embedding 模型(默认 doubao-embedding-vision-250615)
310
- arkApiKey?: string // 豆包 API Key(也可通过环境变量 ARK_API_KEY 设置)
311
- embeddingDimension?: number // 向量维度(默认 1024)
312
- }
313
- ```
314
-
315
- ### AI Agent 工具列表
316
-
317
- 使用 `searchPlugin` 后,Agent 可以使用以下工具:
318
-
319
- #### 搜索相关
320
- - `search_local_documents` - 搜索文档
321
-
322
- #### 索引相关
323
- - `index_document_file` - 索引单个文件
324
- - `index_document_directory` - 索引目录
325
- - `index_document_files` - 批量索引文件
326
- - `update_document_files` - 批量更新索引
327
-
328
- #### 工作空间管理
329
- - `set_search_workspace` - 设置工作空间
330
- - `get_search_workspace` - 获取工作空间状态
331
-
332
- #### 文件监听
333
- - `watch_document_directory` - 监听目录变化
334
- - `unwatch_document_directory` - 停止监听
335
- - `get_watched_directories` - 获取监听列表
336
-
337
- #### 索引管理
338
- - `get_document_index_stats` - 获取统计信息
339
- - `clear_document_index` - 清空索引
340
- - `remove_document_files` - 批量删除索引
341
-
342
- #### 索引优化
343
- - `cleanup_document_index` - 清理无效索引
344
- - `optimize_document_index` - 优化索引
345
- - `check_document_index_health` - 健康检查
346
-
347
- #### 错误处理
348
- - `get_document_index_errors` - 获取索引错误
349
- - `retry_failed_document_indexes` - 重试失败索引
350
-
351
- #### 导出/导入
352
- - `export_document_index` - 导出索引
353
- - `import_document_index` - 导入索引
354
- - `list_document_index_backups` - 列出备份
355
- ```
356
-
357
- ## 特性详解
358
-
359
- ### 🔄 增量索引
360
- - 自动检测文件变化(路径 + 修改时间 + 文件大小)
361
- - 文件未变化时跳过索引,提升性能
362
- - 支持内容哈希去重,相同内容复用索引
363
-
364
- ### 📁 文件监听
365
- - 自动监听目录变化
366
- - 新增/修改文件自动索引
367
- - 删除文件自动清理索引
368
- - 支持防抖,避免频繁触发
369
-
370
- ### 🚀 批量操作
371
- - 批量索引、删除、更新
372
- - 支持进度回调
373
- - 错误处理和重试机制
374
-
375
- ### 💾 索引管理
376
- - 导出/导入索引(备份和恢复)
377
- - 索引优化和维护
378
- - 健康检查和错误恢复
379
-
380
- ## 技术栈
381
-
382
- | 组件 | 技术 |
383
- |-----|-----|
384
- | 向量存储 | LanceDB |
385
- | 全文搜索 | FlexSearch |
386
- | 元数据存储 | SQLite (better-sqlite3) |
387
- | 文本向量化 | 豆包 doubao-embedding-vision-250615(多模态) |
388
- | 中文分词 | nodejieba |
389
- | 文档解析 | mammoth, pdf-parse, xlsx |
390
- | 文件扫描 | fdir |
391
- | 文件监听 | chokidar |
392
-
393
- ## 向量化模型
394
-
395
- 使用字节跳动的 **doubao-embedding-vision-250615** 多模态向量化模型:
396
-
397
- - 支持文本、图片、视频向量化
398
- - 支持多模态混合输入
399
- - 默认 1024 维向量(可配置)
400
- - 需要豆包 API Key(ARK_API_KEY)
401
-
402
- ### 高级向量化 API
403
-
404
- ```typescript
405
- import {
406
- embed, // 文本向量化
407
- embedImage, // 图片向量化
408
- embedVideo, // 视频向量化
409
- embedMultimodal, // 多模态混合
410
- } from '@huyooo/ai-search'
411
-
412
- // 文本向量化
413
- const textVector = await embed('天很蓝,海很深')
414
-
415
- // 图片向量化
416
- const imageVector = await embedImage('https://example.com/image.jpg')
417
-
418
- // 视频向量化
419
- const videoVector = await embedVideo('https://example.com/video.mp4')
420
-
421
- // 多模态混合
422
- const mixedVector = await embedMultimodal([
423
- { type: 'text', text: '这是什么?' },
424
- { type: 'image_url', image_url: { url: 'https://example.com/image.jpg' } },
425
- ])
426
- ```
427
-
428
- ## 许可证
429
-
430
- MIT
431
-