Um novo índice de resumo de documentos para sistemas de controle de qualidade com tecnologia LLM
Nesta postagem do blog, apresentamos uma nova estrutura de dados LlamaIndex: um índice de resumo de documentos. Descrevemos como isso pode ajudar a oferecer melhor desempenho de recuperação em comparação com a pesquisa semântica tradicional e também apresentamos um exemplo.
Fundo
Um dos principais casos de uso de Large Language Models (LLMs) é responder a perguntas sobre seus próprios dados. Para fazer isso, emparelhamos o LLM com um modelo de “recuperação” que pode realizar a recuperação de informações sobre um corpus de conhecimento e realizar a síntese de respostas sobre os textos recuperados usando o LLM. Essa estrutura geral é chamada de Geração Aumentada de Recuperação.
A maioria dos usuários que constroem sistemas de controle de qualidade baseados em LLM atualmente tende a fazer o seguinte:
- Pegue os documentos de origem, divida cada um em pedaços de texto
- Armazene pedaços de texto em um vetor db
- Durante o tempo de consulta, recupere blocos de texto incorporando similaridade e/ou filtros de palavra-chave.
- Realizar síntese de resposta
Limitações das Abordagens Existentes
Existem algumas limitações na recuperação de incorporação usando blocos de texto.
- Pedaços de texto carecem de contexto global. Muitas vezes, a pergunta requer contexto além do que está indexado em um bloco específico.
- Ajuste cuidadoso dos limites de pontuação top-k/semelhança. Torne o valor muito pequeno e você perderá o contexto. Torne o valor muito grande e o custo/latência pode aumentar com um contexto mais irrelevante.
- As incorporações nem sempre selecionam o contexto mais relevante para uma pergunta. As incorporações são inerentemente determinadas separadamente entre o texto e o contexto.
Índice de resumo do documento
Propomos um novo índice no LlamaIndex que irá extrair/indexar um resumo de texto não estruturado para cada documento . Esse índice pode ajudar a melhorar o desempenho de recuperação além das abordagens de recuperação existentes. Ele ajuda a indexar mais informações do que um único bloco de texto e carrega mais significado semântico do que tags de palavra-chave. Ele também permite uma forma mais flexível de recuperação: podemos fazer recuperação LLM e recuperação baseada em incorporação.
Como funciona
Durante o tempo de compilação, ingerimos cada documento e usamos um LLM para extrair um resumo de cada documento. Também dividimos o documento em blocos de texto (nós). Tanto o resumo quanto os nós são armazenados em nossa abstração do Document Store . Mantemos um mapeamento do resumo para os nós/documentos de origem.
Durante o tempo de consulta, recuperamos documentos relevantes para a consulta com base em seus resumos, usando as seguintes abordagens:
- Recuperação baseada em LLM: Apresentamos conjuntos de resumos de documentos ao LLM e pedimos ao LLM para determinar quais documentos são relevantes + sua pontuação de relevância.
- Recuperação baseada em incorporação: Recuperamos documentos relevantes com base na similaridade de incorporação resumida (com um limite de k superior).
O armazenamento de resumos de um documento também permite a recuperação baseada em LLM . Em vez de alimentar o documento inteiro para o LLM no início, podemos primeiro fazer com que o LLM inspecione o resumo conciso do documento para ver se ele é relevante para a consulta. Isso aproveita os recursos de raciocínio dos LLMs, que são mais avançados do que a pesquisa baseada em incorporação, mas evita o custo/latência de alimentar o documento inteiro para o LLM
Informações Adicionais
A recuperação de documentos com resumos pode ser considerada um “meio termo” entre a pesquisa semântica e o resumo de força bruta em todos os documentos. Procuramos documentos com base na relevância do resumo com a consulta fornecida e, em seguida, retornamos todos os *nós* correspondentes aos documentos recuperados.
Por que devemos fazer isso? Esse método de recuperação fornece ao usuário mais contexto do que top-k em um bloco de texto, recuperando o contexto em um nível de documento. Mas também é uma abordagem mais flexível/automática do que a modelagem de tópicos; chega de se preocupar se o seu texto tem as tags de palavra-chave corretas!
Exemplo
Vamos percorrer um exemplo que mostra o índice de resumo do documento, sobre artigos da Wikipédia sobre diferentes cidades.
O restante deste guia apresenta os trechos de código relevantes. Você pode encontrar o passo a passo completo aqui (e aqui está o link do caderno ).
Podemos construir GPTDocumentSummaryIndex
um conjunto de documentos e passar um ResponseSynthesizer
objeto para sintetizar os resumos dos documentos.
from llama_index import (
SimpleDirectoryReader,
LLMPredictor,
ServiceContext,
ResponseSynthesizer
)
from llama_index.indices.document_summary import GPTDocumentSummaryIndex
from langchain.chat_models import ChatOpenAI
# load docs, define service context
...
# build the index
response_synthesizer = ResponseSynthesizer.from_args(response_mode="tree_summarize", use_async=True)
doc_summary_index = GPTDocumentSummaryIndex.from_documents(
city_docs,
service_context=service_context,
response_synthesizer=response_synthesizer
)
summary = doc_summary_index.get_document_summary("Boston")
from llama_index.indices.document_summary import DocumentSummaryIndexRetriever
retriever = DocumentSummaryIndexRetriever(
doc_summary_index,
# choice_select_prompt=choice_select_prompt,
# choice_batch_size=choice_batch_size,
# format_node_batch_fn=format_node_batch_fn,
# parse_choice_select_answer_fn=parse_choice_select_answer_fn,
# service_context=service_context
)
retrieved_nodes = retriever.retrieve("What are the sports teams in Toronto?")
print(retrieved_nodes[0].score)
print(retrieved_nodes[0].node.get_text())The retriever will retrieve a set of relevant nodes for a given index.
8.0
Toronto ( (listen) tə-RON-toh; locally [təˈɹɒɾ̃ə] or [ˈtɹɒɾ̃ə]) is the capital city of the Canadian province of Ontario. With a recorded population of 2,794,356 in 2021, it is the most populous city in Canada...
API de alto nível
query_engine = doc_summary_index.as_query_engine(
response_mode="tree_summarize", use_async=True
)
response = query_engine.query("What are the sports teams in Toronto?")
print(response)
# use retriever as part of a query engine
from llama_index.query_engine import RetrieverQueryEngine
# configure response synthesizer
response_synthesizer = ResponseSynthesizer.from_args()
# assemble query engine
query_engine = RetrieverQueryEngine(
retriever=retriever,
response_synthesizer=response_synthesizer,
)
# query
response = query_engine.query("What are the sports teams in Toronto?")
print(response)
A abordagem de resumo automático sobre qualquer parte do texto é realmente empolgante. Estamos entusiasmados para desenvolver extensões em duas áreas:
- Continue explorando o resumo automático em diferentes camadas. Atualmente está no nível do documento, mas que tal resumir um grande pedaço de texto em um menor? (por exemplo, um one-liner).
- Continue explorando a recuperação baseada em LLM, cujo resumo ajuda a desbloquear.
Guia de resumo do documento
Link do bloco de notas