Phase 11 - Lesson 02

Few-Shot, Chain-of-Thought, Tree-of-Thought

This lesson includes a graded coding exercise that runs in your browser, unlocked with lifetime access.

Dizer a um modelo o que fazer é prompting. Mostrar a ele como pensar é engenharia. A diferença entre 78% e 91% de precisão no mesmo modelo, mesma tarefa e mesmos dados não se deve a um modelo melhor. Deve-se a uma melhor estratégia de raciocínio.

Tipo: Build Idiomas: Python Pré-requisitos: Lição 11.01 (Engenharia de Prompt) Tempo: ~45 minutos

Objetivos de Aprendizagem

  • Implementar poucos exemplos (few-shot prompting) selecionando e formatando demonstrações de exemplos que maximizam a precisão da tarefa
  • Aplicar raciocínio de cadeia de pensamento (CoT) para melhorar a precisão em problemas de múltiplas etapas, como problemas matemáticos de texto
  • Construir um prompt de árvore de pensamento (Tree-of-Thought) que explore múltiplos caminhos de raciocínio e selecione o melhor
  • Mensurar a melhoria de precisão entre zero-shot vs few-shot vs CoT em um benchmark padrão

O Problema

Você constrói um aplicativo de tutoria de matemática. Seu prompt diz: "Resolva este problema de matemática." O GPT-5 acerta 94% das vezes no GSM8K, o benchmark padrão de matemática escolar. Você acha que já atingiu o limite. Não atingiu — o chain-of-thought ainda adiciona de 3 a 4 pontos.

Adicione cinco palavras — "Vamos pensar passo a passo" — e a precisão salta para 91%. Adicione alguns exemplos resolvidos e ela chega a 95%. Mesmo modelo. Mesma temperatura. Mesmo custo de API. A única diferença é que você deu um rascunho ao modelo.

Isso não é um truque. É assim que o raciocínio funciona. Os humanos não resolvem problemas de várias etapas em um único salto mental. Os transformers também não. Quando você força um modelo a gerar tokens intermediários, esses tokens se tornam parte do contexto para o próximo token. Cada etapa de raciocínio alimenta a próxima. O modelo literalmente computa seu caminho até a resposta.

Mas "pensar passo a passo" é o começo, não o fim. E se você amostrasse cinco caminhos de raciocínio e fizesse uma votação por maioria? E se você deixasse o modelo explorar uma árvore de possibilidades, avaliando e podando ramos? E se você intercalasse o raciocínio com o uso de ferramentas? Isso não é hipotético. São técnicas publicadas com melhorias mensuradas, e você construirá todas elas nesta lição.

O Conceito

Zero-Shot vs Few-Shot: Quando Exemplos Superam Instruções

O prompt zero-shot dá ao modelo uma tarefa e nada mais. O prompt few-shot fornece exemplos primeiro.

Wei et al. (2022) mediram isso em 8 benchmarks. Para tarefas simples, como classificação de sentimento, o zero-shot e o few-shot tiveram um desempenho com diferença de até 2% entre si. Para tarefas complexas, como aritmética de múltiplas etapas e raciocínio simbólico, o few-shot melhorou a precisão em 10-25%.

A intuição: exemplos são instruções compactadas. Em vez de descrever o formato de saída, você o mostra. Em vez de explicar o processo de raciocínio, você o demonstra. O modelo faz a correspondência de padrões nos exemplos de forma mais confiável do que interpreta instruções abstratas.

graph TD
    subgraph Comparison["Zero-Shot vs Few-Shot"]
        direction LR
        Z["Zero-Shot\n'Classifique esta avaliação'\nModelo adivinha o formato\n78% no GSM8K"]
        F["Few-Shot\n'Aqui estão 3 exemplos...\nAgora classifique esta avaliação'\nModelo corresponde ao padrão\n85% no GSM8K"]
    end

    Z ~~~ F

    style Z fill:#1a1a2e,stroke:#e94560,color:#fff
    style F fill:#1a1a2e,stroke:#51cf66,color:#fff

Quando o few-shot vence: tarefas sensíveis ao formato, classificação, extração estruturada, jargões específicos de domínio, qualquer tarefa onde o modelo precise corresponder a um padrão específico.

Quando o zero-shot vence: perguntas fatuais simples, tarefas criativas onde exemplos limitam a criatividade, tarefas onde encontrar bons exemplos é mais difícil do que escrever boas instruções.

Seleção de Exemplos: Semelhantes Superam Aleatórios

Nem todos os exemplos são iguais. Escolher exemplos semelhantes à entrada de destino supera a seleção aleatória em 5-15% em tarefas de classificação (Liu et al., 2022). Três princípios:

  1. Semelhança semântica: escolha exemplos mais próximos da entrada no espaço de incorporação (embedding)
  2. Diversidade de rótulos: cubra todas as categorias de saída em seus exemplos
  3. Correspondência de dificuldade: corresponda ao nível de complexidade do problema de destino

O número ideal de exemplos para a maioria das tarefas é de 3 a 5. Abaixo de 3, o modelo não tem sinal suficiente para extrair o padrão. Acima de 5, você atinge retornos decrescentes e desperdiça tokens da janela de contexto. Para classificação com muitos rótulos, use um exemplo por rótulo.

Cadeia de Pensamento (Chain-of-Thought): Dando um Rascunho aos Modelos

O prompt de Cadeia de Pensamento (CoT) foi introduzido por Wei et al. (2022) no Google Brain. A ideia é simples: em vez de pedir ao modelo apenas a resposta, peça a ele para mostrar suas etapas de raciocínio primeiro.

graph LR
    subgraph Standard["Prompting Padrão"]
        Q1["P: Roger tem 5 bolas.\nEle compra 2 latas de 3.\nQuantas bolas?"] --> A1["R: 11"]
    end

    subgraph CoT["Prompting de Cadeia de Pensamento"]
        Q2["P: Roger tem 5 bolas.\nEle compra 2 latas de 3.\nQuantas bolas?"] --> R2["Roger começa com 5.\n2 latas de 3 = 6.\n5 + 6 = 11."] --> A2["R: 11"]
    end

    style Q1 fill:#1a1a2e,stroke:#e94560,color:#fff
    style A1 fill:#1a1a2e,stroke:#e94560,color:#fff
    style Q2 fill:#1a1a2e,stroke:#51cf66,color:#fff
    style R2 fill:#1a1a2e,stroke:#ffa500,color:#fff
    style A2 fill:#1a1a2e,stroke:#51cf66,color:#fff

Por que isso funciona mecanicamente? Cada token que um transformer gera se torna contexto para o próximo token. Sem CoT, o modelo deve comprimir todo o raciocínio no estado oculto de uma única passagem direta (forward pass). Com CoT, o modelo externaliza as computações intermediárias como tokens. Cada token de raciocínio estende a profundidade de computação efetiva.

Benchmarks GSM8K (matemática escolar, 8.5 mil problemas):

Modelo Zero-Shot Zero-Shot CoT Few-Shot CoT
GPT-4o 78% 91% 95%
GPT-5 94% 97% 98%
o4-mini (raciocínio) 97%
Claude Opus 4.7 93% 97% 98%
Gemini 3 Pro 92% 96% 98%
Llama 4 70B 80% 89% 94%
DeepSeek-V3.1 89% 94% 96%

Nota sobre modelos de raciocínio. Modelos como a série-o da OpenAI (o3, o4-mini) e o DeepSeek-R1 executam cadeias de pensamento internamente antes de emitirem sua resposta. Adicionar "Vamos pensar passo a passo" a um modelo de raciocínio é redundante e, às vezes, contraproducente — eles já fizeram isso.

Dois tipos de CoT:

Zero-shot CoT: anexe "Vamos pensar passo a passo" ao prompt. Nenhum exemplo é necessário. Kojima et al. (2022) mostraram que essa única frase melhora a precisão em tarefas de aritmética, bom senso e raciocínio simbólico.

Few-shot CoT: forneça exemplos que incluam etapas de raciocínio. Mais eficaz do que o zero-shot CoT porque o modelo vê o formato de raciocínio exato que você espera.

Quando o CoT prejudica: recuperação fatual simples ("Qual é a capital da França?"), classificação de etapa única, tarefas onde a velocidade importa mais do que a precisão. O CoT adiciona um custo adicional de 50 a 200 tokens de raciocínio por consulta. Para tarefas de alta taxa de transferência (throughput) e baixa complexidade, isso é desperdício de custo.

Auto-Consistência (Self-Consistency): Amostrar Vários, Votar uma Vez

Wang et al. (2023) introduziram a auto-consistência. A percepção: um único caminho de CoT pode conter erros de raciocínio. Mas se você amostrar N caminhos de raciocínio independentes (usando temperature > 0) e fizer uma votação por maioria sobre a resposta final, os erros se cancelam.

graph TD
    P["Problema: 'Uma loja tem 48 maçãs.\nEles vendem 1/3 na segunda-feira\ne 1/4 do restante na terça-feira.\nQuantas restam?'"]

    P --> Path1["Caminho 1: 48 - 16 = 32\n32 - 8 = 24\nResposta: 24"]
    P --> Path2["Caminho 2: 1/3 de 48 = 16\nRestante: 32\n1/4 de 32 = 8\n32 - 8 = 24\nResposta: 24"]
    P --> Path3["Caminho 3: 48/3 = 16 vendidas\n48 - 16 = 32\n32/4 = 8 vendidas\n32 - 8 = 24\nResposta: 24"]
    P --> Path4["Caminho 4: Vende 1/3: 48 - 12 = 36\nVende 1/4: 36 - 9 = 27\nResposta: 27"]
    P --> Path5["Caminho 5: Segunda-feira: 48 * 2/3 = 32\nTerça-feira: 32 * 3/4 = 24\nResposta: 24"]

    Path1 --> V["Voto da Maioria\n24: 4 votos\n27: 1 voto\nFinal: 24"]
    Path2 --> V
    Path3 --> V
    Path4 --> V
    Path5 --> V

    style P fill:#1a1a2e,stroke:#ffa500,color:#fff
    style Path1 fill:#1a1a2e,stroke:#51cf66,color:#fff
    style Path2 fill:#1a1a2e,stroke:#51cf66,color:#fff
    style Path3 fill:#1a1a2e,stroke:#51cf66,color:#fff
    style Path4 fill:#1a1a2e,stroke:#e94560,color:#fff
    style Path5 fill:#1a1a2e,stroke:#51cf66,color:#fff
    style V fill:#1a1a2e,stroke:#51cf66,color:#fff

A auto-consistência melhorou a precisão no GSM8K de 56,5% (CoT único) para 74,4% com N=40 nos experimentos originais com o PaLM 540B. No GPT-5, a melhoria é pequena (97% para 98%) porque a precisão base já está saturada. A técnica brilha mais em modelos com precisão de CoT base de 60-85% — o ponto ideal onde os erros de caminho único são frequentes, mas não sistemáticos. Para modelos de raciocínio (série-o, R1), a auto-consistência é englobada pela amostragem interna integrada.

O custo-benefício: N amostras significa N vezes o custo de API e latência. Na prática, N=5 captura a maior parte do benefício. N=3 é o mínimo para uma votação significativa. N > 10 tem retornos decrescentes para a maioria das tarefas.

Árvore de Pensamento (Tree-of-Thought): Exploração com Ramificação

Yao et al. (2023) introduziram o Tree-of-Thought (ToT). Enquanto o CoT segue um único caminho linear de raciocínio, o ToT explora vários ramos e avalia quais são os mais promissores antes de continuar.

graph TD
    Root["Problema"] --> B1["Pensamento 1a"]
    Root --> B2["Pensamento 1b"]
    Root --> B3["Pensamento 1c"]

    B1 --> E1["Avaliação: 0.8"]
    B2 --> E2["Avaliação: 0.3"]
    B3 --> E3["Avaliação: 0.9"]

    E1 -->|Continuar| B1a["Pensamento 2a"]
    E1 -->|Continuar| B1b["Pensamento 2b"]
    E3 -->|Continuar| B3a["Pensamento 2a"]
    E3 -->|Continuar| B3b["Pensamento 2b"]

    E2 -->|Podar| X["X"]

    B1a --> E4["Avaliação: 0.7"]
    B3a --> E5["Avaliação: 0.95"]

    E5 -->|Melhor caminho| Final["Solução"]

    style Root fill:#1a1a2e,stroke:#ffa500,color:#fff
    style E2 fill:#1a1a2e,stroke:#e94560,color:#fff
    style X fill:#1a1a2e,stroke:#e94560,color:#fff
    style E5 fill:#1a1a2e,stroke:#51cf66,color:#fff
    style Final fill:#1a1a2e,stroke:#51cf66,color:#fff
    style B1 fill:#1a1a2e,stroke:#808080,color:#fff
    style B2 fill:#1a1a2e,stroke:#808080,color:#fff
    style B3 fill:#1a1a2e,stroke:#808080,color:#fff
    style B1a fill:#1a1a2e,stroke:#808080,color:#fff
    style B1b fill:#1a1a2e,stroke:#808080,color:#fff
    style B3a fill:#1a1a2e,stroke:#808080,color:#fff
    style B3b fill:#1a1a2e,stroke:#808080,color:#fff
    style E1 fill:#1a1a2e,stroke:#808080,color:#fff
    style E3 fill:#1a1a2e,stroke:#808080,color:#fff
    style E4 fill:#1a1a2e,stroke:#808080,color:#fff

O ToT tem três componentes:

  1. Geração de pensamentos: produzir múltiplos candidatos para os próximos passos
  2. Avaliação do estado: atribuir uma pontuação para cada candidato (pode usar o próprio LLM como avaliador)
  3. Algoritmo de busca: BFS (busca em largura) ou DFS (busca em profundidade) através da árvore, podando os ramos de pontuação baixa

Na tarefa do Game of 24 (combinar 4 números usando aritmética para obter 24), o GPT-4 com prompt padrão resolve 7,3% dos problemas. Com CoT, 4,0% (o CoT na verdade prejudica aqui porque o espaço de busca é amplo). Com ToT, 74%.

O ToT é caro. Cada nó na árvore requer uma chamada de LLM. Uma árvore com fator de ramificação 3 e profundidade 3 requer até 39 chamadas de LLM. Use-o apenas para problemas onde o espaço de busca é grande mas avaliável — planejamento, resolução de quebra-cabeças, resolução criativa de problemas com restrições.

ReAct: Pensar + Agir

Yao et al. (2022) combinaram rastros de raciocínio com ações. O modelo alterna entre pensar (gerar raciocínio) e agir (chamar ferramentas, pesquisar, computar).

graph LR
    Q["Pergunta:\nQual é a\npopulação do\npaís onde\na Torre Eiffel\nestá localizada?"]
    T1["Pensamento: Preciso\nencontrar qual país\ntem a Torre Eiffel"]
    A1["Ação: buscar\n'localização da Torre Eiffel'"]
    O1["Observação:\nParis, França"]
    T2["Pensamento: Agora preciso\nda população da França"]
    A2["Ação: buscar\n'população da França 2024'"]
    O2["Observação:\n68.4 milhões"]
    T3["Pensamento: Tenho\na resposta"]
    F["Resposta:\n68.4 milhões"]

    Q --> T1 --> A1 --> O1 --> T2 --> A2 --> O2 --> T3 --> F

    style Q fill:#1a1a2e,stroke:#ffa500,color:#fff
    style T1 fill:#1a1a2e,stroke:#51cf66,color:#fff
    style A1 fill:#1a1a2e,stroke:#e94560,color:#fff
    style O1 fill:#1a1a2e,stroke:#808080,color:#fff
    style T2 fill:#1a1a2e,stroke:#51cf66,color:#fff
    style A2 fill:#1a1a2e,stroke:#e94560,color:#fff
    style O2 fill:#1a1a2e,stroke:#808080,color:#fff
    style T3 fill:#1a1a2e,stroke:#51cf66,color:#fff
    style F fill:#1a1a2e,stroke:#51cf66,color:#fff

O ReAct supera o CoT puro em tarefas intensivas de conhecimento porque ele pode fundamentar seu raciocínio em dados reais. No HotpotQA (perguntas e respostas com múltiplos saltos), o ReAct com GPT-4 alcança 35,1% de correspondência exata versus 29,4% apenas com CoT. O verdadeiro poder está no fato de que os erros de raciocínio são corrigidos pelas observações — o modelo pode atualizar seu plano no meio da execução.

O ReAct é a base dos agentes de IA modernos. Todo framework de agente (LangChain, CrewAI, AutoGen) implementa alguma variante do loop Pensamento-Ação-Observação (Thought-Action-Observation). Você construirá agentes completos na Fase 14. Esta lição cobre o padrão de prompting.

Prompting Estruturado: Tags XML, Delimitadores, Cabeçalhos

Conforme os prompts ficam complexos, a estrutura impede que o modelo confunda as seções. Três abordagens:

Tags XML (funciona melhor com o Claude, sólido em todos os lugares):

<context>
You are reviewing a pull request.
The codebase uses TypeScript and React.
</context>

<task>
Review the following diff for bugs, security issues, and style violations.
</task>

<diff>
{diff_content}
</diff>

<output_format>
List each issue with: file, line, severity (critical/warning/info), description.
</output_format>

Cabeçalhos Markdown (universal):

## Role
Senior security engineer at a fintech company.

## Task
Analyze this API endpoint for vulnerabilities.

## Input
{api_code}

## Rules
- Focus on OWASP Top 10
- Rate each finding: critical, high, medium, low
- Include remediation steps

Delimitadores (mínimo, mas eficaz):

---INPUT---
{user_text}
---END INPUT---

---INSTRUCTIONS---
Summarize the above in 3 bullet points.
---END INSTRUCTIONS---

Encadeamento de Prompts (Prompt Chaining): Decomposição Sequencial

Algumas tarefas são complexas demais para um único prompt. O encadeamento de prompts as divide em etapas, onde a saída de um prompt se torna a entrada do próximo.

graph LR
    I["Entrada Bruta"] --> P1["Prompt 1:\nExtrair\nfatos principais"]
    P1 --> O1["Fatos"]
    O1 --> P2["Prompt 2:\nAnalisar\nfatos"]
    P2 --> O2["Análise"]
    O2 --> P3["Prompt 3:\nGerar\nrecomendação"]
    P3 --> F["Saída Final"]

    style I fill:#1a1a2e,stroke:#808080,color:#fff
    style P1 fill:#1a1a2e,stroke:#e94560,color:#fff
    style O1 fill:#1a1a2e,stroke:#ffa500,color:#fff
    style P2 fill:#1a1a2e,stroke:#e94560,color:#fff
    style O2 fill:#1a1a2e,stroke:#ffa500,color:#fff
    style P3 fill:#1a1a2e,stroke:#e94560,color:#fff
    style F fill:#1a1a2e,stroke:#51cf66,color:#fff

O encadeamento supera o prompt único por três razões:

  1. Cada etapa é mais simples: o modelo lida com uma tarefa focada em vez de fazer malabarismos com tudo ao mesmo tempo
  2. As saídas intermediárias são inspecionáveis: você pode validar e corrigir entre as etapas
  3. Diferentes etapas podem usar modelos diferentes: use um modelo barato para extração e um caro para raciocínio

Comparação de Desempenho

Técnica Indicado Para Precisão GSM8K (GPT-5) Chamadas de API Custo Adicional de Tokens Complexidade
Zero-Shot Tarefas simples 94% 1 Nenhum Trivial
Few-Shot Correspondência de formato 96% 1 200-500 tokens Baixa
Zero-Shot CoT Aumento rápido de raciocínio 97% 1 50-200 tokens Trivial
Few-Shot CoT Precisão máxima em chamada única 98% 1 300-600 tokens Baixa
Auto-Consistência (N=5) Raciocínio crítico 98.5% 5 Custo de tokens 5x Média
Modelo de raciocínio (o4-mini) Substituição direta para CoT 97% 1 oculto (2-10x interno) Trivial
Tree-of-Thought Problemas de busca/planejamento N/A (74% no Game of 24) 10-40+ Custo de tokens 10-40x Alta
ReAct Raciocínio fundamentado em conhecimento N/A (35.1% no HotpotQA) 3-10+ Variável Alta
Encadeamento de Prompts Tarefas complexas de várias etapas 96% (pipeline) 2-5 Custo de tokens 2-5x Média

A técnica correta depende de três fatores: requisito de precisão, limite de latência e tolerância ao custo. Para a maioria dos sistemas em produção, o few-shot CoT com um fallback de auto-consistência de 3 amostras cobre 90% dos casos de uso.

Implementação

Construiremos um resolvedor de problemas matemáticos que combina poucas demonstrações (few-shot prompting), raciocínio de cadeia de pensamento (chain-of-thought) e votação por auto-consistência (self-consistency) em um único pipeline. Depois, adicionaremos tree-of-thought para problemas difíceis.

A implementação completa está em code/advanced_prompting.py. Aqui estão os principais componentes.

Passo 1: Repositório de Exemplos Few-Shot

O primeiro componente gerencia os exemplos few-shot e seleciona os mais relevantes para um determinado problema.

GSM8K_EXAMPLES = [
    {
        "question": "Janet's ducks lay 16 eggs per day. She eats three for breakfast every morning and bakes muffins for her friends every day with four. She sells every egg at the farmers' market for 
. How much does she make every day at the farmers' market?", "reasoning": "Janet's ducks lay 16 eggs per day. She eats 3 and bakes 4, using 3 + 4 = 7 eggs. So she has 16 - 7 = 9 eggs left. She sells each for , so she makes 9 * 2 =
8 per day.", "answer": "18" }, ... ]

Cada exemplo possui três partes: a pergunta, a cadeia de raciocínio e a resposta final. A cadeia de raciocínio é o que transforma um exemplo few-shot comum em um exemplo few-shot CoT.

Passo 2: Construtor de Prompt Chain-of-Thought

O construtor de prompt reúne uma mensagem do sistema, exemplos few-shot com cadeias de raciocínio e a pergunta-alvo em um único prompt.

def build_cot_prompt(question, examples, num_examples=3):
    system = (
        "You are a math problem solver. "
        "For each problem, show your step-by-step reasoning, "
        "then give the final numerical answer on the last line "
        "in the format: 'The answer is [number]'."
    )

    example_text = ""
    for ex in examples[:num_examples]:
        example_text += f"Q: {ex['question']}\n"
        example_text += f"A: {ex['reasoning']} The answer is {ex['answer']}.\n\n"

    user = f"{example_text}Q: {question}\nA:"
    return system, user

A restrição de formato ("The answer is [number]") é crítica. Sem ela, a auto-consistência não conseguirá extrair e comparar respostas entre as amostras.

Passo 3: Votação por Auto-Consistência

Amostre N caminhos de raciocínio e obtenha a resposta da maioria.

def self_consistency_solve(question, examples, client, model, n_samples=5):
    system, user = build_cot_prompt(question, examples)

    answers = []
    reasonings = []
    for _ in range(n_samples):
        response = client.chat.completions.create(
            model=model,
            messages=[
                {"role": "system", "content": system},
                {"role": "user", "content": user}
            ],
            temperature=0.7
        )
        text = response.choices[0].message.content
        reasonings.append(text)
        answer = extract_answer(text)
        if answer is not None:
            answers.append(answer)

    vote_counts = Counter(answers)
    best_answer = vote_counts.most_common(1)[0][0] if vote_counts else None
    confidence = vote_counts[best_answer] / len(answers) if best_answer else 0

    return best_answer, confidence, reasonings, vote_counts

O valor de temperature 0.7 é importante. Em uma temperatura de 0.0, todas as N amostras seriam idênticas, frustrando o propósito. Você precisa de aleatoriedade suficiente para obter caminhos de raciocínio diversos, mas não tanto a ponto de fazer com que o modelo produza respostas sem sentido.

Passo 4: Resolvedor Tree-of-Thought

Para problemas onde o raciocínio linear falha, o ToT explora múltiplas abordagens e avalia qual direção é mais promissora.

def tree_of_thought_solve(question, client, model, breadth=3, depth=3):
    thoughts = generate_initial_thoughts(question, client, model, breadth)
    scored = [(t, evaluate_thought(t, question, client, model)) for t in thoughts]
    scored.sort(key=lambda x: x[1], reverse=True)

    for current_depth in range(1, depth):
        next_thoughts = []
        for thought, score in scored[:2]:
            extensions = extend_thought(thought, question, client, model, breadth)
            for ext in extensions:
                ext_score = evaluate_thought(ext, question, client, model)
                next_thoughts.append((ext, ext_score))
        scored = sorted(next_thoughts, key=lambda x: x[1], reverse=True)

    best_thought = scored[0][0] if scored else ""
    return extract_answer(best_thought), best_thought

O avaliador é, ele próprio, uma chamada de LLM. Você pergunta ao modelo: "Em uma escala de 0.0 a 1.0, quão promissor é este caminho de raciocínio para resolver o problema?" Esta é a percepção chave do ToT — o modelo avalia suas próprias soluções parciais.

Passo 5: Pipeline Completo

O pipeline combina todas as técnicas com uma estratégia de escalabilidade (escalonamento).

def solve_with_escalation(question, examples, client, model):
    system, user = build_cot_prompt(question, examples)
    single_response = call_llm(client, model, system, user, temperature=0.0)
    single_answer = extract_answer(single_response)

    sc_answer, confidence, _, _ = self_consistency_solve(
        question, examples, client, model, n_samples=5
    )

    if confidence >= 0.8:
        return sc_answer, "self_consistency", confidence

    tot_answer, _ = tree_of_thought_solve(question, client, model)
    return tot_answer, "tree_of_thought", None

A lógica de escalonamento: tente o caminho mais barato (CoT único) primeiro. Se a confiança da auto-consistência estiver abaixo de 0.8 (menos de 4 de 5 amostras concordam), escale para o ToT. Isso equilibra custo e precisão — a maioria dos problemas é resolvida de forma barata, enquanto problemas difíceis recebem mais computação.

Como Usar

Com LangChain

O LangChain fornece suporte integrado para modelos de prompts e análise de saída (parsers) que simplificam os padrões few-shot e CoT:

from langchain_core.prompts import FewShotPromptTemplate, PromptTemplate
from langchain_openai import ChatOpenAI

example_prompt = PromptTemplate(
    input_variables=["question", "reasoning", "answer"],
    template="Q: {question}\nA: {reasoning} The answer is {answer}."
)

few_shot_prompt = FewShotPromptTemplate(
    examples=examples,
    example_prompt=example_prompt,
    suffix="Q: {input}\nA: Let's think step by step.",
    input_variables=["input"]
)

llm = ChatOpenAI(model="gpt-4o", temperature=0.7)
chain = few_shot_prompt | llm
result = chain.invoke({"input": "If a train travels 120 km in 2 hours..."})

O LangChain também possui classes ExampleSelector para seleção por semelhança semântica:

from langchain_core.example_selectors import SemanticSimilarityExampleSelector
from langchain_openai import OpenAIEmbeddings

selector = SemanticSimilarityExampleSelector.from_examples(
    examples,
    OpenAIEmbeddings(),
    k=3
)

Com DSPy

O DSPy trata as estratégias de prompt como módulos otimizáveis. Em vez de criar prompts CoT manualmente, você define uma assinatura (signature) e deixa o DSPy otimizar o prompt:

import dspy

dspy.configure(lm=dspy.LM("openai/gpt-4o", temperature=0.7))

class MathSolver(dspy.Module):
    def __init__(self):
        self.solve = dspy.ChainOfThought("question -> answer")

    def forward(self, question):
        return self.solve(question=question)

solver = MathSolver()
result = solver(question="Janet's ducks lay 16 eggs per day...")

O módulo ChainOfThought do DSPy adiciona automaticamente rastros de raciocínio. A função dspy.majority implementa a auto-consistência:

result = dspy.majority(
    [solver(question=q) for _ in range(5)],
    field="answer"
)

Comparação: Do Zero vs Frameworks

Recurso Do Zero (esta lição) LangChain DSPy
Controle sobre o formato do prompt Total Baseado em templates Automático
Auto-consistência Votação manual Manual Integrada (dspy.majority)
Seleção de exemplos Lógica personalizada ExampleSelector dspy.BootstrapFewShot
Tree-of-Thought Busca em árvore personalizada Community chains Não integrado
Otimização do prompt Iteração manual Manual Compilação automática
Melhor para Aprendizado, pipelines personalizados Fluxos de trabalho padrão Pesquisa, otimização

Conclusão

Esta lição produz dois artefatos.

1. Prompt de Cadeia de Raciocínio (outputs/prompt-reasoning-chain.md): um modelo de prompt pronto para produção para few-shot CoT com auto-consistência. Insira seus exemplos e domínio do problema.

2. Habilidade de Seleção de Padrões CoT (outputs/skill-cot-patterns.md): um framework de decisão para escolher a técnica de raciocínio correta com base no tipo de tarefa, requisitos de precisão e restrições de custo.

Exercícios

  1. Meça a diferença: Pegue 10 problemas GSM8K. Resolva cada um com zero-shot, few-shot, zero-shot CoT e few-shot CoT. Registre a precisão de cada um. Qual técnica proporciona a maior melhoria no seu modelo?

  2. Experimento de seleção de exemplos: Para os mesmos 10 problemas, compare a seleção aleatória de exemplos versus exemplos semelhantes selecionados manualmente. Meça a diferença de precisão. Em que ponto a qualidade do exemplo importa mais do que a quantidade de exemplos?

  3. Curva de custo da auto-consistência: Execute a auto-consistência com N=1, 3, 5, 7, 10 em 20 problemas GSM8K. Plote precisão vs custo (total de tokens). Onde fica o "joelho" (ponto de inflexão) da curva para o seu modelo?

  4. Construa um loop ReAct: Estenda o pipeline com uma ferramenta de calculadora. Quando o modelo gerar uma expressão matemática, execute-a com a função eval() do Python (em um ambiente isolado) e envie o resultado de volta. Meça se o raciocínio fundamentado em ferramentas supera o CoT puro.

  5. ToT para tarefas criativas: Adapte o resolvedor Tree-of-Thought para uma tarefa de escrita criativa: "Escreva uma história de 6 palavras que seja ao mesmo tempo engraçada e triste." Use o LLM como avaliador. A exploração por ramificações produz resultados criativos melhores do que a geração de disparo único (single-shot)?

Termos-Chave

Termo O que as pessoas dizem O que realmente significa
Few-shot prompting "Dê alguns exemplos a ele" Incluir demonstrações de entrada-saída no prompt para ancorar o formato de saída e o comportamento do modelo
Chain-of-Thought "Faça-o pensar passo a passo" Elaborar tokens de raciocínio intermediários que estendam a computação efetiva do modelo antes de produzir uma resposta final
Auto-Consistência (Self-Consistency) "Execute-o várias vezes" Amostrar N caminhos de raciocínio diversos com temperature > 0 e selecionar a resposta final mais comum por votação de maioria
Tree-of-Thought "Deixe-o explorar opções" Busca estruturada sobre ramos de raciocínio onde cada solução parcial é avaliada e apenas caminhos promissores são expandidos
ReAct "Raciocínio + uso de ferramentas" Intercalar rastros de raciocínio com ações externas (pesquisa, computação, chamadas de API) em um loop Pensamento-Ação-Observação
Encadeamento de prompts (Prompt chaining) "Divida-o em etapas" Decompor uma tarefa complexa em prompts sequenciais onde cada saída alimenta a próxima entrada
Zero-shot CoT "Apenas adicione 'pense passo a passo'" Anexar uma frase de gatilho de raciocínio a um prompt sem exemplos, confiando na capacidade de raciocínio latente do modelo

Leitura Adicional

0 lifetime access. Curriculum based on AI Engineering from Scratch by Rohit Ghumare (MIT, used under attribution).