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érequisLien direct vers Prérequis
- Node.js
v22.13.0ou version ultérieure est installé - Une clé API d’un fournisseur de modèles pris en charge
- Un projet Mastra existant (suivez le guide d’installation pour configurer un nouveau projet)
Créer le WorkflowLien 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.
Créez un fichier
src/mastra/workflows/candidate-workflow.tset définissez votre Workflow :src/mastra/workflows/candidate-workflow.tsimport { 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()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,resumeTextest accessible dansexecute(). 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.tsexistant :src/mastra/workflows/candidate-workflow.tsimport { 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?.resumeTextconst 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.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.tsexistant :src/mastra/workflows/candidate-workflow.tsconst 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 questionfor ${candidateInfo?.candidateName} about how they got into "${candidateInfo?.specialty}".Resume: ${candidateInfo?.resumeText}`const res = await recruiter.generate(prompt)return { question: res?.text?.trim() || '' }},})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.tsexistant :src/mastra/workflows/candidate-workflow.tsconst 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 questionfor ${candidateInfo?.candidateName} asking what interests them most about this role.Resume: ${candidateInfo?.resumeText}`const res = await recruiter.generate(prompt)return { question: res?.text?.trim() || '' }},})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înezgatherCandidateInfoavecaskAboutSpecialtyetaskAboutRole.Dans le fichier
src/mastra/workflows/candidate-workflow.tsexistant, modifiezcandidateWorkflowcomme suit :src/mastra/workflows/candidate-workflow.tsexport 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()Dans votre fichier
src/mastra/index.ts, enregistrez le Workflow :src/mastra/index.tsimport { Mastra } from '@mastra/core'import { candidateWorkflow } from './workflows/candidate-workflow'export const mastra = new Mastra({workflows: { candidateWorkflow },})
Tester le WorkflowLien 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 :
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 !