Você está implementando IA generativa no seu produto. A pergunta que vai aparecer cedo é: "precisamos fazer fine-tuning ou RAG resolve?"
A resposta correta depende de três fatores — tipo de conhecimento necessário, latência aceitável e custo operacional disponível. Esse artigo cobre os critérios práticos para tomar essa decisão com segurança.
Os três caminhos para customizar o comportamento de um LLM
Antes dos critérios, uma definição clara de cada abordagem:
Prompt engineering (prompting): instruir o modelo através do texto enviado em cada chamada. Sem treinamento adicional, sem infraestrutura extra. O modelo usa apenas o que está no contexto da conversa.
RAG (Retrieval-Augmented Generation): recuperar documentos relevantes de uma base de conhecimento e incluí-los no contexto da chamada. O modelo raciocina sobre conteúdo externo que ele não "sabia" durante o treinamento.
Fine-tuning: treinar o modelo com exemplos específicos do seu domínio, ajustando os pesos para que ele se comporte de forma diferente do modelo base. O conhecimento fica "dentro" do modelo.
A maioria dos casos reais começa no prompting, evolui para RAG quando precisa de conhecimento externo e só chega ao fine-tuning quando os dois anteriores atingiram seus limites.
Quando o prompting é suficiente
Para muitos casos de uso, um bom prompt resolve — e adicionar RAG ou fine-tuning seria complexidade desnecessária.
Prompting é a escolha certa quando:
- O modelo já sabe o que você precisa (o conhecimento está no pré-treinamento)
- Você precisa de formato específico de saída: JSON, tabela, lista numerada
- O comportamento muda conforme o contexto da conversa, não conforme documentos externos
- Volume de chamadas é baixo o suficiente para não tornar o custo do contexto um problema
# Exemplo: classificador de suporte com prompting estruturado
import anthropic
client = anthropic.Anthropic()
def classify_support_ticket(ticket: str) -> dict:
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=256,
system="""Você é um sistema de triagem de tickets de suporte.
Classifique o ticket nas seguintes categorias:
- categoria: billing | technical | account | feature_request
- prioridade: low | medium | high | critical
- sentimento: positive | neutral | negative | frustrated
Responda APENAS com JSON válido, sem texto adicional.""",
messages=[
{"role": "user", "content": f"Ticket: {ticket}"}
]
)
import json
return json.loads(response.content[0].text)
Técnicas que elevam muito a qualidade do prompting:
- Chain-of-thought: peça ao modelo para "pensar passo a passo" antes de responder
- Few-shot: inclua 2-3 exemplos de input/output desejado no system prompt
- Structured output: defina o schema JSON esperado explicitamente
- Persona + restrições: "Você é X. Você NUNCA faz Y. Sempre responda Z."
Quando RAG é necessário
RAG resolve o problema fundamental do prompting: o contexto tem limite de tokens. Se o conhecimento que o modelo precisa não cabe na janela de contexto — ou muda frequentemente — RAG é a solução.
RAG é a escolha certa quando:
- O conhecimento é privado (documentos internos, contratos, base de conhecimento da empresa)
- O conhecimento muda com frequência — novos produtos, políticas atualizadas, preços
- Você precisa de citações: "De acordo com o documento X, seção Y..."
- O volume de documentos é grande demais para caber no contexto
Arquitetura básica de RAG
[Query do usuário]
↓
[Embedding da query]
↓
[Busca vetorial (pgvector / Pinecone / Qdrant)]
↓
[Top-K documentos relevantes]
↓
[Contexto montado: documentos + query]
↓
[LLM gera resposta fundamentada nos documentos]
import anthropic
from pgvector.psycopg2 import register_vector
import psycopg2
import numpy as np
client = anthropic.Anthropic()
def get_embedding(text: str) -> list[float]:
"""Gera embedding usando o modelo de embeddings da Anthropic ou OpenAI."""
# Exemplo com text-embedding-3-small da OpenAI
from openai import OpenAI
oai = OpenAI()
response = oai.embeddings.create(
model="text-embedding-3-small",
input=text
)
return response.data[0].embedding
def retrieve_context(query: str, conn, top_k: int = 5) -> list[dict]:
"""Recupera documentos relevantes via busca vetorial."""
query_embedding = get_embedding(query)
with conn.cursor() as cur:
cur.execute("""
SELECT content, source,
1 - (embedding <=> %s::vector) as similarity
FROM documents
ORDER BY embedding <=> %s::vector
LIMIT %s
""", (query_embedding, query_embedding, top_k))
return [
{"content": row[0], "source": row[1], "similarity": row[2]}
for row in cur.fetchall()
]
def rag_query(question: str, conn) -> str:
"""Pipeline RAG completo."""
docs = retrieve_context(question, conn)
context = "\n\n".join([
f"[Fonte: {doc['source']}]\n{doc['content']}"
for doc in docs
if doc['similarity'] > 0.75 # filtra documentos com baixa relevância
])
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
system="""Você é um assistente especializado. Responda APENAS com base
nos documentos fornecidos. Se a informação não estiver nos documentos,
diga explicitamente que não encontrou a informação.
Cite a fonte ao usar informações específicas.""",
messages=[
{
"role": "user",
"content": f"""Documentos relevantes:
{context}
Pergunta: {question}"""
}
]
)
return response.content[0].text
Qualidade do RAG: os pontos onde falha
RAG mal implementado responde com confiança usando documentos irrelevantes. As falhas mais comuns:
- Chunking ruim: dividir documentos no meio de frases ou parágrafos quebra o contexto. Use chunk overlap e respeite a estrutura semântica.
- Threshold de similaridade ignorado: documentos com similaridade < 0.70 costumam ser ruído. Filtre antes de enviar ao LLM.
- Sem re-ranking: a busca vetorial por cosseno não é perfeita. Um re-ranker (cross-encoder) reavalia os top-K com mais precisão.
- Contexto grande demais: incluir muitos documentos piora a qualidade. Prefira 3-5 chunks bem relevantes a 15 mediocres.
Quando fine-tuning faz sentido
Fine-tuning é frequentemente vendido como a solução para tudo — e raramente é necessário. Antes de cogitar fine-tuning, verifique se RAG com prompting de qualidade já não resolve.
Fine-tuning faz sentido quando:
- Você precisa de um estilo/formato/tom muito específico que prompting não mantém consistentemente
- O modelo precisa "aprender" padrões que não estão em nenhum documento — por exemplo, a lógica de scoring proprietária da sua empresa
- Latência é crítica e o contexto longo do RAG é proibitivo
- Você tem um volume enorme de exemplos rotulados de alta qualidade (centenas ou milhares)
- O comportamento precisa ser estável e previsível em dimensões que o modelo base varia
Fine-tuning NÃO é adequado quando:
- Você quer que o modelo "saiba" seus documentos internos — RAG faz isso melhor e com atualização em tempo real
- Você tem menos de 100 exemplos de treinamento de qualidade
- O conhecimento muda frequentemente — fine-tuning tem custo de retreinamento
- O orçamento é limitado — fine-tuning tem custo de treinamento + custo de inferência do modelo customizado
Custo comparativo (estimativas 2026)
| Dimensão | Prompting | RAG | Fine-tuning |
|---|---|---|---|
| Custo de setup | Horas | Dias a semanas | Semanas a meses |
| Custo por query | Baixo | Médio (embedding + LLM) | Médio-alto (modelo customizado) |
| Custo de atualização | Imediato | Reindexar documentos | Retreinamento (alto) |
| Latência | Baixa | Média (busca vetorial + LLM) | Baixa (sem busca) |
| Explicabilidade | Baixa | Alta (cita fontes) | Baixa |
A abordagem híbrida: RAG + fine-tuning
Em sistemas de produção maduros, as duas abordagens são complementares:
- Fine-tuning define o estilo, formato e comportamento base do modelo
- RAG injeta o conhecimento atual e específico em cada chamada
Exemplo: um assistente de atendimento ao cliente pode ter fine-tuning para o tom de voz e os padrões de resposta da empresa, mais RAG para buscar o status real do pedido do cliente no momento da conversa.
Árvore de decisão prática
O modelo base (sem customização) responde bem?
Sim → Use prompting. Invista em prompt engineering de qualidade.
Não ↓
O problema é falta de conhecimento externo/privado?
Sim → Use RAG. Invista em chunking, embedding e threshold de similaridade.
Não ↓
O problema é comportamento inconsistente ou formato?
Sim → Tente prompting avançado (few-shot, chain-of-thought) antes de fine-tuning.
Prompting avançado resolveu?
Sim → Ótimo. Fique aqui.
Não → Fine-tuning pode valer. Mas só se você tiver 200+ exemplos de qualidade.
A regra prática: comece sempre pelo mais simples. Fine-tuning é o último recurso, não o primeiro.
Se você está implementando IA generativa e quer avaliar qual abordagem faz sentido para o seu caso, o diagnóstico gratuito da Neryx é um bom ponto de partida.