建構 AI 招聘人員
在本指南中,你會了解 Mastra 如何協助你使用 LLM 建構 Workflow。
你會建立一個 Workflow,從求職者的履歷收集資料,然後根據求職者的背景,分支至技術或行為問題。在過程中,你會了解如何組織 Workflow 步驟、處理分支,以及整合 LLM 呼叫。
先決條件先決條件 的直接連結
- 已安裝 Node.js
v22.13.0或更新版本 - 受支援的 Model Provider 所提供的 API 金鑰
- 現有的 Mastra 項目(請按照安裝指南設定新項目)
建構 Workflow建構 Workflow 的直接連結
設定 Workflow、定義用於擷取及分類求職者資料的步驟,然後提出合適的跟進問題。
建立新檔案
src/mastra/workflows/candidate-workflow.ts,並定義 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()你需要從履歷文字擷取求職者的詳細資料,並將對方分類為「技術」或「非技術」人員。這個步驟會呼叫 LLM 解析履歷,並傳回結構化 JSON,當中包括姓名、是否屬技術人員、專長及原始履歷文字。透過
inputSchema定義後,你便可存取resumeText,並在execute()內使用它。使用該內容向 LLM 發出提示,並傳回整理後的欄位。在現有的
src/mastra/workflows/candidate-workflow.ts檔案加入以下內容: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},})由於你在
execute()內使用招聘 Agent,因此需要在步驟上方定義它,並加入所需的匯入陳述式。這個步驟會要求識別為「技術」人員的求職者,進一步說明他們如何投身其專業領域。它會使用完整履歷文字,讓 LLM 能夠撰寫相關的跟進問題。
在現有的
src/mastra/workflows/candidate-workflow.ts檔案加入以下內容: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() || '' }},})如果求職者屬於「非技術」人員,你會需要另一個跟進問題。這個步驟會再次參考對方的完整履歷文字,詢問他們對該職位最感興趣的地方。
execute()函式會向 LLM 取得聚焦於職位的問題。在現有的
src/mastra/workflows/candidate-workflow.ts檔案加入以下內容: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() || '' }},})現在,你會組合這些步驟,根據求職者是否屬技術人員實作分支邏輯。Workflow 會先收集求職者資料,然後根據
isTechnical,詢問對方的專長或對職位的看法。這可透過串連gatherCandidateInfo、askAboutSpecialty及askAboutRole完成。在現有的
src/mastra/workflows/candidate-workflow.ts檔案中,按以下方式修改candidateWorkflow: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()在
src/mastra/index.ts檔案中註冊 Workflow:src/mastra/index.tsimport { 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 按鈕。此時,你應該會看到兩個狀態方塊(GatherCandidateInfo 及 AskAboutSpecialty),當中包含 Workflow 步驟的輸出。
你亦可以呼叫 .createRun() 及 .start(),以編程方式測試 Workflow。建立新檔案 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,可解析履歷,並根據求職者的技術能力決定要提出哪個問題。恭喜你,祝你編程愉快!