smart_rag 0.1.0 → 0.2.1
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.
- checksums.yaml +4 -4
- data/.env.example +252 -0
- data/.rspec +2 -0
- data/AGENTS.md +33 -0
- data/API_DOCUMENTATION.md +828 -0
- data/CHANGELOG.md +16 -1
- data/ER-diagram.mmd +144 -0
- data/Gemfile +50 -0
- data/Gemfile.lock +398 -0
- data/Hybrid_Reranking.md +171 -0
- data/README.en.md +420 -28
- data/README.md +534 -63
- data/Rakefile +268 -0
- data/SETUP_GUIDE.md +650 -0
- data/SmartChunking.md +180 -0
- data/USAGE_EXAMPLES.md +1002 -0
- data/config/llm_config.yml +4 -2
- data/config/smart_rag.yml +45 -1
- data/config.ru +15 -0
- data/db/migrations/006_create_text_search_configs.rb +3 -2
- data/db/migrations/008_create_embeddings.rb +5 -4
- data/db/migrations/012_add_metadata_to_source_sections.rb +11 -0
- data/db/migrations/013_create_media_jobs.rb +25 -0
- data/db/migrations/014_add_media_job_operations_indexes.rb +11 -0
- data/db/migrations/015_add_media_leases_and_objects.rb +80 -0
- data/db/migrations/016_add_document_principals_and_staging_references.rb +38 -0
- data/db/migrations/017_add_media_job_request_fingerprint.rb +48 -0
- data/db/seeds/text_search_configs.sql +3 -3
- data/design.md +1057 -0
- data/docs/API_DOCUMENTATION.md +838 -0
- data/docs/DOCUMENTATION_INDEX.en.md +60 -0
- data/docs/DOCUMENTATION_INDEX.md +65 -0
- data/docs/FIX_SUMMARY.md +256 -0
- data/docs/FIX_SUMMARY_COMPLETE.md +273 -0
- data/docs/Hybrid_Reranking.md +171 -0
- data/docs/MIGRATION_GUIDE.md +151 -0
- data/docs/PERFORMANCE_GUIDE.md +58 -0
- data/docs/SETUP_GUIDE.md +659 -0
- data/docs/SmartChunking.md +180 -0
- data/docs/USAGE_EXAMPLES.md +1008 -0
- data/docs/design.md +1057 -0
- data/docs/evidence_pack.md +211 -0
- data/docs/requirements.md +376 -0
- data/docs/retrieval_plan.md +251 -0
- data/docs/smartrag_improvement_plan.md +201 -0
- data/docs/smartrag_refactor.md +216 -0
- data/docs/todo.md +931 -0
- data/examples/common.rb +1 -1
- data/exe/smart-rag-db +163 -0
- data/exe/smart-rag-media-worker +34 -0
- data/lib/smart_rag/config.rb +12 -0
- data/lib/smart_rag/core/document_processor.rb +80 -16
- data/lib/smart_rag/core/local_content_store.rb +51 -0
- data/lib/smart_rag/core/media_extractors.rb +140 -0
- data/lib/smart_rag/core/media_job_queue.rb +353 -0
- data/lib/smart_rag/core/media_metadata_extractor.rb +188 -0
- data/lib/smart_rag/core/media_object_registry.rb +79 -0
- data/lib/smart_rag/core/media_processor.rb +228 -0
- data/lib/smart_rag/core/media_safety_policy.rb +61 -0
- data/lib/smart_rag/core/s3_content_store.rb +78 -0
- data/lib/smart_rag/core/transcript_normalizer.rb +44 -0
- data/lib/smart_rag/core/video_semantic_extractor.rb +130 -0
- data/lib/smart_rag/http_access_policy.rb +86 -0
- data/lib/smart_rag/http_app.rb +188 -0
- data/lib/smart_rag/models/embedding.rb +1 -1
- data/lib/smart_rag/models/research_topic.rb +1 -1
- data/lib/smart_rag/models/research_topic_section.rb +5 -0
- data/lib/smart_rag/models/research_topic_tag.rb +5 -0
- data/lib/smart_rag/models/search_log.rb +1 -1
- data/lib/smart_rag/models/section_fts.rb +5 -0
- data/lib/smart_rag/models/section_tag.rb +5 -0
- data/lib/smart_rag/models/source_document.rb +1 -1
- data/lib/smart_rag/models/source_section.rb +1 -1
- data/lib/smart_rag/models/tag.rb +1 -1
- data/lib/smart_rag/models/text_search_config.rb +5 -0
- data/lib/smart_rag/retrieve.rb +72 -1
- data/lib/smart_rag/services/embedding_service.rb +1 -1
- data/lib/smart_rag/services/fulltext_search_service.rb +11 -13
- data/lib/smart_rag/services/hybrid_search_service.rb +15 -11
- data/lib/smart_rag/services/summarization_service.rb +1 -1
- data/lib/smart_rag/services/tag_service.rb +1 -1
- data/lib/smart_rag/version.rb +1 -1
- data/lib/smart_rag.rb +264 -30
- data/patch_language.rb +27 -0
- data/requirements.md +376 -0
- data/source_documents_export.json +11072 -0
- data/todo.md +931 -0
- data/workers/analyze_content.rb +6 -2
- data/workers/get_embedding.rb +1 -1
- metadata +151 -38
|
@@ -0,0 +1,828 @@
|
|
|
1
|
+
# SmartRAG API 文档
|
|
2
|
+
|
|
3
|
+
## 概述
|
|
4
|
+
|
|
5
|
+
SmartRAG 是一个功能强大的 Ruby gem,提供混合检索增强生成功能,支持向量搜索、全文搜索和混合搜索。
|
|
6
|
+
|
|
7
|
+
## 前置条件
|
|
8
|
+
|
|
9
|
+
```ruby
|
|
10
|
+
require 'smart_rag'
|
|
11
|
+
|
|
12
|
+
# 初始化配置
|
|
13
|
+
SmartRAG.config = SmartRAG::Config.load('config/smart_rag.yml')
|
|
14
|
+
SmartRAG.db = Sequel.connect(SmartRAG.config[:database])
|
|
15
|
+
SmartRAG.logger = Logger.new(STDOUT)
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## 核心 API
|
|
19
|
+
|
|
20
|
+
### SmartRAG::SmartRAG
|
|
21
|
+
|
|
22
|
+
主入口类,提供统一 API 接口。
|
|
23
|
+
|
|
24
|
+
#### 初始化
|
|
25
|
+
|
|
26
|
+
```ruby
|
|
27
|
+
config = {
|
|
28
|
+
database: {
|
|
29
|
+
adapter: 'postgresql',
|
|
30
|
+
host: 'localhost',
|
|
31
|
+
database: 'smart_rag_dev',
|
|
32
|
+
user: 'username',
|
|
33
|
+
password: 'password'
|
|
34
|
+
},
|
|
35
|
+
llm: {
|
|
36
|
+
provider: 'openai',
|
|
37
|
+
api_key: ENV['OPENAI_API_KEY']
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
smart_rag = SmartRAG::SmartRAG.new(config)
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
#### 文档管理
|
|
45
|
+
|
|
46
|
+
##### 添加文档
|
|
47
|
+
|
|
48
|
+
```ruby
|
|
49
|
+
# 从文件添加
|
|
50
|
+
result = smart_rag.add_document('/path/to/document.pdf', {
|
|
51
|
+
title: 'My Document',
|
|
52
|
+
generate_embeddings: true,
|
|
53
|
+
generate_tags: true,
|
|
54
|
+
tags: ['important', 'research']
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
# 从 URL 添加
|
|
58
|
+
result = smart_rag.add_document('https://example.com/article', {
|
|
59
|
+
generate_embeddings: true
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
# 返回值
|
|
63
|
+
{
|
|
64
|
+
document_id: 123,
|
|
65
|
+
section_count: 5,
|
|
66
|
+
status: 'success'
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
**参数:**
|
|
71
|
+
- `document_path` (String): 文件路径或 URL
|
|
72
|
+
- `options` (Hash):
|
|
73
|
+
- `title` (String): 文档标题(可选,自动提取)
|
|
74
|
+
- `tags` (Array<String>): 标签列表
|
|
75
|
+
- `generate_embeddings` (Boolean): 是否生成嵌入(默认: true)
|
|
76
|
+
- `generate_tags` (Boolean): 是否自动生成标签(默认: false)
|
|
77
|
+
|
|
78
|
+
##### 删除文档
|
|
79
|
+
|
|
80
|
+
```ruby
|
|
81
|
+
result = smart_rag.remove_document(123)
|
|
82
|
+
|
|
83
|
+
# 返回值
|
|
84
|
+
{
|
|
85
|
+
success: true,
|
|
86
|
+
deleted_sections: 5,
|
|
87
|
+
deleted_embeddings: 5
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
##### 获取文档详情
|
|
92
|
+
|
|
93
|
+
```ruby
|
|
94
|
+
doc = smart_rag.get_document(123)
|
|
95
|
+
|
|
96
|
+
# 返回值
|
|
97
|
+
{
|
|
98
|
+
id: 123,
|
|
99
|
+
title: 'My Document',
|
|
100
|
+
description: 'Document description',
|
|
101
|
+
author: 'John Doe',
|
|
102
|
+
created_at: '2024-01-01T00:00:00Z',
|
|
103
|
+
updated_at: '2024-01-01T00:00:00Z',
|
|
104
|
+
section_count: 5,
|
|
105
|
+
metadata: { ... }
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
##### 列出文档
|
|
110
|
+
|
|
111
|
+
```ruby
|
|
112
|
+
# 获取第1页,每页20条
|
|
113
|
+
results = smart_rag.list_documents(page: 1, per_page: 20)
|
|
114
|
+
|
|
115
|
+
# 搜索文档
|
|
116
|
+
results = smart_rag.list_documents(search: 'machine learning')
|
|
117
|
+
|
|
118
|
+
# 返回值
|
|
119
|
+
{
|
|
120
|
+
documents: [
|
|
121
|
+
{ id: 1, title: 'Doc 1', ... },
|
|
122
|
+
{ id: 2, title: 'Doc 2', ... }
|
|
123
|
+
],
|
|
124
|
+
total_count: 100,
|
|
125
|
+
page: 1,
|
|
126
|
+
per_page: 20,
|
|
127
|
+
total_pages: 5
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
**参数:**
|
|
132
|
+
- `page` (Integer): 页码(默认: 1)
|
|
133
|
+
- `per_page` (Integer): 每页数量(默认: 20,最大: 100)
|
|
134
|
+
- `search` (String): 搜索关键词(可选)
|
|
135
|
+
|
|
136
|
+
#### 搜索功能
|
|
137
|
+
|
|
138
|
+
##### 混合搜索(默认)
|
|
139
|
+
|
|
140
|
+
```ruby
|
|
141
|
+
results = smart_rag.search('artificial intelligence applications', {
|
|
142
|
+
search_type: 'hybrid', # 可选: 'hybrid', 'vector', 'fulltext'
|
|
143
|
+
limit: 10, # 最大结果数
|
|
144
|
+
alpha: 0.7, # 向量搜索权重(0-1)
|
|
145
|
+
include_content: true, # 包含完整内容
|
|
146
|
+
include_metadata: true, # 包含元数据
|
|
147
|
+
filters: { # 过滤器
|
|
148
|
+
document_ids: [1, 2, 3],
|
|
149
|
+
tag_ids: [4, 5, 6]
|
|
150
|
+
}
|
|
151
|
+
})
|
|
152
|
+
|
|
153
|
+
# 返回值
|
|
154
|
+
{
|
|
155
|
+
query: 'artificial intelligence applications',
|
|
156
|
+
results: [
|
|
157
|
+
{
|
|
158
|
+
section_id: 456,
|
|
159
|
+
document_id: 123,
|
|
160
|
+
section_title: 'AI Overview',
|
|
161
|
+
content: '...',
|
|
162
|
+
similarity: 0.89,
|
|
163
|
+
combined_score: 0.85,
|
|
164
|
+
search_type: 'hybrid',
|
|
165
|
+
metadata: {
|
|
166
|
+
document_title: 'AI Research Paper',
|
|
167
|
+
author: 'Jane Smith'
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
],
|
|
171
|
+
metadata: {
|
|
172
|
+
total_count: 10,
|
|
173
|
+
execution_time_ms: 185,
|
|
174
|
+
language: 'en',
|
|
175
|
+
alpha: 0.7,
|
|
176
|
+
text_result_count: 8,
|
|
177
|
+
vector_result_count: 7,
|
|
178
|
+
multilingual: false
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
**参数:**
|
|
184
|
+
- `query` (String): 搜索查询
|
|
185
|
+
- `options` (Hash):
|
|
186
|
+
- `search_type` (String): 搜索类型 ('hybrid', 'vector', 'fulltext')
|
|
187
|
+
- `limit` (Integer): 最大结果数(默认: 20)
|
|
188
|
+
- `alpha` (Float): 向量搜索权重,0-1之间(默认: 0.7)
|
|
189
|
+
- `include_content` (Boolean): 是否包含完整内容
|
|
190
|
+
- `include_metadata` (Boolean): 是否包含元数据
|
|
191
|
+
- `filters` (Hash): 过滤器选项
|
|
192
|
+
- `document_ids` (Array<Integer>): 文档ID列表
|
|
193
|
+
- `tag_ids` (Array<Integer>): 标签ID列表
|
|
194
|
+
- `date_from` (Date): 开始日期
|
|
195
|
+
- `date_to` (Date): 结束日期
|
|
196
|
+
|
|
197
|
+
##### 向量搜索
|
|
198
|
+
|
|
199
|
+
```ruby
|
|
200
|
+
results = smart_rag.vector_search('machine learning algorithms', {
|
|
201
|
+
limit: 5,
|
|
202
|
+
include_content: true
|
|
203
|
+
})
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
##### 全文搜索
|
|
207
|
+
|
|
208
|
+
```ruby
|
|
209
|
+
results = smart_rag.fulltext_search('natural language processing', {
|
|
210
|
+
limit: 5,
|
|
211
|
+
include_metadata: true
|
|
212
|
+
})
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
#### 研究主题管理
|
|
216
|
+
|
|
217
|
+
##### 创建主题
|
|
218
|
+
|
|
219
|
+
```ruby
|
|
220
|
+
result = smart_rag.create_topic('AI in Healthcare', 'Applications of AI in medical field', {
|
|
221
|
+
tags: ['AI', 'healthcare', 'medicine'],
|
|
222
|
+
document_ids: [1, 2, 3]
|
|
223
|
+
})
|
|
224
|
+
|
|
225
|
+
# 返回值
|
|
226
|
+
{
|
|
227
|
+
topic_id: 456,
|
|
228
|
+
title: 'AI in Healthcare',
|
|
229
|
+
description: 'Applications of AI in medical field',
|
|
230
|
+
tags: ['AI', 'healthcare', 'medicine'],
|
|
231
|
+
document_ids: [1, 2, 3]
|
|
232
|
+
}
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
##### 获取主题详情
|
|
236
|
+
|
|
237
|
+
```ruby
|
|
238
|
+
topic = smart_rag.get_topic(456)
|
|
239
|
+
|
|
240
|
+
# 返回值
|
|
241
|
+
{
|
|
242
|
+
id: 456,
|
|
243
|
+
title: 'AI in Healthcare',
|
|
244
|
+
description: 'Applications of AI in medical field',
|
|
245
|
+
created_at: '2024-01-01T00:00:00Z',
|
|
246
|
+
updated_at: '2024-01-01T00:00:00Z',
|
|
247
|
+
tags: ['AI', 'healthcare', 'medicine'],
|
|
248
|
+
document_count: 5
|
|
249
|
+
}
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
##### 列出主题
|
|
253
|
+
|
|
254
|
+
```ruby
|
|
255
|
+
results = smart_rag.list_topics(
|
|
256
|
+
page: 1,
|
|
257
|
+
per_page: 10,
|
|
258
|
+
search: 'AI'
|
|
259
|
+
)
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
##### 更新主题
|
|
263
|
+
|
|
264
|
+
```ruby
|
|
265
|
+
result = smart_rag.update_topic(456, {
|
|
266
|
+
title: 'AI in Medicine',
|
|
267
|
+
tags: ['AI', 'medicine', 'technology']
|
|
268
|
+
})
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
##### 删除主题
|
|
272
|
+
|
|
273
|
+
```ruby
|
|
274
|
+
result = smart_rag.delete_topic(456)
|
|
275
|
+
|
|
276
|
+
# 返回值
|
|
277
|
+
{
|
|
278
|
+
success: true,
|
|
279
|
+
topic_id: 456
|
|
280
|
+
}
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
##### 添加文档到主题
|
|
284
|
+
|
|
285
|
+
```ruby
|
|
286
|
+
result = smart_rag.add_document_to_topic(456, 123)
|
|
287
|
+
|
|
288
|
+
# 返回值
|
|
289
|
+
{
|
|
290
|
+
success: true,
|
|
291
|
+
added_sections: 5,
|
|
292
|
+
topic_id: 456,
|
|
293
|
+
document_id: 123
|
|
294
|
+
}
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
##### 从主题移除文档
|
|
298
|
+
|
|
299
|
+
```ruby
|
|
300
|
+
result = smart_rag.remove_document_from_topic(456, 123)
|
|
301
|
+
|
|
302
|
+
# 返回值
|
|
303
|
+
{
|
|
304
|
+
success: true,
|
|
305
|
+
deleted_sections: 5,
|
|
306
|
+
topic_id: 456,
|
|
307
|
+
document_id: 123
|
|
308
|
+
}
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
##### 获取主题推荐
|
|
312
|
+
|
|
313
|
+
```ruby
|
|
314
|
+
recommendations = smart_rag.get_topic_recommendations(456, {
|
|
315
|
+
limit: 10
|
|
316
|
+
})
|
|
317
|
+
|
|
318
|
+
# 返回值
|
|
319
|
+
{
|
|
320
|
+
topic_id: 456,
|
|
321
|
+
recommendations: [
|
|
322
|
+
{
|
|
323
|
+
section_id: 789,
|
|
324
|
+
section_title: 'Machine Learning in Surgery',
|
|
325
|
+
document_id: 234,
|
|
326
|
+
matching_tags: 3
|
|
327
|
+
}
|
|
328
|
+
]
|
|
329
|
+
}
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
#### 标签管理
|
|
333
|
+
|
|
334
|
+
##### 生成标签
|
|
335
|
+
|
|
336
|
+
```ruby
|
|
337
|
+
tags = smart_rag.generate_tags('Machine learning algorithms for text classification', {
|
|
338
|
+
max_tags: 5,
|
|
339
|
+
context: 'AI research'
|
|
340
|
+
})
|
|
341
|
+
|
|
342
|
+
# 返回值
|
|
343
|
+
{
|
|
344
|
+
content_tags: ['machine learning', 'text classification', 'algorithms'],
|
|
345
|
+
category_tags: ['AI', 'NLP']
|
|
346
|
+
}
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
##### 列出标签
|
|
350
|
+
|
|
351
|
+
```ruby
|
|
352
|
+
results = smart_rag.list_tags(
|
|
353
|
+
page: 1,
|
|
354
|
+
per_page: 50
|
|
355
|
+
)
|
|
356
|
+
|
|
357
|
+
# 返回值
|
|
358
|
+
{
|
|
359
|
+
tags: [
|
|
360
|
+
{
|
|
361
|
+
id: 1,
|
|
362
|
+
name: 'AI',
|
|
363
|
+
parent_id: nil,
|
|
364
|
+
section_count: 25,
|
|
365
|
+
created_at: '2024-01-01T00:00:00Z'
|
|
366
|
+
}
|
|
367
|
+
],
|
|
368
|
+
total_count: 100,
|
|
369
|
+
page: 1,
|
|
370
|
+
per_page: 50,
|
|
371
|
+
total_pages: 2
|
|
372
|
+
}
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
#### 系统统计
|
|
376
|
+
|
|
377
|
+
```ruby
|
|
378
|
+
stats = smart_rag.statistics
|
|
379
|
+
|
|
380
|
+
# 返回值
|
|
381
|
+
{
|
|
382
|
+
document_count: 150,
|
|
383
|
+
section_count: 750,
|
|
384
|
+
topic_count: 25,
|
|
385
|
+
tag_count: 85,
|
|
386
|
+
embedding_count: 750
|
|
387
|
+
}
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
#### 搜索日志
|
|
391
|
+
|
|
392
|
+
```ruby
|
|
393
|
+
logs = smart_rag.search_logs(
|
|
394
|
+
limit: 100,
|
|
395
|
+
search_type: 'hybrid'
|
|
396
|
+
)
|
|
397
|
+
|
|
398
|
+
# 返回值
|
|
399
|
+
[
|
|
400
|
+
{
|
|
401
|
+
id: 1,
|
|
402
|
+
query: 'artificial intelligence',
|
|
403
|
+
search_type: 'hybrid',
|
|
404
|
+
results_count: 10,
|
|
405
|
+
execution_time_ms: 185,
|
|
406
|
+
created_at: '2024-01-01T00:00:00Z'
|
|
407
|
+
}
|
|
408
|
+
]
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
## Core Classes
|
|
412
|
+
|
|
413
|
+
### SmartRAG::Core::Embedding
|
|
414
|
+
|
|
415
|
+
向量嵌入管理类。
|
|
416
|
+
|
|
417
|
+
```ruby
|
|
418
|
+
embedding = SmartRAG::Core::Embedding.new(db_connection)
|
|
419
|
+
|
|
420
|
+
# 存储嵌入
|
|
421
|
+
embedding.store_embedding(section_id, vector)
|
|
422
|
+
|
|
423
|
+
# 向量搜索
|
|
424
|
+
results = embedding.search_by_vector(query_vector, limit: 5)
|
|
425
|
+
|
|
426
|
+
# 带标签增强的搜索
|
|
427
|
+
results = embedding.search_by_vector_with_tags(
|
|
428
|
+
query_vector,
|
|
429
|
+
tags,
|
|
430
|
+
limit: 10
|
|
431
|
+
)
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
### SmartRAG::Core::QueryProcessor
|
|
435
|
+
|
|
436
|
+
查询处理器,支持自然语言处理。
|
|
437
|
+
|
|
438
|
+
```ruby
|
|
439
|
+
processor = SmartRAG::Core::QueryProcessor.new(
|
|
440
|
+
config,
|
|
441
|
+
embedding_manager,
|
|
442
|
+
fulltext_manager
|
|
443
|
+
)
|
|
444
|
+
|
|
445
|
+
# 处理查询
|
|
446
|
+
results = processor.process_query(
|
|
447
|
+
'What is machine learning?',
|
|
448
|
+
language: :en,
|
|
449
|
+
limit: 5
|
|
450
|
+
)
|
|
451
|
+
|
|
452
|
+
# 生成响应
|
|
453
|
+
response = processor.generate_response(
|
|
454
|
+
'What is machine learning?',
|
|
455
|
+
results
|
|
456
|
+
)
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
### SmartRAG::Core::DocumentProcessor
|
|
460
|
+
|
|
461
|
+
文档处理器,支持多种格式。
|
|
462
|
+
|
|
463
|
+
```ruby
|
|
464
|
+
processor = SmartRAG::Core::DocumentProcessor.new(
|
|
465
|
+
embedding_manager,
|
|
466
|
+
config
|
|
467
|
+
)
|
|
468
|
+
|
|
469
|
+
# 处理文档
|
|
470
|
+
document = processor.process_document(
|
|
471
|
+
'/path/to/document.pdf',
|
|
472
|
+
generate_embeddings: true,
|
|
473
|
+
generate_tags: true
|
|
474
|
+
)
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
### SmartRAG::Services::TagService
|
|
478
|
+
|
|
479
|
+
标签服务,支持标签生成和管理。
|
|
480
|
+
|
|
481
|
+
```ruby
|
|
482
|
+
tag_service = SmartRAG::Services::TagService.new(llm_config)
|
|
483
|
+
|
|
484
|
+
# 生成标签
|
|
485
|
+
tags = tag_service.generate_tags(
|
|
486
|
+
text,
|
|
487
|
+
topic: 'AI research',
|
|
488
|
+
languages: [:en]
|
|
489
|
+
)
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
## 错误处理
|
|
493
|
+
|
|
494
|
+
所有 API 调用都可能抛出以下错误:
|
|
495
|
+
|
|
496
|
+
```ruby
|
|
497
|
+
begin
|
|
498
|
+
result = smart_rag.search('query')
|
|
499
|
+
rescue SmartRAG::Errors::ArgumentError => e
|
|
500
|
+
# 参数错误
|
|
501
|
+
rescue SmartRAG::Errors::DatabaseError => e
|
|
502
|
+
# 数据库错误
|
|
503
|
+
rescue SmartRAG::Errors::EmbeddingGenerationError => e
|
|
504
|
+
# 嵌入生成失败
|
|
505
|
+
rescue SmartRAG::Errors::QueryProcessingError => e
|
|
506
|
+
# 查询处理失败
|
|
507
|
+
rescue SmartRAG::Errors::TagGenerationError => e
|
|
508
|
+
# 标签生成失败
|
|
509
|
+
rescue SmartRAG::Errors::DocumentProcessingError => e
|
|
510
|
+
# 文档处理失败
|
|
511
|
+
end
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
## 最佳实践
|
|
515
|
+
|
|
516
|
+
### 1. 批量操作
|
|
517
|
+
|
|
518
|
+
```ruby
|
|
519
|
+
# 批量添加文档
|
|
520
|
+
doc_paths.each do |path|
|
|
521
|
+
smart_rag.add_document(path, generate_embeddings: true)
|
|
522
|
+
end
|
|
523
|
+
|
|
524
|
+
# 使用线程池加速
|
|
525
|
+
require 'concurrent'
|
|
526
|
+
|
|
527
|
+
pool = Concurrent::FixedThreadPool.new(5)
|
|
528
|
+
doc_paths.each do |path|
|
|
529
|
+
pool.post do
|
|
530
|
+
smart_rag.add_document(path, generate_embeddings: true)
|
|
531
|
+
end
|
|
532
|
+
end
|
|
533
|
+
pool.shutdown
|
|
534
|
+
pool.wait_for_termination
|
|
535
|
+
```
|
|
536
|
+
|
|
537
|
+
### 2. 缓存嵌入
|
|
538
|
+
|
|
539
|
+
```ruby
|
|
540
|
+
# 使用 Redis 缓存嵌入
|
|
541
|
+
require 'redis'
|
|
542
|
+
|
|
543
|
+
redis = Redis.new
|
|
544
|
+
|
|
545
|
+
# 检查缓存
|
|
546
|
+
cached = redis.get("embedding:#{content_hash}")
|
|
547
|
+
if cached
|
|
548
|
+
embedding = JSON.parse(cached)
|
|
549
|
+
else
|
|
550
|
+
embedding = smart_rag.generate_embedding(content)
|
|
551
|
+
redis.set("embedding:#{content_hash}", embedding.to_json, ex: 3600)
|
|
552
|
+
end
|
|
553
|
+
```
|
|
554
|
+
|
|
555
|
+
### 3. 错误重试
|
|
556
|
+
|
|
557
|
+
```ruby
|
|
558
|
+
require 'retriable'
|
|
559
|
+
|
|
560
|
+
Retriable.retriable(on: SmartRAG::Errors::EmbeddingGenerationError, tries: 3) do
|
|
561
|
+
result = smart_rag.add_document(path, generate_embeddings: true)
|
|
562
|
+
end
|
|
563
|
+
```
|
|
564
|
+
|
|
565
|
+
### 4. 异步处理
|
|
566
|
+
|
|
567
|
+
```ruby
|
|
568
|
+
# 使用后台任务处理大型文档
|
|
569
|
+
class DocumentProcessingJob
|
|
570
|
+
def perform(document_path, options = {})
|
|
571
|
+
smart_rag = SmartRAG::SmartRAG.new(config)
|
|
572
|
+
smart_rag.add_document(document_path, options)
|
|
573
|
+
end
|
|
574
|
+
end
|
|
575
|
+
|
|
576
|
+
# 使用 Sidekiq 或其他队列系统
|
|
577
|
+
DocumentProcessingJob.perform_async('/path/to/large_document.pdf')
|
|
578
|
+
```
|
|
579
|
+
|
|
580
|
+
### 5. 监控和日志
|
|
581
|
+
|
|
582
|
+
```ruby
|
|
583
|
+
# 配置详细日志
|
|
584
|
+
SmartRAG.logger = Logger.new('smart_rag.log')
|
|
585
|
+
SmartRAG.logger.level = Logger::DEBUG
|
|
586
|
+
|
|
587
|
+
# 监控搜索性能
|
|
588
|
+
result = smart_rag.search('query')
|
|
589
|
+
puts "Found #{result[:results].length} results in #{result[:metadata][:execution_time_ms]}ms"
|
|
590
|
+
```
|
|
591
|
+
|
|
592
|
+
## 性能优化
|
|
593
|
+
|
|
594
|
+
### 1. 数据库连接池
|
|
595
|
+
|
|
596
|
+
```ruby
|
|
597
|
+
# 配置连接池
|
|
598
|
+
config = {
|
|
599
|
+
database: {
|
|
600
|
+
adapter: 'postgresql',
|
|
601
|
+
host: 'localhost',
|
|
602
|
+
database: 'smart_rag_dev',
|
|
603
|
+
user: 'username',
|
|
604
|
+
password: 'password',
|
|
605
|
+
pool: 25 # 增加连接池大小
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
```
|
|
609
|
+
|
|
610
|
+
### 2. 批量插入
|
|
611
|
+
|
|
612
|
+
```ruby
|
|
613
|
+
# 批量添加文档比逐个添加更高效
|
|
614
|
+
documents.each_slice(10) do |batch|
|
|
615
|
+
batch.each do |doc|
|
|
616
|
+
smart_rag.add_document(doc[:path], doc[:options])
|
|
617
|
+
end
|
|
618
|
+
end
|
|
619
|
+
```
|
|
620
|
+
|
|
621
|
+
### 3. 索引优化
|
|
622
|
+
|
|
623
|
+
```sql
|
|
624
|
+
-- 确保所有索引已创建
|
|
625
|
+
CREATE INDEX CONCURRENTLY idx_document_created_at ON source_documents (created_at);
|
|
626
|
+
CREATE INDEX CONCURRENTLY idx_section_document_id ON source_sections (document_id);
|
|
627
|
+
CREATE INDEX CONCURRENTLY idx_embedding_source_id ON embeddings (source_id);
|
|
628
|
+
```
|
|
629
|
+
|
|
630
|
+
### 4. 调整 RRF 参数
|
|
631
|
+
|
|
632
|
+
```ruby
|
|
633
|
+
# 根据数据集大小调整 RRF k 参数
|
|
634
|
+
results = smart_rag.search('query', {
|
|
635
|
+
alpha: 0.7, # 向量搜索权重
|
|
636
|
+
limit: 10
|
|
637
|
+
})
|
|
638
|
+
```
|
|
639
|
+
|
|
640
|
+
### 5. 使用缓存
|
|
641
|
+
|
|
642
|
+
```ruby
|
|
643
|
+
# 启用查询缓存
|
|
644
|
+
require 'smart_rag/cache'
|
|
645
|
+
|
|
646
|
+
cache = SmartRAG::Cache.new(redis_client)
|
|
647
|
+
|
|
648
|
+
# 缓存搜索结果
|
|
649
|
+
cached_results = cache.fetch("search:#{query_hash}") do
|
|
650
|
+
smart_rag.search(query)
|
|
651
|
+
end
|
|
652
|
+
```
|
|
653
|
+
|
|
654
|
+
## 迁移指南
|
|
655
|
+
|
|
656
|
+
### 从 v0.1 升级到 v0.2
|
|
657
|
+
|
|
658
|
+
#### 破坏性变更
|
|
659
|
+
|
|
660
|
+
1. **API 变更**
|
|
661
|
+
- `add_document` 现在返回 hash 而不是 document 对象
|
|
662
|
+
- `search` 方法返回格式已更新
|
|
663
|
+
|
|
664
|
+
2. **配置变更**
|
|
665
|
+
- `config/smart_rag.yml` 结构已更新
|
|
666
|
+
- 移除了 `embedding_service` 配置块
|
|
667
|
+
|
|
668
|
+
#### 迁移步骤
|
|
669
|
+
|
|
670
|
+
1. 更新配置文件
|
|
671
|
+
|
|
672
|
+
```yaml
|
|
673
|
+
# config/smart_rag.yml (v0.2)
|
|
674
|
+
database:
|
|
675
|
+
adapter: postgresql
|
|
676
|
+
# ... 其他配置
|
|
677
|
+
|
|
678
|
+
llm:
|
|
679
|
+
provider: openai
|
|
680
|
+
api_key: <%= ENV['OPENAI_API_KEY'] %>
|
|
681
|
+
# ... 其他配置
|
|
682
|
+
```
|
|
683
|
+
|
|
684
|
+
2. 更新 API 调用
|
|
685
|
+
|
|
686
|
+
```ruby
|
|
687
|
+
# 旧代码 (v0.1)
|
|
688
|
+
doc = smart_rag.add_document('/path/to/doc.pdf')
|
|
689
|
+
doc_id = doc.id
|
|
690
|
+
|
|
691
|
+
# 新代码 (v0.2)
|
|
692
|
+
result = smart_rag.add_document('/path/to/doc.pdf')
|
|
693
|
+
doc_id = result[:document_id]
|
|
694
|
+
```
|
|
695
|
+
|
|
696
|
+
3. 更新错误处理
|
|
697
|
+
|
|
698
|
+
```ruby
|
|
699
|
+
# 旧代码 (v0.1)
|
|
700
|
+
begin
|
|
701
|
+
smart_rag.search('query')
|
|
702
|
+
rescue StandardError => e
|
|
703
|
+
# 处理错误
|
|
704
|
+
end
|
|
705
|
+
|
|
706
|
+
# 新代码 (v0.2)
|
|
707
|
+
begin
|
|
708
|
+
smart_rag.search('query')
|
|
709
|
+
rescue SmartRAG::Errors::QueryProcessingError => e
|
|
710
|
+
# 处理查询错误
|
|
711
|
+
rescue SmartRAG::Errors::EmbeddingGenerationError => e
|
|
712
|
+
# 处理嵌入错误
|
|
713
|
+
end
|
|
714
|
+
```
|
|
715
|
+
|
|
716
|
+
### 数据库迁移
|
|
717
|
+
|
|
718
|
+
```ruby
|
|
719
|
+
# 运行新的迁移
|
|
720
|
+
bundle exec rake db:migrate
|
|
721
|
+
|
|
722
|
+
# 如果已有 embeddings 表,需要更新
|
|
723
|
+
class UpdateEmbeddingsFormat < Sequel::Migration
|
|
724
|
+
def up
|
|
725
|
+
alter_table :embeddings do
|
|
726
|
+
# 更新向量格式
|
|
727
|
+
set_column_type :vector, 'vector(1024)'
|
|
728
|
+
end
|
|
729
|
+
end
|
|
730
|
+
end
|
|
731
|
+
```
|
|
732
|
+
|
|
733
|
+
## 环境变量
|
|
734
|
+
|
|
735
|
+
```bash
|
|
736
|
+
# LLM API 密钥
|
|
737
|
+
export OPENAI_API_KEY="sk-..."
|
|
738
|
+
export ANTHROPIC_API_KEY="sk-ant-..."
|
|
739
|
+
|
|
740
|
+
# 数据库连接
|
|
741
|
+
export DATABASE_URL="postgresql://user:pass@localhost:5432/smart_rag"
|
|
742
|
+
|
|
743
|
+
# 可选配置
|
|
744
|
+
export SMARTRAG_LOG_LEVEL="debug"
|
|
745
|
+
export SMARTRAG_MAX_WORKERS="5"
|
|
746
|
+
```
|
|
747
|
+
|
|
748
|
+
## 完整示例
|
|
749
|
+
|
|
750
|
+
```ruby
|
|
751
|
+
require 'smart_rag'
|
|
752
|
+
require 'logger'
|
|
753
|
+
|
|
754
|
+
# 配置
|
|
755
|
+
config = {
|
|
756
|
+
database: {
|
|
757
|
+
adapter: 'postgresql',
|
|
758
|
+
host: 'localhost',
|
|
759
|
+
database: 'smart_rag_dev',
|
|
760
|
+
user: 'username',
|
|
761
|
+
password: 'password'
|
|
762
|
+
},
|
|
763
|
+
llm: {
|
|
764
|
+
provider: 'openai',
|
|
765
|
+
api_key: ENV['OPENAI_API_KEY'],
|
|
766
|
+
model: 'gpt-4'
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
# 初始化
|
|
771
|
+
smart_rag = SmartRAG::SmartRAG.new(config)
|
|
772
|
+
smart_rag.logger = Logger.new(STDOUT)
|
|
773
|
+
|
|
774
|
+
# 1. 添加文档
|
|
775
|
+
result = smart_rag.add_document('https://arxiv.org/abs/2301.00001', {
|
|
776
|
+
generate_embeddings: true,
|
|
777
|
+
generate_tags: true
|
|
778
|
+
})
|
|
779
|
+
|
|
780
|
+
puts "Added document #{result[:document_id]} with #{result[:section_count]} sections"
|
|
781
|
+
|
|
782
|
+
# 2. 创建研究主题
|
|
783
|
+
topic = smart_rag.create_topic('Machine Learning Advances', 'Latest developments in ML', {
|
|
784
|
+
tags: ['machine learning', 'AI'],
|
|
785
|
+
document_ids: [result[:document_id]]
|
|
786
|
+
})
|
|
787
|
+
|
|
788
|
+
# 3. 搜索
|
|
789
|
+
search_results = smart_rag.search('transformer architecture', {
|
|
790
|
+
search_type: 'hybrid',
|
|
791
|
+
limit: 5,
|
|
792
|
+
include_content: true,
|
|
793
|
+
include_metadata: true
|
|
794
|
+
})
|
|
795
|
+
|
|
796
|
+
puts "Found #{search_results[:results].length} results"
|
|
797
|
+
|
|
798
|
+
search_results[:results].each do |result|
|
|
799
|
+
puts "\n#{result[:section_title]}"
|
|
800
|
+
puts result[:content][0..200] + "..."
|
|
801
|
+
puts "Score: #{result[:combined_score]}"
|
|
802
|
+
end
|
|
803
|
+
|
|
804
|
+
# 4. 获取统计信息
|
|
805
|
+
stats = smart_rag.statistics
|
|
806
|
+
puts "\nTotal documents: #{stats[:document_count]}"
|
|
807
|
+
puts "Total sections: #{stats[:section_count]}"
|
|
808
|
+
|
|
809
|
+
# 5. 生成标签
|
|
810
|
+
tags = smart_rag.generate_tags('Deep learning for computer vision')
|
|
811
|
+
puts "\nGenerated tags: #{tags[:content_tags].join(', ')}"
|
|
812
|
+
```
|
|
813
|
+
|
|
814
|
+
## 支持
|
|
815
|
+
|
|
816
|
+
如有问题或需要支持,请查阅:
|
|
817
|
+
|
|
818
|
+
1. 设计文档:`design.md`
|
|
819
|
+
2. 设置文档:`SETUP.md`
|
|
820
|
+
3. 测试示例:`spec/integration/api_end_to_end_workflow_spec.rb`
|
|
821
|
+
|
|
822
|
+
## 版本信息
|
|
823
|
+
|
|
824
|
+
当前版本:1.0.0
|
|
825
|
+
|
|
826
|
+
## 许可证
|
|
827
|
+
|
|
828
|
+
MIT License
|