开始创建您自己的评估数据

索引

  1. 概述

  2. 原始数据转语料库数据

  3. 语料数据转问答数据

  4. 使用自定义提示

  5. 使用多个提示词

  6. 如果存在现有查询

概述

为了评估RAG系统,我们需要数据,但在大多数情况下,我们拥有很少或没有令人满意的数据。

然而,随着大语言模型(LLM)的出现,生成合成数据已成为解决这一问题的有效方案之一。

以下指南介绍如何使用LLM生成AutoRAG可用的数据格式。


Data Creation

AutoRAG旨在与Python的"原始数据类型"配合使用,以实现可扩展性和便利性。

因此,要使用AutoRAG,您需要将原始数据转换为corpus dataqa data,并符合我们的data format格式要求。

从原始文档创建语料库数据

  1. 使用lama_index、LangChain等加载器将原始数据加载为文本

  2. 将文本分块成段落。使用Langchain、LlamaIndex等工具。

  3. 将其转换为语料库数据以使用转换器函数。 提供针对llama index DocumentTextNode以及Langchain Document对象的转换器函数, 分别是llama_document_to_parquetllama_text_node_to_parquetlangchain_document_to_parquet

  • 使用Llama Index

from llama_index.core import SimpleDirectoryReader
from llama_index.core.node_parser import TokenTextSplitter
from autorag.data.legacy.corpus import llama_text_node_to_parquet

documents = SimpleDirectoryReader('your_dir_path').load_data()
nodes = TokenTextSplitter(chunk_size=512, chunk_overlap=128).get_nodes_from_documents(documents=documents)
corpus_df = llama_text_node_to_parquet(nodes, 'path/to/corpus.parquet')
  • 使用LangChain

from langchain_community.document_loaders import DirectoryLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
from autorag.data.legacy.corpus import langchain_documents_to_parquet

documents = DirectoryLoader('your_dir_path', glob='**/*.md').load()
documents = RecursiveCharacterTextSplitter(chunk_size=512, chunk_overlap=128).split_documents(documents)
corpus_df = langchain_documents_to_parquet(documents, 'path/to/corpus.parquet')

提示

语料库数据格式可参考corpus data format

从语料数据生成问答数据

提示

问答数据的格式可参考qa data format

import pandas as pd
from llama_index.llms.openai import OpenAI
from autorag.data.legacy.qacreation import generate_qa_llama_index, make_single_content_qa

corpus_df = pd.read_parquet('path/to/corpus.parquet')
llm = OpenAI(model='gpt-3.5-turbo', temperature=1.0)
qa_df = make_single_content_qa(corpus_df, 50, generate_qa_llama_index, llm=llm, question_num_per_content=1,
                               output_filepath='path/to/qa.parquet', cache_batch=64)

generate_qa_llama_index 是一个用于为每段内容生成问题及其generation_gt的函数。 您可以通过修改question_num_per_content参数来设置每段内容生成的问题数量。

make_single_content_qa函数旨在通过输入函数生成qa.parquet文件。 它生成的是"单一内容"问答数据,也称为"单跳"或"单文档"问答数据。 这意味着每个问题仅使用一个文段来回答问题。

什么是passage?

Passage是从原始数据中分块处理的单元。

自动保存功能

从AutoRAG v0.2.9版本开始,新增了自动保存功能! 现在您无需担心数据生成过程中出现意外问题。 数据将自动保存到输入的output_filepath路径中。

您可以设置将结果保存到文件的频率。 只需调整cache_batch参数,默认值为32。

使用自定义提示

您可以使用自定义提示来生成问答数据。 提示中必须包含两个占位符:

  • {{text}}: 内容字符串

  • {{num_questions}}: 要生成的问题数量

import pandas as pd

from llama_index.llms.openai import OpenAI
from autorag.data.legacy.qacreation import generate_qa_llama_index, make_single_content_qa

prompt = """
Generate question and answer pairs for the given passage.

Passage:
{{text}}

Number of questions to generate: {{num_questions}}

Example:
[Q]: What is this?
[A]: This is a sample question.

Result:
"""

corpus_df = pd.read_parquet('path/to/corpus.parquet')
llm = OpenAI(model='gpt-3.5-turbo', temperature=1.0)
qa_df = make_single_content_qa(corpus_df, content_size=50, qa_creation_func=generate_qa_llama_index,
                               llm=llm, prompt=prompt, question_num_per_content=1)

使用多个提示

如需生成不同类型的问题-答案对,您可以使用多个提示词模板。 目前我们支持根据各提示词的比例进行随机分配。 这意味着系统将按比例从每个段落中选取提示词。

为此,您需要提供一个字典。 该字典必须包含键(即提示文本文件路径)和值(即提示的比例)。

import pandas as pd
from llama_index.llms.openai import OpenAI
from autorag.data.legacy.qacreation import generate_qa_llama_index_by_ratio, make_single_content_qa

ratio_dict = {
    'prompt1.txt': 1,
    'prompt2.txt': 2,
    'prompt3.txt': 3
}

corpus_df = pd.read_parquet('path/to/corpus.parquet')
llm = OpenAI(model='gpt-3.5-turbo', temperature=1.0)
qa_df = make_single_content_qa(corpus_df, content_size=50, qa_creation_func=generate_qa_llama_index_by_ratio,
                               llm=llm, prompts_ratio=ratio_dict, question_num_per_content=1, batch=6)

警告

请记住所有提示词必须包含占位符 {{text}}{{num_questions}}

当您已有问答数据时

当您已有现成的问答数据时,可以将其用于AutoRAG。 真实用户的问答数据是非常宝贵的数据资源,因此在生成合成数据前优先使用这些真实数据总是明智之举。

但您需要从语料库数据中为现有查询创建retrieval_gt。 在语料库中寻找retrieval_gt的过程虽然困难,但必须确保准确。 为了降低难度,我们使用嵌入模型和向量数据库来查找相关段落。 之后,您需要确认retrieval_gt是否正确。 如果retrieval_gt不相关,必须将其从数据集中移除。

该功能在您仅准备好查询时可用,若您同时准备好查询和generation_gt时也可使用。

如果只有查询数据:

首先使用现有查询获取retrieval_gt,然后将查询和retrieval_gt输入LLM并生成generation_gt。

  • answer_creation_func, llm 参数是必需的。

  • existing_qa_df 必须包含'query'列。

import pandas as pd
from llama_index.llms.openai import OpenAI
from autorag.data.legacy.qacreation import make_qa_with_existing_qa, generate_answers

corpus_df = pd.read_parquet('path/to/corpus.parquet')
existing_qa_df = pd.read_parquet('path/to/existing_qa.parquet')  # It has to contain 'query' column
llm = OpenAI(model='gpt-3.5-turbo', temperature=1.0)
qa_df = make_qa_with_existing_qa(corpus_df, existing_qa_df, content_size=50,
                                 answer_creation_func=generate_answers,
                                 llm=llm, output_filepath='path/to/qa.parquet', cache_batch=64,
                                 embedding_model='openai_embed_3_large', top_k=5)

您也可以使用PersistentClient将语料库嵌入本地保存。

import pandas as pd
import chromadb
from llama_index.llms.openai import OpenAI
from autorag.data.legacy.qacreation import make_qa_with_existing_qa, generate_answers

client = chromadb.PersistentClient('path/to/chromadb')
collection = client.get_or_create_collection('auto-rag')

corpus_df = pd.read_parquet('path/to/corpus.parquet')
existing_qa_df = pd.read_parquet('path/to/existing_qa.parquet')  # It has to contain 'query' column
llm = OpenAI(model='gpt-3.5-turbo', temperature=1.0)
qa_df = make_qa_with_existing_qa(corpus_df, existing_qa_df, content_size=50,
                                 answer_creation_func=generate_answers, collection=collection,
                                 llm=llm, output_filepath='path/to/qa.parquet', cache_batch=64,
                                 embedding_model='openai_embed_3_large', top_k=5)

如果您同时拥有查询内容和生成目标:

直接使用查询和generation_gt,只需找到并添加retrieval_gt。

  • answer_creation_funcllm 参数不是必需的。

  • exist_gen_gt=True 参数是必需的。

  • existing_qa_df 必须包含'query'和'generation_gt'列。

    • generation_gt(每查询) 必须采用 List[str] 的形式。

import pandas as pd
from llama_index.llms.openai import OpenAI
from autorag.data.legacy.qacreation import make_qa_with_existing_qa

corpus_df = pd.read_parquet('path/to/corpus.parquet')
existing_qa_df = pd.read_parquet(
    'path/to/existing_qa.parquet')  # It has to contain 'query' and 'generation_gt' columns.
llm = OpenAI(model='gpt-3.5-turbo', temperature=1.0)
qa_df = make_qa_with_existing_qa(corpus_df, existing_qa_df, content_size=50, exist_gen_gt=True,
                                 output_filepath='path/to/qa.parquet', cache_batch=64,
                                 embedding_model='openai_embed_3_large', top_k=5)

您也可以使用PersistentClient将语料库嵌入本地保存。

import pandas as pd
import chromadb
from llama_index.llms.openai import OpenAI
from autorag.data.legacy.qacreation import make_qa_with_existing_qa

client = chromadb.PersistentClient('path/to/chromadb')
collection = client.get_or_create_collection('auto-rag')

corpus_df = pd.read_parquet('path/to/corpus.parquet')
existing_qa_df = pd.read_parquet(
    'path/to/existing_qa.parquet')  # It has to contain 'query' and 'generation_gt' columns.
llm = OpenAI(model='gpt-3.5-turbo', temperature=1.0)
qa_df = make_qa_with_existing_qa(corpus_df, existing_qa_df, content_size=50,
                                 exist_gen_gt=True, collection=collection,
                                 output_filepath='path/to/qa.parquet', cache_batch=64,
                                 embedding_model='openai_embed_3_large', top_k=5)