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,134 @@
1
+ from pathlib import Path
2
+ from typing import List, Tuple, Union
3
+
4
+ import numpy as np
5
+ import pandas as pd
6
+
7
+ from autorag.embedding.base import EmbeddingModel
8
+ from autorag.evaluation.metric.util import calculate_cosine_similarity
9
+ from autorag.nodes.passagefilter.base import BasePassageFilter
10
+ from autorag.nodes.passagefilter.similarity_threshold_cutoff import (
11
+ embedding_query_content,
12
+ )
13
+ from autorag.utils import result_to_dataframe
14
+ from autorag.utils.util import empty_cuda_cache, pop_params
15
+
16
+
17
+ class SimilarityPercentileCutoff(BasePassageFilter):
18
+ def __init__(self, project_dir: Union[str, Path], *args, **kwargs):
19
+ """
20
+ Initialize the SimilarityPercentileCutoff module
21
+
22
+ :param project_dir: The project directory to use for initializing the module
23
+ :param embedding_model: The embedding model string to use for calculating similarity
24
+ Default is "openai" which is OpenAI text-embedding-ada-002 embedding model.
25
+ """
26
+ super().__init__(project_dir, *args, **kwargs)
27
+ embedding_model = kwargs.pop("embedding_model", "openai")
28
+ self.embedding_model = EmbeddingModel.load(embedding_model)()
29
+
30
+ def __del__(self):
31
+ super().__del__()
32
+ del self.embedding_model
33
+
34
+ empty_cuda_cache()
35
+
36
+ @result_to_dataframe(["retrieved_contents", "retrieved_ids", "retrieve_scores"])
37
+ def pure(self, previous_result: pd.DataFrame, **kwargs):
38
+ queries, contents, scores, ids = self.cast_to_run(previous_result)
39
+ kwargs = pop_params(self._pure, kwargs)
40
+ return self._pure(queries, contents, scores, ids, **kwargs)
41
+
42
+ def _pure(
43
+ self,
44
+ queries: List[str],
45
+ contents_list: List[List[str]],
46
+ scores_list: List[List[float]],
47
+ ids_list: List[List[str]],
48
+ percentile: float,
49
+ batch: int = 128,
50
+ ) -> Tuple[List[List[str]], List[List[str]], List[List[float]]]:
51
+ """
52
+ Re-calculate each content's similarity with the query and filter out the contents that are below the content's
53
+ length times percentile. If This is a filter and does not override scores. The output of scores is not coming from
54
+ query-content similarity.
55
+ If the value of content's length times percentile is less than 1, keep the only one highest similarity content.
56
+
57
+ :param queries: The list of queries to use for filtering
58
+ :param contents_list: The list of lists of contents to filter
59
+ :param scores_list: The list of lists of scores retrieved
60
+ :param ids_list: The list of lists of ids retrieved
61
+ :param percentile: The percentile to cut off
62
+ :param batch: The number of queries to be processed in a batch
63
+ Default is 128.
64
+ :return: Tuple of lists containing the filtered contents, ids, and scores
65
+ """
66
+ query_embeddings, content_embeddings = embedding_query_content(
67
+ queries, contents_list, self.embedding_model, batch
68
+ )
69
+
70
+ results = list(
71
+ map(
72
+ lambda x: self.__row_pure(x[0], x[1], x[2], x[3], x[4], percentile),
73
+ zip(
74
+ query_embeddings,
75
+ content_embeddings,
76
+ contents_list,
77
+ ids_list,
78
+ scores_list,
79
+ ),
80
+ )
81
+ )
82
+
83
+ remain_content_list = list(map(lambda x: x[0], results))
84
+ remain_ids_list = list(map(lambda x: x[1], results))
85
+ remain_scores_list = list(map(lambda x: x[2], results))
86
+
87
+ return remain_content_list, remain_ids_list, remain_scores_list
88
+
89
+ @staticmethod
90
+ def __row_pure(
91
+ query_embedding: str,
92
+ content_embeddings: List[List[float]],
93
+ content_list: List[str],
94
+ ids_list: List[str],
95
+ scores_list: List[float],
96
+ percentile: float,
97
+ ) -> Tuple[List[str], List[str], List[float]]:
98
+ """
99
+ Return tuple of lists containing the filtered contents, ids, and scores
100
+
101
+ :param query_embedding: Query embedding
102
+ :param content_embeddings: Each content embedding
103
+ :param content_list: Each content
104
+ :param ids_list: Each id
105
+ :param scores_list: Each score
106
+ :param percentile: The percentile to cut off
107
+ :return: Tuple of lists containing the filtered contents, ids, and scores
108
+ """
109
+ num_top_k = int(len(content_embeddings) * percentile)
110
+
111
+ if num_top_k == 0:
112
+ num_top_k = 1
113
+
114
+ similarities = np.array(
115
+ list(
116
+ map(
117
+ lambda x: calculate_cosine_similarity(query_embedding, x),
118
+ content_embeddings,
119
+ )
120
+ )
121
+ ).tolist()
122
+
123
+ content_id_score_similarity = list(
124
+ zip(ids_list, content_list, scores_list, similarities)
125
+ )
126
+
127
+ sorted_content_id_score_similarity = sorted(
128
+ content_id_score_similarity, key=lambda x: x[3], reverse=True
129
+ )[:num_top_k]
130
+
131
+ content_result, id_result, score_result, _ = zip(
132
+ *sorted_content_id_score_similarity
133
+ )
134
+ return list(content_result), list(id_result), list(score_result)
@@ -0,0 +1,112 @@
1
+ from typing import List, Tuple
2
+
3
+ import numpy as np
4
+ import pandas as pd
5
+
6
+ from autorag.embedding.base import EmbeddingModel
7
+ from autorag.evaluation.metric.util import calculate_cosine_similarity
8
+ from autorag.nodes.passagefilter.base import BasePassageFilter
9
+ from autorag.utils.util import (
10
+ embedding_query_content,
11
+ empty_cuda_cache,
12
+ result_to_dataframe,
13
+ pop_params,
14
+ )
15
+
16
+
17
+ class SimilarityThresholdCutoff(BasePassageFilter):
18
+ def __init__(self, project_dir: str, *args, **kwargs):
19
+ """
20
+ Initialize the SimilarityThresholdCutoff module
21
+
22
+ :param project_dir: The project directory to use for initializing the module
23
+ :param embedding_model: The embedding model string to use for calculating similarity
24
+ Default is "openai" which is OpenAI text-embedding-ada-002 embedding model.
25
+ """
26
+ super().__init__(project_dir, *args, **kwargs)
27
+ embedding_model = kwargs.get("embedding_model", "openai")
28
+ self.embedding_model = EmbeddingModel.load(embedding_model)()
29
+
30
+ def __del__(self):
31
+ del self.embedding_model
32
+ empty_cuda_cache()
33
+ super().__del__()
34
+
35
+ @result_to_dataframe(["retrieved_contents", "retrieved_ids", "retrieve_scores"])
36
+ def pure(self, previous_result: pd.DataFrame, *args, **kwargs):
37
+ kwargs = pop_params(self._pure, kwargs)
38
+ queries, contents, scores, ids = self.cast_to_run(previous_result)
39
+ return self._pure(queries, contents, scores, ids, *args, **kwargs)
40
+
41
+ def _pure(
42
+ self,
43
+ queries: List[str],
44
+ contents_list: List[List[str]],
45
+ scores_list: List[List[float]],
46
+ ids_list: List[List[str]],
47
+ threshold: float,
48
+ batch: int = 128,
49
+ ) -> Tuple[List[List[str]], List[List[str]], List[List[float]]]:
50
+ """
51
+ Re-calculate each content's similarity with the query and filter out the contents that are below the threshold.
52
+ If all contents are filtered, keep the only one highest similarity content.
53
+ This is a filter and does not override scores.
54
+ The output of scores is not coming from query-content similarity.
55
+
56
+ :param queries: The list of queries to use for filtering
57
+ :param contents_list: The list of lists of contents to filter
58
+ :param scores_list: The list of lists of scores retrieved
59
+ :param ids_list: The list of lists of ids retrieved
60
+ :param threshold: The threshold to cut off
61
+ :param batch: The number of queries to be processed in a batch
62
+ Default is 128.
63
+ :return: Tuple of lists containing the filtered contents, ids, and scores
64
+ """
65
+ query_embeddings, content_embeddings = embedding_query_content(
66
+ queries, contents_list, self.embedding_model, batch
67
+ )
68
+
69
+ remain_indices = list(
70
+ map(
71
+ lambda x: self.__row_pure(x[0], x[1], threshold),
72
+ zip(query_embeddings, content_embeddings),
73
+ )
74
+ )
75
+
76
+ remain_content_list = list(
77
+ map(lambda c, idx: [c[i] for i in idx], contents_list, remain_indices)
78
+ )
79
+ remain_scores_list = list(
80
+ map(lambda s, idx: [s[i] for i in idx], scores_list, remain_indices)
81
+ )
82
+ remain_ids_list = list(
83
+ map(lambda _id, idx: [_id[i] for i in idx], ids_list, remain_indices)
84
+ )
85
+ return remain_content_list, remain_ids_list, remain_scores_list
86
+
87
+ @staticmethod
88
+ def __row_pure(
89
+ query_embedding: str, content_embeddings: List[List[float]], threshold: float
90
+ ) -> List[int]:
91
+ """
92
+ Return indices that have to remain.
93
+ Return at least one index if there is nothing to remain.
94
+
95
+ :param query_embedding: Query embedding
96
+ :param content_embeddings: Each content embedding
97
+ :param threshold: The threshold to cut off
98
+ :return: Indices to remain at the contents
99
+ """
100
+
101
+ similarities = np.array(
102
+ list(
103
+ map(
104
+ lambda x: calculate_cosine_similarity(query_embedding, x),
105
+ content_embeddings,
106
+ )
107
+ )
108
+ )
109
+ result = np.where(similarities >= threshold)[0].tolist()
110
+ if len(result) > 0:
111
+ return result
112
+ return [np.argmax(similarities)]
@@ -0,0 +1,78 @@
1
+ from typing import List, Tuple
2
+
3
+ import pandas as pd
4
+
5
+ from autorag.nodes.passagefilter.base import BasePassageFilter
6
+ from autorag.utils.util import convert_inputs_to_list, result_to_dataframe
7
+
8
+
9
+ class ThresholdCutoff(BasePassageFilter):
10
+ @result_to_dataframe(["retrieved_contents", "retrieved_ids", "retrieve_scores"])
11
+ def pure(self, previous_result: pd.DataFrame, *args, **kwargs):
12
+ _, contents, scores, ids = self.cast_to_run(previous_result)
13
+ return self._pure(contents, scores, ids, *args, **kwargs)
14
+
15
+ def _pure(
16
+ self,
17
+ contents_list: List[List[str]],
18
+ scores_list: List[List[float]],
19
+ ids_list: List[List[str]],
20
+ threshold: float,
21
+ reverse: bool = False,
22
+ ) -> Tuple[List[List[str]], List[List[str]], List[List[float]]]:
23
+ """
24
+ Filters the contents, scores, and ids based on a previous result's score.
25
+ Keeps at least one item per query if all scores are below the threshold.
26
+
27
+ :param contents_list: List of content strings for each query.
28
+ :param scores_list: List of scores for each content.
29
+ :param ids_list: List of ids for each content.
30
+ :param threshold: The minimum score to keep an item.
31
+ :param reverse: If True, the lower the score, the better.
32
+ Default is False.
33
+ :return: Filtered lists of contents, ids, and scores.
34
+ """
35
+ remain_indices = list(
36
+ map(lambda x: self.__row_pure(x, threshold, reverse), scores_list)
37
+ )
38
+
39
+ remain_content_list = list(
40
+ map(lambda c, idx: [c[i] for i in idx], contents_list, remain_indices)
41
+ )
42
+ remain_scores_list = list(
43
+ map(lambda s, idx: [s[i] for i in idx], scores_list, remain_indices)
44
+ )
45
+ remain_ids_list = list(
46
+ map(lambda _id, idx: [_id[i] for i in idx], ids_list, remain_indices)
47
+ )
48
+
49
+ return remain_content_list, remain_ids_list, remain_scores_list
50
+
51
+ @convert_inputs_to_list
52
+ def __row_pure(
53
+ self, scores_list: List[float], threshold: float, reverse: bool = False
54
+ ) -> List[int]:
55
+ """
56
+ Return indices that have to remain.
57
+ Return at least one index if there is nothing to remain.
58
+
59
+ :param scores_list: Each score
60
+ :param threshold: The threshold to cut off
61
+ :param reverse: If True, the lower the score, the better
62
+ Default is False.
63
+ :return: Indices to remain at the contents
64
+ """
65
+ assert isinstance(scores_list, list), "scores_list must be a list."
66
+
67
+ if reverse:
68
+ remain_indices = [
69
+ i for i, score in enumerate(scores_list) if score <= threshold
70
+ ]
71
+ default_index = scores_list.index(min(scores_list))
72
+ else:
73
+ remain_indices = [
74
+ i for i, score in enumerate(scores_list) if score >= threshold
75
+ ]
76
+ default_index = scores_list.index(max(scores_list))
77
+
78
+ return remain_indices if remain_indices else [default_index]
@@ -0,0 +1,16 @@
1
+ from .cohere import CohereReranker
2
+ from .colbert import ColbertReranker
3
+ from .flag_embedding import FlagEmbeddingReranker
4
+ from .flag_embedding_llm import FlagEmbeddingLLMReranker
5
+ from .jina import JinaReranker
6
+ from .koreranker import KoReranker
7
+ from .monot5 import MonoT5
8
+ from .pass_reranker import PassReranker
9
+ from .rankgpt import RankGPT
10
+ from .sentence_transformer import SentenceTransformerReranker
11
+ from .time_reranker import TimeReranker
12
+ from .upr import Upr
13
+ from .openvino import OpenVINOReranker
14
+ from .voyageai import VoyageAIReranker
15
+ from .mixedbreadai import MixedbreadAIReranker
16
+ from .flashrank import FlashRankReranker
@@ -0,0 +1,44 @@
1
+ import abc
2
+ import logging
3
+ from pathlib import Path
4
+ from typing import Union
5
+
6
+ import pandas as pd
7
+
8
+ from autorag.schema import BaseModule
9
+ from autorag.utils import validate_qa_dataset
10
+ from autorag.utils.cast import cast_retrieve_infos
11
+
12
+ logger = logging.getLogger("AutoRAG")
13
+
14
+
15
+ class BasePassageReranker(BaseModule, metaclass=abc.ABCMeta):
16
+ def __init__(self, project_dir: Union[str, Path], *args, **kwargs):
17
+ logger.info(
18
+ f"Initialize passage reranker node - {self.__class__.__name__} module..."
19
+ )
20
+
21
+ def __del__(self):
22
+ logger.info(
23
+ f"Deleting passage reranker node - {self.__class__.__name__} module..."
24
+ )
25
+
26
+ def cast_to_run(self, previous_result: pd.DataFrame, *args, **kwargs):
27
+ logger.info(
28
+ f"Running passage reranker node - {self.__class__.__name__} module..."
29
+ )
30
+ validate_qa_dataset(previous_result)
31
+
32
+ # find queries columns
33
+ assert "query" in previous_result.columns, (
34
+ "previous_result must have query column."
35
+ )
36
+ queries = previous_result["query"].tolist()
37
+
38
+ retrieve_infos = cast_retrieve_infos(previous_result)
39
+ return (
40
+ queries,
41
+ retrieve_infos["retrieved_contents"],
42
+ retrieve_infos["retrieve_scores"],
43
+ retrieve_infos["retrieved_ids"],
44
+ )
@@ -0,0 +1,118 @@
1
+ import os
2
+ from typing import List, Tuple
3
+
4
+ import cohere
5
+ import pandas as pd
6
+ from cohere import RerankResponseResultsItem
7
+
8
+ from autorag.nodes.passagereranker.base import BasePassageReranker
9
+ from autorag.utils.util import get_event_loop, process_batch, result_to_dataframe
10
+
11
+
12
+ class CohereReranker(BasePassageReranker):
13
+ def __init__(self, project_dir: str, *args, **kwargs):
14
+ """
15
+ Initialize Cohere rerank node.
16
+
17
+ :param project_dir: The project directory path.
18
+ :param api_key: The API key for Cohere rerank.
19
+ You can set it in the environment variable COHERE_API_KEY.
20
+ Or, you can directly set it on the config YAML file using this parameter.
21
+ Default is env variable "COHERE_API_KEY".
22
+ :param kwargs: Extra arguments that are not affected
23
+ """
24
+ super().__init__(project_dir)
25
+ api_key = kwargs.pop("api_key", None)
26
+ api_key = os.getenv("COHERE_API_KEY", None) if api_key is None else api_key
27
+ if api_key is None:
28
+ api_key = os.getenv("CO_API_KEY", None)
29
+ if api_key is None:
30
+ raise KeyError(
31
+ "Please set the API key for Cohere rerank in the environment variable COHERE_API_KEY "
32
+ "or directly set it on the config YAML file."
33
+ )
34
+
35
+ self.cohere_client = cohere.AsyncClientV2(api_key=api_key)
36
+
37
+ def __del__(self):
38
+ del self.cohere_client
39
+ super().__del__()
40
+
41
+ @result_to_dataframe(["retrieved_contents", "retrieved_ids", "retrieve_scores"])
42
+ def pure(self, previous_result: pd.DataFrame, *args, **kwargs):
43
+ queries, contents, scores, ids = self.cast_to_run(previous_result)
44
+ top_k = kwargs.pop("top_k")
45
+ batch = kwargs.pop("batch", 64)
46
+ model = kwargs.pop("model", "rerank-v3.5")
47
+ return self._pure(queries, contents, scores, ids, top_k, batch, model)
48
+
49
+ def _pure(
50
+ self,
51
+ queries: List[str],
52
+ contents_list: List[List[str]],
53
+ scores_list: List[List[float]],
54
+ ids_list: List[List[str]],
55
+ top_k: int,
56
+ batch: int = 64,
57
+ model: str = "rerank-v3.5",
58
+ ) -> Tuple[List[List[str]], List[List[str]], List[List[float]]]:
59
+ """
60
+ Rerank a list of contents with Cohere rerank models.
61
+ You can get the API key from https://cohere.com/rerank and set it in the environment variable COHERE_API_KEY.
62
+
63
+ :param queries: The list of queries to use for reranking
64
+ :param contents_list: The list of lists of contents to rerank
65
+ :param scores_list: The list of lists of scores retrieved from the initial ranking
66
+ :param ids_list: The list of lists of ids retrieved from the initial ranking
67
+ :param top_k: The number of passages to be retrieved
68
+ :param batch: The number of queries to be processed in a batch
69
+ :param model: The model name for Cohere rerank.
70
+ You can choose between "rerank-v3.5", "rerank-english-v3.0", and "rerank-multilingual-v3.0".
71
+ Default is "rerank-v3.5".
72
+ :return: Tuple of lists containing the reranked contents, ids, and scores
73
+ """
74
+ # Run async cohere_rerank_pure function
75
+ tasks = [
76
+ cohere_rerank_pure(self.cohere_client, model, query, document, ids, top_k)
77
+ for query, document, ids in zip(queries, contents_list, ids_list)
78
+ ]
79
+ loop = get_event_loop()
80
+ results = loop.run_until_complete(process_batch(tasks, batch_size=batch))
81
+ content_result = list(map(lambda x: x[0], results))
82
+ id_result = list(map(lambda x: x[1], results))
83
+ score_result = list(map(lambda x: x[2], results))
84
+
85
+ return content_result, id_result, score_result
86
+
87
+
88
+ async def cohere_rerank_pure(
89
+ cohere_client: cohere.AsyncClient,
90
+ model: str,
91
+ query: str,
92
+ documents: List[str],
93
+ ids: List[str],
94
+ top_k: int,
95
+ ) -> Tuple[List[str], List[str], List[float]]:
96
+ """
97
+ Rerank a list of contents with Cohere rerank models.
98
+
99
+ :param cohere_client: The Cohere AsyncClient to use for reranking
100
+ :param model: The model name for Cohere rerank
101
+ :param query: The query to use for reranking
102
+ :param documents: The list of contents to rerank
103
+ :param ids: The list of ids corresponding to the documents
104
+ :param top_k: The number of passages to be retrieved
105
+ :return: Tuple of lists containing the reranked contents, ids, and scores
106
+ """
107
+ rerank_results = await cohere_client.rerank(
108
+ model=model,
109
+ query=query,
110
+ documents=documents,
111
+ top_n=top_k,
112
+ )
113
+ results: List[RerankResponseResultsItem] = rerank_results.results
114
+ reranked_scores: List[float] = list(map(lambda x: x.relevance_score, results))
115
+ indices = list(map(lambda x: x.index, results))
116
+ reranked_contents: List[str] = list(map(lambda i: documents[i], indices))
117
+ reranked_ids: List[str] = list(map(lambda i: ids[i], indices))
118
+ return reranked_contents, reranked_ids, reranked_scores