Recopilación de Información de Reclutamiento de Otoño (秋招)
Skill de recopilación de información para reclutamiento de campus (校招), pasantías y conversión de pasantías a tiempo completo en China. Primero confirma las preferencias de búsqueda de empleo, luego descubre puestos desde fuentes públicas, prioriza la verificación en los sitios web oficiales de las empresas y finalmente utiliza scripts deterministas para realizar la coincidencia, deduplicación entre fuentes, detección de cambios y reconocimiento de fechas límite, y devuelve la lista de puestos directamente en la conversación actual.
Entorno de Ejecución (Código Abierto y Portable)
Este Skill está diseñado para distribución de código abierto. Cualquier persona puede clonarlo en su propia computadora e instalarlo, por lo que debe cumplir con:
-
Multiplataforma: Todos los scripts son Python 3.8+ con biblioteca estándar, y funcionan en Windows / macOS / Linux; no usan rutas absolutas ni dependen de comandos específicos del sistema como
osascriptolaunchd. -
Multi-modelo / Multi-cliente: El descubrimiento de puestos solo utiliza "la capacidad de búsqueda en red / lectura de páginas web integrada en el cliente anfitrión", sin instalar herramientas adicionales, sin controlar el navegador del usuario y sin generar costos adicionales.
-
Solo dos caminos:
- El cliente tiene búsqueda en segundo plano / lectura de páginas web (Trae, Claude y otros clientes de IA principales lo tienen incorporado) → Recopila puestos directamente en segundo plano, sin intervención del usuario;
- El cliente no tiene capacidad de conexión a la red → Muestra al usuario el siguiente mensaje fijo y se detiene, nunca inventa puestos, empresas, enlaces o fechas límite de memoria.
Mensaje fijo cuando la conexión a la red no está disponible:
El cliente actual no tiene capacidad de búsqueda en línea disponible. No puedo obtener información de puestos en tiempo real. Por favor, ejecute esta skill nuevamente en un cliente de IA que admita conexión a la red.
-
Independientemente de qué camino obtenga los puestos, el resultado se escribe uniformemente en
runtime/inbox/jobs-input.json, y el procesamiento posterior es completamente idéntico.
Límites de Configuración
Antes de comenzar, lea completamente:
- configuration.md: Límites de configuración modificable por el usuario, configuración del proyecto y estado de ejecución;
- data-contract.md: Campos de entrada y salida de puestos;
- source-strategy.md: Prioridad de fuentes, proceso de descubrimiento y verificación.
No permita que el usuario modifique config/project.json. Las preferencias del usuario solo se escriben en runtime/user-preferences.json; el estado del programa solo se escribe en runtime/state/.
Paso 0: Inicialización
Primero ejecute:
SKILL_DIR=$(cd "$(dirname "SKILL.md")" && pwd)
python3 "$SKILL_DIR/scripts/bootstrap.py"
Lea runtime/user-preferences.json. Si onboarded no es true, solo pregunte los cinco ítems aún no definidos:
- Año de graduación;
- Puesto objetivo;
- Ciudad objetivo;
- Solo reclutamiento de campus, o también pasantías y conversión de pasantías;
- Qué tipo de empresa busca (usando
discovery.company_type_options:Internet grandes empresas/AI unicornios·empresas de modelos grandes/Verticales·empresas del sector/Todos), y si tiene preferencias adicionales de empresas / sectores.
Escriba las respuestas en runtime/user-preferences.json:
- Ciudad como array vacío significa todo el país;
- El tipo de empresa (ítem 5) se utiliza en el Paso 1 para generar la "cola de empresas" y decidir a quién buscar primero; la lista específica se obtiene en tiempo real durante la ejecución, no está fija, y el usuario no necesita saber qué empresas existen;
- Las preferencias de empresas y sectores se utilizan por defecto para sumar puntos en la clasificación, no como filtro estricto;
- No se pide al usuario que complete una lista de palabras clave, el Agente genera
role_keywordsbasándose en el objetivo en lenguaje natural; por ejemplo, "producto AI" debería cubrir nombres comunes como Gerente de Producto de Aplicaciones AI, Gerente de Producto de Modelos Grandes AI, Gerente de Producto de Agente AI, Gerente de Producto AIGC y Gerente de Producto (dirección AI); - Una vez completado, establezca
onboardedentruey resuma la configuración al usuario.
Al preguntar sobre el tipo de empresa, mantenga un tono neutral consistente con las otras preguntas: explique que la lista específica de empresas es buscada en tiempo real por el asistente durante la ejecución, el usuario solo necesita seleccionar una categoría general, sin necesidad de enumerar empresas.
Sobre si activar las "notificaciones de actualización", pregunte después de obtener el primer resultado (ver Paso 5), no indague durante la inicialización.
Paso 1: Descubrimiento de Puestos (Por Fases + Entrega en Streaming)
Lea config/project.json (especialmente la sección discovery) y references/source-strategy.md.
Principio fundamental: El usuario no espera a que "todo esté buscado", sino "el próximo puesto al que pueda postularse". Por lo tanto, siempre entregue a medida que busca, nunca calcule todo primero y luego entregue. Consulte source-strategy.md para el "descubrimiento en streaming por fases".
El descubrimiento se divide en dos pasos:
1a. Primero descubra la "cola de empresas" (en tiempo real, uno por muchos a la vez)
- El tipo de empresa es seleccionado por el usuario en el Paso 0 (
Internet grandes empresas/AI unicornios·empresas de modelos grandes/Verticales·empresas del sector/Todos); la lista no está fija. - Utilice páginas de pistas de
platformcomo agregadores / rankings / sitios de empleo universitarios que "pueden traer docenas de empresas a la vez", y busque en tiempo real un lote de "nombre de empresa que está contratando + pista de puesto", obteniendo una cola ordenada (por ejemplo: ByteDance → Alibaba → Tencent → ...). - La ordenación puede usar
discovery.employer_anchorspara que las empresas conocidas salgan primero;employer_anchorses solo un ancla de ordenación y un respaldo ocasional, la lista real se basa en esta búsqueda. - Este lote de pistas en sí mismo puede devolverse al usuario como una "versión preliminar (pendiente de verificación)", sin desperdiciar.
1b. Luego, según la cola, "empresa por empresa" verifique y complete (en streaming, una vez buscada una empresa, entregue esa empresa)
- Siga el orden de la cola, procese concurrentemente no más de
discovery.stream.max_concurrent_lookupsempresas a la vez; - Dentro de cada empresa, primero los puestos "más recientes / en contratación" (
in_hiring_first), los existentes después; - Cada vez que termine de buscar una empresa, agregue los puestos de esa empresa a la conversación actual (
deliver_per_company), no espere a que termine toda la cola; - La primera oleada entrega
first_batch_max_companiesempresas (por defecto 3), para que el usuario vea algo en segundos; - Una sola ejecución maneja como máximo
max_companies_per_runempresas y como máximomax_per_companypuestos por empresa, para evitar descontrol; - Después de entregar un lote, si
ask_before_long_tailes verdadero, pregunte "¿Quiere continuar buscando AI unicornios / verticales y otras empresas de larga cola?"; si el usuario dice "continuar", expanda; si dice "suficiente", deténgase inmediatamente y organice los resultados obtenidos; - Las empresas no buscadas en la cola se guardan para la próxima vez, no se descartan.
Los puestos candidatos deben cumplir con data-contract.md: source_tier solo puede ser official, official_wechat o platform; las páginas de agregación / enlaces de medios son rechazadas directamente por el script y solo pueden ser usadas como "pistas". La salida en streaming se escribe uniformemente (se puede agregar varias veces):
runtime/inbox/jobs-input.json
Prohíba adivinar la fecha de publicación o la fecha límite; si la página no las indica claramente, escriba unknown. Si una fuente falla o está vacía, regístrelo fielmente, no intente repetidamente evitar las restricciones de acceso.
Paso 2: Verificación Oficial
Para los puestos descubiertos de fuentes no oficiales, priorice la búsqueda de la página de detalles del sitio web oficial de reclutamiento de la empresa:
- Si encuentra la página de detalles oficial: establezca esta como fuente principal, escriba la página agregadora original en
alternate_sources; - Si solo encuentra la cuenta oficial de WeChat de la empresa: el nivel de fuente se escribe como
official_wechat; - Si no puede encontrar una página oficial: conserve el nivel de fuente real, no lo disfrace como oficial;
- Si la página oficial está claramente cerrada, fuera de línea o ha detenido la contratación:
source_statusse escribe comoclosed; - Si la página aún permite postularse:
source_statusse escribe comoopen; - Si no se puede determinar: escriba
unknown.
Cada vez, verifique en profundidad un máximo de 5 nuevas empresas para evitar costos descontrolados.
Paso 3: Coincidencia, Deduplicación y Detección de Cambios
Ejecute:
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"
El programa debe encargarse de:
- Coincidir por año de graduación, puesto, ciudad y tipo de reclutamiento;
- Las preferencias de empresa y sector solo suman puntos;
- Deduplicación entre fuentes para la misma empresa, mismo puesto, misma ciudad, mismo año de graduación y mismo tipo de reclutamiento;
- Priorizar fuentes oficiales, conservar fuentes más débiles como evidencia de respaldo;
- Comparar campos estables para identificar
new,changed,seen; - Generar
changed_fieldsespecíficos; - Cuando la fecha límite es anterior a la fecha de ejecución, o la página oficial indica claramente que está cerrada, marcar como
expired; - Los puestos vencidos se archivan, no se envían;
fetched_atno participa en la determinación de cambios.
Paso 4: Responder Directamente en el Chat
El script produce por defecto una lista de chat concisa que solo incluye puestos nuevos o modificados que aún no han vencido. Devuelva la salida completa del script en la conversación actual, no solo indique la ruta del archivo ni pida al usuario que abra un informe.
Archivos 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
La lista de chat debe incluir:
- Empresa;
- Nombre del puesto;
- Ciudad;
- Tipo de reclutamiento;
- Salario y beneficios;
- Fecha de publicación;
- Fecha límite;
- Palabras clave del puesto (extraídas de los requisitos del puesto);
- Aspectos destacados del puesto;
- Enlace de postulación;
- Fuente de información;
- Estado y campos de cambio.
daily/ es una instantánea de auditoría interna; outbox/ es una copia interna de la lista de chat actual. El usuario no necesita abrir estos archivos. Los puestos seen, expired y duplicados del mismo lote no deben ser repetidos.
Paso 5: Después de Procesar los Resultados, Preguntar si se Activan las Notificaciones de Actualización
Después de la primera ejecución, cuando se haya entregado la lista de puestos al usuario, pregunte: "¿Me permite notificarle cuando haya puestos nuevos o cambios?"
- Si el usuario no lo permite: establezca
schedule.notify_on_updateenfalse(valor predeterminado), termine, no haga nada adicional; - Si el usuario lo permite: establezca
schedule.notify_on_updateentruey, según el Paso 6, organice las ejecuciones periódicas posteriores.
El usuario puede cambiar de opinión en cualquier momento: si dice "no quiero notificaciones", cambie notify_on_update de nuevo a false, y aunque haya nuevos puestos o cambios, no se enviarán activamente; si dice "reactivar notificaciones", cámbielo de nuevo a true. Es un interruptor que se puede activar y desactivar repetidamente, no una configuración única.
Paso 6: Notificaciones Periódicas (Solo cuando notify_on_update sea true)
El significado de la notificación periódica es simple: cada cierto tiempo, hacer que el Agente vuelva a ejecutar este Skill (volver a recopilar → deduplicar → comparar con el estado histórico).
- Si en esta ejecución hay puestos "nuevos" o "modificados", envíe la lista a la conversación actual;
- Si no hay ningún cambio nuevo, no envíe nada, manténgase en silencio, no moleste al usuario.
Solo depende de "volver a ejecutar + comparar con el estado histórico", no utiliza ventanas emergentes del sistema, correos electrónicos ni Webhooks. "Quién desencadena la re-ejecución" se divide en dos niveles, desde lo general hasta lo mejorado:
6.1 Nivel Predeterminado (Para Todos, Configuración Cero, Multiplataforma y Multimodelo)
Cualquier persona que clone este Skill utiliza este nivel por defecto, sin depender de ningún temporizador:
- Actualización incremental al iniciar la conversación (este es el "recolector diario" universal): Cuando este Skill se activa en una sesión y
notify_on_updateestruey ha pasado un día desde la última ejecución, el Agente automáticamente utiliza la búsqueda en red integrada del anfitrión para volver a recopilar las empresas que le interesan al usuario (como ByteDance, Alibaba) → deduplicar → comparar con el estado histórico → solo enviar los puestos nuevos/modificados al usuario, sin actualizaciones permanece en silencio. El usuario no necesita decir "verifica" cada vez, ni necesita configurar ningún comando en segundo plano. Dado que el usuario abre su cliente de IA todos los días, la tarea de "descubrir nuevos puestos" que requiere conexión a la red ocurre naturalmente en la primera conversación del día — esta es la única forma de recopilación que es de configuración cero, sin costo y no vinculada a un dispositivo para todos los usuarios de GitHub. - Activación por parte del usuario: El usuario puede decir "verifica / mira si hay nuevos" en cualquier momento, y se vuelve a ejecutar de inmediato.
- Añada
--heartbeata la entrada diaria, sin actualizaciones sin salida, solo con actualizaciones se responde con la lista:
python3 "$SKILL_DIR/scripts/run_daily.py" \
--project-config "$SKILL_DIR/config/project.json" --heartbeat
Cuando notify_on_update es true, run_daily.py incluye automáticamente el latido, no es necesario agregar el parámetro manualmente.
6.2 Nivel Mejorado Opcional: Ejecución Programada por el Anfitrión / Sistema ("Notificaciones Automáticas a una Hora Fija Cada Día")
Cuando el usuario quiere explícitamente "notificaciones automáticas a una hora fija cada día", implemente según la siguiente prioridad y explique honestamente los costos:
- Priorice el uso de la capacidad de temporización o recordatorio integrada del Agente / Cliente anfitrión (si la tiene) para que ejecute este Skill a la hora indicada, es lo más sencillo y no requiere tocar el sistema.
- Si el anfitrión no tiene capacidad de temporización, use el script multiplataforma scripts/schedule_task.py para registrar una tarea programada nativa del sistema operativo (macOS launchd / Linux cron / Programador de tareas de Windows). Al ejecutarse, genera la configuración según el sistema del usuario y la hora seleccionada, sin rutas fijas ni vinculación al dispositivo del mantenedor:
# Vista previa primero (por defecto print, no modifica el sistema, seguro):
python3 "$SKILL_DIR/scripts/schedule_task.py" --action print --time 08:00
# Una vez que el usuario confirma, se instala realmente (modificará esta máquina):
python3 "$SKILL_DIR/scripts/schedule_task.py" --action install --time 08:00
# Ver / desinstalar:
python3 "$SKILL_DIR/scripts/schedule_task.py" --action status
python3 "$SKILL_DIR/scripts/schedule_task.py" --action remove
Antes de instalar, primero debe mostrar una vista previa con print y obtener el consentimiento del usuario; después del consentimiento, escriba la hora seleccionada por el usuario en schedule.time y establezca schedule.enabled en true.
Debe explicar claramente al usuario dos limitaciones reales (no ocultarlas, no exagerarlas como "24 horas en la nube"):
- La computadora debe estar encendida: La tarea programada del sistema solo se activa a la hora indicada si la computadora está encendida; si está apagada / en hibernación, no se ejecutará y no se recuperará.
- La tarea programada en sí misma no "vuelve a buscar puestos en la red":
run_daily.pypor defecto solo vuelve a procesar las entradas existentes (deduplicación, cambios, archivo de vencidos), por lo tantocollector.commandenconfig/project.jsondebe mantenerse vacío por defecto y debe permanecer vacío (la razón está en lacommand_notede ese campo). Esto no es un defecto: el verdadero descubrimiento de nuevos puestos lo realiza el "recolector automático al iniciar la conversación" del nivel 6.1, que es de configuración cero y sin costo para todos los usuarios. No existe un comando de red en segundo plano que sea "a la vez universal, gratuito y ejecutable para todos los usuarios de GitHub", así que no intente fijarcollector.commandpara que la tarea programada busque nuevos puestos.
- Si el anfitrión no admite temporización y el usuario no quiere usar tareas del sistema, vuelva al nivel predeterminado: dígale al usuario "La próxima vez que me use, se actualizará automáticamente de forma incremental, o puede decir 'verifica' en cualquier momento", nunca use una tarea programada del sistema local para hacerse pasar por una notificación automática en la nube.
Validación
bash "$SKILL_DIR/scripts/validate_skill.sh"
La validación debe demostrar:
- La primera ejecución produce puestos nuevos;
- La misma entrada ejecutada nuevamente no envía puestos duplicados;
- Los puestos duplicados entre fuentes solo conservan la fuente más fuerte;
- Cuando los campos cambian, se genera
changedy los campos de cambio específicos; - La entrada con cambios ejecutada nuevamente se convierte en
seen; - Los puestos con fecha límite clara y fecha vencida entran en
expired; - Los puestos vencidos no aparecen en la lista de chat;
- Ciudad, tipo de reclutamiento, fecha de publicación, fecha límite, fuente y aspectos destacados aparecen en la lista de chat;
- El comando predeterminado genera directamente la lista de chat, JSON solo se usa para pruebas automatizadas.
Seguridad y Autenticidad
- Solo acceda a páginas públicas, no extraiga contenido detrás de inicio de sesión, interno o interfaces no públicas;
- No almacene cookies, contraseñas de cuentas, información privada de contactos de reclutamiento;
- No evite CAPTCHAs, anti-scraping o restricciones de acceso;
- Fechas desconocidas escriba
unknown, no adivine; - El estado interno y la lista de chat conservan el nombre de la fuente, el nivel, el enlace y la hora de la extracción;
- Todos los puestos deben ser verificados nuevamente en el sitio web oficial de reclutamiento de la empresa antes de postularse.