尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

career-ops 公司黑名单(do-not-apply list)实战:从模板配置到扫描拦截机制全解析

career-ops 公司黑名单(do-not-apply list)实战:从模板配置到扫描拦截机制全解析 career-ops 公司黑名单do-not-apply list实战从模板配置到扫描拦截机制全解析【免费下载链接】career-opsOpen-source AI job search: scan job portals, evaluate listings into a structured A-H report with a global 1-5 score, tailor your CV, track applications — runs locally in your AI coding CLI (Claude Code, Codex, OpenCode, Antigravity…)项目地址: https://gitcode.com/GitHub_Trending/ca/career-ops本文围绕 career-ops 开源项目中templates/blacklist.example.md这份「公司黑名单」配置模板展开系统讲解它的设计意图、安装启用方式、表格式写法、扫描过滤与模式守卫的实现原理。读完你就能在自己的求职数据目录下搭建一套完全自主掌控的 do-not-apply 名单并理解它为什么被设计成「只拦截、不打分」的用户层门禁。全文的每一处行为描述均可在仓库对应源码与文档中找到证据。1. 什么是 Company Blacklist一份属于你自己的「不要投」名单在 AI 求职工具 career-ops 的流水线里scan.mjs会批量扫描职位门户、auto-pipeline/apply等模式会围绕结果自动推进申请动作。但找工作这件事高度私人化——某些公司你可能因为面试流程信号差、多次投递零转化、价值观不合、已在前东家发生纠纷等原因明确不希望系统再帮你投递任何岗位。templates/blacklist.example.md正是为这个场景提供的模板。它定义了一份「用户自己的 do-not-apply 名单」Your own do-not-apply list并有三条铁律用户层user layer、可选启用opt-in系统永远不会替你创建或填充这份文件升级更新也不会触碰它只拦截、不打分一个黑名单条目绝不会改变任何职位的评分a gate, not a signal你的决定永远有最终话语权自动模式撞上黑名单公司会停下来征询你的显式放行。这一设计把「数据归属权」从工具手里交还给你——名单内容属于用户层数据与简历、追踪表等用户数据一样跟随你的数据根目录存放。2. 安装与启用复制模板即可系统不代劳启用黑名单不需要任何配置项开关唯一的动作是把模板复制到数据目录下的约定位置# 将模板复制为数据根目录下的 data/blacklist.md相对仓库根目录 cp templates/blacklist.example.md data/blacklist.md启用条件与位置在源码中有明确实现见 scan.mjsconst BLACKLIST_PATH path.join(DATA_ROOT, data/blacklist.md);其中DATA_ROOT getCareerOpsRoot()导入自 path-resolver.mjs见 scan.mjs即整个用户数据层data/、reports/等的根目录。loadBlacklist()的实现如下export function loadBlacklist(filePath BLACKLIST_PATH) { if (!existsSync(filePath)) return new Map(); // 文件不存在 空表 完全不拦截 return parseBlacklist(readFileSync(filePath, utf-8)); }两个关键结论可以从源码确认文件缺失时行为是 no-op没有黑名单文件 空 Map 扫描行为与无此功能时逐字节一致源码注释原文 the scan stays byte-identical to a pre-#1742 run路径跟随 data root 而非当前目录源码注释#3510指出早期版本用裸相对路径解析会导致用户在配置了 data root 后运行目录里没有黑名单文件时静默失效现在锚定到数据根目录后无论从哪个目录启动扫描都能读到同一份名单。3. 表格式写法Company / Since / Scope / Reason 四列逐列拆解模板的内容是一张四列 Markdown 表格这就是整个配置的语法CompanySinceScopeReasonAcme Corp2026-01-15companyexample: post-interview process signalsGlobex2026-02-01companyexample: repeated applications, zero conversion解析逻辑在 scan.mjs 的parseBlacklist()中逐行按|切分单元格规则如下列位含义解析规则源码确认Company公司名将作为唯一匹配键cells[1]为空、是纯- :分隔行、或等于表头company的行都会被跳过Since记入黑名单的日期cells[2]建议 ISO 格式如2026-01-15仅作归档参考Scope作用范围cells[3]模板示例为company公司级当前解析阶段仅记录、不改变行为Reason拦截原因cells[4]会被原文引用——自动模式停顿时会quote your recorded reason展示给你解析层还有两个值得注意的细节匹配键做归一化key normalizeCompany(company)重复键时第一行胜出first row wins也就是说同家公司写多行只有首次出现的条目生效不写任何额外的元语法整个表格没有作用域符号、没有通配符保持人类可读、可手写维护的朴素风格。4. 匹配原理为什么 Acme Corp. 能拦住 acme corp 的职位模板和源码反复强调匹配是case- and punctuation-insensitively忽略大小写与标点。背后是 tracker-utils.mjs 中所有追踪脚本共享的normalizeCompany()/** * returns {string} Case-folded, punctuation-free, script-preserving key. */ export function normalizeCompany(name) { return normalizeTextKey(name); }注释明确点出了设计动机折叠大小写、剔除标点所以黑名单里写Acme Corp.ATS 源里出现acme corp也能命中merge-tracker 去重、set-status/outcome 行解析、company-history 分组与 scan 黑名单共用同一把稳定钥匙保留非拉丁文字script-preserving这是对早期实现[^a-z0-9]粗暴过滤的修复——此前日文アクメ株式会社、グロベックス合同会社与Яндекс都会被折叠成空串而彼此相等merge-tracker 会把不同公司的申请当成同一行静默覆盖#2429。现在只有非空的公司名才能形成有效键且不同书写系统不会互相误伤。因此在使用上可以放心写你记忆中的公司拼写例如Apple Inc.、Yandex、アクメ株式会社匹配由共享的归一化函数兜底。5. scan.mjs 中的拦截行为计数、摘要与--include-blacklisted审计通道当data/blacklist.md存在时主扫描器 scan.mjs 的处理顺序非常清晰黑名单检查发生在信任度富集之后、标题/层级/地点等常规过滤器之前且被明确标注为公司级决策而非单条帖子的信号见 scan.mjsif (blacklist.size 0) { const blEntry blacklist.get(normalizeCompany(job.company || company.name || )); if (blEntry) { if (!includeBlacklisted) { totalFilteredBlacklist; // 计数被黑名单跳过的帖子 continue; // 直接跳过该职位 } annotatedBlacklisted; // --include-blacklisted 审计路径 job.blacklisted true; const label blacklisted${blEntry.reason ? : ${blEntry.reason} : }; job.note ... // 把 blacklisted: 你的原因 前缀合并进 note } }对应地在运行摘要summary里会有明确输出见 scan.mjsBlacklisted: N skipped (blacklist) # 或启用 --include-blacklisted 时 Blacklisted: N let through annotated (--include-blacklisted)并会被写进data/pipeline.md/ 结果行。还有三处与摘要相关的细节值得注意统计持久化filtered_blacklist是 scan.mjs 中SCAN_RUNS_HEADERdata/scan-runs.tsv的正式列之一因此趋势统计stats.mjs等消费方能持续追踪被黑名单拦下的数量而非只存在于终端输出带原因注释verbose 列表输出会为放行但命中黑名单的条目追加[BLACKLISTED — on your do-not-apply list]见 scan.mjsCLI 逃生门--include-blacklisted的作用是让命中黑名单的帖子以注释形式流过而非过滤掉专门用于审计——你可以借此确认某个公司为什么被拦、或临时检查匹配是否过宽而不用删改名单。帮助文本中的完整命令形态见 scan.mjsnode scan.mjs --include-blacklisted # let data/blacklist.md matches through (annotated)6. 反向扫描 scan-ats-full.mjs 与其它模式同一门禁处处生效ATS 全量反向扫描scan-ats-full.mjs也内置了同一套用户层门禁复用黑名单文件的解析逻辑通过filterBlacklistedOffers()见 scan-ats-full.mjs对每个源的结果做过滤行为与scan.mjs完全对称空表 no-op默认跳过的被计数、绝不静默--include-blacklisted时保留命中条目并把blacklisted: {reason}合并进 note 供审计运行日志同样输出Blacklisted: N skipped (blacklist)/N let through annotated见 scan-ats-full.mjs并把postingsFilteredBlacklist、postingsAnnotatedBlacklisted写入 JSON 结果见 scan-ats-full.mjs。命令行形态为见 scan-ats-full.mjsnode scan-ats-full.mjs --include-blacklisted # audit: let data/blacklist.md matches through, annotated自动流水线模式同样尊重这份名单auto-pipeline、oferta、apply模式文档位于 modes/auto-pipeline.md、modes/oferta.md、[modes/apply.md)在命中黑名单公司时会停下来引用你记录的 Reason并要求显式覆盖override后才继续——Your call always wins即最终决定权始终在你手中这是模板原文对该模式行为的承诺。7. 最佳实践与常见疑问FAQ 视角官方 FAQ 对该功能给出了同款简要指引结合前文源码证据可以沉淀出以下实操建议启用三步走复制模板 → 按需删掉示例行Acme/Globex 仅作演示→ 写入你真实的不要投公司。模板中的示例条目不会自己生效因为系统从不替你创建data/blacklist.md写 Reason 一定认真填它不只是备忘——自动模式停顿时会把原因原文展示给你做是否显式放行的判断依据--include-blacklisted审计时它也会进入 note想临时放行不要改名单使用--include-blacklisted审计开关让命中项带注释流过、保留统计计数比反复增删名单更安全可追溯维护说明见 SCRIPTS 文档完整行为与受支持工作流的官方汇总位于 docs/SCRIPTS.md 的 Company blacklist 章节#1742其中同样强调没有黑名单文件 不拦截没有任何机制会自动往名单里添加公司善用 Since 列做定期复盘例如每季度清理一次超过 12 个月且已无后续问题的条目避免名单随时间失真。一句话总结这套机制的心智模型黑名单是一道位于评分之前的纯拦截闸门——它不参与、不影响任何 A–H 报告的分值或 1–5 分评估只负责在扫描与自动申请管线里替你守住哪些公司绝不自动触碰的边界并把每一次拦截都变成可见的统计与一次可覆盖的人类决策。【免费下载链接】career-opsOpen-source AI job search: scan job portals, evaluate listings into a structured A-H report with a global 1-5 score, tailor your CV, track applications — runs locally in your AI coding CLI (Claude Code, Codex, OpenCode, Antigravity…)项目地址: https://gitcode.com/GitHub_Trending/ca/career-ops创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表