CareerNexus 职联:岗位能力图谱构建与动态演化分析平台(挑战杯 XH-202621)
- 全链路:多源JD接入/清洗交叉验证/结构化抽取(星火+离线双通道)/时序知识图谱/新岗位发现/演化分析/人岗匹配/学习路径 - WebUI 五视图:驾驶舱/图谱工作台/岗位演化/匹配(单人+批量)/学习路径 - 设置中心(config.json)/Token鉴权/SQLite状态库/语义向量通道(BGE-M3本地或联网API) - 71 个 pytest 用例;数据目录仅保留结构(.gitkeep),数据由 scripts/generate_dataset.py 复现
This commit is contained in:
+139
@@ -0,0 +1,139 @@
|
||||
"""CareerNexus 全链路数据模型(pydantic v2)。
|
||||
|
||||
覆盖:JD 原始记录、结构化抽取结果、岗位定义、图谱观察、
|
||||
变更事件、人岗匹配结果、简历画像与人机协同审核记录。
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import date
|
||||
from typing import Literal, Optional
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
|
||||
class JDRecord(BaseModel):
|
||||
"""一条招聘 JD 原始记录。source_id 由接入层分配(文件名#行号),不可变。"""
|
||||
|
||||
jid: str
|
||||
job_title: str
|
||||
company: str
|
||||
city: str = ""
|
||||
salary: str = ""
|
||||
industry: str = "" # 招聘平台标注的所属行业
|
||||
publish_date: date
|
||||
source: str = ""
|
||||
url: str = ""
|
||||
text: str
|
||||
source_id: str = "" # 形如 batch_2023.jsonl#17
|
||||
weight: float = 1.0 # 清洗阶段赋予的时间衰减权重
|
||||
is_duplicate: bool = False # 近重复(抄袭)降权标记
|
||||
dup_of: Optional[str] = None # 指向被保留的最早来源 jid
|
||||
is_noise: bool = False # 噪声(广告/无关条款)标记
|
||||
|
||||
|
||||
class ExtractionResult(BaseModel):
|
||||
"""从单条 JD 文本抽取出的结构化岗位定义。"""
|
||||
|
||||
jid: str = ""
|
||||
job_title: str = ""
|
||||
responsibilities: list[str] = Field(default_factory=list)
|
||||
required_skills: list[str] = Field(default_factory=list)
|
||||
preferred_skills: list[str] = Field(default_factory=list)
|
||||
scenarios: list[str] = Field(default_factory=list)
|
||||
evidence: dict[str, str] = Field(default_factory=dict) # 字段 -> 证据片段
|
||||
confidence: float = 0.0
|
||||
extractor: str = "offline"
|
||||
prompt_version: str = "offline-v1"
|
||||
|
||||
|
||||
class JobDefinition(BaseModel):
|
||||
"""聚合后的岗位定义(图谱中的 Job 节点属性)。"""
|
||||
|
||||
job_id: str
|
||||
title: str
|
||||
category: str = ""
|
||||
industries: list[str] = Field(default_factory=list) # 归属行业(1-2 个)
|
||||
required_skills: list[str] = Field(default_factory=list)
|
||||
preferred_skills: list[str] = Field(default_factory=list)
|
||||
responsibilities: list[str] = Field(default_factory=list)
|
||||
scenarios: list[str] = Field(default_factory=list)
|
||||
expected_years: int = 3
|
||||
status: Literal["active", "pending", "rejected"] = "active"
|
||||
source_count: int = 0 # 支撑 JD 数
|
||||
company_count: int = 0 # 独立企业数
|
||||
# 候选新岗位的支撑证据(新岗位发现时填写):支撑 JD 的 source_id 与出现季度窗口,
|
||||
# 审核入库时用于生成真实的 REQUIRES 区间、来源列表与演化事件。
|
||||
support_source_ids: list[str] = Field(default_factory=list)
|
||||
support_windows: list[str] = Field(default_factory=list)
|
||||
|
||||
|
||||
class GraphObservation(BaseModel):
|
||||
"""一次岗位-技能关系观察(带时间窗,追加而不覆盖)。"""
|
||||
|
||||
job_id: str
|
||||
skill: str
|
||||
importance: Literal["required", "preferred"]
|
||||
weight: float = 1.0
|
||||
window: str = "" # 季度窗口,如 2022Q1
|
||||
source_ids: list[str] = Field(default_factory=list)
|
||||
|
||||
|
||||
class ChangeEvent(BaseModel):
|
||||
"""岗位能力演化事件:新增 / 增强 / 减弱 / 退出。"""
|
||||
|
||||
event_id: str
|
||||
job_id: str
|
||||
skill: str
|
||||
change_type: Literal["新增", "增强", "减弱", "退出"]
|
||||
window: str
|
||||
prev_weight: float = 0.0
|
||||
curr_weight: float = 0.0
|
||||
source_ids: list[str] = Field(default_factory=list)
|
||||
description: str = ""
|
||||
created_at: str = ""
|
||||
|
||||
|
||||
class ResumeProfile(BaseModel):
|
||||
"""脱敏后的简历画像。"""
|
||||
|
||||
name: str = ""
|
||||
phone: str = ""
|
||||
email: str = ""
|
||||
years: float = 0.0
|
||||
skills: list[str] = Field(default_factory=list)
|
||||
scenarios: list[str] = Field(default_factory=list)
|
||||
raw_masked_text: str = ""
|
||||
# 结构化信息(规范简历模板用)
|
||||
gender: str = "" # 性别(不脱敏,人口统计学字段)
|
||||
education: str = "" # 最高学历(本科/硕士/博士…)
|
||||
address: str = "" # 家庭住址/现居地(脱敏到城市)
|
||||
photo_b64: str = "" # 证件照 base64(data URI,无照片为空)
|
||||
sections: list[dict] = Field(default_factory=list) # [{title, text}] 分节正文
|
||||
|
||||
|
||||
class MatchResult(BaseModel):
|
||||
"""人岗匹配结果:总分、四维分、命中/缺失/可迁移技能与学习路径。"""
|
||||
|
||||
job_id: str
|
||||
job_title: str = ""
|
||||
total_score: float = 0.0
|
||||
dimension_scores: dict[str, float] = Field(default_factory=dict)
|
||||
matched_required: list[str] = Field(default_factory=list)
|
||||
missing_required: list[str] = Field(default_factory=list)
|
||||
matched_preferred: list[str] = Field(default_factory=list)
|
||||
missing_preferred: list[str] = Field(default_factory=list)
|
||||
transferable_skills: list[str] = Field(default_factory=list)
|
||||
learning_path: list[dict] = Field(default_factory=list)
|
||||
is_match: bool = False
|
||||
|
||||
|
||||
class ReviewRecord(BaseModel):
|
||||
"""人机协同审核留痕。"""
|
||||
|
||||
candidate_id: str
|
||||
action: Literal["accept", "modify", "reject"]
|
||||
operator: str
|
||||
reason: str = ""
|
||||
before: dict = Field(default_factory=dict)
|
||||
after: dict = Field(default_factory=dict)
|
||||
time: str = ""
|
||||
Reference in New Issue
Block a user