O que é Embutir Etapa Trivial?
Embutir Etapa Trivial (Inline Trivial Step) é uma refatoração de IA para sistemas com LLM, do grupo Compondo prompts. Remover uma chamada que não muda o resultado e juntar o trabalho na etapa vizinha.
Inline Trivial Step
Embutir Etapa Trivial (Inline Trivial Step) é uma refatoração de IA para sistemas com LLM, do grupo Compondo prompts. Remover uma chamada que não muda o resultado e juntar o trabalho na etapa vizinha.
Um passo do pipeline não muda o resultado de forma mensurável, mas custa uma chamada inteira. O caso mais comum é o smell Autocrítica Inútil: o modelo gera um texto e, na chamada seguinte, revisa o próprio texto sem receber nenhuma informação nova.
Imagine um portal de notícias que gera 10 mil resumos por dia. O pipeline tem duas chamadas: resumir e revisar. Quando o time compara as saídas, vê que a revisão devolve o rascunho idêntico, ou com uma vírgula trocada, na grande maioria dos casos. A segunda chamada virou um carimbo caro.
Remova a chamada que não muda o resultado e leve o que ela tinha de útil (um critério, um formato, uma checagem) para o passo vizinho ou para o código.
def write_summary(document):
- draft = llm("Resuma o documento em até 150 palavras.", document)
- reviewed = llm("Revise o resumo abaixo: corrija erros, deixe mais claro "
- "e garanta no máximo 150 palavras.", draft)
- return reviewed
+ summary = llm("Resuma o documento em até 150 palavras. Mantenha nomes, "
+ "números e datas exatamente como no original.", document)
+ if word_count(summary) > 150:
+ summary = truncate_to_sentence(summary, max_words=150) # regra em código
+ return summary
Antes: duas chamadas, e a segunda quase sempre devolve a primeira.
flowchart LR
D(["1. Documento"]):::io --> G(["2. Resumir"]):::llm
G --> R(["3. Revisar o próprio resumo"]):::llm
R --> OUT(["4. Resumo"]):::io
Depois: uma chamada com o critério útil incorporado, e a regra objetiva em código.
flowchart LR
D(["1. Documento"]):::io --> G(["2. Resumir com o critério"]):::llm
G --> C["3. Checar tamanho em código"]:::tool
C --> OUT(["4. Resumo"]):::io
Um passo de revisão sem informação nova lê a mesma coisa com o mesmo modelo e tende a concordar com ela. O que ele tem de valor costuma ser uma instrução que caberia no passo anterior (“mantenha os números exatos”) ou uma regra objetiva que o código faz melhor (“no máximo 150 palavras”).
Repare num detalhe do código antigo: a revisão recebe só o rascunho, não o documento. Ela não tem como saber se um número está certo. O máximo que consegue é reescrever, e cada reescrita é mais uma chance de trocar “R$ 1,2 milhão” por “R$ 12 milhões”.
A pesquisa aponta na mesma direção. O paper “Large Language Models Cannot Self-Correct Reasoning Yet” (Huang et al., 2023) mostrou que, sem um sinal externo, pedir ao modelo para revisar a própria resposta não melhora o raciocínio e às vezes piora.
Embutir o critério no passo que gera evita o erro em vez de tentar corrigi-lo depois. O gerador é quem vê o documento original, então é ele quem precisa ouvir “mantenha os números”. Passar a regra objetiva para o código troca uma chamada probabilística por uma checagem determinística.
Uma conta ilustrativa ajuda a ver onde o custo mora. Suponha um documento de 3.000 tokens e um resumo de 200.
| Entrada | Saída | Espera | |
|---|---|---|---|
| Resumir | 3.000 tokens | 200 tokens | uma geração |
| Revisar | cerca de 250 tokens | 200 tokens | mais uma geração inteira |
A entrada da revisão é barata. O que pesa é a saída: o modelo escreve o resumo de novo, token por token. Tokens de saída costumam custar várias vezes mais que os de entrada, e são eles que definem quanto o usuário espera. Com 10 mil resumos por dia, são 2 milhões de tokens de saída extras para devolver quase o mesmo texto.
Nem toda revisão é trivial. O que separa as duas é a informação que o passo recebe.
| Sinal | Passo trivial | Passo que vale manter |
|---|---|---|
| O que ele vê | Só a saída anterior | A saída e algo novo: o documento, um teste, um resultado de ferramenta |
| Quem julga | O mesmo modelo, com o mesmo pedido vago | Uma rubrica clara, outro modelo ou código |
| O que produz | Quase sempre o mesmo texto | Problemas concretos que mudam o resultado |
Um passo que compara o resumo com o documento e lista números divergentes tem sinal. Um passo que roda os testes de um código gerado também. Esses viram um Avaliador e Otimizador, não uma etapa a embutir.
Este pipeline de classificação de tickets tem um passo que talvez seja trivial. Qual, e o que fazer com ele?
1. classificar(ticket) -> categoria
2. confirmar("A categoria X está correta para este ticket? Responda sim ou não.")
3. se "não": classificar de novo
O passo 2 pede ao modelo para confirmar a própria resposta, sem informação nova. Ele quase sempre diz “sim”. Remova os passos 2 e 3. No lugar, peça uma confiança junto com a categoria (saída estruturada com confidence, ou as probabilidades dos tokens quando a API oferece) e calibre o limiar no eval, porque a confiança declarada pelo modelo nem sempre bate com a taxa real de acerto. Os casos de baixa confiança vão para revisão humana ou para um modelo maior, como numa Cascata de Modelos.
Embutir Etapa Trivial (Inline Trivial Step) é uma refatoração de IA para sistemas com LLM, do grupo Compondo prompts. Remover uma chamada que não muda o resultado e juntar o trabalho na etapa vizinha.
Trata Autocrítica Inútil.
Ao padrão de projeto Encadeamento de Prompts.