Commit 2b995a08 authored by 李文光's avatar 李文光

docs: 外部定稿包 JSON 字段契约对齐并落 recruit-grill/references,skill 相关文档措辞正式化

parent c77014f9
......@@ -17,6 +17,7 @@ recruit-grill skill 的产出是四件套(对外 JD / 对内笔记 / CONTEXT
4. **认领语义复刻 ADR 0001 行级模式**:OA 审批表只读;招聘系统本地维护 bill↔job↔owner 映射(不进整包 state,类比 ADR 0002);认领 = 行级迁移 + 生成 jobId + 占位(他人见"已认领")+ 清待认领快照 + 事件/待办联动。列表全 HR 可见,认领归属本人。
5. **认领落点状态**:认领后 `jdStatus=待确认``approvalStatus=审批通过(来源 OA)`;招聘专员核对 JD 内容后置 `已生效` 再开招,不自动生效。
6. **OA bill 数据契约(双轨)**:审批单携带**对外 MD + 结构化 JSON(岗位执行字段,含 age/gender/nonCompete 等对内执行字段)****对内笔记 MD(寻源策略/命脉推导等)不进 OA**,由 agent 走内部通道按 `oaBillNo` 关联暂存,HR 认领 OA 通过岗位时合并归档进岗位 `internalNote`;对内内容继续受 `_INTERNAL_ONLY_JOB_KEYS`(含 `internalNote`)脱敏保护,不落入对外 JD / LLM prompt。
> 注(2026-09-07 字段名校正):本文与 skill 中的口语短名 age/gender 指的就是 recruit-sys 规范键 `ageRestriction`/`genderRestriction`,落 JSON 一律写规范键;定稿包 JSON 的逐字段契约见 `docs/recruit-grill/references/external-job-package-contract.md`(执行约束 genderRestriction/ageRestriction/probationPeriod/probationCriteria/nonCompete/internalFeasibility/verification 随 OA 单;内部文本 sensitive/internalNote 不进 OA)。
7. **入口1 审批源 seam**:保留系统内简化审批(草稿→待确认→审批中→已生效)为**过渡态**`approvalStatus` 设计为可切换源(内部简化 ↔ OA 直读),同库接通后映射 OA 表状态(待审/通过/驳回)到系统枚举;OA 是审批生命周期 owner,招聘系统只读消费。
## 影响 / Consequences
......
# 企微智能体验证包 —— 给企微侧接入说明(ADR 0003)
> 用途:验证「用人部门 → 定稿包 → OA 审批 → 招聘系统认领」全流程。
> 关联:docs/recruit-grill(skill 维护源 v3.1)、docs/jd-sync(内部 QA 通道)、docs/adr/0003-external-job-claim-oa.md、docs/external-job-claim-design.md
> 当前状态(2026-09-04):定稿包产出与 OA 建单链路可验证;**OA 同库直读与 internalOnly 双轨合并(Phase 3)尚未实现**,见「验证范围」。
## 一、要装哪些 skill
| skill | 是否必装 | 来源(仓库) | 安装到企微 QwenPaw 工作区 |
| --- | --- | --- | --- |
| **recruit-grill** | ✅ 必装(主流程) | `docs/recruit-grill/`(SKILL.md + references/question-bank.md + references/external-job-package-contract.md) | `<QWENPAW_WORKING_DIR>/workspaces/<agent>/skills/recruit-grill/` |
| **jd-sync** | ⬜ 可选(仅内部/QA 过渡导入) | `docs/jd-sync/`(SKILL.md + scripts/sync_jd.py) | `<QWENPAW_WORKING_DIR>/workspaces/<agent>/skills/jd-sync/` |
- 安装后确认技能在 agent 的 skills 列表里为 enabled。
- **版本提醒**:仓库中的 recruit-grill 为 v3.1(8 问 / 6 轮),版本高于旧副本;请以仓库版本为准,勿用工作区旧版覆盖。
## 二、主流程(用人部门视角)
```
用人部门在企微 QwenPaw 与 recruit-grill 对话(一次只问 2~3 问,8 问 / 6 轮闭环)
→ 产出「定稿包」
├─ 对外 JD MD (给人看 / 给 OA 审批)
├─ 结构化 JSON (岗位执行字段,含对内执行字段)
└─ 对内笔记 MD (internalOnly,不进 OA)
→ 用户确认后,agent 代建 OA 审批单(对外 MD + 结构化 JSON)——OA 建单能力已在企微侧实现
→ OA 审批通过
→ 招聘系统 HR「岗位认领」→ 岗位管理 → 招聘流程
```
企微侧对话过程**不得出现「同步到招聘系统」话术**;用人部门完成访谈并确认定稿包后,提交 OA 审批。
## 三、定稿包 JSON 结构(契约)
> **字段权威**:[external-job-package-contract.md](recruit-grill/references/external-job-package-contract.md) 为定稿包 JSON 的逐字段契约(含 skill 口语 age/gender → 规范键 ageRestriction/genderRestriction 的对照与易错名表);本节示例与之对齐。
```json
{
"oaBillNo": "OA-20260904-001",
"source": "qwenpaw-external",
"job": {
"title": "高级前端工程师",
"department": "技术部",
"headcount": 2,
"jd": "# 高级前端工程师(杭州)\n## 背景\n...(对外 JD MD 文本)",
"responsibilities": "1、负责前端架构与工程化;",
"requirements": "1、本科及以上,5 年+ 前端经验;",
"mustHave": "Vue3、TypeScript",
"niceToHave": "React、微前端",
"knockout": "无真实项目",
"competency": "专业能力\n业务理解\n数据分析\n沟通协同\n抗压推进",
"matchKeywords": "前端 Vue 工程化",
"sensitive": "(内部备注,不进对外 JD)",
"genderRestriction": "",
"ageRestriction": "",
"probationPeriod": "3 个月",
"probationCriteria": "转正看…",
"nonCompete": "否"
}
}
```
- `job` 内字段 = 岗位执行标准:**对外内容字段**(title/department/headcount/jd/responsibilities/requirements/mustHave/niceToHave/knockout/competency/matchKeywords)可进对外 JD、OA 与认领预览;**对内字段**只做内部执行,绝不进对外 JD / LLM prompt(后端 llm.py `_INTERNAL_ONLY_JOB_KEYS` 已含 internalNote)。对内字段又分两组(分组细则、逐字段类型/示例/来源见契约文档):① 执行约束——genderRestriction/ageRestriction/probationPeriod/probationCriteria/nonCompete/internalFeasibility/verification,随 OA 审批单携带;② 内部文本——sensitive(内部备注)/internalNote(对内笔记 MD),不进 OA,走 internalOnly 载荷按 oaBillNo 关联。
- 幂等键(后端实际读取顺序):`job.externalId` → 顶层 `external_id``externalJobId``oaBillNo`,命中即更新同一认领单(已认领只跳过)。示例用顶层 `oaBillNo`。⚠️ 顶层 camelCase `externalId` 后端不读——要么放 `job.externalId`,要么用上述任一写法。
### OA bill 双轨约定(Phase 3 落地后生效)
- **进 OA**:对外 MD + 结构化 JSON(含对内执行字段值,作为岗位本身要执行的约束)。
- **不进 OA**:对内笔记 MD(寻源策略/命脉推导等 internalOnly 内容),走内部通道按 `oaBillNo` 关联;招聘系统认领 OA 通过岗位时按 `oaBillNo` 合并归档进岗位 `internalNote`
## 四、招聘系统侧接口(agent 用)
| 接口 | 方法 | 用途 | 鉴权 |
| --- | --- | --- | --- |
| `/api/agent/recruiting-rules` | GET | 读公司级硬规则/术语/待定决策(下次访谈推荐答案用) | `X-Ingest-Token` |
| `/api/agent/jobs?jobId=<id>``?title=<岗位>` | GET | 读历史岗位(对外 JD + 对内档案,老岗位迭代/查重用) | `X-Ingest-Token` |
| `/api/jd/sync-external` | POST | **仅内部/QA**:把定稿 JSON 导入「待认领区」(不面向用人部门) | `X-Ingest-Token` |
- 环境变量(企微 QwenPaw 侧):`RECRUITMENT_API_BASE`(如 `http://<recruit-sys 主机>:4177`)、`RECRUITMENT_INGEST_TOKEN`(与招聘系统 `.env``INGEST_TOKEN` 一致)。
- 招聘系统侧需已配置 `INGEST_TOKEN`,接口才按 token 校验放行。
## 五、验证 checklist(当前可实现部分)
1. recruit-grill 访谈:一句话需求 → 8 问/6 轮闭环 → 产出定稿包(对外 MD + 结构化 JSON + internalOnly 对内笔记)。
2. 老岗位迭代:先用 `/api/agent/jobs?title=…` + `/api/agent/recruiting-rules` 读回旧 JD/规则,推荐答案有据。
3. OA 建单:定稿包中「对外 MD + 结构化 JSON」正确进入审批单;`externalId`/`oaBillNo` 字段填写正确。
4. (可选 QA)通过 `/api/jd/sync-external` 导入 → 招聘系统「岗位认领」出现待认领记录 → 认领 → HR 核对后「确认生效」。
**暂不能验证(Phase 3 未实现,验证时请勿预期以下能力)**:OA 审批通过后自动进入招聘系统待认领、`internalOnly` 对内载荷按 `oaBillNo` 自动合并进 `internalNote`——上述能力需待 OA 同库直读 Reader 落地。
## 六、备注
- 本文件为仓库维护源的一部分;skill 本体以仓库 `docs/recruit-grill/``docs/jd-sync/` 为准,各部署环境的 skill 副本统一从本仓库拷贝。
......@@ -5,15 +5,15 @@
> - Phase 1:后端待认领表 + sync-external 落待认领区 + 认领接口;前端「岗位认领」菜单/页面 + 外部已审批岗位「核对后确认生效」流转(npm run build 通过)。
> - Phase 2:招聘规则库读写 API(GET/PUT /api/recruiting-rules,登录读 / admin 写,文件 data/recruiting-rules.json);agent 只读查询(GET /api/agent/recruiting-rules、GET /api/agent/jobs?jobId=&title=,X-Ingest-Token)。
> Phase 2.5(skill 契约):仓库维护源已同步 ADR 0003——recruit-grill 增加「两种部署形态」(形态 B 读系统规则库/岗位 API);jd-sync 收编至 docs/jd-sync。
> **2026-09-03 battle 校正**:入口2 收尾 = 产出定稿包 → agent 代建 **OA 审批单**(非"同步到招聘系统"话术);OA bill 走双轨(对外 MD + 执行字段进 OA,对内笔记 MD 经 internalOnly 载荷按 oaBillNo 关联,认领时合并归档 internalNote);jd-sync 仅内部/QA 导入。
> 待执行:把仓库 skill 副本部署到企微那台/本地 qwenpaw 工作区并配置环境变量。
> **2026-09-03 方案校正**:入口2 收尾 = 产出定稿包 → agent 代建 **OA 审批单**(而非向用人部门提供"同步到招聘系统"话术);OA bill 采用双轨(对外 MD + 执行字段进 OA,对内笔记 MD 经 internalOnly 载荷按 oaBillNo 关联,认领时合并归档 internalNote);jd-sync 仅供内部/QA 导入。
> 待执行:将仓库 skill 副本部署到企微侧与本地 QwenPaw 工作区,并配置环境变量。
> 未做:Phase 3(OA 同库直读 Reader + 审批源切换)。
## 一、定稿流程
```
入口1:HR 在 recruit-sys 建岗(网页/系统内 grill) ──提交 OA(bill↔jobId)──▶ OA 审批
入口2:用人部门在企微 QwenPaw(recruit-grill) 聊完 → 产出定稿包
入口2:用人部门在企微 QwenPaw(recruit-grill) 完成访谈 → 产出定稿包
(对外 JD MD + 结构化 JSON + 对内笔记 MD[internalOnly])
→ agent 代建 OA 审批单(对外 MD + 结构化 JSON)──▶ OA 审批
│ 审批通过
......@@ -54,7 +54,7 @@
### skill / 分发
12. `docs/recruit-grill/` 提升为唯一维护源并提交(SKILL.md 注明:形态 B 产出定稿包走 OA 审批,不落 qwenpaw 目录、不给用人部门"同步到招聘系统"话术)
13. `jd-sync`(内部/QA)产出契约与 OA bill 双轨契约一致(对外+执行字段进 OA,internalNote 经 internalOnly 载荷关联 oaBillNo);SKILL.md「改版纪律」四件套载体同步检查
14. 分发:本地 qwenpaw workspace 与 ~/.agents/skills 副本以仓库为准;企微那台部署按同一份拷贝 + OA 侧契约
14. 分发:本地 QwenPaw workspace 与 ~/.agents/skills 副本以仓库为准;企微侧部署按同一份拷贝 + OA 侧契约
### 测试与规范
15. 保持后端 25 passed;涉及 models/state_repository 时同步改(§4.1);新表 owner_id 硬规则(§4.2);`test_auth`/`test_ai`/`test_state`/`test_pool` 相应补充;前端改完 `npm run build`
......@@ -63,7 +63,7 @@
## 四、后续项(本期不做,设计预留)
- OA 同库直读落地:确认 hget_oa 审批表结构后实现 Reader + 状态映射(沿用 hr-oa「只增不减」融合先例,OA 表只读)
- 企微那台部署:skill 分发 + 「JD 直推 OA」的对接在 OA/企微侧,招聘系统只消费结果
- 企微部署:skill 分发 + 「JD 直推 OA」的对接在 OA/企微侧,招聘系统只消费结果
- 招聘规则库升级为业务表(当公司级规则需驱动 AI 初筛时,再评估 ADR 0001 `_pool` 式共享实体)
- 批量认领 / 认领前查重
......
---
name: jd-sync
description: 【内部/QA 专用】把已经梳理/确认好的招聘 JD 导入招聘系统「待认领区」(ADR 0003 过渡期通道;生产链路是 OA 审批 → HR 岗位认领)。仅 HR/开发者联调用,不面向用人部门——用人部门收尾动作是产出定稿后提交 OA 审批,不是"同步到招聘系统"。
description: 【内部/QA 专用】把已梳理/确认的招聘 JD 导入招聘系统「待认领区」(ADR 0003 过渡期通道;生产链路为 OA 审批 → HR 岗位认领)。仅供 HR/开发者联调使用,不面向用人部门——用人部门完成访谈并产出定稿后,提交 OA 审批,而非"同步到招聘系统"。
---
# jd-sync —— 把 JD 同步到招聘系统
......@@ -8,19 +8,19 @@ description: 【内部/QA 专用】把已经梳理/确认好的招聘 JD 导入
## 用途
**定位:内部/QA 过渡导入通道,不面向用人部门。**
生产链路(ADR 0003):用人部门在企微聊完 → agent 代建 OA 审批单 → 审批通过 → HR 在系统「岗位认领」认领。
生产链路(ADR 0003):用人部门在企微完成 recruit-grill 访谈 → agent 代建 OA 审批单 → 审批通过 → HR 在系统「岗位认领」中认领。
本 skill 只在 OA 未接通或本地联调时,把一份已定稿的岗位 JSON 导入招聘系统公司级「待认领区」(**不再直接创建岗位**),HR 认领后成为正式岗位。
## 触发(仅内部)
- HR / 开发者联调:把一份已定稿的岗位 JSON 导入待认领区做端到端验证。
- 一轮 recruit-grill 访谈收尾、已产出可用 JD 正文与结构化字段之后(内部转 QA 时)。
- 一轮 recruit-grill 访谈结束、已产出可用 JD 正文与结构化字段后(内部转 QA 场景)。
- **不要**把它做成用人部门的话术;用人部门侧对应动作是「提交 OA 审批」(OA 建单已由 agent 实现)。
## 步骤
1. 汇总岗位全量信息,组织 payload:
- 幂等键(任一即可,重复推送更新同一认领单):`external_id` / `externalJobId` / `oaBillNo`
- `job` 对外字段:title / department / jd / responsibilities / requirements / mustHave / niceToHave / knockout / competency / matchKeywords / headcount
- `job` 内可选**对内字段分列**(仅内部):sensitive / genderRestriction / ageRestriction / internalFeasibility / verification / probationPeriod / probationCriteria / nonCompete 等——系统认领后存入岗位**对内档案**,绝不进入对外 JD / LLM prompt
- 幂等键(后端读取顺序):`job.externalId` → 顶层 `external_id``externalJobId``oaBillNo`,任一命中即更新同一认领单;⚠️ 顶层 `externalId` 不读
- `job` 对外内容字段(可进对外 JD / OA / 认领预览):title / department / headcount / jd / responsibilities / requirements / mustHave / niceToHave / knockout / competency / matchKeywords / workLocation / salaryRange
- `job` 内可选**对内字段分列**(仅内部):genderRestriction / ageRestriction / probationPeriod / probationCriteria / nonCompete / internalFeasibility / verification(执行约束,可随 OA 单)+ sensitive / internalNote(内部文本,不进 OA;本内部通道可直接带 internalNote 全文)——系统认领后存入岗位**对内档案**,绝不进入对外 JD / LLM prompt
2. 运行同步脚本(脚本路径相对本 skill 目录):
```bash
cd {this_skill_dir} && python scripts/sync_jd.py --payload-file /tmp/jd.json
......@@ -33,5 +33,6 @@ description: 【内部/QA 专用】把已经梳理/确认好的招聘 JD 导入
- 失败 → 把失败原因反馈给用户。
## 注意
- 字段口径统一见 `../recruit-grill/references/external-job-package-contract.md`(逐字段契约;部署时 recruit-grill 与 jd-sync 放同一 skills 目录下即可相对引用);对内字段一律写规范键,禁止口语短名(age→ageRestriction、gender→genderRestriction)。
- 环境变量读取:`RECRUITMENT_API_BASE`(默认 `http://127.0.0.1:4177`)、`RECRUITMENT_INGEST_TOKEN`(对应后端 `INGEST_TOKEN`,可选)。
- 若脚本失败,请检查招聘系统是否启动、地址/令牌是否匹配。
......@@ -25,10 +25,10 @@ description: 从用人部门的一句话招聘需求出发,用逼问式访谈
- `GET {RECRUITMENT_API_BASE}/api/agent/jobs?title=<岗位名>`(或 `?jobId=`)→ 老岗位对外 JD + **对内档案**,供「旧岗位迭代 / 入口分流 / 同步前查重」。
- **写(访谈收尾 = 产出「定稿包」,不再以 markdown 为长期事实源;不向用人部门提供"同步到招聘系统"话术)**
- 对外 JD MD(给人看 / 给 OA 审批);
- 结构化 JSON(岗位执行字段,含 age/gender/nonCompete 等对内执行字段);
- 结构化 JSON(岗位执行字段**键名以 `references/external-job-package-contract.md` 契约为准**——对内字段一律用 recruit-sys 规范键:执行约束 `genderRestriction`/`ageRestriction`/`probationPeriod`/`probationCriteria`/`nonCompete`/`internalFeasibility`/`verification`,内部文本 `sensitive`/`internalNote`**禁止**口语短名 age/gender);
- 对内笔记 MD(internalOnly:寻源策略/命脉推导,**不进 OA**)。
- 用户确认后由 agent **代建 OA 审批单**(对外 MD + 结构化 JSON;OA 建单能力在企微那台已实现)。审批通过后 HR 在招聘系统「岗位认领」认领,认领时`oaBillNo` 合并 internalOnly 对内载荷归档进岗位 `internalNote`
- **不重复维护**:在招岗位表 = 系统岗位状态派生;关键词迭代表 R1 → 岗位 `matchKeywords`;性别/年龄等敏感要求只放 JSON 内字段,绝不进对外 JD / LLM prompt。
- 用户确认后由 agent **代建 OA 审批单**(对外 MD + 结构化 JSON;OA 建单能力由企微侧 QwenPaw 提供)。审批通过后,HR 在招聘系统「岗位认领」中认领,并`oaBillNo` 合并 internalOnly 对内载荷归档进岗位 `internalNote`
- **不重复维护**:在招岗位表 = 系统岗位状态派生;关键词迭代表 R1 → 岗位 `matchKeywords`;性别/年龄等敏感要求只放 JSON 内字段`genderRestriction`/`ageRestriction`,绝不进对外 JD / LLM prompt。
- **环境变量**`RECRUITMENT_API_BASE``RECRUITMENT_INGEST_TOKEN`(与系统 `INGEST_TOKEN` 一致;配置后才有读取与同步权限)。
......
# 外部岗位「定稿包 JSON」字段契约(recruit-grill ↔ OA bill ↔ recruit-sys 认领)
> 用途:供三方对齐同一份字段口径——① 企微侧 QwenPaw(recruit-grill 形态 B)组装定稿包 JSON;② agent 代建 OA 审批单(对外 MD + 结构化 JSON);③ 招聘系统认领消费(过渡期为 `/api/jd/sync-external`,Phase 3 为 OA 同库直读)。
> 状态:契约定稿(2026-09-07)。代码事实源:`backend/app/repositories/external_claim_repository.py`、`backend/app/services/llm.py`。
> 一句话命名规则:**JSON 键一律采用招聘系统岗位数据字段(camelCase 规范键)**;skill 与 ADR 中的口语短名(age、gender…)仅为口头简称,落 JSON 时必须转换为规范键。
> 本文件随 recruit-grill skill 分发(置于其 references/ 目录);企微侧 QwenPaw 组装定稿包 JSON 时,以本文为运行依据。
## 0. 差异对齐速查(本次要解决的)
| 口语/文档叫法 | 出现在 | 含义 | JSON 规范键 | 说明 |
| --- | --- | --- | --- | --- |
| age | SKILL.md 形态 B、ADR 0003 | 年龄上限 / 降权线(仅内部) | `ageRestriction` | **禁止以 age 作键名** |
| gender | SKILL.md 形态 B、ADR 0003 | 性别惯例(仅内部) | `genderRestriction` | **禁止以 gender 作键名** |
| 试用期 | 访谈第 8 问 | 试用期时长 | `probationPeriod` | 示例 "3 个月" |
| 转正信号 | 访谈第 8 问 | 试用期内看什么转正 | `probationCriteria` | |
| 竞业 | 访谈第 8 问 | 是否签竞业 | `nonCompete` | 同名,无歧义 |
| 为什么必须外招 | 访谈第 2 问 | 内部消化检查结论 | `internalFeasibility` | |
| 简历验证信号 | 访谈第 5 问 | 命脉怎么在简历上验证 | `verification` | |
| 内部备注 | 访谈收尾 | 敏感说明等内部补充 | `sensitive` | 内部文本 |
| 对内笔记全文 | 形态 B 产出③ | 寻源策略/命脉推导等 | `internalNote` | 内部文本,不进 OA |
结论:**handoff 与后端代码的字段名(ageRestriction/genderRestriction…)为正确口径**;skill 与 ADR 仅使用了口语缩写。组装 JSON 时,应以本文为对照表,将口语缩写转换为规范键。
## 1. JSON 骨架
```json
{
"oaBillNo": "OA-20260904-001",
"source": "qwenpaw-external",
"approvalStatus": "审批通过",
"job": {
"title": "高级前端工程师",
"department": "技术部",
"headcount": 2,
"jd": "# 高级前端工程师(杭州)\n... 对外 JD 全文 MD",
"responsibilities": "…",
"requirements": "…",
"mustHave": "…",
"niceToHave": "…",
"knockout": "…",
"competency": "…",
"matchKeywords": "…",
"genderRestriction": "",
"ageRestriction": "",
"probationPeriod": "3 个月",
"probationCriteria": "转正看…",
"nonCompete": "否",
"internalFeasibility": "无人可培训,必须外招",
"verification": "简历看…",
"sensitive": "…",
"internalNote": "…(internalOnly)"
}
}
```
## 2. 信封层(顶层)字段
| 键 | 必填 | 类型/示例 | 说明 |
| --- | --- | --- | --- |
| `job` | ✅ | object | 岗位主体,见 §3/§4;缺 title 后端直接 400 |
| `oaBillNo` | OA 场景 | "OA-20260904-001" | OA 审批单号;**推荐幂等键**;internalOnly 载荷认领合并的关联键 |
| `external_id` | 过渡期 | "bill-ext-001" | 兼容老写法(sync 脚本/测试用 snake_case) |
| `externalJobId` | 否 | — | 幂等键别名 |
| `source` | 否 | "qwenpaw-external" | 默认即此值 |
| `approvalStatus` | 否 | "审批通过" | 过渡期 sync-external 用;OA 直读后由 OA 状态映射,可省 |
| `department` | 否 | "技术部" | 兜底;规范写法是放 `job.department` |
| `externalId` ⚠️ | — | — | **顶层 camelCase 后端不读**(见下) |
**幂等键(后端实际读取顺序,`upsert_external_claim`)**`job.externalId` → 顶层 `external_id` → 顶层 `externalJobId` → 顶层 `oaBillNo`。命中即更新同一认领单(已认领只跳过);均未提供时按 title+department+source 合并未认领单。示例推荐使用顶层 `oaBillNo`(OA 流程)或 `external_id`(过渡 QA)。
## 3. job:基本信息 + 对外内容字段(可进对外 JD / OA / 认领预览)
| 字段 | 中文 | 必填 | 类型/示例 | 来源(访谈问) |
| --- | --- | --- | --- | --- |
| `title` | 岗位名称 | ✅ | "高级前端工程师" | 一句话需求 |
| `department` | 所属部门 | 建议 | "技术部" | 需求背景 |
| `headcount` | 招聘人数 | 建议 | 2(数字) | 需求背景 |
| `jd` | 对外 JD 全文 MD | ✅ | markdown(标题含地点、含 `薪资:X/月` 行) | 产出① |
| `responsibilities` | 核心职责 | 建议 | "1、负责…;\n2、…" | 第 3 问(≥3 条) |
| `requirements` | 任职要求 | 建议 | 学历/专业/年限/出差/技术栈门槛 | 第 3/4 问 |
| `mustHave` | 硬性条件(命脉) | 建议 | "高并发架构经验" | 第 3 问判定标准 |
| `niceToHave` | 加分项 | 否 | "React、微前端" | 推荐答案衍生 |
| `knockout` | 排除信号 | 建议 | "无真实项目" | 第 6 问 |
| `competency` | 胜任力/素质 | 否 | "专业能力\n业务理解\n沟通协同" | 命脉推导(可空) |
| `matchKeywords` | 匹配关键词 | 建议 | 6-10 个,中文逗号分隔 | 关键词迭代表 R1 |
| `workLocation` | 工作地点 | 否 | "杭州" | 也可只写进 JD 标题 |
| `salaryRange` | 薪资带宽 | 否 | "25-40K" | 第 7 问;也可只写进 JD 正文 |
去向:全部可进对外 JD / OA 审批单 / 认领预览(后端 `_PREVIEW_FIELDS` 展示白名单即本表去掉 title/department/headcount/workLocation/salaryRange 后的大部分)。
## 4. job:对内字段(绝不进对外 JD / LLM prompt / 候选人沟通)
对内字段分两组(这是 handoff 旧文把 sensitive/internalNote 与执行约束混在一起的细分):
### 4a. 执行约束(结构化值,随 OA 审批单携带,作为岗位本身要执行的约束;认领后进岗位对内档案,HR 可见)
| 字段 | 中文 | 示例 | 来源(访谈问) | 取值约定 |
| --- | --- | --- | --- | --- |
| `genderRestriction` | 性别要求 | "男" / "" | 第 4 问(仅内部) | 不设就空串,**键名保留** |
| `ageRestriction` | 年龄要求 | "35 岁以下" / "" | 第 4 问(仅内部) | 同上 |
| `probationPeriod` | 试用期时长 | "3 个月" | 第 8 问 | 只进对内,不写对外 JD |
| `probationCriteria` | 转正标准 | "转正看独立拿下首个大客户" | 第 8 问 | 同上 |
| `nonCompete` | 竞业协议 | "否" | 第 8 问 | 每岗必问,无默认 |
| `internalFeasibility` | 为什么必须外招 | "无人可培训,必须外招" | 第 2 问 | 内部消化结论 |
| `verification` | 简历验证信号 | "简历看主导过的并发项目规模" | 第 5 问 | 命脉怎么验证 |
### 4b. 内部文本(不进 OA,走 internalOnly 载荷按 `oaBillNo` 关联,认领时归档岗位 `internalNote`/`sensitive`)
| 字段 | 中文 | 说明 |
| --- | --- | --- |
| `sensitive` | 内部备注 | 敏感说明等内部补充(性别/年龄之外的敏感口径);不进对外 JD |
| `internalNote` | 对内笔记全文 MD | 寻源策略/命脉推导/目标公司/排除画像等 jd-internal 内容;**internalOnly,绝不进 OA bill**(OA 单仅携带对外 MD 与 §4a 执行约束) |
> 口径说明:handoff §三示例展示的是"定稿包完整 JSON",因此其中可包含 sensitive;**OA 建单侧组装审批单 JSON 时,仅取对外内容字段与 §4a 执行约束**,不携带 sensitive/internalNote——二者由 agent 经内部通道按 oaBillNo 关联(Phase 3 认领合并)。
## 5. 认领时系统派生——不要 agent 填写的键
`id` / `status` / `priority` / `hired` / `jdStatus` / `approvalStatus` / `approvalSource` / `jdVersion` / `matchRuleStatus` / `channelStatus` / `nextAction` / `owner` / `createdAt` / `updatedAt` / `claimId` / `jobId` / `claimedBy` / `claimedAt``claim_external_job` 认领时统一生成或覆盖(jdStatus=待确认、approvalStatus=审批通过·来源 OA…)。agent 即使传入也会被覆盖,无需携带。
## 6. 完整示例(OA 双轨版,字段与本契约一致)
```json
{
"oaBillNo": "OA-20260904-001",
"source": "qwenpaw-external",
"job": {
"title": "高级前端工程师",
"department": "技术部",
"headcount": 2,
"workLocation": "杭州",
"salaryRange": "25-40K",
"jd": "# 高级前端工程师(杭州)\n\n## 背景\n负责前端架构与工程化,支撑业务快速迭代。\n\n薪资:25-40K/月\n\n## 岗位职责\n1、负责前端架构与工程化体系建设;\n\n## 岗位要求\n1、本科及以上,5 年+ 前端经验;",
"responsibilities": "1、负责前端架构与工程化体系建设;\n2、主导核心模块设计与落地;",
"requirements": "1、本科及以上,5 年+ 前端经验;\n2、熟悉 Vue3;",
"mustHave": "高并发 / 复杂中后台架构经验",
"niceToHave": "React、微前端",
"knockout": "无真实项目",
"competency": "专业能力\n业务理解\n沟通协同\n抗压推进",
"matchKeywords": "前端,Vue,工程化,架构",
"genderRestriction": "",
"ageRestriction": "",
"probationPeriod": "3 个月",
"probationCriteria": "转正看能否独立扛起一个业务线的前端架构",
"nonCompete": "否",
"internalFeasibility": "无人可培训,必须外招",
"verification": "简历看主导过的大前端项目规模与并发量",
"sensitive": "(内部补充备注,如无留空)",
"internalNote": "## 命脉推导\n…(寻源策略/目标公司/排除画像全文——internalOnly,不进 OA,走 oaBillNo 关联)"
}
}
```
## 7. 组装前自检清单(提交定稿包前逐项核对)
1. 键名仅取自本文 §2/§3/§4——**严禁自创短键**(age/gender/sex/试用期…)。
2. age→`ageRestriction`、gender→`genderRestriction`、试用期→`probationPeriod`(+`probationCriteria`)、竞业→`nonCompete`
3. 幂等键填写正确:OA 流程使用顶层 `oaBillNo`;过渡 QA 使用顶层 `external_id`(或 `job.externalId`);禁用顶层 `externalId`
4. `title` + `jd` 必有;`responsibilities`/`requirements`/`mustHave`/`knockout`/`matchKeywords` 尽量有;对内执行约束**空也保留键名**
5. 对外 JD MD 文本里不得出现年龄/性别/试用期/竞业/命脉推导等内部内容(与 JSON 内键同源不同去)。
6. `internalNote`/`sensitive` 不随 OA 单提交;需在 OA 审批通过后归档的内容,经 `oaBillNo` 关联通道合并。
## 8. 代码消费点(想改契约先改这里)
- `backend/app/repositories/external_claim_repository.py``_PREVIEW_FIELDS`(认领预览白名单)、`_INTERNAL_ONLY_JOB_KEYS`(对内剥离,8 键,**当前不含 internalNote**——暂无 with_job 调用方所以无泄露路径,未来开放全量预览需补)、`upsert_external_claim`(幂等键读取)、`claim_external_job`(认领归一)。
- `backend/app/services/llm.py``_INTERNAL_ONLY_JOB_KEYS`(9 键,含 internalNote)+ `_sanitize_job_for_external`(对外 JD 生成前剥离)——对内纪律的最终防线。
- `backend/app/routers/agent.py` + `agent_repository.search_jobs_for_agent`:下次访谈读回历史岗位(含对内字段,仅授权 agent + INGEST_TOKEN)。
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment