Agora que você reuniu seus documentos de teste e consultas e realizou uma análise de documentos na fase de preparação, a próxima fase é a fragmentação. Dividir os documentos em uma coleção de partes do tamanho certo, cada uma contendo conteúdo semanticamente relevante, é um fator-chave para o sucesso de sua implementação de Geração Aumentada de Recuperação (RAG). Passar documentos inteiros ou pedaços superdimensionados é caro, pode sobrecarregar os limites de token do modelo e não produz os melhores resultados. Passar informações para um modelo de linguagem grande que é irrelevante para a consulta pode levar a alucinações. Você precisa otimizar o processo de passar informações relevantes e remover informações irrelevantes. Você faz essa otimização usando estratégias eficazes de fragmentação e pesquisa para minimizar falsos positivos e falsos negativos, e maximizar verdadeiros positivos e verdadeiros negativos.
Passar partes que são muito pequenas e não contêm contexto suficiente para abordar a consulta também leva a resultados ruins. O contexto relevante que existe em várias partes pode não ser capturado. A arte é implementar abordagens de fragmentação eficazes para seus tipos de documentos específicos e suas estruturas e conteúdo. Há várias abordagens de fragmentação a considerar, cada uma com suas próprias implicações de custo e eficácia, dependendo do tipo e da estrutura do documento ao qual são aplicadas.
Este artigo descreve várias abordagens de fragmentação e examina como a estrutura de seus documentos pode influenciar a abordagem de fragmentação escolhida.
Este artigo faz parte de uma série. Leia a introdução.
Economia fragmentada
Ao determinar sua estratégia geral de fragmentação, você deve considerar seu orçamento, juntamente com seus requisitos de qualidade e taxa de transferência para seu corpus de documentos. Há custos de engenharia para o projeto e implementação de cada implementação de fragmentação exclusiva e custos de processamento por documento que diferem dependendo da abordagem. Se seus documentos tiverem mídia incorporada ou vinculada, você deve considerar a economia do processamento desses elementos. Para fragmentação, esse processamento geralmente usa modelos de linguagem para gerar descrições da mídia, e essas descrições são então fragmentadas. Uma abordagem alternativa com alguns meios de comunicação é passá-los como estão para um modelo multimodal no momento da inferência, mas essa abordagem não afetaria a economia de fragmentação.
Esta seção examina a economia de imagens de fragmentação e a solução geral.
Economia de fragmentação de imagens
Há um custo para usar um modelo de linguagem para gerar uma descrição de uma imagem que é então fragmentada. Por exemplo, serviços baseados em nuvem, como o Azure OpenAI, cobram em uma base básica por transação ou em uma base de provisionamento pré-pago. Imagens maiores incorrem em um custo maior. Através da sua análise de documentos, você deve determinar quais imagens são valiosas para fragmentar e quais imagens você deve ignorar. A partir daí, você precisa entender o número e os tamanhos das imagens em sua solução e deve pesar o valor de fragmentar as descrições das imagens em relação ao custo de gerar essas descrições.
Uma maneira de determinar quais imagens processar é usar um serviço como o Azure AI Vision para classificar imagens, marcar imagens ou fazer a deteção de logotipo. Você pode usar os resultados e indicadores de confiança para determinar se a imagem adiciona valor significativo e contextual e deve ser processada. As chamadas para o Azure AI Vision podem ser menos dispendiosas do que as chamadas para modelos de linguagem, pelo que esta abordagem pode levar a poupanças de custos. Você precisa experimentar para determinar quais níveis de confiança e quais classificações ou tags fornecem os melhores resultados para seus dados. Outra opção é construir o seu próprio modelo de classificador. Você precisa levar em conta os custos de construção, hospedagem e manutenção de seu próprio modelo de classificador.
Outra otimização de custo é o armazenamento em cache usando o padrão cache-side. Você pode gerar uma chave com base no hash da imagem. Como primeiro passo, você pode verificar se você tem um resultado em cache de uma execução anterior ou documento processado anteriormente. Se o fizer, pode utilizar esse resultado. Essa abordagem evita os custos de chamar um classificador ou um modelo de linguagem. Se não houver cache, quando você ligar para o classificador ou modelo de idioma, você armazenará o resultado em cache. Futuras chamadas para esta imagem usariam o cache.
Um fluxo de trabalho simples integrando todos esses processos de otimização de custos seria:
- Verifique se o processamento da imagem foi armazenado em cache. Em caso afirmativo, use os resultados armazenados em cache.
- Execute o classificador para determinar se você deve processar a imagem. Armazene em cache o resultado da classificação. Só prossiga se a sua lógica de classificação lhe disser para o fazer.
- Gere a descrição da sua imagem. Armazene o resultado em cache.
Economia da solução global
A seguir estão os fatores a serem considerados ao analisar o custo da sua solução geral:
- Número de implementações de fragmentação exclusivas - Cada implementação exclusiva tem um custo de engenharia e manutenção. Você precisa considerar o número de tipos de documentos exclusivos em seu corpus e as compensações de custo versus qualidade de implementações exclusivas para cada um.
- Custo por documento de cada implementação - Algumas abordagens de fragmentação podem levar a blocos de melhor qualidade, mas têm um custo financeiro e temporal mais alto para gerar esses blocos. Por exemplo, usar um modelo pré-criado no Azure AI Document Intelligence provavelmente tem um custo por documento mais alto do que uma implementação de análise de texto puro, mas pode levar a partes melhores.
- Número de documentos iniciais - O número de documentos iniciais que você precisa processar para iniciar sua solução.
- Número de documentos incrementais - O número e a taxa de novos documentos que você deve processar para a manutenção contínua do sistema.
Carregamento e fragmentação
Logicamente, durante a fragmentação, você deve primeiro carregar o documento na memória em algum formato. Em seguida, o código de fragmentação opera em relação à representação na memória do documento. Você pode optar por combinar o código de carregamento com o chunking, ou pode separar o carregamento em sua própria fase. A abordagem escolhida deve basear-se, em grande medida, nas restrições arquitetónicas e nas suas preferências. Esta seção explora brevemente ambas as opções e, em seguida, fornece algumas recomendações gerais.
Carregamento e fragmentação separados
Há várias razões pelas quais você pode optar por separar as fases de carregamento e fragmentação. Talvez você queira encapsular a lógica no código de carregamento. Você pode querer persistir o resultado do código de carregamento antes de fragmentar, especialmente ao experimentar várias permutações de fragmentação para economizar tempo ou custo de processamento. Por fim, talvez você queira executar o código de carregamento e fragmentação em processos separados por motivos de arquitetura, como bulkheading de processo ou segmentação de segurança envolvendo remoção de PII.
Encapsular lógica no código de carregamento
Você pode optar por encapsular a lógica de pré-processamento na fase de carregamento. Isso simplifica o código de fragmentação porque ele não precisa fazer nenhum pré-processamento. O pré-processamento pode ser tão simples quanto remover ou anotar partes do documento que você determinou que deseja ignorar na análise do documento, como marcas d'água, cabeçalhos e rodapés, ou tão complexo quanto reformatar o documento. A seguir estão alguns exemplos de pré-processamento que você pode optar por encapsular na fase de carregamento:
- Remova ou anote itens que deseja ignorar.
- Substitua referências de imagem por descrições de imagens. Durante essa fase, você usa um LLM para gerar uma descrição para a imagem e atualizar o documento com essa descrição. Se você determinou na análise do documento que há texto ao redor que fornece contexto valioso para a imagem, passe isso, junto com a imagem, para o LLM.
- Transfira ou copie imagens para armazenamento de ficheiros, como o Azure Data Lake, para serem processadas separadamente do texto do documento. Se você determinou na análise do documento que há texto ao redor que fornece contexto valioso para a imagem, você precisa armazenar esse texto junto com a imagem no armazenamento de arquivos.
- Reformatar tabelas para que sejam processadas mais facilmente.
Persistindo o resultado do código de carregamento
Há várias razões pelas quais você pode optar por manter o resultado do código de carregamento. Um motivo é se você quiser a capacidade de inspecionar os documentos depois que eles forem carregados e pré-processados, mas antes que a lógica de fragmentação seja executada. Outra razão é que você pode querer executar diferentes lógicas de fragmentação contra o mesmo código pré-processado durante o desenvolvimento ou na produção. A persistência do código carregado acelera esse processo.
Execute o carregamento e fragmentação de código em processos separados
Separar o código de carregamento e fragmentação em processos separados ajuda a permitir a execução de várias implementações de fragmentação em relação ao mesmo código pré-processado. Essa separação também permite que você execute o carregamento e o fragmento de código em diferentes ambientes de computação e em diferentes hardwares. Além disso, esse design permite dimensionar de forma independente a computação usada para carregar e fragmentar.
Combine carregamento e fragmentação
Combinar o código de carregamento e fragmentação é uma implementação mais simples na maioria dos casos. Muitas das operações que você pode considerar fazer no pré-processamento em uma fase de carregamento separada podem ser realizadas na fase de fragmentação. Por exemplo, em vez de substituir URLs de imagem por uma descrição na fase de carregamento, a lógica de fragmentação pode fazer chamadas para o LLM para obter uma descrição de texto e fragmentar a descrição.
Quando você tem formatos de documento como HTML que têm tags com referências a imagens, você precisa garantir que o leitor ou analisador que o código de fragmentação está usando não remova as tags. O código de fragmentação precisa ser capaz de identificar referências de imagem.
Recomendações
A seguir estão algumas recomendações a serem consideradas ao determinar se você combina ou separa sua lógica de fragmentação.
- Comece com a combinação da lógica de carregamento e fragmentação. Separe-os quando a sua solução o exigir.
- Evite converter documentos para um formato intermediário se optar por separar os processos. Operações como essa podem ter perdas.
Abordagens de fragmentação
Esta seção fornece uma visão geral de algumas abordagens comuns de fragmentação. Esta lista não pretende ser exaustiva, mas sim algumas abordagens representativas comuns. Você pode usar várias abordagens na implementação, como combinar o uso de um modelo de linguagem grande para obter uma representação de texto de uma imagem com muitas das abordagens listadas.
Cada abordagem é acompanhada por uma matriz de tomada de decisão resumida que destaca as ferramentas, os custos associados e muito mais. O esforço de engenharia e os custos de processamento são subjetivos e são incluídos para comparação relativa.
Análise baseada em frases
Esta abordagem direta divide os documentos de texto em partes compostas por frases completas. Os benefícios dessa abordagem incluem que ela é barata de implementar, tem baixo custo de processamento e pode ser aplicada a qualquer documento baseado em texto escrito em prosa ou frases completas. Um desafio com essa abordagem é que cada pedaço pode não capturar o contexto completo de um pensamento ou significado. Muitas vezes, várias frases devem ser tomadas juntas para capturar o significado semântico.
Ferramentas: Tokenizador de sentença SpaCy, divisor de texto recursivo LangChain, tokenizador de sentença NLTK
Esforço de engenharia: Baixo
Custo de processamento: Baixo
Casos de uso: documentos não estruturados escritos em prosa ou frases completas, e seu corpus de documentos contém um número proibitivo de diferentes tipos de documentos para construir estratégias individuais de fragmentação para
Exemplos: conteúdo gerado pelo usuário, como feedback aberto de pesquisas, postagens em fóruns, avaliações, mensagens de e-mail, um romance ou um ensaio
Análise de tamanho fixo (com sobreposição)
Essa abordagem divide um documento em partes com base em um número fixo de caracteres ou tokens e permite alguma sobreposição de caracteres entre partes. Esta abordagem tem muitas das mesmas vantagens e desvantagens que a análise baseada em frases. Uma vantagem que essa abordagem tem sobre a análise baseada em frases é que é possível obter partes com significado semântico que abrange várias frases.
Você deve escolher o tamanho fixo das partes e a quantidade de sobreposição. Como os resultados diferem para diferentes tipos de documentos, é melhor usar uma ferramenta como o visualizador de blocos HuggingFace para fazer análises exploratórias. Ferramentas como esta permitem-lhe visualizar como os seus documentos são fragmentados, tendo em conta as suas decisões. É uma prática recomendada usar tokens BERT sobre contagens de caracteres ao usar análise de tamanho fixo. Os tokens BERT são baseados em unidades significativas de linguagem, portanto, preservam mais informações semânticas do que contagens de caracteres.
Ferramentas: LangChain divisor de texto recursivo, Hugging Face chunk visualizer
Esforço de engenharia: Baixo
Custo de processamento: Baixo
Casos de uso: Documentos não estruturados escritos em prosa ou não-prosa com frases completas ou incompletas. Seu corpus de documentos contém um número proibitivo de diferentes tipos de documentos para criar estratégias individuais de fragmentação para
Exemplos: conteúdo gerado pelo usuário, como feedback aberto de pesquisas, postagens em fóruns, avaliações, mensagens de e-mail, notas ou listas pessoais ou de pesquisa
Código personalizado
Essa abordagem analisa documentos usando código personalizado para criar blocos. Essa abordagem é mais bem-sucedida para documentos baseados em texto onde a estrutura é conhecida ou pode ser inferida e um alto grau de controle sobre a criação de blocos é necessário. Você pode usar técnicas de análise de texto, como expressões regulares, para criar blocos com base em padrões dentro da estrutura do documento. O objetivo é criar blocos que tenham tamanho semelhante em comprimento e blocos que tenham conteúdo distinto. Muitas linguagens de programação fornecem suporte para expressões regulares, e algumas têm bibliotecas ou pacotes que oferecem recursos de manipulação de cadeia de caracteres mais elegantes.
Ferramentas: Python (re, regex, BeautifulSoup, lxml, html5lib, marko), R (stringr, xml2), Julia (Gumbo.jl)
Esforço de engenharia: Médio
Custo de processamento: Baixo
Casos de uso: Documentos semi-estruturados onde a estrutura pode ser inferida
Exemplos: depósitos de patentes, documentos de pesquisa, apólices de seguro, roteiros e roteiros
Aumento do modelo de linguagem grande
Modelos de linguagem grandes podem ser usados para criar blocos. Casos de uso comuns são usar um modelo de linguagem grande, como GPT-4, para gerar representações textuais de imagens ou resumos de tabelas que podem ser usadas como partes. O aumento do modelo de linguagem grande é usado com outras abordagens de fragmentação, como código personalizado.
Se você determinou na parte de imagens da seção de análise de documentos que o texto antes ou depois da imagem é necessário para responder a algumas perguntas, você precisa passar esse contexto adicional para o modelo de linguagem grande. É importante experimentar para determinar se esse contexto adicional melhora ou não o desempenho da sua solução.
Se sua lógica de fragmentação dividir a descrição da imagem em vários blocos, certifique-se de incluir o URL da imagem em cada bloco. Incluir a URL da imagem em cada parte garante que os metadados sejam retornados para todas as consultas que a imagem serve, especialmente para cenários em que o usuário final requer a capacidade de acessar a imagem de origem por meio dessa URL ou deseja usar imagens brutas durante o tempo de inferência.
Ferramentas: Azure OpenAI, OpenAI
Esforço de engenharia: Médio
Custo de processamento: Alto
Casos de uso: Imagens, tabelas
Exemplos: gere representações de texto de tabelas e imagens, resuma transcrições de reuniões, discursos, entrevistas ou podcasts
Análise de layout de documentos
As bibliotecas e serviços de análise de layout de documentos combinam recursos de reconhecimento ótico de caracteres (OCR) com modelos de aprendizagem profunda para extrair a estrutura de documentos e texto. Os elementos estruturais podem incluir cabeçalhos, rodapés, títulos, cabeçalhos de seção, tabelas e figuras. O objetivo é dar um melhor significado semântico ao conteúdo contido nos documentos.
As bibliotecas e serviços de análise de layout de documento expõem um modelo que representa o conteúdo, tanto estrutural quanto de texto, do documento. Você ainda precisa escrever um código que interaja com o modelo.
Nota
O Azure AI Document Intelligence é um serviço baseado na nuvem que exige que carregue o documento para o serviço. Você precisa garantir que seus regulamentos de segurança e conformidade permitam que você carregue documentos para serviços como este.
Ferramentas: Modelos de análise de documentos do Azure AI Document Intelligence, Donut, Analisador de Layout
Esforço de engenharia: Médio
Custo de processamento: Médio
Casos de uso: Documentos semiestruturados
Exemplos: Artigos de notícias, páginas web, currículos
Modelo pré-construído
Há serviços, como o Azure AI Document Intelligence, que oferecem modelos pré-criados que você pode aproveitar para vários tipos de documentos. Alguns modelos são treinados para tipos de documentos específicos, como o formulário US Tax W-2, enquanto outros visam um gênero mais amplo de tipos de documentos, como uma fatura.
Ferramentas: Modelos pré-construídos do Azure AI Document Intelligence, Power Automate Intelligent Document Processing, LayoutLMv3
Esforço de engenharia: Baixo
Custo de processamento: Médio/Alto
Casos de uso: documentos estruturados onde existe um modelo pré-construído
Exemplos específicos: faturas, recibos, cartão de seguro de saúde, formulário W-2
Modelo personalizado
Para documentos altamente estruturados onde não existe um modelo pré-construído, talvez seja necessário criar um modelo personalizado. Essa abordagem pode ser eficaz para imagens ou documentos altamente estruturados, dificultando o uso de técnicas de análise de texto.
Ferramentas: Modelos personalizados do Azure AI Document Intelligence, Tesseract
Esforço de engenharia: Alto
Custo de processamento: Médio/Alto
Casos de uso: documentos estruturados em que um modelo pré-construído não existe
Exemplos: Cronogramas de reparo e manutenção automotiva, históricos e registros acadêmicos, manuais técnicos, procedimentos operacionais, diretrizes de manutenção
Estrutura dos documentos
Os documentos variam na quantidade de estrutura que possuem. Alguns documentos, como formulários do governo, têm uma estrutura complexa e bem conhecida, como um documento fiscal W-2 dos EUA. No outro extremo do espectro estão documentos não estruturados, como notas de forma livre. O grau de estrutura de um tipo de documento é um bom ponto de partida para determinar uma abordagem de fragmentação eficaz. Embora não existam regras rígidas e rápidas, esta seção fornece algumas diretrizes a serem seguidas.
Figura 1. A abordagem de fragmentação se ajusta à estrutura do documento
Documentos estruturados
Os documentos estruturados, por vezes referidos como documentos de formato fixo, têm esquemas definidos. Os dados nestes documentos estão localizados em locais fixos. Por exemplo, a data, ou o nome da família do cliente, é encontrado no mesmo local em todos os documentos do mesmo formato fixo. Exemplos de documentos de formato fixo são o documento fiscal W-2 dos EUA.
Os documentos de formato fixo podem ser imagens digitalizadas de documentos originais que foram preenchidos à mão ou têm estruturas de layout complexas, dificultando o processamento com uma abordagem básica de análise de texto. Uma abordagem comum para processar estruturas de documentos complexas é usar modelos de aprendizado de máquina para extrair dados e aplicar significado semântico a esses dados, sempre que possível.
Exemplos: formulário W-2, cartão de seguro
Abordagens comuns: modelos pré-construídos, modelos personalizados
Documentos semi-estruturados
Os documentos semiestruturados não têm um formato ou esquema fixo, como o formulário W-2, mas oferecem consistência em relação ao formato ou esquema. Por exemplo, nem todas as faturas são apresentadas da mesma forma, no entanto, em geral, elas têm um esquema consistente. Você pode esperar que uma fatura tenha uma invoice number
forma de bill to
nome ship to
e endereço, entre outros dados. Uma página da Web pode não ter consistências de esquema, mas eles têm elementos estruturais ou de layout semelhantes, como body
, title
, H1
e p
que podem ser usados para adicionar significado semântico ao texto ao redor.
Como os documentos estruturados, os documentos semiestruturados que têm estruturas de layout complexas são difíceis de processar com análise de texto. Para esses tipos de documentos, os modelos de aprendizado de máquina são uma boa abordagem. Existem modelos pré-construídos para determinados domínios que têm esquemas consistentes, como faturas, contratos ou seguro de saúde. Considere a criação de modelos personalizados para estruturas complexas onde não existe um modelo pré-construído.
Exemplos: faturas, recibos, páginas Web, ficheiros de markdown
Abordagens comuns: Modelos de análise de documentos
Estrutura inferida
Alguns documentos têm uma estrutura, mas não são escritos em marcação. Para estes documentos, a estrutura deve ser inferida. Um bom exemplo é o seguinte documento de regulamentação da UE.
Figura 2. Regulamento da UE que mostra uma estrutura inferida
Como você pode entender claramente a estrutura do documento e não há modelos conhecidos para ele, você pode determinar que pode escrever código personalizado. Um formato de documento como este pode não garantir o esforço para criar um modelo personalizado, dependendo do número de documentos diferentes desse tipo com os quais você está trabalhando. Por exemplo, se o seu corpus for constituído por todos os regulamentos da UE ou leis estaduais dos EUA, um modelo personalizado pode ser uma boa abordagem. Se você estiver trabalhando com um único documento, como a regulamentação da UE no exemplo, o código personalizado pode ser mais econômico.
Exemplos: documentos legais, scripts, especificações de fabricação
Abordagens comuns: código personalizado, modelos personalizados
Documentos não estruturados
Uma boa abordagem para documentos com pouca ou nenhuma estrutura são as abordagens baseadas em frases ou de tamanho fixo com sobreposição.
Exemplos: conteúdo gerado pelo usuário, como feedback aberto de pesquisas, postagens em fóruns ou avaliações, mensagens de e-mail e notas pessoais ou de pesquisa
Abordagens comuns: baseadas em sentenças ou em limites com sobreposição
Experimentação
Embora os melhores ajustes para cada uma das abordagens de fragmentação estejam listados, na prática, qualquer uma das abordagens pode ser apropriada para qualquer tipo de documento. Por exemplo, a análise baseada em frases pode ser apropriada para documentos altamente estruturados ou um modelo personalizado pode ser apropriado para documentos não estruturados. Parte da otimização de sua solução RAG é experimentar várias abordagens de fragmentação, levando em conta o número de recursos que você tem, a habilidade técnica de seus recursos e o volume de documentos que você precisa processar. Para alcançar uma estratégia de fragmentação ideal, você precisa observar as vantagens e compensações de cada uma das abordagens testadas para garantir que está escolhendo a abordagem apropriada para seu caso de uso.