Revisa ofertas de empleo de agencias de selección con Claude Code
Detecta datos ausentes, frases ambiguas, riesgos y diferencias con JobPosting antes de publicar una oferta.
En una agencia de selección, una oferta puede pasar por la persona comercial, el consultor que habla con candidatos y el cliente antes de publicarse. Cada parte añade información distinta. El resultado suele sonar atractivo, pero deja sin respuesta lo que una persona necesita para decidir: salario, lugar de trabajo, tareas del primer mes, modalidad remota, horario, evaluación y etapas del proceso.
El problema aumenta cuando alguien pide a Claude Code que «mejore la oferta para conseguir más candidaturas». Si la entrada mezcla datos confirmados con notas comerciales, la herramienta puede ordenar la redacción sin descubrir que falta una condición laboral. También puede conservar frases como «equipo joven» o «gran autonomía» que no explican el puesto y que requieren revisión humana.
Esta guía muestra un flujo de revisión para agencias que presentan puestos de empresas japonesas o publican ofertas sujetas a las reglas de Japón. Desde abril de 2024, el Ministerio de Salud, Trabajo y Bienestar de Japón exige mostrar datos adicionales en determinadas actividades de contratación e intermediación, como el alcance de posibles cambios de funciones y lugar de trabajo, además de los criterios de renovación de contratos de duración determinada. Las obligaciones cambian según el país, por lo que esta guía no sustituye una revisión jurídica local.
Puntos clave
- Revisa condiciones laborales y campos ausentes antes de embellecer el texto.
- Pide a Claude Code una tabla de dudas, frases ambiguas, señales de riesgo y diferencias con JobPosting.
- Mantén en manos humanas la interpretación legal, el salario, las excepciones por edad, el género, el contrato y la aprobación del cliente.
- Sustituye conceptos vagos por tareas, límites de decisión, formación inicial y criterios de evaluación.
- Mide correcciones, devoluciones del cliente, preguntas de candidatos, candidaturas, entrevistas y renuncias.
El fallo que se repite en una agencia
Una oferta suele nacer de cuatro fuentes: la descripción que entrega el cliente, las notas de la reunión comercial, el texto de una campaña anterior y las preguntas que recibe el consultor. Si nadie identifica qué fuente respalda cada afirmación, una nota como «dos días de trabajo remoto» puede acabar publicada aunque el cliente solo la comentara como posibilidad.
El candidato encuentra otro problema. «Tendrás autonomía» no indica cuántas cuentas gestionará, qué decisiones puede tomar o quién revisará su trabajo. «Salario hasta 6,5 millones de yenes» tampoco aclara qué experiencia corresponde al límite superior. Cuando esos datos aparecen tarde, aumenta el intercambio de mensajes y la renuncia antes de la entrevista.
La agencia está entre el cliente y la persona candidata. Una frase incorrecta puede dañar a ambos. Por eso la primera salida de Claude Code no debe ser una oferta lista para publicar, sino una lista corta de información ausente y preguntas para el cliente.
Regla operativa: Claude Code localiza diferencias y prepara preguntas. Una persona confirma los hechos y decide qué se publica.
Flujo de trabajo desde la recepción hasta la candidatura
Reúne los documentos en una carpeta de trabajo, pero elimina antes nombres de candidatos, empresa actual, notas de evaluación, negociación salarial y datos confidenciales del cliente. Si una duda se puede revisar sin identificar a la persona, usa una versión anónima.
| Material de entrada | Información que se recupera | Revisión humana |
|---|---|---|
| Oferta enviada por el cliente | puesto, tareas, salario y ubicación | condiciones y vigencia |
| Notas de la reunión comercial | motivo de contratación y equipo | confirmación del cliente |
| Preguntas de candidatos | dudas y criterios de comparación | ausencia de datos personales |
| Motivos de renuncia agregados | información que llegó demasiado tarde | muestra suficiente y contexto |
| Texto del portal de empleo | título, etiquetas y fecha de cierre | expresiones que pueden inducir a error |
| Bloque JSON-LD | puesto, ubicación, salario y fechas | coincidencia con el texto visible |
El flujo recomendado tiene cinco pasos:
- Extraer hechos y separar cada dato según su fuente.
- Marcar campos vacíos, contradictorios o pendientes de confirmación.
- Convertir las dudas en preguntas concretas para el cliente.
- Redactar una nueva versión solo con hechos aprobados.
- Comparar el texto visible, el portal externo y el bloque JobPosting antes de publicar.
Si el equipo todavía no tiene reglas para lectura, edición y aprobación, conviene revisar primero la lista de permisos para agencias. Así se evita que una automatización cambie una oferta ya aprobada sin dejar rastro.
Qué se delega y qué decide una persona
Claude Code encaja bien en tareas repetibles: extraer campos, comparar versiones, detectar expresiones imprecisas, agrupar preguntas y preparar una tabla de diferencias. También puede transformar «ambiente de crecimiento» en preguntas verificables: qué formación existe, cuánto dura, quién acompaña a la nueva incorporación y qué se espera al final del tercer mes.
Una persona conserva las decisiones que pueden afectar derechos, expectativas o compromisos comerciales. Debe confirmar el intervalo salarial, las horas extraordinarias, el tipo y duración del contrato, los criterios de renovación, las ubicaciones posibles, el alcance de cambios de puesto y cualquier excepción relacionada con edad o género.
Para puestos en Japón, consulta las fuentes oficiales sobre los datos añadidos a la información laboral desde abril de 2024, las restricciones de edad en la contratación y las reglas de igualdad en la selección. Para otros países, sustituye estas referencias por la autoridad laboral correspondiente y valida el proceso con un profesional.
Google también indica que los datos estructurados de ofertas de empleo deben representar el contenido de la página. No uses JSON-LD para mostrar a buscadores un salario, una ubicación o una modalidad que el candidato no puede comprobar en el texto visible.
Tres casos de uso en una situación real
Caso 1: convertir una promesa vaga en datos útiles
La entrada contiene la oferta, preguntas frecuentes y motivos de renuncia agregados. Claude Code devuelve tres columnas: frase ambigua, duda que provoca y dato que falta pedir al cliente.
Por ejemplo, «gran autonomía» puede transformarse en estas preguntas: ¿cuántos clientes gestiona el puesto?, ¿qué decisiones requieren aprobación?, ¿con qué frecuencia se revisan resultados?, ¿qué indicador se utiliza en la evaluación? La persona responsable elimina cualquier respuesta que el cliente no haya confirmado.
El beneficio no consiste en escribir más. Consiste en mover al principio de la página la información que permite decidir y reducir preguntas posteriores.
Caso 2: señalar expresiones de edad, género o experiencia
La entrada incluye título, requisitos obligatorios, requisitos deseables y etiquetas del portal. La salida separa la frase detectada, el motivo de la señal, una pregunta para el cliente y una posible alternativa basada en tareas o experiencia.
Una expresión como «ideal para menores de 30» no debe corregirse de forma automática ni publicarse porque la herramienta la haya aceptado. Se marca para revisión. El equipo comprueba la norma aplicable y cualquier excepción, y después decide si debe eliminarla o reformular el requisito con experiencia, disponibilidad o funciones reales.
Caso 3: comparar página, portal y JobPosting
La entrada contiene el texto visible, la versión enviada a un portal y el bloque JSON-LD. Claude Code compara title, hiringOrganization, jobLocation, baseSalary, employmentType, datePosted y validThrough.
Un caso habitual es que la página diga «oficina de Tokio», el portal muestre «remoto» y el bloque estructurado incluya varias regiones. La herramienta prepara la diferencia; una persona confirma ubicación, condiciones de teletrabajo, fecha de cierre y salario antes de unificar las tres versiones.
Prompt para copiar y adaptar
Actúa como revisor de ofertas de una agencia de selección.
Objetivo:
Encontrar información ausente, frases ambiguas, dudas de candidatos,
señales que necesitan revisión y diferencias con JobPosting antes de publicar.
Entrada:
- Empresa cliente:
- Puesto:
- Texto de la oferta:
- Motivo de contratación:
- Requisitos obligatorios:
- Requisitos deseables:
- Salario:
- Lugar de trabajo:
- Alcance de posibles cambios de funciones:
- Alcance de posibles cambios de lugar:
- Criterios de renovación del contrato:
- Etapas de selección:
- Preguntas frecuentes de candidatos, sin datos personales:
- Motivos de renuncia agregados:
- JobPosting JSON-LD:
Salida:
1. Tabla de datos ausentes o contradictorios
2. Frases que no permiten entender el trabajo
3. Señales relacionadas con edad, género o posibles errores
4. Información que conviene mover al principio
5. Diferencias entre texto visible, portal y JobPosting
6. Preguntas que debe responder el cliente
Límites:
- No emitas conclusiones jurídicas
- No inventes salario, ubicación, edad, género ni condiciones del contrato
- No incluyas nombres, empresa actual ni evaluaciones de candidatos
- Distingue siempre entre dato confirmado, dato pendiente e inferencia
- No redactes la versión final hasta recibir las respuestas del cliente
Una primera ejecución debe producir preguntas, no una promesa de publicación automática. Después de recibir respuestas, ejecuta un segundo prompt que solo acepte los datos marcados como confirmados.
Código ejecutable para revisar los campos mínimos
Este ejemplo de Node.js no evalúa la legalidad de una oferta. Comprueba que el borrador contiene campos básicos, busca señales en todos los textos que verá el candidato, valida la estructura del salario y exige una sola acción principal. La búsqueda recorre también businessScope, requisitos y futuros campos de texto, no solo el resumen final.
const jobPostDraft = {
clientName: "Empresa SaaS de ejemplo",
roleTitle: "Especialista en éxito del cliente",
businessScope: "Incorporación, revisión de uso y propuestas de renovación",
workLocation: "Shibuya, Tokio / remoto dos días por semana",
locationChangeScope: "Sede, oficinas definidas por la empresa y domicilio autorizado",
workChangeScope: "Éxito del cliente, planificación comercial y soporte",
salaryRange: "4.800.000 JPY a 6.500.000 JPY al año",
contractRenewal: "Contrato indefinido",
workingHours: "9:30 a 18:30 / descanso de 60 minutos",
overtime: "Promedio de 20 horas al mes",
requiredSkills: ["Atención a clientes empresariales", "Uso de servicios SaaS o informáticos"],
preferredSkills: ["Conocimientos básicos de SQL", "Experiencia con Salesforce"],
reviewText: "El puesto atiende incorporación, revisión de uso, renovaciones y consultas.",
ctas: ["candidateApply"],
};
const riskyPhraseRules = [
{ label: "restricción por edad", pattern: /\b(?:solo\s+)?menores?\s+de\s+\d+\b/iu },
{ label: "restricción por género", pattern: /\bsolo\s+(?:para\s+)?mujeres\b/iu },
{ label: "restricción por género", pattern: /\bsolo\s+(?:para\s+)?hombres\b/iu },
{ label: "edad como cultura", pattern: /\bequipo\s+(?:exclusivamente\s+)?joven\b/iu },
{ label: "promesa no demostrada", pattern: /\bcrecimiento\s+garantizado\b/iu },
];
const requiredFields = [
"clientName",
"roleTitle",
"businessScope",
"workLocation",
"locationChangeScope",
"workChangeScope",
"salaryRange",
"contractRenewal",
"workingHours",
"overtime",
];
const nonReaderFacingFields = new Set(["ctas"]);
function collectReaderFacingText(value, path = "") {
if (typeof value === "string") return [{ path, value }];
if (Array.isArray(value)) {
return value.flatMap((item, index) => collectReaderFacingText(item, `${path}[${index}]`));
}
if (!value || typeof value !== "object") return [];
return Object.entries(value).flatMap(([key, item]) => {
if (nonReaderFacingFields.has(key)) return [];
const childPath = path ? `${path}.${key}` : key;
return collectReaderFacingText(item, childPath);
});
}
function parseAmount(token) {
const compact = token.replace(/\s/gu, "");
if (/^\d{1,3}(?:\.\d{3})+(?:,\d+)?$/u.test(compact)) {
return Number(compact.replace(/\./gu, "").replace(",", "."));
}
if (/^\d{1,3}(?:,\d{3})+(?:\.\d+)?$/u.test(compact)) {
return Number(compact.replace(/,/gu, ""));
}
if (/^\d+(?:[.,]\d{1,2})?$/u.test(compact)) {
return Number(compact.replace(",", "."));
}
return Number.NaN;
}
function hasValidSalaryRange(value) {
if (typeof value !== "string") return false;
const currencyPattern =
/(?:\b(?:JPY|EUR|USD|GBP|MXN|ARS|CLP|COP|PEN)\b|[¥€$]|\b(?:yenes?|euros?|dólares?|pesos?|soles?)\b)/iu;
const amountTokens =
value.match(/\d{1,3}(?:[.\s,]\d{3})+(?:[.,]\d+)?|\d+(?:[.,]\d+)?/gu) ?? [];
const amounts = amountTokens.map(parseAmount);
if (!currencyPattern.test(value)) return false;
if (amounts.length < 1 || amounts.length > 2) return false;
if (amounts.some((amount) => !Number.isFinite(amount) || amount <= 0)) return false;
if (amounts.length === 1) return true;
const hasRangeConnector = /(?:\s(?:a|hasta)\s|[-–—])/iu.test(value);
return hasRangeConnector && amounts[0] <= amounts[1];
}
function validateJobPost(draft) {
const errors = [];
const missing = requiredFields.filter((field) => !draft[field]);
if (missing.length) errors.push(`Campos ausentes: ${missing.join(", ")}`);
for (const { path, value } of collectReaderFacingText(draft)) {
for (const rule of riskyPhraseRules) {
if (rule.pattern.test(value)) errors.push(`${path}: ${rule.label}`);
}
}
if (!hasValidSalaryRange(draft.salaryRange)) {
errors.push("salaryRange: debe incluir un importe numérico o un rango válido y una moneda");
}
const hasOneCta =
Array.isArray(draft.ctas) &&
draft.ctas.length === 1 &&
draft.ctas[0] === "candidateApply";
if (!hasOneCta) errors.push("ctas: debe contener solo candidateApply");
return errors;
}
const positiveErrors = validateJobPost(jobPostDraft);
if (positiveErrors.length) {
console.error("El ejemplo válido no superó la revisión:");
console.error(positiveErrors);
process.exit(1);
}
const negativeFixtures = [
{
name: "expresión peligrosa en businessScope",
draft: { ...jobPostDraft, businessScope: "Atención al cliente, solo mujeres" },
expectedError: "businessScope: restricción por género",
},
{
name: "expresión peligrosa dentro de una lista",
draft: {
...jobPostDraft,
preferredSkills: ["SQL", "Experiencia en un equipo exclusivamente joven"],
},
expectedError: "preferredSkills[1]: edad como cultura",
},
{
name: "salario sin importe ni moneda",
draft: { ...jobPostDraft, salaryRange: "salario por confirmar" },
expectedError: "salaryRange: debe incluir un importe numérico o un rango válido y una moneda",
},
{
name: "rango salarial sin moneda",
draft: { ...jobPostDraft, salaryRange: "4.800.000 a 6.500.000 al año" },
expectedError: "salaryRange: debe incluir un importe numérico o un rango válido y una moneda",
},
{
name: "rango salarial invertido",
draft: { ...jobPostDraft, salaryRange: "6.500.000 JPY a 4.800.000 JPY al año" },
expectedError: "salaryRange: debe incluir un importe numérico o un rango válido y una moneda",
},
];
const fixtureFailures = negativeFixtures.flatMap((fixture) => {
const errors = validateJobPost(fixture.draft);
return errors.includes(fixture.expectedError)
? []
: [`${fixture.name}: se esperaba "${fixture.expectedError}"; se obtuvo ${JSON.stringify(errors)}`];
});
if (fixtureFailures.length) {
console.error("Fallaron los casos negativos:");
console.error(fixtureFailures);
process.exit(1);
}
console.log(
`La lista de comprobación está preparada; ${negativeFixtures.length} casos negativos fueron rechazados.`,
);
Guarda el bloque como review-job-post.js y ejecútalo con node review-job-post.js. El proceso termina con código de salida 0 solo si el ejemplo válido pasa y los cinco casos negativos son rechazados. Las pruebas colocan «solo mujeres» en businessScope, una frase de edad dentro de preferredSkills y tres salarios inválidos en salaryRange: un marcador pendiente, un rango sin moneda y un rango invertido.
Errores frecuentes y cómo corregirlos
Error 1: pedir una versión más persuasiva antes de validar los datos. La redacción oculta huecos con frases atractivas. Corrige el orden: primero tabla de ausencias, después preguntas al cliente y solo al final nueva redacción.
Error 2: dejar «equipo joven» como una ventaja genérica. La frase no explica el trabajo y puede abrir una revisión normativa. Sustitúyela por tamaño del equipo, formación inicial, herramientas, funciones y experiencia necesaria.
Error 3: destacar solo el límite superior del salario. El candidato interpreta el máximo como una expectativa probable. Pide al cliente los requisitos, responsabilidades y criterios que corresponden a cada parte del intervalo.
Error 4: actualizar JSON-LD sin actualizar la página. El buscador recibe información distinta a la persona candidata. Compara el texto visible, el portal y el bloque estructurado en una misma revisión.
Error 5: introducir notas personales en el contexto. Una evaluación de entrevista no es necesaria para comprobar una oferta. Trabaja con preguntas y motivos agregados, y elimina identificadores antes de usar la herramienta.
Error 6: tratar una señal automática como decisión legal. Una coincidencia solo indica qué revisar. La decisión final corresponde a una persona que conoce el puesto, el país y la norma aplicable.
Cómo medir el resultado y estimar el retorno
No atribuyas valor solo al número de candidaturas. Registra durante cuatro semanas la cantidad de correcciones por oferta, devoluciones del cliente, días hasta publicar, preguntas posteriores, tasa de candidatura, paso a entrevista y motivos de renuncia.
Una estimación sencilla del ahorro mensual es:
ahorro mensual = ofertas revisadas × minutos evitados por oferta × coste por minuto
Si una agencia revisa 40 ofertas al mes y evita 20 minutos de búsqueda y comparación en cada una, recupera 800 minutos. Esa cifra es una estimación operativa, no una promesa de conversión. Añade por separado el coste de configuración, revisión humana y mantenimiento.
Interpreta las métricas en conjunto. Si aumentan las candidaturas pero cae el paso a entrevista, la oferta quizá atraiga perfiles demasiado amplios. Si persisten muchas devoluciones del cliente, faltan preguntas en la recepción. Si baja el tiempo de publicación pero suben las correcciones después de publicar, el control final es insuficiente.
Preguntas frecuentes
¿Hay que eliminar toda referencia a edad o género? No decidas mediante una sustitución mecánica. Marca la frase, identifica el país y deja que una persona revise la norma, las excepciones y la necesidad real del puesto.
¿Claude Code puede hacer la revisión jurídica? No. Puede encontrar campos, contradicciones y señales. La interpretación legal y la aprobación siguen en manos humanas.
¿Una agencia necesita JobPosting? Puede ser relevante si publica páginas individuales de empleo. El bloque estructurado debe coincidir con la información que ve el candidato y cumplir la documentación vigente de Google.
¿Qué información no debe entrar en el contexto? Nombres de candidatos, empresa actual, comentarios de entrevista, negociación individual y secretos del cliente. Sustituye esos datos por patrones agregados y preguntas anónimas.
Una única salida para implantarlo en el equipo
Una agencia con varios consultores necesita acordar fuentes permitidas, campos obligatorios, responsables de aprobación y registro de cambios. Reúne una oferta reciente, las preguntas del cliente, una lista anónima de dudas de candidatos y el bloque JSON-LD. Con ese material se puede diseñar un flujo pequeño antes de extenderlo a todo el catálogo.
La vía principal para implantarlo es la formación y consultoría de ClaudeCodeLab. El objetivo de la sesión es separar qué revisa Claude Code, qué aprueba la agencia y qué debe confirmar el cliente, dejando una lista de comprobación reutilizable y un criterio de publicación.
Resultado comprobado
Para preparar esta guía se contrastaron las tres referencias del Ministerio de Salud, Trabajo y Bienestar de Japón enlazadas arriba y la documentación de Google sobre JobPosting. También se ejecutó el bloque de Node.js con los datos ficticios incluidos en el artículo: aceptó el borrador válido y rechazó los cinco casos negativos por el motivo esperado. Así se comprobó la detección en businessScope, dentro de una lista y ante salarios pendientes, sin moneda o con el rango invertido.
La comprobación no demuestra que una oferta concreta cumpla la ley ni que vaya a recibir más candidaturas. Sí demuestra que el ejemplo se ejecuta y que detecta las condiciones que declara revisar. El primer paso para un equipo principiante es tomar una oferta y dividirla en cuatro columnas: condiciones, dudas del candidato, señales para revisión y diferencias con JobPosting.
Artículos relacionados
Cómo crear ofertas de empleo y mensajes de captación en serie con Claude Code para tu agencia de reclutamiento
Para reclutadores: crea ofertas y mensajes de captación en serie con Claude Code sin perder calidad ni datos personales.
Cómo comparar ofertas y correos a candidatos con Claude Code antes de enviarlos
Workflow para agencias de reclutamiento: revisar ofertas, emails, notas del cliente y datos JobPosting antes del envío.
Agencias de empleo temporal: notas de matching y textos de oferta con Claude Code en 5 minutos
Coordinadores de empleo temporal: redacta notas de matching y ofertas con IA. Incluye prompt, checklist y script de verificación.
PDF gratis: cheatsheet de Claude Code
Introduce tu email y descarga una hoja con comandos, hábitos de revisión y flujos seguros.
Cuidamos tus datos y no enviamos spam.
Sobre el autor
Masa
Ingeniero enfocado en workflows prácticos con Claude Code.