跳至主要內容

建置 AI 招募人員

在本指南中,你將了解 Mastra 如何協助你使用 LLM 建置 Workflow。

你將建立一個 Workflow,從應徵者的履歷中蒐集資訊,再根據應徵者的背景,分支至技術問題或行為問題。在這個過程中,你會了解如何組織 Workflow 步驟、處理分支,以及整合 LLM 呼叫。

先決條件
「先決條件」的直接連結

  • 已安裝 Node.js v22.13.0 或更新版本
  • 具備支援的 Model Provider 所提供的 API 金鑰
  • 已有 Mastra 專案(請依照安裝指南設定新專案)

建置 Workflow
「建置 Workflow」的直接連結

設定 Workflow、定義用於擷取及分類應徵者資料的步驟,接著提出合適的後續問題。

  1. 建立新檔案 src/mastra/workflows/candidate-workflow.ts,並定義你的 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. 你要從履歷文字中擷取應徵者詳細資料,並將對方分類為「技術」或「非技術」人員。此步驟會呼叫 LLM 解析履歷,並傳回結構化 JSON,其中包含姓名、是否為技術人員、專長,以及原始履歷文字。透過 inputSchema 定義後,你可以在 execute() 中存取 resumeText。使用它提示 LLM,並傳回整理後的欄位。

    將以下內容加入現有的 src/mastra/workflows/candidate-workflow.ts 檔案:

    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
    },
    })

    因為你在 execute() 中使用 Recruiter Agent,所以需要在該步驟上方定義它,並加入必要的 import。

  3. 此步驟會提示被判定為「技術」人員的應徵者,進一步說明他們如何踏入自己的專業領域。它會使用完整的履歷文字,讓 LLM 能擬出切合情境的後續問題。

    將以下內容加入現有的 src/mastra/workflows/candidate-workflow.ts 檔案:

    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. 如果應徵者是「非技術」人員,你會需要不同的後續問題。此步驟會詢問他們對這個職務最感興趣的部分,同樣會參照完整履歷文字。execute() 函式會請 LLM 產生聚焦於職務的問題。

    將以下內容加入現有的 src/mastra/workflows/candidate-workflow.ts 檔案:

    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. 現在,將這些步驟組合起來,依據應徵者是否為技術人員實作分支邏輯。Workflow 會先蒐集應徵者資料,再根據 isTechnical 詢問其專長或職務相關問題。做法是將 gatherCandidateInfoaskAboutSpecialtyaskAboutRole 串接起來。

    將現有 src/mastra/workflows/candidate-workflow.ts 檔案中的 candidateWorkflow 修改如下:

    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. src/mastra/index.ts 檔案中註冊此 Workflow:

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

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

測試 Workflow
「測試 Workflow」的直接連結

啟動開發伺服器後,你可以在 Studio 中測試 Workflow:

mastra dev

在側邊欄前往 Workflows,並選取 candidate-workflow。畫面中央會顯示 Workflow 的圖形檢視,右側邊欄則會預設選取 Run 分頁。你可以在此分頁輸入履歷文字,例如:

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.

輸入履歷文字後,按下 Run 按鈕。現在應該會看到兩個狀態方塊(GatherCandidateInfoAskAboutSpecialty),其中包含 Workflow 步驟的輸出。

你也可以呼叫 .createRun().start(),以程式方式測試 Workflow。建立新檔案 src/test-workflow.ts,並加入以下內容:

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}`)
}

現在執行 Workflow,並在終端機中取得輸出:

npx tsx src/test-workflow.ts

你已建置一個可解析履歷,並依據應徵者的技術能力決定要詢問哪個問題的 Workflow。恭喜完成,祝你開發愉快!