下载地址
https://www.zhengdianxue.com/wp-content/uploads/skills/koseninfo--resume-screener-plus.zip将提示词发送给你的 AI 安装该 skills
请根据 https://skillhub.cn/install/skillhub.md,安装 @koseninfo/resume-screener-plus。按照用户设置条件,岗位,学历,工作年限,base地,技能,行业,业务领域条件进行AI简历筛选,支持文件夹选择,并将符合条件的简历挪到用户设定的存储文件夹;
阅读全文 (展开查看完整说明)
概述
简历筛选技能(resume-screener · Pay Skill)
按两步法批量筛选本地简历文件夹:Step 1 收集并确认筛选条件 → Step 2 选定文件夹执行筛选并落盘。本技能已升级为 SkillHub Pay Skill(基于 x402 协议),既支持 WorkBuddy 内的本地交互式调用,也支持作为可被 Agent 按次付费调用的 HTTP 服务(POST /screen,详见文末「Pay Skill 改造」)。
运行环境(下载后自动自检 + 自动配置)
技能要求 Python 3.8+,依赖见 requirements.txt:pdfplumber(PDF 抽取)、python-docx(.docx 解析)、cryptography(微信支付 X402 的 RSA 签名);GUI 还需 tkinter(官方 Python 安装包自带)。
下载后无需手动装环境——各入口脚本在启动时会自动调用 scripts/_env.py 完成自检与自动安装:
screen_gui.py(GUI 入口):启动前自检并自动补齐依赖;若tkinter缺失会给出平台相关安装指引后退出。pay_server.py(Pay Skill 服务):启动前确保cryptography可用,缺失则自动安装。screen_resumes.py(CLI 引擎):被调用时静默自检并补齐pdfplumber/python-docx。- 若
pay_config.json缺失,自动从pay_config.example.json复制出配置骨架(不覆盖既有)。
也可显式运行一键配置(等价于上述自检):
python scripts/setup_env.py # 自检 + 自动安装缺失依赖 + 生成 pay_config 骨架
python scripts/setup_env.py --no-install # 仅检查,不安装
python scripts/setup_env.py --check-gui # 同时检查 tkinter(GUI 入口需要)自检为幂等操作,反复运行安全;安装失败(如离线)仅告警,不影响已可运行的部分。
# 如需手动准备独立环境(可选)
python -m venv .venv && .venv/Scripts/pip install -r requirements.txt
PY="<你的 python 解释器,或 .venv/Scripts/python.exe>"
SKILL="<本技能目录>"
SCRIPT="$SKILL/scripts/screen_resumes.py"注:
PY写的是本机受管 venv 的示例路径,发布后请替换为使用者自己的 Python 解释器;
--show-defaults会把上次岗位名与配置写入技能目录下的state.json(可删,不影响逻辑)。
支持格式:.docx、.pdf、.txt、.md;.doc 为尽力而为(二进制文本抽取,召回有限)。
Step 1 — 收集并确认筛选条件(逐项弹窗确认)
核心规则:所有筛选条件(岗位名称 / base 地 / 学历 / 工作经验 / 行业经验 / 业务领域 / 存储目录 / 简历文件夹)一视同仁,每一个都必须通过“弹窗/确认卡片”向用户显式确认,禁止在用户未确认的情况下直接沿用默认值或凭假设进入下一步。 即便某条件已有默认值,也要把默认值展示在确认弹窗里,请用户选择“确认沿用”或“修改”;每次都必须真正收集到用户确定的信息后方可推进。
确认弹窗的实现方式(本环境以交互式确认卡片 / 提示充当“弹窗”):
- 先读取已保存默认值:
"$PY" "$SCRIPT" --show-defaults - 对每一个条件,单独渲染一张确认卡片,内容为【条件名 · 当前默认值或候选选项 · 请确认或填写】,并等待用户明确回复后再处理下一个。
- 全部条件(含两个文件夹选择)确认无误后,才进入 Step 2。
各条件说明:
- 岗位名称(必弹窗确认):用户输入岗位关键字(如
Java开发工程师)。支持子串匹配,简历“求职意向/期望职位”优先。在确认弹窗中展示上次默认岗位(last_job_title),请用户确认沿用或修改。用户确认后,本次岗位名称将在 Step 2 运行时被脚本自动写回state.json(成为下次默认)。 - base 地(需弹窗确认):手工输入城市/地区关键字(如
北京),子串匹配,优先匹配“期望工作地/现居地”等字段。 - 学历要求(需弹窗确认):三选一 ——
高中以上/专科以上/本科以上(含本档及以上)。 - 工作经验(需弹窗确认):四选一档位(输入数字即可):
3→ 筛选 2~5 年;5→ 4~7 年;7→ 6~9 年;10→ 10 年以上
(年限从“X年工作经验 / 工作经历日期区间求和 / 最高学历毕业年份”三处综合识别。)
- 技能描述设定(需弹窗确认,主条件·硬性门槛):技能关键字,即具体的工具/工种名称(如 IT 岗的
SpringCloud, MySQL、技工岗的钳工, 焊工)。命中 = 简历「项目经验 / 工作经历 / 专业技能(技能特长)」任一区块中出现该技能名(逗号/空格分隔,所列技能命中任一项即可(OR))。留空则不过滤;填写后作为主条件之一——技能为硬性门槛,填写且任一项都未命中则一律判未通过(行业/业务领域优先项也无法放宽)。 - 行业经验设定(需弹窗确认,非必须满足):行业关键字(如
电力)。命中 = 简历“项目经验”中出现该行业(内置同义词见INDUSTRY_SYNONYMS;逗号分隔,命中任一即通过)。无项目经验区块则回退全文检索。不参与“通过/未通过”判定,仅作为优先排序信号;可留空。 - 业务领域设定(需弹窗确认,非必须满足):业务领域关键字(如
电商、金融、医疗)。命中 = 简历“项目经验”中出现该领域(内置同义词见DOMAIN_SYNONYMS)。不参与“通过/未通过”判定;与行业经验同时命中时该简历排至报告最前并标记★优先。 - 筛选结果存储目录(操作系统原生“选择文件夹”对话框,可新建):通过
scripts/pick_folder.py拉起 Windows 原生文件夹选择框(非聊天确认卡片),让用户直接点选目录;对话框内自带“新建文件夹”按钮。Step 2 会把命中简历复制到这里,并生成screening_report.csv/.json。
所有条件(含两个文件夹选择)必须各自通过弹窗确认,且每次都须真正收集到用户确定的信息,全部确认无误后进入 Step 2。
Step 2 — 选择文件夹并执行筛选
- 简历所在文件夹(操作系统原生“选择文件夹”对话框,禁止纯文本输入):通过
scripts/pick_folder.py拉起 Windows 原生文件夹选择框,让用户直接点选文件夹。脚本会递归扫描该文件夹及其子文件夹(深度上限 3 层)中的简历文件。选定文件夹必须真实存在,否则需重新拉起对话框。
实现要点:本环境 PowerShell 工具的 stdout 被宿主吞掉,故不可用 PowerShell 拉对话框;改用受管 Python 的
tkinter.filedialog.askdirectory(scripts/pick_folder.py),所选路径经 Python stdout 返回,Bash 可正常捕获:SEL=$("$PY" "$SKILL/scripts/pick_folder.py" "选择待筛选简历所在文件夹" "C:/Users/kosen/Downloads")
- 执行脚本(代入 Step 1 收集到的条件;未提供的留空,行业/业务领域留空即不限制、且不影响通过与否):
"$PY" "$SCRIPT"
--folder "简历文件夹路径"
--output "筛选结果存储目录"
--job-title "岗位名称"
--location "base地"
--education "本科以上"
--experience 5
--industry "电力"
--domain "电商"
--skills "Spring, MySQL"- 若要只预览不复制文件,追加
--no-copy;调试抽取效果加--verbose。 --job-title传入后会自动更新state.json的last_job_title。--industry/--domain为可选软条件:留空则不限制;提供后仅用于把“行业+领域双命中”的简历置顶,不会造成未通过。
- 脚本产出:
- 命中简历:复制到
--output目录(重名自动加前缀)。 screening_report.csv/screening_report.json:每份简历的逐项判定、姓名、识别年限、目标岗位、行业/业务领域命中、是否★优先、总结果。双命中简历排在最前。- 控制台汇总:总数 / 通过 / 未通过 / 解析失败 / 优先置顶份数。
- 命中简历:复制到
- 把汇总与报告路径反馈给用户,必要时用
--verbose复跑解释某份未通过原因。
本地 GUI 模式(Windows 原生窗口,可选)
嫌逐步确认繁琐时,可直接运行 GUI 前端,弹出 Windows 原生窗口一次性完成条件设置与筛选:
"$PY" "$SKILL/scripts/screen_gui.py"窗口内容:岗位 / base地 / 学历 / 经验 / 技能描述(主条件)/ 行业 / 领域 输入框;简历文件夹与结果存储目录通过 Windows 原生“选择文件夹”对话框指定;输入框下方展示筛选逻辑注释;底部两个按钮——「筛选」与「取消」(筛选进行中可终止筛选任务,未运行则关闭窗口)。窗口会自动预填上次默认条件。
交互与完成流程:
- 筛选前校验:
简历文件夹与结果存储目录不能相同(选源目录后未单独选结果目录时,结果目录自动默认为源目录下的「筛选结果」子目录,避免相同);若两者被设为同一路径,点击「筛选」会立即弹窗报错、不进入筛选。 - 点击「筛选」后按钮变为 「筛选中…」(禁用),后台运行
screen_resumes.py并实时回显日志;过程中仍可点「取消」终止。 - 真实完成后:按钮变为 「关闭」(手动点击才关闭窗口,不再自动关闭);同时界面下方出现可点击的结果存储目录链接,点击即可直接打开该目录(Windows 资源管理器),便于查看
screening_report.csv/.json与命中简历;报告文件本身也会记录output_dir字段(结果存储路径)。任务以筛选完成 + 报告写入为准,无需依赖自动打开文件夹。
Pay Skill 改造(基于微信支付 Agent Pay X402,符合 SkillHub 教程 agent-pay-upgrade)
本技能已按 SkillHub 教程「升级为 Pay Skill」改造:无需重构筛选业务逻辑,仅在原服务之上叠加微信支付 Agent Pay X402 协议的支付封装,使之成为可被 Agent 按次付费调用的付费技能。封装由scripts/pay_server.py 承担,对应教程四段流程:
- 开发者签名(Developer Signature):用 SkillHub 商户中心下发的 RSA-2048 私钥对 X402 预下单
请求体做 SHA256withRSA 签名(signature_type: SKILLHUB-SHA256-RSA2048),写入 L1 的 signature字段,保证来源可信、未被篡改。
- 微信支付下单(WeChat Pay Order):调用微信支付下单接口(Native / JSAPI / H5)拿到订单标识——
Native 返回 code_url,JSAPI/H5 返回 prepay_id。
- X402 AI 预下单(Pre-order):用开发者密钥调用
POST /palmpayminiapp/clawagentpay/preorder,
换取 payment_code。
- 支付触发返回(Payment Trigger Return):未付费的
POST /screen返回 HTTP 402(兼容模式 200)WeixinPay-Required: <payment_code>头,响应体同时附WeixinPay提示块;Agent 拿到 payment_code
后调用 weixinpay_pay 向用户申请支付授权,再带 WeixinPay-Payment 头(支付证明)重试,服务端校验后触发执行 screen_resumes.py 并返回筛选报告 JSON。
付费前置检查(Pre-payment Check)
原则:绝不对注定失败的请求发起收费。 两道防线:
- 免费端点
POST /preflight(priceCny: 0):付费前先行校验——folder是否存在且服务可访问、
education / experience 取值是否合法、output 上级目录是否存在——并回报本次调用报价。返回{"preflight": "pass"} 后再发起付费调用。
POST /screen内嵌前置校验:即便跳过/preflight直接调用,服务也会在下发支付要求之前执行
同一套校验;参数不合法直接返回 400(含逐项 issues 说明),不进入支付流程、不产生任何费用。
Agent 推荐调用顺序:POST /preflight(免费)→ pass → POST /screen(402 + WeixinPay-Required)→ 用户支付授权 → POST /screen + WeixinPay-Payment(返回结果)。
退款与异常处理(Refund & Exception Handling)
| 场景 | HTTP | 是否收费 | 处理 |
|---|---|---|---|
| 参数不合法(付费前被拦截) | 400 | 否(未进入支付流程) | 响应体 issues 逐项说明,修正后重试 |
| 未付费 / 支付凭证无效或过期 | 402 | 否 | 返回 WeixinPay-Required,重新走支付流程 |
| 已支付,执行成功 | 200 | 是 | 正常返回筛选报告 |
| 已支付,业务执行失败(子进程异常退出 / 超时 / 报告缺失) | 422 | 是 → 全额退款 | 签发 X-REFUND-VOUCHER 头(开发者 RSA 私钥签名退款凭证),响应体附 refund 对象 |
退款政策:full-refund-on-failure——凡已扣费但未成功交付筛选报告的调用,一律全额退款。
本地运行(含演示模式)
PY="<你的 python 解释器>"
SKILL="<本技能目录>"
# 本地自测(自动生成临时 RSA 密钥,mock 预下单,无需真实商户)
"$PY" "$SKILL/scripts/pay_server.py" --port 8787 --mock-preorder --gen-key
# 真实接入(填入 pay_config.json 或环境变量 SKILLHUB_*)
"$PY" "$SKILL/scripts/pay_server.py" --port 8787 --config "$SKILL/scripts/pay_config.json"- 无真实商户配置时,用
--mock-preorder跳过真实预下单网络请求(返回伪payment_code),便于本地
验证 402 + WeixinPay-Required 响应形态;生产环境请提供 SkillHub 商户中心下发的developer_id / pub_key_id / private_key_pem,以及微信支付商户配置(或 static_code_url)。
- 配置文件含私钥,请勿提交或打包;可用环境变量
SKILLHUB_PRIVATE_KEY_PEM等注入。模板见
scripts/pay_config.example.json。退款凭证含支付指纹(X-Payment 的 SHA-256)、退款金额、资产、网络、失败原因、签发时间戳与开发者签名,防伪可验证;调用方 / Facilitator 凭凭证发起原路退款(发布到 SkillHub 后由微信支付 Agent Pay 履约,退款约 1~3 个工作日原路到账)。重复携带同一 X-Payment 重试失败请求不会重复扣费——支付指纹一致,Facilitator 侧幂等。
本地启动 Pay Skill 服务
"$PY" "$SKILL/scripts/pay_server.py"
--port 8787
--price 0.05
--pay-to "0x你的收款地址"
--network base
--dev-secret "你的开发者签名密钥"- 不传
--dev-secret时自动生成一次性密钥(仅本地演示)。 --pay-to/--network/--price需与 SKILL.md 的payment/endpoints[].priceUsdc保持一致;发布到 SkillHub 时替换为平台下发的微信支付商户配置(见references/skillpay-guide.md)。
x402 调用流程(Agent 侧)
Agent → POST /preflight {folder, ...} ← 免费·付费前置检查
← 200 {preflight: "pass", priceUsdc} (fail 则 400 + issues,修正后重试)
Agent → POST /screen {folder, job_title, ...}
← 402 PAYMENT-REQUIRED: <base64 x402 要求>
Agent → 完成支付授权(钱包/微信支付 Agent Pay)
Agent → POST /screen {…} + 头 X-Payment: <base64 支付证明>
← 200 {total, passed, failed, parse_error, priority, report}
(若执行失败 ← 422 + X-REFUND-VOUCHER 退款凭证,全额退款)调用前应先告知用户本次调用的价格(如 $0.05 USDC 或发布后的 ¥0.50/次)。
Endpoints
POST /preflight — priceUsdc: "0"(免费)付费前置检查:校验 folder / education / experience / output 合法性并回报报价;pass 后再付费调用。
POST /screen — priceUsdc: "0.05"请求体(JSON):folder(必填)+ output / job_title / location / education / experience / industry / domain / skills / no_copy(可选),字段含义见 frontmatter inputSchema。成功(200)返回 outputSchema 中的汇总对象;未付费(402)返回 PAYMENT-REQUIRED 头;参数非法(400)不收费;已付费但执行失败(422)附退款凭证。
调参与边界
- 简历格式千差万别,解析为启发式:若某维度识别不准,先看
--verbose输出定位;可在screen_resumes.py的EDU_RANK/EXP_OPTION_RANGE/INDUSTRY_SYNONYMS/DOMAIN_SYNONYMS中扩充关键字。 .doc不支持结构化解析,建议让用户把简历转.docx后重试。- 主条件(岗位 / base地 / 学历 / 经验 / 技能描述)为与关系(全部满足才“通过”);技能描述多关键字为或关系(所列技能在「项目经验 / 工作经历 / 专业技能(技能特长)」任一区块命中任一项即通过),且为硬性门槛——填写且未命中时一律不入选,优先项无法放宽。行业经验、业务领域为非必须满足的软条件,内部多关键字为或关系,仅用于优先排序。
- Pay Skill 服务运行在调用方可访问的网络上;本地模式下
folder为服务进程可访问的本地路径。base_url在发布时应替换为公网可访问的托管地址。