diff --git a/app/ai/extract/prompt.py b/app/ai/extract/prompt.py index b13adf8..5accb18 100644 --- a/app/ai/extract/prompt.py +++ b/app/ai/extract/prompt.py @@ -30,6 +30,7 @@ EXTRACT_SYSTEM_PROMPT = """你是招聘公告信息提取专家。用户会给 "tags": ["六险一金", "不限专业", "带薪年假", "导师带教"], "cities": ["北京市"], "categories": ["后端开发", "人工智能"], + "industries": ["互联网", "人工智能"], "educations": ["本科", "硕士"] } ``` @@ -76,6 +77,9 @@ EXTRACT_SYSTEM_PROMPT = """你是招聘公告信息提取专家。用户会给 - categories:岗位分类数组。**只能从文末「岗位分类数据」列表中原样选取**,不得改写、合并、简化或自造分类名。 根据 recruit_position 中的岗位判断,可多选,最多 5 个,按相关度从高到低排列。 找不到精确匹配时,选该岗位所属领域下的「其他XX职位」;连所属领域都无法判断时填 [] +- industries:行业分类数组。**只能从文末「行业分类数据」列表中原样选取**,不得改写、合并、简化或自造行业名。 + 根据 company_name、company_intro 中体现的公司主营业务判断,可多选,最多 3 个,按相关度从高到低排列。 + 找不到精确匹配时,选同一领域下最接近的行业(如该领域有「其他XX」则用它);连所属领域都无法判断时填「其他行业」 - educations:学历要求数组,如「大专」「本科」「硕士」「博士」 - tags:其他关键标签数组,如「竞争力薪酬」「六险一金」「可远程」「不限专业」。 提取 3-6 个,从公告的薪资福利、工作方式、专业/学历门槛、培养机制、流程特点、地点等维度概括, @@ -94,8 +98,9 @@ EXTRACT_SYSTEM_PROMPT = """你是招聘公告信息提取专家。用户会给 4. apply_end_time 和 apply_end_desc 可以同时有值,也可以只有一个。 5. 数组元素去重,保持公告中出现的顺序,单个元素不超过 64 字。 6. 一份公告涉及多家公司时,以主体招聘方为准。 -7. batches 和 categories 都是封闭枚举:batches 必须是字段说明中列出的 11 个值之一, - categories 必须与文末「岗位分类数据」列表中的某一项完全一致(含标点「/」)。 +7. batches、categories 和 industries 都是封闭枚举:batches 必须是字段说明中列出的 11 个值之一, + categories 必须与文末「岗位分类数据」列表中的某一项完全一致(含标点「/」), + industries 必须与文末「行业分类数据」列表中的某一项完全一致(含标点「/」「(020)」等)。 出现枚举之外的值视为错误输出。 8. 直接输出 JSON,不要输出任何解释文字。 @@ -123,4 +128,28 @@ categories 的取值范围如下(按领域分组,冒号后的名称才是合 - 金融:银行、证券/基金/期货、中后台、投融资、保险、其他金融职位 - 咨询翻译:咨询/调研、翻译、其他咨询类职位 - 其他:能源/地质、农/林/牧/渔、高级管理职位、其他职位类别 + + +## 行业分类数据 + +industries 的取值范围如下(按领域分组,冒号后的名称才是合法取值): + +- 互联网/IT:互联网、生活服务(020)、游戏、云计算、大数据、新零售、电子商务、企业服务、社交网络与媒体、在线教育、广告营销、信息安全、计算机软件、医疗健康、人工智能、计算机服务、物联网 +- 电子硬件通信:半导体/芯片、智能硬件/消费电子、电子/硬件开发、运营商/增值服务、通信/网络设备、计算机硬件、电子/半导体/集成电路 +- 生活服务:餐饮、酒店/民宿、保健/养生、婚庆/摄影、美容/美发、美容、美发、休闲/娱乐、家政服务、宠物服务、运动/健身、旅游/景区、回收/维修、其他生活服务 +- 消费品零售:批发/零售、服装/纺织、日化、进出口贸易、家具/家居、家具/家电/家居、家用电器、珠宝/首饰、食品/饮料/烟酒、其他消费品 +- 房地产建筑:房地产开发经营、房地产中介/租赁、物业管理、房屋建筑工程、土木工程、工程施工、建筑设计、建筑材料、建筑工程咨询服务、机电工程、装修装饰、土地与公共设施管理 +- 教育培训:培训/辅导机构、学校/学历教育、职业培训、学前教育、学术/科研 +- 文娱传媒:文化艺术/娱乐、广播/影视、新闻/出版、广告/公关/会展、体育 +- 制造业:通用设备、专用设备、自动化设备、电气机械/器材、机械设备/机电/重工、仪器仪表、仪器仪表/工业自动化、计算机/通信/其他电子设备、铁路/船舶/航空/航天制造、金属制品、非金属矿物制品、橡胶/塑料制品、化学原料/化学制品、新材料、原材料及加工/模具、印刷/包装/造纸、其他制造业 +- 专业服务:咨询、法律、财务/审计/税务、人力资源服务、检测/认证/知识产权、翻译、其他专业服务 +- 医疗医药:医疗服务、医美服务、生物/制药、医疗器械、医药批发零售、医疗研发外包、IVD +- 汽车:汽车研发/制造、新能源汽车、汽车零部件、汽车智能网联、汽车后市场、4S店/后市场、汽车经销商、摩托车/自行车制造 +- 物流运输:物流/仓储、交通/运输、公路物流、跨境物流、快递、即时配送、同城货运、客运服务、港口/铁路/公路/机场、装卸搬运和仓储业 +- 能源环保:新能源、光伏、风电、储能、动力电池、其他新能源、电力/热力/燃气/水利、石油/石化、化工、采掘/冶炼、矿产/地质、环保 +- 金融:银行、证券/期货、基金、保险、投资/融资、财富管理、互联网金融、信托租赁/拍卖/典当/担保、其他金融业 +- 其他:农/林/牧/渔、政府/公共事业、非盈利机构、其他行业 + + + """ diff --git a/app/models/recruit_announcement_industry.py b/app/models/recruit_announcement_industry.py new file mode 100644 index 0000000..f000cb4 --- /dev/null +++ b/app/models/recruit_announcement_industry.py @@ -0,0 +1,19 @@ +"""MySQL: bg_recruit_announcement_industry 招聘公告-行业关联表模型""" + +from datetime import datetime + +from sqlalchemy import BigInteger, DateTime, String +from sqlalchemy.orm import Mapped, mapped_column + +from app.core.database import MysqlBase + + +class RecruitAnnouncementIndustry(MysqlBase): + """招聘公告-行业关联表""" + + __tablename__ = "bg_recruit_announcement_industry" + + id: Mapped[int] = mapped_column(BigInteger, primary_key=True, comment="主键ID(雪花)") + announcement_id: Mapped[int] = mapped_column(BigInteger, nullable=False, comment="公告id") + industry_name: Mapped[str] = mapped_column(String(64), nullable=False, comment="行业分类值,取自固定分类表,如互联网/人工智能/半导体/芯片") + create_time: Mapped[datetime] = mapped_column(DateTime, nullable=False, comment="创建时间") diff --git a/app/service/recruit_announcement_service.py b/app/service/recruit_announcement_service.py index 200547b..8c6fe31 100644 --- a/app/service/recruit_announcement_service.py +++ b/app/service/recruit_announcement_service.py @@ -15,6 +15,7 @@ from app.models.recruit_announcement_batch import RecruitAnnouncementBatch from app.models.recruit_announcement_category import RecruitAnnouncementCategory from app.models.recruit_announcement_city import RecruitAnnouncementCity from app.models.recruit_announcement_education import RecruitAnnouncementEducation +from app.models.recruit_announcement_industry import RecruitAnnouncementIndustry from app.models.recruit_announcement_tag import RecruitAnnouncementTag from app.models.recruit_announcement_year import RecruitAnnouncementYear from app.service.company_service import find_or_create_company @@ -42,7 +43,7 @@ def _truncate(value: object, limit: int) -> str | None: def _save_announcement(announcement_id: int, company_id: int, url: str, data: dict) -> None: - """保存公告主表和六张关联表,单事务提交。""" + """保存公告主表和七张关联表,单事务提交。""" now = datetime.now() with MysqlSession() as session: @@ -130,6 +131,17 @@ def _save_announcement(announcement_id: int, company_id: int, url: str, data: di ) ) + # 行业 + for industry in data.get("industries") or []: + session.execute( + insert(RecruitAnnouncementIndustry).values( + id=next_id(), + announcement_id=announcement_id, + industry_name=str(industry)[:64], + create_time=now, + ) + ) + # 学历要求 for edu in data.get("educations") or []: session.execute( diff --git a/doc/recruit_announcement.sql b/doc/recruit_announcement.sql index 086e194..ecb61dd 100644 --- a/doc/recruit_announcement.sql +++ b/doc/recruit_announcement.sql @@ -1,7 +1,7 @@ -- ============================================================ -- 招聘公告数据表设计 -- 说明:分析对象为「招聘公告」,多值属性(招聘届数、批次、标签组、 --- 热招城市、岗位大类、学历要求)直接拆关联表存原始值, +-- 热招城市、岗位大类、行业、学历要求)直接拆关联表存原始值, -- 不引入任何字典表,避免归一化对公告解析结果的限制。 -- ============================================================ @@ -114,6 +114,20 @@ CREATE TABLE `bg_recruit_announcement_category` ( ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='招聘公告-岗位大类关联表'; +-- ============================================================ +-- 行业关联表 +-- ============================================================ +CREATE TABLE `bg_recruit_announcement_industry` ( + `id` BIGINT NOT NULL COMMENT '主键ID(雪花)', + `announcement_id` BIGINT NOT NULL COMMENT '公告id', + `industry_name` VARCHAR(64) NOT NULL COMMENT '行业分类值,取自固定分类表,如互联网/人工智能/半导体/芯片', + `create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + PRIMARY KEY (`id`), + KEY `idx_announcement_id` (`announcement_id`), + KEY `idx_industry_name` (`industry_name`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='招聘公告-行业关联表'; + + -- ============================================================ -- 学历要求关联表 -- ============================================================