Melhorar a qualidade da cadeia de RAG
Este artigo aborda como você pode melhorar a qualidade do aplicativo RAG usando componentes da cadeia RAG.
A cadeia RAG recebe uma consulta do usuário como entrada, recupera informações relevantes com base nessa consulta e gera uma resposta apropriada fundamentada nos dados recuperados. Embora as etapas exatas dentro de uma cadeia RAG possam variar amplamente dependendo do caso de uso e dos requisitos, os seguintes são os principais componentes a serem considerados ao construir sua cadeia RAG:
- Compreensão de consulta: analisar e transformar as consultas dos usuários para melhor representar a intenção e extrair informações relevantes, como filtros ou palavras-chave, para melhorar o processo de recuperação.
- Recuperação: localizar as partes mais relevantes das informações fornecidas em uma consulta de recuperação. No caso de dados não estruturados, isso normalmente envolve uma ou uma combinação de pesquisa semântica ou baseada em palavra-chave.
- Ampliação da solicitação: combinar uma consulta de usuário com informações recuperadas e instruções para orientar o LLM para gerar respostas de alta qualidade.
- LLM: selecionar o modelo mais apropriado (e parâmetros do modelo) para seu aplicativo para otimizar/balancear o desempenho, a latência e o custo.
- Pós-processamento e limitações: aplicação de etapas adicionais de processamento e medidas de segurança para garantir que as respostas geradas pelo LLM estejam no tópico, sejam consistentes factualmente e sigam diretrizes ou restrições específicas.
Implementar e avaliar correções de qualidade iterativamente mostra como iterar sobre os componentes de uma cadeia.
Entendimento da consulta
Usar a consulta de usuário diretamente como uma consulta de recuperação pode funcionar para algumas consultas. No entanto, geralmente é benéfico reformular a consulta antes da etapa de recuperação. O entendimento da consulta compreende uma etapa (ou série de etapas) no início de uma cadeia para analisar e transformar as consultas dos usuários para melhor representar a intenção, extrair informações relevantes e, por fim, auxiliar o processo subsequente de recuperação. As abordagens para transformar uma consulta de usuário para melhorar a recuperação incluem:
Reescrita de consulta: a reescrita de consulta envolve traduzir uma consulta do usuário em uma ou mais consultas que melhor representam a intenção original. O objetivo é reformular a consulta de uma forma que aumente a probabilidade da etapa de recuperação encontrar os documentos mais relevantes. Isso pode ser particularmente útil ao lidar com consultas complexas ou ambíguas que podem não corresponder diretamente à terminologia usada nos documentos de recuperação.
Exemplos:
- Parafrasear o histórico de conversas em um chat multiturno
- Corrigir erros de ortografia na consulta do usuário
- Substituir palavras ou frases na consulta do usuário por sinônimos para capturar uma gama mais ampla de documentos relevantes
Importante
A reescrita de consulta deve ser feita em conjunto com alterações no componente de recuperação
Extração de filtros: em alguns casos, as consultas de usuário podem conter filtros ou critérios específicos que podem ser usados para restringir os resultados da pesquisa. A extração de filtros envolve identificar e extrair esses filtros da consulta e passá-los para a etapa de recuperação como parâmetros adicionais. Isso pode ajudar a melhorar a relevância dos documentos recuperados, concentrando-se em subconjuntos específicos dos dados disponíveis.
Exemplos:
- Extrair períodos de tempo específicos mencionados na consulta, como “artigos dos últimos 6 meses” ou “relatórios de 2023”.
- Identificar menções de produtos, serviços ou categorias específicos na consulta, como “Serviços Profissionais do Databricks” ou “notebooks”.
- Extrair entidades geográficas da consulta, como nomes de cidade ou códigos de país.
Observação
A extração de filtros deve ser realizada em conjunto com mudanças nos componentes de pipeline de dados e cadeia de recuperação da extração de metadados. A etapa de extração de metadados deve garantir que os campos de metadados relevantes estejam disponíveis para cada documento/parte, e a etapa de recuperação deve ser implementada para aceitar e aplicar os filtros extraídos.
Além da reescrita de consulta e extração de filtros, outra consideração importante no entendimento de consultas é se utilizar uma única chamada de LLM ou várias chamadas. Embora usar uma única chamada com uma solicitação cuidadosamente elaborada possa ser eficiente, há casos em que dividir o processo de entendimento da consulta em várias chamadas de LLM pode gerar melhores resultados. Isso, aliás, é uma regra geralmente aplicável quando você está tentando implementar várias etapas lógicas complexas em uma única solicitação.
Por exemplo, você pode usar uma chamada de LLM para classificar a intenção da consulta, outra para extrair entidades relevantes e uma terceira para reescrever a consulta com base nas informações extraídas. Embora essa abordagem possa adicionar algum atraso ao processo geral, ela pode permitir um controle mais refinado e potencialmente melhorar a qualidade dos documentos recuperados.
Entendimento de consultas em várias etapas para um bot de suporte
Veja como um componente de entendimento de consulta em várias etapas pode ser estruturado para um bot de suporte ao cliente:
- Classificação de intenção: use um LLM para classificar a consulta do usuário em categorias pré-definidas, como “informações sobre produto”, “solução de problemas” ou “gerenciamento de conta”.
- Extração de entidades: com base na intenção identificada, use outra chamada de LLM para extrair entidades relevantes da consulta, como nomes de produtos, erros relatados ou números de conta.
- Reescrita da consulta: use a intenção e as entidades extraídas para reescrever a consulta original em um formato mais específico e direcionado, por exemplo, “Minha cadeia RAG está falhando ao implantar no Model Serving, estou vendo o seguinte erro...”.
Recuperação
O componente de recuperação da cadeia RAG é responsável por encontrar as partes mais relevantes de informação fornecidas em uma consulta de recuperação. No contexto de dados não estruturados, a recuperação geralmente envolve uma ou uma combinação de busca semântica, busca baseada em palavras-chave e filtragem de metadados. A escolha da estratégia de recuperação depende dos requisitos específicos do aplicativo, da natureza dos dados e dos tipos de consultas que você espera lidar. Vamos comparar estas opções:
- Pesquisa semântica: a pesquisa semântica usa um modelo de inserção para converter cada parte do texto em uma representação vetorial que captura seu significado semântico. Comparando a representação vetorial da consulta de recuperação com as representações vetoriais das partes, a pesquisa semântica pode recuperar documentos conceitualmente semelhantes, mesmo que eles não contenham as palavras-chave exatas da consulta.
- Pesquisa baseada em palavras-chave: a pesquisa baseada em palavras-chave determina a relevância dos documentos analisando a frequência e a distribuição de palavras compartilhadas entre a consulta de recuperação e os documentos indexados. Quanto mais frequentemente as mesmas palavras aparecerem na consulta e em um documento, maior a pontuação de relevância atribuída a esse documento.
- Pesquisa híbrida: a pesquisa híbrida combina os pontos fortes da pesquisa semântica e baseada em palavras-chave empregando um processo de recuperação em duas etapas. Primeiro, ela executa uma pesquisa semântica para recuperar um conjunto de documentos conceitualmente relevantes. Em seguida, ela aplica a pesquisa baseada em palavras-chave nesse conjunto reduzido para refinar ainda mais os resultados com base em correspondências exatas de palavra-chave. Por fim, ela combina as pontuações de ambas as etapas para classificar os documentos.
Comparar estratégias de recuperação
A tabela a seguir contrasta cada uma dessas estratégias de recuperação entre si:
Pesquisa semântica | Pesquisa por palavra-chave | Pesquisa híbrida | |
---|---|---|---|
Explicação simples | Se os mesmos conceitos aparecerem na consulta e em um documento em potencial, eles são relevantes. | Se as mesmas palavras aparecerem na consulta e em um documento em potencial, elas são relevantes. Quanto mais palavras da consulta no documento, mais relevante é esse documento. | Executa uma pesquisa semântica E uma pesquisa de palavras-chave e combina os resultados. |
Exemplo de caso de uso | Suporte ao cliente onde as consultas de usuário são diferentes das palavras nos manuais do produto. Exemplo: “como eu ligo meu telefone?” e a seção do manual é chamada de “ativando a energia”. | Suporte ao cliente onde as consultas contêm termos técnicos específicos e não descritivos. Exemplo: “o que o modelo HD7-8D faz?” | Consultas de suporte ao cliente que combinam termos semânticos e técnicos. Exemplo: “como eu ligo meu HD7-8D?” |
Abordagens técnicas | Usa inserções para representar o texto em um espaço vetorial contínuo, permitindo a pesquisa semântica. | Baseia-se em métodos discretos baseados em tokens como bag-of-words, TF-IDF e BM25 para correspondência de palavras-chave. | Use uma abordagem de reclassificação para combinar os resultados, como fusão de classificação recíproca ou um modelo de reclassificação. |
Pontos fortes | Recuperar informações contextualmente semelhantes a uma consulta, mesmo que as palavras exatas não sejam usadas. | Cenários que exigem correspondências precisas de palavras-chave, ideais para consultas focadas em termos específicos, como nomes de produtos. | Combina o melhor de ambas as abordagens. |
Maneiras de aprimorar o processo de recuperação
Além dessas estratégias principais de recuperação, existem várias técnicas que você pode aplicar para aprimorar ainda mais o processo de recuperação:
- Expansão de consulta: a expansão de consulta pode ajudar a capturar uma gama mais ampla de documentos relevantes usando diversas variações da consulta de recuperação. Isso pode ser feito tanto conduzindo pesquisas individuais para cada consulta expandida quanto utilizando uma concatenação de todas as consultas expandidas em uma única consulta de recuperação.
Observação
A expansão de consultas deve ser realizada em conjunto com mudanças no componente de entendimento de consultas (cadeia RAG). As diversas variações de uma consulta de recuperação normalmente são geradas nesta etapa.
- Reclassificação: após recuperar um conjunto inicial de partes, aplique critérios adicionais de classificação (por exemplo, ordenação por tempo) ou um modelo de reclassificação para reordenar os resultados. A reclassificação pode ajudar a priorizar as partes mais relevantes considerando uma consulta específica de recuperação. A reclassificação com modelos de codificador cruzado como mxbai-rerank e ColBERTv2 pode resultar em melhorias no desempenho de recuperação.
- Filtragem de metadados: use filtros de metadados extraídos da etapa de entendimento da consulta para reduzir o espaço de busca com base em critérios específicos. Os filtros de metadados podem incluir atributos como tipo de documento, data de criação, autor ou marcas específicas do domínio. Ao combinar filtros de metadados com busca semântica ou baseada em palavras-chave, você pode criar recuperações mais direcionadas e eficientes.
Observação
A filtragem de metadados deve ser realizada em conjunto com mudanças nos componentes de entendimento de consulta (cadeia RAG) e extração de metadados (pipeline de dados).
Ampliação da solicitação
A ampliação da solicitação é a etapa em que a consulta do usuário é combinada com as informações recuperadas e instruções em um modelo de solicitação para orientar o modelo de linguagem na geração de respostas de alta qualidade. Iterar neste modelo para otimizar a solicitação fornecida ao LLM (também conhecido como engenharia de prompt) é necessário para garantir que o modelo seja orientado a produzir respostas precisas, fundamentadas e coerentes.
Existem guias completos sobre engenharia de prompt, mas aqui estão algumas considerações a ter em mente ao iterar no modelo de solicitação:
- Forneça exemplos
- Inclua exemplos de consultas bem formuladas e suas respostas ideais correspondentes dentro do próprio modelo de solicitação (few-shot learning). Isso ajuda o modelo a entender o formato desejado, o estilo e o conteúdo das respostas.
- Uma maneira útil de criar bons exemplos é identificar os tipos de consultas com os quais sua cadeia tem dificuldades. Crie respostas de referência para essas consultas e inclua-as como exemplos na solicitação.
- Certifique-se de que os exemplos fornecidos sejam representativos das consultas dos usuários que você prevê no momento da inferência. Procure abranger uma variedade diversificada de consultas esperadas para ajudar o modelo a generalizar melhor.
- Parametrize seu modelo de solicitação
- Projete seu modelo de solicitação para ser flexível, parametrizando-o para incorporar informações adicionais além dos dados recuperados e da consulta do usuário. Isso pode incluir variáveis como data atual, contexto do usuário ou outros metadados relevantes.
- Injetar essas variáveis na solicitação durante o tempo de inferência pode permitir respostas mais personalizadas ou com reconhecimento do contexto.
- Considere o uso de solicitações de Cadeia de Pensamento
- Para consultas complexas onde respostas diretas não são prontamente aparentes, considere solicitações de Cadeia de Pensamento (CoT). Essa estratégia de engenharia de prompt divide perguntas complicadas em etapas mais simples e sequenciais, orientando o LLM por meio de um processo de raciocínio lógico.
- Ao solicitar ao modelo a “pensar no problema passo a passo”, você o encoraja a fornecer respostas mais detalhadas e bem fundamentadas, o que pode ser especialmente eficaz para lidar com consultas de várias etapas ou abertas.
- As solicitações podem não ser transferidas entre modelos
- Reconheça que as solicitações geralmente não são transferidas diretamente entre diferentes modelos de linguagem. Cada modelo tem suas características únicas, onde uma solicitação que funciona bem para um modelo pode não ser tão eficaz para outro.
- Experimente diferentes formatos e comprimentos de solicitação, consulte guias online (como OpenAI Cookbook, Anthropic cookbook) e esteja preparado para adaptar e refinar suas solicitações ao alternar entre modelos.
LLM
O componente de geração da cadeia RAG recebe o modelo de solicitação ampliada da etapa anterior e o passa para um LLM. Ao selecionar e otimizar um LLM para o componente de geração de uma cadeia RAG, considere os seguintes fatores, que são igualmente aplicáveis a qualquer outra etapa que envolva chamadas de LLM:
- Experimente diferentes modelos prontos para uso.
- Cada modelo tem suas próprias propriedades, pontos fortes e fraquezas únicas. Alguns modelos podem ter melhor compreensão de certos domínios ou desempenhar melhor em tarefas específicas.
- Como mencionado anteriormente, tenha em mente que a escolha do modelo também pode influenciar o processo de engenharia de prompts, pois modelos diferentes podem responder de maneira diferente às mesmas solicitações.
- Se houver várias etapas em sua cadeia que exigem um LLM, como chamadas para entendimento de consulta além da etapa de geração, considere usar modelos diferentes para diferentes etapas. Modelos mais caros e de propósito geral podem ser exagerados para tarefas como determinar a intenção de uma consulta do usuário.
- Comece pequeno e aumente conforme necessário.
- Embora seja tentador recorrer imediatamente aos modelos mais poderosos e capazes disponíveis (como o GPT-4, Claude), frequentemente é mais eficiente começar com modelos menores e mais leves.
- Em muitos casos, alternativas menores de código aberto como Llama 3 ou DBRX podem oferecer resultados satisfatórios com um custo menor e tempos de inferência mais rápidos. Esses modelos podem ser particularmente eficazes para tarefas que não exigem raciocínio altamente complexo ou conhecimento extensivo do mundo.
- Ao desenvolver e refinar sua cadeia RAG, avalie continuamente o desempenho e as limitações do modelo escolhido. Se você perceber que o modelo enfrenta dificuldades com certos tipos de consultas ou não consegue fornecer respostas suficientemente detalhadas ou precisas, considere escalar para um modelo mais capaz.
- Monitore o impacto da troca de modelos em métricas-chave como qualidade da resposta, latência e custo, para garantir que você esteja alcançando o equilíbrio certo para os requisitos do seu caso de uso específico.
- Otimize os parâmetros do modelo
- Experimente diferentes configurações de parâmetros para encontrar o equilíbrio ideal entre qualidade da resposta, diversidade e coerência. Por exemplo, ajustar a temperatura pode controlar a aleatoriedade do texto gerado, enquanto max_tokens pode limitar o comprimento da resposta.
- Lembre-se de que as configurações ideais dos parâmetros podem variar dependendo da tarefa específica, da solicitação e do estilo de saída desejado. Teste e refine iterativamente essas configurações com base na avaliação das respostas geradas.
- Ajuste fino específico para a tarefa
- Ao refinar o desempenho, considere ajustar modelos menores para subtarefas específicas dentro da sua cadeia RAG, como entendimento de consultas.
- Ao treinar modelos especializados para tarefas individuais dentro da cadeia RAG, você pode potencialmente melhorar o desempenho geral, reduzir a latência e diminuir os custos de inferência em comparação com o uso de um único modelo grande para todas as tarefas.
- Pré-treinamento contínuo
- Se o aplicativo RAG lida com um domínio especializado ou requer conhecimento que não está bem representado no LLM pré-treinado, considere realizar um pré-treinamento contínuo (CPT) com dados específicos do domínio.
- O pré-treinamento contínuo pode melhorar a compreensão do modelo sobre terminologia específica ou conceitos únicos ao seu domínio. Isso, por sua vez, pode reduzir a necessidade de engenharia extensiva de prompts ou few-shot learning.
Pós-processamento e limitações
Após o LLM gerar uma resposta, muitas vezes é necessário aplicar técnicas de pós-processamento ou limitações para garantir que a saída atenda aos requisitos desejados de formato, estilo e conteúdo. Esta última etapa (ou várias etapas) na cadeia pode ajudar a manter consistência e qualidade em todas as respostas geradas. Se você está implementando pós-processamento e limitações, considere algumas das seguintes práticas:
- Impor o formato de saída
- Dependendo do seu caso de uso, você pode precisar que as respostas geradas sigam um formato específico, como um modelo estruturado ou um tipo de arquivo específico (como JSON, HTML, Markdown, entre outros).
- Se a saída estruturada for necessária, bibliotecas como Instructor ou Outlines fornecem bons pontos de partida para implementar esse tipo de etapa de validação.
- Ao desenvolver, reserve um tempo para garantir que a etapa de pós-processamento seja flexível o suficiente para lidar com variações nas respostas geradas, mantendo o formato necessário.
- Manter a consistência de estilo
- Se seu aplicativo RAG possui diretrizes específicas de estilo ou requisitos de tom (por exemplo, formal vs. casual, conciso vs. detalhado), uma etapa de pós-processamento pode verificar e impor esses atributos de estilo em todas as respostas geradas.
- Filtros de conteúdo e limitações de segurança
- Dependendo da natureza de seu aplicativo RAG e dos potenciais riscos associados ao conteúdo gerado, pode ser importante implementar filtros de conteúdo ou limitações de segurança para evitar a saída de informações inadequadas, ofensivas ou prejudiciais.
- Considere o uso de modelos como Llama Guard ou APIs especificamente projetadas para moderação de conteúdo e segurança, como a API de moderação da OpenAI, para implementar limitações de segurança.
- Lidando com alucinações
- Defender-se contra alucinações também pode ser implementado como uma etapa de pós-processamento. Isso pode envolver a comparação cruzada da saída gerada com documentos recuperados, ou o uso de LLMs adicionais para validar a precisão factual da resposta.
- Desenvolva mecanismos de fallback para lidar com casos em que a resposta gerada não atenda aos requisitos de precisão factual, como gerar respostas alternativas ou fornecer avisos ao usuário.
- Tratamento de erros
- Com quaisquer etapas de pós-processamento, implemente mecanismos para lidar adequadamente com casos em que a etapa encontra um problema ou não consegue gerar uma resposta satisfatória. Isso pode envolver a geração de uma resposta padrão ou a escalada do problema para um operador humano para revisão manual.