宣布 LlamaCloud 全面上线(以及我们获得 1900 万美元 A 轮融资)!
LlamaIndex

Ravi Theja 2023-05-07

使用 LlamaIndex 构建和评估问答系统

引言

LlamaIndex (GPT Index) 提供了一个接口,用于连接您的大型语言模型 (LLM) 与外部数据。LlamaIndex 提供了各种数据结构来索引您的数据,例如列表索引、向量索引、关键字索引和树索引。它提供了高级 API 和低级 API — 高级 API 仅用五行代码即可构建问答 (QA) 系统,而低级 API 允许您自定义检索和合成的各个方面。

然而,将这些系统投入生产需要仔细评估整体系统的性能——即给定输入时的输出质量。评估检索增强生成可能具有挑战性,因为用户需要为给定上下文设计一组相关问题的数据集。为了克服这些障碍,LlamaIndex 提供了问题生成和无标签评估模块。

在这篇博客中,我们将讨论使用问题生成和评估模块的三步评估过程

  1. 从文档中生成问题
  2. 使用 LlamaIndex QueryEngine 抽象(管理 LLM 和数据索引之间的交互)为问题生成答案/源节点。
  3. 评估问题(查询)、答案和源节点是否匹配/一致

1. 问题生成

需要注意的是,这种方法不需要真实标签。问题生成的目的是基于上下文生成一个初始输入数据集,用于评估问答系统。

LlamaIndex 提供了 DataGenerator 类,它使用 ListIndex 从给定文档生成问题。默认情况下,它使用 OpenAI ChatGPT (gpt-3.5-turbo) 进行问题生成。

from llama_index.evaluation import DatasetGenerator
from llama_index import SimpleDirectoryReader

# Load documents
reader = SimpleDirectoryReader("./data")
documents = reader.load_data()

# Generate Question
data_generator = DatasetGenerator.from_documents(documents)
question = data_generator.generate_questions_from_nodes()

2. 生成答案/源节点(上下文)

使用列表索引,我们在响应对象中为生成的问题生成答案和源节点。

from llama_index import GPTVectorStoreIndex, SimpleDirectoryReader, load_index_from_storage, StorageContext

# load documents
documents = SimpleDirectoryReader('./data').load_data()

# Create Index
index = GPTVectorStoreIndex.from_documents(documents)

# save index to disk
index.set_index_id("vector_index")
index.storage_context.persist('storage')

# rebuild storage context
storage_context = StorageContext.from_defaults(persist_dir='storage')
# load index
index = load_index_from_storage(storage_context, index_id="vector_index")

# Query the index
query_engine = index.as_query_engine(similarity_top_k=3)
response = query_engine.query(<Query>)

# Response object has both response and source nodes.

3. 评估

评估模块可用于回答以下三个问题

  1. 生成的响应和源节点(上下文)是否匹配?— 响应 + 源节点(上下文)
  2. 生成的响应、源节点(上下文)和查询是否匹配?— 查询 + 响应 + 源节点(上下文)
  3. 检索到的源节点中哪些源节点用于生成响应?— 查询 + 响应 + 单个源节点(上下文)

评估可以通过查询、上下文和响应的某种组合来完成,将这些与 LLM 调用结合起来。

响应 + 源节点(上下文)

此函数回答以下问题:生成的响应和源节点(上下文)是否匹配?

给定查询的响应对象会返回响应以及生成响应所使用的源节点(上下文)。我们现在可以根据检索到的源进行评估——而无需考虑查询!这使您能够衡量幻觉——如果响应与检索到的源不匹配,这意味着模型可能正在“幻觉”一个答案,因为它没有将其答案根植于提示中提供的上下文。

结果是二元响应——即“是/否”。

  • 是 — 响应和源节点(上下文)匹配。
  • 否 — 响应和源节点(上下文)不匹配。
from llama_index.evaluation import ResponseEvaluator

# build service context
llm_predictor = LLMPredictor(llm=ChatOpenAI(temperature=0, model_name="gpt-4"))
service_context = ServiceContext.from_defaults(llm_predictor=llm_predictor)

# Build index and get response object
...

# define evaluator
evaluator = ResponseEvaluator(service_context=service_context)

# evaluate using the response object
eval_result = evaluator.evaluate(response)

查询 + 响应 + 源节点(上下文)

此函数回答以下问题:生成的响应、源节点(上下文)和查询是否匹配?

通常使用“响应 + 源节点(上下文)”方法时,生成的响应与源节点一致,但可能不是查询的答案。因此,将查询与响应和源节点一起考虑是进行更准确分析的好方法。

目标是确定响应 + 源上下文是否回答了查询。结果是二元响应——即“是/否”。

  • 是 — 查询、响应和源节点(上下文)匹配。
  • 否 — 查询、响应和源节点(上下文)不匹配。
from llama_index.evaluation import QueryResponseEvaluator

# build service context
llm_predictor = LLMPredictor(llm=ChatOpenAI(temperature=0, model_name="gpt-4"))
service_context = ServiceContext.from_defaults(llm_predictor=llm_predictor)

# Build index and get response object
...

# define evaluator
evaluator = QueryResponseEvaluator(service_context=service_context)

# evaluate using the response object
eval_result = evaluator.evaluate(query, response)

查询 + 响应 + 单个源节点(上下文)

此函数回答以下问题:检索到的源节点中哪些源节点用于生成响应?

在现实世界中,源节点通常可能来自不同的文档。在这种情况下,了解哪些源节点是相关的并向用户显示这些文档非常重要。这种评估模式将查看每个源节点,并判断每个源节点是否包含对查询的答案。

from llama_index.evaluation import QueryResponseEvaluator

# build service context
llm_predictor = LLMPredictor(llm=ChatOpenAI(temperature=0, model_name="gpt-4"))
service_context = ServiceContext.from_defaults(llm_predictor=llm_predictor)

# build index and get response object 
...

# define evaluator
evaluator = QueryResponseEvaluator(service_context=service_context)

# evaluate using the response object
eval_result = evaluator.evaluate_source_nodes(response)

使用 LlamaIndex 评估问答系统的 Google Colab notebook —

结论

LlamaIndex 提供了一个无需真实标签即可构建和评估问答系统的全面解决方案。通过使用问题生成和评估模块,您可以确保您的系统准确可靠,使其适合生产环境。