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.
Files changed (90) hide show
  1. checksums.yaml +4 -4
  2. data/.env.example +252 -0
  3. data/.rspec +2 -0
  4. data/AGENTS.md +33 -0
  5. data/API_DOCUMENTATION.md +828 -0
  6. data/CHANGELOG.md +16 -1
  7. data/ER-diagram.mmd +144 -0
  8. data/Gemfile +50 -0
  9. data/Gemfile.lock +398 -0
  10. data/Hybrid_Reranking.md +171 -0
  11. data/README.en.md +420 -28
  12. data/README.md +534 -63
  13. data/Rakefile +268 -0
  14. data/SETUP_GUIDE.md +650 -0
  15. data/SmartChunking.md +180 -0
  16. data/USAGE_EXAMPLES.md +1002 -0
  17. data/config/llm_config.yml +4 -2
  18. data/config/smart_rag.yml +45 -1
  19. data/config.ru +15 -0
  20. data/db/migrations/006_create_text_search_configs.rb +3 -2
  21. data/db/migrations/008_create_embeddings.rb +5 -4
  22. data/db/migrations/012_add_metadata_to_source_sections.rb +11 -0
  23. data/db/migrations/013_create_media_jobs.rb +25 -0
  24. data/db/migrations/014_add_media_job_operations_indexes.rb +11 -0
  25. data/db/migrations/015_add_media_leases_and_objects.rb +80 -0
  26. data/db/migrations/016_add_document_principals_and_staging_references.rb +38 -0
  27. data/db/migrations/017_add_media_job_request_fingerprint.rb +48 -0
  28. data/db/seeds/text_search_configs.sql +3 -3
  29. data/design.md +1057 -0
  30. data/docs/API_DOCUMENTATION.md +838 -0
  31. data/docs/DOCUMENTATION_INDEX.en.md +60 -0
  32. data/docs/DOCUMENTATION_INDEX.md +65 -0
  33. data/docs/FIX_SUMMARY.md +256 -0
  34. data/docs/FIX_SUMMARY_COMPLETE.md +273 -0
  35. data/docs/Hybrid_Reranking.md +171 -0
  36. data/docs/MIGRATION_GUIDE.md +151 -0
  37. data/docs/PERFORMANCE_GUIDE.md +58 -0
  38. data/docs/SETUP_GUIDE.md +659 -0
  39. data/docs/SmartChunking.md +180 -0
  40. data/docs/USAGE_EXAMPLES.md +1008 -0
  41. data/docs/design.md +1057 -0
  42. data/docs/evidence_pack.md +211 -0
  43. data/docs/requirements.md +376 -0
  44. data/docs/retrieval_plan.md +251 -0
  45. data/docs/smartrag_improvement_plan.md +201 -0
  46. data/docs/smartrag_refactor.md +216 -0
  47. data/docs/todo.md +931 -0
  48. data/examples/common.rb +1 -1
  49. data/exe/smart-rag-db +163 -0
  50. data/exe/smart-rag-media-worker +34 -0
  51. data/lib/smart_rag/config.rb +12 -0
  52. data/lib/smart_rag/core/document_processor.rb +80 -16
  53. data/lib/smart_rag/core/local_content_store.rb +51 -0
  54. data/lib/smart_rag/core/media_extractors.rb +140 -0
  55. data/lib/smart_rag/core/media_job_queue.rb +353 -0
  56. data/lib/smart_rag/core/media_metadata_extractor.rb +188 -0
  57. data/lib/smart_rag/core/media_object_registry.rb +79 -0
  58. data/lib/smart_rag/core/media_processor.rb +228 -0
  59. data/lib/smart_rag/core/media_safety_policy.rb +61 -0
  60. data/lib/smart_rag/core/s3_content_store.rb +78 -0
  61. data/lib/smart_rag/core/transcript_normalizer.rb +44 -0
  62. data/lib/smart_rag/core/video_semantic_extractor.rb +130 -0
  63. data/lib/smart_rag/http_access_policy.rb +86 -0
  64. data/lib/smart_rag/http_app.rb +188 -0
  65. data/lib/smart_rag/models/embedding.rb +1 -1
  66. data/lib/smart_rag/models/research_topic.rb +1 -1
  67. data/lib/smart_rag/models/research_topic_section.rb +5 -0
  68. data/lib/smart_rag/models/research_topic_tag.rb +5 -0
  69. data/lib/smart_rag/models/search_log.rb +1 -1
  70. data/lib/smart_rag/models/section_fts.rb +5 -0
  71. data/lib/smart_rag/models/section_tag.rb +5 -0
  72. data/lib/smart_rag/models/source_document.rb +1 -1
  73. data/lib/smart_rag/models/source_section.rb +1 -1
  74. data/lib/smart_rag/models/tag.rb +1 -1
  75. data/lib/smart_rag/models/text_search_config.rb +5 -0
  76. data/lib/smart_rag/retrieve.rb +72 -1
  77. data/lib/smart_rag/services/embedding_service.rb +1 -1
  78. data/lib/smart_rag/services/fulltext_search_service.rb +11 -13
  79. data/lib/smart_rag/services/hybrid_search_service.rb +15 -11
  80. data/lib/smart_rag/services/summarization_service.rb +1 -1
  81. data/lib/smart_rag/services/tag_service.rb +1 -1
  82. data/lib/smart_rag/version.rb +1 -1
  83. data/lib/smart_rag.rb +264 -30
  84. data/patch_language.rb +27 -0
  85. data/requirements.md +376 -0
  86. data/source_documents_export.json +11072 -0
  87. data/todo.md +931 -0
  88. data/workers/analyze_content.rb +6 -2
  89. data/workers/get_embedding.rb +1 -1
  90. 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