O que é prompt few-shot?
Prompt few-shot é colocar alguns pares de entrada e saída já resolvidos antes da entrada real. Na prática são de dois a oito. Eles não ensinam a tarefa ao modelo: fixam o formato da resposta, o conjunto de saídas possíveis e a fronteira entre casos parecidos. Os pesos não mudam, e cada exemplo custa tokens em toda chamada, para sempre.
É a terceira modalidade de prompt baseado em exemplos, depois do zero-shot e do one-shot. “Shot” significa exemplo, não tentativa, e “few” não tem definição formal: qualquer número acima de um e abaixo do ponto em que a janela de contexto começa a incomodar.
A pergunta que traz a maioria das pessoas até aqui não é o que é, e sim quantos usar e quais. As duas têm resposta parcial na literatura e resposta completa só na sua tarefa.
Como o bloco fica montado
A tarefa que vou usar no artigo inteiro: extrair o prazo de entrega, em dias, de uma frase escrita por um fornecedor.
Os quatro exemplos não foram escolhidos por acaso. Cada um resolve uma coisa que a instrução resolveria mal:
entrega em 3 dias úteis → 3fixa que a saída é um número puro, sem unidade e sem frase em volta.prazo: uma semana → 7mostra que expressão em linguagem natural vira número, e que a conversão é de dias corridos.pronta entrega → 0cobre o caso limite que produziria uma resposta criativa.sob consulta → nullmostra o que fazer quando não há prazo, que é a instrução mais difícil de dar por escrito e a mais fácil de mostrar.
Escrever isso em prosa custaria três parágrafos e ainda deixaria a decimal, o “dias úteis” e o caso vazio em aberto.
O que os exemplos realmente ensinam
Aqui está o resultado mais útil e menos intuitivo da área. Um trabalho de 2022 trocou os rótulos dos exemplos por rótulos aleatórios — associando de propósito a entrada errada à saída errada — e mediu o efeito em 12 modelos, incluindo o GPT-3. O desempenho caiu bem pouco. Os autores identificaram o que de fato carrega o resultado: o conjunto de rótulos possíveis, a distribuição das entradas e o formato geral da sequência1.
Traduzindo para a tarefa acima: o que o modelo extrai dos quatro pares é “a saída
é um número ou null”, “as entradas se parecem com frase comercial de fornecedor”
e “o padrão é entrada, seta, saída”. O mapeamento específico entre “uma semana” e
7 contribui menos do que qualquer um imagina.
Isso não autoriza escrever exemplo errado. Autoriza redistribuir a sua atenção: garantir que o formato do exemplo é byte a byte o que você quer receber rende mais que meia hora escolhendo o caso semanticamente mais representativo. E se um rótulo errado ficar no prompt, alguém vai copiar o bloco para outro serviço em seis meses.
Onde os exemplos entram na estrutura de mensagens
Duas montagens produzem, para o modelo, quase o mesmo texto. A diferença é operacional.
No bloco único, instrução e exemplos ficam juntos no system prompt e só a entrada real vai como mensagem do usuário. A vantagem é o prefixo estável: é exatamente o que o prompt caching consegue reaproveitar, e com exemplos fixos isso derruba o custo por chamada.
Nos turnos alternados, cada exemplo vira um par de mensagens, uma de user
com a entrada e uma de assistant com a saída. A fronteira entre entrada e saída
fica marcada pela própria estrutura, sem depender de separador que você inventou,
e o modelo está treinado nesse formato de conversa.
Em Python, a segunda montagem é um laço sobre uma lista de tuplas:
EXEMPLOS = [
("entrega em 3 dias úteis", "3"),
("prazo: uma semana", "7"),
("pronta entrega", "0"),
("sob consulta", "null"),
]
def montar(entrada: str) -> list[dict]:
mensagens = []
for pergunta, resposta in EXEMPLOS:
mensagens.append({"role": "user", "content": pergunta})
mensagens.append({"role": "assistant", "content": resposta})
mensagens.append({"role": "user", "content": entrada})
return mensagens
O ganho real dessas dez linhas não é elegância. É que os exemplos passam a ser dados: dá para versioná-los, trocá-los por tarefa e rodar o conjunto de teste com duas listas diferentes sem editar prosa.
Quantos exemplos
O paper do GPT-3 é a referência mais citada aqui e a mais mal lida. Ele usou 64 exemplos nas tarefas de perguntas e respostas, e o ganho de zero para few variou enormemente por dataset: em WebQuestions, o modelo de 175B foi de 14,4% sem exemplo para 41,5% com 64; em TriviaQA, foi de 64,3% para 71,2%2. Mesmo modelo, mesma quantidade de exemplos, efeitos de tamanho completamente diferentes.
A leitura que sobrevive é sobre a forma da curva, não sobre o número. O primeiro exemplo resolve formato. Os seguintes resolvem fronteira, e cada fronteira que você quer fixar custa pelo menos um exemplo de cada lado dela. Depois disso o retorno cai rápido enquanto o custo continua linear.
Isso dá um piso concreto em vez de um chute. Se a tarefa tem quatro categorias e duas delas se confundem, o mínimo é um exemplo por categoria mais um segundo para cada lado da confusão, o que dá seis. Se existe caso vazio, sete. Chegar a esse número por construção é diferente de chegar a ele porque cinco parecia pouco.
E vale olhar a composição, não só a contagem. Um bloco com seis exemplos em que quatro caem na mesma categoria empurra o modelo naquela direção antes de ele ler qualquer coisa, pelo mesmo mecanismo de viés de rótulo descrito adiante. Distribuição parelha entre as saídas possíveis custa zero e evita um erro que se manifesta como “o modelo prefere a categoria mais comum”.
Existe um regime bem acima disso que as janelas grandes tornaram viável. Um trabalho de 2024 investigou centenas a milhares de exemplos no contexto e encontrou ganhos consistentes em várias tarefas geradoras e discriminativas; notavelmente, o many-shot conseguiu sobrepor vieses do pré-treino, o que o few-shot não consegue, e ficou comparável a fine-tuning em parte dos casos. Os mesmos autores registram que o custo de inferência cresce linearmente nesse regime3. É um caminho real, e é um caminho caro: a partir de certo volume, a comparação honesta deixa de ser com o few-shot e passa a ser com treinar um modelo pequeno.
Escolher e ordenar os exemplos
Duas decisões que parecem detalhe e não são.
Quais exemplos. Um trabalho de 2021 mostrou que o resultado do GPT-3 depende bastante de quais exemplos entram, e que recuperar exemplos semanticamente próximos da entrada atual supera de forma consistente a seleção aleatória, com os maiores ganhos em geração a partir de tabela e em perguntas e respostas de domínio aberto4. Na prática isso significa manter um banco de casos resolvidos e selecionar os cinco mais parecidos com a entrada em cada chamada. Você ganha relevância e perde o cache do prefixo, então a conta muda.
Em que ordem. Um estudo do mesmo ano encontrou algo mais desconfortável: com os mesmos exemplos, apenas permutados, o desempenho vai de perto do estado da arte a perto de chute. O efeito aparece em todos os tamanhos de modelo testados, não se resolve trocando o subconjunto de exemplos, e uma permutação boa para um modelo não transfere para outro. Os autores propuseram escolher a ordem por estatística de entropia sobre um conjunto de validação artificial gerado pelo próprio modelo, o que rendeu 13% de melhoria relativa em onze tarefas de classificação5.
Parte disso tem causa conhecida. Um trabalho de 2021 mostrou que o modelo já
chega com preferência por certas respostas, principalmente as comuns no
pré-treino e as que aparecem perto do fim do prompt, e que calibrar a saída com
uma entrada neutra recupera até 30 pontos absolutos de acurácia média6. Se
todos os seus exemplos terminam com null, o modelo vai gostar de null.
A conclusão operacional é chata e é a certa: fixe uma ordem, versione junto do prompt e trate mudança de ordem como mudança de código, que exige rodar o conjunto de teste de novo.
Few-shot ou fine-tuning
A comparação aparece cedo e costuma ser resolvida por gosto. O critério útil é onde o exemplo passa a ser caro.
Few-shot paga por chamada. Fine-tuning paga uma vez no treino e depois entrega um modelo que já se comporta daquele jeito, com o prompt de volta ao tamanho do zero-shot. Existe um volume a partir do qual a segunda conta fica menor, e ele depende de três coisas: quantos tokens de exemplo você carrega, quantas chamadas por mês e quanto custa manter mais um artefato treinado no seu processo de deploy.
Há um segundo critério, menos financeiro. Fine-tuning cabe quando o comportamento não cabe em exemplos que caibam na janela: um estilo de escrita inteiro, um vocabulário de domínio grande, uma convenção com centenas de casos particulares. Few-shot cabe quando o comportamento é descritível em meia dúzia de casos, que é a maioria absoluta das tarefas de extração e classificação.
O trabalho de 2024 sobre many-shot encontrou desempenho comparável ao de fine-tuning em parte das tarefas quando se usa centenas de exemplos no contexto3. Isso não fecha a discussão, mas move a fronteira: com janela grande e prompt caching, o ponto em que treinar compensa ficou mais longe do que era em 2023.
Onde falha
Tarefa em que exemplo não muda nada. No próprio paper do GPT-3, o Winograd ficou em 88,3% em zero-shot, 89,7% com um exemplo e 88,6% com vários2. Nem toda tarefa tem formato ou fronteira para fixar, e nessas você está pagando contexto por nada.
Tarefa aberta. Se você pede um texto e dá quatro exemplos, recebe variações dos quatro. O espaço de resposta encolheu sem que ninguém pedisse.
Modelo de raciocínio. Modelos treinados para produzir os passos antes da resposta já têm um formato interno de pensamento. Exemplos com raciocínio escrito competem com ele e costumam atrapalhar.
Exemplo que envelhece. O bloco foi escrito quando existiam três categorias. Hoje existem cinco, e as duas novas não aparecem em exemplo nenhum. O modelo continua devolvendo as três antigas, com confiança, e ninguém revisa prompt.
Dado real vazando para o prompt. Exemplo tirado da base de produção costuma carregar nome, CPF e valor de cliente de verdade. Ele fica no system prompt, vai para o log, e às vezes vai para o provedor com retenção diferente da que você prometeu.
Quanto custa
Ordem de grandeza. Um exemplo dessa tarefa, com a frase do fornecedor inteira, fica em torno de 60 tokens. Cinco exemplos são 300 tokens em toda chamada; vinte são 1.200.
Em 2 milhões de extrações por mês, a diferença entre cinco e vinte exemplos são 1,8 bilhão de tokens de entrada por mês. Nenhuma discussão sobre qual modelo é mais barato compensa essa diferença, e ela existe inteiramente por causa de uma decisão que quase sempre foi tomada sem medir.
Duas coisas mudam essa conta. Prompt caching, quando os exemplos são fixos e ficam no prefixo, cobra uma fração pelo trecho reaproveitado. E seleção dinâmica de exemplo, que melhora a relevância, joga o cache fora justamente porque o prefixo muda a cada requisição.
Por onde começar
- Comece sem exemplo e meça. Sem a linha de base do zero-shot, você não consegue saber o que os exemplos compraram.
- Acrescente um exemplo para o formato. Escreva a saída dele exatamente como você quer receber, incluindo ausência de bloco de código.
- Acrescente um par para cada fronteira que estiver sendo errada. Um caso de cada lado. Fronteira sem os dois lados não fica fixada.
- Inclua o caso vazio e o caso de borda. Se
nullé uma resposta válida, um dos exemplos precisa devolvernull. - Guarde os exemplos como dados, não como texto. Lista de tuplas, arquivo versionado, mesma coisa que você faria com fixture de teste.
- Fixe a ordem e rode os 30 casos a cada mudança, inclusive quando a mudança for só a ordem.
O passo 3 é o que separa few-shot de “coloquei mais exemplos para garantir”. Um exemplo que não corresponde a um erro observado é 60 tokens por chamada sem contrapartida.
Footnotes
-
Min et al. (2022) substituíram os rótulos corretos por rótulos aleatórios em 12 modelos e mediram queda pequena, apontando o espaço de rótulos, a distribuição das entradas e o formato da sequência como o que carrega o resultado. ↩
-
Brown et al. (2020) reportam, com o modelo de 175B e 64 exemplos, 14,4% em zero-shot contra 41,5% em few-shot no WebQuestions e 64,3% contra 71,2% no TriviaQA; no Winograd, os três modos ficam em 88,3%, 89,7% e 88,6%. ↩ ↩2
-
Agarwal et al. (2024) mediram o regime de centenas a milhares de exemplos, com ganhos consistentes, capacidade de sobrepor vieses do pré-treino e custo de inferência crescendo linearmente. ↩ ↩2
-
Liu et al. (2021) mostraram que o resultado depende de quais exemplos entram e que recuperar exemplos semanticamente próximos da entrada supera a seleção aleatória de forma consistente. ↩
-
Lu et al. (2021) encontraram permutações dos mesmos exemplos indo de perto do estado da arte a perto de chute, sem transferência entre modelos, e propuseram uma seleção de ordem por entropia com 13% de melhoria relativa em onze tarefas de classificação. ↩
-
Zhao et al. (2021) descrevem a preferência do modelo por respostas comuns no pré-treino e por rótulos próximos do fim do prompt, e recuperam até 30 pontos absolutos calibrando com uma entrada neutra. ↩
Perguntas frequentes
- Qual é um exemplo de prompt few-shot?
- Uma instrução como quantos dias de prazo, seguida de quatro pares resolvidos: entrega em 3 dias úteis vira 3, prazo de uma semana vira 7, pronta entrega vira 0, sob consulta vira null. Depois vem a frase real do fornecedor. Os quatro pares são os shots.
- Quantos shots usar no few-shot?
- De três a cinco cobre a maioria dos casos, com um exemplo para cada fronteira que você quer fixar e um para o caso vazio. Acima disso o custo cresce linearmente e o ganho não. A resposta certa vem de medir a sua tarefa, não de uma regra geral.
- Como fazer few-shot prompting em Python?
- Monte a lista de mensagens intercalando papéis: para cada par, uma mensagem de user com a entrada e uma de assistant com a saída esperada; no fim, a entrada real como user. Um laço sobre uma lista de tuplas resolve, e mudar os exemplos passa a ser mudar dados, não texto.
- Os exemplos precisam ter a resposta correta?
- Menos do que parece. Um trabalho de 2022 trocou os rótulos por aleatórios e o desempenho caiu pouco em 12 modelos. O que os exemplos entregam é o conjunto de rótulos possíveis, a cara das entradas e o formato da sequência. Ainda assim, rótulo errado é dívida: alguém vai copiar o prompt.
- A ordem dos exemplos muda o resultado?
- Muda, e mais do que se espera. Um estudo de 2021 encontrou permutações dos mesmos exemplos indo de perto do estado da arte a perto de chute, com o efeito presente em todos os tamanhos de modelo testados. Uma boa ordem para um modelo não transfere para outro.
- Few-shot substitui fine-tuning?
- Na maioria dos casos, sim, e é muito mais rápido de iterar. Fine-tuning passa a valer quando o volume de chamadas torna o custo dos exemplos em toda requisição maior que o custo de treinar, ou quando o comportamento desejado não cabe em exemplos que caibam na janela.
Referências
- Brown, T. B. et al.. Language Models are Few-Shot Learners (2020)arXiv:2005.14165
- Min, S. et al.. Rethinking the Role of Demonstrations: What Makes In-Context Learning Work? (2022)arXiv:2202.12837
- Liu, J. et al.. What Makes Good In-Context Examples for GPT-3? (2021)arXiv:2101.06804
- Lu, Y. et al.. Fantastically Ordered Prompts and Where to Find Them: Overcoming Few-Shot Prompt Order Sensitivity (2021)arXiv:2104.08786
- Zhao, T. Z. et al.. Calibrate Before Use: Improving Few-Shot Performance of Language Models (2021)arXiv:2102.09690
- Agarwal, R. et al.. Many-Shot In-Context Learning (2024)arXiv:2404.11018