2026-09-14 · 原文发布日
n8n模板:简历表单收集后自动解析打分并通知HR
免费模板,候选人通过n8n表单上传PDF简历,文件存Google Drive,文本交给gpt-4o-mini解析成结构化字段并清洗格式,再按工作年限和是否具备指定技能(默认React、Node.js、PostgreSQL)算匹配分,结果写入PostgreSQL候选人表并向HR的Slack频道推送详情与分数。技能关键词和评分规则可按岗位改。
原文要点
来源是WeblineIndia发布在n8n模板库的免费工作流:用n8n表单触发器收集候选人PDF简历,文件上传到指定Google Drive文件夹并提取文本,交给OpenAI的gpt-4o-mini解析成结构化候选人字段,再清洗姓名大小写、邮箱格式、工作年限数值,按工作年限加是否具备React、Node.js、PostgreSQL三技能计算匹配分,写入PostgreSQL的public.candidates表,最后向HR的Slack频道推送候选人详情与分数。页面未提供可下载的工作流JSON、提示词全文、评分公式细节与建表语句。
这次做成什么
在自有n8n实例搭通“简历表单→Drive存档→AI解析→打分→入库→通知HR”流水线,用一份虚构简历跑通。原页面不含可导入文件与评分公式,以下节点配置、提示词、打分代码、建表SQL均为本站按描述独立编写的重建方案,导入原模板后需逐项核对字段映射。
准备什么
- 可登录的n8n实例,且能对外公开表单URL(自托管需配置公网访问或隧道)
- Google账号并开通Drive API,可在n8n配置OAuth2凭据
- OpenAI API密钥且可调用gpt-4o-mini
- PostgreSQL数据库及建表、写表权限
- Slack工作区与可发消息的OAuth应用或Webhook
- 一份虚构候选人简历PDF,不得使用真实求职者信息
具体怎么做
建候选人表
在PostgreSQL执行下方材料的建表SQL,创建public.candidates,包含姓名、邮箱、年限、技能数组、匹配分等列,列名与后续映射保持一致。
配置表单触发器与Drive存档
添加n8n Form Trigger节点,表单加姓名、邮箱两个文本字段和一个只接受PDF的文件上传字段,发布后把表单URL发给测试者。其后接Google Drive节点(OAuth2凭据),Operation选Upload,把表单二进制文件上传到指定文件夹并记下返回的文件ID。
提取文本并调用OpenAI
接Extract from File节点从PDF提取文本;接OpenAI节点,Model选gpt-4o-mini,System消息用下方材料的完整提示词,User消息传入简历文本,要求JSON输出。再接Code节点做规范化:姓名每个单词首字母大写、邮箱转小写并trim、工作年限转数字。
计算匹配分
再接Code节点,使用下方材料的打分代码:年限每满1年得2分(上限20分),技能列表中每命中React、Node.js、PostgreSQL一个得10分,总分上限50分。技能关键词数组放在代码顶部常量,换岗位时只改这一行。
入库并通知HR
接Postgres节点把规范化字段与分数插入public.candidates;接Slack节点向HR频道发消息,正文含候选人姓名、邮箱、年限、命中技能与得分。手动执行一次并检查三处输出。
可直接复制的材料
简历字段提取提示词(粘贴到OpenAI节点System消息)
本站独立编写,原文未公开提示词;skills数组元素建议统一首字母大写以便打分匹配。
你是简历解析助手。从用户给的简历文本中提取字段并只返回一个JSON对象:{"name":候选人姓名字符串,"email":邮箱字符串,"experience_years":全职工作年限数字,只保留整数,"skills":技能字符串数组,只收技术技能,如["React","Node.js"],"current_title":最近职位字符串}。找不到的字段:字符串填null,数字填0,数组填空数组。不要输出JSON以外的任何文字。打分代码(粘贴到n8n Code节点)
本站独立设计的示例评分规则(年限封顶20分+每技能10分,总分50),原文只说有年限与技能两个维度、未给公式,可按岗位改REQUIRED与权重。
const REQUIRED = ["React", "Node.js", "PostgreSQL"];
return items.map(item => {
const d = item.json;
const years = Number(d.experience_years) || 0;
const skills = Array.isArray(d.skills) ? d.skills : [];
const hits = REQUIRED.filter(s => skills.includes(s));
const score = Math.min(years * 2, 20) + hits.length * 10;
return { json: { ...d, matched_skills: hits, score: Math.min(score, 50) } };
});建表SQL(在PostgreSQL执行一次)
本站独立编写的示例结构;若导入原模板,以模板实际映射列名为准。skills用TEXT[]对应数组。
CREATE TABLE IF NOT EXISTS public.candidates (
id SERIAL PRIMARY KEY,
name TEXT,
email TEXT,
experience_years INT,
skills TEXT[],
matched_skills TEXT[],
score INT,
drive_file_id TEXT,
created_at TIMESTAMP DEFAULT now()
);输入与输出示例
本站虚构演示输入与按本站评分规则推算的期望输出,非原作者运行结果,未实测。
输入
虚构简历:林晓舟,邮箱LIN.Xiaozhou@Example.COM,6年后端与全栈经验,最近职位高级全栈工程师,技术栈含React、Node.js、PostgreSQL、Docker、GraphQL。对应输出
规范化后name为“林晓舟”、email转为lin.xiaozhou@example.com、experience_years为6;打分:年限6×2=12分,命中React、Node.js、PostgreSQL三项得30分,合计42分。candidates表新增一行score=42,HR的Slack频道收到含姓名、邮箱、命中技能与42分的消息。做完检查这些
- 提交表单后Google Drive目标文件夹出现上传的PDF且文件ID写入candidates.drive_file_id
- candidates表新行的email已全部小写、experience_years为整数、skills为数组而非逗号字符串
- 手动核对打分:用example输入应得42分,与代码公式一致
- Slack的HR频道消息同时包含姓名、邮箱、年限、命中技能和得分五项
- 把REQUIRED改成岗位新技能(如Python)后重跑,分数随之变化
容易卡住的地方
- 自托管n8n的表单URL默认是localhost,候选人外网打不开,需配置公网地址
- Google Drive OAuth2凭据要用有目标文件夹写入权限的账号授权
- 技能匹配是精确字符串比较,简历写成react小写或Node都会漏配,可在规范化时统一大小写
- 原文未给评分公式与权重,本站公式只是示例,别当作原模板行为对外承诺
- PDF若是扫描图片版,文本提取为空,需另行OCR,本条流程不覆盖
本站借助AI整理来源事实,独立编写中文操作指南与示例。示例不代表实际运行结果;来源效果尚未由本站独立复现。付费模板与模型、服务费用分别计算。
- 原文标题
- Parse and score resumes with OpenAI GPT-4o, Google Drive, PostgreSQL and Slack
- 原作者
- WeblineIndia
- 原始发布日期
- 2026-09-14T08:49:26.953Z
- 来源
- https://n8n.io/workflows/19560