技术札记

从 0 到 1 构建招聘领域大模型:以 BOSS 直聘类场景为例

招聘大模型不是给聊天机器人接一个 API。本文从业务目标、招聘数据治理、领域继续预训练、SFT 与 DPO、RAG、人才匹配、评测、安全合规到 12 周落地计划,给出一套可复现的开源工程方案。

HOUHUIYANG.COM

扫码继续阅读

正在生成…

从 0 到 1 构建招聘领域大模型:以 BOSS 直聘类场景为例

houhuiyang.com/zh/notes/building-a-recruitment-llm-from-zero-to-one

如果让我从零开始,为一家类似 BOSS 直聘的招聘平台建设大模型,我不会先买 GPU,也不会先讨论做 7B、32B 还是 100B。

我会先问三个问题:

  1. 模型要改善哪一个业务结果?
  2. 我们拥有什么合法、独有、可以验证的数据?
  3. 哪些问题应该交给大模型,哪些仍然应该由搜索、推荐和规则系统完成?

招聘业务最容易犯的错误,是把“建设行业大模型”理解成训练一个会聊天的模型。真正可用的系统,不是一颗模型,而是一套由数据、检索、匹配、生成、风控、评测和人工决策共同组成的系统。

先说明边界:公开备案信息显示,BOSS 直聘运营主体的“南北阁”于 2024 年完成生成式人工智能服务备案,备案号为 Beijing-NanBeiGe-20240102。但它的完整数据配方、训练流程与内部架构并未公开。国家互联网信息办公室备案公告

因此,本文不是对 BOSS 直聘内部系统的还原,而是以“BOSS 直聘类平台”为业务案例,给出一套基于开源技术、可以真正落地的参考架构。

先纠正“从 0 训练”的理解

从随机参数开始预训练一个通用基础模型,需要数万亿 Token、长期集群调度、分布式训练能力和极高算力投入。对于绝大多数招聘平台,这不是合理的第一步。

更务实的“从 0 到 1”是:

开源基础模型
    ↓
招聘领域继续预训练(可选)
    ↓
招聘任务 SFT
    ↓
偏好优化与安全对齐
    ↓
RAG、工具调用和匹配系统
    ↓
离线评测、灰度发布和反馈闭环

这里的“自研”不一定意味着从随机权重开始。企业真正应该拥有的是领域数据、训练配方、评测集、服务架构和反馈闭环。

只有当企业同时具备海量合法语料、稳定算力、成熟训练团队,并且开源模型在 Tokenizer、语言覆盖或核心能力上存在无法修补的缺陷时,才值得讨论从头预训练。

第一步:把业务目标写成可以评测的任务

招聘平台同时服务求职者和招聘者,两边目标并不相同。

求职者关心:

招聘者关心:

第一版不要同时解决全部问题。我会选择三个可衡量场景:

场景模型输出首要指标
JD 结构化与改写标准职位、技能、经验、学历、地点、薪资与规范化 JD字段 F1、事实保真率、发布采纳率
简历—岗位匹配解释匹配点、缺口、证据和不确定性Recall@K、NDCG、解释证据准确率
招聘对话助手基于岗位与履历生成问题、回复和下一步建议回复率、人工采纳率、安全违规率

不要一开始就把“招聘成功率”作为单一指标。录用结果延迟长,还受薪资、地点、公司品牌、招聘者行为和宏观环境影响。第一阶段需要同时观察模型质量指标、过程指标和最终业务指标。

第二步:把系统拆开,不让 LLM 包办一切

招聘平台的核心不是一个万能聊天框,而是分层系统:

                         ┌──────────────────────────┐
求职者 / 招聘者 ───────→ │ 对话、搜索、推荐、内容生成 │
                         └────────────┬─────────────┘
                                      ↓
                         ┌──────────────────────────┐
                         │ 任务路由与安全策略层       │
                         │ 意图 / 权限 / 风险 / 成本  │
                         └──────┬─────────┬─────────┘
                                │         │
                 ┌──────────────┘         └──────────────┐
                 ↓                                         ↓
      ┌──────────────────────┐                  ┌──────────────────────┐
      │ 招聘领域 LLM          │                  │ 匹配与排序系统         │
      │ 抽取 / 生成 / 解释    │                  │ 双塔召回 / 精排 / 重排 │
      └──────────┬───────────┘                  └──────────┬───────────┘
                 ↓                                         ↓
      ┌──────────────────────┐                  ┌──────────────────────┐
      │ RAG 与业务工具        │                  │ 特征与向量平台         │
      │ 职位库 / 公司库 / API │                  │ 用户 / 岗位 / 行为     │
      └──────────┬───────────┘                  └──────────┬───────────┘
                 └──────────────────┬──────────────────────┘
                                    ↓
                         ┌──────────────────────────┐
                         │ 数据治理、评测、审计与反馈 │
                         └──────────────────────────┘

LLM 适合做语义理解、信息抽取、内容生成、复杂解释与工具编排;它不适合独自承担亿级候选集的低延迟召回,也不应该直接做不可解释的自动淘汰。

一个成熟方案通常是:

一套最小可用的开源技术栈

不要为了“全开源”堆十几个框架。第一版每层保留一个主要实现和一个可替换接口:

第一版选择关键输出
数据处理Python/SQL + DataTrove 或 Spark版本化 Parquet、数据卡、血缘
训练PyTorch + LLaMA-Factory/TRL,规模扩大后接 FSDP 或 DeepSpeedAdapter/Checkpoint、训练指标
向量与关键词检索OpenSearch,或 PostgreSQL + pgvector 起步可过滤的候选集与证据
Embedding/Reranker开放权重的中英双语 Embedding + Cross-Encoder向量、相关性分数
推理vLLM 或 SGLangOpenAI-compatible API
实验与评测MLflow + 自建黄金集与回归脚本数据、模型、Prompt、指标版本

组件名称不是重点,接口才是。训练样本、Embedding、检索结果、模型输出和评测结果都要带 dataset_versionmodel_versionprompt_versiontrace_id,否则线上错误无法回溯。

第三步:先建立招聘领域本体

没有统一语义,训练数据越多,冲突越多。

例如“Java 高级开发”“后端研发工程师”“服务端工程师”和“高级 Java 工程师”可能指向同一职业族;“熟悉大模型”可能意味着会调用 API,也可能要求训练、评测或推理优化。

我会先建立一套版本化的招聘本体:

职业族 → 标准职位 → 专业方向 → 技能 → 熟练度
                                   ├─ 必须 / 加分
                                   ├─ 使用年限
                                   └─ 最近使用时间

岗位 → 行业 → 公司阶段 → 地点 → 工作方式 → 薪资区间

候选人 → 经历 → 项目 → 责任 → 行为 → 结果 → 证据

本体不是让所有公司使用同一种职位名称,而是为搜索、训练和评测建立共同坐标系。每个映射都要保留原文、标准值、置信度和版本,避免模型把不确定推断写成事实。

一个 JD 结构化样本至少应该包含:

{
  "source_text": "招聘高级后端,5年以上,熟悉Java和微服务,有大模型经验优先",
  "job_family": "软件研发",
  "normalized_title": "高级后端开发工程师",
  "required_skills": ["Java", "微服务"],
  "preferred_skills": ["大语言模型"],
  "experience_min_years": 5,
  "evidence": {
    "experience_min_years": "5年以上",
    "required_skills": ["熟悉Java和微服务"]
  },
  "confidence": 0.96,
  "ontology_version": "job-ontology-2026-08"
}

关键不是 JSON,而是 evidence。招聘领域的模型输出必须能回到原始证据。

第四步:建立合法、可追溯的数据资产

招聘数据比普通网页数据敏感得多。简历可能包含姓名、联系方式、教育经历、工作经历、地理位置和期望薪资;聊天记录还可能包含家庭情况、健康信息和其他私密内容。

我会把数据分为四层:

数据层典型内容主要用途
公共知识职业分类、公开技能文档、劳动法规、公开公司信息领域知识与 RAG
平台业务数据获得授权的 JD、脱敏简历、搜索与交互继续预训练与匹配
专家标注数据职位标准化、技能证据、匹配判断、优劣回答SFT、偏好优化、评测
在线反馈数据采纳、修改、回复、投递、面试及投诉迭代与效果验证

每条数据必须带上:

不能因为数据在平台数据库里,就默认可以用于训练。产品使用、推荐、风控和模型训练是不同处理目的,需要分别审查授权基础和最小必要范围。

招聘数据清洗流水线

数据源登记与权限审查
        ↓
解析 JD、简历、聊天与行为日志
        ↓
删除模板噪声、广告、联系方式诱导和异常字符
        ↓
语言、职位、行业与内容类型识别
        ↓
PII 检测、字段化、令牌化替换与隔离映射
        ↓
精确去重、简历版本去重、JD 模板近似去重
        ↓
虚假、低质、歧视性和冲突内容检测
        ↓
质量评分与证据完整性检查
        ↓
按时间、用户和公司隔离训练 / 验证 / 测试集
        ↓
数据卡、版本号与审计记录

脱敏不能只用正则。邮箱和手机号适合规则,姓名、学校、公司项目、地址和自由文本中的身份线索还需要 NER、词典、模型检测和抽样复核。

训练集切分也不能随机按行切。一个人的多份简历、一个公司的模板 JD 或同一次对话如果跨越训练集和测试集,评测结果会虚高。应按用户、企业和时间进行分组隔离,并建立公开基准污染检查。

第五步:选择开源基础模型,而不是只看榜单

中文招聘场景可以从 Qwen、GLM、Llama 等开放权重模型中选择候选。Qwen 官方生态支持 Transformers、vLLM、SGLang 等推理方式,也可配合 LLaMA-Factory、TRL、Axolotl 等进行 SFT 和偏好优化。Qwen 官方仓库

选择时我会关注:

  1. 许可证:是否允许目标商业用途和模型衍生;
  2. 中文与中英混合能力:职位名、技术栈和公司描述经常混合语言;
  3. 结构化输出:JSON Schema 遵循和字段稳定性;
  4. 长上下文:能否处理完整简历、JD 与对话,但不要只看标称长度;
  5. 工具调用:参数正确率、失败恢复和权限边界;
  6. 部署成本:目标并发下的 TTFT、TPOT、吞吐与显存;
  7. 领域基线:在自建招聘评测集上的真实表现。

第一版通常从 7B~14B 级别的模型开始更合理。先证明数据和任务有效,再决定是否升级更大模型。模型越大,不代表每一个抽取和分类任务都更好;许多稳定任务可以蒸馏给小模型。

Tokenizer 也需要评估。统计真实中文 JD、简历和技术词汇的平均字符/Token、截断率和特殊术语切分。如果效率可以接受,不要轻易修改词表;增加 Token 会改变 Embedding 与训练兼容性,收益必须通过实验验证。

第六步:分阶段训练,而不是一次把所有数据倒进去

阶段 A:领域继续预训练(CPT,可选)

CPT 用大量未标注招聘文本,让基础模型熟悉职位表达、技能关系、职业路径和招聘语言。

适合的数据包括:

不要直接把所有聊天和简历投入 CPT。先做 PII、安全、质量、重复和配比治理。训练时混入一定比例的通用数据,降低领域灾难性遗忘,并通过小规模消融决定是否值得做 CPT。

如果基础模型已经很好、领域语料规模有限,直接做 SFT + RAG 往往性价比更高。

CPT 的目标仍是下一个 Token 的交叉熵:

L_CPT = -Σ log Pθ(x_t | x_<t)

工程上需要控制四件事:

每个 Checkpoint 都记录数据 Manifest、代码提交、随机种子、优化器状态和样本混合比例。领域 Loss 下降但通用评测明显退化,说明模型正在遗忘,不是训练成功。

阶段 B:监督微调(SFT)

SFT 用来教模型完成明确任务和遵守输出契约。数据应该覆盖:

一条高质量 SFT 样本不是只有问题和答案,还应包含任务类型、输入来源、证据、允许工具、标准答案、风险标签和数据版本。

{
  "messages": [
    {"role": "system", "content": "你是招聘助手。只能根据给定简历和岗位回答,不得推断年龄、婚育或健康情况。"},
    {"role": "user", "content": "请分析候选人与岗位的匹配点和缺口。\n[岗位]...\n[简历]..."},
    {"role": "assistant", "content": "{\"matched\":[...],\"gaps\":[...],\"unknown\":[...],\"evidence\":[...]}"}
  ],
  "task": "job_candidate_explanation",
  "risk_tags": ["employment", "personal_information"],
  "dataset_version": "recruit-sft-2026-08"
}

使用 LoRA 或 QLoRA 可以快速验证方向,LLaMA-Factory 已支持继续预训练、SFT、DPO 等流程。LLaMA-Factory

model_name_or_path: Qwen/Qwen3-8B
stage: sft
do_train: true
finetuning_type: lora
lora_target: all
dataset: recruitment_sft
template: qwen3
cutoff_len: 4096
learning_rate: 1.0e-4
num_train_epochs: 2.0
bf16: true
val_size: 0.05
llamafactory-cli train recruitment_sft.yaml

这只是起点,不是可直接复制的最优参数。学习率、轮数、序列长度、LoRA Rank 和数据配比,都要通过验证集与消融实验决定。

SFT 还有几个经常被忽略的细节:

全量微调是否优于 LoRA,取决于数据规模、任务跨度和算力。第一版先用 LoRA 证明数据有效;当 Adapter 容量成为明确瓶颈,再对相同数据做全参对照,而不是凭感觉升级。

阶段 C:偏好优化

当模型已经会完成任务,但回答风格、证据忠实度或拒答边界不稳定时,再构建偏好数据。

同一个输入准备 chosenrejected

DPO 比传统 RLHF 更容易作为第一版工程方案;TRL 已提供 SFT、DPO、奖励建模和其他后训练工具。Hugging Face TRL

不要因为 GRPO 流行就使用它。只有当任务有可靠、可计算的奖励,例如 JSON Schema、SQL 执行、代码测试或规则验证时,强化学习才更容易获得稳定收益。主观招聘判断不能只交给一个奖励模型。

DPO 直接拉大同一输入下优选回答与拒绝回答的相对概率:

L_DPO = -log σ(β[(log πθ(y+|x)-log πref(y+|x))
                 -(log πθ(y-|x)-log πref(y-|x))])

这里 β 控制偏离参考模型的强度。实际训练要按任务、长度和风险分桶,检查“偏好提升”是否只是让答案变长。招聘专家之间意见不一致的样本,不应强行制造唯一标签,应保留多标注者分布或进入人工复核。

第七步:实时事实用 RAG,业务动作走工具

岗位状态、薪资、公司信息和招聘进度会不断变化,不能期待模型参数保存实时事实。

RAG 的知识源可以包括:

用户问题
   ↓
意图识别与权限检查
   ↓
结构化过滤(地点、薪资、经验、状态)
   ↓
混合检索(关键词 + 向量)
   ↓
Reranker 精排
   ↓
证据压缩与来源标记
   ↓
LLM 生成或调用业务工具
   ↓
事实、权限与安全校验

招聘检索不能只有向量相似度。地点、薪资、经验、学历要求、岗位状态和权限是硬过滤条件;语义检索负责理解“AI 平台研发”和“LLM Infra”等表达差异;Reranker 再对少量候选进行精排。

不要直接相加 BM25 与向量分数,它们通常不在同一尺度。第一版可以用 Reciprocal Rank Fusion:

RRF(d) = Σ 1 / (k + rank_i(d))

先分别取得关键词与向量 Top-K,再按名次融合,最后把前 50~200 条交给 Cross-Encoder。索引按 tenant_id、岗位状态、地点、薪资和更新时间做服务端过滤;权限过滤必须发生在上下文进入 LLM 之前,而不是生成后再遮盖。

投递简历、发送消息、修改 JD 等写操作必须通过工具完成,并具备:

模型可以建议动作,但不能绕过业务权限直接操作。

第八步:匹配系统要单独训练

招聘平台的海量岗位匹配,本质上仍是推荐与搜索问题。

第一阶段使用双塔模型:候选人塔编码简历与行为,岗位塔编码 JD 与企业特征,向量索引用于快速召回。随后使用 Cross-Encoder 或学习排序模型做精排,最后结合多样性、时效性、已读去重和业务约束进行重排。

候选人画像 ─→ Candidate Tower ─┐
                                ├─ 向量相似度 → ANN Top-K 召回
岗位画像   ─→ Job Tower ───────┘
                                      ↓
                         Cross-Encoder / Learning-to-Rank
                                      ↓
                      规则、时效、多样性与公平约束重排
                                      ↓
                              LLM 生成匹配解释

LLM 可以生成训练弱标签、补充语义特征和解释结果,但不要让它逐个遍历几百万岗位。

训练标签也不能简单定义成“点击就是正样本”。职位曝光受旧模型控制,点击受标题和薪资吸引,沟通受招聘者活跃度影响。可以构建分层标签:曝光、点击、收藏、投递、回复、约面、面试和录用,并考虑位置偏差、负采样和延迟反馈。

双塔可以用对比学习训练。对一个候选人向量 u、正岗位 v+ 和批内岗位集合,常见目标是:

L_retrieval = -log exp(sim(u,v+)/τ) / Σ_j exp(sim(u,v_j)/τ)

随机负样本太简单,模型学不到岗位之间的细微差别;应加入同职位不同级别、同技能不同地点等难负样本。但曝光过且未点击不一定代表不合适,可能只是位置太低;从线上日志挖负样本时要记录曝光位置,并过滤潜在假负例。

精排输入可以组合语义交叉特征、结构化匹配、时效性和行为统计。LLM 生成的匹配解释只能读取最终排序所使用的事实特征与原文证据,避免“排序依据是一套,解释又编一套”。

第九步:评测集应该先于大规模训练

没有自建评测集,就无法知道领域训练是否真的有效。

生成与理解评测

能力指标
字段抽取Precision、Recall、F1、Schema Valid Rate
JD 改写事实保真、完整性、违规率、人工采纳率
匹配解释证据准确率、遗漏率、无依据断言率
RAG 问答Recall@K、引用正确率、Groundedness、拒答准确率
工具调用参数正确率、执行成功率、越权率、重复执行率
安全合规PII 泄露率、歧视表达率、Prompt Injection 成功率

匹配与排序评测

测试集必须按时间冻结,训练数据不得包含未来反馈。公开榜单只能衡量通用能力,不能替代招聘领域评测。

上线采用影子流量和小比例灰度,先让模型生成但不影响用户,再与现网结果对比。只有安全门禁、质量指标和延迟成本同时达标,才逐步扩大流量。

第十步:部署不是启动一个 vLLM 就结束

vLLM、SGLang 等开源推理引擎可以提供高吞吐服务,但生产架构还需要模型网关、队列、缓存、降级与观测。vLLM 官方项目

API Gateway
   ↓
身份、配额、内容长度与风险检查
   ↓
任务路由
   ├─ 小模型:分类、抽取、改写
   ├─ 大模型:复杂分析与对话
   ├─ Embedding / Reranker:检索匹配
   └─ 规则服务:硬约束与安全
   ↓
批处理、KV Cache、超时与熔断
   ↓
结构校验、引用校验与内容安全
   ↓
日志、Trace、成本与质量采样

需要持续观测:

模型升级不是替换一个文件。Prompt、Tokenizer、RAG、工具 Schema、量化方式和推理参数都可能改变结果,必须一起版本化。

容量规划可以先用一个简单近似:

所需副本数 ≈ 峰值 QPS × P95 服务时间
             ÷ 单副本安全并发 × 余量系数

然后用真实输入长度和输出长度压测修正。至少分别压测短抽取、长简历分析和多轮对话;平均 Token 长度会掩盖长尾 OOM。部署前比较 BF16、FP8/INT8 和低比特量化在招聘黄金集上的回归,不能只比较吞吐。

招聘场景最重要的安全线

招聘不是普通内容生成。一个错误推荐可能浪费时间,一个不透明的淘汰决策可能影响人的职业机会。

《个人信息保护法》第二十四条要求,利用个人信息进行自动化决策时,应保证决策透明度和结果公平、公正。《中华人民共和国个人信息保护法》

工程上至少要做到:

  1. 不把性别、年龄、民族、婚育、健康等信息作为未经合法论证的匹配特征;
  2. 检查学校、地址、职业中断等代理变量造成的间接偏差;
  3. 不让 LLM 单独作出录用或淘汰决定;
  4. 为重要推荐提供基于岗位和履历证据的解释;
  5. 提供人工复核、纠错、退出个性化推荐和申诉通道;
  6. 将简历访问权限落实到检索、Prompt、日志和缓存每一层;
  7. 对训练数据、模型版本、Prompt 和工具调用保留审计链;
  8. 面向公众提供生成式服务前,完成适用的安全评估、算法备案或大模型登记评估。

“模型没有使用姓名”并不等于公平。学校、邮编、工作年份和表达风格都可能成为身份代理。公平评测必须按合法且必要的分群做差异分析,并由法务、伦理、招聘专家与算法团队共同审查。

一套可以执行的 12 周路线

周期目标可交付结果
第 1~2 周定义任务与基线三个场景、黄金评测集、现网基线、合规清单
第 3~4 周数据与本体招聘本体 v1、数据血缘、脱敏流水线、训练集 v1
第 5~6 周开源模型 PoC3 个基础模型横评、LoRA SFT、错误分类报告
第 7~8 周RAG 与匹配混合检索、Reranker、双塔召回基线、证据引用
第 9~10 周偏好与安全DPO 数据、安全集、红队测试、权限与审计
第 11 周影子与灰度线上影子流量、延迟成本报告、1%~5% 灰度
第 12 周复盘与决策业务增益、质量回归、是否扩大训练和模型规模

第一个版本的通过条件应该提前写清楚,例如:

具体阈值必须根据业务基线确定,不应该从别人的文章里复制。

最容易失败的七种方式

  1. 先训练,后找场景:最后只有一个演示聊天框,没有业务指标。
  2. 把数据库当训练授权:忽略简历、对话和行为数据的处理目的与权限。
  3. 随机切分数据:同一用户或模板泄漏到测试集,制造虚假高分。
  4. 只做 LLM,不做召回排序:成本高、延迟大,也无法处理海量候选集。
  5. 只看通用榜单:模型会做数学题,却无法稳定抽取薪资和技能证据。
  6. 用线上点击直接当真相:把旧推荐系统的位置偏差继续训练进新系统。
  7. 让模型自动淘汰候选人:缺少证据、解释、人工复核与公平性控制。

最后的判断

招聘领域大模型真正的壁垒,不是把一个开源模型换成自己的名字,也不是训练参数越多越好。

它的壁垒来自:

如果这五件事没有做好,自研模型只是昂贵的聊天机器人。

如果这五件事形成闭环,即使第一版只使用一个 7B~14B 的开源模型,也可能创造真实价值。

从 0 到 1 构建招聘大模型,不是从 0 写出 Transformer,而是从 0 建立一套能够把招聘知识、业务数据、模型能力和真实结果连接起来的系统。

参考资料

返回技术札记