Exercícios Práticos: Fundamentos de Prompting e Raciocínio
Este capítulo apresentou técnicas fundamentais de prompting e raciocínio para sistemas de agentes de IA. Os exercícios a seguir permitem experimentar hands-on com as técnicas mais importantes: in-context learning com seleção dinâmica, chain-of-thought reasoning e o framework ReAct para agentes autônomos.
Exercício 1: Few-Shot Dynamic Classifier
Arquivo: sandbox/chapter-04/01-few-shot-classifier.py
Dataset: datasets/sentiment_examples.jsonl
Objetivo: Implementar um classificador de sentimento usando few-shot learning com seleção dinâmica de exemplos baseada em similaridade semântica.
Conceitos aplicados:
- In-Context Learning (ICL)
- Embeddings para seleção de exemplos relevantes
- Comparação empírica: seleção aleatória vs. semântica
O que você vai construir:
class FewShotSelector:
"""Seleciona dinamicamente os k exemplos mais relevantes."""
def select_similar(self, query: str, k: int = 3) -> List[Dict]:
"""Seleciona exemplos por similaridade de cosseno."""
query_emb = self.model.encode([query])[0]
similarities = cosine_similarity([query_emb], self.embeddings)[0]
top_indices = np.argsort(similarities)[-k:][::-1]
return [self.examples[i] for i in top_indices]Resultado esperado:
Avaliação: Seleção Aleatória
Acurácia: 65.0% (13/20)
Avaliação: Seleção Semântica
Acurácia: 85.0% (17/20)
Melhoria com seleção semântica: +20.0%
Desafios adicionais:
- Experimente diferentes valores de
k(3, 5, 10 exemplos) - Compare modelos de embedding (all-MiniLM-L6-v2 vs. multilingual-e5-base)
- Implemente diversidade nos exemplos (evitar redundância)
Questões para reflexão:
- Por que seleção semântica supera seleção aleatória?
- Quando seleção aleatória pode ser preferível? (dica: custo computacional)
- Como implementar cache de embeddings para reduzir latência?
Exercício 2: Chain-of-Thought Math Solver
Arquivo: sandbox/chapter-04/02-cot-math-solver.py
Dataset: datasets/math_problems.jsonl
Objetivo: Implementar solver de problemas matemáticos comparando três abordagens: zero-shot CoT, few-shot CoT e self-consistency.
Conceitos aplicados:
- Zero-shot CoT: “Let’s think step by step”
- Few-shot CoT: exemplos com raciocínio explícito
- Self-consistency: voting majoritário com múltiplas cadeias
- Análise de trade-offs: acurácia vs. custo vs. latência
O que você vai construir:
def self_consistency_solve(
problem: str,
n_samples: int = 5
) -> Tuple[str, float]:
"""
Gera N soluções independentes e retorna resposta por voting.
Returns:
(resposta_final, confiança)
"""
answers = []
for _ in range(n_samples):
reasoning = generate_cot(problem, temperature=0.7)
answer = extract_answer(reasoning)
answers.append(answer)
# Voting majoritário
most_common = Counter(answers).most_common(1)[0]
confidence = most_common[1] / n_samples
return most_common[0], confidenceResultado esperado:
Zero-Shot CoT:
Acurácia: 60.0% (9/15)
Custo estimado: $0.003
Few-Shot CoT:
Acurácia: 73.3% (11/15)
Custo estimado: $0.005
Self-Consistency (N=5):
Acurácia: 86.7% (13/15)
Custo estimado: $0.025
Confiança média: 0.85
Desafios adicionais:
- Implemente extração robusta de resposta numérica (regex aprimorado)
- Adicione detecção de contradições no raciocínio
- Compare “Think step by step” vs. “Solve carefully” vs. outros prompts
- Meça token usage real e calcule custo exato (se usar APIs)
Questões para reflexão:
- Self-consistency vale 5× no custo para seu caso de uso?
- Como detectar quando o modelo está “adivinhando” vs. raciocinando?
- Quando CoT piora a performance? (dica: tarefas muito simples)
Exercício 3: Simple ReAct Agent
Arquivo: sandbox/chapter-04/03-simple-react-agent.py
Objetivo: Implementar agente ReAct básico com três ferramentas: calculadora, API de temperatura e conversor de moeda.
Conceitos aplicados:
- ReAct framework (Reasoning + Acting)
- Parsing de Pensamento/Ação/Observação
- Tool registry e dispatching
- Loop iterativo com limite de passos (evitar loops infinitos)
O que você vai construir:
class ReactAgent:
"""Agente ReAct com ferramentas."""
def run(self, question: str, max_iterations: int = 5) -> str:
"""
Loop Pensamento-Ação-Observação.
1. Gera Pensamento (reasoning)
2. Escolhe Ação (tool + argumentos)
3. Executa tool → Observação
4. Repete até resposta final ou limite
"""
for i in range(max_iterations):
thought, action = self._simulate_reasoning(question, history)
observation = self._execute_action(action)
if self._is_final_answer(thought):
return thought
return "Limite de iterações atingido."Ferramentas implementadas:
calculator(expression): Avalia expressões matemáticasget_temperature(city): Retorna temperatura (mock API)convert_currency(amount, from, to): Converte moedas (mock API)
Resultado esperado:
Pergunta: Qual a temperatura em São Paulo?
[Iteração 1]
Pensamento: Preciso obter informações sobre temperatura
Ação: get_temperature("São Paulo")
Observação: 28°C
[Iteração 2]
Pensamento: Tenho a informação necessária
Resposta Final: A temperatura em São Paulo é 28°C.
Desafios adicionais:
- Adicione retry logic quando parsing de Ação falha
- Implemente detecção de loops (agente repete mesma ação)
- Adicione logging estruturado (JSON) para debugging
- Compare ReAct vs. raciocínio direto (sem ferramentas)
Questões para reflexão:
- Quando ReAct é superior a raciocínio direto?
- Como lidar com ferramentas que falham intermitentemente?
- Como escalar de 3 ferramentas para 50+? (arquitetura modular)
Os exercícios usam simulação de LLMs para permitir execução sem API keys.
Para produção, seria necessário integrar com APIs reais. Por exemplo, para OpenAI:
# Substituir simulate_llm_response() por:
from openai import OpenAI
client = OpenAI(api_key="sua-api-key")
response = client.chat.completions.create(
model="gpt-4-turbo-preview",
messages=[{"role": "user", "content": prompt}],
temperature=0.7
)
output = response.choices[0].message.contentVeja sandbox/chapter-04/README.md para exemplos completos com OpenAI e Anthropic.
Também seria possível utilizar modelos open source locais (Llama2, Falcon) via bibliotecas como transformers, llama-cpp-python ou ferramentas como Ollama e vLLM.