AI Engineering Academy · Aula

Recuperação pai-filho e do pequeno para o grande

Armazene fragmentos filhos pequenos para uma recuperação precisa, mas retorne seus fragmentos pais maiores ao LLM para obter um contexto mais rico, equilibrando a precisão da recuperação com a qualidade da geração.

Aula 3 de 413 etapas

Recuperação pai-filho e do pequeno para o grande é uma aula grátis de AI Engineering Academy no CoddyKit. Esta é a aula 3 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de AI Engineering Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de AI Engineering Academy inclui 4 aulas no total.

O dilema entre precisão e contexto

Os sistemas RAG enfrentam uma tensão: trechos pequenos são recuperados com alta precisão porque cada trecho se concentra em uma ideia, mas não têm o contexto ao redor de que o LLM precisa para gerar uma resposta completa. Trechos grandes fornecem um contexto rico, mas reduzem a precisão da recuperação porque correspondem fracamente a muitas consultas, em vez de corresponder fortemente a uma só. A segmentação pai-filho resolve esse dilema.

A arquitetura pai-filho

Na segmentação pai-filho, você cria duas camadas de trechos a partir do mesmo documento. Trechos filhos são pequenos (por exemplo, de 1 a 3 frases) e são incorporados e indexados para recuperação. Trechos pai são seções maiores (por exemplo, parágrafos ou páginas inteiros) armazenadas separadamente. Quando um filho é recuperado, você retorna o pai ao LLM.

Construindo a hierarquia de trechos

O primeiro passo é dividir o documento em trechos pai grandes e, depois, dividir cada pai em trechos filho menores. Cada trecho filho mantém uma referência — normalmente um campo de metadados parent_id — que aponta de volta para seu pai. Esse mapeamento permite localizar a passagem pai completa a partir de qualquer filho recuperado.

from langchain.text_splitter import RecursiveCharacterTextSplitter

parent_splitter = RecursiveCharacterTextSplitter(chunk_size=1500, chunk_overlap=0)
child_splitter = RecursiveCharacterTextSplitter(chunk_size=300, chunk_overlap=30)

parent_chunks = parent_splitter.split_documents(docs)
child_chunks = []
for i, parent in enumerate(parent_chunks):
    children = child_splitter.split_documents([parent])
    for child in children:
        child.metadata['parent_id'] = i
    child_chunks.extend(children)

Indexando apenas os trechos filho

Apenas os trechos filho são incorporados e armazenados no banco de dados vetorial. Os trechos pai são armazenados em um armazenamento separado de chave-valor (um dicionário na memória, Redis ou um banco de dados de documentos). Assim, o índice vetorial permanece denso e preciso, enquanto o contexto rico fica fora dele.

# Store parents in a docstore
parent_store = {i: chunk.page_content for i, chunk in enumerate(parent_chunks)}

# Embed and index only children
vectorstore = Chroma.from_documents(
    child_chunks,
    embedding=OpenAIEmbeddings()
)

Recuperação: entra o filho, sai o pai

Durante a recuperação, a consulta do usuário é incorporada e comparada com os trechos filho. Os k principais trechos filho são encontrados, e suas referências parent_id são resolvidas consultando o armazenamento dos pais. As passagens pai — não os filhos — são então inseridas no prompt do LLM. O LLM recebe um contexto amplo; a recuperação foi precisa.

def retrieve_with_parents(query, vectorstore, parent_store, k=5):
    child_results = vectorstore.similarity_search(query, k=k)
    seen_parent_ids = set()
    parent_contexts = []
    for child in child_results:
        pid = child.metadata['parent_id']
        if pid not in seen_parent_ids:
            parent_contexts.append(parent_store[pid])
            seen_parent_ids.add(pid)
    return parent_contexts

ParentDocumentRetriever do LangChain

O LangChain fornece a classe ParentDocumentRetriever, que implementa esse padrão imediatamente. O senhor fornece um separador pai, um separador filho, um armazenamento vetorial para as incorporações filhas e um armazenamento de documentos para os documentos pais. Ele configura a hierarquia e gerencia a recuperação de forma transparente.

from langchain.retrievers import ParentDocumentRetriever
from langchain.storage import InMemoryStore

store = InMemoryStore()
retriever = ParentDocumentRetriever(
    vectorstore=vectorstore,
    docstore=store,
    child_splitter=child_splitter,
    parent_splitter=parent_splitter
)
retriever.add_documents(docs)
results = retriever.invoke('What is the refund policy?')

Recuperação do Pequeno para o Grande Explicada

A recuperação do pequeno para o grande é outro nome para o mesmo conceito: o senhor recupera partes pequenas e precisas, mas depois as expande para o contexto ao redor antes de enviá-las ao LLM. Algumas implementações expandem o conteúdo não para um pai fixo, mas para uma janela de frases adjacentes — fornecendo ao modelo as frases anteriores e posteriores à parte correspondente para manter a continuidade contextual.

def retrieve_with_window(query, vectorstore, sentences, window=2, k=5):
    results = vectorstore.similarity_search(query, k=k)
    expanded = []
    for r in results:
        idx = r.metadata['sentence_index']
        start = max(0, idx - window)
        end = min(len(sentences), idx + window + 1)
        expanded.append(' '.join(sentences[start:end]))
    return expanded

Eliminando Duplicatas das Partes Pais

Várias partes filhas do mesmo pai podem ser recuperadas para uma única consulta. Sem a eliminação de duplicatas, a mesma passagem pai apareceria várias vezes no prompt, desperdiçando tokens. Sempre elimine duplicatas pelo ID do pai antes de montar o contexto. O exemplo de código na função de recuperação acima faz isso com um conjunto seen_parent_ids.

Quando Usar a Divisão em Partes Pai e Filha

A recuperação pai-filha funciona melhor quando os documentos têm uma estrutura hierárquica clara: capítulos com seções, artigos com parágrafos ou wikis com subseções. Ela é especialmente eficaz para documentação técnica extensa, na qual perguntas precisas exigem respostas localizadas, mas essas respostas só fazem sentido dentro de uma seção mais ampla de contexto.

Escolhendo os Tamanhos das Partes Filhas e Pais

Uma configuração típica é: partes filhas de 200 a 400 tokens (ideias únicas e focadas) e partes pais de 1.000 a 2.000 tokens (seções completas). Se as partes filhas forem pequenas demais, elas se tornarão frases individuais que não têm significado por si mesmas. Se as partes pais forem grandes demais, o senhor começará a reintroduzir o problema de diluição do contexto que estava tentando evitar.

Comparando Abordagens: Um Resumo

Resumindo as estratégias de divisão apresentadas até agora: tamanho fixo é rápido, mas rompe o contexto; a divisão semântica preserva a coerência do tópico; a abordagem pai-filha otimiza tanto a precisão da recuperação quanto a riqueza do contexto do LLM. Para a maioria dos sistemas RAG em produção que lidam com documentos extensos, a divisão pai-filha oferece a melhor qualidade de recuperação com uma complexidade administrável.

Verificação Rápida

Teste sua compreensão sobre a divisão em partes pai e filha apresentada nesta lição.

Recapitulação da Lição

Nesta lição, o senhor aprendeu que: as partes filhas proporcionam uma recuperação precisa, enquanto as partes pais fornecem um contexto rico, o ParentDocumentRetriever do LangChain implementa isso automaticamente e a eliminação de duplicatas pelo ID do pai evita a repetição do contexto. Em seguida, exploraremos estratégias de divisão específicas para documentos de código e documentos HTML.

Grátis para começar

Aprenda Python com um tutor de IA — grátis

Escreva e execute código real no seu navegador, obtenha ajuda instantânea de um tutor de IA 24/7 e continue de onde parou na web ou no app.

Cursos
30
Aulas
120

Perguntas Frequentes

A aula “Recuperação pai-filho e do pequeno para o grande” é grátis?

Sim — o texto completo de “Recuperação pai-filho e do pequeno para o grande” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de AI Engineering Academy, atualize para CoddyKit PRO. O curso de AI Engineering Academy inclui 4 aulas no total.

O que vou aprender em “Recuperação pai-filho e do pequeno para o grande”?

Armazene fragmentos filhos pequenos para uma recuperação precisa, mas retorne seus fragmentos pais maiores ao LLM para obter um contexto mais rico, equilibrando a precisão da recuperação com a qualid… Você pratica AI Engineering Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar AI Engineering Academy?

Nenhuma experiência prévia é necessária. AI Engineering Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 3 de 4.

Quanto tempo leva a aula “Recuperação pai-filho e do pequeno para o grande”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de AI Engineering Academy?

Sim. Cada aula de AI Engineering Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. Por que a divisão ingênua prejudica a recuperação
  2. Divisão semântica com similaridade de embeddings
  3. Recuperação pai-filho e do pequeno para o grande
  4. Estratégias específicas para código e HTML
← Voltar para AI Engineering Academy