A arquitetura moderna padrão de chatbot com base de conhecimento
A pesquisa tradicional em uma base de conhecimento retorna links; o usuário os lê. O RAG transforma isso em uma resposta conversacional única, com citações. Quando bem feito, os usuários obtêm respostas em 2 segundos, em vez de vasculhar 5 documentos. Quando mal feito, o chatbot alucina e seu CTO bane o projeto por um ano. Esta página mostra a diferença.
A stack mínima viável para produção
- Armazenamento vetorial: pgvector se você já usa Postgres, Pinecone ou Qdrant para uma opção gerenciada
- Embeddings: text-embedding-3-large, chamado diretamente na OpenAI — a Kunavo não oferece embeddings, e a chamada de embedding é uma requisição separada da chamada de geração de qualquer forma
- Recuperação: híbrida (vetorial + BM25 com fusão recíproca de ranking)
- Geração: Claude Sonnet 5 com cache_control no prompt do sistema
- Interface: respostas em streaming, renderização de citações, fallback "Eu não sei"
from openai import OpenAI
client = OpenAI(api_key="sk-kn-...", base_url="https://api.kunavo.com/v1")
def chat(question: str, history: list[dict]) -> dict:
chunks = hybrid_retrieve(question, k=5) # vector + BM25
context = "\n\n---\n\n".join(
f"[doc:{c['id']}] {c['text']}" for c in chunks
)
resp = client.chat.completions.create(
model="claude-sonnet-5",
messages=[
{"role": "system", "content": [{
"type": "text",
"text": (
"Answer only from Context. Cite [doc:N] for each claim. "
"If Context doesn't answer, say 'I don't have that.' "
"Be concise, no throat-clearing."
),
"cache_control": {"type": "ephemeral"},
}]},
*history,
{"role": "user", "content": f"# Context\n{context}\n\n# Q\n{question}"},
],
max_tokens=600,
)
answer = resp.choices[0].message.content
cited_ids = parse_citations(answer) # extract [doc:N] references
return {"answer": answer, "sources": [c for c in chunks if c["id"] in cited_ids]}Custo em escala de produção
- Indexação inicial: ~US$ 0,25 para 5.000 documentos de 500 tokens cada
- 1.000 consultas/dia: ~US$ 210/mês com cache
- 10.000 consultas/dia: ~US$ 2.100/mês
- Usando Haiku 4.5 em vez de Sonnet: ~4 vezes mais barato, ~85% da qualidade das respostas
Veja a análise arquitetural completa no guia de implementação de RAG. Observações de ajuste específicas por idioma no aprofundamento sobre RAG em japonês e no guia de RAG em espanhol.
Os três padrões que realmente evitam alucinações
- Cite toda afirmação: tags
[doc:42]na saída do modelo. Se o id citado não estiver no conjunto recuperado, o modelo alucinou — bloqueie e registre - Recusa explícita no prompt do sistema: "Se o Contexto não responder, diga 'Eu não tenho essa informação.'" Sem isso, o modelo preenche a resposta com conhecimento geral
- Limite de saída de 600 tokens: respostas curtas geralmente são respostas precisas. É nas saídas mais longas que surgem invenções extras
O que lançar na semana 1 versus na semana 4
| Semana | Marco |
|---|---|
| 1 | 100 documentos, uma única estratégia de segmentação, pesquisa vetorial básica, conjunto de avaliação com 10 perguntas, ~70% de recall@5 |
| 2 | Corpus completo, recuperação híbrida, conjunto de avaliação com 100 perguntas, citações obrigatórias, beta interno |
| 3 | Ajuste a segmentação com base nas perguntas que falharam, lance para usuários internos, meça o CSAT |
| 4 | Monitoramento + painel de custos, limite diário de gastos, beta público ou lançamento em produção |
Comece em /app/signup
Uma recarga de US$ 10 cobre a indexação inicial de ~100 mil documentos e 1.500 consultas de teste — mais que suficiente para um protótipo funcional, e o saldo nunca expira. Depois, leia o guia completo de RAG para conhecer os padrões de produção.
Perguntas frequentes
Quanto custa uma consulta a um chatbot RAG?
Cerca de US$ 0,007 por consulta com Claude Sonnet 4.6 e cache de prompts ativo, ou cerca de US$ 0,001 com Claude Haiku 4.5 — que oferece aproximadamente 85% da qualidade por um sétimo do custo.
Como evitar que um chatbot RAG tenha alucinações?
Três medidas resolvem a maior parte do problema: exigir que o modelo cite um ID [doc:N] para cada afirmação, incluir uma instrução explícita de recusa no prompt do sistema e limitar a resposta com max_tokens=600. Depois, verifique se cada ID citado está no conjunto recuperado antes de exibir a resposta.
Qual deve ser o tamanho dos trechos em um índice RAG?
De 1.000 a 1.500 caracteres por trecho, com sobreposição de 100 a 200 caracteres; divida com RecursiveCharacterTextSplitter e gere embeddings com text-embedding-3-large.
A busca vetorial sozinha é suficiente para a recuperação RAG?
Não. A recuperação híbrida combina similaridade vetorial com busca por palavras-chave BM25 e mescla os resultados com fusão recíproca de posições, selecionando os 5 principais trechos.