CommunityEscrita e Ediçãogithub.com

outreachmagic/lead-enrich

Pesquisa de pessoas para agentes de IA. Pesquisa no Serper por LinkedIn, domínio da empresa e site. Combina com Outreach Magic para deduplicação economizando créditos.

O que é lead-enrich?

Este skill permite que agentes de IA (como Claude Code, Cursor ou Codex) realizem enriquecimento de leads pesquisando informações de pessoas (nome + empresa) usando a API de busca do Google via Serper.dev. Ele utiliza o modelo de raciocínio embutido do próprio agente para extrair dados estruturados como LinkedIn, domínio e site da empresa, eliminando a necessidade de chamadas externas a LLMs. O skill funciona de forma independente com apenas uma chave Serper, mas quando combinado com o skill Outreach Magic, oferece deduplicação inteligente que economiza créditos (verificando se o lead já possui LinkedIn e email salvos antes de gastar créditos Serper), armazenamento persistente em SQLite, e suporte a workflows em lote para CSV/JSON. Inclui regras claras de comportamento do agente, como verificação de duplicatas antes de qualquer chamada Serper, transparência nos créditos gastos, e integração opcional com um skill separado de busca de email para completar perfis.

Funciona com✓Claude Code✓Codex CLI✓Cursor✓Gemini CLI
npx skills add outreachmagic/lead-enrich

Installed? Explore more Escrita e Edição skills: steipete/notion, langchain-ai/langchain, bytedance/podcast-generation · View all 6 →

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

Lead Enrich

Pesquise uma pessoa (nome + empresa) usando a Serper.dev (Pesquisa Google). Usa o modelo embutido do agente para extração. Nenhuma API LLM externa necessária.

Funciona de forma independente — apenas uma chave Serper. Combina com Outreach Magic para deduplicação economizando créditos (evita Serper quando leads já têm LinkedIn/email) e armazenamento persistente entre sessões.

Economia de crédito (com OM): verifica o outreachmagic primeiro. Se o lead já tiver LinkedIn + email na mesma empresa, zero créditos Serper gastos. LinkedIn sem email pula Serper — use email-finder para trykitt. Registros apenas com email ainda recebem pesquisas de LinkedIn (1–2 créditos Serper). Correspondências de nome em empresas diferentes retornam ambiguous para que APIs não sejam desperdiçadas.

Configuração

Autônomo (sem OM)

Apenas uma chave Serper. Execute serper-search diretamente. Os resultados são impressos como JSON.

ChavePara
SERPER_API_KEYserper.dev — API de Pesquisa Google
python3 scripts/enrich.py serper-search --query '"Acme Corp" site oficial'
python3 scripts/enrich.py serper-search --query 'site:linkedin.com/in Jane Doe Acme Corp'
# → direcione os resultados para seu modelo extrair, ou use serper-format

Defina SERPER_API_KEY em seu ambiente ou via ~/.hermes/skills/lead-enrich/config.json.

Com Outreach Magic (dedup + salvar)

Adiciona deduplicação pré-voo (pular leads já no OM) e salva o enriquecimento estruturado em seu pipeline SQLite local. Requer o skill outreachmagic com pipeline.py login.

ChavePara
Todas as chaves autônomas acima +
OUTREACHMAGIC_AGENT_KEYLogin OM via pipeline.py login
python3 scripts/enrich.py check "Jane Doe" "Acme Corp"        # 0 créditos
python3 scripts/enrich.py batch-check --workspace W input.json # dedup em lote

Salve sua chave Serper no Portal Outreach Magic → Configurações → Chaves de API, então execute pipeline.py sync-secrets. Verifique com enrich.py config (serper_api_key_source deve ser agent_secrets).

3. Localização de email (skill email-finder)

A localização de email não está no lead-enrich v2+. Instale email-finder com o outreachmagic usando o guia de instalação da plataforma. Ou instale de forma autônoma via npx skills add outreachmagic/email-finder.

Após o enriquecimento Serper salvar company_domain, execute:

python3 ~/.hermes/skills/email-finder/scripts/email_finder.py find --name "Jane Doe" \
  --domain acme.com --linkedin "https://linkedin.com/in/janedoe" --save

Veja references/email-finder.md e a documentação do skill email-finder.

Resumos de workspace (sem créditos Serper): após salvar leads, use o outreachmagic workspace summary --workspace <slug> --json para contagens de tags e conexões do LinkedIn aceitas por remetente. Em workspaces grandes (>2.000 leads), adicione --tags-only para contagens de tags mais rápidas. Apenas DB local — pull opcional.

Fluxos de trabalho comuns

Usuário dizVocê faz
"Pesquise esta pessoa"Pesquisa Serper → salva via import-profiles
"Enriqueça meu CSV"batch-check / import → enriquece campos ausentes → salva no OM
"Encontre também o email dele"Após o enriquecimento, passe para email-finder

CSVs do Sales Nav / Vayne: use o outreachmagic import-profiles --file … (detecta colunas automaticamente).

Fluxo de trabalho CSV / lista de premiações (preferido para 10+ pessoas)

Caminhos como outreachmagic/imports/awards.csv são relativos ao seu diretório de workspace (onde o agente executa o comando), não à pasta de instalação do skill.

# 0 créditos — deduplica o arquivo inteiro primeiro (carimba automaticamente serper_attempted em linhas completas)
python3 scripts/enrich.py batch-check --workspace your_workspace outreachmagic/imports/awards.csv

# Re-executa dedup pulando leads já marcados com serper_attempted
python3 scripts/enrich.py batch-check --workspace your_workspace --skip-tagged outreachmagic/imports/awards.csv

# Serper apenas para linhas que precisam de LinkedIn/domínio (pula team_award, exists_linkedin_*, skipped_serper_attempted)

# Após a pesquisa — corrige título/indústria apenas (0 créditos Serper)
python3 scripts/enrich.py backfill --fields title,industry --workspace your_workspace outreachmagic/imports/patch.csv

batch-check aceita .json ou .csv. backfill requer email ou linkedin por linha; usa import-profiles em blocos via companion_common (200 linhas/bloco, até 300s/bloco; preenche campos vazios; adicione --overwrite para substituir).

Quando usar

  • Usuário diz "pesquise esta pessoa" / "procure Jane Doe da Acme"
  • Usuário quer enriquecer uma lista de prospects antes do contato
  • Usuário pergunta "já temos este lead?" antes de pesquisar
  • Usuário fornece um CSV/JSON de nomes e empresas para enriquecer em lote
  • Usuário menciona Serper, enriquecimento de lead ou pesquisa de pessoas

Regras de Comportamento do Agente (Importante)

  1. Deduplicar primeiro (com OM). Antes de qualquer chamada à API Serper, execute enrich.py check. Se o lead tiver LinkedIn + email na mesma empresa, pule o Serper completamente. Se o LinkedIn existir mas sem email, pule o Serper e ofereça email-finder quando o usuário quiser um endereço. Nunca gaste créditos Serper em leads já completos no outreachmagic. Autônomo: pule a verificação — execute serper-search diretamente.
  2. Apenas Serper. Prefira enrich.py serper-search --query "..." (stdlib HTTP, chave do config/env). Ou use curl com $SERPER_API_KEY — nunca incorpore a chave em logs de chat. Nunca raspe o Google ou LinkedIn diretamente.
  3. Apenas modelo embutido. Você (o agente) extrai JSON dos resultados do Serper. Nenhuma API LLM externa (sem Gemini, sem OpenAI) — seu próprio raciocínio é o motor de extração.
  4. Pesquisa completa antes de salvar. Execute toda a escada de pesquisa primeiro, depois salve de uma vez.
  5. Salvar via outreachmagic (com OM). Use import-profiles para leads com LinkedIn. Sempre anexe serper_attempted às tags ao salvar (incluído automaticamente na saída de map-to-om). Para leads sem LinkedIn mas com lead_id conhecido, carimbe a tag via stamp-attempted ou import-profiles com id + tags — não confie apenas em notas. Para verificações de dedup somente leitura, use pipeline.py query ou enrich.py check — nunca INSERT/UPDATE brutos. Nunca execute ambos os caminhos de salvamento para a mesma pessoa. Autônomo: salve a saída JSON em um arquivo — sem necessidade de OM.
  6. Marcar após enriquecimento (com OM). Todo lead que passar pelo Serper deve receber serper_attempted ao salvar. Evita reprocessamento em execuções futuras.
  7. Verificar tag antes do Serper (com OM). Antes de gastar créditos Serper, verifique serper_attempted (via enrich.py check --skip-tagged ou skip_reason na saída de verificação). Se presente e o LinkedIn ainda estiver vazio, pule a menos que o usuário queira explicitamente uma nova tentativa (por exemplo, desatualizado >30 dias).
  8. Transparência. Mostre quais consultas Serper foram executadas, a confiança e o que foi salvo. O usuário deve ver exatamente para onde seus créditos foram.
  9. Lote com sabedoria. Limite a 50 pessoas por execução. Para listas CSV/premiações execute batch-check uma vez no arquivo inteiro (JSON ou CSV) antes de qualquer Serper. Processe o Serper apenas para status que precisam de LinkedIn/domínio. Pule linhas team_award, exists_linkedin_email e skipped_serper_attempted.
  10. Localização de email — use email-finder. Após o enriquecimento salvar company_domain, passe para email-finder (email_finder.py find --save). Veja references/email-finder.md. Nunca invente ou adivinhe emails neste skill.

Início Rápido

# Pessoa única (mais comum)
python3 scripts/enrich.py check "Jane Doe" "Acme Corp"
# → se "not_found", prossiga com o pacote de pesquisa Serper abaixo

# Com workspace (associa lead ao seu pipeline de workspace)
python3 scripts/enrich.py check --workspace your_workspace "Jane Doe" "Acme Corp"

# Lote de JSON ou CSV (execute isso antes do Serper em listas)
python3 scripts/enrich.py batch-check --workspace your_workspace outreachmagic/imports/people.json
python3 scripts/enrich.py batch-check --workspace your_workspace --skip-tagged outreachmagic/imports/awards.csv

# Carimbar serper_attempted após falha na pesquisa do LinkedIn (quando lead_id é conhecido)
python3 scripts/enrich.py stamp-attempted --workspace your_workspace --lead-ids 42,43 \
  --notes "Nenhum LinkedIn encontrado via Serper"

# Preencher título/indústria em leads existentes (linkedin ou email obrigatório)
python3 scripts/enrich.py backfill --fields title,industry outreachmagic/imports/patch.csv

# Atualizar skill com segurança a partir do lançamento do GitHub (verificado por checksum)
python3 scripts/enrich.py update --check
python3 scripts/enrich.py update

update verifica checksums SHA256 de update-manifest.json antes de substituir arquivos. Se os checksums estiverem ausentes ou não coincidirem, a atualização é abortada.

Fluxo de Trabalho Principal

Fase 1 — Verificação de Dedup (0 créditos)

Para cada pessoa, execute:

# Sem workspace (consulta em toda a organização)
python3 scripts/enrich.py check "Jane Doe" "Acme Corp"

# Com workspace (escopo para seu pipeline de workspace)
python3 scripts/enrich.py check --workspace your_workspace "Jane Doe" "Acme Corp"

Saída por pessoa:

StatusSignificadoAção
exists_linkedin_emailMesma empresa, LinkedIn + emailPule Serper e APIs de email
exists_linkedin_no_emailMesma empresa, LinkedIn, sem emailPule Serper → email-finder se usuário quiser email
exists_no_linkedin_emailMesma empresa, email, sem LinkedInApenas consultas Serper de LinkedIn
exists_no_linkedinMesma empresa, nenhumApenas consultas Serper de LinkedIn
skipped_serper_attemptedTem tag serper_attempted, sem LinkedInPule Serper — já tentado
ambiguousNome corresponde, empresa não correspondeExecute pacote Serper completo — não pule
not_foundNenhuma correspondênciaExecute pacote de pesquisa Serper completo
team_awardLinha de equipe/grupo (sem indivíduo)Pule Serper — marque team_award, adicione nota de contato
dedup_disableddedup_before_search: false no configExecute Serper conforme solicitado

A saída de verificação inclui tags e skip_reason opcional (has_linkedin ou skipped_serper_attempted). Usa batch-lead-lookup (local, zero créditos Serper).

Fase 2 — Pacote de Pesquisa Serper

Execute apenas para pessoas que precisam dele. 2 a 4 pesquisas por pessoa dependendo da qualidade do resultado:

Estimador de Orçamento de Créditos Serper

  • Por pessoa mínimo: 0 créditos Serper (exists_linkedin_email).
  • Caminho comum: 2 créditos (2a empresa estrita + 2c perfil LinkedIn).
  • Por pessoa máximo absoluto: 4 créditos quando todos os fallbacks são necessários (2a + 2b + 2c + 2e).
  • Fórmula de lote: min=0, max=4*N onde N é o número de pessoas na execução.
  • Exemplo de limite de lote: com N=50, máximo absoluto é 200 créditos (pior caso).

2a. Descoberta de empresa — estrita (sempre)

Preferido (sem chave no histórico do shell):

python3 scripts/enrich.py serper-search --query '"Acme Corp" site oficial' --label company_discovery_strict

Ou tente novamente com uma consulta mais simples:

python3 scripts/enrich.py serper-search --query 'Acme Corp website' --label company_discovery_broad

2b. Descoberta de empresa — ampla (condicional)

Execute apenas se 2a não retornar resultados orgânicos com um link http:// ou https://:

python3 scripts/enrich.py serper-search --query 'Acme Corp site oficial' --label company_discovery_broad

(Mesmo modelo, nome da empresa sem aspas.)

2c. Perfil LinkedIn (sempre)

Construa a consulta (empresa sem aspas — corresponde a nomes variantes de empregador em snippets):

site:linkedin.com/in {Primeiro Último} {até 5 palavras do cargo} {Nome da Empresa}

Exemplo:

python3 scripts/enrich.py serper-search \
  --query 'site:linkedin.com/in Jane Doe VP Marketing Acme Corp' \
  --label linkedin_profile

Fase 3 — Extração do Modelo

Passe os resultados formatados do Serper para si mesmo (o modelo agente) com esta instrução de sistema:

Você é um assistente de pesquisa. A mensagem do usuário contém resultados de pesquisa do Google Serper.dev
em seções rotuladas. Você NÃO tem pesquisa web ao vivo — use apenas os blocos colados.

Tarefa: para UMA pessoa específica em UMA empresa, extraia:
- company_domain: apenas o hostname registrável (sem caminho, sem www), ou string vazia
- company_website: URL completa https:// da página inicial se suportada, ou string vazia
- linkedin_url: https://linkedin.com/in/… para a pessoa nomeada nesta empresa, ou string vazia
- confidence: alta | média | baixa
- note: explicação opcional de ambiguidade ou lacunas

Regras:
- Toda URL não vazia deve aparecer nos blocos Serper (normalização menor de query string é aceitável)
- O nome no LinkedIn pode diferir da entrada (apelido vs nome legal) — corresponda na mesma pessoa + empregador
- Antes de aceitar `linkedin_url`, verifique a qualidade da correspondência:
  - Extraia tokens de primeiro e último nome de `Nome completo: {full_name}` (ignore pontuação)
  - O resultado `/in/` escolhido deve ter *ambos* os tokens presentes no `title` ou `snippet` do resultado
  - Se nenhum resultado `/in/` atender ao requisito de token, retorne `linkedin_url` como string vazia e defina `confidence` como `baixa`
- O site público da empresa pode usar um nome de banner diferente da entrada — prefira evidências oficiais
- Ao resolver `company_domain`:
  - Prefira `knowledgeGraph.website` quando presente
  - Rejeite agregadores/registros comuns (exemplos: `naceweb.org`, `usnews.com`, `wikipedia.org`, `niche.com`, `facebook.com`, `instagram.com`, `twitter.com`)
  - Se `company_name` parecer ausente ou corresponder de perto ao nome da pessoa, retorne string vazia
- Nunca invente URLs ou slugs

Responda APENAS com um único objeto JSON (sem cercas markdown):
{"company_domain":"","company_website":"","linkedin_url":"","confidence":"média","note":""}

Use este modelo de mensagem do usuário:

### Pessoa alvo
Nome completo: {full_name}
Cargo/função informado: {stated_role}
Empresa (conforme fornecida): {company_name}

### Resultados da pesquisa
{formatted_serper_sections}

### Tarefa
Retorne o objeto JSON descrito na instrução de sistema.

Em seguida, analise sua própria resposta: remova cercas markdown, extraia o objeto JSON.

Fallback de colheita do LinkedIn: se linkedin_url estiver vazio após a extração, escaneie os resultados orgânicos brutos do Serper em busca de URLs /in/ onde o título contenha os tokens de primeiro e último nome. Prefira correspondências

…

[truncado para tradução — o conteúdo original foi cortado; mantive a tradução fiel até onde o original foi fornecido.]

Habilidades Relacionadas