| name | job-tracker |
| description | 校招岗位自动追踪系统。搜索 2026 校园招聘信息,匹配目标方向,写入飞书多维表格,
并通过飞书 IM 推送摘要提醒。支持定时自动执行和手动触发。
核心机制:80% 精准匹配 + 20% 探索推荐,用户反馈闭环自进化。
Triggers: "搜岗位", "查秋招", "岗位推送", "job search", "校招追踪",
or scheduled via Cron.
|
| author | Claude Code |
| version | 2.0.0 |
| date | "2026-05-04T00:00:00.000Z" |
| allowed-tools | ["Bash","Read","Write","Edit","Grep","Glob","mcp__feishu__bitable_v1_appTableRecord_create","mcp__feishu__bitable_v1_appTableRecord_search","mcp__feishu__bitable_v1_appTableRecord_update","mcp__feishu__im_v1_message_create","mcp__feishu__docx_builtin_import","mcp__feishu__wiki_v2_spaceNode_create","mcp__feishu__drive_v1_permissionMember_create","mcp__tavily__tavily_search","mcp__fetch__fetch","mcp__playwright__browser_navigate","mcp__playwright__browser_snapshot","mcp__playwright__browser_close","mcp__playwright__browser_click","CronCreate","CronList","CronDelete","WebSearch","WebFetch"] |
Job Tracker — 校招岗位自动追踪 v2
Automated campus recruitment job discovery with a Core + Explore dual-track
strategy, feedback-loop personalization, and Feishu IM push notifications.
Design Philosophy
Core + Explore (80/20)
- Core (~80%): Exact matches — target cities, target roles, priority companies.
These are the jobs you would apply to without hesitation.
- Explore (~20%): Broadening horizons — adjacent cities (Zhuhai, Dongguan),
related roles (motion control, autonomous driving planning), startups you
have not heard of. These are "maybe interesting" — you decide.
Configurable in profile.md: set exploration_ratio to 0 to disable exploration,
or up to 0.3 for more serendipity.
Feedback Loop
After each batch push, the system asks you to rate jobs (1-5). Over time:
- Companies/roles you rate highly → boosted in future searches
- Companies/roles you rate poorly → deprioritized
- The system maintains a preferences.json file tracking your taste
Self-Evolution
The skill adapts across runs:
- Reads historical ratings from preferences.json
- Adjusts search keywords and filter weights
- Explores adjacent domains you have not rated yet (maintaining novelty)
Architecture
profile.md + preferences.json
│
▼
Search (Tavily + WebFetch)
│
▼
Filter & Rank (Core 80% + Explore 20%)
│
▼
Feishu Bitable ← Feishu IM Push → User Feedback → preferences.json
Workflow
Step 0: Load Context
Read profile.md and preferences.json (if exists). Determine:
- Core search parameters (cities, roles, companies)
- Exploration parameters (adjacent cities, related roles)
- Historical preferences (boosted/deprioritized companies and roles)
Step 1: Multi-Source Search
Run all tiers in parallel where possible. Playwright browser operations are
sequential (one browser instance).
Tier 1 — WeChat 公众号 via Playwright (highest signal, newest info):
University career center 公众号 are the FIRST place campus recruitment
announcements appear, before aggregator sites or search engines index them.
1. Playwright navigate to weixin.sogou.com/weixin
2. For each monitored 公众号:
search: "{公众号名} 2026校招 招聘推荐 宣讲会"
3. browser_snapshot → extract article list
4. Filter: articles from last 7 days
5. For each new article → browser_navigate to article → snapshot → extract jobs
6. browser_close when done
Why Playwright: mcp__fetch__fetch and WebFetch are blocked by mp.weixin.qq.com
robots.txt and network security policies. Playwright simulates a real browser and
bypasses these restrictions. Sogou WeChat search is accessible via Playwright
even though its robots.txt blocks automated tools.
Default monitored 公众号 (configurable in profile.md):
- 华南理工大学学生就业指导中心
- 中山大学就业指导中心
- 深高金职业发展中心
- 广东工业大学学生就业指导中心
- 广东招聘就业指导中心
Foreign companies in Guangdong: Each batch should include 1-2 positions
from foreign companies with Guangdong offices (ABB, KUKA, Texas Instruments,
Siemens, Bosch, Valeo, Schneider Electric, etc.). These typically offer better
WLB and are often overlooked by domestic candidates. Search with:
WebSearch: "{foreign_company} 2026校招 广州 深圳 佛山"
Tier 2 — Company Career Pages (direct, high signal):
WebSearch: "{tier1_company} 2026校园招聘 岗位 应届生"
+ direct WebFetch of known career page URLs from profile.md
(e.g. xiaopeng.jobs.feishu.cn/campus, we.dji.com/campus/position)
Tier 3 — University Career Center Websites (good signal):
WebSearch: "{local_universities} 就业网 2026 校招 宣讲会 {role}"
Career center article pages are indexed by search engines even when
the main portal requires login.
Tier 4 — Job Aggregators (medium signal):
WebSearch: "2026校招 {role} {city} site:(yingjiesheng.com OR campus.niuqizp.com)"
Tier 5 — Broad Discovery (lower signal, catches surprises):
WebSearch: "{role} OR {related_role} 2026应届生 {core_city} OR {explore_city}"
Finds startups and roles outside the known company list.
Tier 6 — User-submitted Links (on-demand):
- XHS links →
mcp__fetch__fetch (works for individual XHS links)
- WeChat links shared by user → Playwright navigate
Source Reliability
| Source | Trust | Recency | Access Method |
|---|
| 公众号 via Sogou+Playwright | Highest | Same-day | Playwright browser |
| Company career page (feishu.cn/jobs) | Highest | Current | WebFetch |
| University career center website | High | 1-3 day lag | WebSearch |
| Job aggregator (yingjiesheng) | Medium | Days | WebSearch |
| General web search | Low-Medium | Varies | WebSearch |
| XHS / social media | Low | Varies | mcp__fetch__fetch |
What Does NOT Work
| Channel | Reason |
|---|
| mp.weixin.qq.com direct fetch | robots.txt + network security block |
| 搜狗微信 direct fetch | robots.txt (bypassed via Playwright) |
| Boss直聘/猎聘 | Anti-scraping + mixed社招/校招 |
| 大学就业网主页 | SSO login required |
Step 2: Filter & Score
For each result, compute a match score (0-100):
| Factor | Weight | Description |
|---|
| City match | 30 | Core city = full, Guangdong explore = half, outside 广东 = 0 |
| Role match | 25 | Exact role = full, related = half, unrelated = 0 |
| Company tier | 20 | Tier1=full, Tier2=half, Tier3=quarter, unknown=10 |
| Education fit | 15 | Degree OK = full, borderline = half |
| Historical pref | 10 | Boosted company/role = +bonus, deprioritized = -penalty |
Explore quota: Reserve ~20% of the batch for exploration results.
Cap at max 3 explore items per batch.
Deal-breakers (instant skip):
- City not in Guangdong province (core + explore cities are all within 广东)
- Education requirement exceeds user degree AND uncompromising
- Explicitly excluded by user in profile.md
Step 3: Deduplicate & Write
- Query existing records from Bitable
- Match by (公司名称 + 岗位名称). If exists → skip. If > 30 days old → update.
- Write new records. Match score in 匹配度 field:
- Score >= 70 → 高
- Score 40-69 → 中
- Score < 40 → 低
Step 4: Create Push Document + IM Notification
Delegate to feishu.skill for document creation and writing.
4a — Build document content in Python
Generate a formatted markdown-like structure for the push report:
- emoji headings (H1/H2)
- Bold company names in bullet lists
- Job listings, industry news, skill analysis sections
- Links to bitable and external sources
4b — Create wiki doc via feishu.skill
Call feishu.skill workflow:
- Locate target folder: space_id=7635789242190269391, parent_node_token=K5JAwbeviiCuO5karpSczcVcn5c (岗位推送)
- Create empty wiki node: wiki_v2_spaceNode_create
- Fill content: Python Block API (text blocks with bold, bullet, links, emoji)
- Grant permission: drive_v1_permissionMember_create(full_access for ou_6f718…)
Important constraints from feishu.skill:
- Always use Python for Block API — bash corrupts Chinese text
- Bullet lists: use text block_type=2 + style.list.type='bullet' (NOT block_type=9)
- Divider block_type=19 NOT supported
- Company names: use bold text_style for visual emphasis
- Separator: use blank text blocks between sections
4c — Write Summary Records to Bitable
Write new positions to the bitable as before (see Step 3).
4d — Push IM Notification
Send to Feishu chat via im_v1_message_create:
Step 5: Process Feedback (Async)
When user replies with ratings:
- Parse ratings per company/role
- Update preferences.json:
- High ratings (4-5) → boost company/role weight
- Low ratings (1-2) → deprioritize
- Neutral (3) → no change
- Update existing Bitable records with user rating
- Confirm: "已记录你的偏好,下次推送会更精准"
Step 6: Cron Self-Renewal
At the end of each run, delete the current cron and re-create it with
identical parameters. This bypasses the 7-day auto-expiry.
preferences.json Format
{
"companies": {
"小鹏汽车": {"rating": 4.5, "count": 2},
"某初创公司": {"rating": 2.0, "count": 1}
},
"roles": {
"机器人软件工程师": {"rating": 5.0, "count": 3}
},
"cities": {
"深圳": {"rating": 3.0, "count": 2}
},
"last_updated": "2026-05-04"
}
Configuration
All user-specific settings live in profile.md (gitignored).
profile.example.md is the safe-to-publish template.
Key Options
| Option | Description | Default |
|---|
| exploration_ratio | Fraction from explore track | 0.2 |
| exploration_cities | Adjacent cities for exploration | [] |
| related_roles | Adjacent role types to explore | [] |
| deal_breakers | Hard filters (instant skip) | [] |
File Structure
skills/job-tracker/
├── SKILL.md ← This file — full workflow
├── README.md ← GitHub-facing setup guide
├── profile.example.md ← Template config (safe to publish)
├── profile.md ← Personal config (gitignored)
├── preferences.json ← Learned preferences (gitignored, auto-generated)
└── .gitignore
GitHub vs Personal Use
| File | GitHub | Personal |
|---|
| SKILL.md | ✅ Publish as-is | ✅ Use as-is |
| README.md | ✅ Publish as-is | ✅ Reference |
| profile.example.md | ✅ Publish (template) | ✅ Keep as reference |
| profile.md | ❌ Gitignored | ✅ Your real config |
| preferences.json | ❌ Gitignored | ✅ Auto-generated |
| .gitignore | ✅ Publish | ✅ Use as-is |
Verification
After each run, verify:
- New records in Bitable via bitable_v1_appTableRecord_search
- Push delivered — check message_id in IM response
- Cron self-renewed — check CronList shows new job ID
- No duplicates — pre + new = post count
Edge Cases & Robustness
User Forgot to Rate
- If no rating reply within 3 days → assume neutral (no preference change).
- Next push includes a gentle reminder: "上次的岗位还没评分,回复 1-5 告诉我偏好"
- Unrated batches do NOT affect preferences.json — no learning is better than wrong learning.
Zero Results Found
- Push: "📋 本周暂未发现新岗位。已记录的岗位仍可投递:{bitable URL}"
- Do NOT skip the push — silence is worse than a "no results" message.
- Cron still self-renews normally.
Bitable Write Failure
- Retry once after 5 seconds.
- If retry also fails → push error summary: "⚠ 岗位搜索完成但写入失败:{error}。数据已暂存,下次重试。"
- Continue with push and cron renewal (partial success is better than total failure).
IM Push Failure
- Bitable was already updated — the data is safe.
- Log the error. No retry needed (user can always check the table directly).
- Cron self-renews normally.
Cron Self-Renewal Failure
- If CronDelete or CronCreate fails during self-renewal:
- Old cron still exists and will fire one more time (7-day window gives buffer).
- Push a warning: "⚠ Cron 自动续期失败,请手动重建。当前 cron 将在 7 天后过期。"
- Two consecutive failures → escalate: "🚨 岗位追踪 Cron 即将中断,请立即处理。"
preferences.json Corruption
- Wrap read in try/catch. If parse fails → reset to
{} and log.
- Push: "⚠ 偏好数据损坏已重置,之前的评分记录丢失。"
- Old ratings in Bitable are preserved (can be manually re-imported).
Search Returns Stale/Noise Results
- Apply a recency heuristic: prefer results published within last 30 days.
- If a source domain consistently produces noise (e.g., 猎聘 with社招), deprioritize it automatically.
- If > 50% of results are deduplicated as already-existing → the market is quiet, this is normal, don't force it.
Xiaohongshu / Non-Standard Sources
- Individual XHS links CAN be fetched via
mcp__fetch__fetch (verified).
- XHS cannot be systematically crawled (no login, no search API).
- Strategy: search engines may index XHS posts → WebSearch "小红书 招聘 机器人 广州" → fetch individual links.
- Tag XHS-sourced records with 信息来源 = "小红书" so user knows to verify independently.
How to Invoke
Manual Trigger
Say any of these in the chat:
搜岗位
查秋招
岗位推送
job search
校招追踪
Or use the explicit slash command:
/job-tracker
Claude Code matches the skill via the description frontmatter and invokes it automatically.
Manual with Override
When invoked manually, the skill will first ask:
"要调整搜索范围吗?比如临时加一个城市或方向?"
Reply with overrides like:
- "也看看东莞" → adds 东莞 to this run's explore list
- "只看广州" → restricts to core city only, no exploration
- "多搜一些初创" → bumps exploration_ratio to 0.3 for this run
Automatic (Cron)
Runs every Monday and Thursday at 10:00 local time. No user action needed.
Push arrives in Feishu chat automatically.
To check status: "Cron 状态" or "CronList"
Rating Flow
After each push, reply in the Feishu chat (not here):
评分 小鹏汽车 5 库卡 4 亿航 3
Or simply:
5 4 3
(Matches the order of companies in the push message)
The skill processes this in the next interaction and updates preferences.json.
Troubleshooting
| Issue | Cause | Fix |
|---|
| Auth token expired | Feishu UAT expired | Re-authorize Feishu app |
| Permission denied on bitable | App lacks bitable scope | Add bitable:app in Feishu console |
| Permission denied on IM | App lacks message scope | Add im:message:send |
| Cron expired | 7-day limit reached | Self-renewal should handle it |
| No explore results | exploration_cities empty | Add cities to explore list |
| Feedback not learning | preferences.json missing | Auto-creates on first rating |
| Forgot to rate | Normal | No penalty; reminder on next push |
| Push not received | IM token or chat_id issue | Check table directly; verify chat_id |
| Skill not triggering | Phrase not matched | Use /job-tracker explicitly |