> Discover all available pages from the documentation index: https://mastra.zisheng.pro/fr/llms.txt # 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 - Node.js `v22.13.0` ou version ultérieure est installé - Une clé API d’un [fournisseur de modèles](https://mastra.zisheng.pro/fr/models) pris en charge - Un projet Mastra existant (suivez le [guide d’installation](https://mastra.zisheng.pro/fr/guides/getting-started/quickstart) pour configurer un nouveau projet) ## 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 : ```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 : ```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 : ```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 : ```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 : ```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 : ```ts import { Mastra } from '@mastra/core' import { candidateWorkflow } from './workflows/candidate-workflow' export const mastra = new Mastra({ workflows: { candidateWorkflow }, }) ``` ## Tester le Workflow Vous pouvez tester votre Workflow dans [Studio](https://mastra.zisheng.pro/fr/docs/studio/overview) en démarrant le serveur de développement : ```bash 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 : ```text 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()`](https://mastra.zisheng.pro/fr/reference/workflows/workflow-methods/create-run) et [`.start()`](https://mastra.zisheng.pro/fr/reference/workflows/run-methods/start). Créez un fichier `src/test-workflow.ts` et ajoutez ce qui suit : ```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 : ```bash 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 !