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だけが無言で壊れます

同梱CVテンプレートに日本語を入れてコンパイルした比較。左はそのままのテンプレートで冒頭の日本語行が完全に消えている。右はluatexja-fontspecとNoto Sans CJK JPを足したもので、日本語の要約文と職務経歴の見出しが正しく表示されている
同じ日本語テキストを入れた同じテンプレート。左=そのまま(警告59件・日本語が消える)/右=2行追加後(警告0件)。どちらも lualatex は終了コード0で成功扱い(本記事の実測)
30秒でわかる ai-job-search(2026年9月15日時点)
  • 正体: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検証、給与照合、重複キー生成、上流追従)だけです。

ai-job-searchのコアワークフロー。/setupでCV・LinkedIn等からプロフィール生成、/scrapeでポータルCLIから求人収集と重複排除、/rankで5軸採点と言語ゲートと締切、/applyでCVとカバーレター起草からレビューとPDF検証、/interviewで面接準備、/outcomeで結果記録とフォローアップ
送信は一切しない。下書きを作ってローカルのCSVとMarkdownに記録するまでが範囲
コマンド 役割
/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パーサが見る順序・連絡先・キーワード網羅を確認します。

読者の3つの問いへの答え
何ができる:求人の収集・採点から応募書類の作成・PDF体裁検証・面接準備・結果追跡までを、14個のコマンドで反復可能にする。② 何を解決する:応募のたびにCVを手で作り直し、書式崩れとATS落ちに気づかないまま送る問題。③ 何を代替できる:CV添削サービスの下書き工程と、求人サイトを毎日巡回する手間。応募の送信そのものは代替しない(下書きまで)。

結論——日本語で「そのまま使える部分」と「自分で直す部分」

検証結果を先に置きます。

日本語利用の可否。手を入れる必要あり:日本の求人サイトCLIは未同梱、CVテンプレはmoderncvの欧米形式、LaTeXは日本語フォント設定を自分で追加、文体ルールは英文前提。そのまま使える:Languages表に日本語を書けば言語ゲートが効く、LinkedIn検索はTokyo Japanで指定可、freehireはcountry jpで絞れる、カバーレターは求人票の言語に自動追従
枠組みは言語非依存。壊れるのはLaTeXと、市場固有の部分
検証項目 日本語での結果 対応
プロフィール・評価基準 ✅ 言語非依存。日本語で書いても構造は同じ なし
言語ゲート(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
日本のボードを足すときの注意:`/add-portal` は生成前に robots.txt と利用規約を確認し、ログイン必須のポータルは「この方式では無理」と断る設計です。規約が自動アクセスを禁じている場合は、その旨を伝えたうえで生成物に個人利用限定の警告を入れます。生成したCLIは自分のフォークに置く前提で、上流には取り込まれません(市場固有のものは各自のフォーク、という方針)。

検証2:LaTeXの日本語——コンパイルは成功するのに文字が消える

ここが本記事の主題です。同梱テンプレートは2種類あります。

CVcv/main_example.texmoderncv(bankingスタイル)を lualatex でコンパイル
カバーレターcover_letters/cover_example.texfontspec でLato/Ralewayを読む独自 cover.clsxelatex でコンパイル

どちらも欧文フォントだけを指定しており、日本語のグリフを持つフォントが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文字でした。

flowchart TD A["CVに日本語を入れる
(プロフィール要約・見出し)"] --> 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とNoto Sans CJK JPを設定してコンパイルした結果。冒頭の日本語の志望動機文が正しく表示されている
カバーレター側は 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(lualatexxelatex)です。日本語で使うならこれに日本語フォントと luatexjaxeCJK が加わります。

# 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

/setupdocuments/ に置いたCV・LinkedInエクスポート・推薦状を読む経路、CV1枚を貼る経路、対話で埋める経路の3つを提示します。書き込みを始める前に git remote を調べ、公開フォークなら次の警告を出して確認を求めます。GitHubの仕様上、公開リポジトリのフォークは非公開にできないためです。

プロフィールをpushしてはいけない:`/setup` が書き込むのはgitで追跡されるファイル(`CLAUDE.md` とプロフィール群)で、氏名・連絡先・職歴・給与希望が入ります。公開フォークへpushすると誰でも読めます。安全策は2つ、①コミットするがpushしない ②私有リポジトリを作ってそこへpushし、上流を upstream として追加する(SETUP.md §8に手順)。トラッカー・給与データ・documents/・応募アーカイブはgitignore済みで、どちらの場合もgitに入りません。

上流追従の仕組みも用意されています。tools/check_upstream_updates.py は各方法論ファイルの framework_version を上流と比較して「自分がカスタマイズしたどのファイルが更新されたか」を出し、tools/upstream_triage.py は未取り込みコミットを「見る価値あり/たぶん不要」に仕分けます(git patch-id で取り込み済みを落とす)。どちらも報告専用で、マージやpushはしません。

ai-job-searchの数字。GitHubスター42.4k、コミット271件(2026年3月23日から)、最新タグv1.7.1が2026年9月6日、スラッシュコマンド13個
2026-09-15時点のリポジトリ実測(GitHub表示・git log・タグ)
項目 実測(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年版】に整理があります。

まとめ

ai-job-searchは日本語でも使える。ただしLaTeXだけは先に直す必要がある。プロフィール・評価基準・言語ゲート・カバーレターの言語追従は言語非依存で、LinkedIn検索も -l "Tokyo, Japan" で日本の求人を指定できる。一方、同梱のCV・カバーレターのLaTeXテンプレートは欧文フォントしか設定しておらず、日本語を入れると終了コード0のままPDFから日本語だけが消える(実測:警告59件・テキスト層0文字)。luatexja-fontspecxeCJK にそれぞれ日本語フォントを指定する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で、同梱テンプレートに日本語を入れて lualatexxelatex を実行。素のテンプレートで警告59件・50件かつテキスト層0文字、パッケージ追加後は警告0件・抽出可・CVは2.108秒→33.916秒。検索CLIは bun test 62件・44件、Pythonは432件が通過(2026-09-15)