ここ数ヶ月の間に、別々の人から同じことを聞かれました。日本式のレジュメを共有してもらえないか、と。
英語のレジュメではなく、履歴書と職務経歴書。日本の企業に応募する際に実際に求められるフォーマットです。
そのたびに、返事は同じでした。「ちょっと確認して後で返します」と。
英語のレジュメはそれなりに整っていました。一方、日本語の方は中途半端なメモの寄せ集めで、英語版を更新するたびにすぐ古くなる。毎回それを手で書き直すのは、しかも第二言語で、現実的ではありませんでした。
そこで作ったのが JPResume です。英文レジュメから履歴書と職務経歴書を生成し、両方を同期させるための小さなSwift CLIツールです。
日本式レジュメが単なる翻訳ではない理由
英文レジュメしか書いたことがないと、日本式のレジュメも単なる翻訳だと思いがちです。でも実際はそうではありません。
履歴書は、基本的に決まったフォーマットのグリッドです。氏名、フリガナ、写真欄、年・月単位で並ぶ学歴・職歴、資格、志望動機、本人希望記入欄。それぞれに細かい慣習があります。現職の書き方、職歴の締め方(「現在に至る」)、西暦か和暦か。
企業によって重視度は違いますが、初めて触れると分かりにくいポイントばかりです。
職務経歴書はその対になる自由形式のドキュメントです。職務要約から始まり、各職歴の詳細、スキル、実績、自己PR。こちらは書き方そのものにコツがあります。
例えば「29.8%のサインアップ増加を達成」という表現は英語では自然でも、日本語では少し浮きます。「新規会員登録数の29.8%増加に寄与」のような表現の方が馴染みます。
さらに厄介なのが整合性です。英語版と日本語版で、日付・役職・内容が一致している必要があります。ずれに気づくのは、大抵よくないタイミングです。
この整合性の問題は、ツールで解決できる部分でもあります。
仕組み
意図的にシンプルなパイプラインにしています。魔法はありません。
flowchart LR
parse[Parse]
normalize["Normalize (LLM)"]
repair[Repair]
validate[Validate]
generate["Generate (LLM)"]
render[Render]
parse --> normalize --> repair --> validate --> generate --> render
Parse は決定論的な処理です。markdown、DOCX、PDFを入力として受け取り、ざっくりとした構造化データに変換します。Markdownはそのままパース。DOCXとPDFはテキスト抽出後に前処理を行います。スキャンPDFの場合はOCR(Vision)にフォールバックします。
Normalize で初めてLLMが登場します。パース結果と jpresume_config.yaml(漢字氏名、フリガナ、住所、学歴、資格など日本特有の情報)を元に、正規化された構造を生成します。日付は整数化され、箇条書きは実績と責務に分類され、スキルはカテゴリごとに整理されます。
ここで重要なのは、「情報を補完しない」ことです。曖昧な場合は推測せず、低信頼としてマークするようにしています。
Repair は再び決定論的です。職歴の並び替え、重複期間の整理、is_current の整合性修正などを行います。Validate では、重複、低信頼データ、不自然な空白期間、年数のズレなどを警告として出します。
Generate で履歴書と職務経歴書のJSONを生成し、Render でMarkdownとPDFに変換します。PDFはCoreGraphicsとヒラギノを使って、日本語として自然に見える組版になるようにしています。
構成としてはよくある形です。できるところは決定論的に、必要なところだけLLMを使い、その間に確認可能な中間状態を挟む。
実際の使い方
CLIは一発で実行できます。
jpresume convert resume.md --provider claude-cli --format both
ただ、普段は agent skill を使っています。理由は external mode です。
external mode では、LLMステージは直接APIを呼びません。プロンプトをファイルとして書き出して終了します。その後、エージェント(Claude CodeやCursorなど)がそれを読み取り、結果JSONを生成して書き戻し、--ingest で処理を再開します。
つまり、エージェント自体がモデルになります。
この違いは意外と大きいです。すべてのプロンプトとレスポンスが見える。途中で止めて確認できる。誤ったフィールドはJSONを直接修正して再取り込みできる。
Normalizeの結果もブラックボックスではなくなります。どのように解釈されたかを確認してから次に進める。
このツールをワンショットで作っていたら、この部分は見落としていたと思います。初稿を作るだけなら十分ですが、実際に提出するドキュメントではレビューのループが重要です。
現時点での限界
JPResumeは、現時点ではほぼ自分のレジュメでしか検証していません。
ソフトウェアエンジニアとしての職歴、比較的きれいな日付、認知されやすい企業名、JLPTのように定型化された資格。かなり扱いやすいケースです。
キャリアチェンジ、海外大学、長期ブランク、特殊な職種、日本の慣習と大きく異なる業界などはまだカバーできていません。
別のレジュメを入れたときに、正規化や生成でうまく処理できない部分が出る可能性は高いと思っています。修正自体は簡単にできるように設計していますが、まだ実例は多くありません。
もし試してみて気になる点があれば、IssueでもPRでも、何でも歓迎です。READMEにインストール方法とagent skillの説明を載せています。
ツールが変わっても残るもの
このツール自体よりも、残るのは構成の方だと思っています。
決定論的なパース、情報を補完しない正規化、バリデーション後の意図的な停止、エージェントがモデルとして振る舞いながら結果をレビューできるexternal mode。
このパターンは、日本式レジュメに限らず、契約書や申請書のように「間違った値が入ると困る」ドキュメント全般に応用できます。
現時点では、markdownのレジュメから履歴書と職務経歴書を生成し、そのまま提出できる状態にするツールです。
数ヶ月前は、それができませんでした。