ai-job-search(MadsLorentzen/ai-job-search・GitHubスター42.4k・MIT)は、Claude Codeを求職アシスタントに変えるフレームワークです。求人を集め、自分のプロフィールと突き合わせて採点し、CVとカバーレターをLaTeXで起草し、PDFをコンパイルして体裁とATS(応募者追跡システム)での読み取りまで確認し、面接準備と結果記録まで回します。作者は2025年末に職を失った地球物理学者で、自分の求職にこのワークフローを毎週使ったとREADMEに書いています。2026年3月の公開から半年で42.4kスターに達しました。
日本語圏で最初に出る疑問は「これは日本語で使えるのか」です。READMEは「中核のワークフローは言語・国に依存しない。ただし求人ポータル検索はデンマーク市場向けに作ってある」と書きますが、日本語で実際に何が起きるかは書かれていません。本記事はリポジトリを手元に置き、求人検索CLI・言語ゲート・LaTeXの日本語出力の3点を実際に動かして確かめました。結論から言うと、枠組みは使えて、LaTeXだけが無言で壊れます。
lualatex は終了コード0で成功扱い(本記事の実測)- ・正体:Claude Codeのコマンド12個+スキル2個で求職ループを回すMITのフレームワーク。42.4kスター
- ・何ができる:求人収集(
/scrape)→採点(/rank)→CV・カバーレター起草とPDF検証(/apply)→面接準備(/interview)→結果記録(/outcome) - ・日本語で使える部分:プロフィール・評価ルール・言語ゲート・カバーレターの言語自動追従。LinkedIn検索は
-l "Tokyo, Japan" - ・直す部分:①日本の求人サイトCLIは未同梱 ②LaTeXが日本語を無言で落とす(2行で解決)③CVは欧米形式で履歴書・職務経歴書ではない
- ・実測:日本語を入れたCVは警告59件でテキスト層0文字。
luatexja-fontspec追加で0件・2.1秒→33.9秒
Claude Code自体のコマンドやスキルの仕組みはClaude Code|2026年版・インストールからCLAUDE.md・Hooks・本番運用までの実装手引きにまとめています。本記事はその応用例として、求職という具体的な業務に落としたフレームワークを見ます。
ai-job-searchとは——求職の反復をコマンドに固定する
このOSSの正体は、モデルでもCLIツールでもなくプロンプトとルールの集合です。.claude/commands/ に12個のスラッシュコマンド、.claude/skills/ に3つのスキル(/scrape にあたる job-scraper、/upskill、そして評価基準や文体規則を収めた job-application-assistant)が入っており、Claude Codeがそれを読んで動きます。Pythonのコードは補助ツール(PDF検証、給与照合、重複キー生成、上流追従)だけです。
| コマンド | 役割 |
|---|---|
/setup |
CV・LinkedInエクスポート・推薦状などを読み、プロフィールと評価基準を生成 |
/scrape |
導入済みポータルCLIを並列実行して求人を収集、既応募・既読と重複排除 |
/rank |
収集分を5軸で一括採点。締切・言語ゲート・地理条件で足切りし順位づけ |
/apply <url> |
適合度評価 → CV・カバーレター起草 → レビュアーエージェントの批評 → 改稿 → PDFコンパイルと目視検証 → ATSテキスト層チェック |
/interview |
提出済み書類と求人票からステージ別の想定問答を作り、模擬面接も行う |
/outcome |
面接・内定・不採用・音信不通を記録。10日超の停滞に催促文の下書きを作る |
/expand /upskill |
公開プロフィール(GitHub等)から経歴を補強/求人群とのスキル差分から学習計画 |
/add-portal /add-template |
自分の市場の求人サイトCLI/自分のCVテンプレートを登録 |
/gmail-sync /notion-sync /html-report |
メールから選考状況を拾う/Notionへ読み取り専用で公開/オフラインHTMLダッシュボード |
特徴的なのは /apply です。起草したClaudeとは別コンテキストのレビュアーエージェントを立て、企業情報を調べて草稿を批評させ、それを受けて書き直します。さらに実際にPDFをコンパイルして、レンダリング結果を読んで「CVが2ページちょうどか」「役職名が次ページに孤立していないか」「カバーレターが1ページに収まり署名が見えるか」を直します。最後に pdftotext でテキスト層を抜き、ATSパーサが見る順序・連絡先・キーワード網羅を確認します。
① 何ができる:求人の収集・採点から応募書類の作成・PDF体裁検証・面接準備・結果追跡までを、14個のコマンドで反復可能にする。② 何を解決する:応募のたびにCVを手で作り直し、書式崩れとATS落ちに気づかないまま送る問題。③ 何を代替できる:CV添削サービスの下書き工程と、求人サイトを毎日巡回する手間。応募の送信そのものは代替しない(下書きまで)。
結論——日本語で「そのまま使える部分」と「自分で直す部分」
検証結果を先に置きます。
| 検証項目 | 日本語での結果 | 対応 |
|---|---|---|
| プロフィール・評価基準 | ✅ 言語非依存。日本語で書いても構造は同じ | なし |
言語ゲート(04-job-evaluation.md) |
✅ Languages表に「日本語(ネイティブ)」等を書けば機能する | なし |
| カバーレターの言語 | ✅ 求人票の言語に自動で合わせる仕様 | なし |
| LinkedIn検索CLI | ⚠️ -l "Tokyo, Japan" で指定可(本環境からは403で実行不可) |
実機で要確認 |
| freehire検索CLI | ⚠️ --country jp で指定可(同上)。技術職特化 |
実機で要確認 |
| 日本の求人サイト(doda・Green等) | ❌ 同梱なし | /add-portal で自作 |
| CVのLaTeX(lualatex) | ❌ 日本語が無言で消える(警告59件・テキスト層0文字) | 2行追加 |
| カバーレターのLaTeX(xelatex) | ❌ 同上(警告50件) | 2行追加 |
| CVの様式 | ❌ moderncv banking=欧米式。履歴書・職務経歴書ではない | /add-template で差し替え |
/apply の言語抽出 |
⚠️ プロンプトに「Danish or English」と直書き | 1行書き換え |
| 給与照合ツール | ⚠️ 表記ゆれ吸収がデンマーク語前提。データは自分で用意 | 任意機能 |
そのまま動く側の根拠を1つ挙げます。言語ゲートは 04-job-evaluation.md に定義され、求人が職務要件として求める言語を、プロフィールのLanguages表と突き合わせます。表に無い言語を要求されたらFAIL(採点も起草もしない)、表にあるが求められる水準が自分の宣言より高そうならFLAG(採点も起草もするが人間に判断を委ねる)、それ以外はPASS。ここに「デンマーク語」や「英語」は埋め込まれておらず、自分の表に書いた言語で動きます。日本語話者が英語必須の外資求人を見る、という使い方にそのまま乗ります。
検証1:日本の求人をどう集めるか
同梱の検索CLIは .agents/skills/ に6つあります。
| ポータル | 既定 | 場所の指定 | 備考 |
|---|---|---|---|
linkedin-search |
有効 | --location が必須。任意の国・都市・Remote |
公開ページ利用。個人利用限定(LinkedIn利用規約) |
freehire-search |
有効 | --country(ISO 3166 2文字)・--region・--remote |
公開REST API・APIキー不要。技術職特化 |
jobindex jobnet jobbank jobdanmark |
無効 | — | デンマークの実例4本。/setup が市場を聞いて有効化する |
デンマークの4本が既定で無効なのは重要です。「デンマーク向けOSS」という第一印象に反して、箱から出した状態で動くのは国を問わない2本だけで、日本から使っても無関係な求人が混ざりません。
# LinkedIn:場所は必須フラグ。日本の求人もこれで指定する
bun run .agents/skills/linkedin-search/cli/src/cli.ts search \
-q "機械学習エンジニア" -l "Tokyo, Japan" --jobage 7 --limit 20 --format json
# freehire:ISO 3166 の2文字コード
bun run .agents/skills/freehire-search/cli/src/cli.ts search \
-q "python" --country jp --limit 20 --format json
本記事の実行環境では、両方とも {"error":"Request failed: 403 Forbidden","code":"SEARCH_FAILED"} を返しました。これはこの検証環境からの外向き通信が両サービスに拒否されたためで、通常のPCでも失敗するという意味ではありません。CLIの引数解釈とJSON整形は、ネットワークを使わないテストで確認できます。
$ cd .agents/skills/linkedin-search/cli && bun test
62 pass / 0 fail (5 files, 1.70s)
$ cd ../../freehire-search/cli && bun test
44 pass / 0 fail (5 files, 1.03s)
$ cd ../../.. && python3 -m pytest -q tests
432 passed, 154 subtests passed in 8.37s
検証2:LaTeXの日本語——コンパイルは成功するのに文字が消える
ここが本記事の主題です。同梱テンプレートは2種類あります。
・CV:cv/main_example.tex。moderncv(bankingスタイル)を lualatex でコンパイル
・カバーレター:cover_letters/cover_example.tex。fontspec でLato/Ralewayを読む独自 cover.cls を xelatex でコンパイル
どちらも欧文フォントだけを指定しており、日本語のグリフを持つフォントが1つも設定されていません。ここに日本語を入れるとどうなるかを実測しました。
# CV(英語のまま)— 正常
$ lualatex -interaction=nonstopmode main_example.tex
exit 0 / Pages: 2 / Missing character 警告: 0 / 2.108秒
# CV に日本語を1行入れただけ — 成功扱いなのに日本語が消える
$ lualatex -interaction=nonstopmode main_ja_plain.tex
exit 0 / Pages: 2 / Missing character 警告: 59
Missing character: There is no 要 (U+8981) in font [lmsans10-bold]
$ pdftotext main_ja_plain.pdf - | grep -c "要約"
0
終了コードは0、ページ数も正しい、PDFも生成される。失敗を示すのはログの中の警告59件だけで、画面上からもPDFのテキスト層からも日本語は消えます。カバーレター(xelatex)も同じで、警告50件・テキスト層0文字でした。
(プロフィール要約・見出し)"] --> B["lualatex / xelatex を実行"] B --> C{"欧文フォントに
そのグリフはあるか?"} C -- "ある(英数字)" --> D["正常に描画"] C -- "無い(日本語)" --> E["ログに Missing character 警告
終了コードは 0 のまま"] E --> F["PDFは生成される
ページ数も正しい"] F --> G["画面に日本語が出ない
テキスト層にも 0 文字"] G --> H["対策:luatexja-fontspec / xeCJK と
日本語フォントを設定する"] H --> D
対策は2行です。CV側(lualatex)はプリアンブルに次を足します。
% cv/main_<company>_<role>.tex のプリアンブルに追加
\usepackage{luatexja-fontspec}
\setmainjfont{Noto Sans CJK JP}
\setsansjfont{Noto Sans CJK JP}
カバーレター側(xelatex)は xeCJK を使います。
% cover_letters/cover_<company>_<role>.tex の \begin{document} より前に追加
\usepackage{xeCJK}
\setCJKmainfont{Noto Sans CJK JP}
\setCJKsansfont{Noto Sans CJK JP}
追加後の実測は次のとおりです。
| テンプレート | 状態 | 終了コード | Missing character | PDFテキスト層の日本語 | コンパイル時間 |
|---|---|---|---|---|---|
| CV(英語のまま) | 素のテンプレート | 0 | 0 | — | 2.108秒 |
| CV+日本語 | 素のテンプレート | 0 | 59 | 0文字(消失) | — |
| CV+日本語 | luatexja-fontspec 追加 |
0 | 0 | ✅ 抽出できる | 33.916秒 |
| カバーレター+日本語 | 素のテンプレート | 0 | 50 | 0文字(消失) | — |
| カバーレター+日本語 | xeCJK 追加 |
0 | 0 | ✅ 抽出できる | — |
xeCJK で解決。素のテンプレートではこの日本語が1文字も出ない(本記事の実測)日本語フォントのグリフが無い状態では、/apply のATSチェック(pdftotext でテキスト層を抜いてキーワード網羅を見る工程)も日本語のキーワードを1つも見つけられません。英語CVを作るなら無関係ですが、日本語CVを作るつもりなら最初に直すべき箇所です。
なお、TeX環境側の準備も要ります。SETUP.mdの最小TeX環境向けパッケージ一覧は moderncv fontawesome5 fontawesome6 academicons import luatexbase pgf titlesec textpos xltxtra xunicode cite realscripts needspace で、CJK関連が入っていません。本記事のUbuntu環境では texlive-lang-japanese(luatexja)と texlive-lang-chinese(xeCJKが依存する ctexhook)、および fonts-noto-cjk を追加しました。またコンパイル時間は2.1秒から33.9秒へ伸びます。/apply はPDFを見ながら体裁を直すため複数回コンパイルする設計なので、日本語CVでは1回の応募にその分の時間がかかります。
検証3:言語ゲートと文体——効くもの、英文前提のもの
プロフィールのIdentityセクションにはLanguagesの表があり、/setup がCVやLinkedInエクスポートから抽出するか、直接聞いてきます。ここに書いた言語と水準が、以降すべての評価に効きます。
- **Languages:**
| Language | Level |
|----------|-------|
| 日本語 | ネイティブ |
| English | B2 / business working proficiency |
- **CV language:** 日本語 <!-- 既定は英語。/setup が聞いてくる -->
言語ゲートの判定は3値です。表に無い言語を職務要件として求める求人はFAIL(採点も起草もせず、要件の原文を引用して除外理由を残す)。表にある言語だが求人の水準が自分の宣言より高そうならFLAG(採点も起草もするが、求人の要件と自分の宣言を並べて人間に判断させる)。それ以外はPASS。ドキュメントは「CEFRの記号・LinkedIn式の表現・平たい言葉が現実には混在し、互いに正確には対応しない。迷ったら黙ってPASSにせずFLAGにせよ」と明記しています。求人票が書かれている言語ではなく、職務として要求される言語で判定する、という区別も書かれています。
カバーレターは求人票の言語に自動で合わせ、CVは求人ごとに切り替えずプロフィール単位で固定します(使い回せるように、という理由が書かれています)。CVの言語を日本語にした場合は、05-cv-templates.md が「\section{...} の見出しとReferences欄の定型文はテンプレートに英語で直書きされている。本文だけ訳して見出しを英語のまま残すと雑に見える」と注意し、スペイン語の対訳例まで挙げています。日本語なら Core Competencies → スキル、Professional Experience → 職務経歴、Education → 学歴 のように置き換える作業です。
一方で英文前提が残っている箇所も見つかりました。
・.claude/commands/apply.md の冒頭で求人票から抽出する項目に「language of the posting (Danish or English)」と言語の選択肢が直書きされています。判定ロジック自体は汎用なので実害は小さいものの、日本語の求人を扱うならこの1行は書き換えるのが素直です
・03-writing-style.md の禁止表現は「I am passionate about」「leverage my skills」といった英語のクリシェ一覧で、見出しの悪例にはデンマーク語が混じります。日本語の応募書類で避けたい定型表現(「貴社の益々のご発展を」等)は自分で足す必要があります
・salary_lookup.py の企業名あいまい一致は「デンマーク・北欧の文字と法人格(A/S、ApS)」を吸収する実装です。給与データ自体は自分で用意する任意機能なので、「株式会社」の扱いを含めて日本向けには作り直しになります
ai-job-searchの導入手順と、先に知っておくこと
前提はClaude Code・Python 3.10以上・Bun・LaTeX(lualatex と xelatex)です。日本語で使うならこれに日本語フォントと luatexja/xeCJK が加わります。
# 1. フォークして取得(プロフィールを置くなら私有リポジトリを推奨)
git clone https://github.com/<you>/ai-job-search && cd ai-job-search
# 2. 検索CLIの依存(Bun)。ネットワーク無しでテストが通ることを確認できる
cd .agents/skills/linkedin-search/cli && bun install && bun test && cd -
# 3. Claude Code を起動してプロフィール作成
claude
> /setup
/setup は documents/ に置いたCV・LinkedInエクスポート・推薦状を読む経路、CV1枚を貼る経路、対話で埋める経路の3つを提示します。書き込みを始める前に git remote を調べ、公開フォークなら次の警告を出して確認を求めます。GitHubの仕様上、公開リポジトリのフォークは非公開にできないためです。
upstream として追加する(SETUP.md §8に手順)。トラッカー・給与データ・documents/・応募アーカイブはgitignore済みで、どちらの場合もgitに入りません。
上流追従の仕組みも用意されています。tools/check_upstream_updates.py は各方法論ファイルの framework_version を上流と比較して「自分がカスタマイズしたどのファイルが更新されたか」を出し、tools/upstream_triage.py は未取り込みコミットを「見る価値あり/たぶん不要」に仕分けます(git patch-id で取り込み済みを落とす)。どちらも報告専用で、マージやpushはしません。
| 項目 | 実測(2026-09-15) |
|---|---|
| 初回コミット | 2026-03-23(Initial release) |
| コミット数 | 271(Mads Lorentzen 105・他2名で64・以下略) |
| 最新タグ/最終コミット | v1.7.1(2026-09-06)/2026-09-10 |
| スター/フォーク/オープンIssue | 42.4k/14.5k/4 |
| テスト | Python 432件+サブテスト154件(8.4秒)、Bun 62件+44件 |
| ライセンス | MIT |
Claude Code以外のエージェント(Codex・Antigravity・Gemini CLI)向けには AGENTS.md が用意され、検索CLIはそのまま動くと書かれています。スキルという単位でエージェントに能力を足す考え方そのものはClaude Skillsとは|「スキル=フォルダ」の仕組みと作り方・使い方を徹底解説に、/apply が使う「別コンテキストのレビュアーを立てる」構成はClaude Code サブエージェントとは?作り方・frontmatter全項目・呼び出し方まとめ【2026年版】に整理があります。
まとめ
-l "Tokyo, Japan" で日本の求人を指定できる。一方、同梱のCV・カバーレターのLaTeXテンプレートは欧文フォントしか設定しておらず、日本語を入れると終了コード0のままPDFから日本語だけが消える(実測:警告59件・テキスト層0文字)。luatexja-fontspec と xeCJK にそれぞれ日本語フォントを指定する2行で解決し、その代わりコンパイルは2.1秒から33.9秒に伸びる。日本の求人サイトは /add-portal で自作、CVの様式は欧米式なので日本の職務経歴書が要るなら /add-template で差し替える。
・向く:英語CVで外資・海外求人に応募する人、応募書類のPDF体裁とATS通過を毎回検証したい人、求職の記録をローカルに残したい人
・向かない:日本の履歴書・職務経歴書の様式をそのまま欲しい人、LaTeXに触りたくない人、フォークに個人情報をpushしてしまいそうな運用
・最初にやること:/setup の前に私有リポジトリを用意 → 日本語CVを作るならテンプレートに上記2行を追加 → /add-portal で使っている求人サイトを1つ登録
参照ソース
・MadsLorentzen/ai-job-search(公式リポジトリ・README・SETUP.md・CLAUDE.md・.claude/ 配下) — コマンド構成・ポータルCLI・言語ゲート・プライバシー方針の一次情報。2026-09-15時点の master(コミット c7bd494)を読解
・SETUP.md — LaTeX と最小TeX環境の依存パッケージ — tlmgr install の一覧にCJK関連が無いことの根拠
・luatexja(CTAN)/xeCJK(CTAN) — 本記事で追加した日本語組版パッケージ
・実測:Ubuntu+TeX Live(apt)+Noto Sans CJK JPで、同梱テンプレートに日本語を入れて lualatex/xelatex を実行。素のテンプレートで警告59件・50件かつテキスト層0文字、パッケージ追加後は警告0件・抽出可・CVは2.108秒→33.916秒。検索CLIは bun test 62件・44件、Pythonは432件が通過(2026-09-15)