boss
Skill0 starsChanged 15 days agoMITView on GitHub
agent-browser-bridge 的子技能——BOSS 直聘(zhipin.com)职位筛选与打招呼投递专项。当任务需要在 BOSS 直聘上搜索职位、筛选岗位、读取 JD、按候选人简历匹配生成打招呼语并发送投递消息时,读取本文件执行。覆盖:按城市+薪资+关键词搜索、提取职位卡片、破解薪资字体加密(PUA 码点)、读 JD、按简历画像评分与定制打招呼、发送(打招呼+简历网址+简历 PDF 各一条)与送达验证、每日沟通上限与风控停止规则。前置:根 SKILL.md 的桥已就绪(host 存活、扩展已连接),用户已在浏览器登录 zhipin.com;涉及发送动作前必须经用户确认。
4 other projects use a version of this.
Adopted by
Most recently taken up by
- echoVic/boss-skilltheir own version, first seen Oct 27, 2026
- mefayed/boss-skilltheir own version, first seen Aug 22, 2026
- kratosxxxxxx/Agency-Workflow-skillstheir own version, first seen May 12, 2026
- LaserPhaser/teamwork-plugintheir own version, first seen Mar 28, 2026
Other versions4 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 4
- echoVic/boss-skill★ 546same name
- kratosxxxxxx/Agency-Workflow-skills★ 97same name
- mefayed/boss-skill★ 5same name
- LaserPhaser/teamwork-plugin★ 1same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository10 other files it gives its agents.
- AGENTS.mdAGENTS.md
- agent-browser-captchaSkill
- chatgptSkill
- agent-browser-debugSkill
- firefoxSkill
- linkedinSkill
- maimaiSkill
- notebooklmSkill
- agent-browser-bridgeSkill
- xhsSkill
The file
Files
BOSS 直聘专项:职位筛选与打招呼投递
路径约定:本文的
<skill 目录>指本文件所在目录,<仓库根>=<skill 目录>/../..,命令行入口为<skill 目录>/../scripts/bb.mjs(根 SKILL.md 记作<bb>)。这些位置是可推导的,不要用find ~之类全盘搜索去定位;完整约定见根SKILL.md「路径约定」一节。
依赖:agent-browser-bridge 根 skill(host 存活、扩展已连接、用户已登录 zhipin.com)。所有浏览器操作走该桥的 page.* RPC 或下方自包含脚本。
禁止自己写 BOSS 投递脚本(强制):本专项
scripts/*.mjs内置了 BOSS 风控防护——限速与随机抖动、单 tab 内操作、tabs.prepare静默注入、安全验证/频率限制/每日沟通上限自动停止、PUA 薪资字体解密、送达验证。自己临时写的裸脚本没有这些防护,容易触发 BOSS 的频率限制与安全验证,且报错常被误判成选择器问题而继续重试,进一步加重限制。 需求不匹配时先改参数(--query/--city/--salary/ 评分阈值 / 模板文案);确实缺功能才自己写,且必须以本目录scripts/中同类脚本为模板复制改写,继承其限速与阻断检测,并在交付说明里注明「基于scripts/X.mjs改写,因缺少 Y」。禁止从零手写。
多 Agent 要求:每个投递 Agent 必须设置唯一 AGENT_ID,并在操作目标 Tab 前取得租约;不要让多个投递 Agent 共用同一 Tab。租约被占用时收到 TAB_LEASED 必须停止并换用自己的 Tab,不得绕过。
export AGENT_ID="boss-apply-1"0. 第一性原理与流程总览
以找到工作为目标,持续执行,而不是只完成一轮投递。 每次投递优先选择「岗位真实存在、薪资达标、通勤可接受、JD 与候选人经历有明确交集」的职位;宁可少投高匹配职位,也不向明显不匹配、地点不明、猎头/派遣或已投递岗位重复发送。
用户授权后进入持续投递模式:投递成功后自动继续下一页、下一个关键词和下一个高匹配岗位;只有 BOSS 明确阻止(安全验证、频率限制、登录失效、平台拦截、完善简历、会话错配、每日沟通上限)或没有更多符合条件的岗位时才停止。遇到阻断保留记录并向用户报告,不反复刷新绕过限制。
登录态确认 → 读取简历画像(§5) → 搜索筛选(§1) → 提取职位卡片(§2) → 破薪资加密/OCR(§3) → 按简历匹配度评分(§5)
→ 逐个读 JD(§4) → 硬排除错配岗 → 排除已投递职位(§7) → 生成简历定制打招呼(§6) → 投递(打招呼+简历网址+PDF网址)
→ 验证送达(§8) → 写入投递记录 → 自动继续下一岗位/下一页/下一关键词
→ 直到平台阻断或没有更多符合条件的岗位1. 搜索筛选
搜索页 URL 模板(北京,薪资 20-50K 档):
https://www.zhipin.com/web/geek/jobs?query={关键词}&city=101010100&salary=406city=101010100= 北京;salary=406= 20-50K 档(BOSS 的 salary 是档位编码,406=20-50K;换城市/档位需从页面筛选器抓当前 URL)。- 关键词如
前端、前端 React、AI前端,可多开几个搜索页;扩展关键词按简历画像选用,见 §11。 - 没有按距离排序的选项:按职位地点字段(如"北京·海淀区·苏州桥")与候选人住址远近人工判断。
- 猎头岗、劳务派遣岗(公司名带"某"或猎头标识)、只看城市无具体区位的岗:按匹配度单独判断。
2. 提取职位卡片
列表页 DOM(li 卡片):
[...document.querySelectorAll('li')]
.filter(li => li.querySelector('.job-salary'))
.map(li => ({
title: li.querySelector('.job-title')?.innerText ?? li.querySelector('a.job-card-left')?.innerText,
url: li.querySelector('a[href*="/job_detail/"]')?.href,
salary: li.querySelector('.job-salary')?.innerText, // 注意:PUA 码点,见 §3
area: li.querySelector('.job-area')?.innerText, // 部分卡片为 null
company: li.querySelector('.company-name')?.innerText,
tags: [...li.querySelectorAll('.tag-list li')].map(t => t.innerText),
}));3. 薪资字体加密(关键难点)
BOSS 薪资/经验的数字用 PUA 字符(U+E030~U+E03A)显示,DOM 里拿不到真实数字,@font-face 动态字体每页都变。
可靠方案:macOS 窗口截图 + 视觉 OCR(不要用 CDP 截图,BOSS 页会卡):
- 此步要求 Chrome 窗口在屏幕上可见(截的是真实渲染画面,窗口被遮挡/最小化会截到旧内容或空白)——若任务处于静默模式(默认后台操作不抢焦点),先
tabs.activate或page.focus把窗口带到前台,再执行下面两步; mac_computer_use_toolcu 平面get_app_state("com.google.Chrome", screenshot=True)截 Chrome 窗口;- 保存 Frame 为 png,用 Read/视觉模型读出渲染后的真实薪资(如"20-35K·15薪")。
已实测确认的码点映射(页面对 kanzhun-mix 字体,注意每页可能不同,仅作参考):
0xE030=2, 0xE031=0, 0xE032=1, 0xE033=2, 0xE034=3, 0xE035=4, 0xE036=5, 0xE037=6, 0xE038=7, 0xE039=8, 0xE03A=9。不要依赖映射猜数,以 OCR 为准;详情页 body 文本有时含明文薪资(如"20-30K"),可作交叉验证。
4. 读取 JD
打开 https://www.zhipin.com/job_detail/<id>.html(用 page.navigate 导航,不要用 page.evaluate 改 location.href),用 page.waitForReady 或 page.waitForSelector(选职位描述节点)条件等待,不要用固定 sleep。提取:
const body = document.body.innerText;
body.match(/职位描述([\s\S]{0,1500})/)?.[1] // JD 正文
body.slice(0, 400) // 职位头部(薪资/经验/学历)注意详情页底部还有"工作地址"(判断真实通勤距离)、HR 姓名与角色(打招呼可点名)。
5. 简历画像与匹配评分(筛选的硬约束)
简历是唯一事实来源,JD 只能用于寻找交集,绝不能反向给候选人添加技术、项目或熟练度。 筛选与生成打招呼前,先读取候选人简历核心文件(路径由调用方提供,如环境变量 BOSS_RESUME_FILES 或任务参数),作为匹配基准,不要用泛化经验替代。
对每个未投递岗位计算 100 分制优先级(权重按候选人简历画像调整,以下是通用模板):
| 维度 | 分值 | 打分要点(示例:前端/全栈画像) |
| 技术匹配 | 45 | 与简历真实经历的技能交集(如 React/TS/Vue/Node/AI Agent/LLM/RAG 等);命中简历核心项目加权 |
| 通勤 | 25 | 候选人住址附近的区域优先;地点不明确最多 10 分;远距离降分或排除 |
| 薪资 | 20 | 明确达到候选人薪资底线(本任务档位 20-50K);范围含底线但档位不明时降分;无法确认真实薪资时不优先 |
| 岗位质量 | 10 | 正式编制、职责具体、公司/HR 信息完整得分;猎头、劳务派遣、地点模糊或明显批量招聘降分 |
硬排除(直接跳过,不计分或判 0):简历未覆盖的方向、明显与简历错配的岗位(如 JD 实际是另一方向却被关键词误召回)、薪资低于候选人底线、在校/应届/1-3 年初级岗等候选人简历不匹配的层级。默认只投 70 分以上且未被硬排除的岗位;同一公司多岗位仅保留最匹配的 1~2 个,避免重复消耗投递额度。
6. 生成打招呼语(必须按简历匹配度定制)
默认行为:严格按候选人简历匹配度生成,这是海投不跑偏的核心约束。每条 150~220 字,且必须满足:
- 开头点名应聘职位;
- 必须嵌入简历真实项目,并只映射候选人确实做过的 JD 要求(技能交集);
- 禁止根据 JD 关键词臆测或声称候选人掌握未被简历证明的技术,包括但不限于"精通/熟悉/有项目经验";简历没有明确证据的技术默认不写;只能在确有依据时使用"精通""熟悉""使用过"等相应等级表述;
- 提 1~2 个与 JD 强相关且在简历中可核验的真实经历,不要用简历里不适合对外说的表述;
- 提通勤距离优势(如"住 X,离贵司很近");
- 结尾附简历网址 + 期待沟通;
- 每条都不同,禁止千篇一律;若岗位与简历交集很弱,直接跳过而非硬编打招呼。
发送前必须做"简历事实检查":逐项核对文案中的技术、项目、年限、成果和熟练度是否能在简历核心文件中找到依据;找不到依据就删除或改为明确的谨慎表述。匹配度评分也不得因 JD 关键词本身加分。
投递时每条职位发 3 条独立消息(对方方便复制):
- 定制打招呼语
- 简历网址(环境变量
BOSS_RESUME_SITE) - 简历 PDF 网址(环境变量
BOSS_RESUME_PDF,见 §9 拦截规则)
7. 去重记录(硬规则)
投递记录持久化保存到 JSONL(追加式审计记录是事实来源)。默认存 <skill 目录>/state/applied-jobs.jsonl,可用环境变量 BOSS_STATE_DIR 覆盖为持久目录。
每条记录至少包含:jobId、职位详情 URL、职位名、公司、工作地点、薪资、HR/会话标识、首次投递时间、发送结果、消息摘要。
发送前必须先读取记录,并按以下字段去重:
- 优先按职位详情 URL 或
jobId; - URL 变化时,按「公司 + 职位名 + 工作地点」匹配;
- 历史会话中已向同一职位/同一 HR 打过招呼,也视为已投递;
- 仅查看过、收藏过、沟通过但没有发送消息的岗位,不视为已投递。
无法确定是否已经投递时,默认跳过,不冒险重复发送。发送三条消息并逐条验证后,才写入 sent 记录;部分成功写入 partial,下次只补发缺失消息,不重发已送达消息。unknown 只代表 RPC/脚本超时或状态暂未渲染,不等于未发送:补发前必须重新读取当前会话 DOM,按精确消息文本和当前会话核对;若消息已存在且状态为"送达/已读",更新为 sent,禁止重发。
8. 投递(发送)流程
- 详情页点「立即沟通」:
a.btn-startchat(点击后跳转到/web/geek/chat,新会话在左侧列表顶部且selected,需验证选中会话的公司/HR 匹配预期,不匹配就重试一次点击)。 - 聊天页结构:输入框
div.chat-input(contenteditable);发送按钮button.btn-send(有内容才 enabled)。点击「立即沟通」后,聊天页是异步加载的:不能仅凭 URL 已跳转或点击 RPC 成功就继续。必须等待并确认当前会话的公司/HR 与职位匹配,且div.chat-input已出现;若页面正文为空、输入框不存在或会话仍在加载,先等待后重新只读核对,未确认输入框前禁止进入下一个岗位。若重试后仍未渲染,记录为unknown/未完成并保留当前会话现场,不要留下空会话后静默跳过。 - 输入文本:
scripts/boss-send-chat.mjs用 CDPInput.insertText(受信任事件,能触发 Vue/React 受控更新),写入前会先page.focusEl聚焦.chat-input——Input.insertText只作用于当前焦点元素,不聚焦则文字落不到输入框;它还是「光标处追加」,写入后脚本会校验输入框内容与待发文本精确相等,不等即退出(残留草稿会让发送内容变成「草稿+本次文本」)。然后轮询发送按钮直到真正可用(最多约 3 秒)再点击。BOSS 的 contenteditable/Vue 状态同步是异步的,禁止仅依赖固定延迟。手写流程时才用 native setter + InputEvent(见根SKILL.md「实战踩坑清单」第 5 条)。 - 每条消息发送后必须按"当前会话 + 本次发送文本"定位消息气泡,优先使用
.message-item.item-myself/.message-content,并在同一气泡的父级内检查"送达/已读";不能用宽泛选择器直接取 DOM 最后一项,也不能只检查最短文本子节点。遇到平台暂不支持直接发送立即记录为blocked。遇到 RPC/扩展超时或暂未渲染,记录unknown后先做一次只读页面核对;确认不存在且输入框为空时才允许补发,确认已存在则改为sent,严禁因 UNKNOWN 直接重发。
单条消息发送脚本(推荐):
BRIDGE_TOKEN=$(cat ~/.chrome-agent-bridge/token) node <skill 目录>/scripts/boss-send-chat.mjs <tabId> "<消息文本>"- 脚本自动申请当前 Tab 的 120 秒租约(读取
AGENT_ID,默认按进程生成);租约失败立即退出。 - 退出码:
0=sent(已送达/已读);1=verify failed(UNKNOWN/未发出/输入未清);2=blocked(平台拦截)。 1/2均不得未经人工核对就补发,避免重复消息;脚本内置异步按钮轮询、当前文本精确匹配和 UNKNOWN 只读复核。
批量投递模板(推荐入口):
BRIDGE_TOKEN=$(cat ~/.chrome-agent-bridge/token) \
BOSS_RESUME_SITE="https://example.com/resume" \
BOSS_RESUME_PDF="https://example.com/%E7%AE%80%E5%8E%86.pdf" \
node <skill 目录>/scripts/boss-batch-apply.mjs <tabId>- 使用前把
jobs数组替换为实际职位(URL + 会话校验关键词check+ 定制打招呼语)。 - 每个职位:
page.navigate打开详情 → 点「立即沟通」→ 轮询等待.chat-input出现且选中会话文本匹配check(不匹配自动重试一次)→ 发 3 条(PDF 未配置自动跳过)→ 轻量验证。 - 严格单条送达验证(送达/已读、UNKNOWN 复核)用
boss-send-chat.mjs;批量脚本是轻量模板。
9. 拦截规则(实测)
- 明文手机号/微信号被 BOSS 拦截:发送含 11 位手机号明文的消息会返回"为保护用户信息安全,平台暂不支持直接发送手机号、微信号等联系方式"。
- PDF 文件名含手机号时(如
张三13800000000.pdf),必须用 URL 编码形式发送:https://example.com/%E5%BC%A0%E4%B8%8913800000000.pdf编码后能送达,对方打开自动解码为中文文件名。
10. 风控与安全(硬要求)
- 用户明确授权后,符合筛选条件的岗位无需逐个等待确认;仍须在执行前完成去重检查。
- 用户说"继续""一直投递"或同义表达后,进入持续投递模式:不能只投一两个岗位就主动结束(见 §11)。
- 任何安全验证、验证码页(URL 带
_security_check)、登录失效、完善简历提示、异常弹窗、会话与目标职位不匹配,立即停止,让用户手动处理。 - 每日沟通上限 / 次数限制(明确停止信号,必须停):BOSS 对每日「立即沟通」次数有上限(实测账户约 150 次/天)。达到上限后,点击「立即沟通」会弹出居中对话框,文案为:
您已达到沟通上限 您今天已与150位BOSS沟通,休息一下,明天再来吧~+ 按钮确定DOM 载体通常是[class*=dialog]内出现您已达到沟通上限文本;同时聊天页不再出现.chat-input,发送脚本连续返回no .chat-input。 检测做法:每次点「立即沟通」后、以及批量每轮开始前,用page.evaluate扫描document.body.innerText或[class*=dialog]是否含您已达到沟通上限/您今天已与\d+位BOSS沟通;一旦命中即判定为上限(不是瞬态、不是单岗位偶发),这就是最终停止条件。 处置:立即停止整个自动化,不要高频重试、不要循环那些被跳过的岗位去绕过风控,也不要点「确定」反复触发。把被上限截断、尚未发送的有效岗位 jobId 单独保存到state/quota-blocked-pending.jsonl(含 title/company/salary/score/greeting,便于下次补投),如实汇总"已达每日沟通上限(今日约150次),剩余 N 个合格岗位待明日/下次额度恢复后补投"。 - 发送动作不可逆,必须确保目标职位、公司、HR 和文案均已核对;不确定就跳过,不猜测、不误投。
- 多 Agent 并行投递时,每个 Agent 使用独立 Tab 和唯一
AGENT_ID;启动批处理前先调用/tabs/claim。同一账号的投递额度、聊天会话和风控状态仍是共享的,因此不得并发狂发;建议按 Agent 分工关键词/页面,并保持发送节奏。 - 每职位 3 条消息之间有间隔;不要并发狂发,BOSS 可能弹安全验证/会员提示。
- 空会话防护:点击「立即沟通」后如果只创建了会话、但输入框尚未出现,不能把它当作已处理岗位,也不能直接切换下一个岗位。先按条件等待并重新读取当前会话;确认输入框、目标公司/HR 和职位均已匹配后才允许发送。若最终未发送任何消息,必须在投递记录中标记为
not_sent/unknown并报告原因。 - 用户已登录态由顶部导航("消息/简历/用户名")确认;未登录先让用户扫码登录。
- 历史会话里的旧消息不要重复发;投递过的职位跳过。
11. 持续投递执行策略
- 用户明确说"继续""一直投递"或同义表达后,进入持续投递模式;不要在每个职位、每一页或每个关键词之间再次询问确认。
- 推荐关键词顺序(前端/全栈基线示例,按简历画像调整):
AI前端→AI Agent→React→前端→全栈。基线关键词耗尽后,按简历匹配度追加相邻高价值关键词(如TypeScript、大前端、Vue、Node.js、可视化、小程序、AI Agent全栈、Next.js、Electron、AIGC、前端工程化、B端中后台、低代码等);每追加一个关键词同样走「提取→破薪资→评分→排除硬排除项→读 JD→生成定制打招呼→投递」全流程。 - 每投递一个岗位:立即校验三条消息的送达状态并追加写入 JSONL,再开始下一个岗位;不得先批量发送后补记录。若为
partial/unknown,先做只读核对,补齐或确认已送达后再继续;不得因为单个岗位验证异常结束持续投递。 - 达到每日沟通上限即停(见 §10):批量中出现「前几个成功、之后持续
no .chat-input」的断层,就是上限信号;立即停止,把未发的合格岗位存state/quota-blocked-pending.jsonl,如实汇总待补投数。 - 每个搜索结果页处理完后继续翻页;翻页前重新读取去重记录。当前页没有合格岗位时切换下一个关键词。
- 停止时汇总:成功投递数、部分成功数、跳过数及原因、最后阻断原因、下一步需要用户处理的事项。
资产
scripts/boss-send-chat.mjs:单条消息发送+验证(输入→点发送→验证送达),使用scripts/boss-verify-helpers.mjs的analyzeDelivery/decideOutcome/matchDelivery/isBlocked做结构化判定。scripts/boss-verify-helpers.mjs:送达验证纯逻辑模块(不依赖浏览器,可单测)。scripts/boss-batch-apply.mjs:多职位批量投递模板(打开详情→立即沟通→发 3 条→轻量验证),复制后改jobs数组即可。
退出码与「用户叫停」(v0.3.11+ 必须处理)
两个脚本都会在发送前后检查停止状态,并在退出时主动释放 Tab 租约:
| 退出码 | 含义 |
0 | send-chat:已确认送达/已读 |
1 | 失败 / 未定论(UNKNOWN 时不自动重发,交人工核对) |
2 | 平台拦截(BLOCKED) |
3 | 用户点了页面上的「停止 Agent」 |
退出码 3 是「用户明确叫停」,不是普通失败:
- 脚本会立即终止整批(batch-apply 不再导航、不再点「立即沟通」;send-chat 不点发送)。
- 不得自动重试、不得自动补发。要恢复得显式
agent.resume(details.resumeWith就是这个值)。 - 停止只拦写操作(
page.click/page.type/navigate/CDP 的Input.*)。scripts/boss-send-chat.mjs的「输入」走 CDPInput.insertText,会被闸门拦; 「点击发送」走page.evaluate不被拦,所以脚本在点击前自己调agent.stopStatus检查—— 改这些脚本时不要把这个检查删了。
历史坑(v0.3.11 修):旧的
evalResult()写成resp.ok === false ? null : ..., 把桥层错误静默变成{},于是「用户叫停 / 租约被占 / 超时」全被误报成 「元素不存在 / 未送达」,而openChat()的重试循环还会继续点下去。 现在桥错误由assertOk()显式抛出,AGENT_STOPPED直接终止进程。
租约泄漏(v0.3.11 修):旧脚本拿到租约后从不释放,异常退出会把该 tab 锁 120 秒, 下一个 Agent 拿到
TAB_LEASED却不知道是谁占的(实测残留 3 个)。 现在所有退出路径(含unhandledRejection/uncaughtException)都先releaseLease()。
state/applied-jobs.jsonl:已投递岗位的追加式去重与审计记录;开始任务前读取,成功发送后写入。state/quota-blocked-pending.jsonl:被每日沟通上限截断、尚未发送的有效岗位队列。下次继续且额度恢复后,先消费此队列再扩展新关键词;补投前仍按 jobId 去重。
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

