File size: 45,425 Bytes
11c7a1e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bd45820
 
 
 
11c7a1e
 
 
 
 
02b500d
 
 
 
11c7a1e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
02b500d
11c7a1e
 
 
02b500d
11c7a1e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
02b500d
11c7a1e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
02b500d
11c7a1e
 
 
 
 
 
 
02b500d
11c7a1e
02b500d
 
11c7a1e
02b500d
11c7a1e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
02b500d
11c7a1e
 
 
 
 
 
02b500d
 
11c7a1e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
02b500d
11c7a1e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
02b500d
11c7a1e
 
 
02b500d
11c7a1e
 
 
 
 
 
 
 
02b500d
11c7a1e
 
 
 
 
 
 
 
 
 
 
02b500d
11c7a1e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e9359fe
 
11c7a1e
 
 
 
 
 
e9359fe
 
11c7a1e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c8208d7
11c7a1e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e9359fe
 
11c7a1e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
02b500d
11c7a1e
 
 
02b500d
11c7a1e
02b500d
11c7a1e
 
 
 
 
 
 
 
 
02b500d
11c7a1e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
02b500d
11c7a1e
 
 
 
 
 
 
02b500d
11c7a1e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
02b500d
11c7a1e
02b500d
11c7a1e
02b500d
11c7a1e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
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
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
# LightRAG: Simple and Fast Retrieval-Augmented Generation

<img src="./README.assets/b2aaf634151b4706892693ffb43d9093.png" width="800" alt="LightRAG Diagram">

## 🎉 新闻

- [X] [2025.03.18]🎯📢LightRAG现已支持引文功能。
- [X] [2025.02.05]🎯📢我们团队发布了[VideoRAG](https://github.com/HKUDS/VideoRAG),用于理解超长上下文视频。
- [X] [2025.01.13]🎯📢我们团队发布了[MiniRAG](https://github.com/HKUDS/MiniRAG),使用小型模型简化RAG。
- [X] [2025.01.06]🎯📢现在您可以[使用PostgreSQL进行存储](#using-postgresql-for-storage)。
- [X] [2024.12.31]🎯📢LightRAG现在支持[通过文档ID删除](https://github.com/HKUDS/LightRAG?tab=readme-ov-file#delete)。
- [X] [2024.11.25]🎯📢LightRAG现在支持无缝集成[自定义知识图谱](https://github.com/HKUDS/LightRAG?tab=readme-ov-file#insert-custom-kg),使用户能够用自己的领域专业知识增强系统。
- [X] [2024.11.19]🎯📢LightRAG的综合指南现已在[LearnOpenCV](https://learnopencv.com/lightrag)上发布。非常感谢博客作者。
- [X] [2024.11.12]🎯📢LightRAG现在支持[Oracle Database 23ai的所有存储类型(KV、向量和图)](https://github.com/HKUDS/LightRAG/blob/main/examples/lightrag_oracle_demo.py)。
- [X] [2024.11.11]🎯📢LightRAG现在支持[通过实体名称删除实体](https://github.com/HKUDS/LightRAG?tab=readme-ov-file#delete)。
- [X] [2024.11.09]🎯📢推出[LightRAG Gui](https://lightrag-gui.streamlit.app),允许您插入、查询、可视化和下载LightRAG知识。
- [X] [2024.11.04]🎯📢现在您可以[使用Neo4J进行存储](https://github.com/HKUDS/LightRAG?tab=readme-ov-file#using-neo4j-for-storage)。
- [X] [2024.10.29]🎯📢LightRAG现在通过`textract`支持多种文件类型,包括PDF、DOC、PPT和CSV。
- [X] [2024.10.20]🎯📢我们为LightRAG添加了一个新功能:图形可视化。
- [X] [2024.10.18]🎯📢我们添加了[LightRAG介绍视频](https://youtu.be/oageL-1I0GE)的链接。感谢作者!
- [X] [2024.10.17]🎯📢我们创建了一个[Discord频道](https://discord.gg/yF2MmDJyGJ)!欢迎加入分享和讨论!🎉🎉
- [X] [2024.10.16]🎯📢LightRAG现在支持[Ollama模型](https://github.com/HKUDS/LightRAG?tab=readme-ov-file#quick-start)!
- [X] [2024.10.15]🎯📢LightRAG现在支持[Hugging Face模型](https://github.com/HKUDS/LightRAG?tab=readme-ov-file#quick-start)!

<details>
  <summary style="font-size: 1.4em; font-weight: bold; cursor: pointer; display: list-item;">
    算法流程图
  </summary>

![LightRAG索引流程图](https://learnopencv.com/wp-content/uploads/2024/11/LightRAG-VectorDB-Json-KV-Store-Indexing-Flowchart-scaled.jpg)
*图1:LightRAG索引流程图 - 图片来源:[Source](https://learnopencv.com/lightrag/)*
![LightRAG检索和查询流程图](https://learnopencv.com/wp-content/uploads/2024/11/LightRAG-Querying-Flowchart-Dual-Level-Retrieval-Generation-Knowledge-Graphs-scaled.jpg)
*图2:LightRAG检索和查询流程图 - 图片来源:[Source](https://learnopencv.com/lightrag/)*

</details>

## 安装

### 安装LightRAG核心

* 从源代码安装(推荐)

```bash
cd LightRAG
pip install -e .
```

* 从PyPI安装

```bash
pip install lightrag-hku
```

### 安装LightRAG服务器

LightRAG服务器旨在提供Web UI和API支持。Web UI便于文档索引、知识图谱探索和简单的RAG查询界面。LightRAG服务器还提供兼容Ollama的接口,旨在将LightRAG模拟为Ollama聊天模型。这使得AI聊天机器人(如Open WebUI)可以轻松访问LightRAG。

* 从PyPI安装

```bash
pip install "lightrag-hku[api]"
```

* 从源代码安装

```bash
# 如有必要,创建Python虚拟环境
# 以可编辑模式安装并支持API
pip install -e ".[api]"
```

**有关LightRAG服务器的更多信息,请参阅[LightRAG服务器](./lightrag/api/README.md)。**

## 快速开始

* [视频演示](https://www.youtube.com/watch?v=g21royNJ4fw)展示如何在本地运行LightRAG。
* 所有代码都可以在`examples`中找到。
* 如果使用OpenAI模型,请在环境中设置OpenAI API密钥:`export OPENAI_API_KEY="sk-..."`* 下载演示文本"狄更斯的圣诞颂歌":

```bash
curl https://raw.githubusercontent.com/gusye1234/nano-graphrag/main/tests/mock_data.txt > ./book.txt
```

## 查询

使用以下Python代码片段(在脚本中)初始化LightRAG并执行查询:

```python
import os
import asyncio
from lightrag import LightRAG, QueryParam
from lightrag.llm.openai import gpt_4o_mini_complete, gpt_4o_complete, openai_embed
from lightrag.kg.shared_storage import initialize_pipeline_status
from lightrag.utils import setup_logger

setup_logger("lightrag", level="INFO")

async def initialize_rag():
    rag = LightRAG(
        working_dir="your/path",
        embedding_func=openai_embed,
        llm_model_func=gpt_4o_mini_complete
    )

    await rag.initialize_storages()
    await initialize_pipeline_status()

    return rag

def main():
    # 初始化RAG实例
    rag = asyncio.run(initialize_rag())
    # 插入文本
    rag.insert("Your text")

    # 执行朴素搜索
    mode="naive"
    # 执行本地搜索
    mode="local"
    # 执行全局搜索
    mode="global"
    # 执行混合搜索
    mode="hybrid"
    # 混合模式集成知识图谱和向量检索
    mode="mix"

    rag.query(
        "这个故事的主要主题是什么?",
        param=QueryParam(mode=mode)
    )

if __name__ == "__main__":
    main()
```

### 查询参数

```python
class QueryParam:
    mode: Literal["local", "global", "hybrid", "naive", "mix"] = "global"
    """指定检索模式:
    - "local":专注于上下文相关信息。
    - "global":利用全局知识。
    - "hybrid":结合本地和全局检索方法。
    - "naive":执行基本搜索,不使用高级技术。
    - "mix":集成知识图谱和向量检索。混合模式结合知识图谱和向量搜索:
        - 同时使用结构化(KG)和非结构化(向量)信息
        - 通过分析关系和上下文提供全面的答案
        - 通过HTML img标签支持图像内容
        - 允许通过top_k参数控制检索深度
    """
    only_need_context: bool = False
    """如果为True,仅返回检索到的上下文而不生成响应。"""
    response_type: str = "Multiple Paragraphs"
    """定义响应格式。示例:'Multiple Paragraphs'(多段落), 'Single Paragraph'(单段落), 'Bullet Points'(要点列表)。"""
    top_k: int = 60
    """要检索的顶部项目数量。在'local'模式下代表实体,在'global'模式下代表关系。"""
    max_token_for_text_unit: int = 4000
    """每个检索文本块允许的最大令牌数。"""
    max_token_for_global_context: int = 4000
    """全局检索中关系描述的最大令牌分配。"""
    max_token_for_local_context: int = 4000
    """本地检索中实体描述的最大令牌分配。"""
    ids: list[str] | None = None # 仅支持PG向量数据库
    """用于过滤RAG的ID列表。"""
    model_func: Callable[..., object] | None = None
    """查询使用的LLM模型函数。如果提供了此选项,它将代替LightRAG全局模型函数。
    这允许为不同的查询模式使用不同的模型。
    """
    ...
```

> top_k的默认值可以通过环境变量TOP_K更改。

### LLM and Embedding注入

LightRAG 需要利用LLM和Embeding模型来完成文档索引和知识库查询工作。在初始化LightRAG的时候需要把阶段,需要把LLM和Embedding的操作函数注入到对象中:

<details>
<summary> <b>使用类OpenAI的API</b> </summary>

* LightRAG还支持类OpenAI的聊天/嵌入API:

```python
async def llm_model_func(
    prompt, system_prompt=None, history_messages=[], keyword_extraction=False, **kwargs
) -> str:
    return await openai_complete_if_cache(
        "solar-mini",
        prompt,
        system_prompt=system_prompt,
        history_messages=history_messages,
        api_key=os.getenv("UPSTAGE_API_KEY"),
        base_url="https://api.upstage.ai/v1/solar",
        **kwargs
    )

async def embedding_func(texts: list[str]) -> np.ndarray:
    return await openai_embed(
        texts,
        model="solar-embedding-1-large-query",
        api_key=os.getenv("UPSTAGE_API_KEY"),
        base_url="https://api.upstage.ai/v1/solar"
    )

async def initialize_rag():
    rag = LightRAG(
        working_dir=WORKING_DIR,
        llm_model_func=llm_model_func,
        embedding_func=EmbeddingFunc(
            embedding_dim=4096,
            max_token_size=8192,
            func=embedding_func
        )
    )

    await rag.initialize_storages()
    await initialize_pipeline_status()

    return rag
```

</details>

<details>
<summary> <b>使用Hugging Face模型</b> </summary>

* 如果您想使用Hugging Face模型,只需要按如下方式设置LightRAG:

参见`lightrag_hf_demo.py`

```python
# 使用Hugging Face模型初始化LightRAG
rag = LightRAG(
    working_dir=WORKING_DIR,
    llm_model_func=hf_model_complete,  # 使用Hugging Face模型进行文本生成
    llm_model_name='meta-llama/Llama-3.1-8B-Instruct',  # Hugging Face的模型名称
    # 使用Hugging Face嵌入函数
    embedding_func=EmbeddingFunc(
        embedding_dim=384,
        max_token_size=5000,
        func=lambda texts: hf_embed(
            texts,
            tokenizer=AutoTokenizer.from_pretrained("sentence-transformers/all-MiniLM-L6-v2"),
            embed_model=AutoModel.from_pretrained("sentence-transformers/all-MiniLM-L6-v2")
        )
    ),
)
```

</details>

<details>
<summary> <b>使用Ollama模型</b> </summary>
如果您想使用Ollama模型,您需要拉取计划使用的模型和嵌入模型,例如`nomic-embed-text`。

然后您只需要按如下方式设置LightRAG:

```python
# 使用Ollama模型初始化LightRAG
rag = LightRAG(
    working_dir=WORKING_DIR,
    llm_model_func=ollama_model_complete,  # 使用Ollama模型进行文本生成
    llm_model_name='your_model_name', # 您的模型名称
    # 使用Ollama嵌入函数
    embedding_func=EmbeddingFunc(
        embedding_dim=768,
        max_token_size=8192,
        func=lambda texts: ollama_embed(
            texts,
            embed_model="nomic-embed-text"
        )
    ),
)
```

* **增加上下文大小**

为了使LightRAG正常工作,上下文应至少为32k令牌。默认情况下,Ollama模型的上下文大小为8k。您可以通过以下两种方式之一实现这一点:

* **在Modelfile中增加`num_ctx`参数**

1. 拉取模型:

```bash
ollama pull qwen2
```

2. 显示模型文件:

```bash
ollama show --modelfile qwen2 > Modelfile
```

3. 编辑Modelfile,添加以下行:

```bash
PARAMETER num_ctx 32768
```

4. 创建修改后的模型:

```bash
ollama create -f Modelfile qwen2m
```

* **通过Ollama API设置`num_ctx`**

您可以使用`llm_model_kwargs`参数配置ollama:

```python
rag = LightRAG(
    working_dir=WORKING_DIR,
    llm_model_func=ollama_model_complete,  # 使用Ollama模型进行文本生成
    llm_model_name='your_model_name', # 您的模型名称
    llm_model_kwargs={"options": {"num_ctx": 32768}},
    # 使用Ollama嵌入函数
    embedding_func=EmbeddingFunc(
        embedding_dim=768,
        max_token_size=8192,
        func=lambda texts: ollama_embedding(
            texts,
            embed_model="nomic-embed-text"
        )
    ),
)
```

* **低RAM GPU**

为了在低RAM GPU上运行此实验,您应该选择小型模型并调整上下文窗口(增加上下文会增加内存消耗)。例如,在6Gb RAM的改装挖矿GPU上运行这个ollama示例需要将上下文大小设置为26k,同时使用`gemma2:2b`。它能够在`book.txt`中找到197个实体和19个关系。

</details>
<details>
<summary> <b>LlamaIndex</b> </summary>

LightRAG支持与LlamaIndex集成 (`llm/llama_index_impl.py`):

- 通过LlamaIndex与OpenAI和其他提供商集成
- 详细设置和示例请参见[LlamaIndex文档](lightrag/llm/Readme.md)

**使用示例:**

```python
# 使用LlamaIndex直接访问OpenAI
import asyncio
from lightrag import LightRAG
from lightrag.llm.llama_index_impl import llama_index_complete_if_cache, llama_index_embed
from llama_index.embeddings.openai import OpenAIEmbedding
from llama_index.llms.openai import OpenAI
from lightrag.kg.shared_storage import initialize_pipeline_status
from lightrag.utils import setup_logger

# 为LightRAG设置日志处理程序
setup_logger("lightrag", level="INFO")

async def initialize_rag():
    rag = LightRAG(
        working_dir="your/path",
        llm_model_func=llama_index_complete_if_cache,  # LlamaIndex兼容的完成函数
        embedding_func=EmbeddingFunc(    # LlamaIndex兼容的嵌入函数
            embedding_dim=1536,
            max_token_size=8192,
            func=lambda texts: llama_index_embed(texts, embed_model=embed_model)
        ),
    )

    await rag.initialize_storages()
    await initialize_pipeline_status()

    return rag

def main():
    # 初始化RAG实例
    rag = asyncio.run(initialize_rag())

    with open("./book.txt", "r", encoding="utf-8") as f:
        rag.insert(f.read())

    # 执行朴素搜索
    print(
        rag.query("这个故事的主要主题是什么?", param=QueryParam(mode="naive"))
    )

    # 执行本地搜索
    print(
        rag.query("这个故事的主要主题是什么?", param=QueryParam(mode="local"))
    )

    # 执行全局搜索
    print(
        rag.query("这个故事的主要主题是什么?", param=QueryParam(mode="global"))
    )

    # 执行混合搜索
    print(
        rag.query("这个故事的主要主题是什么?", param=QueryParam(mode="hybrid"))
    )

if __name__ == "__main__":
    main()
```

**详细文档和示例,请参见:**

- [LlamaIndex文档](lightrag/llm/Readme.md)
- [直接OpenAI示例](examples/lightrag_llamaindex_direct_demo.py)
- [LiteLLM代理示例](examples/lightrag_llamaindex_litellm_demo.py)

</details>

### 对话历史

LightRAG现在通过对话历史功能支持多轮对话。以下是使用方法:

```python
# 创建对话历史
conversation_history = [
    {"role": "user", "content": "主角对圣诞节的态度是什么?"},
    {"role": "assistant", "content": "在故事开始时,埃比尼泽·斯克鲁奇对圣诞节持非常消极的态度..."},
    {"role": "user", "content": "他的态度是如何改变的?"}
]

# 创建带有对话历史的查询参数
query_param = QueryParam(
    mode="mix",  # 或其他模式:"local"、"global"、"hybrid"
    conversation_history=conversation_history,  # 添加对话历史
    history_turns=3  # 考虑最近的对话轮数
)

# 进行考虑对话历史的查询
response = rag.query(
    "是什么导致了他性格的这种变化?",
    param=query_param
)
```

### 自定义提示词

LightRAG现在支持自定义提示,以便对系统行为进行精细控制。以下是使用方法:

```python
# 创建查询参数
query_param = QueryParam(
    mode="hybrid",  # 或其他模式:"local"、"global"、"hybrid"、"mix"和"naive"
)

# 示例1:使用默认系统提示
response_default = rag.query(
    "可再生能源的主要好处是什么?",
    param=query_param
)
print(response_default)

# 示例2:使用自定义提示
custom_prompt = """
您是环境科学领域的专家助手。请提供详细且结构化的答案,并附带示例。
---对话历史---
{history}

---知识库---
{context_data}

---响应规则---

- 目标格式和长度:{response_type}
"""
response_custom = rag.query(
    "可再生能源的主要好处是什么?",
    param=query_param,
    system_prompt=custom_prompt  # 传递自定义提示
)
print(response_custom)
```

### 关键词提取

我们引入了新函数`query_with_separate_keyword_extraction`来增强关键词提取功能。该函数将关键词提取过程与用户提示分开,专注于查询以提高提取关键词的相关性。

* 工作原理

该函数将输入分为两部分:

- `用户查询`
- `提示`

然后仅对`用户查询`执行关键词提取。这种分离确保提取过程是集中和相关的,不受`提示`中任何额外语言的影响。它还允许`提示`纯粹用于响应格式化,保持用户原始问题的意图和清晰度。

* 使用示例

这个`示例`展示了如何为教育内容定制函数,专注于为高年级学生提供详细解释。

```python
rag.query_with_separate_keyword_extraction(
    query="解释重力定律",
    prompt="提供适合学习物理的高中生的详细解释。",
    param=QueryParam(mode="hybrid")
)
```

### 插入自定义知识

```python
custom_kg = {
    "chunks": [
        {
            "content": "Alice和Bob正在合作进行量子计算研究。",
            "source_id": "doc-1"
        }
    ],
    "entities": [
        {
            "entity_name": "Alice",
            "entity_type": "person",
            "description": "Alice是一位专门研究量子物理的研究员。",
            "source_id": "doc-1"
        },
        {
            "entity_name": "Bob",
            "entity_type": "person",
            "description": "Bob是一位数学家。",
            "source_id": "doc-1"
        },
        {
            "entity_name": "量子计算",
            "entity_type": "technology",
            "description": "量子计算利用量子力学现象进行计算。",
            "source_id": "doc-1"
        }
    ],
    "relationships": [
        {
            "src_id": "Alice",
            "tgt_id": "Bob",
            "description": "Alice和Bob是研究伙伴。",
            "keywords": "合作 研究",
            "weight": 1.0,
            "source_id": "doc-1"
        },
        {
            "src_id": "Alice",
            "tgt_id": "量子计算",
            "description": "Alice进行量子计算研究。",
            "keywords": "研究 专业",
            "weight": 1.0,
            "source_id": "doc-1"
        },
        {
            "src_id": "Bob",
            "tgt_id": "量子计算",
            "description": "Bob研究量子计算。",
            "keywords": "研究 应用",
            "weight": 1.0,
            "source_id": "doc-1"
        }
    ]
}

rag.insert_custom_kg(custom_kg)
```

## 插入

<details>
  <summary> <b> 基本插入 </b></summary>

```python
# 基本插入
rag.insert("文本")
```

</details>

<details>
  <summary> <b> 批量插入 </b></summary>

```python
# 基本批量插入:一次插入多个文本
rag.insert(["文本1", "文本2",...])

# 带有自定义批量大小配置的批量插入
rag = LightRAG(
    working_dir=WORKING_DIR,
    addon_params={
        "insert_batch_size": 4  # 每批处理4个文档
    }
)

rag.insert(["文本1", "文本2", "文本3", ...])  # 文档将以4个为一批进行处理
```

`addon_params`中的`insert_batch_size`参数控制插入过程中每批处理的文档数量。这对于以下情况很有用:

- 管理大型文档集合的内存使用
- 优化处理速度
- 提供更好的进度跟踪
- 如果未指定,默认值为10

</details>

<details>
  <summary> <b> 带ID插入 </b></summary>

如果您想为文档提供自己的ID,文档数量和ID数量必须相同。

```python
# 插入单个文本,并为其提供ID
rag.insert("文本1", ids=["文本1的ID"])

# 插入多个文本,并为它们提供ID
rag.insert(["文本1", "文本2",...], ids=["文本1的ID", "文本2的ID"])
```

</details>

<details>
  <summary><b>使用管道插入</b></summary>

`apipeline_enqueue_documents``apipeline_process_enqueue_documents`函数允许您对文档进行增量插入到图中。

这对于需要在后台处理文档的场景很有用,同时仍允许主线程继续执行。

并使用例程处理新文档。

```python
rag = LightRAG(..)

await rag.apipeline_enqueue_documents(input)
# 您的循环例程
await rag.apipeline_process_enqueue_documents(input)
```

</details>

<details>
  <summary><b>插入多文件类型支持</b></summary>

`textract`支持读取TXT、DOCX、PPTX、CSV和PDF等文件类型。

```python
import textract

file_path = 'TEXT.pdf'
text_content = textract.process(file_path)

rag.insert(text_content.decode('utf-8'))
```

</details>

<details>
  <summary><b>引文功能</b></summary>

通过提供文件路径,系统确保可以将来源追溯到其原始文档。

```python
# 定义文档及其文件路径
documents = ["文档内容1", "文档内容2"]
file_paths = ["path/to/doc1.txt", "path/to/doc2.txt"]

# 插入带有文件路径的文档
rag.insert(documents, file_paths=file_paths)
```

</details>

## 存储

<details>
<summary> <b>使用Neo4J进行存储</b> </summary>

* 对于生产级场景,您很可能想要利用企业级解决方案
* 进行KG存储。推荐在Docker中运行Neo4J以进行无缝本地测试。
* 参见:https://hub.docker.com/_/neo4j

```python
export NEO4J_URI="neo4j://localhost:7687"
export NEO4J_USERNAME="neo4j"
export NEO4J_PASSWORD="password"

# 为LightRAG设置日志记录器
setup_logger("lightrag", level="INFO")

# 当您启动项目时,请确保通过指定kg="Neo4JStorage"来覆盖默认的KG:NetworkX。

# 注意:默认设置使用NetworkX
# 使用Neo4J实现初始化LightRAG。
async def initialize_rag():
    rag = LightRAG(
        working_dir=WORKING_DIR,
        llm_model_func=gpt_4o_mini_complete,  # 使用gpt_4o_mini_complete LLM模型
        graph_storage="Neo4JStorage", #<-----------覆盖KG默认值
    )

    # 初始化数据库连接
    await rag.initialize_storages()
    # 初始化文档处理的管道状态
    await initialize_pipeline_status()

    return rag
```

参见test_neo4j.py获取工作示例。

</details>

<details>
<summary> <b>使用Faiss进行存储</b> </summary>

- 安装所需依赖:

```
pip install faiss-cpu
```

如果您有GPU支持,也可以安装`faiss-gpu`。

- 这里我们使用`sentence-transformers`,但您也可以使用维度为`3072`的`OpenAIEmbedding`模型。

```python
async def embedding_func(texts: list[str]) -> np.ndarray:
    model = SentenceTransformer('all-MiniLM-L6-v2')
    embeddings = model.encode(texts, convert_to_numpy=True)
    return embeddings

# 使用LLM模型函数和嵌入函数初始化LightRAG
rag = LightRAG(
    working_dir=WORKING_DIR,
    llm_model_func=llm_model_func,
    embedding_func=EmbeddingFunc(
        embedding_dim=384,
        max_token_size=8192,
        func=embedding_func,
    ),
    vector_storage="FaissVectorDBStorage",
    vector_db_storage_cls_kwargs={
        "cosine_better_than_threshold": 0.3  # 您期望的阈值
    }
)
```

</details>

<details>
<summary> <b>使用PostgreSQL进行存储</b> </summary>

对于生产级场景,您很可能想要利用企业级解决方案。PostgreSQL可以为您提供一站式解决方案,作为KV存储、向量数据库(pgvector)和图数据库(apache AGE)。

* PostgreSQL很轻量,整个二进制发行版包括所有必要的插件可以压缩到40MB:参考[Windows发布版](https://github.com/ShanGor/apache-age-windows/releases/tag/PG17%2Fv1.5.0-rc0),它在Linux/Mac上也很容易安装。
* 如果您是初学者并想避免麻烦,推荐使用docker,请从这个镜像开始(请务必阅读概述):https://hub.docker.com/r/shangor/postgres-for-rag
* 如何开始?参考:[examples/lightrag_zhipu_postgres_demo.py](https://github.com/HKUDS/LightRAG/blob/main/examples/lightrag_zhipu_postgres_demo.py)
* 为AGE创建索引示例:(如有必要,将下面的`dickens`改为您的图名)
  ```sql
  load 'age';
  SET search_path = ag_catalog, "$user", public;
  CREATE INDEX CONCURRENTLY entity_p_idx ON dickens."Entity" (id);
  CREATE INDEX CONCURRENTLY vertex_p_idx ON dickens."_ag_label_vertex" (id);
  CREATE INDEX CONCURRENTLY directed_p_idx ON dickens."DIRECTED" (id);
  CREATE INDEX CONCURRENTLY directed_eid_idx ON dickens."DIRECTED" (end_id);
  CREATE INDEX CONCURRENTLY directed_sid_idx ON dickens."DIRECTED" (start_id);
  CREATE INDEX CONCURRENTLY directed_seid_idx ON dickens."DIRECTED" (start_id,end_id);
  CREATE INDEX CONCURRENTLY edge_p_idx ON dickens."_ag_label_edge" (id);
  CREATE INDEX CONCURRENTLY edge_sid_idx ON dickens."_ag_label_edge" (start_id);
  CREATE INDEX CONCURRENTLY edge_eid_idx ON dickens."_ag_label_edge" (end_id);
  CREATE INDEX CONCURRENTLY edge_seid_idx ON dickens."_ag_label_edge" (start_id,end_id);
  create INDEX CONCURRENTLY vertex_idx_node_id ON dickens."_ag_label_vertex" (ag_catalog.agtype_access_operator(properties, '"node_id"'::agtype));
  create INDEX CONCURRENTLY entity_idx_node_id ON dickens."Entity" (ag_catalog.agtype_access_operator(properties, '"node_id"'::agtype));
  CREATE INDEX CONCURRENTLY entity_node_id_gin_idx ON dickens."Entity" using gin(properties);
  ALTER TABLE dickens."DIRECTED" CLUSTER ON directed_sid_idx;

  -- 如有必要可以删除
  drop INDEX entity_p_idx;
  drop INDEX vertex_p_idx;
  drop INDEX directed_p_idx;
  drop INDEX directed_eid_idx;
  drop INDEX directed_sid_idx;
  drop INDEX directed_seid_idx;
  drop INDEX edge_p_idx;
  drop INDEX edge_sid_idx;
  drop INDEX edge_eid_idx;
  drop INDEX edge_seid_idx;
  drop INDEX vertex_idx_node_id;
  drop INDEX entity_idx_node_id;
  drop INDEX entity_node_id_gin_idx;
  ```
* Apache AGE的已知问题:发布版本存在以下问题:
  > 您可能会发现节点/边的属性是空的。
  > 这是发布版本的已知问题:https://github.com/apache/age/pull/1721
  >
  > 您可以从源代码编译AGE来修复它。
  >

</details>

## 删除

```python
#  删除实体:通过实体名称删除实体
rag.delete_by_entity("Project Gutenberg")

#  删除文档:通过文档ID删除与文档相关的实体和关系
rag.delete_by_doc_id("doc_id")
```

## 编辑实体和关系

LightRAG现在支持全面的知识图谱管理功能,允许您在知识图谱中创建、编辑和删除实体和关系。

<details>
<summary> <b>创建实体和关系</b> </summary>

```python
# 创建新实体
entity = rag.create_entity("Google", {
    "description": "Google是一家专注于互联网相关服务和产品的跨国科技公司。",
    "entity_type": "company"
})

# 创建另一个实体
product = rag.create_entity("Gmail", {
    "description": "Gmail是由Google开发的电子邮件服务。",
    "entity_type": "product"
})

# 创建实体之间的关系
relation = rag.create_relation("Google", "Gmail", {
    "description": "Google开发和运营Gmail。",
    "keywords": "开发 运营 服务",
    "weight": 2.0
})
```

</details>

<details>
<summary> <b>编辑实体和关系</b> </summary>

```python
# 编辑现有实体
updated_entity = rag.edit_entity("Google", {
    "description": "Google是Alphabet Inc.的子公司,成立于1998年。",
    "entity_type": "tech_company"
})

# 重命名实体(所有关系都会正确迁移)
renamed_entity = rag.edit_entity("Gmail", {
    "entity_name": "Google Mail",
    "description": "Google Mail(前身为Gmail)是一项电子邮件服务。"
})

# 编辑实体之间的关系
updated_relation = rag.edit_relation("Google", "Google Mail", {
    "description": "Google创建并维护Google Mail服务。",
    "keywords": "创建 维护 电子邮件服务",
    "weight": 3.0
})
```

</details>

所有操作都有同步和异步版本。异步版本带有前缀"a"(例如,`acreate_entity``aedit_relation`)。

#### 实体操作

- **create_entity**:创建具有指定属性的新实体
- **edit_entity**:更新现有实体的属性或重命名它

#### 关系操作

- **create_relation**:在现有实体之间创建新关系
- **edit_relation**:更新现有关系的属性

这些操作在图数据库和向量数据库组件之间保持数据一致性,确保您的知识图谱保持连贯。

## 数据导出功能

### 概述

LightRAG允许您以各种格式导出知识图谱数据,用于分析、共享和备份目的。系统支持导出实体、关系和关系数据。

### 导出功能

#### 基本用法

```python
# 基本CSV导出(默认格式)
rag.export_data("knowledge_graph.csv")

# 指定任意格式
rag.export_data("output.xlsx", file_format="excel")
```

#### 支持的不同文件格式

```python
# 以CSV格式导出数据
rag.export_data("graph_data.csv", file_format="csv")

# 导出数据到Excel表格
rag.export_data("graph_data.xlsx", file_format="excel")

# 以markdown格式导出数据
rag.export_data("graph_data.md", file_format="md")

# 导出数据为文本
rag.export_data("graph_data.txt", file_format="txt")
```

#### 附加选项

在导出中包含向量嵌入(可选):

```python
rag.export_data("complete_data.csv", include_vector_data=True)
```

### 导出数据包括

所有导出包括:

* 实体信息(名称、ID、元数据)
* 关系数据(实体之间的连接)
* 来自向量数据库的关系信息

## 实体合并

<details>
<summary> <b>合并实体及其关系</b> </summary>

LightRAG现在支持将多个实体合并为单个实体,自动处理所有关系:

```python
# 基本实体合并
rag.merge_entities(
    source_entities=["人工智能", "AI", "机器智能"],
    target_entity="AI技术"
)
```

使用自定义合并策略:

```python
# 为不同字段定义自定义合并策略
rag.merge_entities(
    source_entities=["约翰·史密斯", "史密斯博士", "J·史密斯"],
    target_entity="约翰·史密斯",
    merge_strategy={
        "description": "concatenate",  # 组合所有描述
        "entity_type": "keep_first",   # 保留第一个实体的类型
        "source_id": "join_unique"     # 组合所有唯一的源ID
    }
)
```

使用自定义目标实体数据:

```python
# 为合并后的实体指定确切值
rag.merge_entities(
    source_entities=["纽约", "NYC", "大苹果"],
    target_entity="纽约市",
    target_entity_data={
        "entity_type": "LOCATION",
        "description": "纽约市是美国人口最多的城市。",
    }
)
```

结合两种方法的高级用法:

```python
# 使用策略和自定义数据合并公司实体
rag.merge_entities(
    source_entities=["微软公司", "Microsoft Corporation", "MSFT"],
    target_entity="微软",
    merge_strategy={
        "description": "concatenate",  # 组合所有描述
        "source_id": "join_unique"     # 组合源ID
    },
    target_entity_data={
        "entity_type": "ORGANIZATION",
    }
)
```

合并实体时:

* 所有来自源实体的关系都会重定向到目标实体
* 重复的关系会被智能合并
* 防止自我关系(循环)
* 合并后删除源实体
* 保留关系权重和属性

</details>

## 缓存

<details>
  <summary> <b>清除缓存</b> </summary>

您可以使用不同模式清除LLM响应缓存:

```python
# 清除所有缓存
await rag.aclear_cache()

# 清除本地模式缓存
await rag.aclear_cache(modes=["local"])

# 清除提取缓存
await rag.aclear_cache(modes=["default"])

# 清除多个模式
await rag.aclear_cache(modes=["local", "global", "hybrid"])

# 同步版本
rag.clear_cache(modes=["local"])
```

有效的模式包括:

- `"default"`:提取缓存
- `"naive"`:朴素搜索缓存
- `"local"`:本地搜索缓存
- `"global"`:全局搜索缓存
- `"hybrid"`:混合搜索缓存
- `"mix"`:混合搜索缓存

</details>

## LightRAG初始化参数

<details>
<summary> 参数 </summary>

| **参数** | **类型** | **说明** | **默认值** |
|--------------|----------|-----------------|-------------|
| **working_dir** | `str` | 存储缓存的目录 | `lightrag_cache+timestamp` |
| **kv_storage** | `str` | 文档和文本块的存储类型。支持的类型:`JsonKVStorage`、`OracleKVStorage` | `JsonKVStorage` |
| **vector_storage** | `str` | 嵌入向量的存储类型。支持的类型:`NanoVectorDBStorage`、`OracleVectorDBStorage` | `NanoVectorDBStorage` |
| **graph_storage** | `str` | 图边和节点的存储类型。支持的类型:`NetworkXStorage`、`Neo4JStorage`、`OracleGraphStorage` | `NetworkXStorage` |
| **chunk_token_size** | `int` | 拆分文档时每个块的最大令牌大小 | `1200` |
| **chunk_overlap_token_size** | `int` | 拆分文档时两个块之间的重叠令牌大小 | `100` |
| **tiktoken_model_name** | `str` | 用于计算令牌数的Tiktoken编码器的模型名称 | `gpt-4o-mini` |
| **entity_extract_max_gleaning** | `int` | 实体提取过程中的循环次数,附加历史消息 | `1` |
| **entity_summary_to_max_tokens** | `int` | 每个实体摘要的最大令牌大小 | `500` |
| **node_embedding_algorithm** | `str` | 节点嵌入算法(当前未使用) | `node2vec` |
| **node2vec_params** | `dict` | 节点嵌入的参数 | `{"dimensions": 1536,"num_walks": 10,"walk_length": 40,"window_size": 2,"iterations": 3,"random_seed": 3,}` |
| **embedding_func** | `EmbeddingFunc` | 从文本生成嵌入向量的函数 | `openai_embed` |
| **embedding_batch_num** | `int` | 嵌入过程的最大批量大小(每批发送多个文本) | `32` |
| **embedding_func_max_async** | `int` | 最大并发异步嵌入进程数 | `16` |
| **llm_model_func** | `callable` | LLM生成的函数 | `gpt_4o_mini_complete` |
| **llm_model_name** | `str` | 用于生成的LLM模型名称 | `meta-llama/Llama-3.2-1B-Instruct` |
| **llm_model_max_token_size** | `int` | LLM生成的最大令牌大小(影响实体关系摘要) | `32768`(默认值由环境变量MAX_TOKENS更改) |
| **llm_model_max_async** | `int` | 最大并发异步LLM进程数 | `4`(默认值由环境变量MAX_ASYNC更改) |
| **llm_model_kwargs** | `dict` | LLM生成的附加参数 | |
| **vector_db_storage_cls_kwargs** | `dict` | 向量数据库的附加参数,如设置节点和关系检索的阈值 | cosine_better_than_threshold: 0.2(默认值由环境变量COSINE_THRESHOLD更改) |
| **enable_llm_cache** | `bool` | 如果为`TRUE`,将LLM结果存储在缓存中;重复的提示返回缓存的响应 | `TRUE` |
| **enable_llm_cache_for_entity_extract** | `bool` | 如果为`TRUE`,将实体提取的LLM结果存储在缓存中;适合初学者调试应用程序 | `TRUE` |
| **addon_params** | `dict` | 附加参数,例如`{"example_number": 1, "language": "Simplified Chinese", "entity_types": ["organization", "person", "geo", "event"], "insert_batch_size": 10}`:设置示例限制、输出语言和文档处理的批量大小 | `example_number: 所有示例, language: English, insert_batch_size: 10` |
| **convert_response_to_json_func** | `callable` | 未使用 | `convert_response_to_json` |
| **embedding_cache_config** | `dict` | 问答缓存的配置。包含三个参数:`enabled`:布尔值,启用/禁用缓存查找功能。启用时,系统将在生成新答案之前检查缓存的响应。`similarity_threshold`:浮点值(0-1),相似度阈值。当新问题与缓存问题的相似度超过此阈值时,将直接返回缓存的答案而不调用LLM。`use_llm_check`:布尔值,启用/禁用LLM相似度验证。启用时,在返回缓存答案之前,将使用LLM作为二次检查来验证问题之间的相似度。 | 默认:`{"enabled": False, "similarity_threshold": 0.95, "use_llm_check": False}` |

</details>

## 错误处理

<details>
<summary>点击查看错误处理详情</summary>

API包括全面的错误处理:

- 文件未找到错误(404)
- 处理错误(500)
- 支持多种文件编码(UTF-8和GBK)

</details>

## LightRAG API

LightRAG服务器旨在提供Web UI和API支持。**有关LightRAG服务器的更多信息,请参阅[LightRAG服务器](./lightrag/api/README.md)。**

## 知识图谱可视化

LightRAG服务器提供全面的知识图谱可视化功能。它支持各种重力布局、节点查询、子图过滤等。**有关LightRAG服务器的更多信息,请参阅[LightRAG服务器](./lightrag/api/README.md)。**

![iShot_2025-03-23_12.40.08](./README.assets/iShot_2025-03-23_12.40.08.png)

## 评估

### 数据集

LightRAG使用的数据集可以从[TommyChien/UltraDomain](https://huggingface.co/datasets/TommyChien/UltraDomain)下载。

### 生成查询

LightRAG使用以下提示生成高级查询,相应的代码在`example/generate_query.py`中。

<details>
<summary> 提示 </summary>

```python
给定以下数据集描述:

{description}

请识别5个可能会使用此数据集的潜在用户。对于每个用户,列出他们会使用此数据集执行的5个任务。然后,对于每个(用户,任务)组合,生成5个需要对整个数据集有高级理解的问题。

按以下结构输出结果:
- 用户1:[用户描述]
    - 任务1:[任务描述]
        - 问题1:
        - 问题2:
        - 问题3:
        - 问题4:
        - 问题5:
    - 任务2:[任务描述]
        ...
    - 任务5:[任务描述]
- 用户2:[用户描述]
    ...
- 用户5:[用户描述]
    ...
```

</details>

### 批量评估

为了评估两个RAG系统在高级查询上的性能,LightRAG使用以下提示,具体代码可在`example/batch_eval.py`中找到。

<details>
<summary> 提示 </summary>

```python
---角色---
您是一位专家,负责根据三个标准评估同一问题的两个答案:**全面性**、**多样性**和**赋能性**。
---目标---
您将根据三个标准评估同一问题的两个答案:**全面性**、**多样性**和**赋能性**。

- **全面性**:答案提供了多少细节来涵盖问题的所有方面和细节?
- **多样性**:答案在提供关于问题的不同视角和见解方面有多丰富多样?
- **赋能性**:答案在多大程度上帮助读者理解并对主题做出明智判断?

对于每个标准,选择更好的答案(答案1或答案2)并解释原因。然后,根据这三个类别选择总体赢家。

这是问题:
{query}

这是两个答案:

**答案1:**
{answer1}

**答案2:**
{answer2}

使用上述三个标准评估两个答案,并为每个标准提供详细解释。

以下列JSON格式输出您的评估:

{{
    "全面性": {{
        "获胜者": "[答案1或答案2]",
        "解释": "[在此提供解释]"
    }},
    "赋能性": {{
        "获胜者": "[答案1或答案2]",
        "解释": "[在此提供解释]"
    }},
    "总体获胜者": {{
        "获胜者": "[答案1或答案2]",
        "解释": "[根据三个标准总结为什么这个答案是总体获胜者]"
    }}
}}
```

</details>

### 总体性能表

|                      |**农业**|            |**计算机科学**|            |**法律**|            |**混合**|            |
|----------------------|---------------|------------|------|------------|---------|------------|-------|------------|
|                      |NaiveRAG|**LightRAG**|NaiveRAG|**LightRAG**|NaiveRAG|**LightRAG**|NaiveRAG|**LightRAG**|
|**全面性**|32.4%|**67.6%**|38.4%|**61.6%**|16.4%|**83.6%**|38.8%|**61.2%**|
|**多样性**|23.6%|**76.4%**|38.0%|**62.0%**|13.6%|**86.4%**|32.4%|**67.6%**|
|**赋能性**|32.4%|**67.6%**|38.8%|**61.2%**|16.4%|**83.6%**|42.8%|**57.2%**|
|**总体**|32.4%|**67.6%**|38.8%|**61.2%**|15.2%|**84.8%**|40.0%|**60.0%**|
|                      |RQ-RAG|**LightRAG**|RQ-RAG|**LightRAG**|RQ-RAG|**LightRAG**|RQ-RAG|**LightRAG**|
|**全面性**|31.6%|**68.4%**|38.8%|**61.2%**|15.2%|**84.8%**|39.2%|**60.8%**|
|**多样性**|29.2%|**70.8%**|39.2%|**60.8%**|11.6%|**88.4%**|30.8%|**69.2%**|
|**赋能性**|31.6%|**68.4%**|36.4%|**63.6%**|15.2%|**84.8%**|42.4%|**57.6%**|
|**总体**|32.4%|**67.6%**|38.0%|**62.0%**|14.4%|**85.6%**|40.0%|**60.0%**|
|                      |HyDE|**LightRAG**|HyDE|**LightRAG**|HyDE|**LightRAG**|HyDE|**LightRAG**|
|**全面性**|26.0%|**74.0%**|41.6%|**58.4%**|26.8%|**73.2%**|40.4%|**59.6%**|
|**多样性**|24.0%|**76.0%**|38.8%|**61.2%**|20.0%|**80.0%**|32.4%|**67.6%**|
|**赋能性**|25.2%|**74.8%**|40.8%|**59.2%**|26.0%|**74.0%**|46.0%|**54.0%**|
|**总体**|24.8%|**75.2%**|41.6%|**58.4%**|26.4%|**73.6%**|42.4%|**57.6%**|
|                      |GraphRAG|**LightRAG**|GraphRAG|**LightRAG**|GraphRAG|**LightRAG**|GraphRAG|**LightRAG**|
|**全面性**|45.6%|**54.4%**|48.4%|**51.6%**|48.4%|**51.6%**|**50.4%**|49.6%|
|**多样性**|22.8%|**77.2%**|40.8%|**59.2%**|26.4%|**73.6%**|36.0%|**64.0%**|
|**赋能性**|41.2%|**58.8%**|45.2%|**54.8%**|43.6%|**56.4%**|**50.8%**|49.2%|
|**总体**|45.2%|**54.8%**|48.0%|**52.0%**|47.2%|**52.8%**|**50.4%**|49.6%|

## 复现

所有代码都可以在`./reproduce`目录中找到。

### 步骤0 提取唯一上下文

首先,我们需要提取数据集中的唯一上下文。

<details>
<summary> 代码 </summary>

```python
def extract_unique_contexts(input_directory, output_directory):

    os.makedirs(output_directory, exist_ok=True)

    jsonl_files = glob.glob(os.path.join(input_directory, '*.jsonl'))
    print(f"找到{len(jsonl_files)}个JSONL文件。")

    for file_path in jsonl_files:
        filename = os.path.basename(file_path)
        name, ext = os.path.splitext(filename)
        output_filename = f"{name}_unique_contexts.json"
        output_path = os.path.join(output_directory, output_filename)

        unique_contexts_dict = {}

        print(f"处理文件:{filename}")

        try:
            with open(file_path, 'r', encoding='utf-8') as infile:
                for line_number, line in enumerate(infile, start=1):
                    line = line.strip()
                    if not line:
                        continue
                    try:
                        json_obj = json.loads(line)
                        context = json_obj.get('context')
                        if context and context not in unique_contexts_dict:
                            unique_contexts_dict[context] = None
                    except json.JSONDecodeError as e:
                        print(f"文件{filename}第{line_number}行JSON解码错误:{e}")
        except FileNotFoundError:
            print(f"未找到文件:{filename}")
            continue
        except Exception as e:
            print(f"处理文件{filename}时发生错误:{e}")
            continue

        unique_contexts_list = list(unique_contexts_dict.keys())
        print(f"文件{filename}中有{len(unique_contexts_list)}个唯一的`context`条目。")

        try:
            with open(output_path, 'w', encoding='utf-8') as outfile:
                json.dump(unique_contexts_list, outfile, ensure_ascii=False, indent=4)
            print(f"唯一的`context`条目已保存到:{output_filename}")
        except Exception as e:
            print(f"保存到文件{output_filename}时发生错误:{e}")

    print("所有文件已处理完成。")

```

</details>

### 步骤1 插入上下文

对于提取的上下文,我们将它们插入到LightRAG系统中。

<details>
<summary> 代码 </summary>

```python
def insert_text(rag, file_path):
    with open(file_path, mode='r') as f:
        unique_contexts = json.load(f)

    retries = 0
    max_retries = 3
    while retries < max_retries:
        try:
            rag.insert(unique_contexts)
            break
        except Exception as e:
            retries += 1
            print(f"插入失败,重试({retries}/{max_retries}),错误:{e}")
            time.sleep(10)
    if retries == max_retries:
        print("超过最大重试次数后插入失败")
```

</details>

### 步骤2 生成查询

我们从数据集中每个上下文的前半部分和后半部分提取令牌,然后将它们组合为数据集描述以生成查询。

<details>
<summary> 代码 </summary>

```python
tokenizer = GPT2Tokenizer.from_pretrained('gpt2')

def get_summary(context, tot_tokens=2000):
    tokens = tokenizer.tokenize(context)
    half_tokens = tot_tokens // 2

    start_tokens = tokens[1000:1000 + half_tokens]
    end_tokens = tokens[-(1000 + half_tokens):1000]

    summary_tokens = start_tokens + end_tokens
    summary = tokenizer.convert_tokens_to_string(summary_tokens)

    return summary
```

</details>

### 步骤3 查询

对于步骤2中生成的查询,我们将提取它们并查询LightRAG。

<details>
<summary> 代码 </summary>

```python
def extract_queries(file_path):
    with open(file_path, 'r') as f:
        data = f.read()

    data = data.replace('**', '')

    queries = re.findall(r'- Question \d+: (.+)', data)

    return queries
```

</details>

## Star历史

<a href="https://star-history.com/#HKUDS/LightRAG&Date">
 <picture>
   <source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=HKUDS/LightRAG&type=Date&theme=dark" />
   <source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=HKUDS/LightRAG&type=Date" />
   <img alt="Star History Chart" src="https://api.star-history.com/svg?repos=HKUDS/LightRAG&type=Date" />
 </picture>
</a>

## 贡献

感谢所有贡献者!

<a href="https://github.com/HKUDS/LightRAG/graphs/contributors">
  <img src="https://contrib.rocks/image?repo=HKUDS/LightRAG" />
</a>

## 🌟引用

```python
@article{guo2024lightrag,
title={LightRAG: Simple and Fast Retrieval-Augmented Generation},
author={Zirui Guo and Lianghao Xia and Yanhua Yu and Tu Ao and Chao Huang},
year={2024},
eprint={2410.05779},
archivePrefix={arXiv},
primaryClass={cs.IR}
}
```

**感谢您对我们工作的关注!**