AutoRAG 0.0.0__py3-none-any.whl

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 (184) hide show
  1. autorag/__init__.py +82 -0
  2. autorag/chunker.py +51 -0
  3. autorag/cli.py +209 -0
  4. autorag/dashboard.py +199 -0
  5. autorag/data/__init__.py +109 -0
  6. autorag/data/chunk/__init__.py +2 -0
  7. autorag/data/chunk/base.py +128 -0
  8. autorag/data/chunk/langchain_chunk.py +76 -0
  9. autorag/data/chunk/llama_index_chunk.py +96 -0
  10. autorag/data/chunk/run.py +38 -0
  11. autorag/data/legacy/__init__.py +0 -0
  12. autorag/data/legacy/corpus/__init__.py +2 -0
  13. autorag/data/legacy/corpus/langchain.py +47 -0
  14. autorag/data/legacy/corpus/llama_index.py +93 -0
  15. autorag/data/legacy/qacreation/__init__.py +6 -0
  16. autorag/data/legacy/qacreation/base.py +239 -0
  17. autorag/data/legacy/qacreation/llama_index.py +253 -0
  18. autorag/data/legacy/qacreation/llama_index_default_prompt.txt +54 -0
  19. autorag/data/legacy/qacreation/ragas.py +75 -0
  20. autorag/data/legacy/qacreation/simple.py +99 -0
  21. autorag/data/parse/__init__.py +1 -0
  22. autorag/data/parse/base.py +79 -0
  23. autorag/data/parse/clova.py +194 -0
  24. autorag/data/parse/langchain_parse.py +87 -0
  25. autorag/data/parse/llamaparse.py +126 -0
  26. autorag/data/parse/run.py +141 -0
  27. autorag/data/parse/table_hybrid_parse.py +134 -0
  28. autorag/data/qa/__init__.py +3 -0
  29. autorag/data/qa/evolve/__init__.py +0 -0
  30. autorag/data/qa/evolve/llama_index_query_evolve.py +64 -0
  31. autorag/data/qa/evolve/openai_query_evolve.py +81 -0
  32. autorag/data/qa/evolve/prompt.py +288 -0
  33. autorag/data/qa/extract_evidence.py +1 -0
  34. autorag/data/qa/filter/__init__.py +0 -0
  35. autorag/data/qa/filter/dontknow.py +117 -0
  36. autorag/data/qa/filter/passage_dependency.py +88 -0
  37. autorag/data/qa/filter/prompt.py +73 -0
  38. autorag/data/qa/generation_gt/__init__.py +0 -0
  39. autorag/data/qa/generation_gt/base.py +16 -0
  40. autorag/data/qa/generation_gt/llama_index_gen_gt.py +41 -0
  41. autorag/data/qa/generation_gt/openai_gen_gt.py +84 -0
  42. autorag/data/qa/generation_gt/prompt.py +27 -0
  43. autorag/data/qa/query/__init__.py +0 -0
  44. autorag/data/qa/query/llama_gen_query.py +82 -0
  45. autorag/data/qa/query/openai_gen_query.py +95 -0
  46. autorag/data/qa/query/prompt.py +201 -0
  47. autorag/data/qa/sample.py +26 -0
  48. autorag/data/qa/schema.py +322 -0
  49. autorag/data/utils/__init__.py +0 -0
  50. autorag/data/utils/util.py +103 -0
  51. autorag/deploy/__init__.py +9 -0
  52. autorag/deploy/api.py +303 -0
  53. autorag/deploy/base.py +235 -0
  54. autorag/deploy/gradio.py +74 -0
  55. autorag/deploy/swagger.yml +202 -0
  56. autorag/embedding/__init__.py +0 -0
  57. autorag/embedding/base.py +144 -0
  58. autorag/embedding/vllm.py +256 -0
  59. autorag/evaluation/__init__.py +3 -0
  60. autorag/evaluation/generation.py +88 -0
  61. autorag/evaluation/metric/__init__.py +22 -0
  62. autorag/evaluation/metric/deepeval_prompt.py +322 -0
  63. autorag/evaluation/metric/g_eval_prompts/coh_detailed.txt +32 -0
  64. autorag/evaluation/metric/g_eval_prompts/con_detailed.txt +33 -0
  65. autorag/evaluation/metric/g_eval_prompts/flu_detailed.txt +26 -0
  66. autorag/evaluation/metric/g_eval_prompts/rel_detailed.txt +33 -0
  67. autorag/evaluation/metric/generation.py +504 -0
  68. autorag/evaluation/metric/retrieval.py +115 -0
  69. autorag/evaluation/metric/retrieval_contents.py +65 -0
  70. autorag/evaluation/metric/util.py +88 -0
  71. autorag/evaluation/retrieval.py +83 -0
  72. autorag/evaluation/retrieval_contents.py +65 -0
  73. autorag/evaluation/util.py +43 -0
  74. autorag/evaluator.py +559 -0
  75. autorag/node_line.py +65 -0
  76. autorag/nodes/__init__.py +0 -0
  77. autorag/nodes/generator/__init__.py +4 -0
  78. autorag/nodes/generator/base.py +103 -0
  79. autorag/nodes/generator/llama_index_llm.py +169 -0
  80. autorag/nodes/generator/openai_llm.py +329 -0
  81. autorag/nodes/generator/run.py +148 -0
  82. autorag/nodes/generator/vllm.py +147 -0
  83. autorag/nodes/generator/vllm_api.py +191 -0
  84. autorag/nodes/hybridretrieval/__init__.py +2 -0
  85. autorag/nodes/hybridretrieval/base.py +58 -0
  86. autorag/nodes/hybridretrieval/hybrid_cc.py +227 -0
  87. autorag/nodes/hybridretrieval/hybrid_rrf.py +149 -0
  88. autorag/nodes/hybridretrieval/run.py +137 -0
  89. autorag/nodes/lexicalretrieval/__init__.py +1 -0
  90. autorag/nodes/lexicalretrieval/bm25.py +381 -0
  91. autorag/nodes/lexicalretrieval/run.py +148 -0
  92. autorag/nodes/passageaugmenter/__init__.py +2 -0
  93. autorag/nodes/passageaugmenter/base.py +76 -0
  94. autorag/nodes/passageaugmenter/pass_passage_augmenter.py +43 -0
  95. autorag/nodes/passageaugmenter/prev_next_augmenter.py +155 -0
  96. autorag/nodes/passageaugmenter/run.py +131 -0
  97. autorag/nodes/passagecompressor/__init__.py +4 -0
  98. autorag/nodes/passagecompressor/base.py +78 -0
  99. autorag/nodes/passagecompressor/longllmlingua.py +115 -0
  100. autorag/nodes/passagecompressor/pass_compressor.py +16 -0
  101. autorag/nodes/passagecompressor/refine.py +54 -0
  102. autorag/nodes/passagecompressor/run.py +186 -0
  103. autorag/nodes/passagecompressor/tree_summarize.py +56 -0
  104. autorag/nodes/passagefilter/__init__.py +6 -0
  105. autorag/nodes/passagefilter/base.py +40 -0
  106. autorag/nodes/passagefilter/pass_passage_filter.py +14 -0
  107. autorag/nodes/passagefilter/percentile_cutoff.py +58 -0
  108. autorag/nodes/passagefilter/recency.py +105 -0
  109. autorag/nodes/passagefilter/run.py +138 -0
  110. autorag/nodes/passagefilter/similarity_percentile_cutoff.py +134 -0
  111. autorag/nodes/passagefilter/similarity_threshold_cutoff.py +112 -0
  112. autorag/nodes/passagefilter/threshold_cutoff.py +78 -0
  113. autorag/nodes/passagereranker/__init__.py +16 -0
  114. autorag/nodes/passagereranker/base.py +44 -0
  115. autorag/nodes/passagereranker/cohere.py +118 -0
  116. autorag/nodes/passagereranker/colbert.py +213 -0
  117. autorag/nodes/passagereranker/flag_embedding.py +112 -0
  118. autorag/nodes/passagereranker/flag_embedding_llm.py +101 -0
  119. autorag/nodes/passagereranker/flashrank.py +245 -0
  120. autorag/nodes/passagereranker/jina.py +115 -0
  121. autorag/nodes/passagereranker/koreranker.py +136 -0
  122. autorag/nodes/passagereranker/mixedbreadai.py +126 -0
  123. autorag/nodes/passagereranker/monot5.py +190 -0
  124. autorag/nodes/passagereranker/openvino.py +191 -0
  125. autorag/nodes/passagereranker/pass_reranker.py +31 -0
  126. autorag/nodes/passagereranker/rankgpt.py +170 -0
  127. autorag/nodes/passagereranker/run.py +145 -0
  128. autorag/nodes/passagereranker/sentence_transformer.py +129 -0
  129. autorag/nodes/passagereranker/tart/__init__.py +1 -0
  130. autorag/nodes/passagereranker/tart/modeling_enc_t5.py +152 -0
  131. autorag/nodes/passagereranker/tart/tart.py +139 -0
  132. autorag/nodes/passagereranker/tart/tokenization_enc_t5.py +112 -0
  133. autorag/nodes/passagereranker/time_reranker.py +72 -0
  134. autorag/nodes/passagereranker/upr.py +160 -0
  135. autorag/nodes/passagereranker/voyageai.py +109 -0
  136. autorag/nodes/promptmaker/__init__.py +12 -0
  137. autorag/nodes/promptmaker/base.py +32 -0
  138. autorag/nodes/promptmaker/chat_fstring.py +73 -0
  139. autorag/nodes/promptmaker/fstring.py +49 -0
  140. autorag/nodes/promptmaker/long_context_reorder.py +83 -0
  141. autorag/nodes/promptmaker/run.py +283 -0
  142. autorag/nodes/promptmaker/window_replacement.py +85 -0
  143. autorag/nodes/queryexpansion/__init__.py +4 -0
  144. autorag/nodes/queryexpansion/base.py +62 -0
  145. autorag/nodes/queryexpansion/hyde.py +43 -0
  146. autorag/nodes/queryexpansion/multi_query_expansion.py +57 -0
  147. autorag/nodes/queryexpansion/pass_query_expansion.py +22 -0
  148. autorag/nodes/queryexpansion/query_decompose.py +111 -0
  149. autorag/nodes/queryexpansion/run.py +308 -0
  150. autorag/nodes/retrieval/__init__.py +0 -0
  151. autorag/nodes/retrieval/base.py +127 -0
  152. autorag/nodes/retrieval/run_util.py +152 -0
  153. autorag/nodes/semanticretrieval/__init__.py +1 -0
  154. autorag/nodes/semanticretrieval/run.py +148 -0
  155. autorag/nodes/semanticretrieval/vectordb.py +339 -0
  156. autorag/nodes/util.py +16 -0
  157. autorag/parser.py +37 -0
  158. autorag/schema/__init__.py +3 -0
  159. autorag/schema/base.py +35 -0
  160. autorag/schema/metricinput.py +99 -0
  161. autorag/schema/module.py +24 -0
  162. autorag/schema/node.py +144 -0
  163. autorag/strategy.py +165 -0
  164. autorag/support.py +235 -0
  165. autorag/utils/__init__.py +8 -0
  166. autorag/utils/cast.py +45 -0
  167. autorag/utils/preprocess.py +149 -0
  168. autorag/utils/util.py +759 -0
  169. autorag/validator.py +98 -0
  170. autorag/vectordb/__init__.py +75 -0
  171. autorag/vectordb/base.py +73 -0
  172. autorag/vectordb/chroma.py +118 -0
  173. autorag/vectordb/couchbase.py +239 -0
  174. autorag/vectordb/milvus.py +169 -0
  175. autorag/vectordb/pinecone.py +121 -0
  176. autorag/vectordb/qdrant.py +155 -0
  177. autorag/vectordb/weaviate.py +184 -0
  178. autorag/web.py +81 -0
  179. autorag-0.0.0.dist-info/METADATA +780 -0
  180. autorag-0.0.0.dist-info/RECORD +184 -0
  181. autorag-0.0.0.dist-info/WHEEL +5 -0
  182. autorag-0.0.0.dist-info/entry_points.txt +2 -0
  183. autorag-0.0.0.dist-info/licenses/LICENSE +201 -0
  184. autorag-0.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,288 @@
1
+ # The RAGAS prompts are coming from RAGAS under Apache-2.0 License. (English version) (the AutoRAG team translates Korean version prompt)
2
+ # You can see the original prompts at the RAGAS library at https://github.com/explodinggradients/ragas/blob/main/src/ragas/testset/prompts.py
3
+ from llama_index.core.base.llms.types import ChatMessage, MessageRole
4
+
5
+ QUERY_EVOLVE_PROMPT = {
6
+ "conditional_evolve_ragas": {
7
+ "en": [
8
+ ChatMessage(
9
+ role=MessageRole.SYSTEM,
10
+ content="""Rewrite the provided question to increase its complexity by introducing a conditional element.
11
+ The goal is to make the question more intricate by incorporating a scenario or condition that affects the context of the question.
12
+ Follow the rules given below while rewriting the question.
13
+ 1. The rewritten question should not be longer than 25 words. Use abbreviation wherever possible.
14
+ 2. The rewritten question must be reasonable and must be understood and responded by humans.
15
+ 3. The rewritten question must be fully answerable from information present context.
16
+ 4. phrases like 'provided context','according to the context?',etc are not allowed to appear in the question.
17
+ """,
18
+ ),
19
+ ChatMessage(
20
+ role=MessageRole.USER,
21
+ content="""Question : What is the function of the roots of a plant?
22
+ Context : The roots of a plant absorb water and nutrients from the soil, anchor the plant in the ground, and store food.
23
+ Output : """,
24
+ ),
25
+ ChatMessage(
26
+ role=MessageRole.ASSISTANT,
27
+ content="What dual purpose do plant roots serve concerning soil nutrients and stability?",
28
+ ),
29
+ ChatMessage(
30
+ role=MessageRole.USER,
31
+ content="""Question : How do vaccines protect against diseases?
32
+ Context : Vaccines protect against diseases by stimulating the body's immune response to produce antibodies, which recognize and combat pathogens.
33
+ Output : """,
34
+ ),
35
+ ChatMessage(
36
+ role=MessageRole.ASSISTANT,
37
+ content="How do vaccines utilize the body's immune system to defend against pathogens?",
38
+ ),
39
+ ],
40
+ "ko": [
41
+ ChatMessage(
42
+ role=MessageRole.SYSTEM,
43
+ content="""제공된 질문에 조건에 관련한 내용을 추가하여 복잡성을 높이세요.
44
+ 질문의 Context에 영향을 미치는 시나리오나 조건을 포함하여 질문을 더 복잡하게 만드는 것이 목표입니다.
45
+ 질문을 다시 작성할 때 다음 규칙을 따르십시오.
46
+ 1. 다시 작성된 질문은 100자를 넘지 않아야 합니다. 가능한 경우 약어를 사용하십시오.
47
+ 2. 다시 작성된 질문은 합리적이어야 하며 사람이 이해하고 응답할 수 있어야 합니다.
48
+ 3. 다시 작성된 질문은 현재 Context에서 완전히 답변할 수 있어야 합니다.
49
+ 4. '제공된 글', '단락에 따르면?', 'Context에 의하면' 등의 문구는 질문에 나타날 수 없습니다.
50
+ 5. 한국어로 질문을 작성하세요.
51
+ """,
52
+ ),
53
+ ChatMessage(
54
+ role=MessageRole.USER,
55
+ content="""Question: 식물의 뿌리 기능이 뭐야?
56
+ Context: 식물의 뿌리는 토양에서 물과 영양분을 흡수하고, 식물을 땅에 고정하며, 영양분을 저장합니다.
57
+ Output: """,
58
+ ),
59
+ ChatMessage(
60
+ role=MessageRole.ASSISTANT,
61
+ content="식물의 뿌리는 토양 영양분과 안정성에 대해 어떤 역할을 하나요?",
62
+ ),
63
+ ChatMessage(
64
+ role=MessageRole.USER,
65
+ content="""Question: 백신은 질병을 어떻게 예방하나요?
66
+ Context: 백신은 신체의 면역 반응을 자극하여 병원체를 인식하고 싸우는 항체를 생성함으로써 질병으로부터 보호합니다.
67
+ Output: """,
68
+ ),
69
+ ChatMessage(
70
+ role=MessageRole.ASSISTANT,
71
+ content="백신은 신체의 면역 체계를 어떻게 활용해서 질병을 예방합니까?",
72
+ ),
73
+ ],
74
+ "ja": [
75
+ ChatMessage(
76
+ role=MessageRole.SYSTEM,
77
+ content="""提供された質問に条件に関する内容を追加して、複雑さを高めます。
78
+ 質問のContextに影響を与えるシナリオや条件を含めて、質問をより複雑にすることが目標です。
79
+ 質問を再作成するときは、次のルールに従います。
80
+ 1. 再作成された質問は100文字を超えてはいけません。 可能であれば略語を使ってください
81
+ 2. 再作成された質問は合理的でなければならず、人が理解して回答できるものでなければなりません。
82
+ 3. 再作成された質問は、現在のContextで完全に答えられる必要があります。
83
+ 4. 「提供された文」、「段落によると?」、「Contextによると」などのフレーズは質問に表示されません。
84
+ 5. 日本語で質問を書きましょう。
85
+ """,
86
+ ),
87
+ ChatMessage(
88
+ role=MessageRole.USER,
89
+ content="""Question: 植物の根の機能は何ですか?
90
+ Context: 植物の根は土壌から水や栄養分を吸収し、植物を地面に固定し、栄養分を蓄えます。
91
+ Output: """,
92
+ ),
93
+ ChatMessage(
94
+ role=MessageRole.ASSISTANT,
95
+ content="植物の根は土壌栄養分と安定性に対してどのような役割をしますか?",
96
+ ),
97
+ ChatMessage(
98
+ role=MessageRole.USER,
99
+ content="""Question: ワクチンは病気をどのように予防しますか?
100
+ Context: ワクチンは、体の免疫反応を刺激して病原体を認識し、戦う抗体を生成することで病気から守ります。
101
+ Output: """,
102
+ ),
103
+ ChatMessage(
104
+ role=MessageRole.ASSISTANT,
105
+ content="ワクチンは体の免疫システムをどのように活用して病気を予防しますか?",
106
+ ),
107
+ ],
108
+ },
109
+ "reasoning_evolve_ragas": {
110
+ "en": [
111
+ ChatMessage(
112
+ role=MessageRole.SYSTEM,
113
+ content="""Complicate the given question by rewriting question into a multi-hop reasoning question based on the provided context.
114
+ Answering the question should require the reader to make multiple logical connections or inferences using the information available in given context.
115
+ Rules to follow when rewriting question:
116
+ 1. Ensure that the rewritten question can be answered entirely from the information present in the contexts.
117
+ 2. Do not frame questions that contains more than 15 words. Use abbreviation wherever possible.
118
+ 3. Make sure the question is clear and unambiguous.
119
+ 4. phrases like 'based on the provided context','according to the context',etc are not allowed to appear in the question.""",
120
+ ),
121
+ ChatMessage(
122
+ role=MessageRole.USER,
123
+ content="""Question: What is the capital of France?,
124
+ Context: France is a country in Western Europe. It has several cities, including Paris, Lyon, and Marseille. Paris is not only known for its cultural landmarks like the Eiffel Tower and the Louvre Museum but also as the administrative center.
125
+ Output: """,
126
+ ),
127
+ ChatMessage(
128
+ role=MessageRole.ASSISTANT,
129
+ content="Linking the Eiffel Tower and administrative center, which city stands as both?",
130
+ ),
131
+ ChatMessage(
132
+ role=MessageRole.USER,
133
+ content="""Question: What does the append() method do in Python?
134
+ Context: In Python, lists are used to store multiple items in a single variable. Lists are one of 4 built-in data types used to store collections of data. The append() method adds a single item to the end of a list.
135
+ Output: """,
136
+ ),
137
+ ChatMessage(
138
+ role=MessageRole.ASSISTANT,
139
+ content="If a list represents a variable collection, what method extends it by one item?",
140
+ ),
141
+ ],
142
+ "ko": [
143
+ ChatMessage(
144
+ role=MessageRole.SYSTEM,
145
+ content="""주어진 Context를 기반으로 기존 질문을 복잡하게 만들어 여러 논리적인 사고가 필요한 질문으로 다시 작성하세요.
146
+ 질문에 답하려면 주어진 Context의 정보를 사용해 여러 논리적 사고나 추론을 해야 합니다.
147
+ 질문을 다시 작성할 때 따라야 할 규칙:
148
+ 1. 다시 작성된 질문은 Context에 있는 정보만으로 완전히 답변할 수 있어야 합니다.
149
+ 2. 100자를 초과하는 질문을 작성하지 마세요. 가능한 경우 약어를 사용하세요.
150
+ 3. 질문이 명확하고 모호하지 않도록 하세요.
151
+ 4. '제공된 Context에 기반하여', '해당 단락에 따르면' 등의 문구는 질문에 포함되지 않아야 합니다.
152
+ 5. 한국어로 질문을 작성하세요.""",
153
+ ),
154
+ ChatMessage(
155
+ role=MessageRole.USER,
156
+ content="""Question: 프랑스의 수도는 어디인가요?,
157
+ Context: 프랑스는 서유럽에 있는 나라입니다. 파리, 리옹, 마르세유를 포함한 여러 도시가 있습니다. 파리는 에펠탑과 루브르 박물관 같은 문화적 랜드마크로 유명할 뿐만 아니라 행정 중심지로도 알려져 있습니다.
158
+ Output: """,
159
+ ),
160
+ ChatMessage(
161
+ role=MessageRole.ASSISTANT,
162
+ content="에펠탑과 행정 중심지, 두 단어는 어떤 도시를 가리키나요?",
163
+ ),
164
+ ChatMessage(
165
+ role=MessageRole.USER,
166
+ content="""질문: Python에서 append() 메서드는 무엇을 하나요?
167
+ 컨텍스트: Python에서 리스트는 하나의 변수에 여러 항목을 저장하는 데 사용됩니다. 리스트는 데이터를 저장하는 데 사용되는 4가지 내장 데이터 유형 중 하나입니다. append() 메서드는 리스트의 끝에 새로운 항목을 추가합니다.
168
+ 출력: """,
169
+ ),
170
+ ChatMessage(
171
+ role=MessageRole.ASSISTANT,
172
+ content="리스트가 변수들을 모아 놓은 것을 나타낸다면, 어떤 메서드를 사용해야 항목을 하나 더 추가할 수 있습니까?",
173
+ ),
174
+ ],
175
+ "ja": [
176
+ ChatMessage(
177
+ role=MessageRole.SYSTEM,
178
+ content="""与えられたContextに基づいて既存の質問を複雑にして、様々な論理的思考が必要な質問として書き直しましょう。
179
+ 質問に答えるためには、与えられたContextの情報を使って様々な論理的思考や推論をしなければなりません。
180
+ 質問を再作成するときに従うべきルール:
181
+ 1. 再作成された質問は、Contextにある情報だけで完全に答えられる必要があります。
182
+ 2. 100文字を超える質問を作成してはいけません。 可能であれば略語を使ってください。
183
+ 3. 質問が明確で曖昧にならないようにしましょう。
184
+ 4. 「提供されたContextに基づいて」、「当該段落によると」などのフレーズは、質問に含まれてはいけません。
185
+ 5. 日本語で質問を書きましょう。""",
186
+ ),
187
+ ChatMessage(
188
+ role=MessageRole.USER,
189
+ content="""Question: フランスの首都はどこですか?,
190
+ Context: フランスは西ヨーロッパにある国です。 パリ、リヨン、マルセイユを含むいくつかの都市があります。 パリはエッフェル塔やルーブル博物館のような文化的ランドマークとして有名なだけでなく、行政の中心地としても知られています。
191
+ Output: """,
192
+ ),
193
+ ChatMessage(
194
+ role=MessageRole.ASSISTANT,
195
+ content="エッフェル塔と行政の中心地、二つの単語はどんな都市を指していますか?",
196
+ ),
197
+ ChatMessage(
198
+ role=MessageRole.USER,
199
+ content="""Question: Pythonでappend() メソッドは何をしますか?
200
+ Context: Pythonで、リストは 1 つの変数に複数の項目を保存するために使用されます。 リストは、データを保存するために使用される 4 つの組み込みデータ タイプの 1 つです。 append()メソッドは、リストの最後に新しい項目を追加します。
201
+ Output: """,
202
+ ),
203
+ ChatMessage(
204
+ role=MessageRole.ASSISTANT,
205
+ content="リストが変数を集めたものである場合、どのメソッドを使えば項目を一つ追加することができますか?",
206
+ ),
207
+ ],
208
+ },
209
+ "compress_ragas": {
210
+ "en": [
211
+ ChatMessage(
212
+ role=MessageRole.SYSTEM,
213
+ content="""Rewrite the following question to make it more indirect and shorter while retaining the essence of the original question.
214
+ The goal is to create a question that conveys the same meaning but in a less direct manner. The rewritten question should shorter so use abbreviation wherever possible.""",
215
+ ),
216
+ ChatMessage(
217
+ role=MessageRole.USER,
218
+ content="""Question: What is the distance between the Earth and the Moon?
219
+ Output: """,
220
+ ),
221
+ ChatMessage(
222
+ role=MessageRole.ASSISTANT,
223
+ content="How far is the Moon from Earth?",
224
+ ),
225
+ ChatMessage(
226
+ role=MessageRole.USER,
227
+ content="""Question: What ingredients are required to bake a chocolate cake?
228
+ Output: """,
229
+ ),
230
+ ChatMessage(
231
+ role=MessageRole.ASSISTANT,
232
+ content="What's needed for a chocolate cake?",
233
+ ),
234
+ ],
235
+ "ko": [
236
+ ChatMessage(
237
+ role=MessageRole.SYSTEM,
238
+ content="""주어진 질문을 더 간접적이고 짧게 다시 작성하세요.
239
+ 목표는 질문을 원래 질문의 본질을 유지하면서 너무 직설적이지 않게 만드는 것입니다.
240
+ 약어 등을 사용하여 질문을 더 짧게 만드세요.""",
241
+ ),
242
+ ChatMessage(
243
+ role=MessageRole.USER,
244
+ content="""Question: 지구와 달 사이의 거리는 얼마입니까?
245
+ Output: """,
246
+ ),
247
+ ChatMessage(
248
+ role=MessageRole.ASSISTANT,
249
+ content="달은 지구에서 얼마나 떨어져 있나요?",
250
+ ),
251
+ ChatMessage(
252
+ role=MessageRole.USER,
253
+ content="""Question: 초콜릿 케이크를 굽기 위해 필요한 재료는 무엇입니까?
254
+ Output: """,
255
+ ),
256
+ ChatMessage(
257
+ role=MessageRole.ASSISTANT,
258
+ content="초콜릿 케이크에 필요한 것은 무엇인가요?",
259
+ ),
260
+ ],
261
+ "ja": [
262
+ ChatMessage(
263
+ role=MessageRole.SYSTEM,
264
+ content="""与えられた質問をより間接的かつ短く書き換えます。
265
+ 目標は、質問を元の質問の本質を保ちながら、あまりストレートにならないようにすることです。
266
+ 略語などを使用して、質問をより短くします。""",
267
+ ),
268
+ ChatMessage(
269
+ role=MessageRole.USER,
270
+ content="""Question: 地球と月の間の距離はどれくらいですか?
271
+ Output: """,
272
+ ),
273
+ ChatMessage(
274
+ role=MessageRole.ASSISTANT,
275
+ content="月は地球からどれくらい離れていますか?",
276
+ ),
277
+ ChatMessage(
278
+ role=MessageRole.USER,
279
+ content="""Question: チョコレートケーキを焼くために必要な材料は何ですか?
280
+ Output: """,
281
+ ),
282
+ ChatMessage(
283
+ role=MessageRole.ASSISTANT,
284
+ content="チョコレートケーキに必要なものは何ですか?",
285
+ ),
286
+ ],
287
+ },
288
+ }
@@ -0,0 +1 @@
1
+ # This module is about extracting evidence from the given retrieval gt passage
File without changes
@@ -0,0 +1,117 @@
1
+ from typing import Dict, List
2
+
3
+ from llama_index.core.base.llms.base import BaseLLM
4
+ from llama_index.core.base.llms.types import ChatMessage, MessageRole, ChatResponse
5
+ from llama_index.llms.openai.utils import to_openai_message_dicts
6
+ from openai import AsyncClient
7
+ from pydantic import BaseModel
8
+
9
+ from autorag.data.qa.filter.prompt import FILTER_PROMPT
10
+
11
+ dont_know_phrases = {
12
+ "en": [
13
+ "I don't know",
14
+ "I do not know",
15
+ "Don't know",
16
+ "Do not know",
17
+ ],
18
+ "ko": [
19
+ "몰라요",
20
+ "모르겠습니다",
21
+ "모르겠어요",
22
+ "몰라",
23
+ "내가 어떻게 알아?",
24
+ "모르겠소",
25
+ "몰라유",
26
+ "모르것는디",
27
+ "모르겠어유",
28
+ "모르겠네유",
29
+ "모르겠네요",
30
+ ],
31
+ "ja": [
32
+ "知りません",
33
+ "わかりません",
34
+ "分かりません",
35
+ "知らないです",
36
+ "よく分かってません",
37
+ "わかりかねます",
38
+ "存じません",
39
+ "お答えいたしかねます",
40
+ ],
41
+ }
42
+
43
+
44
+ def dontknow_filter_rule_based(row: Dict, lang: str = "en") -> bool:
45
+ assert "generation_gt" in row.keys(), (
46
+ "generation_gt column is not in the DataFrame."
47
+ )
48
+ dont_know_phrase = dont_know_phrases[lang]
49
+ return not any(
50
+ phrase in s for phrase in dont_know_phrase for s in row["generation_gt"]
51
+ )
52
+
53
+
54
+ class Response(BaseModel):
55
+ is_dont_know: bool
56
+
57
+
58
+ async def dontknow_filter_openai(
59
+ row: Dict,
60
+ client: AsyncClient,
61
+ model_name: str = "gpt-4o-mini-2024-07-18",
62
+ lang: str = "en",
63
+ ) -> bool:
64
+ """
65
+ This will drop rows that have a "don't know" answer.
66
+ It will drop unanswerable questions from the QA dataset.
67
+ You can use this filter with the ` batch_filter ` function at `QA` class.
68
+
69
+ :param row: The row dict from QA dataset.
70
+ :param client: The OpenAI client.
71
+ :param model_name: The model name.
72
+ You have to use gpt-4o-2024-08-06 or gpt-4o-mini-2024-07-18.
73
+ :param lang: The supported language is en, ko or ja.
74
+ :return: False if the row generation_gt is a "don't know" meaning.
75
+ """
76
+ assert "generation_gt" in row.keys(), "generation_gt column is not in the row."
77
+ system_prompt: List[ChatMessage] = FILTER_PROMPT["dontknow_filter"][lang]
78
+ result = []
79
+ for gen_gt in row["generation_gt"]:
80
+ completion = await client.beta.chat.completions.parse(
81
+ model=model_name,
82
+ messages=to_openai_message_dicts(
83
+ system_prompt + [ChatMessage(role=MessageRole.USER, content=gen_gt)]
84
+ ),
85
+ response_format=Response,
86
+ )
87
+ result.append(completion.choices[0].message.parsed.is_dont_know)
88
+ return not any(result)
89
+
90
+
91
+ async def dontknow_filter_llama_index(
92
+ row: Dict,
93
+ llm: BaseLLM,
94
+ lang: str = "en",
95
+ ) -> bool:
96
+ """
97
+ This will drop rows that have a "don't know" answer.
98
+ It will drop unanswerable questions from the QA dataset.
99
+ You can use this filter with the ` batch_filter ` function at `QA` class.
100
+
101
+ :param row: The row dict from QA dataset.
102
+ :param llm: The Llama index llm instance.
103
+ It will be good if you set max tokens to low for saving tokens.
104
+ :param lang: The supported language is en, ko or ja.
105
+ :return: False if the row generation_gt is a "don't know" meaning.
106
+ """
107
+ assert "generation_gt" in row.keys(), "generation_gt column is not in the row."
108
+ system_prompt: List[ChatMessage] = FILTER_PROMPT["dontknow_filter"][lang]
109
+ results = []
110
+ for gen_gt in row["generation_gt"]:
111
+ response: ChatResponse = await llm.achat(
112
+ messages=system_prompt
113
+ + [ChatMessage(role=MessageRole.USER, content=gen_gt)]
114
+ )
115
+ result_str = response.message.content
116
+ results.append("true" in result_str.lower().strip())
117
+ return not any(results)
@@ -0,0 +1,88 @@
1
+ from typing import Dict, List
2
+
3
+ from llama_index.core.base.llms.base import BaseLLM
4
+ from llama_index.core.base.llms.types import ChatMessage, MessageRole, ChatResponse
5
+ from llama_index.llms.openai.utils import to_openai_message_dicts
6
+ from openai import AsyncClient
7
+ from pydantic import BaseModel
8
+
9
+ from autorag.data.qa.filter.prompt import FILTER_PROMPT
10
+
11
+
12
+ class Response(BaseModel):
13
+ is_passage_dependent: bool
14
+
15
+
16
+ async def passage_dependency_filter_openai(
17
+ row: Dict,
18
+ client: AsyncClient,
19
+ model_name: str = "gpt-4o-mini-2024-07-18",
20
+ lang: str = "en",
21
+ ) -> bool:
22
+ """
23
+ This will drop passage-dependent question rows.
24
+ Passage-dependent questions are questions that the answer will change depending on what passage you choose.
25
+ The passage-dependent questions will not be good for RAG evaluation, because any retrieval system can't find the right passage with passage-dependent question.
26
+ For example, when someone asks "What is the highest score according to the table?" the answer will be different depending on the table.
27
+ And what is the table? The retrieval system can't find the right passage with this question.
28
+ You can use this filter with the ` batch_filter ` function at `QA` class.
29
+
30
+ :param row: The row dict from QA dataset.
31
+ :param client: The OpenAI client.
32
+ :param model_name: The model name.
33
+ You have to use gpt-4o-2024-08-06 or gpt-4o-mini-2024-07-18.
34
+ :param lang: The supported language is en, ko or ja.
35
+ :return: False if the row question is a passage-dependent question (to be filtered).
36
+ """
37
+ assert "query" in row.keys(), "query column is not in the row."
38
+ system_prompt: List[ChatMessage] = FILTER_PROMPT["passage_dependency"][lang]
39
+ query = row["query"]
40
+ completion = await client.beta.chat.completions.parse(
41
+ model=model_name,
42
+ messages=to_openai_message_dicts(
43
+ system_prompt
44
+ + [
45
+ ChatMessage(
46
+ role=MessageRole.USER,
47
+ content=f"Question: {query}\nIs this the question passage dependent?",
48
+ )
49
+ ]
50
+ ),
51
+ response_format=Response,
52
+ )
53
+ return not completion.choices[0].message.parsed.is_passage_dependent
54
+
55
+
56
+ async def passage_dependency_filter_llama_index(
57
+ row: Dict,
58
+ llm: BaseLLM,
59
+ lang: str = "en",
60
+ ) -> bool:
61
+ """
62
+ This will drop passage-dependent question rows.
63
+ Passage-dependent questions are questions that the answer will change depending on what passage you choose.
64
+ The passage-dependent questions will not be good for RAG evaluation, because any retrieval system can't find the right passage with passage-dependent question.
65
+ For example, when someone asks "What is the highest score according to the table?" the answer will be different depending on the table.
66
+ And what is the table? The retrieval system can't find the right passage with this question.
67
+ You can use this filter with the ` batch_filter ` function at `QA` class.
68
+
69
+ :param row: The row dict from QA dataset.
70
+ :param llm: The Llama index llm instance.
71
+ It will be good if you set max tokens to low for saving tokens.
72
+ :param lang: The supported language is en, ko or ja.
73
+ :return: False if the row question is a passage-dependent question (to be filtered).
74
+ """
75
+ assert "query" in row.keys(), "query column is not in the row."
76
+ system_prompt: List[ChatMessage] = FILTER_PROMPT["passage_dependency"][lang]
77
+ query = row["query"]
78
+ response: ChatResponse = await llm.achat(
79
+ messages=system_prompt
80
+ + [
81
+ ChatMessage(
82
+ role=MessageRole.USER,
83
+ content=f"Question: {query}\nIs this the question passage dependent?",
84
+ )
85
+ ]
86
+ )
87
+ result_str = response.message.content
88
+ return "true" not in result_str.lower().strip()
@@ -0,0 +1,73 @@
1
+ from llama_index.core.base.llms.types import ChatMessage, MessageRole
2
+
3
+ FILTER_PROMPT = {
4
+ "dontknow_filter": {
5
+ "en": [
6
+ ChatMessage(
7
+ role=MessageRole.SYSTEM,
8
+ content="""The following sentence is an answer about a question. You have to decide the answer implies 'I don't know'.
9
+ If the answer implies 'I don't know', return True. If not, return False.""",
10
+ ),
11
+ ],
12
+ "ko": [
13
+ ChatMessage(
14
+ role=MessageRole.SYSTEM,
15
+ content="""다음 문장은 어떠한 질문에 대한 대답입니다. 해당 문장이 질문에 대해서 '모른다고' 답한 것인지 판단하십시오.
16
+ 만약 해당 문장이 '모른다고' 답한 것이라면, True를 반환하세요. 그렇지 않다면 False를 반환하세요.""",
17
+ )
18
+ ],
19
+ "ja": [
20
+ ChatMessage(
21
+ role=MessageRole.SYSTEM,
22
+ content="""次の文章はある質問に対する答えです。 該当文章が質問に対して「知らない」と答えたのか判断します。
23
+ もし、その文章が「知らない」と答えたのであれば、Trueを返します。 そうでなければFalseを返します。""",
24
+ )
25
+ ],
26
+ },
27
+ "passage_dependency": {
28
+ "en": [
29
+ ChatMessage(
30
+ role=MessageRole.SYSTEM,
31
+ content="""You are a classifier that recognize 'passage dependent' questions.
32
+ The 'passage dependent' is the question that the answer will be change depending on what passage you choose.
33
+ For example) 'What is the highest score according to the table?'
34
+ This sentence is the passage dependent question because the answer will be different depending on the table.
35
+
36
+ In contrast, the following sentence is not passage dependant.
37
+ 'What is the highest score of the KBO baseball history in one game?'
38
+ 'What is the capital of France?'
39
+ These sentences will have the same answer regardless of the passage.
40
+
41
+ Please return True if the input question is passage dependent. Else return False.""",
42
+ )
43
+ ],
44
+ "ko": [
45
+ ChatMessage(
46
+ role=MessageRole.SYSTEM,
47
+ content="""당신은 '단락 의존' 질문을 인식하는 분류기입니다.
48
+ '단락 의존'이란 어떤 단락이 선택 되는지 따라 답이 달라지는 질문을 의미합니다.
49
+ 예를 들어, '주어진 표에 따르면 가장 높은 점수는 무엇인가요?'라는 질문은 단락 의존 질문입니다. 왜냐하면 표가 어떤 것인지에 따라 그 답이 달라지기 때문입니다.
50
+
51
+ 반면에, 다음 문장들은 단락 의존적이지 않습니다.
52
+ 'KBO 야구 역사상 한 경기에서 가장 높은 점수는 무엇인가요?' 또는 '프랑스의 수도는 무엇인가요?'
53
+ 이러한 문장은 단락에 관계 없이 동일한 답을 가집니다.
54
+
55
+ 입력된 질문이 단락 의존적이라면 True를 반환하고, 그렇지 않으면 False를 반환하세요.""",
56
+ )
57
+ ],
58
+ "ja": [
59
+ ChatMessage(
60
+ role=MessageRole.SYSTEM,
61
+ content="""あなたは「段落依存」の質問を認識する分類器です。
62
+ 「段落依存」とは、どの段落が選択されるかによって答えが変わる質問を意味します。
63
+ たとえば、「与えられた表によると、最も高い点数は何ですか?」という質問は、段落依存の質問です。 なぜなら、表がどんなものかによってその答えが変わるからです。
64
+
65
+ 一方、次の文章は段落依存的ではありません。
66
+ KBO野球史上1試合で最も高い点数は何ですか?またはフランスの首都は何ですか?'
67
+ このような文章は段落に関係なく同じ答えを持ちます。
68
+
69
+ 入力された質問が段落依存的である場合はTrueを返し、そうでない場合はFalseを返します。""",
70
+ )
71
+ ],
72
+ },
73
+ }
File without changes
@@ -0,0 +1,16 @@
1
+ from typing import Dict
2
+
3
+
4
+ def add_gen_gt(row: Dict, new_gen_gt: str) -> Dict:
5
+ if "generation_gt" in list(row.keys()):
6
+ if isinstance(row["generation_gt"], list):
7
+ row["generation_gt"].append(new_gen_gt)
8
+ elif isinstance(row["generation_gt"], str):
9
+ row["generation_gt"] = [row["generation_gt"], new_gen_gt]
10
+ else:
11
+ raise ValueError(
12
+ "generation_gt should be either a string or a list of strings."
13
+ )
14
+ return row
15
+ row["generation_gt"] = [new_gen_gt]
16
+ return row
@@ -0,0 +1,41 @@
1
+ import itertools
2
+ from typing import Dict
3
+
4
+
5
+ from llama_index.core.base.llms.base import BaseLLM
6
+ from llama_index.core.base.llms.types import MessageRole, ChatMessage
7
+
8
+ from autorag.data.qa.generation_gt.base import add_gen_gt
9
+ from autorag.data.qa.generation_gt.prompt import GEN_GT_SYSTEM_PROMPT
10
+
11
+
12
+ async def make_gen_gt_llama_index(row: Dict, llm: BaseLLM, system_prompt: str) -> Dict:
13
+ retrieval_gt_contents = list(
14
+ itertools.chain.from_iterable(row["retrieval_gt_contents"])
15
+ )
16
+ query = row["query"]
17
+ passage_str = "\n".join(retrieval_gt_contents)
18
+ user_prompt = f"Text:\n<|text_start|>\n{passage_str}\n<|text_end|>\n\nQuestion:\n{query}\n\nAnswer:"
19
+
20
+ response = await llm.achat(
21
+ messages=[
22
+ ChatMessage(role=MessageRole.SYSTEM, content=system_prompt),
23
+ ChatMessage(role=MessageRole.USER, content=user_prompt),
24
+ ],
25
+ temperature=0.0,
26
+ )
27
+ return add_gen_gt(row, response.message.content)
28
+
29
+
30
+ async def make_concise_gen_gt(row: Dict, llm: BaseLLM, lang: str = "en") -> Dict:
31
+ return await make_gen_gt_llama_index(
32
+ row, llm, GEN_GT_SYSTEM_PROMPT["concise"][lang]
33
+ )
34
+
35
+
36
+ async def make_basic_gen_gt(row: Dict, llm: BaseLLM, lang: str = "en") -> Dict:
37
+ return await make_gen_gt_llama_index(row, llm, GEN_GT_SYSTEM_PROMPT["basic"][lang])
38
+
39
+
40
+ async def make_custom_gen_gt(row: Dict, llm: BaseLLM, system_prompt: str) -> Dict:
41
+ return await make_gen_gt_llama_index(row, llm, system_prompt)