Blog
RAGLLMAgentsKafkaKubernetes

Quby: RAG, agentes de texto e voz num único stack

·11 min de leitura

Este texto é nota de estudo, não material comercial. Descreve como montei e conectei o Quby, um laboratório multi-tenant de IA para atendimento: RAG (retrieval-augmented generation), agentes de texto em vários canais e agentes de voz para suporte ao vivo.

Onde testar (links do estudo):

  • Só agentes de voz: https://demo.quby.com.br — escolha um modelo no catálogo e inicie a chamada no navegador.
  • Landing do produto: https://quby.com.br — contexto comercial e formulário para demo completa da Quby.
  • Produto autenticado: app.quby.com.br — dashboard, upload de conhecimento e inbox multicanal.
O foco do estudo é prático: uma base de conhecimento por organização, um caminho de busca semântica reutilizado em todo lugar, e orquestração que mantém regras de negócio no backend enquanto o LLM cuida da linguagem.

O que o Quby tenta demonstrar

O Quby junta três ideias que costumam ficar em repositórios separados:

1. Respostas ancoradas — usar PDFs, tabelas de preço, FAQs e processos da empresa, não memória genérica do modelo. 2. Agentes com trilho — qualificação, handoff para humano e roteamento devem sobreviver a troca de modelo e de canal. 3. O mesmo “cérebro” no chat e na voz — WhatsApp, webchat, e-mail, SMS e telefone compartilham leads, histórico e RAG quando faz sentido.

A stack roda em Kubernetes: PostgreSQL guarda dados transacionais, histórico de conversas e embeddings pgvector para RAG. Apache Kafka no cluster leva trabalho assíncrono (follow-up, outbound, enriquecimento, eventos de integração) para não bloquear HTTP e voz. Clerk para auth multi-tenant; OpenAI para embeddings e chat. Voz com Vapi e as mesmas tools de RAG do texto. Observabilidade com New Relic e Datadog (traces, métricas e visibilidade de webhooks e workers).

Arquitetura em uma visão

Canais (webchat, worker WhatsApp, e-mail, SMS, voz Vapi)
        │
        ▼
Route handlers / webhooks  ──►  conversations + messages (PostgreSQL)
        │
        ├── caminho sync: /api/ai/process (orquestrador)
        │      ├── máquina de estados
        │      ├── OpenAI Assistants opcional por org
        │      ├── RAG: buildKnowledgeContextBlock → prompt
        │      └── handoff / roteamento
        │
        └── caminho async: publicação no Kafka (Kubernetes)
               ├── follow-up e nurture
               ├── dispatch SMS / WhatsApp / e-mail
               └── enriquecimento e integrações
        │
        ▼
Leads, orçamentos, inbox (dashboard)
        │
        ▼
New Relic + Datadog (traces, métricas, latência de webhook)

Multi-tenancy: tudo escopado por organization_id. Chunks, assistentes e credenciais de canal são por org. Isso torna o estudo um padrão reutilizável, não um chatbot single-tenant.

RAG: ingestão, índice, recuperação

O módulo (lib/org-knowledge.ts) é pequeno e explícito.

Ingestão

  • Upload de PDF, Markdown ou texto via POST /api/knowledge/upload.
  • PDF no servidor com unpdf (evita APIs de PDF que exigem DOM em serverless).
  • Texto bruto em org_knowledge_documents com status de indexação.

Chunks e embeddings

  • Chunks ~2,4k caracteres, corte em parágrafo, overlap ~200 caracteres.
  • Embeddings OpenAI text-embedding-3-small (1536 dimensões).
  • Vetores em org_knowledge_chunks.
  • Reindex apaga chunks antigos do documento (idempotente).

Busca

  • Query embedada com o mesmo modelo.
  • Busca por similaridade no PostgreSQL (pgvector + função SQL escopada, ex.: search_org_knowledge), com limiar padrão 0,55.
  • Hits com título, tipo de fonte, conteúdo e score.

Montagem do prompt

buildKnowledgeContextBlock vira bloco limitado de “fontes internas” usado no orquestrador, webchat do tenant, geração de orçamento, etc.

Lição do estudo: uma função de retrieval, vários consumidores.

Trabalho assíncrono no Kafka (Kubernetes)

Nem todo efeito colateral cabe na request que respondeu ao cliente. Follow-up estilo cron, outreach proativo e passos pesados de integração viram eventos no Kafka, consumidos por workers no mesmo cluster da API.

Padrão do estudo:

1. O caminho síncrono persiste intenção no PostgreSQL (lead, rascunho de orçamento, estado da conversa). 2. A API ou um scheduler publica no tópico (chave por org quando possível). 3. O consumer aplica com idempotência: outbound, webhook ERP, segunda passada de LLM, etc.

Webchat e tools Vapi ficam dentro de timeout apertado; o backlog escala nos consumers. Processamento at-least-once com retry no consumer.

Observabilidade (New Relic e Datadog)

Agentes quebram de forma banal: retrieval lento, cron duplicado, auth de webhook, lag no Kafka. O estudo usa New Relic e Datadog de forma complementar:

  • Traces em /api/ai/process, upload de conhecimento e tools Vapi (knowledge-search, ticket).
  • Métricas de lag, duração de batch de embedding e erro em tools de voz.
  • Logs correlacionados por organization_id e id de conversa quando a política permite.
Ferramentas não substituem log de domínio; expõem regressão ao mudar prompt, limiar de RAG ou topologia do broker.

Agentes de texto: máquina de estados + LLM

Deixar o modelo decidir o funil quebra CRM. O Quby inverte isso.

lib/conversation-state-machine.ts define perfis e estados (IDENTIFY_INTENT, COLLECT_BUDGET, CREATE_LEAD, HANDOFF_OR_CLOSE, …). O backend escolhe o próximo estado; o LLM redige o passo atual e usa RAG em perguntas de domínio.

POST /api/ai/process carrega estado, lead, blocos RAG e histórico cross-channel, decide handoff/roteamento e chama Chat Completions ou runOpenAIAssistantTurn quando a org usa Assistants.

Lição: agente aqui é fluxo com pele de LLM, não um prompt único fingindo ser CRM.

Agentes de voz: Vapi + mesmo RAG

POST /api/webhook/vapi recebe ciclo de vida da chamada.

A tool search_knowledge posta em POST /api/webhook/vapi/knowledge-search: autentica, resolve a org, chama searchOrgKnowledge, devolve texto curto para o modelo de voz resumir em uma ou duas frases. Schema em lib/vapi-knowledge-search-tool.ts.

POST /api/webhook/vapi/ticket cria lead (create_quby_lead) no mesmo pipeline do webchat.

Lição: voz não é outra base; é RAG como function call sob latência de telefone.

Catálogo público de voz (demo)

O estudo expõe um sandbox só de voz em demo.quby.com.br. A página testa apenas agentes de voz: selecione um modelo à esquerda, abra o painel de chamada e converse no browser. É o caminho mais rápido para sentir latência, tools e personas sem login no produto.

| Agente | Papel no estudo | |--------|------------------| | Atendimento (Bob) | Concessionária: vendas, locação, serviço e peças | | Status de frota | Operação interna: coleta e atualização de status de ativos | | Renovação de locação (Bob) | Fluxo executivo: renovação e oferta de buyout do equipamento | | Prospecção ativa (Sarah) | Vendas proativa: qualificar lead e propor equipamento |

Para a plataforma completa (webchat, inbox, base de conhecimento, setup por org), a landing em quby.com.br leva ao formulário de demo comercial; a URL de voz acima fica propositalmente estreita para testar agentes isolados.

Inbox multicanal

| Canal | Entrada | Observação | |--------|---------|------------| | Webchat | stream + widget | RAG no site do cliente | | WhatsApp | worker + webhook | thread unificada | | E-mail | Gmail OAuth + push | mesmas conversas | | SMS | Twilio | número por org | | Voz | Vapi | tools RAG + lead |

lib/multichannel-ai-autoresponse.ts e lib/cross-channel-context.ts alinham autoresposta e histórico entre canais.

Operar o estudo com segurança

  • Segredos só no servidor.
  • Sem hit útil no RAG → oferecer retorno humano, não inventar.
  • Orçamento como rascunho; envio com revisão humana.
  • Busca sempre filtrada por organization_id no Postgres e no RAG.

O que testar nos demos

1. Voz: abra https://demo.quby.com.br, escolha Atendimento ou Prospecção ativa e pergunte algo que deveria acionar search_knowledge (preço, garantia, processo). 2. Produto completo: veja https://quby.com.br para posicionamento e formulário de demo guiada. 3. Operação: login em app.quby.com.br para subir PDFs na base da org e ver o mesmo RAG nos canais de texto da inbox.

Checks mentais:

  • Mesma fronteira de org no RAG, seja webchat ou chamada Vapi.
  • Criação de lead após qualificação na voz (create_quby_lead) alinhada ao funil do webchat, mesmo com UI diferente.

Encerramento

O Quby, neste estudo, é plataforma de laboratório para RAG, orquestração de agentes e tools de voz num stack multi-tenant. O núcleo é retrieval compartilhado, estado de funil determinístico e adaptadores de canal na mesma fronteira de org.

Para desenhar algo parecido, comece por searchOrgKnowledge e buildKnowledgeContextBlock como espinha dorsal; depois pendure chat, voz e orçamentos desse eixo.