o problema
Quando um modelo responde sobre um documento que você mandou, a resposta e a fonte ficam no mesmo lugar: o texto gerado. Você pede “cite o trecho que sustenta isso” e recebe um trecho entre aspas — que é só mais texto saindo do decoder. Nada no caminho verifica se aquelas aspas correspondem a algo que existe no documento, em que posição, ou se é mesmo o trecho mais relevante. Para conferir, alguém do outro lado precisa abrir o arquivo e procurar a string na mão.
Isso tem dois custos concretos. O primeiro é de confiança: um produto que mostra fonte ao usuário precisa que a fonte seja clicável, e um ponteiro só é clicável se for um índice, não uma citação em prosa. O segundo é de fatura: quando você pede citação literal via prompt, cada palavra copiada do documento é gerada de novo e cobrada como token de saída. Um sistema de RAG que cita bastante paga duas vezes pelo mesmo texto — uma na entrada, outra na saída.
a ideia
A feature de citations tira a citação do fluxo de tokens e a coloca no protocolo. O documento é fatiado em pedaços antes de o modelo ver a pergunta; o modelo, internamente, emite referência a esses pedaços num formato padronizado; a API resolve a referência, recorta o texto original e devolve isso como campo estruturado, junto de índices de posição.
O efeito é que a citação deixa de ser algo que o modelo escreve e passa a ser algo que o modelo seleciona. Segundo a documentação, isso garante que a citação contenha ponteiros válidos para os documentos fornecidos, e a Anthropic afirma que, nas avaliações internas, a feature cita os trechos mais relevantes com frequência significativamente maior do que abordagens puramente por prompt.
como funciona
Você marca citations: {"enabled": true} em cada bloco document da mensagem. A configuração é all-or-nothing por request: ou todos os documentos têm citações ligadas, ou nenhum. A fonte pode ser texto inline, base64, URL ou um file_id da Files API.
O chunking depende do tipo de documento e determina a menor unidade citável:
- texto puro: fatiado em frases, citação por índice de caractere (0-indexado, fim exclusivo), tipo
char_location; - PDF: texto extraído e fatiado em frases, citação por número de página (1-indexado, fim exclusivo), tipo
page_location; - custom content: seus blocos são usados como estão, sem fatiamento adicional, citação por índice de bloco, tipo
content_block_location.
title e context vão para o modelo mas não são citáveis — context é o lugar recomendado para metadados, inclusive JSON serializado, já que title tem limite de tamanho.
A resposta muda de forma: em vez de um bloco de texto, vêm vários. Cada bloco carrega uma afirmação e, opcionalmente, um array citations. O texto de ligação (“According to the document, “) vem em bloco próprio, sem citação; a afirmação sustentada vem no bloco seguinte, com o ponteiro. Cada citação traz cited_text, document_index (0-indexado sobre todos os documentos do request, atravessando mensagens), document_title e o par de índices do tipo correspondente.
Em streaming, as citações chegam como citations_delta dentro de content_block_delta. Cada delta traz uma citação para anexar à lista do bloco de texto corrente — é um caso a mais no seu switch de deltas, ao lado de text_delta.
Para RAG, a escolha do tipo de documento é a escolha de granularidade: cada chunk como documento de texto puro, se você quer que o modelo cite frases isoladas dentro do chunk; custom content, se o chunk é a unidade que você quer expor.
o que isso custou
Ligar citações aumenta os tokens de entrada — a documentação fala em acréscimo leve, vindo de adições ao system prompt e do chunking. A economia é do outro lado: cited_text não entra na conta de saída nem na de entrada quando reenviado.
O conflito mais duro é com structured outputs. Os dois são incompatíveis por construção: se você habilita citações em qualquer documento do usuário (blocos document ou search_result) e também passa output_config.format, a API responde 400. Citar exige intercalar blocos, e um schema JSON estrito não tolera essa intercalação. Se seu pipeline depende de saída validada por schema, citações estão fora dele.
Só há citação de texto. Imagem não é citável, e PDF que é digitalização sem texto extraível fica de fora. Os blocos de citação gerados não podem ser cacheados — o que se cacheia é o documento de origem, aplicando cache_control no bloco de topo.
E vale ler a garantia pelo que ela diz: o ponteiro é válido, aponta mesmo para um trecho existente. Que a afirmação do bloco decorra do trecho citado continua sendo problema seu.
onde isso aparece hoje
A feature funciona junto com prompt caching, token counting e batch processing, e está disponível em todos os modelos ativos — na Claude API e nas plataformas de AWS, Google Cloud e Microsoft Foundry. É elegível a ZDR, exceto para os Covered Models.
O desdobramento mais direto são os blocos search_result, que levam pipelines de RAG a passar resultados de busca como conteúdo de primeira classe, já com suporte a citação embutido — e que herdam a mesma incompatibilidade com structured outputs. A Files API fecha o ciclo do lado operacional: sobe o documento uma vez, referencia por file_id em vários requests com citação.