Aller au contenu principal

Créer un recruteur avec l’IA

Dans ce guide, vous découvrirez comment Mastra vous aide à créer des Workflows avec des LLM.

Vous créerez un Workflow qui recueille des informations à partir du CV d’un candidat, puis se ramifie vers une question technique ou comportementale selon le profil du candidat. Vous verrez au passage comment structurer les étapes d’un Workflow, gérer les ramifications et intégrer des appels à des LLM.

Prérequis
Lien direct vers Prérequis

Créer le Workflow
Lien direct vers Créer le Workflow

Configurez le Workflow, définissez les étapes qui extraient et classifient les données du candidat, puis posez des questions de suivi adaptées.

  1. Créez un fichier src/mastra/workflows/candidate-workflow.ts et définissez votre Workflow :

    src/mastra/workflows/candidate-workflow.ts
    import { createWorkflow, createStep } from '@mastra/core/workflows'
    import { z } from 'zod'

    export const candidateWorkflow = createWorkflow({
    id: 'candidate-workflow',
    inputSchema: z.object({
    resumeText: z.string(),
    }),
    outputSchema: z.object({
    askAboutSpecialty: z.object({
    question: z.string(),
    }),
    askAboutRole: z.object({
    question: z.string(),
    }),
    }),
    }).commit()
  2. Vous souhaitez extraire les informations du candidat du texte de son CV et le classer comme « technique » ou « non technique ». Cette étape appelle un LLM pour analyser le CV et retourne un JSON structuré comprenant le nom, le statut technique, la spécialité et le texte original du CV. Défini par inputSchema, resumeText est accessible dans execute(). Utilisez-le pour envoyer un prompt à un LLM et retourner les champs organisés.

    Ajoutez ce qui suit au fichier src/mastra/workflows/candidate-workflow.ts existant :

    src/mastra/workflows/candidate-workflow.ts
    import { Agent } from '@mastra/core/agent'

    const recruiter = new Agent({
    id: 'recruiter-agent',
    name: 'Recruiter Agent',
    instructions: `You are a recruiter.`,
    model: 'openai/gpt-5.6-sol',
    })

    const gatherCandidateInfo = createStep({
    id: 'gatherCandidateInfo',
    inputSchema: z.object({
    resumeText: z.string(),
    }),
    outputSchema: z.object({
    candidateName: z.string(),
    isTechnical: z.boolean(),
    specialty: z.string(),
    resumeText: z.string(),
    }),
    execute: async ({ inputData }) => {
    const resumeText = inputData?.resumeText

    const prompt = `Extract details from the resume text:
    "${resumeText}"`

    const res = await recruiter.generate(prompt, {
    structuredOutput: {
    schema: z.object({
    candidateName: z.string(),
    isTechnical: z.boolean(),
    specialty: z.string(),
    resumeText: z.string(),
    }),
    },
    })

    return res.object
    },
    })

    Comme vous utilisez un Agent Recruiter dans execute(), vous devez le définir au-dessus de l’étape et ajouter les imports nécessaires.

  3. Cette étape demande à un candidat identifié comme « technique » des informations sur la manière dont il est arrivé à sa spécialité. Elle utilise l’intégralité du texte du CV afin que le LLM puisse rédiger une question de suivi pertinente.

    Ajoutez ce qui suit au fichier src/mastra/workflows/candidate-workflow.ts existant :

    src/mastra/workflows/candidate-workflow.ts
    const askAboutSpecialty = createStep({
    id: 'askAboutSpecialty',
    inputSchema: z.object({
    candidateName: z.string(),
    isTechnical: z.boolean(),
    specialty: z.string(),
    resumeText: z.string(),
    }),
    outputSchema: z.object({
    question: z.string(),
    }),
    execute: async ({ inputData: candidateInfo }) => {
    const prompt = `You are a recruiter. Given the resume below, craft a short question
    for ${candidateInfo?.candidateName} about how they got into "${candidateInfo?.specialty}".
    Resume: ${candidateInfo?.resumeText}`
    const res = await recruiter.generate(prompt)

    return { question: res?.text?.trim() || '' }
    },
    })
  4. Si le candidat est « non technique », vous souhaitez poser une question de suivi différente. Cette étape lui demande ce qui l’intéresse le plus dans le poste, en se référant de nouveau à l’intégralité de son CV. La fonction execute() demande au LLM une question axée sur le poste.

    Ajoutez ce qui suit au fichier src/mastra/workflows/candidate-workflow.ts existant :

    src/mastra/workflows/candidate-workflow.ts
    const askAboutRole = createStep({
    id: 'askAboutRole',
    inputSchema: z.object({
    candidateName: z.string(),
    isTechnical: z.boolean(),
    specialty: z.string(),
    resumeText: z.string(),
    }),
    outputSchema: z.object({
    question: z.string(),
    }),
    execute: async ({ inputData: candidateInfo }) => {
    const prompt = `You are a recruiter. Given the resume below, craft a short question
    for ${candidateInfo?.candidateName} asking what interests them most about this role.
    Resume: ${candidateInfo?.resumeText}`
    const res = await recruiter.generate(prompt)
    return { question: res?.text?.trim() || '' }
    },
    })
  5. Vous combinez maintenant les étapes pour implémenter une logique de ramification fondée sur le statut technique du candidat. Le Workflow recueille d’abord les données du candidat, puis pose une question sur sa spécialité ou son poste selon la valeur de isTechnical. Pour cela, enchaînez gatherCandidateInfo avec askAboutSpecialty et askAboutRole.

    Dans le fichier src/mastra/workflows/candidate-workflow.ts existant, modifiez candidateWorkflow comme suit :

    src/mastra/workflows/candidate-workflow.ts
    export const candidateWorkflow = createWorkflow({
    id: 'candidate-workflow',
    inputSchema: z.object({
    resumeText: z.string(),
    }),
    outputSchema: z.object({
    askAboutSpecialty: z.object({
    question: z.string(),
    }),
    askAboutRole: z.object({
    question: z.string(),
    }),
    }),
    })
    .then(gatherCandidateInfo)
    .branch([
    [async ({ inputData: { isTechnical } }) => isTechnical, askAboutSpecialty],
    [async ({ inputData: { isTechnical } }) => !isTechnical, askAboutRole],
    ])
    .commit()
  6. Dans votre fichier src/mastra/index.ts, enregistrez le Workflow :

    src/mastra/index.ts
    import { Mastra } from '@mastra/core'
    import { candidateWorkflow } from './workflows/candidate-workflow'

    export const mastra = new Mastra({
    workflows: { candidateWorkflow },
    })

Tester le Workflow
Lien direct vers Tester le Workflow

Vous pouvez tester votre Workflow dans Studio en démarrant le serveur de développement :

mastra dev

Dans la barre latérale, accédez à Workflows et sélectionnez candidate-workflow. Au centre, vous verrez une vue graphique de votre Workflow et, dans la barre latérale droite, l’onglet Run est sélectionné par défaut. Dans cet onglet, vous pouvez saisir le texte d’un CV, par exemple :

Knowledgeable Software Engineer with more than 10 years of experience in software development. Proven expertise in the design and development of software databases and optimization of user interfaces.

Après avoir saisi le texte du CV, appuyez sur le bouton Run. Vous devriez alors voir deux panneaux d’état, GatherCandidateInfo et AskAboutSpecialty, qui contiennent la sortie des étapes du Workflow.

Vous pouvez aussi tester le Workflow par programmation en appelant .createRun() et .start(). Créez un fichier src/test-workflow.ts et ajoutez ce qui suit :

src/test-workflow.ts
import { mastra } from './mastra'

const run = await mastra.getWorkflow('candidateWorkflow').createRun()

const res = await run.start({
inputData: {
resumeText:
'Knowledgeable Software Engineer with more than 10 years of experience in software development. Proven expertise in the design and development of software databases and optimization of user interfaces.',
},
})

// Dump the complete workflow result (includes status, steps and result)
console.log(JSON.stringify(res, null, 2))

// Get the workflow output value
if (res.status === 'success') {
const question = res.result.askAboutRole?.question ?? res.result.askAboutSpecialty?.question

console.log(`Output value: ${question}`)
}

Exécutez maintenant le Workflow et obtenez la sortie dans votre terminal :

npx tsx src/test-workflow.ts

Vous avez créé un Workflow qui analyse un CV et décide quelle question poser selon les compétences techniques du candidat. Félicitations et bon développement !