Conteúdo detalhado
📄 Fontes de conhecimento
Antes de "plugar RAG", saiba o que vai plugar. Conteúdo se divide em estruturado (CSV, SQL, API) e não-estruturado (FAQ, PDF, página). Cada tipo exige tratamento diferente.
✓ Estruturado — direto via tool
- ✓Catálogo de produtos em CSV
- ✓Tabela de preços em SQL
- ✓Endpoint REST de estoque
- ✓Calendário de horários
- ✓Dados de cliente no CRM
✗ Não-estruturado — via RAG
- ✗FAQ em página HTML
- ✗Política de devolução em PDF
- ✗Manual técnico em Markdown
- ✗Base de conhecimento Notion/Confluence
- ✗Glossário corporativo
✂️ Chunking e embeddings
RAG depende de quebrar documentos em pedaços pequenos (chunks) e converter cada um em vetor (embedding) para busca semântica. Chunk errado = recall ruim = bot que diz "não sei" sobre coisa que está na base.
Pequeno demais perde contexto, grande demais perde precisão.
Sobreposição entre chunks evita cortar conceito ao meio.
Quebrar por H2/H3 vence quebra cega por tamanho.
Cada chunk com source, date, section, version.
💡 Embeddings
Reembede tudo quando trocar de modelo de embedding. Misturar embeddings de dois modelos diferentes na mesma collection gera busca aleatória.
🔍 RAG na prática
RAG = buscar os k pedaços mais relevantes, injetar no prompt, deixar o modelo responder com base neles (e citar a fonte). Soa simples, mas tem armadilha em cada etapa.
1. Embed da query
Pergunta do usuário vira vetor com o mesmo modelo dos chunks.
2. Busca top-k
Vector store devolve os k chunks mais próximos (k=5 é bom default).
3. Reranking (opcional)
Modelo menor reordena os k por relevância real. Aumenta precisão.
4. Injeção no prompt
Chunks entram em bloco marcado "[CONHECIMENTO]". Modelo cita.
5. Geração com citação
Resposta inclui referência ao chunk usado. Auditável.
🛠️ Declarar tools
Tool = nome + descrição + schema. O modelo nunca vê o código — só o contrato. Descrição ruim = tool ignorada. Schema ruim = parâmetros errados.
{
"name": "buscar_imoveis",
"description": "Busca imóveis disponíveis para venda ou aluguel
no catálogo da Vivenda. Use sempre que o usuário
pedir lista de opções por região, faixa de preço
ou número de quartos.",
"parameters": {
"type": "object",
"properties": {
"cidade": {"type": "string", "description": "Ex: São Paulo"},
"bairro": {"type": "string"},
"quartos": {"type": "integer", "minimum": 1},
"max_preco": {"type": "number"},
"finalidade": {"type": "string", "enum": ["venda", "aluguel"]}
},
"required": ["cidade", "finalidade"]
}
}
⚠️ Schema e backend juntos
Schema é contrato. Modelo respeita. Se você marca um campo como required, garanta que o backend trata erro quando vier vazio — porque algum dia vai vir.
🎯 Quando tool, quando RAG
A regra é simples mas é a que mais se erra: RAG para texto estático e relativamente raro de mudar; tool para dado dinâmico ou ação. Misturar mal aumenta latência e custo sem ganho.
✓ RAG
- ✓Política de devolução
- ✓Manual de uso do produto
- ✓Lista de perguntas frequentes
- ✓Glossário e termos do negócio
- ✓Documentação técnica
✗ Tool
- ✗Preço atual de produto
- ✗Estoque em tempo real
- ✗Horários disponíveis
- ✗Status de pedido
- ✗Qualquer escrita (criar, atualizar, cancelar)
🧯 Tratamento de erro
Tool vai falhar. Timeout, 500, parâmetro inválido, ratelimit. A pergunta não é "se", é "como". Tool que falha silenciosa vira agente que mente.
[Tool error]
{
"error": true,
"code": "TIMEOUT",
"message": "Catálogo demorou mais que 5s para responder. Tente novamente.",
"retryable": true
}
// Modelo lê e decide:
// - Pode tentar de novo (1x).
// - Se falhar de novo: "Marina, nosso catálogo está lento agora.
// Posso te avisar em alguns minutos quando voltar?"
💡 Sanitize errors
Nunca devolva ao modelo o erro cru do banco/API. Vire SQL exception em "banco indisponível". Vire 500 em "sistema com problema". Modelo não precisa do stack trace — e logar ele em log do LLM é vazamento.
📌 Resumo do módulo
Próximo:
2.3 — 🎫 Custom fields e contexto do cliente