用 n8n 做一条 HR 内容生成与审批流,我最后只自动化了前半段
这条流程的输入很简单:业务方提交岗位信息,n8n 生成 JD 草稿、面试邀约模板和候选人沟通注意事项,然后发到 Slack 或飞书让招聘同事确认。我的原则是,凡是会被候选人直接看到的内容,都必须有人点确认。
1. 流程结构
我最终保留了 6 个节点:
Webhook -> Set -> AI Agent -> Function -> Approval Message -> Database
Webhook 接收岗位表单,Set 节点整理字段,AI Agent 起草内容,Function 节点做长度和敏感词检查,Approval Message 发给负责人,Database 记录状态。表单字段不要太多,先收这些就够:
{"job_title":"后端工程师","level":"P6","location":"上海","must_have":["Node.js","PostgreSQL","云服务经验"],"manager_note":"团队需要能独立推进内部工具的人"}
2. AI 节点 Prompt
我没有让模型一次写完所有东西,而是要求它输出固定 JSON,后续节点再拆:
你是招聘运营助理。请根据输入生成三段内容:jd_draft、interview_invite、risk_notes。避免夸张表达,只输出 JSON,不要输出解释。
固定结构会牺牲一点自由度,但能明显减少下游节点解析失败。我的实际模板里还会要求“不要承诺薪酬范围之外的内容,不要替用人经理判断候选人是否合适”。
3. Function 节点做硬校验
AI 生成后,我用 Function 节点挡掉几类问题:
const item = $json;
const text = `${item.jd_draft}\n${item.interview_invite}`;
const banned = ['保底', '轻松月入', '不限年龄'];
const hit = banned.filter(word => text.includes(word));
return [{ json: { ...item, needs_review: hit.length > 0 || text.length > 1800, review_reason: hit.length ? `命中敏感词:${hit.join(',')}` : '' } }];
这里不要迷信模型自检。像“年龄不限”这种表达,最好用硬规则直接拦。
4. 审批消息要短
我最开始把完整 JD、邀约、风险备注都塞进通知,结果没人愿意看。后来改成摘要 + 链接:
岗位:{{$json.job_title}}
地点:{{$json.location}}
风险:{{$json.review_reason || '未命中硬规则'}}
请在后台确认 JD 和候选人沟通文案。
审批系统如果暂时没有,可以先写入 Google Sheet 或内部表格,把记录 ID 放进消息。重点是让“谁确认过”有痕迹。
5. 失败重试
n8n 的坑不在“能不能跑”,而在“失败后谁知道”。我给 AI 节点和消息节点都加了错误分支,写一条失败记录。模型超时后不要立刻循环重试三次。我的设置是第一次失败等 2 分钟,第二次失败就转人工处理。候选人沟通场景里,稳定比省几分钟重要。
6. 复盘
这条流程上线后,省下来的不是“写字时间”,而是减少了从零开始的摩擦。招聘同事仍然要改标题、确认岗位真实卖点、删掉过度顺滑的话。n8n 适合做管道,AI 适合做草稿,最后的判断仍然要留在人那里。