Repository: Marker-Inc-Korea/AutoRAG
Issue: Error when specify strategy on query expansion
Root cause: Configuration Error

YAML file

```
    - node_type: query_expansion
      strategy:
        metrics: [ retrieval_recall, retrieval_f1, retrieval_precision, retrieval_ndcg, retrieval_map, retrieval_mrr ]
        strategy: rank
        top_k: 20
        retrieval_modules:
          - module_type: bm25
            bm25_tokenizer: ko_kiwi
          - module_type: vectordb
            embedding_model: openai_embed_3_large
      modules:
        - module_type: pass_query_expansion
        - module_type: hyde
```

—

Error code

```
                    ERROR    [__init__.py:75] >> Unexpected exception                                                                                                  __init__.py:75
                             ╭────────────────────────────────────────────────── Traceback (most recent call last) ──────────────────────────────────────────────────╮               
                             │ /usr/local/bin/autorag:8 in <module>                                                                                                  │               
                             │                                                                                                                                       │               
                             │   5 from autorag.cli import cli                                                                                                       │               
                             │   6 if __name__ == '__main__':                                                                                                        │               
                             │   7 │   sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])                                                              │               
                             │ ❱ 8 │   sys.exit(cli())                                                                                                               │               
                             │   9                                                                                                                                   │               
                             │                                                                                                                                       │               
                             │ /usr/local/lib/python3.10/dist-packages/click/core.py:1157 in __call__                                                                │               
                             │                                                                                                                                       │               
                             │   1154 │                                                                                                                              │               
                             │   1155 │   def __call__(self, *args: t.Any, **kwargs: t.Any) -> t.Any:                                                                │               
                             │   1156 │   │   """Alias for :meth:`main`."""                                                                                          │               
                             │ ❱ 1157 │   │   return self.main(*args, **kwargs)                                                                                      │               
                             │   1158                                                                                                                                │               
                             │   1159                                                                                                                                │               
                             │   1160 class Command(BaseCommand):                                                                                                    │               
                             │                                                                                                                                       │               
                             │ /usr/local/lib/python3.10/dist-packages/click/core.py:1078 in main                                                                    │               
                             │                                                                                                                                       │               
                             │   1075 │   │   try:                                                                                                                   │               
                             │   1076 │   │   │   try:                                                                                                               │               
                             │   1077 │   │   │   │   with self.make_context(prog_name, args, **extra) as ctx:                                                       │               
                             │ ❱ 1078 │   │   │   │   │   rv = self.invoke(ctx)                                                                                      │               
                             │   1079 │   │   │   │   │   if not standalone_mode:                                                                                    │               
                             │   1080 │   │   │   │   │   │   return rv                                                                                              │               
                             │   1081 │   │   │   │   │   # it's not safe to `ctx.exit(rv)` here!                                                                    │               
                             │                                                                                                                                       │               
                             │ /usr/local/lib/python3.10/dist-packages/click/core.py:1688 in invoke                                                                  │               
                             │                                                                                                                                       │               
                             │   1685 │   │   │   │   super().invoke(ctx)                                                                                            │               
                             │   1686 │   │   │   │   sub_ctx = cmd.make_context(cmd_name, args, parent=ctx)                                                         │               
                             │   1687 │   │   │   │   with sub_ctx:                                                                                                  │               
                             │ ❱ 1688 │   │   │   │   │   return _process_result(sub_ctx.command.invoke(sub_ctx))                                                    │               
                             │   1689 │   │                                                                                                                          │               
                             │   1690 │   │   # In chain mode we create the contexts step by step, but after the                                                     │               
                             │   1691 │   │   # base command has been invoked.  Because at that point we do not                                                      │               
                             │                                                                                                                                       │               
                             │ /usr/local/lib/python3.10/dist-packages/click/core.py:1434 in invoke                                                                  │               
                             │                                                                                                                                       │               
                             │   1431 │   │   │   echo(style(message, fg="red"), err=True)                                                                           │               
                             │   1432 │   │                                                                                                                          │               
                             │   1433 │   │   if self.callback is not None:                                                                                          │               
                             │ ❱ 1434 │   │   │   return ctx.invoke(self.callback, **ctx.params)                                                                     │               
                             │   1435 │                                                                                                                              │               
                             │   1436 │   def shell_complete(self, ctx: Context, incomplete: str) -> t.List["CompletionItem"]:                                       │               
                             │   1437 │   │   """Return a list of completions for the incomplete value. Looks                                                        │               
                             │                                                                                                                                       │               
                             │ /usr/local/lib/python3.10/dist-packages/click/core.py:783 in invoke                                                                   │               
                             │                                                                                                                                       │               
                             │    780 │   │                                                                                                                          │               
                             │    781 │   │   with augment_usage_errors(__self):                                                                                     │               
                             │    782 │   │   │   with ctx:                                                                                                          │               
                             │ ❱  783 │   │   │   │   return __callback(*args, **kwargs)                                                                             │               
                             │    784 │                                                                                                                              │               
                             │    785 │   def forward(                                                                                                               │               
                             │    786 │   │   __self, __cmd: "Command", *args: t.Any, **kwargs: t.Any  # noqa: B902                                                  │               
                             │                                                                                                                                       │               
                             │ /usr/local/lib/python3.10/dist-packages/autorag/cli.py:35 in evaluate                                                                 │               
                             │                                                                                                                                       │               
                             │    32 │   if not os.path.exists(config):                                                                                              │               
                             │    33 │   │   raise ValueError(f"Config file {config} does not exist.")                                                               │               
                             │    34 │   evaluator = Evaluator(qa_data_path, corpus_data_path, project_dir=project_dir)                                              │               
                             │ ❱  35 │   evaluator.start_trial(config)                                                                                               │               
                             │    36 │   logger.info('Evaluation complete.')                                                                                         │               
                             │    37                                                                                                                                 │               
                             │    38                                                                                                                                 │               
                             │                                                                                                                                       │               
                             │ /usr/local/lib/python3.10/dist-packages/autorag/evaluator.py:98 in start_trial                                                        │               
                             │                                                                                                                                       │               
                             │    95 │   │   │   if i == 0:                                                                                                          │               
                             │    96 │   │   │   │   previous_result = self.qa_data                                                                                  │               
                             │    97 │   │   │   logger.info(f'Running node line {node_line_name}...')                                                               │               
                             │ ❱  98 │   │   │   previous_result = run_node_line(node_line, node_line_dir, previous_result)                                          │               
                             │    99 │   │   │                                                                                                                       │               
                             │   100 │   │   │   trial_summary_df = self._append_node_line_summary(node_line_name,                                                   │               
                             │       node_line_dir, trial_summary_df)                                                                                                │               
                             │   101                                                                                                                                 │               
                             │                                                                                                                                       │               
                             │ /usr/local/lib/python3.10/dist-packages/autorag/node_line.py:45 in run_node_line                                                      │               
                             │                                                                                                                                       │               
                             │   42 │                                                                                                                                │               
                             │   43 │   summary_lst = []                                                                                                             │               
                             │   44 │   for node in nodes:                                                                                                           │               
                             │ ❱ 45 │   │   previous_result = node.run(previous_result, node_line_dir)                                                               │               
                             │   46 │   │   node_summary_df = load_summary_file(os.path.join(node_line_dir, node.node_type,                                          │               
                             │      'summary.csv'))                                                                                                                  │               
                             │   47 │   │   best_node_row = node_summary_df.loc[node_summary_df['is_best']]                                                          │               
                             │   48 │   │   summary_lst.append({                                                                                                     │               
                             │                                                                                                                                       │               
                             │ /usr/local/lib/python3.10/dist-packages/autorag/schema/node.py:57 in run                                                              │               
                             │                                                                                                                                       │               
                             │    54 │   def run(self, previous_result: pd.DataFrame, node_line_dir: str) -> pd.DataFrame:                                           │               
                             │    55 │   │   logger.info(f'Running node {self.node_type}...')                                                                        │               
                             │    56 │   │   input_modules, input_params = self.get_param_combinations()                                                             │               
                             │ ❱  57 │   │   return self.run_node(modules=input_modules,                                                                             │               
                             │    58 │   │   │   │   │   │   │    module_params=input_params,                                                                        │               
                             │    59 │   │   │   │   │   │   │    previous_result=previous_result,                                                                   │               
                             │    60 │   │   │   │   │   │   │    node_line_dir=node_line_dir,                                                                       │               
                             │                                                                                                                                       │               
                             │ /usr/local/lib/python3.10/dist-packages/autorag/nodes/queryexpansion/run.py:94 in run_query_expansion_node                            │               
                             │                                                                                                                                       │               
                             │    91 │   │   retrieval_gt = pd.read_parquet(os.path.join(project_dir, "data", "qa.parquet"),                                         │               
                             │       engine='pyarrow')['retrieval_gt'].tolist()                                                                                      │               
                             │    92 │   │                                                                                                                           │               
                             │    93 │   │   # run evaluation                                                                                                        │               
                             │ ❱  94 │   │   evaluation_results = list(map(lambda result: evaluate_one_query_expansion_node(                                         │               
                             │    95 │   │   │   retrieval_callables, retrieval_params, result['queries'].tolist(),                                                  │               
                             │       retrieval_gt,                                                                                                                   │               
                             │    96 │   │   │   general_strategy['metrics'], project_dir, previous_result,                                                          │               
                             │       strategies.get('strategy', 'mean')), results))                                                                                  │               
                             │    97                                                                                                                                 │               
                             │                                                                                                                                       │               
                             │ /usr/local/lib/python3.10/dist-packages/autorag/nodes/queryexpansion/run.py:94 in <lambda>                                            │               
                             │                                                                                                                                       │               
                             │    91 │   │   retrieval_gt = pd.read_parquet(os.path.join(project_dir, "data", "qa.parquet"),                                         │               
                             │       engine='pyarrow')['retrieval_gt'].tolist()                                                                                      │               
                             │    92 │   │                                                                                                                           │               
                             │    93 │   │   # run evaluation                                                                                                        │               
                             │ ❱  94 │   │   evaluation_results = list(map(lambda result: evaluate_one_query_expansion_node(                                         │               
                             │    95 │   │   │   retrieval_callables, retrieval_params, result['queries'].tolist(),                                                  │               
                             │       retrieval_gt,                                                                                                                   │               
                             │    96 │   │   │   general_strategy['metrics'], project_dir, previous_result,                                                          │               
                             │       strategies.get('strategy', 'mean')), results))                                                                                  │               
                             │    97                                                                                                                                 │               
                             │                                                                                                                                       │               
                             │ /usr/local/lib/python3.10/dist-packages/autorag/nodes/queryexpansion/run.py:134 in evaluate_one_query_expansion_node                  │               
                             │                                                                                                                                       │               
                             │   131 │   │   │   │   │   │   │   │   │     previous_result: pd.DataFrame,                                                            │               
                             │   132 │   │   │   │   │   │   │   │   │     strategy_name: str) -> pd.DataFrame:                                                      │               
                             │   133 │   previous_result['queries'] = expanded_queries                                                                               │               
                             │ ❱ 134 │   retrieval_results = list(map(lambda x: x[0](project_dir=project_dir,                                                        │               
                             │       previous_result=previous_result, **x[1]),                                                                                       │               
                             │   135 │   │   │   │   │   │   │   │    zip(retrieval_funcs, retrieval_params)))                                                       │               
                             │   136 │   evaluation_results = list(map(lambda x: evaluate_retrieval_node(x, retrieval_gt,                                            │               
                             │       metrics,                                                                                                                        │               
                             │   137 │   │   │   │   │   │   │   │   │   │   │   │   │   │   │   │   │                                                               │               
                             │       previous_result['query'].tolist(),                                                                                              │               
                             │                                                                                                                                       │               
                             │ /usr/local/lib/python3.10/dist-packages/autorag/nodes/queryexpansion/run.py:134 in <lambda>                                           │               
                             │                                                                                                                                       │               
                             │   131 │   │   │   │   │   │   │   │   │     previous_result: pd.DataFrame,                                                            │               
                             │   132 │   │   │   │   │   │   │   │   │     strategy_name: str) -> pd.DataFrame:                                                      │               
                             │   133 │   previous_result['queries'] = expanded_queries                                                                               │               
                             │ ❱ 134 │   retrieval_results = list(map(lambda x: x[0](project_dir=project_dir,                                                        │               
                             │       previous_result=previous_result, **x[1]),                                                                                       │               
                             │   135 │   │   │   │   │   │   │   │    zip(retrieval_funcs, retrieval_params)))                                                       │               
                             │   136 │   evaluation_results = list(map(lambda x: evaluate_retrieval_node(x, retrieval_gt,                                            │               
                             │       metrics,                                                                                                                        │               
                             │   137 │   │   │   │   │   │   │   │   │   │   │   │   │   │   │   │   │                                                               │               
                             │       previous_result['query'].tolist(),                                                                                              │               
                             │                                                                                                                                       │               
                             │ /usr/local/lib/python3.10/dist-packages/autorag/utils/util.py:53 in wrapper                                                           │               
                             │                                                                                                                                       │               
                             │    50 │   def decorator_result_to_dataframe(func: Callable):                                                                          │               
                             │    51 │   │   @functools.wraps(func)                                                                                                  │               
                             │    52 │   │   def wrapper(*args, **kwargs) -> pd.DataFrame:                                                                           │               
                             │ ❱  53 │   │   │   results = func(*args, **kwargs)                                                                                     │               
                             │    54 │   │   │   if len(column_names) == 1:                                                                                          │               
                             │    55 │   │   │   │   df_input = {column_names[0]: results}                                                                           │               
                             │    56 │   │   │   else:                                                                                                               │               
                             │                                                                                                                                       │               
                             │ /usr/local/lib/python3.10/dist-packages/autorag/nodes/retrieval/base.py:65 in wrapper                                                 │               
                             │                                                                                                                                       │               
                             │    62 │   │   # run retrieval function                                                                                                │               
                             │    63 │   │   if func.__name__ == "bm25":                                                                                             │               
                             │    64 │   │   │   bm25_corpus = load_bm25_corpus(bm25_path)                                                                           │               
                             │ ❱  65 │   │   │   ids, scores = func(queries=queries, bm25_corpus=bm25_corpus, **kwargs)                                              │               
                             │    66 │   │   elif func.__name__ == "vectordb":                                                                                       │               
                             │    67 │   │   │   chroma_collection = load_chroma_collection(db_path=chroma_path,                                                     │               
                             │       collection_name=embedding_model_str)                                                                                            │               
                             │    68 │   │   │   if embedding_model_str in embedding_models:                                                                         │               
                             ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯               
                             TypeError: bm25() got an unexpected keyword argument 'strategy'
```