Esta página descreve a infraestrutura comum aos agentes. O papel de cada agente está em [Agentes de IA — funil comercial](ia/agentes-comerciais), em [Agentes de IA — contrato, entrega e carteira](ia/agentes-entrega) e em [Organization Intelligence](ia/organization-intelligence) (perfil, auditoria, Health Score, Delivery Advisor e Customer Success).
Fila de agentes
Arquivo: src/fila.ts. Executor: src/agentes.ts.
- Mensagem: todo gatilho vira
{agente, alvo: {tipo, id}, origem, opcoes?, depois?, tentativa?, organizacao_id?, request_id?}. O alvo pode serlead,cliente,oportunidade,contrato,escopo,mudancaouorganizacao. - Agentes que a fila conhece (
NomeAgente):site,resumo,proxima_acao,estrategia,embedding,risco,expansao,escopo,perfil,auditoria,saude,entrega,sucesso,fonte_analista(AI Source Analyzer, ADR-0015) ewebhook_entrada(payload de webhook de provedor guardado na fila antes do 200 ao provedor; o consumidor roda o parser e o pipeline de entrada — ADR-0015). - Os demais agentes são chamados direto pelas rotas: SDR, rascunho, detalhamento, reunião, briefing, contrato, validador, mudança, relatório, Copiloto, o agente de perfil do onboarding e os do Knowledge Center.
- Registro:
HANDLERSemagentes.tsliga cada nome a uma função.riscodecide pelo alvo: cliente vai paraavaliarRiscoCliente; lead vai para a próxima ação.escopocom um contrato do tipo aditivo aplica a mudança (aplicarPorAditivo) em vez de gerar escopo.auditoria(Organization Auditor),saude(Health Score),entrega(Delivery Advisor, só alvo escopo) esucesso(Customer Success, só alvo cliente) engolem o próprio erro com log: são opcionais e o cron refaz.perfilestá declarado sem efeito (só log) — o agente de perfil roda direto no onboarding. - **Despacho (
despachar):** - com o binding
FILA(Cloudflare Queue), a mensagem é enfileirada e a requisição volta na hora; - sem o binding, a mensagem roda no
waitUntilda própria requisição (processar).
A fila está ligada desde 26/09/2026 (Workers Paid; queues em wrangler.jsonc: Queue radar-agentes, lote de até 5, 3 entregas). Se o envio para a fila falha, a mensagem roda inline no waitUntil (log fila.envio_falhou). Sem o binding (desenvolvimento, testes), tudo roda inline.
- **Consumidor (
consumirLote):** executa, dáacke encadeia o próximo agente dedepois(enfileirado com a mesmaorganizacao_id; se a fila recusar, roda ali mesmo). A tentativa é contada porattemptsda entrega. Erro fazretryaté a 3ª entrega; na 3ª,ackcom log e soma ao contador de mensagens mortas em KV, que o alerta de operação lê (dead-letter por log, para não travar a fila). - Organização e rastreio:
despacharcarimba aorganizacao_ide orequest_iddo contexto atual na mensagem;processarreentra na organização (comOrg) e o consumidor norequest_idde origem (comRequisicao), para os logs do consumidor se ligarem aos da requisição.
Cadeias (CADEIAS)
| Gatilho | Agente | Depois | Quem dispara hoje |
|---|---|---|---|
handoff | site | embedding, resumo, proxima_acao | Agente SDR, no handoff ou no encerramento da Triagem |
fechado | embedding | — | Conversão do lead em cliente |
convertido | risco | sucesso | Conversão (alvo: cliente): risco e plano de sucesso do cliente novo |
cliente_movimento | risco | — | Nota, oportunidade aberta ou tarefa concluída no Cliente 360 |
assinado | escopo | auditoria | Último signatário na assinatura Radar (/c/:token/assinar) e conclusão pela Clicksign; o contrato novo é evidência para o Organization Auditor |
escopo_concluido | expansao | — | Encerramento do projeto em /radar/escopo/:id |
escopo_movimento | entrega | — | Etapa do escopo movida em /radar/escopo/:id (item, concluir, adicionar, status, datas) |
onboarding_publicado | saude | auditoria | Perfil publicado pelo onboarding (alvo: organização) |
fonte_alterada | auditoria | saude | Fonte da organização (site, redes) relida com conteúdo diferente no onboarding |
catalogo_editado | auditoria | — | Edição do catálogo em /radar/catalogo |
detalhamento_fechado | proxima_acao | — | Fechamento da etapa 2 (POST /d/:codigo/fechar), com forcar e origem detalhamento |
abertura | proxima_acao | — | Abertura da Pré-proposta (/p) e da Proposta (/pp, origem proposta_aberta); respeita o intervalo mínimo |
Toda cadeia declarada tem quem a dispare, e test/fila.test.ts confere isso no código-fonte. A próxima ação continua síncrona onde o resultado é usado na hora:
- reunião registrada ou marcada: o Consultor volta à página esperando a ação nova;
- cron de silêncio: o e-mail leva a sugestão;
- botão do Consultor.
Por isso não há cadeias reuniao_registrada nem silencio. Os demais gatilhos avulsos (aceite pelo lead, WhatsApp, webhooks do Resend, formulário de contato) também chamam gerarProximaAcao direto.
O botão "reler" da expansão no 360 despacha uma mensagem avulsa (agente: 'expansao', sem cadeia).
Crons
Os crons rodam por executarCron em src/cron.ts (o scheduled() de src/index.ts só delega; o "Rodar agora" de /radar/plataforma chama a mesma função), uma vez por organização ativa (paraCadaOrganizacao), cada uma no seu contexto. Detalhes de operação (marcadores, alertas, recuperação) em [Infraestrutura](tecnica/infraestrutura).
0 * * * *: silêncio de 48 h, que gera a próxima ação dos leads parados; depois, os alertas de operação e a recuperação de um diário ou semanal que não rodou (eventocron_recuperado).0 11 * * MON-FRI(8h em Brasília, dias úteis): aviso de fim do teste → risco dos clientes → escalação de etapas atrasadas → Health Score → Delivery Advisor (rodarEntregas) → auditoria por 20 conversas novas do SDR → digest.30 11 * * MON(segunda, 8h30): Organization Auditor → Customer Success (rodarSucessos) → expansão (até 30 clientes) → relatório semanal.
Esqueleto comum: executarAnalise
Arquivo: src/agentes.ts. Usam o esqueleto o risco do cliente (ANALISE_RISCO_CLIENTE), a expansão (ANALISE_EXPANSAO), o Delivery Advisor (ANALISE_ENTREGA, alvo escopo, evento entrega_sugerida) e o Customer Success (ANALISE_SUCESSO, alvo cliente, evento sucesso_plano). Os agentes mais antigos (site, resumo, estratégia, reunião, detalhamento, próxima ação, briefing) e o Organization Auditor (tipo auditoria, alvo organização) repetem o mesmo padrão à mão. Contrato, escopo e mudança gravam nas próprias tabelas.
O fluxo tem sete passos:
- Entrada:
entrada(env, alvoId)monta o system prompt, a mensagem do usuário e achaveHash. Devolvernullsignifica "nada a analisar". - Hash: SHA-256 de
{v: versao, k: chaveHash}. A chave contém só o que muda a resposta: ids de eventos, status, datas. O risco do cliente não inclui a data: o passar do tempo entra pelas regras calculadas na hora (chave e nível). A expansão inclui o mês. Os agentes que leem o perfil da Organização põem a versão dele na chave, e os que leem um documento funcional, a versão do documento (versaoDocumental). - Cache: se já existe uma linha em
analises_iapara o mesmo alvo, tipo ehash_entrada, ela é devolvida sem chamar o modelo. Comforcar, o hash é gravado com o sufixo:timestampe não serve de cache depois. - Chamada:
chamarClaudecom o modelo,maxTokensethinkingdo agente, rótulo = tipo. O custo vai paraia_chamadas. - Validação em código:
interpretar(texto)devolve o objeto tipado ounull. O código nunca confia no texto: vocabulários fechados, tamanhos cortados, ids conferidos. - Fallback: sem saída válida, roda
regra(env, alvoId), a versão determinística. A linha é gravada commodelo: 'regra'e sem custo. - Gravação: grava em
analises_ia(comalvo_tipo/alvo_id, elead_idquando há lead de origem), registra o evento<tipo>_gerado(regra,custo_usd) e rodaaplicar, se houver. A expansão, por exemplo, reprecifica e reescreve o conteúdo emaplicar.
Modelos, preços e limite
Arquivo: src/claude.ts.
- Modelos:
MODELO = 'claude-sonnet-5'é o padrão.MODELO_PROXIMA_ACAO = 'claude-opus-5'serve a próxima ação e a expansão;MODELO_ESTRATEGIA = 'claude-opus-5'serve a estratégia;MODELO_AUDITOR = 'claude-opus-5'(src/perfil/auditor.ts) serve o Organization Auditor.MODELO_COPILOTO = MODELO. Os embeddings usamMODELO_EMBEDDING = 'voyage-3.5'(src/embeddings.ts). - **Preços (US$ por milhão de tokens), em
PRECOS_USD_POR_MTOK:** - Sonnet 5: entrada 2, saída 10, leitura de cache 0,2, escrita de cache 2,5.
- Opus 5: entrada 5, saída 25, leitura de cache 0,5, escrita de cache 6,25.
Um modelo desconhecido é cobrado pelo preço de MODELO.
- Cliente e cache: um cliente do SDK oficial por requisição (
maxRetries: 2,timeout: 90 s). Todas as chamadas usam cache de prompt efêmero no system e no prefixo.thinking: 'disabled'é usado em saídas curtas em JSON. - Custo:
registrarChamadaIAgrava uma linha emia_chamadas(rótulo, modelo, tokens de entrada, saída e cache, US$,lead_id/conversa_id) e soma ao cache de uso do mês da Organização. Todos os agentes registram, inclusive o resumo e o relatório semanal (desde 25/09/2026). - Limite mensal por Organização: a porta única é
iaBloqueada(env, rotulo), que conferelimiteIaAtingidoquando há Organização no contexto.chamarClaudea chama antes de cada chamada. O Agente SDR e o Copiloto montam a chamada no SDK (cliente(), por causa do tool use) e chamamiaBloqueadaantes. O teto éorganizacoes.limite_ia_usd_mesou, sem ele, a IA incluída no Plano (planos.ts; o plano interno não tem limite). O uso é somado deia_chamadasdesde o dia 1º, em horário de Brasília, com cache de 5 min. Atingido o teto, o modelo não é chamado e o eventolimite_ia_atingidoé registrado (com o rótulo de quem pediu). O que acontece depois depende do chamador: - quem usa
chamarClaudecai no fallback; - o SDR oferece ao visitante o formulário de contato e faz o Handoff (motivo
limite_ia); - o Copiloto avisa o Consultor e não guarda a pergunta.
- Cache de narrativas: o briefing da Home (alvo
usuario) e o relatório semanal (alvoorganizacao) guardam o texto emanalises_iapor hash da entrada. Reabrir a Home ou a prévia/radar/relatoriocom os mesmos dados não chama o modelo. - Gating por plano: é diferente do limite. O Copiloto só funciona a partir do Plano Profissional (402 abaixo dele).
Memória
| Onde | O que guarda | Validade e reaproveitamento |
|---|---|---|
analises_ia | Saída de cada análise por alvo (lead_id ou alvo_tipo/alvo_id) e tipo: site, resumo, estrategia, detalhamento, reuniao, risco (do lead, vindo da próxima ação), risco_cliente, expansao, entrega (alvo escopo), sucesso (alvo cliente), auditoria (alvo organizacao), briefing (alvo usuario), relatorio (alvo organizacao). Também grava modelo, versao_prompt, hash_entrada, tokens e custo_usd. | Cache por hash de entrada. Os leitores pegam a mais recente (order=id.desc). O histórico fica. |
recomendacoes_ia | Próxima ação do lead: ação, título, porquê, urgência, assunto, rascunho, alternativa, confiança, modelo, versão, hash, custo e o desfecho (status, motivo, resolvida_por, resolvida_em). | Uma pendente por lead; a nova expira as anteriores (expirada). O desfecho (executada, editada, dispensada) é o dado de treino. |
copiloto_conversas | Conversa do Consultor com o Copiloto: mensagens (com tool use), ações pendentes, auditoria das decisões, número de chamadas, custo. | Uma conversa ativa por usuário; expira_em padrão de 7 dias (migração 0015). O histórico é cortado para as últimas 60 mensagens. |
conversas | Transcrição da Triagem do Agente SDR (com os blocos tool_use/tool_result). | Uma por sessão do widget. Lida pelo resumo, pela próxima ação, pela estratégia, pelo rascunho e pelo detalhamento. |
ia_chamadas | Uma linha por chamada ao modelo: rótulo, modelo, tokens, cache, US$. | Base do custo por lead e por Organização e do limite mensal. |
Além delas, o perfil de IA da Organização (organizacao_perfil_ia, lido por contextoOrganizacional com cache de 1 min) entra no system prompt de quase todos os agentes; ver [Agentes de IA — funil comercial](ia/agentes-comerciais) e [Organization Intelligence](ia/organization-intelligence).
A memória de cada agente é montada a cada chamada a partir dessas tabelas e das de negócio (eventos, notas, tarefas, propostas). Nenhum agente guarda estado próprio fora delas.
Vetores (leads parecidos)
Arquivo: src/embeddings.ts. Tabela lead_embeddings. Função SQL leads_parecidos (pgvector, migração 0011).
- **Texto do lead (
textoDoLead): setor, dor, momento, porte, ferramentas, urgência e orçamento, até 2.000 caracteres. Sem nome nem e-mail.** - Vetor: Voyage AI (
voyage-3.5, 1024 dimensões,input_type: document), timeout de 15 s. É idempotente pelo texto: o mesmo texto não gera nova chamada. - Quando indexa:
- o agente
embeddingnacadeia:handoffe nacadeia:fechado; - a mudança do estágio para
ganhoouperdidona página do lead; mudar_estagioparaperdidopelo Copiloto.- Busca:
parecidosSemanticosprocura vizinhos entre os leadsganho/perdido, por distância de cosseno, com similaridade mínima de 0,55 e até 3 resultados.parecidosDoLead(src/parecidos.ts) usa esse resultado quando existe e, sem ele, a regra por setor, momento e porte. A estratégia usa só a regra. - **Sem
VOYAGE_API_KEYou sem a migração:** tudo devolvenulle a Radhr AI segue pela regra. - Isolamento: a função SQL
leads_parecidossó procura vizinhos da organização do lead-alvo (migração 0024). O RLS não protegeria aqui, porque o Worker usa a service key.parecidosDoLeadsegue como segunda barreira: só aceita ids presentes na lista de fechados da Organização atual.
Contexto por organização
Arquivo: src/org-contexto.ts.
- Como funciona: um
AsyncLocalStorage(flagnodejs_compat) guarda a organização da execução.orgAtual()devolve o id ounullfora de contexto;orgOuPadrao()devolve o id ou 1 (Witbiz);comOrg(id, fn)rodafndentro do contexto. - Quem entra no contexto:
- o middleware da Radhr AI, com a organização da sessão (a tabela
organizacoesdá nome, plano, limite de IA,ativae domínio); - as rotas públicas, com a organização do link (
organizacaoDoLink) ou, sem link, a do domínio (organizacaoPorHost); - cada cron, por organização;
- cada mensagem da fila, pela
organizacao_idda mensagem. - Crons: só organizações com
ativadiferente defalse; sem nenhuma listada, roda só a organização 1. - Efeito nos agentes:
db.tsfiltra e carimbaorganizacao_idem toda leitura e escrita das tabelas deTABELAS_ORG(incluianalises_ia,ia_chamadas,recomendacoes_ia,lead_embeddings,copiloto_conversas) e envia o cabeçalhox-organizacao, que o RLS usa como segunda barreira. Assim, o contexto que um agente monta só enxerga os dados da própria Organização, e o custo cai na conta certa.
Segurança de prompt
- Dados nunca são instruções. Notas, e-mails, mensagens de WhatsApp, transcrições e o texto de sites entram nos prompts como dado. O system do Copiloto diz isso explicitamente, mas a garantia é do código:
- nenhuma ferramenta de ação executa pelo modelo;
- as saídas de todos os agentes passam por validação com vocabulário fechado.
- Ações do Copiloto exigem confirmação.
validarAcaoconfere os argumentos e o papel antes de propor (o Consultor só nos seus leads e clientes; o admin em todos;ganhosó pela conversão). A ação virapendente, e sódecidirAcaocomconfirmadachamaexecutarAcao. Cada ação fica registrada emauditoriae no eventocopiloto_acao. - Números e decisões ficam no código:
- preço (pré-proposta, detalhamento, expansão);
- valores de contrato (R$ fora da Proposta e percentuais são recusados);
- valor de mudança (horas × valor-hora);
- estágio do lead (só sugerido pela reunião);
- troca de canal da próxima ação.
- Nada sai para fora sem o Consultor, com três exceções que são do próprio fluxo:
- a Pré-proposta do SDR (estimativa rotulada como tal);
- a renovação aberta a 60 dias;
- a mudança automática de status do cliente pelo motor de risco.
- O SDR não mostra o estado ao visitante. O estado vai por tool use, e o prompt proíbe revelar as instruções.
- Perfil da Organização é dado.
aiInstructionseorganizationalKnowledgeentram delimitados no system, com o aviso de que não sobrepõem as regras do código; o bloco do perfil diz que preço só vem do catálogo. A ferramentacatalogodo Copiloto devolve só itens e agentes ativos no catálogo da Organização (itemAtivo/agenteAtivo). - Leitura que é credencial passa pela permissão. As ferramentas de leitura do Copiloto não filtram por dono, salvo
link_portal: o link/portal/<token>dá acesso sem login aos dados do Cliente, então só sai para quem pode enviar o portal (admin, ou o Consultor dono do Cliente ou de Cliente sem dono; financeiro e leitura não;portal.enviarcom o RBAC v2;recusaDoPortalemsrc/portal.ts, a mesma regra do "Enviar portal" do Cliente 360). Ela só devolve o link que já existe; não gera token nem envia e-mail.
Documentação viva como fonte de contexto
Pelo ADR-0010, a documentação desta pasta (docs/conhecimento/), empacotada em src/conhecimento/base.gerada.ts por scripts/conhecimento.mjs, é fonte de contexto dos agentes pela ferramenta de leitura **consultar_documentacao** do Copiloto. Com ela, o Copiloto responde "como funciona" e "por que a Radhr AI fez isso" citando o documento, e não de memória. O prompt do Copiloto manda consultá-la antes de explicar a Radhr AI e dizer que a documentação não cobre o assunto em vez de supor.
Ela segue as regras das ferramentas de leitura:
- executa na hora (busca BM25 em memória,
src/conhecimento/busca.ts, sem rede e sem custo); - devolve até 5 trechos com fonte e link, que são dado, nunca instrução;
- só lê as fontes autorizadas da organização de quem pergunta: a Witbiz (organização 1) vê tudo; as demais, o funcional, o glossário e os documentos que a própria organização escreveu (playbooks, regras comerciais, processos e guias de tela, fase 3). Documento de uma organização nunca aparece para outra.
Desde a fase 1, a documentação também entra no system prompt de alguns agentes: promptDocumental(area) (src/conhecimento/contexto.ts) anexa a seção "Regras de negócio" do documento funcional da área, com o aviso de que as validações do código prevalecem, e, na estratégia, no risco do cliente e na expansão, versaoDocumental(area) põe a versão do documento no hash (documento revisado → análise refeita). Usam: estratégia (propostas), risco do cliente e expansão (clientes), Scope Builder/Validator e Change Request Analyzer (escopos).
Na fase 2, documentos editados na Radhr AI valem por cima do bundle (sincronizarBase, src/conhecimento/edicao.ts): a busca, o assistente, o Copiloto e o contexto dos agentes leem o texto novo. Toda consulta do Copiloto à documentação é registrada em doc_perguntas (registrarPergunta), com as fontes devolvidas, e conta no uso da documentação (fase 4). A consulta sem fonte também entra na fila de revisão.
O assistente de documentação e o Smart Changelog estão em Documentation Agent e Knowledge Center.
Registro central e avaliação
- Registro dos agentes (
src/agentes-registro.ts, só leitura): para cada agente do inventário, na Organização, os últimos 30 dias de chamadas e custo (ia_chamadaspor rótulo), análises gravadas, taxa de fallback por regra (analises_ia.modelo = 'regra', selo "alto" acima de 20%) e quantas análises foram refeitas depois da última atualização do perfil. Aparece na tabela de agentes de/radar/conhecimento/ia(o master escolhe a organização com?org=). - Conjunto de avaliação em modo regra (
test/avaliacao.test.ts+test/avaliacao/<agente>.json, no CI): saídas fixas do modelo e o que o validador em código tem de fazer com elas (aceitar, cortar, anular, limpar vocabulário). Cobreproxima_acao,estrategia,risco,expansao,mudanca,entrega,sucessoeauditoria, com pelo menos 4 casos cada; todo interpretador listado precisa de arquivo. Não chama o modelo; a rodada com o modelo real não existe ainda.