
这是什么
十三个斜杠命令把 Claude Code 变成一条求职流水线:/setup 从一文件夹材料、一份粘贴的简历或一场访谈里建出结构化画像;/scrape 通过每个招聘站各自的 CLI 技能去搜;/rank 批量给岗位打分;/apply 跑一对起草者与审阅者,写出 LaTeX 简历与求职信、编译、检查渲染后的页面,再像简历筛选系统那样去读 PDF 的文字层。随仓库附带六个招聘站技能——四个面向丹麦市场,加上不限地区的 LinkedIn 与 freehire——而 /add-portal 能生成新的。它从不提交任何申请。
谁做的本是地球物理学家,2025 年底岗位被撤。他做出这套框架来跑自己的求职,每周用在自己的职业生涯上,并在 README 里报告结果:六十九份定制申请、二十次一面、一份签下的合同,2026 年 6 月入职做 AI 工程师。他对每一个谈过的雇主都说明了申请材料有机器参与,并写道这通常引来一场技术对话,而不是成为减分项。293 次提交里他写了 108 次,至今仍然自己审每一条 pull request。
它是怎么搭起来的
组成 · 6没有服务端、没有数据库、也没有构建步骤。这套框架是一组让通用编程 agent 去读的 Markdown 指令、一组它去调用的小型命令行程序,以及一个存放状态的普通文件夹——一张申请记录 CSV、一份已看过岗位的 JSON、每个投出的申请一个目录。/scrape 靠形状而不是注册表来发现招聘站工具:技能目录下任何一个暴露 search 与 detail、并遵守约定输出契约的文件夹都会被收进来,所以新增一个招聘站就是新增一个文件夹,永远不用改框架本身。哪些写成指令、哪些写成程序,分界线落在「什么必须精确」上——抓一个招聘站、数一份编译后 PDF 的页数、提取 PDF 的文字层,都是带离线测试的真程序;而评估匹配度、把十年的经历组织成一段叙述,是指令。让整件事能跨会话续上的正是那些状态文件,而它们是用户自己仓库里的普通文件,不属于框架。
- .claude/commands/
- 十三个 Markdown 文件,一个斜杠命令一个——工作流本身。
/setup、/scrape、/rank、/apply是核心回路;其余负责面试准备、结果归档、不依赖日历的跟进,以及报告生成。 - .claude/skills/job-application-assistant/
- 判断层:一份技能文件加七份编号参考,覆盖候选人画像、行为画像、写作风格、匹配度评估标准、简历与求职信规则,以及面试准备。「绝不编造经历」这条规则就落在这里。
- .agents/skills/<portal>-search/
- 每个招聘站一个自包含文件夹——一份技能文件、一个带源码与自有测试的
cli/,再加一份 URL 参考。随仓库附带六个:四个丹麦招聘站,加上 LinkedIn 与 freehire。每一个都零运行时依赖,测试套件在断网时也全绿。 - tools/
- 机械检查:编译后 PDF 的页数与文字层提取、一个报告空洞/孤立条目/页脚碰撞的排版测量工具、为可选的浏览器请求头重试把关的 robots.txt 闸门,以及维护权限白名单与 gitignore 规则的守卫。
- LaTeX 工具链
- 简历用
lualatex编译 moderncv 模板,求职信用xelatex编译一个自定义文档类——因为后者的类需要fontspec。有一个注册命令可以把任一者换成别的、能从命令行编译出 PDF 的工具链,模板以占位符形式存放,因此不带任何个人数据。 - 状态文件
job_search_tracker.csv记申请,一份 JSON 记已看过的岗位用于去重,每个投出的申请一个目录、存放当时的简历、求职信与职位原文,另有一份邮件读取的同步状态。纯文本,在用户自己的仓库里,不用这套框架也能读。
取舍,以及它替代了什么
招聘站技能靠手工拷进来 替代 一个从别人 fork 里自动抓取的安装器
已安装的技能本来就被允许在每次调用时免确认运行,所以自动安装器会跳过唯一真正要紧的那道检查——使用者自己先读一遍代码。README 明确说没有安装器是一个安全决定,而不是缺失的功能。
整条工作流停在提交之前那一步 替代 针对申请表单的浏览器自动化、保存招聘站凭证、会自动投递的调度器
维护者称这条线是刻意划的、且是长期的,并以这个理由关掉了一个贡献来的多人 Web 应用——不是因为质量。
每个招聘站一份统一契约,靠形状被发现 替代 注册表,或一个带各站分支的抓取器
不改框架就能扩展,而一份地区 fork 只要拷一个文件夹就能分享。让这件事安全的是契约本身:结构化输出、诚实的 user-agent、被限流时退避,以及站点拦下诚实 UA 时拒绝退回浏览器 UA。
上游以打了 tag 的 release 抵达,并带一步预览 替代 直接拉上游分支
每个使用者都改过自己的副本——画像文件、评估标准、自己写的招聘站技能——所以一次合并是涉及个人数据的操作。一个工具预览某次更新会动到哪些个性化文件,另一个把进来的提交分成「值得看」与「大概可跳过」。
依据README 的文件结构一节、扩展点一节,以及 CONTRIBUTING.md。
制作过程
7 个阶段- 01
它让作者拿到了工作
README 用作者自己的求职回答了读者最先要问的那个问题。他本是地球物理学家,2025 年底岗位被撤;他做出这套东西来跑自己的申请,用的是仓库里同一套
/scrape、/apply和/interview流程,每周一次,用在自己的职业生涯上。他报告的数字是六十九份定制申请、二十次一面、一份签下的合同,并在 2026 年 6 月入职做 AI 工程师。他还补上了大多数项目会略过的那一段——他对每一个谈过的雇主都说明了申请材料有机器参与,而这通常引来一场真正的技术对话,而不是成为减分项。这些是作者本人的数字,本档案没有核实过;值得记下来的原因在于:它们恰恰是这套项目自己的方法会要求出处的那类主张,而 README 把它们写成一段个人自述,不是一份基准。 - 02
一万五千个 fork,以及它带来的那个陷阱
分发方式就是 fork。README 的第一条指令是把这个仓库 fork 下来、填好自己的画像、然后拥有它;44,451 星对应 15,313 个 fork,这个比例在本档案里没见过第二个。设计是自洽的——每个人都该改自己的副本,上游更新以打了 tag 的 release 抵达,并有一个脚本先预览某次合并会动到哪些个性化文件。它同时制造了一个仓库自己写明的问题:一个警告块说,公开仓库的 fork 永远都是公开的,GitHub 不提供私有 fork,而
/setup会把你的姓名、联系方式、工作经历与薪资期望写进被版本跟踪的文件里。于是 README 推荐给所有人的那条路径——fork、克隆、填进去——恰恰不适合它真正面向的那个人。正确的做法是建一个私有仓库、把这个仓库加成upstream,而这份两分钟的配方写在另一份文档的第八节里。一个项目自己的上手说明是次优选项、并且明说这件事,并不常见。 - 03
让它不一样的那一步:它真的去看 PDF
一份 LaTeX 简历可以在源码里完全正确、在页面上完全错误——职位名被孤零零推到下一页、求职信溢出到第二张纸、图标字体没能展开时列表项目符号悄悄退回正文字体。所以
/apply会用lualatex编译简历、用xelatex编译求职信,然后读渲染出来的页面并反复修改,直到简历严格两页、没有孤立的条目,求职信严格一页、签名可见。接着它还会再走一步:检查文字层而不是画面,因为筛选系统解析的正是文字层——联系方式以字面文本存在、没有乱码字形、阅读顺序正常,以及按解析器实际提取到的内容算出关键词覆盖率。诚实规则写在流程里:画像真正支持的关键词才补进去,真正的缺口留着可见,而不是硬塞进去。简历超页时的删减也不是从最老的一段开始,而是逐行按「与这份岗位的相关度、在文档里的独特性、求职信是否依赖它」打分,先删总分最低的那行。Language Gate 对语言做同样的事:要求一门画像里完全没声明的语言的岗位直接拒掉,而在你确实会的一门语言上要求高于你所报等级的,只标出来交给你判断,不会静默丢弃。 - 04
一个 bug 修复围绕 Unicode 与 Windows 的追踪器
项目的真实工程功底体现在 issue 区,而一连串已合并的 pull request 读下来是同一个主题。有贡献者报告说,追踪器的归一化把公司名与职位名转成小写、然后删掉
[a-z0-9]之外的一切——这让两个没有 ASCII 形式的字符都归一化成空字符串,于是一家公司里已经记录过的申请被重新排名,而一个名字会被归一化没的公司顺带把它名下的无关职位一起带出候选列表。同一个过滤器还让预组合的Café与分解形式的Cafe加组合重音互不相等。修法是归一化后保留组合记号,而维护者单独点出用来证明这一点的那组用例,是一对只差一个这种记号的天城文词。配套的一条修的是岗位键:任何没有 ASCII 缩写的公司名都会变成字面量unknown-company,于是两家不同公司配同一个拉丁文职位名会产出同一个键,第二条职位被当成已经看过。再下一条:六个工具把含非 ASCII 字符的 JSON 原样打到管道标准输出上,而 Windows 的管道默认走 ANSI 代码页,于是任何一条西里尔文、中文或天城文的职位都会让工具当场崩掉。维护者在那一轮留言里点明了它为什么能活这么久——持续集成只有 Linux,而管道正是 agent 运行每个工具的方式——所以这一整类 bug 对那套本该抓住它的测试完全不可见。 - 05
一条硬规则,而整条工作流里没有任何机械检查在跑它
追踪器里最好的一条 issue,讲的是一次谁也没执行的「推迟」。仓库里有两个地方写着页数限制是某个校验工具的职责、而另一个步骤已经在跑它了——一处写在工作流文档里,另一处写在排版检查工具的文档字符串里,后者还补了一句持续集成也在跑。有贡献者把整个仓库搜了一遍,找那个工具带页数参数的所有调用,结果只找到参数定义、那两处散文式推迟,以及一条只覆盖示例文档的 CI 断言。工作流里没有任何一个真正会跑的步骤传了这个参数。 于是简历的两页上限、求职信的一页上限,实际是由模型看着一张图判断出来的,而机械检查就在手边、没被调用。修法补上了那两处调用和四个测试;维护者拿编译好的示例文档确认,并说明此前是什么在独自扛着这条规则。这是一种值得点名的失败:一个整个主张就是「说法必须可核」的仓库,检查存在、文档说它在跑、而它没跑。
- 06
它不会越过的那条线
有一个 pull request 送来一个完整的多人 Web 应用——后端、前端、按账号隔离、口令哈希、给每个用户独立轮转的调度器。维护者关掉了它,理由是整个追踪器里最有意思的一句话:这个模板会准备好一份申请,然后永远停在发送之前那一步。 不用浏览器自动化去操作申请表单、不保存招聘站凭证、没有会自动投递的调度器。他说这条线是刻意划的、且是长期的。同一套政策贯穿那些招聘站技能:被机器人防护拦下的 CLI 默认不会伪装成浏览器——它报告被拒,并把使用者引向一份写好的手动流程;有贡献者做的技能里,云防护拦截这件事被如实写出来,并请求保留那个诚实的 user-agent。它也解释了一个本来会被当成缺失功能的设计:这里刻意没有安装器去从别人的 fork 里拷招聘站技能,因为已安装的技能本来就被允许免确认运行,所以自动安装器会跳过唯一真正要紧的那道检查——使用者自己先读一遍代码。这也是为什么一批质量完全合格的招聘站技能被拒了:针对某个行业的站点,维护者写道,会让人没有原则性的理由去拒绝下一个行业,这与按国家划分的站点得到的是同一个回答。而其中一条 PR 还会把贡献者自己的岗位取舍——一份点名三维美术类职位、排除高级职位的清单——写进共享的抓取技能里,那会加载进每一个使用者的搜索,不管他是什么领域。
- 07
三月一次提交,七月一百二十三次
按月提交数比任何总结都更能说明这个项目的走向:三月 1 次、四月 12 次、六月 3 次,然后七月 123 次、八月 107 次、九月 47 次。这个拐点有确切的日期。2026 年 7 月 10 日,它登上 GitHub 趋势榜首位,一天涨了 3,700 多星、总量到 17,700,第二天早上就有一篇中文开发者社区专栏介绍了它的画像系统、起草者与审阅者那一对,以及 PDF 检查回路。在那之前,它是一个能用、提交寥寥的个人工具;十二天后它有了第一个打了 tag 的 release
v1.0.0,到九月已经有九个——每一个的标题都是一句主张而不是一个版本号,从「Language Gate 与对 ATS 安全的日期字段」,到「能抵达你的 fork 的上游、藏不住的钩子」,再到「更便宜的排名、会大声失败的招聘站、不再跟 CI 打架的 fork」。九个全是正式发布,没有一个是预发布。此后有五十位贡献者碰过它,多数只提交一次,而留下来的那两位,名字就出现在上面那些修复里。
相关档案
全部档案 →第 061 号
DeepSeek Harness
DeepSeek 的 agent 运行框架:模型适配器、工具注册表、会话日志、乃至 agent loop 本身,全都是插件——换掉它们靠的是改配置文件,而不是分叉源码。
第 060 号
VibeGame
用一句话描述一个游戏,一队 agent 就分头开工——架构师做计划、程序员实现、审计员拿代码对计划、而必须有一个「玩家」真的把它玩过,任务才算验收。
第 054 号
gate4agent
一套 Rust 工作台,用来跨机器运行、观察和编排命令行编码 agent——把 Claude Code、Codex、Kimi 和 Grok 包在同一个传输层、同一个中继和同一个操作协议后面。