Communitygithub.com

moonbeautiful/autumn-recruiting-radar

Skill de coleta de informações sobre recrutamento de outono na China.

O que é autumn-recruiting-radar?

Este skill foi projetado para coletar informações sobre recrutamento de outono, estágios e conversão de estágios para contratação na China continental. Ele primeiro confirma as preferências do usuário, depois descobre vagas a partir de fontes públicas, prioriza a verificação nos sites oficiais de recrutamento das empresas e, finalmente, usa scripts determinísticos para realizar a correspondência, deduplicação entre fontes, detecção de mudanças e identificação de prazos finais. O resultado é uma lista de vagas diretamente na conversa. Ele é multiplataforma (Windows, macOS, Linux), funciona em qualquer cliente de IA que tenha capacidade de busca na web e não requer instalação de ferramentas adicionais. Suporta Trae, Claude e outros clientes de IA populares. O processo é iterativo: o agente descobre uma fila de empresas em tempo real, busca vagas empresa por empresa com entrega em streaming para que o usuário veja resultados rapidamente, e armazena tudo em arquivos JSON para processamento posterior. Ele também realiza verificação oficial, correspondência de preferências, deduplicação, detecção de mudanças e identificação de status expirado. Os resultados são entregues diretamente no chat, sem necessidade de o usuário abrir arquivos. Por fim, oferece notificações de atualização opcionais (com verificação de batimento cardíaco) que podem ser configuradas para disparar no início de uma sessão ou em horários fixos (via tarefas do sistema), mas sempre com transparência sobre as limitações (exige computador ligado).

Funciona com✓Claude Code~Codex CLI~Cursor
npx skills add moonbeautiful/autumn-recruiting-radar

Perguntar na sua IA favorita

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

Documentação

Radar de Recrutamento de Outono

Skill de coleta de informações sobre recrutamento de outono, estágios e conversão de estágios para contratação na China continental. Primeiro, confirme as preferências de emprego; depois, descubra vagas a partir de fontes públicas; priorize a verificação nos sites oficiais de recrutamento das empresas; finalmente, use scripts determinísticos para correspondência, deduplicação entre fontes, detecção de mudanças e identificação de prazos finais, e entregue a lista de vagas diretamente na conversa atual.

Ambiente de Execução (Código Aberto e Portátil)

Este skill é distribuído como código aberto, qualquer pessoa pode cloná-lo e instalá-lo em seu próprio computador. Portanto, deve atender aos seguintes requisitos:

  • Multiplataforma: Todos os scripts usam apenas a biblioteca padrão do Python 3.8+, funcionando em Windows / macOS / Linux; não usam caminhos absolutos fixos, nem dependem de comandos exclusivos de um sistema, como osascript ou launchd.

  • Independente de modelo / cliente: A descoberta de vagas usa apenas a "capacidade de busca na web / leitura de páginas integrada ao cliente host", sem instalar ferramentas adicionais, controlar o navegador do usuário ou gerar custos extras.

  • Apenas dois caminhos:

    1. O cliente tem capacidade de busca / leitura de páginas (Trae, Claude e outros clientes de IA populares já possuem) → colete vagas diretamente via internet, sem ação do usuário;
    2. O cliente realmente não tem nenhuma capacidade de rede → exiba a mensagem fixa abaixo e pare, nunca invente vagas, empresas, links ou prazos de memória.

    Mensagem fixa quando a rede não está disponível:

    O cliente atual não possui capacidade de busca na internet disponível. Não consigo obter informações de vagas em tempo real. Execute este skill novamente em um cliente de IA que suporte conexão com a internet.

  • Independentemente de qual caminho obtiver as vagas, o resultado é sempre escrito em runtime/inbox/jobs-input.json; o processamento subsequente é idêntico.

Limites de Configuração

Antes de começar, leia completamente:

  • configuration.md: Limites de configuração editável pelo usuário, configuração do projeto e estado de execução;
  • data-contract.md: Campos de entrada e saída de vagas;
  • source-strategy.md: Prioridade de fontes, fluxo de descoberta e verificação.

Não permita que o usuário modifique config/project.json. As preferências do usuário são escritas apenas em runtime/user-preferences.json; o estado do programa é escrito apenas em runtime/state/.

Passo 0: Inicialização

Primeiro, execute:

SKILL_DIR=$(cd "$(dirname "SKILL.md")" && pwd)
python3 "$SKILL_DIR/scripts/bootstrap.py"

Leia runtime/user-preferences.json. Se onboarded não for true, pergunte apenas os cinco itens ainda não definidos:

  1. Ano de formatura;
  2. Cargo alvo;
  3. Cidade alvo;
  4. Apenas recrutamento de outono, ou também estágios e conversão de estágios;
  5. Que tipo de empresa procura (use discovery.company_type_options: grandes empresas de internet / unicórnios de IA · empresas de modelos grandes / empresas de nicho · setoriais / todos), e se há preferência adicional por empresas / setores.

Escreva as respostas em runtime/user-preferences.json:

  • Cidade vazia como array vazio indica todo o país;
  • O tipo de empresa (item 5) é usado no Passo 1 para gerar a "fila de empresas" e decidir a prioridade de pesquisa; a lista específica é obtida em tempo real pela execução, não é fixa, e o usuário não precisa saber quais empresas existem;
  • Preferências de empresas e setores são usadas apenas para pontuação de ordenação, não como filtro rígido;
  • Não exija que o usuário preencha uma lista de palavras-chave; o agente gera role_keywords a partir do alvo em linguagem natural; por exemplo, "produto de IA" deve cobrir nomes comuns como gerente de produto de aplicação de IA, gerente de produto de modelo grande de IA, gerente de produto de agente de IA, gerente de produto AIGC e gerente de produto (direção de IA);
  • Após concluir, defina onboarded como true e apresente um resumo da configuração ao usuário.

Ao perguntar sobre o tipo de empresa, mantenha um tom neutro consistente com as outras perguntas: explique que a lista específica de empresas será pesquisada em tempo real pelo assistente durante a execução, e o usuário só precisa escolher uma categoria ampla, sem precisar listar as próprias empresas.

Sobre se deve ativar "notificações de atualização", pergunte apenas depois que o primeiro resultado for entregue (veja Passo 5); não pergunte durante a inicialização.

Passo 1: Descoberta de Vagas (Em Fases + Entrega em Fluxo Contínuo)

Leia config/project.json (especialmente a seção discovery) e references/source-strategy.md.

Princípio central: O usuário não está esperando "tudo ser pesquisado", mas sim "a próxima vaga para a qual pode se candidatar". Portanto, sempre entregue à medida que pesquisa, nunca calcule tudo antes de entregar. Consulte source-strategy.md para "descoberta em fluxo contínuo por fases".

A descoberta ocorre em duas etapas:

1a. Primeiro, descubra a "fila de empresas" (em tempo real, uma pesquisa para várias)

  • O tipo de empresa é selecionado pelo usuário no Passo 0 (grandes empresas de internet / unicórnios de IA · empresas de modelos grandes / empresas de nicho · setoriais / todos); a lista não é fixa.
  • Use páginas de pista de platform como agregadores / rankings / sites de emprego universitários, que "podem trazer dezenas de empresas de uma vez", e pesquise em tempo real um lote de "nomes de empresas contratantes + pistas de vagas" de acordo com a cidade, cargo e tipo de empresa do usuário, obtendo uma fila ordenada (por exemplo: ByteDance → Alibaba → Tencent → …).
  • A ordenação pode usar discovery.employer_anchors para que empresas conhecidas apareçam primeiro; employer_anchors são apenas âncoras de ordenação e fallback ocasional; a lista real é baseada na pesquisa atual.
  • Este lote de pistas pode ser entregue ao usuário como uma "versão preliminar (a ser verificada)" primeiro, sem desperdício.

1b. Em seguida, verifique e complete empresa por empresa na fila (fluxo contínuo, conforme termina uma, entrega uma)

  • Siga a ordem da fila, processando no máximo discovery.stream.max_concurrent_lookups empresas simultaneamente;
  • Dentro de cada empresa, priorize as vagas "mais recentemente publicadas / em contratação" (in_hiring_first); as antigas vêm depois;
  • Assim que terminar de pesquisar uma empresa, adicione as vagas dessa empresa à conversa atual (deliver_per_company), não espere a fila inteira terminar;
  • A primeira leva entrega no máximo first_batch_max_companies empresas (padrão 3), para que o usuário veja resultados em segundos;
  • Uma única execução processa no máximo max_companies_per_run empresas, cada empresa no máximo max_per_company vagas, para evitar descontrole;
  • Após entregar um lote, se ask_before_long_tail for verdadeiro, pergunte "Quer continuar procurando por unicórnios de IA / nicho etc.?"; o usuário diz "continuar" para expandir, ou "já chega" para parar imediatamente e organizar os resultados já obtidos;
  • As empresas da fila que não foram pesquisadas são mantidas para a próxima execução, não descartadas.

As vagas candidatas devem atender ao data-contract.md: source_tier só pode ser um de official, official_wechat ou platform; páginas de agregação / links de mídia são rejeitados diretamente pelo script, servindo apenas como "pistas". A produção em fluxo contínuo vaga por vaga é escrita (pode ser anexada várias vezes) em:

runtime/inbox/jobs-input.json

É proibido adivinhar datas de publicação ou prazos finais; quando a página não os fornecer explicitamente, escreva unknown. Se uma fonte falhar ou estiver vazia, registre fielmente, sem contornar repetidamente as restrições de acesso.

Passo 2: Verificação Oficial

Para vagas descobertas em fontes não oficiais, priorize a busca pela página de detalhes oficial do recrutamento da empresa:

  • Encontrada a página oficial de detalhes: defina-a como fonte principal, a página agregadora original é escrita em alternate_sources;
  • Encontrado apenas o WeChat oficial da empresa: o nível da fonte é official_wechat;
  • Incapaz de encontrar página oficial: mantenha o nível real da fonte, não finja ser oficial;
  • Página oficial explicitamente fechada, descontinuada ou com recrutamento encerrado: source_status como closed;
  • Página ainda aceitando candidaturas: source_status como open;
  • Incapaz de determinar: unknown.

A cada execução, verifique no máximo 5 novas empresas em profundidade para evitar custos fora de controle.

Passo 3: Correspondência, Deduplicação e Detecção de Mudanças

Execute:

python3 "$SKILL_DIR/scripts/radar.py" run \
  --input "$SKILL_DIR/runtime/inbox/jobs-input.json" \
  --preferences "$SKILL_DIR/runtime/user-preferences.json" \
  --project-config "$SKILL_DIR/config/project.json" \
  --state-dir "$SKILL_DIR/runtime/state"

O programa deve ser responsável por:

  • Corresponder por ano de formatura, cargo, cidade e tipo de recrutamento;
  • Preferências de empresa e setor apenas somam pontos;
  • Deduplicar entre fontes para mesma empresa, mesmo cargo, mesma cidade, mesmo ano de formatura, mesmo tipo de recrutamento;
  • Fontes oficiais têm prioridade; fontes mais fracas são mantidas como evidência de backup;
  • Comparar campos estáveis, identificando new, changed, seen;
  • Gerar changed_fields específicos;
  • Marcar como expired quando o prazo final é anterior à data de execução, ou a página oficial indica explicitamente fechamento;
  • Vagas expiradas vão para o arquivo morto, não entram na entrega;
  • fetched_at não participa do julgamento de mudanças.

Passo 4: Responder Diretamente no Chat

O script gera, por padrão, uma lista de chat concisa contendo apenas vagas novas e com mudanças que ainda não expiraram. Entregue a saída completa do script na conversa atual, não informe apenas o caminho do arquivo, nem peça ao usuário para abrir um relatório.

Arquivos de estado interno:

runtime/state/
├── jobs.json
├── jobs.csv
├── seen.json
├── expired.json
├── rejected.json
├── daily/YYYY-MM-DD.md
└── outbox/YYYY-MM-DD.md

A lista de chat deve incluir:

  • Empresa;
  • Nome da vaga;
  • Cidade;
  • Tipo de recrutamento;
  • Salário e benefícios;
  • Data de publicação;
  • Prazo final;
  • Palavras-chave da vaga (extraídas dos requisitos);
  • Destaques da vaga;
  • Link de candidatura;
  • Fonte da informação;
  • Status e campos de alteração.

daily/ são instantâneos de auditoria interna; outbox/ é uma cópia interna da lista de chat atual. O usuário não precisa abrir esses arquivos. Vagas seen, expired e repetidas do mesmo lote não devem ser reenviadas.

Passo 5: Após o Processamento dos Resultados, Pergunte se Deseja Ativar Notificações de Atualização

Após a primeira execução, quando a lista de vagas for entregue ao usuário, pergunte: "Quando houver vagas novas ou com alterações, posso notificá-lo?"

  • Usuário não permite: defina schedule.notify_on_update como false (já é o padrão), termine, não faça nada extra;
  • Usuário permite: defina schedule.notify_on_update como true e, conforme o Passo 6, agende as execuções periódicas subsequentes.

O usuário pode mudar de ideia a qualquer momento: dizer "não quero mais notificações" volta notify_on_update para false, e mesmo que haja novas vagas ou mudanças, não será enviado ativamente; dizer "quero notificações de novo" volta para true. É uma chave que pode ser ligada e desligada repetidamente, não uma configuração única.

Passo 6: Notificações Periódicas (Apenas quando notify_on_update é true)

O significado da verificação periódica é simples: de tempos em tempos, faça o agente executar este skill novamente (recoleta → deduplicação → comparação com o estado histórico).

  • Se esta execução produzir vagas "novas" ou "com alterações", entregue a lista na conversa atual;
  • Se não houver nenhuma novidade ou alteração, não envie nada, fique em silêncio, não incomode o usuário.

Depende apenas de "reexecução + comparação com estado histórico", sem pop-ups de sistema, e-mails ou webhooks. "Quem dispara a reexecução" é dividido em duas camadas, do geral ao aprimorado:

6.1 Camada Padrão (Para Todos, Zero Configuração, Multiplataforma e Multimodelo)

Qualquer pessoa que clonar este skill usará esta camada por padrão, sem depender de nenhum temporizador:

  1. Atualização incremental ao iniciar a sessão (este é o "coletor diário" universal): Quando este skill é ativado em uma sessão, e notify_on_update é true, e já passou um dia desde a última execução, o agente usa automaticamente a busca na internet do próprio host para recoletar as empresas de interesse do usuário (como ByteDance, Alibaba) → deduplicação → comparação com o estado histórico → envia apenas o novo/alterado para o usuário, sem atualizações fica em silêncio. O usuário não precisa dizer "verificar" toda vez, nem precisa configurar nenhum comando em segundo plano. Como o usuário abre seu cliente de IA todos os dias, a descoberta de novas vagas, que requer conexão com a internet, acontece naturalmente na primeira conversa do dia — esta é a única forma de coleta que é zero configuração, zero custo e não vinculada a dispositivo para todos os usuários do GitHub.
  2. Disparo pelo usuário: O usuário pode dizer "verificar / ver se tem novidades" a qualquer momento, e a reexecução é imediata.
  3. Ponto de entrada diário com --heartbeat: sem atualizações, saída zero; com atualizações, responde com a lista:
python3 "$SKILL_DIR/scripts/run_daily.py" \
  --project-config "$SKILL_DIR/config/project.json" --heartbeat

Quando notify_on_update é true, run_daily.py anexa automaticamente a verificação periódica, sem necessidade de adicionar o parâmetro manualmente.

6.2 Camada Aprimorada Opcional: Execução Programada pelo Host / Sistema ("Envio Automático em Horário Fixo Todos os Dias")

Quando o usuário explicitamente deseja "envio automático em horário fixo todos os dias", implemente de acordo com a seguinte prioridade, e explique honestamente os custos:

  1. Priorize o uso da capacidade de temporização ou lembrete do próprio agente / cliente host (se houver), para que ele execute este skill no horário definido, é mais fácil e não requer mexer no sistema.
  2. Se o host não tiver capacidade de temporização, use o script multiplataforma scripts/schedule_task.py para registrar uma tarefa programada nativa do sistema operacional (macOS launchd / Linux cron / Windows Agendador de Tarefas). Ele gera a configuração no momento da execução com base no sistema do usuário e no horário escolhido, não fixa caminhos, não vincula ao dispositivo do mantenedor:
# Primeiro, visualize (padrão print, não altera o sistema, seguro):
python3 "$SKILL_DIR/scripts/schedule_task.py" --action print --time 08:00
# Após confirmação do usuário, instale de fato (modificará o computador):
python3 "$SKILL_DIR/scripts/schedule_task.py" --action install --time 08:00
# Verificar / remover:
python3 "$SKILL_DIR/scripts/schedule_task.py" --action status
python3 "$SKILL_DIR/scripts/schedule_task.py" --action remove

Antes de instalar, primeiro faça uma pré-visualização com print e obtenha o consentimento do usuário; após o consentimento, escreva o horário escolhido pelo usuário em schedule.time e defina schedule.enabled como true.

Duas limitações reais que devem ser explicadas claramente ao usuário (não ocultar, não exagerar como "24 horas na nuvem"):

  • O computador precisa estar ligado: A tarefa programada do sistema só será disparada se o computador estiver ligado no horário definido; durante desligamento / suspensão, não será executada, nem será recuperada.
  • A tarefa programada em si não "pesquisa novas vagas na internet": run_daily.py por padrão apenas reprocessa a entrada existente (deduplicação, mudanças, arquivamento de expirados), portanto, config/project.json na seção collector.command deve permanecer vazio por padrão e deve ser mantido vazio (motivo na command_note do campo). Isso não é uma falha: a descoberta de novas vagas é realizada pela "coleta automática via internet ao iniciar a sessão" da seção 6.1, que é zero configuração e zero custo para todos os usuários. Não existe um comando de rede em segundo plano que seja "universal, gratuito e executável para todos os usuários do GitHub", portanto, não invente um collector.command para distribuir, apenas para que a tarefa programada possa pesquisar novas vagas.
  1. Se o host não suporta temporização e o usuário não quer usar tarefas do sistema, volte para a camada padrão: diga ao usuário "Quando você me usar novamente, atualizarei automaticamente, ou diga 'verificar' a qualquer momento", nunca finja que uma tarefa programada local é um envio automático na nuvem.

Verificação

bash "$SKILL_DIR/scripts/validate_skill.sh"

A verificação deve provar:

  1. A primeira execução produz vagas novas;
  2. A mesma entrada executada novamente não reenvia vagas duplicadas;
  3. Vagas duplicadas entre fontes mantêm apenas a fonte mais forte;
  4. Quando campos mudam, gera changed e os campos de alteração;
  5. Entrada com alterações executada novamente torna-se seen;
  6. Vagas com prazo final claro e data expirada entram em expired;
  7. Vagas expiradas não entram na lista de chat;
  8. Cidade, tipo de recrutamento, data de publicação, prazo final, fonte e destaques estão todos na lista de chat;
  9. O comando padrão gera a lista de chat diretamente; JSON é usado apenas para testes automatizados.

Segurança e Autenticidade

  • Acesse apenas páginas públicas, não colete dados após login, internos ou de interfaces não públicas;
  • Não armazene cookies, senhas ou informações privadas de contatos de recrutamento;
  • Não burle CAPTCHAs, medidas anti-bot ou restrições de acesso;
  • Datas desconhecidas escreva unknown, não adivinhe;
  • O estado interno e a lista de chat mantêm nome, nível, link e data de coleta da fonte;
  • Todas as vagas devem ser verificadas novamente no site oficial de recrutamento da empresa antes da candidatura.

Habilidades Relacionadas