一、导读
GitHub 前一日涨星榜(截至 2026-10-18)第一名是 VoiceStudio,但本站 10 月 14 日刚发过;跳过它之后,当日涨星最高的合规大模型应用项目是 MadsLorentzen/ai-job-search(当日 +1397,总星 49658)。它不是又一个「AI 帮你写简历」的套壳网页,而是一套跑在 Claude Code 上的完整求职工作流:13 个斜杠命令覆盖从职位抓取、匹配打分、定制投递、面试准备到结果追踪的全流程,全部数据留在本地,MIT 协议,fork 即可拥有。作者是一位被裁员的地球物理学家,用自己写的这套框架投了 69 份定制申请、拿到 20 场初面和 1 份合同,2026 年 6 月上岗 AI 工程师——这个故事本身就是它涨星的最大动因。
二、项目速览
| 项目 | 数据(截至 2026-10-18) |
|---|---|
| 仓库 | MadsLorentzen/ai-job-search |
| 当日涨星 / 总星 | +1397 / 49658 |
| Fork / Watch | 16822 / 184 |
| 创建时间 | 2026-03-18 |
| 最新版本 | v1.7.2(2026-09-29),v1.0.0 于 2026-07-22 |
| 协议 / 语言 | MIT;Python(工具脚本)+ TypeScript(职位门户 CLI,Bun 运行时) |
| 核心贡献者 | MadsLorentzen(110 commits)、ayobamiseun(63)、oscarbol09(31) |
| 形态 | 无可执行主体:一组 Markdown 工作流资产 + CLI 工具 + LaTeX 模板,挂载到 Claude Code 运行 |
| 运行前提 | Claude Code 订阅(Pro/Max 或 API 按量)、Python 3.10+、Bun、LaTeX 工具链 |
先说清楚它的形态,这决定了后面所有架构讨论的坐标系:这个仓库里没有「主程序」。没有 server、没有 daemon、没有 GUI,甚至没有一个入口脚本。它交付的是三类东西:.claude/commands/ 下 13 个斜杠命令定义(Markdown 写的工作流编排)、.claude/skills/ 下的技能知识库(评分框架、写作风格、模板规则)、.agents/skills/ 下 6 个职位门户 CLI 工具。当你敲下 /apply <url>,真正执行的是 Claude Code 的模型按照这些 Markdown 里写死的步骤编排,调用 LaTeX 编译器、PDF 校验脚本和门户 CLI 完成一次完整的投递生产。这是「提示词即程序」路线走到极致的一个样本——后面会看到,作者为了对抗这条路线的天然缺陷(不可预测、易被注入、事实漂移),设计了相当多的工程约束。
三、为什么是它:涨星动因
第一动因是真实故事的可信度。README 开头没有堆功能清单,而是作者第一人称的自述:地球物理学家,2025 年底岗位被裁,用自己写的这套框架跑自己的求职——「每周用,用在真人身上」,69 份定制申请、20 场初面、1 份合同,2026 年 6 月入职 AI 工程师岗位。他甚至在每次面试中主动坦白用了 AI 框架,结果这通常引发了 genuine technical conversation 而不是减分。在 AI 求职工具普遍被质疑「海投垃圾简历」的舆论环境里,一个带真名、带 LinkedIn 可查、带可复盘数字的案例比任何 benchmark 都有传播力。
第二动因是赛道顺风。看当日涨星榜前排就能发现:ECC(agent harness 优化,+1145)、stablyai/orca(智能体舰队平台,+829)、anomalyco/opencode(编码智能体,+576)、ruvnet/ruflo(多智能体 swarm,+406)清一色是 Claude Code 生态项目。Claude Code 的斜杠命令 + 技能文件 + 子代理派生这套机制在 2026 年已经成为「个人自动化」的事实标准,而 ai-job-search 是这个标准上第一个跑通完整垂直场景(求职)并且以工程严谨度出圈的项目,生态流量自然外溢到它身上。
第三动因是隐私与主权的差异点。「fork it and own it」——框架本体公开,个人数据(profile、tracker、薪资数据、投递档案)全部 gitignore 留在本地,文档明确写着 documents never leave the machine by design。这与 SaaS 求职工具把简历数据喂给云端形成直接对照,在求职者对数据滥用高度敏感的当下是个精准的卖点。HN 上的曝光其实很小(三次提交都是 1-2 分的小帖),这轮涨星主要靠 trendshift 榜单与 LinkedIn/社交媒体的口口相传,是典型的社区自发扩散曲线。
四、架构原理

整体架构:五层工作流资产
graph TB
subgraph User["用户交互层:13 个斜杠命令"]
CMD["/setup /scrape /rank /apply<br/>/interview /outcome /gmail-sync<br/>/expand /upskill /html-report<br/>/notion-sync /add-template /add-portal"]
end
subgraph Orchestration["编排层:Claude Code"]
D["Drafter 主代理<br/>(持有 profile 与模板上下文)"]
R["Reviewer 子代理<br/>(fresh context,专司批判)"]
end
subgraph Knowledge["知识层:job-application-assistant 技能文件"]
K1["01 候选人档案"]
K2["02 行为画像 PI/DISC"]
K3["03 写作风格"]
K4["04 职位评分框架 v1.2.6"]
K5["05/06 CV 与求职信模板"]
K6["07 面试准备 STAR 库"]
end
subgraph Tools["工具层"]
T1["6 个门户 CLI(Bun)<br/>jobindex / jobnet / jobbank<br/>jobdanmark / linkedin / freehire"]
T2["verify_pdf.py / verify_layout.py"]
T3["salary_lookup.py<br/>pdftotext / pypdf"]
end
subgraph Data["数据层(本地,全部 gitignore)"]
D1["documents/ 投递归档"]
D2["job_search_tracker.csv"]
D3["company_research/ 缓存(TTL)"]
D4["seen_jobs.json"]
end
CMD --> D
D -- "Step 3 派生" --> R
K1 --> D
K4 --> D
D --> T1
D --> T2
D --> T3
T1 --> D4
D --> D1
D --> D2
R --> D3
五层自上而下:用户只面对斜杠命令;编排层是 Claude Code 里的 drafter 主代理,它在需要批判视角时派生一个 fresh context 的 reviewer 子代理;知识层是七份技能文件,其中 01-candidate-profile.md(候选人档案)与 04-job-evaluation.md(评分框架,frontmatter 标注 framework_version 1.2.6,文件改动必须联动 bump 版本号,由 CI 强制)是两个中枢;工具层把模型不擅长的活外包给确定性程序;数据层全部留在本地。
这个分层里最值得注意的设计是事实权威三源制度:CV 和求职信里的每一个事实,都必须能被三个文件之一直接支撑——01-candidate-profile.md、主 CV 模板 cv/main_example.tex、CLAUDE.md 的候选人档案段。配套有一条「Standing rule」:用户在对话中确认或补充的任何新事实(一个量化指标、一段项目细节),必须当轮写回 01-candidate-profile.md。apply.md 里对这条规则的理由写得很直白:审计环节无法区分「捏造」和「用户上周口头说过但没记录」,它只能一律删除——不写回,真实成就就会在后续某次投递中静默消失。
核心机制一:drafter-reviewer 双代理分离
/apply 是整个框架的核心,一个八步流水线。第 1-2 步由 drafter 完成职位评估与起草;第 3 步用 Agent 工具派生一个 reviewer 子代理,以全新上下文扮演「招聘经理代理人」:它先查 company_research/<规范化公司名>.json 的 TTL 缓存决定是否需要重新调研公司(verify-before-use 原则,搜索只从用户确认的公司名出发,绝不从职位描述里的链接出发),然后对照候选人的行为画像(PI/DISC)检查求职信的语气是否失真——一个「Collaborator」型人格不应该被写出 solo-hero 的进攻性文风。
reviewer 的输出被强制分为两部分:Part A 是结构化编辑,一个 JSON 数组,每条带精确的 old_string/new_string/reason,drafter 用 Edit 工具直接套用,不需要重读文件;Part B 是叙事建议,按遗漏关键词、公司角度、行动化改写、语气问题四类归档,留给 drafter 用判断力处理。第 4 步 drafter 修订,并有一条硬规则:任何会导致虚构技能或经验的建议一律不采纳,真实缺口用「honest bridge」(诚实的桥接表述)呈现。
这套分离的工程价值在于对抗 LLM 的自恋盲区:同一个上下文里的模型很难批判自己刚写的东西,fresh context 的 reviewer 没有 drafter 的沉没成本,更容易发现遗漏关键词、平淡的框架和泛化措辞。配套还有三条 token 效率规则:草稿以 inline 方式塞进 reviewer 的 prompt 而不是让它重读文件;验证清单只在流程末尾跑一次,reviewer 专注内容批判不做验证;已读文件绝不重复读取。
核心机制二:双门 + 五维评分
/rank 与 /apply 的评估环节共用 04-job-evaluation.md 定义的评分体系,它在打分之前先跑两道硬门:
- Eligibility Gate(资格门):逐字读职位的工作权限条款并分类。明确要求公民身份/永久居留 → FAIL,不评分不起草,引用原文回给用户;要求安全审查(security clearance)→ 多数国家 FAIL;明确欢迎国际申请人 → PASS;条款沉默 → PROCEED 但标记 unverified。文档特别强调两条易错规则:silence is not permission(大公司毕业生项目常在官网而非广告里设籍贯门槛),公司级「欢迎国际申请人」不等于岗位级许可(常见模式是总声明后面跟一张覆盖项目清单)。
- Language Gate(语言门):对职位以工作条件形式要求的语言做三值判定——完全没申报的语言 → FAIL 硬停;申报了但职位门槛(fluent/C1)可能高于申报水平 → FLAG 但继续评分,把两边原文都亮给用户裁决;门槛不高于申报水平 → PASS。判定纪律明确写着:拿不准时倾向 FLAG,人是 tiebreaker。
过了双门才进入五维加权评分:技术技能匹配 30%、经验匹配 25%、行为/文化匹配 15%、职业一致性 30%,地点与后勤是 pass/fail 不进权重。综合分对应五档结论:75+ Strong Fit(全力定制)、60-74 Good Fit(投,但求职信里正视缺口)、45-59 Moderate(与用户商量)、30-44 Weak(除非有战略理由否则跳过)、<30 直接跳过。/rank 把这套体系批量化:并行代理逐条抓取职位、五维打分,deal-breaker(写进 profile 的自由格式硬条款,如「不 on-call」「最低薪资 X」)一票否决,截止日期临近打 urgent 标,已过期标记 expired,最后输出带排序的 shortlist。
核心机制三:PDF 编译验证循环与 ATS 文本层检查
第 5 步在 apply.md 里被标注为 mandatory and non-skippable,理由是「源文件看着没问题不等于 PDF 没问题」:分页决策不可预测,常见的失败模式包括职位标题与内容条目被分页拆散(orphaned entry titles)、求职信溢出到第二页、列表项字体静默回退。流程是先编译(CV 用 lualatex——pdflatex 在新版 MiKTeX 上会因 fontawesome5 字体扩展报错;求职信用 xelatex——cover.cls 依赖 fontspec),然后「measure first, then look」:verify_layout.py 先量化版面(空洞比例、孤行、页脚碰撞——一次视觉检查看不出「这页有 40% 是空的」),再由模型读渲染页面做迭代修补(\needspace、\enlargethispage、字体包装器),直到 CV 恰好 2 页、求职信恰好 1 页且签名可见。
第 6 步做 ATS(简历解析系统)检查,方向更刁钻:ATS 读的是 PDF 内嵌文本层,不是渲染页面,而 LaTeX 可能产出文本层完全乱掉的 PDF——图标字形占了邮箱的位置、双栏布局导致行序交错。流程用 pdftotext(或可选的 pypdf)提取文本层,按解析器的视角验证联系方式以字面文本存在、无乱码字形、阅读顺序合理,再对职位关键词做覆盖率评分。配套一条诚实规则:profile 真实支撑的关键词才补入,真实缺口保持可见,never stuffed。
还有一处容易忽略的精细设计:CV 超 2 页时不是机械地从最老的段落砍,而是对每条 bullet 按「与目标职位的相关性 × 在文档内的唯一性 × 是否被求职信依赖」打分,最低分先裁——于是一条命中职位关键词的老岗位经历能活下来,一条不相关的新经历先被牺牲。
与同类架构路线的差异
把「让 ChatGPT 帮我改简历」称为路线 A:单轮、无状态、无验证,输出质量完全依赖用户当场粘贴的上下文,产出是否排版破碎、是否虚构经历全凭运气。ai-job-search 是路线 B:把简历当数据产品管理——profile 是唯一事实源,评分框架带版本号,产出经过编译验证和文本层检查,投递历史归档可审计。当日同榜的 ECC 做的是给 agent harness 本身做性能优化(skills/instincts/memory),是横向基础设施;ai-job-search 则证明垂直场景深耕 + 工程纪律也能撑起一个 5 万星项目。它的可复用资产其实不是求职本身,而是那套「untrusted input 处置 + 事实权威源 + 产物级验证循环」的工作流模式——任何要拿 LLM 生成正式文档的场景(法律文书、标书、报告)都能照搬。
五、应用场景
场景一:批量职位筛选与定制投递
痛点:招聘平台上每天刷出上百个职位,人工逐个读 JD、改简历、写求职信,一份认真定制的申请要花一到两小时,多数人的实际做法是海投同一份简历,回复率惨淡。
如何解决:/scrape 驱动 6 个门户 CLI 并行搜索(结果自动去重),/rank 对新抓职位批量跑五维评分生成 shortlist(每个职位给出诚实的优势与缺口、deal-breaker 否决、deadline 紧迫标记),选中一条直接进入 /apply 八步流水线,产出针对该职位定制、编译验证过、ATS 可解析的 CV 与求职信 PDF。
最小示例:
gh repo fork MadsLorentzen/ai-job-search --clone
cd ai-job-search && python3 tools/install_portal_clis.py
claude # 进入 Claude Code 后:
# /setup # 建档:喂 documents/ 目录、粘贴 CV 或走访谈
# /scrape # 多门户搜索并按匹配度排序
# /rank # 批量评分出 shortlist
# /apply https://jobindex.dk/job/1234567
收益与量化:作者本人的漏斗数字是 69 份申请 → 20 场初面(约 29%)→ 1 份合同,且全部申请在面试中主动披露由 AI 框架生成。单份申请的边际时间从小时级降到分钟级(等待编译与审稿),质量却优于海投模板。
适用边界:内建门户面向丹麦市场加两个跨国源(LinkedIn 公开接口仅限个人低频使用,自动化访问违反其服务条款;freehire 聚合器为公开 REST API)。LinkedIn 等有反爬墙的站点请不要放量;不适合需要内部推荐制、猎头渠道为主的岗位市场。
场景二:面试准备与模拟对练
痛点:拿到面试后,候选人往往只记得自己「投了什么」,不记得对方「读到了什么」——各轮面试官看的其实是归档里那份特定的 CV 版本。
如何解决:/interview 从投递档案构建阶段特定的 prep pack:当时那版 CV、求职信、前几轮反馈、原始 JD,然后用 verify-before-use 规则调研公司与面试官,把可能的问题映射到你 profile 里的 STAR 案例库,最后按 07-interview-prep.md 的角色扮演协议做 mock interview。关键纪律:经历缺口给诚实的桥接答案,never invented experience。
最小示例:tracker 里有在途申请后,直接 /interview,它会列出待面申请让你选。
收益:准备材料从「重新翻邮箱找 JD」变成结构化复盘;STAR 映射保证每个预期问题都有真实事例支撑。
不建议:拿它背诵标准答案——框架设计上就拒绝编造,mock 的价值在于暴露你真实经历里的表达缺口。
场景三:投递管道管理与静默跟进
痛点:投出 40 份申请后没人管得住状态:哪家石沉大海、哪家该发跟进邮件、哪家的拒信其实附了「六个月后可再投」。
如何解决:/outcome 记录每场结果并归档提交材料;/outcome followup 找出静默超过 10 天的在途申请,用你的写作风格起草跟进信——草稿只写不发,每个申请最多跟进两次,且只引用你已提交材料里的论据;/gmail-sync 读 Gmail 里的面试邀约、测评链接、offer、拒信,批量提议状态变更并引用源邮件,你批准后才写 tracker,conflict 信号标记人工处理而非猜测。
最小示例:/outcome(记录结果)→ /outcome followup(起草跟进)→ /gmail-sync(收件箱状态回填)→ /html-report(生成离线 HTML 仪表盘,内联 SVG 图表零依赖)。
收益:漏斗数字可视(/html-report 出状态/行业/渠道/漏斗图),跟进动作有纪律(不多发、不代发),数据主权完整。
场景四:技能差距分析与学习规划
痛点:转岗或升级方向时,「我该学什么」通常靠感觉,学的优先级与市场真实需求脱节。
如何解决:/upskill 对比 profile 与你追踪的(以及评分过但未投的)职位数据,产出技能差距热图和带时间估算的学习计划,学习资源经网络搜索补充;/expand 则反向补充弹药——扫描你在 profile 里挂出的 GitHub、portfolio、Kaggle、Google Scholar 公开源,把没写进简历的能力带 source tag 补进档案。
收益:把「投递反馈」变成「学习信号」:被反复 FLAG 的语言门槛、反复出现的缺口技能,就是下一个月的学习清单。
场景五:迁移到你的市场(/add-portal 与社区 fork)
痛点:框架内建门户是丹麦生态,其他国家用户第一反应是「对我没用」。
如何解决:/add-portal 接受任意招聘网站 URL,调查其搜索 URL 模式、结果页结构与 robots.txt 访问规则,按统一契约(search/detail CLI、--format json|table|plain 输出、SKILL.md 的 enabled: 标志、自带离线测试)脚手架出新的门户技能,试跑一次 live query 才注册。/scrape 靠契约自动发现技能,无需注册表。社区在 Discussions #78 维护各市场 fork 的门户索引,借用的方式是手动复制那个文件夹——没有安装器是刻意的安全决策,因为 settings.json 的 allowlist 会让这些 CLI 免确认运行,唯一的安全闸门就是你先读一遍代码。
边界:需要登录墙的门户会被生成器直接拒绝;条款严苛的站点生成的技能会带 personal-use-only 警告。
六、快速上手
前置:Claude Code 订阅(无免费档;偶尔使用可走 API 按量计费)、Python 3.10+、Bun、带 lualatex 与 xelatex 的 LaTeX 发行版(TinyTeX 需按 SETUP.md 补装 extra 包)。三步冷启动:
# 1. 注意:fork 必然是公开仓库,个人数据会进 tracked 文件;
# 自用请建 private 仓库并挂 upstream(SETUP.md 第 8 节有 2 分钟配方)
gh repo fork MadsLorentzen/ai-job-search --clone
cd ai-job-search
python3 tools/install_portal_clis.py # 按 CI 的 glob 发现并安装全部门户 CLI
# 2. 建档(三条路径自动探测:documents/ 目录、单 CV 粘贴、访谈式)
claude # 输入 /setup
# 3. 跑起来
# /scrape → /rank → /apply <url>
两条实操提醒:第一,升级走 tagged release 而非拉裸 master,tools/check_upstream_updates.py 会先预览这次更新会碰到你哪些个性化文件,upstream_triage.py 把落后的 commit 分拣成「值得看」与「大概率可跳过」;第二,/reset 删数据前要求你手输 RESET 确认,删除范围会先列清楚。
七、横向对比
| 维度 | ai-job-search | 直接用 ChatGPT/Claude 改简历 | SaaS 求职工具(LazyApply 类) |
|---|---|---|---|
| 运行位置 | 本地 fork,数据不出机器 | 本地/云端会话,无持久档案 | 云端 SaaS |
| 事实管理 | 三源权威制 + Grounding Audit | 无,全靠当轮上下文 | 黑盒 |
| 定制逻辑 | 双门 + 五维加权评分 + deal-breaker | 单轮对话判断 | 通常关键词堆砌 |
| 质量验证 | PDF 编译检查 + ATS 文本层检查 | 无 | 无公开验证机制 |
| 反注入 | posting 视为数据、权限 allowlist + CI 守卫 | 无 | 无 |
| 成本 | Claude 订阅 + 本地 LaTeX | 订阅费 | 月费制(价格待确认) |
| 可定制 | 三扩展点:门户/模板/评分标准 | 每次重讲需求 | 不可 |
同一生态位上还有两个参照:ECC(当日 +1145)做的是 agent harness 横向优化,不绑定求职场景;K-Dense-AI 的 scientific-agent-skills(本站 10-16 已发)证明了同样的「技能文件 + 严谨工序」模式在科研领域可复制。ai-job-search 的独特性在于它是端到端跑通一个真实人生场景、并以可审计的工程纪律为卖点的完整实现。
八、局限与风险
指令级防御不是沙箱——SECURITY.md 开篇就承认这一点。框架面对的根本风险面无法根除:一个带文件权限的 LLM 同时读不可信的网页内容(职位描述)和你的个人数据。allowlist 管住的是 Bash 命令,模型的 WebFetch/WebSearch 原生工具在它的射程之外,这正是 untrusted-input 指令规则必须存在的原因。在不信任的招聘板上使用前,作者建议亲自过目 agent 抓了什么、写了什么。
平台条款风险:LinkedIn 的公开职位接口明确标注仅供个人低频使用,自动化访问违反其 ToS;各国招聘网站对爬取的态度不一,robots_check.py 只能管住自家工具的行为。
输出合规争议:AI 批量生成申请正在引发招聘方的甄别军备竞赛,部分雇主明确反感 AI 海投。本项目的差异化恰恰是「定制 + 诚实 + 可披露」(作者每场面试都主动坦白),但如果用法退化为提量海投,价值主张就塌了。
市场覆盖:核心工作流(评估/起草/审稿)语言与国家无关,但搜索技能缺省只有丹麦市场;非丹麦用户必须先用 /add-portal 自建或从社区 fork 借用,存在前置成本。
模型依赖:整个工作流的判断质量上限就是底层 Claude 模型的水平;framework_version 机制能保护你的个性化文件不被升级覆盖,但方法学本身的演进方向由上游作者决定。
九、小结与行动建议
ai-job-search 的启示大于它的功能本身:它证明了 Claude Code 这类「提示词即程序」的形态,靠工程纪律(事实权威源、产物级验证循环、untrusted input 处置、CI 守卫权限面)可以做到接近生产级的可靠性。给不同读者的建议:
- 正在求职的工程师:值得 fork 一份跑通
/setup,丹麦之外的先用 linkedin-search/freehire-search 两个跨国源,再考虑/add-portal接本地招聘板;记住自用建 private 仓库。 - 做 LLM 应用的开发者:把
apply.md的八步编排当免费教材读——双代理分离、结构化编辑反馈(Part A JSON)、token 效率规则这三样可以直接搬进你自己的工作流。 - 企业内 HR Tech 团队:评分框架的双门 + 五维加权 + 阈值分档是一套现成的、可解释的匹配方法学,比黑盒推荐更经得起合规审视。
- 关注安全的人:SECURITY.md 的威胁模型自白(instruction-level defenses raise the bar; they are not a sandbox)是坦诚的示范,值得所有 agentic 项目效仿。
- 观望者:这个项目当前依赖 Claude Code 订阅,总拥有成本不低;先读它的 SECURITY.md 与
04-job-evaluation.md再决定是否投入。
参考资料
- 仓库主页与 README(架构、工作流、作者自述):https://github.com/MadsLorentzen/ai-job-search (获取日期 2026-10-18)
.claude/commands/apply.md八步工作流定义(master 分支):https://github.com/MadsLorentzen/ai-job-search/blob/master/.claude/commands/apply.md (获取日期 2026-10-18).claude/skills/job-application-assistant/04-job-evaluation.md评分框架 v1.2.6(双门 + 五维 + 权重阈值):同仓库 master 分支(获取日期 2026-10-18)- SECURITY.md 威胁模型与安全策略:同仓库 master 分支(获取日期 2026-10-18)
- CHANGELOG.md 与 Releases v1.0.0–v1.7.2:https://github.com/MadsLorentzen/ai-job-search/releases (获取日期 2026-10-18)
- GitHub API 仓库元数据(星数、fork、贡献者、commits,截至 2026-10-18):https://api.github.com/repos/MadsLorentzen/ai-job-search
- 社区 fork 与门户索引(Discussions #78):https://github.com/MadsLorentzen/ai-job-search/discussions/78
- The Next New Thing 实操演示视频(2026-08 录制):https://www.youtube.com/watch?v=HoVxjMNFYv4
读者留言
COMMENTS 暂无还没有留言,来说第一句?