diff --git a/config/hr_sources.json b/config/hr_sources.json new file mode 100644 index 00000000000..85a8aa01f78 --- /dev/null +++ b/config/hr_sources.json @@ -0,0 +1,20 @@ +{ + "version": 1, + "name": "HR × AI 资讯台", + "timezone": "Asia/Shanghai", + "daily_pick_limit": 12, + "categories": [ + "政策与劳动合规", + "AI 招聘与招聘工具", + "组织与人才管理", + "学习发展与技能转型", + "HR 产品与数字化", + "案例、报告与趋势" + ], + "priority_regions": [ + "全国", + "上海", + "北京" + ], + "sources": [] +} \ No newline at end of file diff --git a/data/hr-radar.json b/data/hr-radar.json new file mode 100644 index 00000000000..a245c9a244a --- /dev/null +++ b/data/hr-radar.json @@ -0,0 +1,194 @@ +{ + "generated_at": "2026-07-19T16:11:48.313477+08:00", + "name": "HR × AI 资讯台", + "total_count": 7, + "categories": [ + "政策与劳动合规", + "AI 招聘与招聘工具", + "组织与人才管理", + "学习发展与技能转型", + "HR 产品与数字化", + "案例、报告与趋势" + ], + "items_by_category": { + "政策与劳动合规": [], + "AI 招聘与招聘工具": [], + "组织与人才管理": [ + { + "title": "Remote work isn’t always a ‘reasonable’ accommodation: 4 tips for employers", + "url": "https://www.hrdive.com/news/remote-work-isnt-always-a-reasonable-accommodation-4-tips-for-employers/825542/", + "published_at": "2026-07-17T15:55:00+00:00", + "source_id": "hr_dive", + "source_name": "HR Dive", + "source_region": "全球", + "source_level": "行业媒体", + "is_ai_hr": false, + "category": "组织与人才管理", + "id": "94f58f5ed83b" + }, + { + "title": "How AI ‘workslop’ is undermining your organization’s performance", + "url": "https://www.hrdive.com/news/how-ai-workslop-is-undermining-your-organizations-performance/825517/", + "published_at": "2026-07-17T14:35:00+00:00", + "source_id": "hr_dive", + "source_name": "HR Dive", + "source_region": "全球", + "source_level": "行业媒体", + "is_ai_hr": true, + "category": "组织与人才管理", + "id": "61c5e5abb7a9" + } + ], + "学习发展与技能转型": [ + { + "title": "AI may conceal growing ‘learning debt’ for fast-changing roles", + "url": "https://www.hrdive.com/news/ai-may-conceal-growing-learning-debt-for-fast-changing-roles/825396/", + "published_at": "2026-07-16T14:46:00+00:00", + "source_id": "hr_dive", + "source_name": "HR Dive", + "source_region": "全球", + "source_level": "行业媒体", + "is_ai_hr": true, + "category": "学习发展与技能转型", + "id": "94cfcdff3a70" + } + ], + "HR 产品与数字化": [], + "案例、报告与趋势": [ + { + "title": "Nespresso must face African American’s race discrimination claim, court rules", + "url": "https://www.hrdive.com/news/nespresso-must-face-african-americans-race-discrimination-claim-court-rul/825536/", + "published_at": "2026-07-17T15:55:00+00:00", + "source_id": "hr_dive", + "source_name": "HR Dive", + "source_region": "全球", + "source_level": "行业媒体", + "is_ai_hr": false, + "category": "案例、报告与趋势", + "id": "fdcaa8dd76ca" + }, + { + "title": "Secondhand harassment supports hostile work environment claim, 5th Circuit holds", + "url": "https://www.hrdive.com/news/secondhand-harassment-supports-hostile-work-environment-claim-5th-circuit/825514/", + "published_at": "2026-07-17T15:55:00+00:00", + "source_id": "hr_dive", + "source_name": "HR Dive", + "source_region": "全球", + "source_level": "行业媒体", + "is_ai_hr": false, + "category": "案例、报告与趋势", + "id": "fcbccc5e4d6b" + }, + { + "title": "Employers may soon find it harder to retain workers", + "url": "https://www.hrdive.com/news/employers-may-soon-find-it-harder-to-retain-workers/825505/", + "published_at": "2026-07-17T14:35:00+00:00", + "source_id": "hr_dive", + "source_name": "HR Dive", + "source_region": "全球", + "source_level": "行业媒体", + "is_ai_hr": false, + "category": "案例、报告与趋势", + "id": "93e723797f1c" + }, + { + "title": "This week in 5 numbers: Employees spend nearly a day ‘botsitting’ AI each week", + "url": "https://www.hrdive.com/news/employees-spend-nearly-a-day-botsitting-ai-each-week/825433/", + "published_at": "2026-07-16T20:15:00+00:00", + "source_id": "hr_dive", + "source_name": "HR Dive", + "source_region": "全球", + "source_level": "行业媒体", + "is_ai_hr": false, + "category": "案例、报告与趋势", + "id": "6ad54dae4cba" + } + ] + }, + "all_items": [ + { + "title": "Remote work isn’t always a ‘reasonable’ accommodation: 4 tips for employers", + "url": "https://www.hrdive.com/news/remote-work-isnt-always-a-reasonable-accommodation-4-tips-for-employers/825542/", + "published_at": "2026-07-17T15:55:00+00:00", + "source_id": "hr_dive", + "source_name": "HR Dive", + "source_region": "全球", + "source_level": "行业媒体", + "is_ai_hr": false, + "category": "组织与人才管理", + "id": "94f58f5ed83b" + }, + { + "title": "Nespresso must face African American’s race discrimination claim, court rules", + "url": "https://www.hrdive.com/news/nespresso-must-face-african-americans-race-discrimination-claim-court-rul/825536/", + "published_at": "2026-07-17T15:55:00+00:00", + "source_id": "hr_dive", + "source_name": "HR Dive", + "source_region": "全球", + "source_level": "行业媒体", + "is_ai_hr": false, + "category": "案例、报告与趋势", + "id": "fdcaa8dd76ca" + }, + { + "title": "Secondhand harassment supports hostile work environment claim, 5th Circuit holds", + "url": "https://www.hrdive.com/news/secondhand-harassment-supports-hostile-work-environment-claim-5th-circuit/825514/", + "published_at": "2026-07-17T15:55:00+00:00", + "source_id": "hr_dive", + "source_name": "HR Dive", + "source_region": "全球", + "source_level": "行业媒体", + "is_ai_hr": false, + "category": "案例、报告与趋势", + "id": "fcbccc5e4d6b" + }, + { + "title": "Employers may soon find it harder to retain workers", + "url": "https://www.hrdive.com/news/employers-may-soon-find-it-harder-to-retain-workers/825505/", + "published_at": "2026-07-17T14:35:00+00:00", + "source_id": "hr_dive", + "source_name": "HR Dive", + "source_region": "全球", + "source_level": "行业媒体", + "is_ai_hr": false, + "category": "案例、报告与趋势", + "id": "93e723797f1c" + }, + { + "title": "How AI ‘workslop’ is undermining your organization’s performance", + "url": "https://www.hrdive.com/news/how-ai-workslop-is-undermining-your-organizations-performance/825517/", + "published_at": "2026-07-17T14:35:00+00:00", + "source_id": "hr_dive", + "source_name": "HR Dive", + "source_region": "全球", + "source_level": "行业媒体", + "is_ai_hr": true, + "category": "组织与人才管理", + "id": "61c5e5abb7a9" + }, + { + "title": "This week in 5 numbers: Employees spend nearly a day ‘botsitting’ AI each week", + "url": "https://www.hrdive.com/news/employees-spend-nearly-a-day-botsitting-ai-each-week/825433/", + "published_at": "2026-07-16T20:15:00+00:00", + "source_id": "hr_dive", + "source_name": "HR Dive", + "source_region": "全球", + "source_level": "行业媒体", + "is_ai_hr": false, + "category": "案例、报告与趋势", + "id": "6ad54dae4cba" + }, + { + "title": "AI may conceal growing ‘learning debt’ for fast-changing roles", + "url": "https://www.hrdive.com/news/ai-may-conceal-growing-learning-debt-for-fast-changing-roles/825396/", + "published_at": "2026-07-16T14:46:00+00:00", + "source_id": "hr_dive", + "source_name": "HR Dive", + "source_region": "全球", + "source_level": "行业媒体", + "is_ai_hr": true, + "category": "学习发展与技能转型", + "id": "94cfcdff3a70" + } + ] +} \ No newline at end of file diff --git a/docs/HR_RADAR_MVP.md b/docs/HR_RADAR_MVP.md new file mode 100644 index 00000000000..7ce77a7e0af --- /dev/null +++ b/docs/HR_RADAR_MVP.md @@ -0,0 +1,122 @@ +# 中国 HR × AI 情报台:MVP 需求说明 + +## 1. 项目定位 + +这是一个面向中国大陆 HR 团队的内部公开资讯情报台。 + +目标不是做泛 AI 新闻聚合,而是在工作日每天帮助 HR 团队快速了解: + +- 有哪些劳动用工、就业、社保、人才及数据合规政策变化; +- AI 正在如何影响招聘、组织管理、培训与 HR 数字化; +- 有哪些值得评估的 HR 产品、企业实践和人才趋势。 + +站点只收录公开资讯。不得出现公司内部信息、员工信息、候选人数据、未公开招聘计划、内部评价或内部文档。 + +## 2. 使用范围 + +- 使用者:内部 HR、HRBP、招聘、HRIS、学习发展及相关管理者; +- 访问方式:任何获得链接的团队成员可访问; +- 内容性质:公开资讯汇总与内部信息参考; +- 免责声明:自动摘要不构成劳动法律意见;政策以官方原文及法务意见为准。 + +## 3. 政策覆盖范围 + +全国政策为主,重点关注: + +1. 上海; +2. 北京; +3. 深圳。 + +所有政策资讯尽可能展示: + +- 适用地区; +- 信息等级:官方政策 / 官方解读 / 行业资讯; +- 生效日期(原文明确时); +- 官方原文链接。 + +## 4. 首版栏目 + +1. 政策与劳动合规 +2. AI 招聘与招聘工具 +3. 组织与人才管理 +4. 学习发展与技能转型 +5. HR 产品与数字化 +6. 案例、报告与趋势 + +## 5. 内容优先级 + +从高到低排序: + +1. 全国、上海、北京、深圳的劳动用工与合规政策; +2. 影响招聘、候选人数据、员工个人信息或自动化决策的 AI 变化; +3. HR SaaS、招聘系统、企业协同和企业 AI 的重要产品更新; +4. 可信企业案例; +5. 人才、就业、技能和组织趋势报告。 + +每日精选目标为 8 至 12 条。 + +## 6. 纳入主题 + +### 6.1 劳动政策与合规 + +- 劳动合同、劳动关系、劳动争议; +- 工时、加班、休假、工资支付; +- 社会保险、公积金、最低工资; +- 招聘、就业、人才引进、职业技能和培训补贴; +- 裁员、竞业限制、劳务派遣、灵活用工、外包; +- 个人信息保护、员工数据、员工监控; +- 算法治理、生成式 AI、自动化决策。 + +### 6.2 AI × HR + +- AI 招聘、AI 面试、简历筛选、人才画像; +- HR Agent、HR 智能体、员工服务自动化; +- AI 绩效、人才盘点、组织设计、员工体验; +- 企业 AI 培训、岗位技能转型、学习发展; +- People Analytics、人才智能、HR 数据治理; +- HR SaaS 与企业 AI 产品更新。 + +## 7. 明确排除 + +- 纯模型、芯片、编程工具、AI 绘图和视频模型新闻; +- 与招聘、员工、组织、培训、劳动政策无关的泛 AI 新闻; +- HR 厂商奖项、品牌宣传和无实际产品/案例价值的营销稿; +- 付费报告全文; +- 未经验证的自媒体政策解读; +- 公众号、X、小红书、抖音等需要不稳定抓取或账号权限的内容; +- 任何公司内部信息或个人数据。 + +## 8. 首批优先信源方向 + +### 官方与政策 + +- 人力资源和社会保障部; +- 中国政府网; +- 国家互联网信息办公室; +- 国家统计局; +- 上海市人力资源和社会保障局; +- 北京市人力资源和社会保障局; +- 深圳市人力资源和社会保障局。 + +### HR 产品、招聘与企业数字化 + +- 北森; +- Moka; +- 飞书; +- 钉钉; +- 智联招聘; +- 猎聘。 + +### 趋势参考 + +- LinkedIn Talent Blog / Economic Graph; +- 世界经济论坛(WEF)。 + +## 9. 更新和发布规则 + +- 更新频率:工作日每天北京时间 08:30; +- 数据来源:优先官方 RSS、Atom、公开 API 和稳定公开页面; +- 不使用私人邮箱、Cookie、登录态或付费社交平台 API; +- 每条内容保留原始来源链接; +- 政策类和合规类内容必须优先展示官方原文; +- AI 生成摘要仅用于辅助阅读,不能替代法务审核。 diff --git a/hr/index.html b/hr/index.html new file mode 100644 index 00000000000..d6a748fb3e0 --- /dev/null +++ b/hr/index.html @@ -0,0 +1,136 @@ + + + + + + HR × AI 资讯台 + + + +
+

HR × AI 资讯台

+
聚焦 HR 与 AI 交叉领域
+
加载中...
+
+ +
+
+ ⚠️ 本页面仅汇总公开资讯,不构成劳动法律意见。政策类内容请以官方原文及法务意见为准。 +
+
加载中...
+
+ + + + + + \ No newline at end of file diff --git a/scripts/update_hr_radar.py b/scripts/update_hr_radar.py new file mode 100644 index 00000000000..1018ec6bbf1 --- /dev/null +++ b/scripts/update_hr_radar.py @@ -0,0 +1,321 @@ +#!/usr/bin/env python3 +""" +HR × AI 资讯台 - 抓取与处理脚本 +基于原项目思路,但独立运行,只处理 HR 相关资讯 +""" + +import json +import hashlib +from datetime import datetime, timezone, timedelta +from pathlib import Path +import feedparser + +# 读取配置文件 +CONFIG_PATH = Path("config/hr_sources.json") +OUTPUT_DIR = Path("data") +OUTPUT_PATH = OUTPUT_DIR / "hr-radar.json" + +# HR 关键词库(按栏目分类) +HR_KEYWORDS = { + "policy": [ + "劳动合同", "劳动关系", "劳动争议", "社保", "公积金", "最低工资", + "工时", "加班", "休假", "招聘", "就业", "人才引进", "职业技能", + "培训补贴", "裁员", "竞业限制", "劳务派遣", "灵活用工", "外包", + "个人信息", "员工数据", "员工监控", "算法", "生成式AI", "自动化决策", + "劳动", "劳动法", "合规", "用工", "工资", "薪酬", "福利", + "social security", "labor law", "employment", "compliance", + "workforce", "payroll", "benefits" + ], + "ai_recruiting": [ + "AI招聘", "智能招聘", "AI面试", "简历筛选", "人才画像", + "招聘自动化", "ATS", "候选人", "AI recruiting", "AI hiring", + "resume screening", "talent acquisition", "interview" + ], + "org_talent": [ + "组织", "人才", "绩效", "人才盘点", "组织设计", "HRBP", + "员工体验", "People Analytics", "组织发展", "OD", "Talent", + "organization", "performance", "talent management" + ], + "learning": [ + "AI培训", "学习发展", "技能转型", "企业培训", "岗位技能", + "人才培养", "L&D", "learning", "upskilling", "training" + ], + "hr_product": [ + "HR SaaS", "飞书", "钉钉", "北森", "Moka", "Workday", + "SAP", "人力资源系统", "数字化", "HR tech", "HRIS", + "SaaS", "software", "platform" + ], + "cases": [ + "案例", "报告", "趋势", "研究", "调研", "白皮书", + "report", "trend", "study", "research", "case study" + ] +} + +# AI 相关关键词(用于交叉判断) +AI_KEYWORDS = [ + "AI", "人工智能", "大模型", "LLM", "生成式", "GenAI", "Agent", + "智能体", "算法", "自动化", "机器学习", "深度学习", "数字化", + "artificial intelligence", "machine learning", "automation", + "generative AI", "large language model" +] + +# 噪音排除(看到这些词的内容不要) +NOISE_KEYWORDS = [ + "娱乐", "明星", "八卦", "体育", "彩票", "旅游", "美食", + "游戏", "影视", "股票", "炒股", "crypto", "bitcoin" +] + + +def load_config() -> dict: + with open(CONFIG_PATH, "r", encoding="utf-8") as f: + return json.load(f) + + +def fetch_rss(source: dict) -> list[dict]: + """抓取 RSS 来源""" + url = source.get("url", "") + if not url: + return [] + + items = [] + try: + parsed = feedparser.parse(url) + for entry in parsed.entries: + title = entry.get("title", "") + link = entry.get("link", "") + published = entry.get("published", "") + + if not title or not link: + continue + + # 解析时间 + parsed_time = None + if published: + try: + if hasattr(entry, "published_parsed") and entry.published_parsed: + parsed_time = datetime(*entry.published_parsed[:6], tzinfo=timezone.utc) + elif hasattr(entry, "updated_parsed") and entry.updated_parsed: + parsed_time = datetime(*entry.updated_parsed[:6], tzinfo=timezone.utc) + except Exception: + pass + + if not parsed_time: + parsed_time = datetime.now(timezone.utc) + + items.append({ + "title": title, + "url": link, + "published_at": parsed_time.isoformat(), + "source_id": source.get("id", "unknown"), + "source_name": source.get("name", "Unknown"), + "source_region": source.get("region", "未知"), + "source_level": source.get("level", "一般") + }) + except Exception as e: + print(f"抓取失败 {source.get('name')}: {e}") + + return items + + +def classify_item(title: str) -> str | None: + """基于标题关键词分类到 6 个栏目之一""" + t = title.lower() + + # 1. 政策与劳动合规(最高优先级) + if any(kw.lower() in t for kw in HR_KEYWORDS["policy"]): + return "政策与劳动合规" + + # 2. AI 招聘 + if any(kw.lower() in t for kw in HR_KEYWORDS["ai_recruiting"]): + return "AI 招聘与招聘工具" + + # 3. 组织与人才 + if any(kw.lower() in t for kw in HR_KEYWORDS["org_talent"]): + return "组织与人才管理" + + # 4. 学习发展 + if any(kw.lower() in t for kw in HR_KEYWORDS["learning"]): + return "学习发展与技能转型" + + # 5. HR 产品 + if any(kw.lower() in t for kw in HR_KEYWORDS["hr_product"]): + return "HR 产品与数字化" + + # 6. 案例报告 + if any(kw.lower() in t for kw in HR_KEYWORDS["cases"]): + return "案例、报告与趋势" + + return None + + +def is_hr_relevant(title: str) -> bool: + """判断是否 HR 相关""" + t = title.lower() + + # 排除噪音 + for noise in NOISE_KEYWORDS: + if noise.lower() in t: + return False + + # 只要有 HR 或 AI 相关关键词,就保留 + all_hr = [] + for kw_list in HR_KEYWORDS.values(): + all_hr.extend(kw_list) + + has_hr = any(kw.lower() in t for kw in all_hr) + has_ai = any(kw.lower() in t for kw in AI_KEYWORDS) + + return has_hr or has_ai + + +def is_ai_hr_crossover(title: str) -> bool: + """判断是否 AI × HR 交叉内容""" + t = title.lower() + all_hr = [] + for kw_list in HR_KEYWORDS.values(): + all_hr.extend(kw_list) + has_hr = any(kw.lower() in t for kw in all_hr) + has_ai = any(kw.lower() in t for kw in AI_KEYWORDS) + return has_hr and has_ai + + +def dedupe_items(items: list[dict]) -> list[dict]: + """基于 URL 和标题去重""" + seen_urls = set() + seen_titles = set() + result = [] + + for item in items: + url = item.get("url", "") + title = item.get("title", "") + + if url in seen_urls: + continue + seen_urls.add(url) + + title_norm = title.strip().lower() + if title_norm in seen_titles: + continue + seen_titles.add(title_norm) + + result.append(item) + + return result + + +def main(): + print("=" * 40) + print("HR × AI 资讯台 - 更新脚本") + print("=" * 40) + + config = load_config() + categories = config.get("categories", []) + + # 读取配置中的 sources,如果为空则使用内置测试源 + sources = config.get("sources", []) + if not sources: + print("配置中 sources 为空,使用内置测试源...") + sources = [ + { + "id": "hr_dive", + "name": "HR Dive", + "type": "rss", + "url": "https://www.hrdive.com/feeds/news/", + "region": "全球", + "level": "行业媒体", + "default_category": "HR 产品与数字化", + "enabled": True + }, + { + "id": "people_mgmt", + "name": "People Management", + "type": "rss", + "url": "https://www.peoplemanagement.co.uk/rss", + "region": "全球", + "level": "行业媒体", + "default_category": "组织与人才管理", + "enabled": True + }, + { + "id": "hbr_manage", + "name": "HBR Managing People", + "type": "rss", + "url": "https://hbr.org/rss/topic/managing-people", + "region": "全球", + "level": "权威媒体", + "default_category": "案例、报告与趋势", + "enabled": True + } + ] + + all_items = [] + for source in sources: + if not source.get("enabled", True): + continue + print(f"正在抓取: {source['name']} ...") + items = fetch_rss(source) + print(f" 获取 {len(items)} 条") + all_items.extend(items) + + print(f"\n总计抓取: {len(all_items)} 条原始资讯") + + # 筛选与分类 + processed = [] + for item in all_items: + title = item.get("title", "") + if not is_hr_relevant(title): + continue + + category = classify_item(title) + if not category: + category = item.get("default_category", "案例、报告与趋势") + + item["is_ai_hr"] = is_ai_hr_crossover(title) + item["category"] = category + + # 生成唯一 ID + uid = hashlib.md5(f"{item['url']}{item['title']}".encode()).hexdigest()[:12] + item["id"] = uid + + processed.append(item) + + print(f"HR 相关筛选后: {len(processed)} 条") + + # 去重 + processed = dedupe_items(processed) + print(f"去重后: {len(processed)} 条") + + # 按时间倒序 + processed.sort(key=lambda x: x.get("published_at", ""), reverse=True) + + # 取每日上限 + limit = config.get("daily_pick_limit", 12) + final_items = processed[:limit] + + # 按栏目分组 + categorized = {cat: [] for cat in categories} + for item in final_items: + cat = item.get("category", "案例、报告与趋势") + if cat in categorized: + categorized[cat].append(item) + + # 生成输出 + OUTPUT_DIR.mkdir(parents=True, exist_ok=True) + + output = { + "generated_at": datetime.now(timezone(timedelta(hours=8))).isoformat(), + "name": config.get("name", "HR × AI 资讯台"), + "total_count": len(final_items), + "categories": categories, + "items_by_category": categorized, + "all_items": final_items + } + + with open(OUTPUT_PATH, "w", encoding="utf-8") as f: + json.dump(output, f, ensure_ascii=False, indent=2) + + print(f"\n已生成: {OUTPUT_PATH}") + print(f" 共 {len(final_items)} 条精选资讯") + +if __name__ == "__main__": + main() \ No newline at end of file