"""自备数据集生成器(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", "ReactJS"], "L2", ["JavaScript"]), ("Angular", "前端", ["AngularJS"], "L2", ["TypeScript"]), ("jQuery", "前端", [], "L1", ["JavaScript"]), ("Webpack", "前端", [], "L2", ["JavaScript"]), ("Vite", "前端", [], "L2", ["JavaScript"]), ("Node.js", "前端", ["Node", "NodeJS"], "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算法", ["Transformers", "Transformer"], "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应用开发", "大模型应用", "大语言模型应用", "LLM", "大语言模型", "大模型", "LLM推理", "LLM评测", "大模型推理", "大语言模型应用开发"], "L3", ["Python", "NLP"]), ("RAG", "AI算法", ["检索增强生成"], "L3", ["大模型应用开发", "向量数据库"]), ("提示词工程", "AI算法", ["Prompt工程", "Prompt Engineering", "提示词设计"], "L2", ["大模型应用开发"]), ("智能体开发", "AI算法", ["Agent开发", "多智能体", "Multi-Agent", "智能体", "Agent", "AI Agent"], "L3", ["大模型应用开发"]), ("向量数据库", "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", ["数据分析"]), # 机器人与智能系统(岗位覆盖扩展) ("ROS", "AI算法", ["机器人操作系统"], "L2", ["C++", "Linux"]), ("SLAM", "AI算法", ["同步定位与建图"], "L3", ["计算机视觉"]), ("路径规划", "AI算法", [], "L3", ["机器学习"]), # 数据治理 ("数据治理", "大数据", [], "L2", ["SQL"]), ("数据脱敏", "大数据", ["数据遮蔽"], "L2", ["SQL"]), ("元数据管理", "大数据", ["元数据"], "L2", ["数据治理"]), ("数据血缘", "大数据", [], "L3", ["元数据管理"]), ("湖仓一体", "大数据", ["实时湖仓"], "L3", ["Hive"]), # 边缘计算 ("边缘推理", "物联网", ["边缘推理框架"], "L3", ["边缘计算", "深度学习"]), ("TensorRT", "AI算法", [], "L3", ["深度学习"]), ("KubeEdge", "云原生", [], "L3", ["Kubernetes", "边缘计算"]), # 安全与隐私计算 ("零信任", "安全", ["零信任架构"], "L3", []), ("入侵检测", "安全", [], "L2", ["Linux"]), ("等保合规", "安全", [], "L2", []), ("联邦学习", "AI算法", [], "L3", ["机器学习"]), ("多方安全计算", "安全", ["MPC"], "L3", []), ("同态加密", "安全", [], "L3", []), ("差分隐私", "安全", [], "L3", ["机器学习"]), ] SCENARIOS = ["电商", "金融", "物流", "社交", "教育", "医疗", "政务", "游戏", "出行", "智能制造", "短视频", "广告", "供应链", "零售", "安防"] # 行业词表(岗位归属 1-2 个行业,图谱中构建 Industry 节点) INDUSTRIES = ["互联网/软件", "人工智能", "金融科技", "智能制造", "物联网", "智慧城市", "智慧医疗"] # ---------------------------------------------------------------- 岗位原型 def arc(title, category, years, salary, scenarios, industries, duty_tmpls, duty_objs, timeline, volumes, test_n=8): 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, test_n=test_n) 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}), # —— 岗位覆盖扩展(8 个既有岗位族,2019 年前已存在,支撑赛题领域覆盖) —— # 大数据开发:2019-2021 Hadoop 离线系 → 2022+ Flink 实时/湖仓一体(演化信号) arc("大数据开发工程师", "大数据", 3, "16K-32K", ["电商", "金融", "短视频"], ["互联网/软件", "金融科技"], ["负责{o}的离线计算任务开发", "搭建{o}的实时计算链路", "参与{o}的数据模型设计", "优化{o}的任务性能与资源消耗", "维护{o}的调度依赖与数据质量"], ["离线数仓", "实时数仓", "用户行为日志", "流量数据", "交易数据", "数据集市"], [(2019, 2021, ["SQL", "Hadoop", "Hive", "Spark", "HDFS"], ["Sqoop", "HBase", "Scala"]), (2022, 2026, ["SQL", "Spark", "Flink", "Kafka", "Hive"], ["ClickHouse", "Doris", "湖仓一体"])], {2019: 4, 2020: 4, 2021: 4, 2022: 5, 2023: 5, 2024: 6, 2025: 6, 2026: 6}, test_n=4), # 机器学习工程师:2023+ 加分项出现"模型微调/大模型应用开发"(演化信号) arc("机器学习工程师", "AI算法", 3, "18K-35K", ["金融", "电商", "广告"], ["人工智能"], ["负责{o}的特征工程与模型训练", "参与{o}的离线评估与线上实验", "优化{o}的推理性能与资源占用", "建设{o}的样本与特征流水线", "跟进{o}的算法迭代与复盘"], ["风控模型", "搜索排序", "召回策略", "销量预测", "异常检测", "用户分层"], [(2019, 2022, ["Python", "机器学习", "Scikit-learn", "SQL", "XGBoost"], ["LightGBM", "TensorFlow", "Spark"]), (2023, 2026, ["Python", "机器学习", "深度学习", "PyTorch", "XGBoost"], ["模型微调", "大模型应用开发", "LightGBM"])], {2019: 4, 2020: 4, 2021: 4, 2022: 5, 2023: 5, 2024: 6, 2025: 6, 2026: 6}, test_n=4), arc("智能机器人算法工程师", "AI算法", 3, "20K-40K", ["智能制造", "物流", "出行"], ["人工智能", "智能制造"], ["负责{o}的算法研发与调优", "参与{o}的仿真验证与实机部署", "优化{o}的实时性与鲁棒性", "建设{o}的数据闭环与评测体系", "跟进{o}的前沿方案并落地"], ["SLAM 建图", "定位导航", "运动规划", "多传感器融合", "机械臂控制", "避障策略"], [(2019, 2026, ["C++", "Python", "ROS", "SLAM", "路径规划"], ["深度学习", "强化学习", "OpenCV"])], {2019: 4, 2020: 4, 2021: 4, 2022: 5, 2023: 5, 2024: 6, 2025: 6, 2026: 6}, test_n=4), arc("数据治理工程师", "大数据", 3, "15K-30K", ["金融", "政务", "医疗"], ["金融科技", "互联网/软件"], ["负责{o}的标准制定与落地", "建设{o}的元数据与血缘体系", "推进{o}的质量监控与整改", "制定{o}的分级分类与脱敏策略", "组织{o}的盘点与确权工作"], ["数据资产", "主数据", "指标口径", "敏感数据", "数据目录", "质量规则"], [(2019, 2026, ["SQL", "数据治理", "元数据管理", "数据脱敏", "Python"], ["数据血缘", "Hive", "Spark"])], {2019: 4, 2020: 4, 2021: 4, 2022: 5, 2023: 5, 2024: 6, 2025: 6, 2026: 6}, test_n=4), arc("边缘计算工程师", "物联网", 3, "16K-30K", ["智能制造", "安防", "物流"], ["物联网", "智能制造"], ["负责{o}的部署与调优", "参与{o}的模型压缩与推理加速", "建设{o}的云边协同链路", "优化{o}的资源占用与稳定性", "编写{o}的技术文档"], ["边缘网关", "边缘节点", "端侧推理", "视频分析", "设备接入", "边云协同"], [(2019, 2021, ["C++", "Python", "Linux", "MQTT", "嵌入式开发"], ["Docker", "边缘计算", "OpenCV"]), (2022, 2026, ["Python", "边缘计算", "Docker", "Linux", "MQTT"], ["边缘推理", "TensorRT", "KubeEdge"])], {2019: 4, 2020: 4, 2021: 4, 2022: 5, 2023: 5, 2024: 6, 2025: 6, 2026: 6}, test_n=4), arc("物联网安全工程师", "物联网", 3, "16K-32K", ["智能制造", "安防", "政务"], ["物联网", "智慧城市"], ["负责{o}的安全评估与加固", "建设{o}的入侵检测与响应体系", "参与{o}的固件安全审计", "制定{o}的接入认证策略", "跟踪{o}的漏洞情报与处置"], ["设备接入", "设备网络", "边缘网关", "固件", "通信协议", "密钥体系"], [(2019, 2026, ["Linux", "Python", "入侵检测", "零信任", "MQTT"], ["等保合规", "嵌入式开发", "云计算"])], {2019: 4, 2020: 4, 2021: 4, 2022: 5, 2023: 5, 2024: 6, 2025: 6, 2026: 6}, test_n=4), arc("智能系统架构师", "云原生", 5, "30K-60K·14薪", ["金融", "政务", "智能制造"], ["互联网/软件", "人工智能"], ["负责{o}的整体架构设计", "主导{o}的技术选型与评审", "制定{o}的容量与容灾方案", "推动{o}的架构演进与落地", "沉淀{o}的架构规范与最佳实践"], ["智能平台", "业务中台", "云边端协同", "高可用体系", "多云架构", "技术路线"], [(2019, 2021, ["分布式系统", "微服务", "云计算", "高并发", "Linux"], ["Docker", "Kubernetes", "Service Mesh"]), (2022, 2026, ["分布式系统", "微服务", "Kubernetes", "云计算", "高并发"], ["Service Mesh", "边缘计算", "物联网平台"])], {2019: 4, 2020: 4, 2021: 4, 2022: 5, 2023: 5, 2024: 6, 2025: 6, 2026: 6}, test_n=4), arc("隐私计算工程师", "AI算法", 4, "25K-45K", ["金融", "政务", "医疗"], ["人工智能", "金融科技"], ["负责{o}的方案设计与实现", "参与{o}的性能优化与工程化", "建设{o}的协同计算链路", "评估{o}的安全性与合规性", "跟进{o}的最新研究成果"], ["联邦建模", "多方联合统计", "安全求交", "数据协作", "密文计算", "隐私保护"], [(2019, 2026, ["Python", "机器学习", "联邦学习", "同态加密", "多方安全计算"], ["差分隐私", "模型微调", "Spark"])], {2019: 4, 2020: 4, 2021: 4, 2022: 5, 2023: 5, 2024: 6, 2025: 6, 2026: 6}, test_n=4), ] COMPANY_PRE = ["星澜", "云启", "数联", "智汇", "蓝湾", "极光", "恒宇", "锐思", "博远", "辰安", "飞鱼", "墨白", "青藤", "远望", "砺石", "潮汐", "峰行", "微光", "若谷", "启航"] COMPANY_SUF = ["科技", "网络", "信息", "数据", "智能", "软件", "互联", "数字"] # ---------------------------------------------------------------- 近期演化信号(2024–2026Q3) # 评审反馈修复:此前仅 6 个岗位有深度演化剧本,其余岗位 2023Q1 后事件空档、 # 且 2026Q4 属未来窗口。这里为每个既有岗位补 3-6 个轻量近期信号(贴合"AI 渗透" # 真实趋势:2024+ 多数岗位出现 AI 辅助/大模型加分项,2025+ 部分技能减弱/退出): # add_pref: [(起始年, 技能)] 该年起作为加分项写入 JD(触发"新增"事件) # fade: (起始年, 技能) 该年起从 JD 技能清单消失(触发"退出"事件) # weaken: (起始年, 技能, 保留概率) 高量级岗位该年起提及率下降(触发"减弱"事件) RECENT_SIGNALS = { # —— 2024 年时间轴已换代的岗位:只补 2025/2026 信号 —— "Java开发工程师": {"add_pref": [(2025, "RAG")], "weaken": (2026, "MySQL", 0.4)}, "Python开发工程师": {"add_pref": [(2025, "向量数据库")], "weaken": (2026, "Redis", 0.4)}, "前端工程师": {"add_pref": [(2025, "大模型应用开发")], "fade": (2026, "微前端")}, "算法工程师": {"add_pref": [(2025, "RAG")], "fade": (2026, "强化学习")}, "数据分析师": {"add_pref": [(2025, "提示词工程")], "weaken": (2026, "Excel", 0.4)}, "运维工程师(SRE)": {"add_pref": [(2025, "AI辅助编程")], "weaken": (2026, "Docker", 0.4)}, "NLP工程师": {"add_pref": [(2025, "AI辅助编程")], "fade": (2026, "LangChain")}, "CV工程师": {"add_pref": [(2025, "AI辅助编程")], "fade": (2026, "模型微调")}, # —— 其余岗位:2024 起补 AI 加分项 + 2026 技能退出 —— "数据工程师": {"add_pref": [(2024, "大模型应用开发"), (2025, "AI辅助编程")], "weaken": (2026, "Spark", 0.4)}, "测试开发工程师": {"add_pref": [(2024, "AI辅助编程"), (2025, "大模型应用开发")], "weaken": (2026, "性能测试", 0.4)}, "嵌入式工程师": {"add_pref": [(2024, "AI辅助编程"), (2025, "边缘推理")], "fade": (2026, "STM32")}, "物联网工程师": {"add_pref": [(2024, "AI辅助编程"), (2025, "大模型应用开发")], "fade": (2026, "LoRa")}, "云原生工程师": {"add_pref": [(2024, "AI辅助编程"), (2025, "大模型应用开发")], "fade": (2026, "Service Mesh")}, "AI产品经理": {"add_pref": [(2024, "AI辅助编程"), (2025, "RAG")], "fade": (2026, "用户增长")}, "Go开发工程师": {"add_pref": [(2024, "AI辅助编程"), (2025, "大模型应用开发")], "fade": (2026, "Kafka")}, "大数据开发工程师": {"add_pref": [(2024, "大模型应用开发"), (2025, "AI辅助编程")], "fade": (2026, "Hive")}, "机器学习工程师": {"add_pref": [(2024, "AI辅助编程"), (2025, "RAG")], "fade": (2026, "XGBoost")}, "智能机器人算法工程师": {"add_pref": [(2024, "大模型应用开发"), (2025, "AI辅助编程")], "fade": (2026, "OpenCV")}, "数据治理工程师": {"add_pref": [(2024, "大模型应用开发"), (2025, "AI辅助编程")], "fade": (2026, "Hive")}, "边缘计算工程师": {"add_pref": [(2024, "AI辅助编程"), (2025, "大模型应用开发")], "fade": (2026, "KubeEdge")}, "物联网安全工程师": {"add_pref": [(2024, "大模型应用开发"), (2025, "AI辅助编程")], "fade": (2026, "嵌入式开发")}, "智能系统架构师": {"add_pref": [(2024, "大模型应用开发"), (2025, "AI辅助编程")], "fade": (2026, "Service Mesh")}, "隐私计算工程师": {"add_pref": [(2024, "大模型应用开发"), (2025, "AI辅助编程")], "fade": (2026, "Spark")}, } # 数据收敛到当前季度:今天是 2026-08(2026Q3),2026 年 JD 只落在 1-9 月, # 不生成 2026Q4 等未来窗口(含近重复副本与噪声记录的日期上限)。 CURRENT_YEAR_MAX_MONTH = 9 def apply_recent_signals(a: dict, year: int, req: list[str], pref: list[str], ) -> tuple[list[str], list[str]]: """按 RECENT_SIGNALS 对当年技能清单施加近期演化信号(先定结构再渲染,gold 自动一致)。""" sig = RECENT_SIGNALS.get(a["title"]) if not sig: return req, pref for y0, s in sig.get("add_pref", ()): if year >= y0 and s not in req and s not in pref: pref.append(s) fade = sig.get("fade") if fade and year >= fade[0]: req = [x for x in req if x != fade[1]] pref = [x for x in pref if x != fade[1]] wk = sig.get("weaken") if wk and year >= wk[0] and rng.random() > wk[2]: req = [x for x in req if x != wk[1]] pref = [x for x in pref if x != wk[1]] return req, pref # 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])] req, pref = apply_recent_signals(a, year, req, pref) 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) # 2026 年只取 1-9 月:数据收敛到当前季度 2026Q3,不出现未来窗口 month = month or rng.randint(1, CURRENT_YEAR_MAX_MONTH if year >= 2026 else 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, CURRENT_YEAR_MAX_MONTH, 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", resp: list[str] | None = None) -> dict: """构造一条待审核候选的快照(审核留痕种子用)。""" return {"job_id": f"cand_{title}", "title": title, "category": "新岗位候选", "required_skills": req, "preferred_skills": pref, "responsibilities": list(resp or []), "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, resp=["负责智能助手/企业知识库等大模型应用的开发与落地", "设计提示词与流程编排,建设应用评测体系", "优化推理成本与延迟,跟进生态工具"]), "after": _cand("大模型应用工程师", ["提示词工程", "Python", "LangChain", "大模型应用开发", "NLP"], ["模型微调", "向量数据库", "RAG"], ["教育", "医疗", "金融"], 42, 38, "active", resp=["负责智能助手/企业知识库等大模型应用的开发与落地", "设计提示词与流程编排,建设应用评测体系", "优化推理成本与延迟,跟进生态工具"]), "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, resp=["负责检索链路搭建与召回重排优化", "建设知识库加工流水线,评估问答质量"]), "after": _cand("RAG工程师", ["Python", "RAG", "向量数据库", "大模型应用开发", "LangChain", "Elasticsearch"], ["模型微调", "知识图谱"], ["金融", "政务", "教育"], 28, 22, "active", resp=["负责检索链路搭建与召回重排优化", "建设知识库加工流水线,评估问答质量"]), "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, resp=["负责提示词设计与模板库沉淀", "评估输出质量,编写最佳实践文档"]), "after": _cand("提示词工程师", ["提示词工程", "大模型应用开发", "Python", "数据分析"], ["LangChain", "RAG", "AI产品"], ["教育", "电商", "广告"], 18, 14, "active", resp=["负责提示词设计与模板库沉淀", "评估输出质量,编写最佳实践文档"]), "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 # 月份年内均匀铺开:季度窗口计数只随剧本(时间轴/量级)变化; # 2026 年收敛到 1-9 月(当前季度 2026Q3,不生成未来窗口) span = CURRENT_YEAR_MAX_MONTH if year >= 2026 else 12 rec, _ = make_jd(a, year, f"J{seq:05d}", month=i * span // 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) max_month = CURRENT_YEAR_MAX_MONTH if year >= 2026 else 12 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, max_month), 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 for a in ARCHETYPES: per_arc = a["test_n"] # 原 18 岗位 × 8 + 扩展 8 岗位 × 4 = 176 条 >= 120 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()