Bases técnicas costumam falhar no RAG por um motivo menos vistoso que o modelo escolhido: a ingestão destrói a estrutura do documento. Quando um divisor corta uma função no meio, separa um endpoint do schema de resposta ou mistura exemplos de versões diferentes, o mecanismo de recuperação pode encontrar palavras relevantes sem encontrar o contexto necessário para responder.

Chunking por sintaxe trata esse problema usando a estrutura do conteúdo como sinal principal. Em vez de dividir tudo a cada quantidade fixa de caracteres, o pipeline identifica blocos como funções, classes, endpoints, schemas, tabelas e seções de referência. O objetivo não é criar chunks sempre pequenos. É manter unidades que façam sentido para uma pergunta e ainda caibam no contexto enviado ao modelo.

A técnica não elimina alucinações nem substitui avaliação. Ela melhora a evidência disponível para o modelo. Para chegar a um sistema confiável, combine segmentação estrutural, metadados, recuperação em camadas e validação da resposta.

Estratégia de ingestão de dados

Comece separando os tipos de fonte. Código, documentação conceitual, referência de API, exemplos de requisição e notas de versão têm estruturas e padrões de consulta diferentes. Um único algoritmo de chunking para todos esses materiais tende a produzir unidades inconsistentes.

Na documentação em Markdown, preserve a hierarquia de títulos. Uma seção deve carregar o caminho de seus títulos pai, por exemplo, produto, autenticação e criação de token. Esse caminho funciona como contexto adicional quando o texto da seção é recuperado isoladamente.

Para código, use um parser da linguagem sempre que houver uma gramática disponível. A unidade principal pode ser uma função, método, classe ou bloco de configuração. O parser permite identificar início e fim do nó sem depender de contagem de caracteres. Em linguagens ou formatos sem parser adequado, use uma combinação de delimitadores confiáveis, indentação e regras específicas do formato, deixando casos ambíguos para revisão ou fallback.

Na documentação de APIs, trate cada endpoint como uma unidade composta. O método HTTP, o caminho, os parâmetros, as regras de autenticação, o corpo da requisição, o schema de resposta, os códigos de erro e os exemplos devem permanecer relacionados. Se esse bloco ficar grande demais, divida por subestrutura, mas repita no metadata o método e o caminho em cada parte.

Uma estratégia prática é aplicar esta sequência:

  1. Detecte o formato do arquivo e a linguagem.
  2. Extraia a estrutura sintática ou hierárquica.
  3. Crie um chunk para cada unidade semântica.
  4. Acrescente contexto dos pais, como nome da classe ou caminho da seção.
  5. Divida apenas unidades que ultrapassem o limite definido.
  6. Gere metadados que permitam filtrar e reconstruir o contexto.

O limite de tamanho deve ser uma restrição, não o critério primário. Uma função curta deve permanecer inteira mesmo que use poucos tokens. Uma classe extensa pode exigir divisão por métodos, mas cada parte deve informar a classe de origem e as relações relevantes. Sobreposição entre chunks também precisa ser aplicada com cuidado. Em texto corrido, ela pode preservar continuidade. Em código, duplicar trechos pode aumentar ruído e custo. Prefira relações estruturais, como nome da classe, assinatura e imports relevantes, antes de copiar linhas arbitrariamente.

Registre a versão do documento, a fonte, a linguagem, o caminho no repositório, o símbolo principal, a seção pai e a data de ingestão. Esses campos ajudam a evitar que uma resposta combine uma versão antiga de uma função com uma referência atualizada de endpoint.

Configuração do vetor store

O vetor store deve guardar mais que o embedding e o texto. Cada registro precisa ter um identificador estável, o conteúdo do chunk e metadados suficientes para filtrar, ordenar e buscar unidades relacionadas.

Um conjunto inicial de metadados pode incluir source, document_version, language, content_type, section_path, symbol, http_method, endpoint_path, parent_id e chunk_index. Use os campos disponíveis de acordo com a fonte. Um endpoint não precisa de symbol, enquanto uma função não precisa de http_method.

Mantenha o texto usado no embedding legível e autocontido. Em um chunk de função, inclua a assinatura, o nome da classe e a linguagem. Em um schema, inclua o nome do recurso e a relação com o endpoint. Não transforme todos os metadados em texto repetido sem necessidade, pois isso pode aumentar tokens e fazer termos estruturais dominarem a representação.

A busca vetorial é útil para perguntas conceituais, mas não deve ser a única forma de localizar código. Consultas com nomes exatos de funções, códigos de erro, caminhos de endpoint e propriedades de schema se beneficiam de busca lexical. Uma arquitetura híbrida combina correspondência textual com similaridade semântica e depois aplica filtros estruturais.

Escolha o modelo de embeddings considerando o idioma, o tipo de conteúdo e o orçamento de inferência. Embeddings não são gratuitos em sistemas operacionais, mesmo quando o modelo pode ser executado localmente. Há custo de processamento, armazenamento, atualização e latência. O tamanho do vetor também afeta o armazenamento e a consulta. Teste com perguntas reais antes de decidir pela maior representação disponível.

Crie uma política explícita para atualização. Quando um arquivo muda, reprocese os chunks afetados e remova ou marque como inativos os registros antigos. Sem controle de versão, o sistema pode recuperar duas implementações incompatíveis. Para APIs, filtre por versão quando a pergunta indicar esse contexto. Quando não indicar, a aplicação deve declarar qual versão foi usada ou pedir esclarecimento, em vez de misturar resultados.

Retrieval estratificado

Retrieval estratificado significa recuperar evidência em etapas, usando primeiro a intenção e depois a estrutura do documento. Essa abordagem evita depender de uma única busca ampla que retorna vários trechos parecidos, mas incompletos.

Na primeira camada, classifique a pergunta de forma simples. Ela pede uma explicação conceitual, a localização de uma função, o uso de um endpoint, a comparação entre versões ou a solução de um erro? Essa classificação pode ser feita por regras, por um modelo pequeno ou pelo próprio serviço de aplicação. Não é necessário usar um modelo caro para toda decisão de roteamento.

Na segunda camada, aplique filtros disponíveis. Se a pergunta menciona uma linguagem, versão, serviço, método HTTP ou caminho, use esses sinais para reduzir o espaço de busca. Filtros não devem ser aplicados de modo rígido quando a extração for incerta. Uma alternativa é rodar uma busca filtrada e outra mais ampla, comparando os resultados.

Na terceira camada, faça a recuperação híbrida. Combine busca lexical para identificadores exatos com busca vetorial para paráfrases e conceitos. Depois, use um reranker ou uma regra de pontuação para priorizar chunks que contenham a unidade completa, a versão correta e os termos da consulta. O reranking adiciona latência e custo, então vale medir se o ganho justifica seu uso em cada tipo de pergunta.

Na quarta camada, expanda o contexto por relações. Se o resultado principal for um método, recupere a classe, a interface implementada ou os tipos usados apenas quando forem relevantes. Se for um endpoint, recupere o schema, as regras de autenticação e os erros associados. Essa expansão deve ser limitada. Enviar toda a árvore de dependências ao modelo aumenta custo, latência e a chance de distração.

Uma regra útil é separar evidência primária de evidência auxiliar. A definição do endpoint ou da função é primária. Um exemplo de uso, uma explicação conceitual e uma nota de versão podem ser auxiliares. No prompt, indique essa diferença e peça ao modelo para não tratar exemplos como contrato normativo quando houver conflito.

O limite de contexto do modelo continua sendo uma restrição concreta. Mesmo quando há espaço suficiente para muitos tokens, mais contexto não significa mais precisão. Contexto irrelevante compete com a evidência principal. Registre quantos chunks foram recuperados, quantos tokens foram enviados e quais fontes sustentaram a resposta. Esses dados ajudam a ajustar o pipeline sem depender de impressão subjetiva.

Validação da resposta

A última etapa é verificar se o sistema respondeu com base na evidência correta. Avalie o pipeline com um conjunto de perguntas reais, incluindo consultas sobre funções, parâmetros, erros, versões e casos em que a informação não existe. Para cada pergunta, registre se o chunk correto foi recuperado e se a resposta respeitou esse material. Separar qualidade de retrieval da qualidade de geração mostra onde está o problema.

Inclua testes de integridade estrutural. Uma função recuperada deve conter sua assinatura e corpo relevante. Um endpoint deve manter método, caminho e schema compatíveis. Um chunk dividido não pode perder a indicação de que é continuação. Também teste arquivos atualizados, símbolos renomeados e documentos removidos.

Na geração, exija citações internas ou referências aos documentos recuperados. A resposta deve distinguir fato encontrado, inferência e informação ausente. Quando os trechos forem insuficientes ou conflitantes, o comportamento correto é declarar a limitação e pedir contexto, não completar a lacuna com uma suposição plausível.

Acompanhe métricas de recuperação, como cobertura do chunk esperado, precisão dos primeiros resultados e taxa de respostas sem evidência suficiente. Monitore também latência, tokens enviados e custo por consulta. Um chunking melhor pode reduzir chamadas repetidas e contexto desperdiçado, mas a análise precisa considerar o custo adicional de parsing, reranking e reindexação.

Para colocar a técnica em prática, escolha um conjunto pequeno de documentos, crie uma versão por tamanho fixo como referência e compare com a segmentação por sintaxe. Use as mesmas perguntas, o mesmo modelo e a mesma regra de geração. Se a abordagem estrutural recuperar blocos mais completos e reduzir respostas sem suporte, você terá evidência para expandir a ingestão. Caso contrário, revise o parser, os metadados ou a estratégia de retrieval antes de atribuir o resultado ao modelo.

Chunking por sintaxe é uma decisão de arquitetura, não um ajuste isolado de configuração. A unidade correta depende do tipo de documento, da forma das perguntas e das relações que precisam permanecer intactas. O ganho aparece quando ingestão, armazenamento, recuperação e validação tratam essa estrutura como parte do conhecimento, em vez de enxergarem a documentação apenas como uma sequência de caracteres.