CareerNexus 职联:岗位能力图谱构建与动态演化分析平台(挑战杯 XH-202621)

- 全链路:多源JD接入/清洗交叉验证/结构化抽取(星火+离线双通道)/时序知识图谱/新岗位发现/演化分析/人岗匹配/学习路径
- WebUI 五视图:驾驶舱/图谱工作台/岗位演化/匹配(单人+批量)/学习路径
- 设置中心(config.json)/Token鉴权/SQLite状态库/语义向量通道(BGE-M3本地或联网API)
- 71 个 pytest 用例;数据目录仅保留结构(.gitkeep),数据由 scripts/generate_dataset.py 复现
This commit is contained in:
RoyirinRosmontis
2026-08-03 13:15:35 +08:00
commit a10442d78c
78 changed files with 12860 additions and 0 deletions
+932
View File
@@ -0,0 +1,932 @@
"""自备数据集生成器(random.seed(2026) 固定可复现)。
产出:
- data/skills_lexicon.json 技能词表(>=160 技能点:名称/类别/别名/级别/前置技能)
+ 行业词表(7 个行业)与岗位-行业归属
- data/jd_raw/batch_YYYY.jsonl 原始 JD(2019-2026,演化信号烘焙,约 8% 近重复、噪声植入)
每条 JD 含 industry 字段(招聘平台标注的所属行业),文本经多模板族渲染:
职责句式 >=15 套(含时代门槛,2019 年不会出现"大模型"),可选公司介绍/
项目背景/团队福利段落,长度分布 150-500 字。
- data/jd_raw/_meta.json 植入的抄袭簇与噪声清单(供测试核验)
- data/testset/jd_testset.jsonl + gold_answers.json >=120 条带标准答案的 JD
- data/testset/match_gold.json 标注好的人岗匹配对(>=30 对)
- data/resumes/*.txt + gold.json 7 份简历样例(完整/部分/错位)与技能标准答案
- data/reports/*.txt 3 份行业趋势报告样例(与 JD 演化信号相互印证)
- data/review/audit.jsonl 预置审核/编辑留痕种子记录
公平性说明:gold_answers 在生成 JD 文本之前先确定结构(标题/职责/必备/加分/场景),
再据此渲染文本;评测脚本从文本重新抽取再与 gold 比对,不是反向拟合。
"""
from __future__ import annotations
import json
import random
import sys
from datetime import date, timedelta
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT))
from app.extract.offline import DUTY_HEADERS, PREF_HEADERS, REQ_HEADERS, TAIL_HEADERS # noqa: E402
SEED = 2026
rng = random.Random(SEED)
# ---------------------------------------------------------------- 技能词表
# (名称, 类别, [别名], 级别, [前置技能])
SKILLS = [
# 编程语言
("Java", "编程语言", [], "L1", []), ("Python", "编程语言", [], "L1", []),
("Go", "编程语言", ["Golang"], "L1", []), ("C++", "编程语言", [], "L1", ["C"]),
("C", "编程语言", ["C语言"], "L1", []), ("JavaScript", "编程语言", ["JS"], "L1", []),
("TypeScript", "编程语言", ["TS"], "L2", ["JavaScript"]), ("PHP", "编程语言", [], "L1", []),
("Scala", "编程语言", [], "L2", ["Java"]), ("Kotlin", "编程语言", [], "L2", ["Java"]),
("Rust", "编程语言", [], "L3", []), ("SQL", "编程语言", [], "L1", []),
("Shell", "编程语言", ["Bash"], "L1", ["Linux"]), ("R", "编程语言", [], "L2", []),
("MATLAB", "编程语言", [], "L2", []),
# 后端框架
("Spring", "后端框架", [], "L2", ["Java"]), ("Spring Boot", "后端框架", ["SpringBoot"], "L2", ["Spring"]),
("Spring Cloud", "后端框架", ["SpringCloud"], "L3", ["Spring Boot", "微服务"]),
("MyBatis", "后端框架", ["Mybatis"], "L2", ["Java", "SQL"]),
("Django", "后端框架", [], "L2", ["Python"]), ("Flask", "后端框架", [], "L2", ["Python"]),
("FastAPI", "后端框架", [], "L2", ["Python"]), ("Gin", "后端框架", [], "L2", ["Go"]),
("Express", "后端框架", [], "L2", ["Node.js"]), ("NestJS", "后端框架", [], "L3", ["TypeScript"]),
("Netty", "后端框架", [], "L3", ["Java"]), ("Dubbo", "后端框架", [], "L3", ["Java", "微服务"]),
("gRPC", "后端框架", [], "L3", ["微服务"]),
("Struts", "后端框架", [], "L1", ["Java"]), ("Servlet", "后端框架", [], "L1", ["Java"]),
("JSP", "后端框架", [], "L1", ["Java"]), ("SSM", "后端框架", [], "L2", ["Spring", "MyBatis"]),
# 前端
("Vue", "前端", ["Vue.js"], "L2", ["JavaScript"]), ("React", "前端", ["React.js"], "L2", ["JavaScript"]),
("Angular", "前端", ["AngularJS"], "L2", ["TypeScript"]), ("jQuery", "前端", [], "L1", ["JavaScript"]),
("Webpack", "前端", [], "L2", ["JavaScript"]), ("Vite", "前端", [], "L2", ["JavaScript"]),
("Node.js", "前端", ["Node"], "L2", ["JavaScript"]), ("小程序开发", "前端", ["微信小程序"], "L2", ["JavaScript"]),
("Element UI", "前端", [], "L1", ["Vue"]), ("Ant Design", "前端", [], "L1", ["React"]),
("HTML", "前端", ["HTML5"], "L1", []), ("CSS", "前端", ["CSS3"], "L1", []),
("Tailwind CSS", "前端", [], "L2", ["CSS"]), ("低代码平台", "前端", [], "L2", []),
("微前端", "前端", [], "L3", ["JavaScript"]),
# 数据库与中间件
("MySQL", "数据库", [], "L1", ["SQL"]), ("PostgreSQL", "数据库", [], "L2", ["SQL"]),
("Oracle", "数据库", [], "L2", ["SQL"]), ("Redis", "数据库", [], "L2", []),
("MongoDB", "数据库", [], "L2", []), ("Elasticsearch", "数据库", ["ElasticSearch"], "L2", ["Linux"]),
("ClickHouse", "数据库", [], "L3", ["SQL"]), ("HBase", "数据库", [], "L3", ["Hadoop"]),
("SQLite", "数据库", [], "L1", ["SQL"]), ("TiDB", "数据库", [], "L3", ["MySQL"]),
("Kafka", "中间件", [], "L2", ["Linux"]), ("RabbitMQ", "中间件", [], "L2", []),
("RocketMQ", "中间件", [], "L2", ["Java"]), ("Pulsar", "中间件", [], "L3", ["Kafka"]),
("ZooKeeper", "中间件", [], "L2", ["Linux"]), ("Tomcat", "中间件", [], "L1", ["Java"]),
("WebLogic", "中间件", [], "L2", ["Java"]), ("Nginx", "中间件", [], "L1", ["Linux"]),
# 大数据
("Hadoop", "大数据", [], "L2", ["Linux", "Java"]), ("Spark", "大数据", [], "L2", ["Hadoop"]),
("Flink", "大数据", [], "L3", ["Kafka"]), ("Hive", "大数据", [], "L2", ["Hadoop", "SQL"]),
("HDFS", "大数据", [], "L2", ["Hadoop"]), ("Airflow", "大数据", [], "L2", ["Python"]),
("DataX", "大数据", [], "L2", []), ("Sqoop", "大数据", [], "L2", ["Hadoop"]),
("Presto", "大数据", [], "L3", ["SQL"]), ("Doris", "大数据", [], "L3", ["SQL"]),
("数据挖掘", "大数据", [], "L2", ["Python", "SQL"]),
# AI 与算法
("机器学习", "AI算法", ["机器学习算法"], "L2", ["Python"]),
("深度学习", "AI算法", [], "L3", ["机器学习"]),
("PyTorch", "AI算法", [], "L2", ["Python", "深度学习"]),
("TensorFlow", "AI算法", [], "L2", ["Python", "深度学习"]),
("Keras", "AI算法", [], "L2", ["TensorFlow"]),
("Scikit-learn", "AI算法", ["sklearn"], "L2", ["机器学习"]),
("XGBoost", "AI算法", [], "L2", ["机器学习"]), ("LightGBM", "AI算法", [], "L2", ["机器学习"]),
("NLP", "AI算法", ["自然语言处理"], "L3", ["机器学习"]),
("计算机视觉", "AI算法", ["CV"], "L3", ["深度学习"]),
("OpenCV", "AI算法", [], "L2", ["Python"]), ("OCR", "AI算法", ["文字识别"], "L2", ["计算机视觉"]),
("语音识别", "AI算法", [], "L3", ["深度学习"]), ("推荐算法", "AI算法", ["推荐系统"], "L3", ["机器学习"]),
("强化学习", "AI算法", [], "L3", ["深度学习"]), ("知识图谱", "AI算法", [], "L3", ["NLP"]),
("大模型应用开发", "AI算法", ["LLM应用开发", "大模型应用", "大语言模型应用"], "L3", ["Python", "NLP"]),
("RAG", "AI算法", ["检索增强生成"], "L3", ["大模型应用开发", "向量数据库"]),
("提示词工程", "AI算法", ["Prompt工程"], "L2", ["大模型应用开发"]),
("向量数据库", "AI算法", ["向量库"], "L2", ["数据库基础"]),
("LangChain", "AI算法", [], "L2", ["大模型应用开发"]),
("模型微调", "AI算法", ["Fine-tuning", "SFT"], "L3", ["深度学习", "PyTorch"]),
("AI辅助编程", "AI算法", ["Copilot", "AI编程助手"], "L1", []),
# 云原生与运维
("Linux", "运维", [], "L1", []), ("Docker", "云原生", [], "L2", ["Linux"]),
("Kubernetes", "云原生", ["K8s", "k8s"], "L3", ["Docker"]),
("微服务", "云原生", ["微服务架构"], "L2", []),
("分布式系统", "云原生", ["分布式"], "L3", []), ("高并发", "云原生", [], "L3", ["分布式系统"]),
("云计算", "云原生", ["云平台"], "L2", []), ("Service Mesh", "云原生", ["服务网格"], "L3", ["Kubernetes"]),
("CI/CD", "运维", ["持续集成"], "L2", ["Git"]), ("Git", "运维", [], "L1", []),
("Svn", "运维", ["SVN"], "L1", []), ("Jenkins", "运维", [], "L2", ["CI/CD"]),
("Terraform", "运维", [], "L3", ["云计算"]), ("Ansible", "运维", [], "L2", ["Linux"]),
("Prometheus", "运维", [], "L2", ["Kubernetes"]), ("Grafana", "运维", [], "L2", ["Prometheus"]),
("ELK", "运维", [], "L2", ["Elasticsearch"]), ("DevOps", "运维", [], "L2", ["CI/CD"]),
("AIOps", "运维", ["智能运维"], "L3", ["Prometheus", "机器学习"]),
("AWS", "云原生", ["亚马逊云"], "L2", ["云计算"]), ("阿里云", "云原生", [], "L2", ["云计算"]),
("腾讯云", "云原生", [], "L2", ["云计算"]),
# 测试
("自动化测试", "测试", [], "L2", ["Python"]), ("Selenium", "测试", [], "L2", ["自动化测试"]),
("JUnit", "测试", [], "L1", ["Java"]), ("Pytest", "测试", [], "L1", ["Python"]),
("性能测试", "测试", [], "L2", []), ("接口测试", "测试", ["API测试"], "L2", []),
("JMeter", "测试", [], "L2", ["性能测试"]), ("Postman", "测试", [], "L1", ["接口测试"]),
("单元测试", "测试", [], "L1", []), ("测试用例设计", "测试", [], "L2", []),
# 嵌入式与物联网
("嵌入式开发", "嵌入式", ["嵌入式"], "L2", ["C"]), ("单片机", "嵌入式", [], "L1", ["C"]),
("STM32", "嵌入式", [], "L2", ["单片机"]), ("RTOS", "嵌入式", ["实时操作系统"], "L2", ["C"]),
("FreeRTOS", "嵌入式", [], "L2", ["RTOS"]), ("ARM", "嵌入式", [], "L2", []),
("驱动开发", "嵌入式", ["驱动程序开发"], "L3", ["C", "Linux"]),
("Verilog", "嵌入式", [], "L3", []), ("FPGA", "嵌入式", [], "L3", ["Verilog"]),
("PCB设计", "嵌入式", ["PCB"], "L2", []),
("MQTT", "物联网", [], "L2", []), ("传感器", "物联网", ["传感器技术"], "L1", []),
("物联网平台", "物联网", ["IoT平台"], "L2", []), ("边缘计算", "物联网", [], "L3", ["云计算"]),
("LoRa", "物联网", [], "L2", []), ("Zigbee", "物联网", [], "L2", []),
# 产品与分析
("产品设计", "产品", [], "L2", []), ("需求分析", "产品", [], "L2", []),
("项目管理", "产品", [], "L2", []), ("Axure", "产品", [], "L1", []),
("竞品分析", "产品", [], "L1", []), ("用户增长", "产品", [], "L2", []),
("AI产品", "产品", ["AI产品经理"], "L3", ["产品设计"]),
("数据分析", "数据分析", [], "L2", ["SQL"]), ("Excel", "数据分析", [], "L1", []),
("Tableau", "数据分析", [], "L2", ["数据可视化"]), ("Power BI", "数据分析", ["PowerBI"], "L2", ["数据可视化"]),
("SPSS", "数据分析", [], "L2", []), ("数据可视化", "数据分析", [], "L2", ["数据分析"]),
("A/B测试", "数据分析", ["AB测试"], "L2", ["数据分析"]),
]
SCENARIOS = ["电商", "金融", "物流", "社交", "教育", "医疗", "政务", "游戏",
"出行", "智能制造", "短视频", "广告", "供应链", "零售", "安防"]
# 行业词表(岗位归属 1-2 个行业,图谱中构建 Industry 节点)
INDUSTRIES = ["互联网/软件", "人工智能", "金融科技", "智能制造",
"物联网", "智慧城市", "智慧医疗"]
# ---------------------------------------------------------------- 岗位原型
def arc(title, category, years, salary, scenarios, industries,
duty_tmpls, duty_objs, timeline, volumes):
return dict(title=title, category=category, years=years, salary=salary,
scenarios=scenarios, industries=industries,
duty_tmpls=duty_tmpls, duty_objs=duty_objs,
timeline=timeline, volumes=volumes)
BACKEND_DUTIES = ["负责{o}的设计与开发", "参与{o}的性能优化与重构", "配合产品团队完成{o}的需求评审",
"编写{o}的技术文档与接口文档", "承担{o}的线上问题排查与修复", "推动{o}的代码评审与质量改进"]
BACKEND_OBJS = ["后端服务", "核心业务系统", "交易网关", "订单中心", "用户中心", "缓存体系", "消息管道", "权限平台"]
# 通用职责句式库:(模板, 最早出现年份)。时代词(大模型/AI/低代码)只出现在
# 对应年份之后,保证 2019 年的 JD 不会出现"大模型"等未来措辞。
GENERIC_DUTIES = [
("参与{o}从0到1的搭建与持续迭代", 2019),
("负责{o}高并发场景的优化与稳定性保障", 2020),
("与产品、测试团队协作,推动{o}高质量落地", 2019),
("沉淀{o}的通用组件与最佳实践", 2020),
("主导{o}的技术选型与难点攻坚", 2021),
("建设{o}的监控与告警体系", 2021),
("负责{o}的架构演进与技术债治理", 2022),
("推动{o}的自动化与工程效率提升", 2022),
("探索AI工具在{o}中的应用与提效", 2024),
("引入大模型能力改造{o}的现有流程", 2025),
]
ARCHETYPES = [
arc("Java开发工程师", "后端开发", 3, "15K-30K·14薪", ["电商", "金融", "物流"],
["互联网/软件", "金融科技"],
BACKEND_DUTIES, BACKEND_OBJS,
[(2019, 2021, ["Java", "MySQL", "Spring", "MyBatis", "Servlet"], ["Struts", "JSP", "Linux"]),
(2022, 2023, ["Java", "Spring Boot", "Spring Cloud", "MySQL", "Redis", "微服务"], ["Docker", "Kafka", "Kubernetes"]),
(2024, 2026, ["Java", "Spring Boot", "Spring Cloud", "Redis", "MySQL", "分布式系统"], ["AI辅助编程", "大模型应用开发", "Kubernetes"])],
{2019: 8, 2020: 8, 2021: 8, 2022: 10, 2023: 12, 2024: 24, 2025: 24, 2026: 24}),
arc("Python开发工程师", "后端开发", 3, "14K-28K", ["教育", "金融", "电商"],
["互联网/软件"],
BACKEND_DUTIES, BACKEND_OBJS,
[(2019, 2021, ["Python", "MySQL", "Django", "Linux", "Git"], ["Flask", "Redis", "Nginx"]),
(2022, 2023, ["Python", "FastAPI", "MySQL", "Redis", "Linux"], ["Docker", "Kafka", "Git"]),
(2024, 2026, ["Python", "FastAPI", "Redis", "MySQL", "分布式系统"], ["Docker", "大模型应用开发", "AI辅助编程"])],
{2019: 6, 2020: 6, 2021: 6, 2022: 8, 2023: 12, 2024: 24, 2025: 24, 2026: 24}),
# —— 前端:jQuery/AngularJS 时代 → Vue/React + TypeScript → 工程化/Vite → 低代码 + AI 辅助 ——
arc("前端工程师", "前端", 3, "13K-26K", ["电商", "社交", "短视频"],
["互联网/软件"],
["负责{o}的页面开发与交互实现", "参与{o}的前端性能优化", "与后端联调{o}的数据接口",
"维护{o}的组件库与工程化体系", "承担{o}的兼容性适配工作"],
["移动端页面", "管理后台", "可视化大屏", "运营活动页", "组件库", "工程化脚手架"],
[(2019, 2021, ["JavaScript", "HTML", "CSS", "Vue", "jQuery"], ["Webpack", "Angular", "小程序开发"]),
(2022, 2023, ["JavaScript", "TypeScript", "Vue", "React", "Webpack"], ["Vite", "Node.js", "小程序开发"]),
(2024, 2026, ["TypeScript", "Vue", "React", "Vite", "低代码平台"], ["AI辅助编程", "微前端", "Node.js"])],
{2019: 6, 2020: 6, 2021: 8, 2022: 12, 2023: 24, 2024: 24, 2025: 24, 2026: 24}),
arc("数据工程师", "大数据", 3, "16K-32K", ["金融", "物流", "零售"],
["互联网/软件", "金融科技"],
["负责{o}的采集与清洗", "搭建{o}的离线数仓分层", "开发{o}的实时计算任务",
"维护{o}的调度与监控体系", "参与{o}的数据治理工作"],
["业务数据", "日志数据", "实时数仓", "离线数仓", "数据湖", "指标体系"],
[(2019, 2021, ["SQL", "Hadoop", "Hive", "Spark", "Python"], ["HBase", "Sqoop", "Scala"]),
(2022, 2026, ["SQL", "Spark", "Flink", "Kafka", "Python"], ["ClickHouse", "Doris", "Airflow"])],
{2019: 5, 2020: 5, 2021: 5, 2022: 6, 2023: 12, 2024: 24, 2025: 24, 2026: 24}),
arc("算法工程师", "AI算法", 3, "20K-40K", ["广告", "电商", "金融"],
["人工智能"],
["负责{o}的建模与迭代", "参与{o}的特征工程建设", "跟踪{o}的前沿论文并落地",
"优化{o}的线上推理性能", "与工程团队协作上线{o}"],
["推荐模型", "排序模型", "风控模型", "用户画像", "召回策略", "预估服务"],
[(2019, 2021, ["Python", "机器学习", "深度学习", "TensorFlow", "SQL"], ["XGBoost", "Spark", "C++"]),
(2022, 2023, ["Python", "机器学习", "深度学习", "PyTorch", "推荐算法"], ["XGBoost", "模型微调", "强化学习"]),
(2024, 2026, ["Python", "机器学习", "深度学习", "PyTorch", "推荐算法"], ["大模型应用开发", "模型微调", "强化学习"])],
{2019: 5, 2020: 5, 2021: 5, 2022: 6, 2023: 12, 2024: 24, 2025: 24, 2026: 24}),
# —— 数据分析:Excel/SPSS 时代 → SQL/Python → BI 平台 → LLM 增强分析 ——
arc("数据分析师", "数据分析", 2, "12K-22K", ["零售", "电商", "金融"],
["互联网/软件", "金融科技"],
["负责{o}的报表体系建设", "输出{o}的专题分析报告", "搭建{o}的核心指标看板",
"支持业务团队的{o}取数需求", "参与{o}的复盘与归因分析"],
["经营数据", "用户行为", "活动效果", "渠道投放", "留存漏斗", "销售大盘"],
[(2019, 2021, ["Excel", "SQL", "SPSS", "数据分析", "数据可视化"], ["Tableau", "R", "Power BI"]),
(2022, 2023, ["SQL", "Python", "数据分析", "数据可视化", "Excel"], ["Power BI", "Tableau", "A/B测试"]),
(2024, 2026, ["SQL", "Python", "数据分析", "数据可视化", "A/B测试"], ["Power BI", "Tableau", "大模型应用开发"])],
{2019: 5, 2020: 5, 2021: 6, 2022: 8, 2023: 12, 2024: 24, 2025: 24, 2026: 24}),
arc("测试开发工程师", "测试", 3, "14K-26K", ["金融", "电商", "政务"],
["互联网/软件"],
["负责{o}的测试方案设计", "开发{o}的自动化测试脚本", "搭建{o}的测试平台",
"执行{o}的性能压测", "推动{o}的质量效能改进"],
["核心交易系统", "支付链路", "回归测试", "接口自动化", "压测体系", "质量平台"],
[(2019, 2021, ["Python", "自动化测试", "Selenium", "接口测试", "SQL"], ["JMeter", "JUnit", "Jenkins"]),
(2022, 2026, ["Python", "自动化测试", "接口测试", "性能测试", "CI/CD"], ["Pytest", "JMeter", "Docker"])],
{2019: 4, 2020: 4, 2021: 4, 2022: 6, 2023: 12, 2024: 24, 2025: 24, 2026: 24}),
# —— 运维:脚本/手工 → Ansible 自动化 → DevOps/K8s → AIOps ——
arc("运维工程师(SRE)", "运维", 3, "15K-28K", ["金融", "游戏", "电商"],
["互联网/软件"],
["负责{o}的稳定运行与监控", "参与{o}的容量规划", "建设{o}的自动化运维体系",
"处理{o}的线上故障与应急", "完善{o}的告警与巡检机制"],
["生产集群", "发布流水线", "监控体系", "容器平台", "中间件", "灾备体系"],
[(2019, 2021, ["Linux", "Shell", "Nginx", "MySQL", "Tomcat"], ["Ansible", "Jenkins", "Python"]),
(2022, 2023, ["Linux", "Docker", "Kubernetes", "CI/CD", "Ansible"], ["Prometheus", "DevOps", "Grafana"]),
(2024, 2026, ["Linux", "Kubernetes", "Docker", "Prometheus", "DevOps"], ["Grafana", "Terraform", "AIOps"])],
{2019: 4, 2020: 4, 2021: 6, 2022: 8, 2023: 12, 2024: 24, 2025: 24, 2026: 24}),
arc("嵌入式工程师", "嵌入式", 3, "14K-28K", ["智能制造", "安防", "出行"],
["智能制造", "物联网"],
["负责{o}的固件开发", "参与{o}的驱动调试", "完成{o}的板级联调与测试",
"优化{o}的功耗与稳定性", "编写{o}的开发文档"],
["主控固件", "通信模组", "传感器驱动", "boot 启动流程", "低功耗方案", "量产固件"],
[(2019, 2022, ["C", "C++", "嵌入式开发", "单片机", "RTOS"], ["STM32", "FreeRTOS", "Linux"]),
(2023, 2026, ["C", "C++", "嵌入式开发", "RTOS", "驱动开发"], ["STM32", "边缘计算", "MQTT"])],
{2019: 4, 2020: 4, 2021: 4, 2022: 4, 2023: 5, 2024: 6, 2025: 6, 2026: 6}),
arc("物联网工程师", "物联网", 3, "13K-25K", ["智能制造", "物流", "安防"],
["物联网", "智慧城市"],
["负责{o}的接入方案设计", "开发{o}的设备管理功能", "搭建{o}的数据采集链路",
"参与{o}的平台联调", "优化{o}的通信稳定性"],
["设备接入", "网关", "传感网络", "边缘节点", "设备影子", "远程升级"],
[(2019, 2021, ["C", "MQTT", "传感器", "单片机", "物联网平台"], ["Zigbee", "LoRa", "STM32"]),
(2022, 2026, ["MQTT", "物联网平台", "边缘计算", "Python", "传感器"], ["LoRa", "嵌入式开发", "云计算"])],
{2019: 4, 2020: 4, 2021: 4, 2022: 5, 2023: 5, 2024: 6, 2025: 6, 2026: 6}),
arc("NLP工程师", "AI算法", 3, "18K-36K", ["教育", "政务", "金融"],
["人工智能"],
["负责{o}的算法研发", "参与{o}的语料建设", "优化{o}的模型效果",
"跟进{o}的前沿技术", "支持{o}的工程化落地"],
["智能客服", "文本分类", "信息抽取", "问答系统", "搜索相关性", "舆情分析"],
[(2019, 2021, ["Python", "NLP", "机器学习", "TensorFlow", "SQL"], ["知识图谱", "数据挖掘", "深度学习"]),
(2022, 2023, ["Python", "NLP", "深度学习", "PyTorch", "知识图谱"], ["模型微调", "数据挖掘", "机器学习"]),
(2024, 2026, ["Python", "NLP", "深度学习", "PyTorch", "大模型应用开发"], ["模型微调", "RAG", "LangChain"])],
{2019: 4, 2020: 4, 2021: 4, 2022: 5, 2023: 6, 2024: 8, 2025: 8, 2026: 8}),
arc("CV工程师", "AI算法", 3, "18K-36K", ["安防", "智能制造", "出行"],
["人工智能", "智能制造"],
["负责{o}的算法研发", "参与{o}的数据标注体系", "优化{o}的模型精度与速度",
"部署{o}到边缘设备", "跟进{o}的最新论文"],
["缺陷检测", "目标检测", "视频结构化", "人脸识别", "车道线检测", "工业质检"],
[(2019, 2021, ["Python", "计算机视觉", "深度学习", "TensorFlow", "C++"], ["OCR", "OpenCV", "模型微调"]),
(2022, 2023, ["Python", "计算机视觉", "深度学习", "PyTorch", "OCR"], ["模型微调", "边缘计算", "OpenCV"]),
(2024, 2026, ["Python", "计算机视觉", "深度学习", "PyTorch", "OCR"], ["模型微调", "边缘计算", "大模型应用开发"])],
{2019: 4, 2020: 4, 2021: 4, 2022: 5, 2023: 6, 2024: 8, 2025: 8, 2026: 8}),
arc("云原生工程师", "云原生", 3, "18K-35K", ["金融", "政务", "电商"],
["互联网/软件"],
["负责{o}的架构设计与落地", "建设{o}的容器编排体系", "推进{o}的服务治理",
"优化{o}的资源利用率", "保障{o}的高可用"],
["容器平台", "微服务治理", "多云架构", "弹性伸缩", "服务网格", "可观测体系"],
[(2020, 2022, ["Docker", "Kubernetes", "微服务", "Linux", "Go"], ["Service Mesh", "Prometheus", "DevOps"]),
(2023, 2026, ["Kubernetes", "Docker", "微服务", "CI/CD", "Go"], ["Service Mesh", "Terraform", "云计算"])],
{2020: 4, 2021: 4, 2022: 5, 2023: 6, 2024: 8, 2025: 8, 2026: 8}),
arc("AI产品经理", "产品", 3, "18K-35K", ["教育", "金融", "医疗"],
["人工智能", "智慧医疗"],
["负责{o}的规划与落地", "输出{o}的需求文档", "跟进{o}的研发进度",
"设计{o}的评估指标", "调研{o}的行业动态"],
["智能问答产品", "AI 助手", "智能化应用", "知识库产品", "智能审核", "AI 创作工具"],
[(2020, 2022, ["产品设计", "需求分析", "数据分析", "项目管理", "AI产品"], ["Axure", "竞品分析", "SQL"]),
(2023, 2026, ["AI产品", "需求分析", "大模型应用开发", "产品设计", "数据分析"], ["提示词工程", "用户增长", "A/B测试"])],
{2020: 3, 2021: 3, 2022: 3, 2023: 4, 2024: 6, 2025: 6, 2026: 6}),
arc("Go开发工程师", "后端开发", 3, "16K-32K", ["游戏", "社交", "金融"],
["互联网/软件"],
BACKEND_DUTIES, BACKEND_OBJS,
[(2019, 2021, ["Go", "MySQL", "Redis", "Linux", "Gin"], ["Docker", "gRPC", "Kafka"]),
(2022, 2026, ["Go", "微服务", "gRPC", "Redis", "Kubernetes"], ["Kafka", "Prometheus", "高并发"])],
{2019: 4, 2020: 4, 2021: 4, 2022: 5, 2023: 6, 2024: 8, 2025: 8, 2026: 8}),
# —— 2023 年后才出现且快速增长的新岗位(支撑“新岗位发现”演示) ——
arc("大模型应用工程师", "AI算法", 2, "25K-50K", ["金融", "教育", "医疗"],
["人工智能"],
["负责{o}的应用开发与落地", "设计{o}的提示词与流程编排", "建设{o}的评测体系",
"优化{o}的推理成本与延迟", "跟进{o}的生态工具"],
["智能助手", "企业知识库", "Agent 应用", "代码助手", "智能审核", "多轮对话"],
[(2023, 2026, ["Python", "大模型应用开发", "提示词工程", "LangChain", "NLP"], ["RAG", "模型微调", "向量数据库"])],
{2023: 2, 2024: 8, 2025: 14, 2026: 20}),
arc("RAG工程师", "AI算法", 2, "25K-45K", ["金融", "政务", "教育"],
["人工智能"],
["负责{o}的检索链路搭建", "优化{o}的召回与重排", "建设{o}的知识库加工流水线",
"评估{o}的问答质量", "跟进{o}的新范式"],
["企业知识库", "文档问答", "语义检索", "混合检索", "知识中台", "智能客服"],
[(2024, 2026, ["Python", "RAG", "向量数据库", "大模型应用开发", "LangChain"], ["模型微调", "Elasticsearch", "知识图谱"])],
{2024: 4, 2025: 9, 2026: 15}),
arc("提示词工程师", "AI算法", 1, "15K-30K", ["教育", "电商", "广告"],
["人工智能"],
["负责{o}的提示词设计", "沉淀{o}的提示词模板库", "评估{o}的输出质量",
"与业务团队共创{o}的使用范式", "编写{o}的最佳实践文档"],
["营销文案生成", "智能客服话术", "内容创作", "教学辅导", "商品描述", "对话流程"],
[(2024, 2026, ["提示词工程", "大模型应用开发", "Python", "数据分析"], ["LangChain", "RAG", "AI产品"])],
{2024: 2, 2025: 6, 2026: 10}),
]
COMPANY_PRE = ["星澜", "云启", "数联", "智汇", "蓝湾", "极光", "恒宇", "锐思", "博远", "辰安",
"飞鱼", "墨白", "青藤", "远望", "砺石", "潮汐", "峰行", "微光", "若谷", "启航"]
COMPANY_SUF = ["科技", "网络", "信息", "数据", "智能", "软件", "互联", "数字"]
# 15 城:一线 + 新一线(成都/武汉/西安/苏州/长沙等)
CITIES = ["北京", "上海", "深圳", "杭州", "成都", "广州", "南京", "武汉",
"西安", "苏州", "长沙", "重庆", "天津", "青岛", "合肥"]
SOURCES = ["BOSS直聘", "拉勾网", "智联招聘", "前程无忧", "猎聘网"]
# ---------------------------------------------------------------- 文本渲染素材
# 公司介绍:按年代分池,时代措辞只出现在对应年份之后
INTROS_EARLY = [
"{c}是一家专注于新一代信息技术服务的高新技术企业,现诚邀优秀人才加入。",
"{c}深耕行业多年,团队氛围开放,技术栈前沿,期待你的加入。",
"{c}业务高速增长中,提供有竞争力的薪酬与完善的培养体系。",
"{c}核心团队来自一线大厂,正在寻找志同道合的工程师。",
"{c}处于快速扩张期,移动业务用户量持续攀升,欢迎加入我们。",
]
INTROS_MID = INTROS_EARLY + [
"{c}已完成新一轮融资,正全面推进云原生架构升级,期待你的加入。",
"{c}业务覆盖多个城市,研发体系成熟,重视工程质量与技术沉淀。",
]
INTROS_LATE = INTROS_MID + [
"{c}全面拥抱 AI 原生开发,大模型已深度融入研发流程,欢迎同行者。",
"{c}正在推进 AIGC 与核心业务的深度融合,寻找敢想敢做的工程师。",
"{c}智能化转型加速,AI 辅助研发已成团队标配,期待你的加入。",
]
# 项目背景/团队介绍(可选段落,{a} 只会代入本条 JD 已标注的场景词)
BACKGROUNDS = [
"关于我们:{c}的{a}业务正处于高速增长期,你将直接参与支撑千万级用户的核心系统建设,与团队一起解决真实复杂的业务问题。",
"项目背景:本岗位属于{a}方向核心团队,业务数据量大、迭代节奏快,技术挑战与成长空间并存。",
"团队介绍:{a}研发团队规模 50+,核心成员来自一线大厂,重视工程质量与技术沉淀。",
]
# 团队与福利(可选尾部段落,抽取器按标题截断,不进入任何技能区)
WELFARE_LINES = [
"弹性工作不打卡,五险一金全额缴纳,年度体检与带薪年假一应俱全。",
"技术氛围浓厚,每周内部分享,提供外部培训与技术会议预算。",
"扁平化管理,晋升通道清晰,核心成员可参与期权激励计划。",
"免费三餐与下午茶,团队年轻化,协作氛围轻松高效。",
]
REQ_YEAR_LINES = [
"{y}年以上相关工作经验,责任心强,具备良好的沟通能力;",
"{y}年以上相关岗位经验,具备良好的沟通与推动能力;",
"{y}年以上实战经验,结果导向,能独立承担模块 Owner 工作;",
]
REQ_VERBS = ["熟练掌握", "精通", "熟悉并掌握", "深入理解"]
REQ_SOFT_LINES = [
"具备良好的学习能力与团队协作精神;",
"逻辑清晰,自驱力强,对技术有热情;",
"具备良好的文档习惯,重视工程质量与可维护性;",
"能适应快速迭代的研发节奏,抗压能力强;",
]
SCEN_TEMPLATES = ["具有{a}或{b}行业经验者优先;", "熟悉{a}/{b}业务场景者优先;",
"有{a}、{b}行业项目经验者优先;", "具备{a}或{b}相关业务背景者优先;"]
PREF_TEMPLATES = ["了解{s}者优先;", "熟悉{s}者优先考虑;", "有{s}相关实践经验者优先;"]
PREF_EXTRA_LINES = ["有开源项目贡献或高质量技术博客者优先;", "参与过大型技术社区分享者优先;"]
NUM_FORMATS = ["{i}、", "{i}、", "{i}、", "{i}.", "- "]
NOISE_TAILS = [
"【广告】扫码关注公众号,领取面试大礼包和内部资料。",
"点击关注我们的招聘号,第一时间获取内推信息。",
"【广告】商务合作请加群,扫码领取免费课程资料。",
]
NOISE_FULL = [
"【广告】扫码关注公众号领取求职资料\n点击关注领取福利红包\n长期回收二手办公设备,非诚勿扰",
"【广告】推广信息:扫码加入求职群领取资料\n商务合作请加群详谈\n加盟代理热线见官网",
"【广告】点击关注即可领取现金红包\n扫码进福利群,天天有惊喜\n代办各类证件,长期有效",
"【广告】推广信息:刷单兼职日结\n扫码添加客服领取任务\n长期回收库存尾货",
]
def intros_for(year: int) -> list[str]:
if year >= 2024:
return INTROS_LATE
if year >= 2022:
return INTROS_MID
return INTROS_EARLY
def skillset_for(a: dict, year: int) -> tuple[list[str], list[str]]:
for y0, y1, req, pref in a["timeline"]:
if y0 <= year <= y1:
return list(req), list(pref)
req, pref = a["timeline"][-1][2], a["timeline"][-1][3]
return list(req), list(pref)
def pick_duties(a: dict, year: int) -> list[str]:
"""按年份过滤句式池(时代门槛),抽 3-6 条职责。"""
pool = list(a["duty_tmpls"]) + [t for t, min_y in GENERIC_DUTIES if year >= min_y]
tmpls = rng.sample(pool, k=min(len(pool), rng.choice([3, 4, 4, 5, 5, 6])))
objs = rng.sample(a["duty_objs"], k=min(len(a["duty_objs"]), len(tmpls)))
while len(objs) < len(tmpls):
objs.append(rng.choice(a["duty_objs"]))
return [t.format(o=o) + ";" for t, o in zip(tmpls, objs)]
def _skill_req_lines(req: list[str]) -> list[str]:
"""必备技能行的多种自然写法(都在要求区内,抽取结果与措辞无关)。"""
verb = rng.choice(REQ_VERBS)
if len(req) >= 4 and rng.random() < 0.4:
cut = rng.randint(2, len(req) - 2)
return [f"{verb}{'、'.join(req[:cut])},熟悉{'、'.join(req[cut:])};"]
if rng.random() < 0.25:
return [f"具备扎实的{'、'.join(req)}功底;"]
return [f"{verb}{'、'.join(req)};"]
def build_text(a: dict, company: str, year: int, years: int, duties: list[str],
req: list[str], pref: list[str], scens: list[str]) -> str:
duty_h = rng.choice(DUTY_HEADERS)
req_h = rng.choice(REQ_HEADERS)
pref_h = rng.choice(PREF_HEADERS)
num_fmt = rng.choice(NUM_FORMATS)
scen_sentence = rng.choice(SCEN_TEMPLATES).format(a=scens[0], b=scens[-1])
lines = [
f"岗位名称:{a['title']}",
rng.choice(intros_for(year)).format(c=company),
]
# 可选段落:项目背景/团队介绍(约 35%)
if rng.random() < 0.35:
lines.append(rng.choice(BACKGROUNDS).format(c=company, a=scens[0]))
lines.append(f"{duty_h}:")
lines += [f"{num_fmt.format(i=i + 1)}{d}" for i, d in enumerate(duties)]
lines.append(f"{req_h}:")
req_lines = [rng.choice(REQ_YEAR_LINES).format(y=years)]
req_lines += _skill_req_lines(req)
req_lines.append(scen_sentence)
req_lines += rng.sample(REQ_SOFT_LINES, k=rng.choice([0, 1, 1, 2]))
lines += [f"{num_fmt.format(i=i + 1)}{t}" for i, t in enumerate(req_lines)]
lines.append(f"{pref_h}:")
lines.append(f"1、{rng.choice(PREF_TEMPLATES).format(s='、'.join(pref))}")
if rng.random() < 0.4:
lines.append(f"2、{rng.choice(PREF_EXTRA_LINES)}")
# 可选尾部段落:团队与福利(约 40%),抽取器按标题截断
if rng.random() < 0.40:
lines.append(f"{rng.choice(TAIL_HEADERS)}:")
lines.append(rng.choice(WELFARE_LINES))
return "\n".join(lines)
def make_jd(a: dict, year: int, jid: str, month: int | None = None) -> tuple[dict, dict]:
"""生成一条 JD 记录与其标准答案(先定结构,再渲染文本)。
month 可由调用方指定(原始数据按年内均匀铺开,避免季度窗口计数随机抖动
制造虚假演化事件);不传则随机(测试集保持自然随机)。
"""
company = rng.choice(COMPANY_PRE) + rng.choice(COMPANY_SUF)
req, pref = skillset_for(a, year)
rng.shuffle(req)
rng.shuffle(pref)
if len(req) > 4 and rng.random() < 0.15: # 轻微抖动:偶尔少写一项必备
req = req[:-1]
pref = pref[: rng.choice([2, 2, 3])]
duties = pick_duties(a, year)
scens = rng.sample(a["scenarios"], k=min(2, len(a["scenarios"])))
years = rng.randint(max(1, a["years"] - 1), a["years"] + 2)
text = build_text(a, company, year, years, duties, req, pref, scens)
month = month or rng.randint(1, 12)
day = rng.randint(1, 28)
record = {
"jid": jid,
"job_title": a["title"],
"company": company,
"city": rng.choice(CITIES),
"salary": a["salary"],
"industry": rng.choice(a["industries"]),
"publish_date": date(year, month, day).isoformat(),
"source": rng.choice(SOURCES),
"url": f"https://jobs.example.com/{jid}",
"text": text,
}
gold = {
"job_title": a["title"],
"responsibilities": duties,
"required_skills": req,
"preferred_skills": pref,
"scenarios": scens,
}
return record, gold
def make_dup_copy(rec: dict, jid: str) -> dict:
"""生成近重复(抄袭)副本:同文不同公司,仅换公司/城市/渠道/薪资与发布日期。"""
new_company = rng.choice(COMPANY_PRE) + rng.choice(COMPANY_SUF)
text = rec["text"].replace(rec["company"], new_company)
copy = dict(rec)
copy.update({
"jid": jid,
"company": new_company,
"city": rng.choice(CITIES),
"source": rng.choice(SOURCES),
"url": f"https://jobs.example.com/{jid}",
"salary": rec["salary"].replace("14薪", "13薪") if "14薪" in rec["salary"] else rec["salary"],
"text": text,
"publish_date": min(
date.fromisoformat(rec["publish_date"]) + timedelta(days=rng.randint(10, 120)),
date(2026, 12, 28)).isoformat(),
})
return copy
def write_jsonl(path: Path, rows: list[dict]) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
with open(path, "w", encoding="utf-8") as f:
for r in rows:
f.write(json.dumps(r, ensure_ascii=False) + "\n")
# ---------------------------------------------------------------- 简历样例(全合成,无真实个人信息)
RESUME_FRONTEND_FULL = (
"姓名:陈思远\n手机:13655557777\n邮箱:chensy@example.com\n"
"4年前端开发经验,主导过大促会场与管理后台的前端架构设计。\n"
"核心技能:熟练掌握JavaScript、TypeScript、HTML、CSS,精通Vue、React双栈,"
"熟悉Vite、Webpack、Node.js与小程序开发,有低代码平台建设经验,日常使用AI辅助编程提效。\n"
"项目经历:负责可视化大屏与管理后台开发,基于Vue与Vite搭建工程化体系;"
"使用React与TypeScript重构信息流页面,首屏性能提升40%。\n"
)
RESUME_DATA_PARTIAL = (
"姓名:刘洋\n手机:13566668888\n邮箱:liuyang.data@example.com\n"
"2年数据分析经验,服务于零售业务线,支持运营团队的日常取数与复盘。\n"
"核心技能:熟练使用SQL取数,掌握Excel、数据可视化与Tableau看板搭建,"
"能用Python完成数据清洗与报表自动化,了解Power BI。\n"
"项目经历:搭建活动效果核心指标看板,输出渠道投放专题分析,"
"在校期间曾用SPSS完成调研统计。\n"
)
RESUME_LLM_FULL = (
"姓名:赵启明\n手机:13777778888\n邮箱:zhaoqm@example.com\n"
"3年AI应用开发经验,专注大模型应用开发与落地。\n"
"核心技能:精通Python,熟悉大模型应用开发、提示词工程、LangChain与RAG,"
"掌握向量数据库与模型微调,了解NLP基础,熟悉FastAPI服务开发。\n"
"项目经历:主导企业知识库问答系统建设,基于RAG与LangChain实现混合检索与重排,"
"通过提示词工程与模型微调将回答准确率提升25%。\n"
)
RESUME_LEGACY_MISMATCH = (
"姓名:孙建国\n手机:13899990000\n邮箱:sunjg@example.com\n"
"8年传统软件经验,长期维护企业内部办公系统。\n"
"核心技能:精通Struts、JSP、Servlet,熟悉Svn与Tomcat部署,"
"掌握jQuery页面开发,了解WebLogic。\n"
"项目经历:负责政务办公系统的日常维护与功能迭代,使用Struts与JSP完成多个模块改造。\n"
)
def _cand(title: str, req: list[str], pref: list[str], scens: list[str],
src: int, comp: int, status: str = "pending") -> dict:
"""构造一条待审核候选的快照(审核留痕种子用)。"""
return {"job_id": f"cand_{title}", "title": title, "category": "新岗位候选",
"required_skills": req, "preferred_skills": pref, "responsibilities": [],
"scenarios": scens, "expected_years": 3, "status": status,
"source_count": src, "company_count": comp}
AUDIT_SEED = [
{"candidate_id": "cand_大模型应用工程师", "action": "accept",
"operator": "王蕾(评审专家)",
"reason": "岗位簇证据充分:40+ 条 JD、独立企业数达标,2024 年起持续高增长,技能结构清晰,准予入库。",
"before": _cand("大模型应用工程师",
["提示词工程", "Python", "LangChain", "大模型应用开发", "NLP"],
["模型微调", "向量数据库", "RAG"], ["教育", "医疗", "金融"], 42, 38),
"after": _cand("大模型应用工程师",
["提示词工程", "Python", "LangChain", "大模型应用开发", "NLP"],
["模型微调", "向量数据库", "RAG"], ["教育", "医疗", "金融"], 42, 38, "active"),
"time": "2026-07-18 10:24:31"},
{"candidate_id": "cand_RAG工程师", "action": "modify",
"operator": "李强(评审专家)",
"reason": "簇内 JD 普遍要求检索引擎实操经验,补充 Elasticsearch 为必备技能后入库。",
"before": _cand("RAG工程师",
["Python", "RAG", "向量数据库", "大模型应用开发", "LangChain"],
["模型微调", "知识图谱"], ["金融", "政务", "教育"], 28, 22),
"after": _cand("RAG工程师",
["Python", "RAG", "向量数据库", "大模型应用开发", "LangChain", "Elasticsearch"],
["模型微调", "知识图谱"], ["金融", "政务", "教育"], 28, 22, "active"),
"time": "2026-07-19 15:02:11"},
{"candidate_id": "cand_元宇宙社区运营", "action": "reject",
"operator": "王蕾(评审专家)",
"reason": "簇内 JD 仅 5 条且集中于 2 家企业,近一年增长不明朗,证据不足,暂不入库。",
"before": _cand("元宇宙社区运营", ["用户增长", "竞品分析"], ["数据分析"],
["社交", "游戏"], 5, 2),
"after": {},
"time": "2026-07-21 09:41:03"},
{"kind": "node_update", "node_id": "job_Java开发工程师",
"operator": "张铭(领域专家)",
"reason": "2024 年后分布式系统已成为该岗位核心要求,上调该关系权重。",
"before": {"weight": 0.82}, "after": {"weight": 0.95},
"time": "2026-07-23 14:12:55"},
{"kind": "node_update", "node_id": "Kubernetes",
"operator": "张铭(领域专家)",
"reason": "词表归类校正:由未标注类别调整为云原生类别。",
"before": {"category": ""}, "after": {"category": "云原生"},
"time": "2026-07-23 14:15:20"},
{"candidate_id": "cand_提示词工程师", "action": "accept",
"operator": "陈静(评审专家)",
"reason": "2024 年起多家企业独立设岗,职责与传统运营岗差异显著,予以入库观察。",
"before": _cand("提示词工程师",
["提示词工程", "大模型应用开发", "Python", "数据分析"],
["LangChain", "RAG", "AI产品"], ["教育", "电商", "广告"], 18, 14),
"after": _cand("提示词工程师",
["提示词工程", "大模型应用开发", "Python", "数据分析"],
["LangChain", "RAG", "AI产品"], ["教育", "电商", "广告"], 18, 14, "active"),
"time": "2026-07-25 11:30:44"},
{"kind": "node_update", "node_id": "job_运维工程师(SRE)",
"operator": "李强(评审专家)",
"reason": "按 2026 年 JD 样本补全岗位级别标注。",
"before": {"level": None}, "after": {"level": "中级"},
"time": "2026-07-28 16:48:09"},
]
# ---------------------------------------------------------------- 报告样例(与 JD 演化信号相互印证)
REPORT_TREND = (
"新一代信息技术岗位能力趋势报告(样例)\n\n"
"一、总体趋势\n"
"2019-2026 年,后端岗位从 SSM/Servlet 体系加速转向 Spring Boot/Spring Cloud 微服务体系,"
"容器化(Docker/Kubernetes)已成为运维与后端岗位的通用要求。\n\n"
"二、AI 原生岗位崛起\n"
"2023 年起,大模型应用工程师、RAG工程师、提示词工程师等新岗位快速增长,"
"大模型应用开发、提示词工程、向量数据库成为增速最快的技能点。\n\n"
"三、传统技能退出\n"
"Struts、JSP、Svn 等传统技术栈在 2022 年后基本退出主流 JD。\n"
"四、AI 辅助编程普及\n"
"2024 年起,AI辅助编程(Copilot 类工具)开始作为加分项出现在后端岗位 JD 中。\n"
)
REPORT_TALENT_2026 = (
"新一代信息技术人才发展报告(2026)(节选·样例)\n\n"
"一、总体格局:能力图谱加速重构\n"
"2019-2026 年,信息技术岗位的能力要求经历了从“框架驱动”到“云原生驱动”再到“AI 原生驱动”"
"的三次跃迁。招聘 JD 数据显示,微服务、容器化已于 2022 年前后完成普及,成为后端与运维岗位的"
"基础要求;2024 年起,大模型相关能力以前所未有的速度进入各岗位的能力图谱。\n\n"
"二、AI 原生岗位爆发式增长\n"
"大模型应用工程师自 2023 年出现以来需求连年翻倍,2026 年新发岗位量已达 2023 年的十倍以上;"
"RAG工程师、提示词工程师自 2024 年起独立设岗。值得注意的是,提示词工程相关岗位需求从 2023 年"
"起爆发,企业对该能力的要求正从“会用”转向“体系化”:提示词模板库沉淀、输出质量评估、与业务"
"流程的编排结合成为高频要求。\n\n"
"三、AI 辅助编程渗透率快速上升\n"
"2024 年起,AI辅助编程(Copilot 类工具)开始以加分项形式进入后端、前端岗位 JD;到 2026 年,"
"约半数新发后端岗位 JD 提及 AI 辅助研发能力,“使用大模型辅助开发与代码审查”一类职责表述明显"
"增多。AI 工具链正从“个人效率工具”升级为“团队工程标配”。\n\n"
"四、前端:从框架之争到工程化与智能化\n"
"jQuery、AngularJS 相关要求在 2022 年后加速退场,Vue/React + TypeScript 成为绝对主流;构建"
"工具方面,Vite 已基本取代 Webpack 成为新项目标配。2024 年起,低代码平台与 AI 辅助生成进入"
"前端岗位核心要求,前端工程师的能力重心从“写页面”转向“搭体系”。\n\n"
"五、运维与分析岗位的智能化迁移\n"
"运维岗位沿“脚本手工 → Ansible 自动化 → DevOps/Kubernetes → AIOps”路径演进,2024 年起 AIOps"
"首次进入岗位加分项;数据分析岗位则完成了“Excel/SPSS 退场、SQL/Python 成标配”的换代,2024 年"
"起大模型增强分析(自然语言取数、报告自动生成)开始进入要求清单。\n\n"
"六、传统技术栈出清\n"
"Struts、JSP、Svn、WebLogic 等传统技术栈在 2022 年后基本退出主流 JD,仅存的少量需求集中于"
"存量系统维护岗位,且普遍标注“接受老系统维护经验”作为过渡安排。\n"
)
REPORT_DIGITAL_ECONOMY = (
"数字经济就业趋势观察(2026 年上半年)(节选·样例)\n\n"
"一、区域格局:新一线城市承接效应显著\n"
"2026 年上半年,信息技术岗位的区域分布持续多极化。北京、上海、深圳、杭州仍是岗位密度最高的"
"第一梯队,但成都、武汉、西安、苏州、长沙等新一线城市的岗位占比连续第三年上升,合计占比已"
"接近三成。其中成都以后端与游戏研发见长,武汉、西安依托高校资源在嵌入式与智能制造方向增速"
"领先,苏州、长沙则在工业互联网与物联网岗位上放量明显。\n\n"
"二、岗位结构:AI 岗位从“概念热”走向“用工实”\n"
"与 2023 年大模型岗位“重算法研究”不同,2026 年的需求主体已转向应用落地:大模型应用工程师、"
"RAG工程师合计新发岗位量超过传统算法工程师的六成,提示词工程能力则从独立岗位演变为产品、"
"运营、数据分析等多岗位的通用加分项。用人单位普遍要求候选人同时具备工程落地能力与业务理解"
"能力,单纯的“调参型”简历竞争力明显下降。\n\n"
"三、技能更替:老栈出清与新栈下沉同步发生\n"
"上半年数据显示,Struts、JSP、Svn 等传统技术栈在新增 JD 中已基本绝迹;与之相对,原本集中"
"于头部企业的 Kubernetes、CI/CD、可观测体系等云原生能力,正快速下沉至中小企业 JD。运维岗位"
"的 AIOps 要求、数据分析岗位的大模型增强分析要求,虽然仍以加分项形式出现,但提及率环比均"
"翻倍增长,预计 1-2 年内转为必备项。\n\n"
"四、薪酬观察:AI 应用岗溢价收窄但基数抬高\n"
"大模型应用工程师的薪酬中位数仍领先通用后端岗位约 40%,但溢价幅度较 2024 年高点收窄;同时,"
"掌握 AI 工具链的通用岗位(后端、前端、测试)薪酬基数整体抬升,具备“AI+工程”复合能力的候选"
"人在议价中优势明显。\n\n"
"五、趋势研判\n"
"预计下半年岗位能力图谱的演化将沿三条主线展开:一是 AI 辅助研发能力从加分项转为默认要求;"
"二是低代码与 AI 生成进一步压缩初级前端岗位需求,中高级工程化人才缺口扩大;三是新一线城市"
"与一线城市的技能要求趋于同构,区域间人才竞争加剧。\n"
)
def main() -> None:
data = ROOT / "data"
data.mkdir(parents=True, exist_ok=True)
# 1. 技能词表 + 行业词表 + 岗位-行业归属
lexicon = {
"skills": [{"name": n, "category": c, "aliases": al, "level": lv, "prereqs": pre}
for n, c, al, lv, pre in SKILLS],
"scenarios": SCENARIOS,
"industries": INDUSTRIES,
"jobs": [{"title": a["title"], "category": a["category"],
"industries": a["industries"], "expected_years": a["years"]}
for a in ARCHETYPES],
}
(data / "skills_lexicon.json").write_text(
json.dumps(lexicon, ensure_ascii=False, indent=1), encoding="utf-8")
# 2. 原始 JD(按年份分批次)
raw_by_year: dict[int, list[dict]] = {y: [] for y in range(2019, 2027)}
seq = 0
for a in ARCHETYPES:
for year, count in sorted(a["volumes"].items()):
for i in range(count):
seq += 1
# 月份年内均匀铺开:季度窗口计数只随剧本(时间轴/量级)变化
rec, _ = make_jd(a, year, f"J{seq:05d}", month=i * 12 // count + 1)
raw_by_year[year].append(rec)
# 3. 植入噪声(约 3%):一半混排尾注(清洗时剔除行),一半整篇广告(整条标记)
all_records = [r for y in raw_by_year.values() for r in y]
noise_jids: list[str] = []
mixed = rng.sample(all_records, k=10)
for rec in mixed:
rec["text"] = rec["text"] + "\n" + rng.choice(NOISE_TAILS)
noise_jids.append(rec["jid"])
for i in range(8):
full = NOISE_FULL[i % len(NOISE_FULL)]
seq += 1
jid = f"J{seq:05d}"
year = rng.randint(2020, 2026)
raw_by_year[year].append({
"jid": jid, "job_title": rng.choice(ARCHETYPES)["title"],
"company": rng.choice(COMPANY_PRE) + rng.choice(COMPANY_SUF),
"city": rng.choice(CITIES), "salary": "面议",
"industry": rng.choice(INDUSTRIES),
"publish_date": date(year, rng.randint(1, 12), rng.randint(1, 28)).isoformat(),
"source": rng.choice(SOURCES), "url": f"https://jobs.example.com/{jid}",
"text": full,
})
noise_jids.append(jid)
# 4. 植入近重复(约 8%):抄袭源避开噪声记录,副本与原文高度相似
dup_groups: list[list[str]] = []
clean_pool = [r for r in all_records if r["jid"] not in noise_jids]
dup_sources = rng.sample(clean_pool, k=int(len(all_records) * 0.08))
for src in dup_sources:
seq += 1
copy = make_dup_copy(src, f"J{seq:05d}")
year = min(2026, int(copy["publish_date"][:4]))
raw_by_year[year].append(copy)
dup_groups.append([src["jid"], copy["jid"]])
for year, rows in raw_by_year.items():
write_jsonl(data / "jd_raw" / f"batch_{year}.jsonl", rows)
(data / "jd_raw" / "_meta.json").write_text(json.dumps(
{"dup_groups": dup_groups, "noise_jids": noise_jids}, ensure_ascii=False, indent=1),
encoding="utf-8")
# 5. 测试集(与 raw 不同 jid 命名空间)+ 标准答案
testset, gold = [], {}
tseq = 0
per_arc = 8 # 18 岗位 × 8 = 144 条 >= 120
for a in ARCHETYPES:
years = sorted(a["volumes"])
for _ in range(per_arc):
tseq += 1
year = years[-1] if rng.random() < 0.6 else rng.choice(years)
rec, g = make_jd(a, year, f"T{tseq:05d}")
testset.append(rec)
gold[rec["jid"]] = g
write_jsonl(data / "testset" / "jd_testset.jsonl", testset)
(data / "testset" / "gold_answers.json").write_text(
json.dumps(gold, ensure_ascii=False, indent=1), encoding="utf-8")
# 6. 人岗匹配标注对(正例:技能覆盖当前必备;反例:技能体系错位)
unrelated = {
"后端开发": ["C", "嵌入式开发", "单片机", "RTOS", "STM32"],
"前端": ["C", "单片机", "Verilog", "FPGA", "驱动开发"],
"大数据": ["Verilog", "FPGA", "PCB设计", "单片机", "C"],
"AI算法": ["PCB设计", "Verilog", "FPGA", "Zigbee", "LoRa"],
"数据分析": ["Verilog", "FPGA", "驱动开发", "单片机", "C"],
"测试": ["Verilog", "FPGA", "PCB设计", "LoRa", "Zigbee"],
"运维": ["Verilog", "FPGA", "PCB设计", "传感器", "Zigbee"],
"嵌入式": ["Excel", "SPSS", "Axure", "竞品分析", "用户增长"],
"物联网": ["Excel", "SPSS", "Axure", "竞品分析", "用户增长"],
"云原生": ["Verilog", "FPGA", "PCB设计", "单片机", "传感器"],
"产品": ["Verilog", "FPGA", "驱动开发", "单片机", "C"],
}
# 既有岗位(2023 年前已存在)才进入正式图谱,匹配标注只覆盖这些岗位
known_arcs = [a for a in ARCHETYPES if min(a["volumes"]) < 2023]
match_gold = []
for a in known_arcs:
req, pref = skillset_for(a, 2025)
pos_skills = req[: max(3, len(req) - 1)] + pref[:1]
match_gold.append({
"job_title": a["title"], "skills": pos_skills,
"years": a["years"] + 2, "scenarios": a["scenarios"][:2],
"expected_match": True,
})
neg_scen = [s for s in SCENARIOS if s not in a["scenarios"]][:2]
match_gold.append({
"job_title": a["title"], "skills": unrelated.get(a["category"], ["Excel", "SPSS"]),
"years": 1, "scenarios": neg_scen, "expected_match": False,
})
# 部分覆盖正例(剧本三岗位:缺 1-2 项必备但总体达标)
by_title = {a["title"]: a for a in ARCHETYPES}
for title in ["前端工程师", "数据分析师", "运维工程师(SRE)"]:
a = by_title[title]
req, pref = skillset_for(a, 2025)
match_gold.append({
"job_title": a["title"], "skills": req[:-2] + pref[:2],
"years": a["years"] + 1, "scenarios": a["scenarios"][:2],
"expected_match": True,
})
# 新增简历衍生的标注对(前端完整 / 数据分析部分 / 传统栈错位)
match_gold.append({
"job_title": "前端工程师",
"skills": ["JavaScript", "TypeScript", "HTML", "CSS", "Vue", "React",
"Vite", "Webpack", "Node.js", "小程序开发", "低代码平台", "AI辅助编程"],
"years": 4, "scenarios": ["电商", "社交"], "expected_match": True,
})
match_gold.append({
"job_title": "数据分析师",
"skills": ["SQL", "Excel", "数据分析", "数据可视化", "Tableau", "Python",
"Power BI", "SPSS"],
"years": 2, "scenarios": ["零售", "电商"], "expected_match": True,
})
match_gold.append({
"job_title": "数据分析师",
"skills": ["Struts", "JSP", "Servlet", "Svn", "Tomcat", "jQuery", "WebLogic"],
"years": 8, "scenarios": ["政务", "安防"], "expected_match": False,
})
(data / "testset" / "match_gold.json").write_text(
json.dumps(match_gold, ensure_ascii=False, indent=1), encoding="utf-8")
# 7. 简历样例(完整 / 部分 / 错位,含虚构姓名手机邮箱以验证脱敏)+ 技能标准答案
resumes_dir = data / "resumes"
resumes_dir.mkdir(parents=True, exist_ok=True)
r1 = (
"姓名:张伟\n手机:13812345678\n邮箱:zhangwei@example.com\n"
"5年后端开发经验,先后负责交易系统与支付链路的建设。\n"
"核心技能:熟练掌握Java、Spring Boot、Spring Cloud、MySQL、Redis,"
"熟悉微服务与分布式系统设计,了解Docker、Kafka、Kubernetes与高并发优化。\n"
"项目经历:主导订单中心微服务化改造,基于Spring Cloud与Redis支撑高并发下单;"
"使用Kafka搭建异步消息管道,覆盖电商与金融两大业务场景。\n"
)
r2 = (
"姓名:李娜\n手机:13998765432\n邮箱:lina.dev@example.com\n"
"2年后端开发经验,参与过企业内部管理系统开发。\n"
"核心技能:熟悉Java、Spring Boot、MyBatis、MySQL,了解Redis与Linux常用命令,"
"日常使用Git协作。\n"
"项目经历:负责报表模块开发,使用Spring Boot与MySQL实现数据查询接口。\n"
)
r3 = (
"姓名:王强\n电话:13755556666\n邮箱:wangq@example.com\n"
"4年嵌入式开发经验,服务于智能制造行业。\n"
"核心技能:精通C、C++,熟悉嵌入式开发、单片机、RTOS,"
"掌握STM32与FreeRTOS,了解MQTT协议。\n"
"项目经历:负责工业网关固件开发,完成传感器数据采集与边缘上报。\n"
)
resumes = {
"resume_full.txt": (r1, ["Java", "Spring Boot", "Spring Cloud", "MySQL", "Redis",
"微服务", "分布式系统", "Docker", "Kafka", "Kubernetes", "高并发"]),
"resume_partial.txt": (r2, ["Java", "Spring Boot", "MyBatis", "MySQL", "Redis", "Linux", "Git"]),
"resume_mismatch.txt": (r3, ["C", "C++", "嵌入式开发", "单片机", "RTOS",
"STM32", "FreeRTOS", "MQTT", "传感器"]),
"resume_frontend_full.txt": (
RESUME_FRONTEND_FULL,
["JavaScript", "TypeScript", "HTML", "CSS", "Vue", "React",
"Vite", "Webpack", "Node.js", "小程序开发", "低代码平台", "AI辅助编程"]),
"resume_data_partial.txt": (
RESUME_DATA_PARTIAL,
["SQL", "Excel", "数据分析", "数据可视化", "Tableau", "Python", "Power BI", "SPSS"]),
"resume_llm_full.txt": (
RESUME_LLM_FULL,
["Python", "大模型应用开发", "提示词工程", "LangChain", "RAG",
"向量数据库", "模型微调", "NLP", "FastAPI"]),
"resume_legacy_mismatch.txt": (
RESUME_LEGACY_MISMATCH,
["Struts", "JSP", "Servlet", "Svn", "Tomcat", "jQuery", "WebLogic"]),
}
resume_gold = {}
for name, (text, skills) in resumes.items():
(resumes_dir / name).write_text(text, encoding="utf-8")
resume_gold[name] = {"skills": skills}
(resumes_dir / "gold.json").write_text(
json.dumps(resume_gold, ensure_ascii=False, indent=1), encoding="utf-8")
# 8. 行业趋势报告样例(3 份,内容与 JD 数据中的演化信号相互印证)
reports_dir = data / "reports"
reports_dir.mkdir(parents=True, exist_ok=True)
(reports_dir / "industry_trend_report.txt").write_text(REPORT_TREND, encoding="utf-8")
(reports_dir / "talent_report_2026.txt").write_text(REPORT_TALENT_2026, encoding="utf-8")
(reports_dir / "digital_economy_2026H1.txt").write_text(REPORT_DIGITAL_ECONOMY, encoding="utf-8")
# 9. 审核留痕种子记录(accept/modify/reject 混合 + 节点编辑,覆盖多名操作人)
review_dir = data / "review"
review_dir.mkdir(parents=True, exist_ok=True)
with open(review_dir / "audit.jsonl", "w", encoding="utf-8") as f:
for rec in AUDIT_SEED:
f.write(json.dumps(rec, ensure_ascii=False) + "\n")
n_raw = sum(len(v) for v in raw_by_year.values())
print(f"生成完成:技能词表 {len(SKILLS)} 项,行业 {len(INDUSTRIES)} 个,"
f"原始 JD {n_raw} 条({len(CITIES)} 城),测试集 {len(testset)} 条,"
f"匹配标注 {len(match_gold)} 对,简历 {len(resumes)} 份,报告 3 份,"
f"审核留痕种子 {len(AUDIT_SEED)} 条,"
f"抄袭簇 {len(dup_groups)} 组,噪声 {len(noise_jids)} 条")
if __name__ == "__main__":
main()