agent-sdr
Especificação completa do agente SDR (Sales Development Representative).
Resumo executivo
Qualifica leads inbound via WhatsApp usando frameworks estruturados (BANT/GPCT/MEDDIC), captura dados ricos no CRM e agenda reunião com vendedor humano apenas para leads qualificados. Elimina o gargalo de triagem manual em operações com volume alto de inbound.
Mercado e ICP
Setores ideais
- B2B em geral (software, consultoria, serviços)
- Infoprodutos com ticket > R$ 500
- Saúde particular (clínicas, terapeutas)
- Imóveis (compra e locação)
- Educação privada
- Serviços profissionais (advocacia, contabilidade, arquitetura)
Porte do cliente
- Pequenas empresas: 50-200 leads/mês, time pequeno que não dá conta
- Médias empresas: 200-2.000 leads/mês, time existe mas é caro
- Grandes: 2.000+ leads/mês, automação é estratégica
Cliente NÃO ideal
- Empresas com volume baixo (< 30 leads/mês não justifica)
- Vendas que dependem 100% de relacionamento humano (advocacia premium, M&A)
- Produtos commoditizados sem qualificação necessária
Ticket que justifica
- Mínimo R$ 1.500 por venda (abaixo, custo do agente não compensa)
- Ideal: R$ 5.000+
- Alto valor: R$ 50.000+ (aí o agente paga seu custo em 1-2 reuniões)
Casos de uso típicos
Caso 1: Clínica de emagrecimento (USA Salus)
- Lead vê anúncio Meta Ads sobre programa premium
- Clica em “Saber mais” → vai para WhatsApp
- agent-sdr inicia conversa, descobre dor (peso, prazo, urgência)
- Identifica fit, agenda consulta inicial com Dra
- Vendedor humano só vê leads já qualificados
Caso 2: Software B2B (TaskFlow)
- Empresa busca solução de gestão de projetos
- Preenche formulário no site
- agent-sdr qualifica via GPCT (Goals, Plans, Challenges, Timeline)
- Identifica decisores, dor, urgência
- Agenda discovery call com AE
Caso 3: Curso online (Reverso Academy)
- Lead chega via webinar/lead magnet
- agent-sdr qualifica perfil do aluno (objetivo, momento de carreira)
- Identifica produto adequado (entry level vs premium)
- Encaminha para vendedor com contexto completo
Caso 4: Imobiliária
- Lead vê anúncio de imóvel
- agent-sdr descobre: comprar ou alugar, faixa de preço, prazo, financiamento
- Agenda visita com corretor responsável pela região
Estrutura específica do código
Arquivos que MUDAM em relação ao template
agent-sdr/├── src/│ ├── prompts/│ │ ├── system_base.md ← ESPECÍFICO: prompt de SDR│ │ └── fragments/│ │ ├── bant.md ← ESPECÍFICO: como aplicar BANT│ │ ├── gpct.md ← ESPECÍFICO: GPCT alternativo│ │ └── agendamento.md ← ESPECÍFICO: como agendar│ ││ ├── tools/│ │ ├── qualificar_lead.py ← ESPECÍFICO│ │ ├── agendar_reuniao.py ← ESPECÍFICO│ │ ├── enviar_material.py ← ESPECÍFICO│ │ └── consultar_disponibilidade.py ← ESPECÍFICO│ ││ ├── flows/│ │ ├── primeiro_contato.py ← ESPECÍFICO│ │ ├── qualificacao_bant.py ← ESPECÍFICO│ │ ├── apresentacao.py ← ESPECÍFICO│ │ └── agendamento.py ← ESPECÍFICO│ ││ └── config/│ └── default_config.yaml ← ESPECÍFICO: configs SDR│├── eval/│ └── datasets/│ └── casos_baseline.jsonl ← ESPECÍFICO: 30+ casos SDR│└── tenants/_template/ ├── config.yaml ← Tem seção qualificacao └── knowledge/ ├── empresa.md ├── produtos.md ← Importante para apresentação ├── icp.md ← Quem é o cliente ideal └── casos.md ← Casos de sucessoTools específicas
qualificar_lead
@toolasync def qualificar_lead( lead_id: str, necessidade: Optional[str] = None, prazo: Optional[str] = None, decisor: Optional[bool] = None, orcamento: Optional[str] = None, tenant: dict = None) -> str: """ Atualiza dados de qualificação no CRM. Pode ser chamada parcialmente (ex: só com necessidade) e atualizada conforme conversa progride.
Args: lead_id: ID do lead no CRM necessidade: Dor/objetivo principal prazo: Quando precisa resolver decisor: É decisor ou influenciador orcamento: Faixa de investimento """ crm = CRMFactory.create(tenant)
fields = {} if necessidade: fields["bant_necessidade"] = necessidade if prazo: fields["bant_prazo"] = prazo if decisor is not None: fields["bant_decisor"] = decisor if orcamento: fields["bant_orcamento"] = orcamento
if fields: await crm.update_lead(lead_id, custom_fields=fields)
# Verifica se está qualificado (todos campos preenchidos) lead = await crm.get_lead(lead_id) if all(lead.custom_fields.get(f"bant_{k}") for k in ["necessidade", "prazo", "decisor", "orcamento"]): await crm.move_to_stage(lead_id, "qualificado") return "Lead totalmente qualificado e movido para etapa 'qualificado'"
return f"Dados atualizados: {list(fields.keys())}"agendar_reuniao
@toolasync def agendar_reuniao( lead_id: str, data_hora_iso: str, duracao_minutos: int = 30, tenant: dict = None) -> str: """ Agenda reunião com consultor. Cria evento no Google Calendar e atualiza CRM com etapa 'reuniao_agendada'. """ consultor = tenant.qualificacao.agendamento.consultor_email calendar_id = tenant.qualificacao.agendamento.consultor_calendar_id
lead = await crm.get_lead(lead_id)
event = await google_calendar.create_event( calendar_id=calendar_id, title=f"Discovery — {lead.nome}", description=f"Lead qualificado via WhatsApp.\n\nDor: {lead.bant_necessidade}\nOrçamento: {lead.bant_orcamento}", start=data_hora_iso, duration_minutes=duracao_minutos, attendees=[lead.email] if lead.email else [] )
await crm.move_to_stage(lead_id, "reuniao_agendada")
return f"Reunião agendada para {data_hora_iso}. ID: {event.id}"enviar_material
@toolasync def enviar_material( tipo: Literal["case", "video_institucional", "depoimento", "comparativo"], contexto: str, tenant: dict = None) -> str: """ Envia material complementar ao lead. Busca no Qdrant material adequado ao contexto e envia via WhatsApp. """ rag = RAGRetriever(collection=tenant.rag.collection)
# Busca material adequado results = await rag.search( query=f"{tipo} relevante para: {contexto}", filter={"tipo": tipo}, top_k=1 )
if not results: return f"Nenhum material do tipo {tipo} encontrado"
material = results[0]
# Envia via provider (link ou mídia) provider = MessagingFactory.create(tenant) if material.metadata.get("media_url"): await provider.send_media(...) else: await provider.send_text(...)
return f"Material enviado: {material.title}"Flows específicos
flows/qualificacao_bant.py
"""Fluxo de qualificação BANT.Conduz coleta dos 4 pontos em até 5 mensagens."""class BANTFlow: PERGUNTAS = { "necessidade": [ "Qual é a principal dificuldade que você está enfrentando?", "O que te trouxe até aqui hoje?", "Que problema você está tentando resolver?", ], "prazo": [ "Em quanto tempo você precisa que isso esteja resolvido?", "Qual é a urgência? É algo pra agora ou pode esperar?", ], "decisor": [ "Você é quem decide ou outras pessoas estão envolvidas?", "Vocês têm um processo de decisão ou é direto contigo?", ], "orcamento": [ "Já existe um orçamento previsto para isso?", "Vocês têm uma faixa de investimento em mente?", ], }
def proxima_pergunta(self, state: AgentState) -> tuple[str, str] | None: """Retorna (campo, pergunta) ou None se completo.""" for campo in ["necessidade", "prazo", "decisor", "orcamento"]: if not state.custom_state.get(f"bant_{campo}"): # Escolhe pergunta variada (não repetir) ja_usadas = state.custom_state.get("perguntas_feitas", []) disponiveis = [p for p in self.PERGUNTAS[campo] if p not in ja_usadas] pergunta = random.choice(disponiveis or self.PERGUNTAS[campo]) return campo, pergunta return None
def is_qualified(self, state: AgentState) -> bool: """Critério de qualificação.""" bant = state.custom_state return ( bool(bant.get("bant_necessidade")) and bant.get("bant_prazo") in ["imediato", "30 dias", "60 dias", "90 dias"] and bant.get("bant_decisor") in [True, "decisor", "influenciador"] and bool(bant.get("bant_orcamento")) )System prompt template
# IdentidadeVocê é {{agente_nome}}, {{agente_cargo}} da {{nome_empresa}}.Atende leads via WhatsApp de forma {{tom}}.Nunca diz que é IA a menos que perguntem diretamente.
# Empresa{{empresa_descricao}}
Nosso cliente ideal: {{icp}}
# Seu objetivoQualificar o lead em 4-6 mensagens usando framework {{framework}} adaptado e, se for fit, agendar reunião com consultor humano.
# Como você atua1. Cumprimente e descubra o que motivou o contato2. Aprofunde a dor com 1-2 perguntas3. Colete BANT (necessidade, prazo, decisor, orçamento) ao longo da conversa4. Apresente brevemente como a empresa ajuda5. Identifique fit e ofereça reunião com consultor
# Suas ferramentas- **qualificar_lead**: atualiza CRM com BANT (use após cada resposta relevante)- **agendar_reuniao**: cria evento no calendar do consultor- **enviar_material**: envia case ou depoimento quando relevante- **handoff_humano**: transfere para humano se necessário
# Critério de qualificaçãoLead é qualificado quando:- Tem dor clara e articulada- Prazo é menor que 90 dias- É decisor OU influenciador forte- Tem orçamento alinhado
Se faltar algum desses, continue qualificando. Não force agendamento sem fit.
# Regras invioláveis{{include: fragments/regras_invioneis.md}}
# Quando transferir{{include: fragments/handoff.md}}
# Tom e estilo{{include: fragments/tom_{{tom}}.md}}Configuração default
# src/config/default_config.yaml para agent-sdr
agent_type: sdrdefault_model: claude-sonnet-4-7default_temperature: 0.7
qualification: framework: bant # bant | gpct | meddic max_messages: 5 required_fields: - dor - prazo - decisor - orcamento
perguntas_variantes: 3 # quantas alternativas por pergunta
agendamento: duracao_padrao_minutos: 30 buffer_minutos: 15 horarios_padrao: - "10:00-12:00" - "14:00-17:00"
rag: default_top_k: 3 default_threshold: 0.75
response: max_messages_per_minute: 15 delay_between_messages_ms: 2000 # SDR pode demorar mais (mais consultivo)
handoff: transferir_quando: - mensagens_sem_avancar: 3 - palavras_chave: ["cancelar", "não quero", "remover"] - cliente_irritado: trueKPIs e métricas
Métricas operacionais
| Métrica | Como medir | Meta |
|---|---|---|
| Taxa de qualificação completa | % leads que completaram BANT | > 60% |
| Taxa de agendamento | % qualificados que agendaram | > 70% |
| Tempo médio até agendamento | Horas entre 1ª msg e agendamento | < 24h |
| Show rate | % de reuniões que aconteceram | > 70% |
| Custo por reunião | Tokens consumidos / reuniões | Variável |
Métricas de qualidade
| Métrica | Como medir |
|---|---|
| Tom adequado | LLM-as-judge no Langfuse |
| Aderência ao framework | Verifica se BANT foi seguido |
| Mensagens por qualificação | Eficiência (menos = melhor) |
| Taxa de handoff | % conversas que viraram humano (médio = bom) |
Dataset de eval
Mínimo 30 casos cobrindo:
- Easy (10 casos): lead motivado e claro
- Medium (10 casos): lead com objeções leves
- Hard (10 casos): lead frio, com dúvidas, hesitante
Exemplo de caso:
{ "id": "sdr_001", "tier": "easy", "input": { "history": [], "message": "Oi, vi anúncio sobre programa premium, queria saber mais" }, "expected": { "must_call_tool": null, "must_ask_about": ["motivação", "dor", "necessidade"], "must_not_include": ["preço explícito", "agendamento direto"], "tone": "consultivo", "max_words": 50 }}Pricing sugerido
| Item | Faixa |
|---|---|
| Setup único | R$ 4.000 a R$ 6.000 |
| Mensalidade | R$ 1.200 a R$ 2.000 |
| Volume API | Pass-through Claude + 30% |
Justificativa do pricing
- Setup cobre: configuração, knowledge base, prompts customizados, integração CRM, calendar, primeiro mês de calibração
- Mensalidade cobre: hosting, observabilidade, ajustes mensais, suporte
- Margem alvo: 65-70% considerando custos de API e infra
Tempo de implementação
| Fase | Duração |
|---|---|
| Briefing e coleta de dados | 3 dias |
| Configuração técnica (config.yaml, integrações) | 5 dias |
| Customização de prompt e tools | 5 dias |
| Ingestão de knowledge base | 2 dias |
| Testes internos | 3 dias |
| Calibração com primeiros leads reais | 7 dias |
| Total no primeiro cliente | 3-4 semanas |
| Total em clientes seguintes | 1 semana |
Diferencial competitivo
Por que esse SDR é melhor que automação genérica
- Qualificação estruturada: capture dados ricos, não apenas conversa solta
- Frameworks reconhecidos: BANT/GPCT/MEDDIC adaptados ao contexto BR
- Integração CRM nativa: dados vão direto pro lugar certo
- Knowledge base por cliente: agente conhece a empresa, não responde genérico
- Handoff inteligente: humano recebe lead com contexto completo
- Observabilidade total: cada conversa rastreada, melhorada continuamente
- Custo previsível: pricing modular, escala com sucesso
vs concorrência (Botconversa, Zapia, n8n manual)
- Eles vendem “automação genérica”, você vende “SDR estruturado”
- Eles trocam JSON de fluxo, você ensina conversação real
- Eles não fazem eval, você melhora toda semana
Próximos passos sugeridos
Quando construir o agent-sdr:
- Começar pelo
triadeflow-core(ainda não existe) - Clonar
agent-templateparaagent-sdr - Escrever
system_base.mdespecífico para SDR - Criar tools
qualificar_lead,agendar_reuniao,enviar_material - Criar flows de BANT
- Montar dataset de eval com 30 casos reais (de conversas anteriores via Langfuse ou histórico de WhatsApp do cliente piloto)
- Subir primeiro cliente (sugestão: USA Salus ou outro com volume conhecido)
- Calibrar 7 dias antes de liberar volume completo
- Documentar lições aprendidas e refinar template