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
osascriptoulaunchd. -
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:
- 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;
- 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:
- Ano de formatura;
- Cargo alvo;
- Cidade alvo;
- Apenas recrutamento de outono, ou também estágios e conversão de estágios;
- 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_keywordsa 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
onboardedcomotruee 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
platformcomo 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_anchorspara que empresas conhecidas apareçam primeiro;employer_anchorssã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_lookupsempresas 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_companiesempresas (padrão 3), para que o usuário veja resultados em segundos; - Uma única execução processa no máximo
max_companies_per_runempresas, cada empresa no máximomax_per_companyvagas, para evitar descontrole; - Após entregar um lote, se
ask_before_long_tailfor 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_statuscomoclosed; - Página ainda aceitando candidaturas:
source_statuscomoopen; - 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_fieldsespecíficos; - Marcar como
expiredquando 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_atnã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_updatecomofalse(já é o padrão), termine, não faça nada extra; - Usuário permite: defina
schedule.notify_on_updatecomotruee, 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:
- 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. - Disparo pelo usuário: O usuário pode dizer "verificar / ver se tem novidades" a qualquer momento, e a reexecução é imediata.
- 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:
- 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.
- 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.pypor padrão apenas reprocessa a entrada existente (deduplicação, mudanças, arquivamento de expirados), portanto,config/project.jsonna seçãocollector.commanddeve permanecer vazio por padrão e deve ser mantido vazio (motivo nacommand_notedo 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 umcollector.commandpara distribuir, apenas para que a tarefa programada possa pesquisar novas vagas.
- 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:
- A primeira execução produz vagas novas;
- A mesma entrada executada novamente não reenvia vagas duplicadas;
- Vagas duplicadas entre fontes mantêm apenas a fonte mais forte;
- Quando campos mudam, gera
changede os campos de alteração; - Entrada com alterações executada novamente torna-se
seen; - Vagas com prazo final claro e data expirada entram em
expired; - Vagas expiradas não entram na lista de chat;
- Cidade, tipo de recrutamento, data de publicação, prazo final, fonte e destaques estão todos na lista de chat;
- 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.