アーキテクチャドキュメント
プロジェクト: Resume Review マルチエージェントシステム
バージョン: 1.0
最終更新: 2026-01-11
概要
Resume Review マルチエージェントシステムは、LangGraph を活用して複数の専門AIエージェントを調整し、職務経歴書を自動的にレビュー・改善するPythonベースのCLIツールです。ハイブリッドマルチモデルアーキテクチャにより、単一モデル構成と比較して 大幅なコスト削減 と 高速な実行 を実現しています。
主要技術
- オーケストレーション: LangGraph StateGraph(ファンアウト/ファンインパターン)
- 状態管理: Pydantic 2.0(型安全、検証済み状態遷移)
- LLMプロバイダー: Anthropic Claude、Google Gemini、OpenAI(マルチモデルハイブリッド)
- ツール: Playwright(スクリーンショット取得)、Quarto(ドキュメント検証)
- 言語: Python 3.13+
システムアーキテクチャ
ハイレベルフロー
アーキテクチャ原則
- ファンアウト/ファンインパターン: エージェントは効率化のため並列実行
- 型安全な状態: Pydanticモデルがノード間の契約を強制
- ステートレスエージェント: 各エージェントはReviewStateの純粋関数
- コスト最適化: 認知タスクに応じて異なるモデルを使用
- グレースフルデグラデーション: オプション機能(デザインレビュー)がワークフローをブロックしない
状態管理
ReviewStateスキーマ
ワークフロー全体の状態は、すべてのノードを流れる単一のPydanticモデルで管理されます:
class ReviewState(TypedDict):
# 入力
qmd_content: str
target_role: str
screenshot_path: Optional[str]
job_posting_content: Optional[str]
# エージェントフィードバック(個々のノードがこれらに書き込み)
recruiter_feedback: Optional[Feedback]
tech_writer_feedback: Optional[Feedback]
copywriter_feedback: Optional[Feedback]
# 集約結果
current_feedback: List[Feedback]
current_score: float
# イテレーション追跡
iteration: int
max_iterations: int
threshold: float
# リビジョン
revised_content: Optional[str]
# ポートフォリオ & デザイン
portfolio_items: List[PortfolioItem]
design_feedback: Optional[DesignFeedback]
状態遷移フロー
主要な不変条件:
iterationは減少しないcurrent_scoreは集約のたびに再計算される- 個々のエージェントフィードバックはイテレーションごとに一度設定されるとイミュータブル
マルチエージェントオーケストレーション
ファンアウト/ファンインパターン
システムはLangGraphのネイティブなファンアウト/ファンインを使用して並列エージェント実行を行います:
ファンアウト(Routerノード):
# Routerノードが並列実行をトリガー
workflow.add_edge("router", "recruiter")
workflow.add_edge("router", "tech_writer")
workflow.add_edge("router", "copywriter")
ファンイン(Aggregatorノード):
# Aggregatorは3つすべての完了を待機
workflow.add_edge("recruiter", "aggregator")
workflow.add_edge("tech_writer", "aggregator")
workflow.add_edge("copywriter", "aggregator")
LangGraphが自動的に処理するもの:
- 3つのエージェントの並列実行
- Aggregatorでの同期バリア
- 複数ブランチからの状態マージ
エージェントの責務
| エージェント | モデル | 視点 | 重み |
|---|---|---|---|
| リクルーター | Gemini 3.0 Flash | 契約獲得、市場性 | 30% |
| テクニカルライター | OpenAI o3-mini | 技術的深さ、明瞭性 | 20% |
| コピーライター | Claude Sonnet 4.5 | マーケティング効果、インパクト | 25% |
| UXデザイナー | Gemini 3.0 Flash | 情報階層、スキャナビリティ | 15% |
| ビジュアルデザイナー | Gemini 3.0 Flash | 視覚的プレゼンテーション(スクリーンショットから) | 10% |
設計根拠:
- リクルーター(Gemini): 大量評価、コスト重視
- テクニカルライター(o3-mini): 深い技術評価のための高度な推論
- コピーライター(Claude): クリエイティブ/マーケティング言語で最高品質
- デザイナー(Gemini): スクリーンショット分析用の高速ビジョンモデル
コスト最適化
ハイブリッドマルチモデル戦略
ベースライン(すべてのエージェントにClaude Opus 4.5):
- レビューあたりのコスト: 高コスト
- 実行時間: 順次実行のため遅い
最適化済み(ハイブリッド構成):
- レビューあたりのコスト: 大幅に削減
- 実行時間: 並列実行により高速化
モデル選択ロジック
# config/model_config.pyで定義
DEFAULT_MODEL_ASSIGNMENTS = {
"recruiter": "gemini-3.0-flash", # 大量処理、低コスト
"tech_writer": "o3-mini", # 高度な推論
"copywriter": "claude-sonnet-4-5-20250929", # クリエイティブ品質
"ux_designer": "gemini-3.0-flash", # 高速ビジョン
"visual_designer": "gemini-3.0-flash", # 高速ビジョン
"revisor": "gemini-3.0-flash", # 全文書き換え、大量処理
}
コスト内訳(イテレーションあたり):
| コンポーネント | モデル | 入力トークン | 出力トークン | コスト |
|---|---|---|---|---|
| リクルーター | Gemini 3.0 Flash | 約2K | 約500 | $0.003 |
| テクニカルライター | o3-mini | 約2K | 約500 | $0.15 |
| コピーライター | Claude Sonnet 4.5 | 約2K | 約500 | $0.20 |
| UXデザイナー | Gemini 3.0 Flash | 約2K | 約300 | $0.002 |
| ビジュアルデザイナー | Gemini 3.0 Flash | 約1K(画像) | 約300 | $0.002 |
| リバイザー | Gemini 3.0 Flash | 約3K | 約2K | $0.008 |
| 合計 | - | - | - | 約$0.37/イテレーション |
通常のワークフロー: 1-2イテレーション → 合計$0.37-$0.74
ツール統合
LLMクライアントファクトリ
プロバイダーの違いを統一インターフェースで抽象化:
class LLMClient:
def invoke(self, messages: List[dict], model: str) -> str:
"""同期呼び出し"""
def invoke_with_vision(self, prompt: str, image_path: str, model: str) -> str:
"""ビジョンモデル呼び出し(現在Geminiのみ)"""
プロバイダー:
- Gemini:
langchain_google_genai.ChatGoogleGenerativeAI - OpenAI:
langchain_openai.ChatOpenAI - Anthropic:
langchain_anthropic.ChatAnthropic
スクリーンショット取得(Playwright)
ビジュアルデザインレビューに使用:
def capture_screenshot(url: str, output_path: str) -> str:
with sync_playwright() as p:
browser = p.chromium.launch()
page = browser.new_page(viewport={"width": 1920, "height": 1080})
page.goto(url)
page.screenshot(path=output_path, full_page=True)
browser.close()
return output_path
統合フロー:
- CLIフラグ:
--screenshot-url http://localhost:3000/ja - ワークフロー開始前にスクリーンショットを取得
ReviewStateにscreenshot_pathを渡す- ビジュアルデザイナーエージェントがビジョンモデルで分析
Quarto検証
生成されたQMDファイルが構文的に有効であることを確認:
def validate_quarto(content: str) -> ValidationResult:
# 一時ファイルに書き込み
# 実行: quarto check {temp_file}
# エラーをパースして構造化フィードバックを返す
自動リトライループ(Feature 009):
- 検証失敗時、エラーフィードバックとともにリバイザーを再呼び出し
- 最大リトライ: 3(設定可能)
- ログは
iter{N}_validation_retry.mdに保存
主要な設計判断
1. なぜLangGraph?
検討した代替案: LangChain LLMChain、カスタムオーケストレーション
LangGraphの利点:
- ファンアウト/ファンインのネイティブサポート(複雑なDAG)
- 組み込みの状態管理
- ビジュアルデバッグ(LangSmithトレース)
- インタラクティブ開発用のLangGraph Studio
2. なぜ状態にPydantic?
検討した代替案: プレーン辞書、dataclasses
Pydanticの利点:
- 状態遷移のランタイム検証
- mypyによる型安全
- 自動JSONシリアライゼーション
- ノード入出力の明確な契約
3. なぜマルチモデルハイブリッド?
検討した代替案: Claudeのみ、Geminiのみ
ハイブリッドの利点:
- コスト最適化(低コストモデルの活用)
- パフォーマンス最適化(並列実行)
- タスクごとの最良のモデル(o3-miniの推論、Claudeのクリエイティビティ)
- 1つのプロバイダーに問題があった場合のフォールバック
4. なぜファンアウト/ファンイン?
検討した代替案: 順次エージェント実行
ファンアウト/ファンインの利点:
- 順次より3倍高速(エージェントが並列実行)
- LangSmithでの可視性向上(個別ノードトレース)
- 将来のエージェントごとのリトライロジックが可能
- 関心事のよりクリーンな分離
パフォーマンス指標
実行時間
- 単一イテレーション: 約60秒(ハイブリッド)vs 約180秒(Claudeのみ)
- 並列高速化: 3倍(ファンアウト/ファンインより)
- 通常のワークフロー(2イテレーション): 約2-3分
トークン使用量
- イテレーションあたりの入力トークン: 約12Kトークン
- イテレーションあたりの出力トークン: 約3Kトークン
- ワークフローあたりの総トークン(2イテレーション): 約30Kトークン
品質指標
- 平均最終スコア: 8.5/10(閾値: 8.0)
- イテレーションあたりの改善: 平均+1.2ポイント
- 収束率: 2イテレーション以内で85%
今後の拡張
計画中の機能
- リアルタイムフィードバック用のストリーミング出力
- エージェントごとのリトライロジック(単一エージェント失敗時)
- プロンプト最適化のためのA/Bテストフレームワーク
- LLM-as-a-Judge評価(RagasまたはLangSmith使用)
- 特定エージェントロール用のファインチューニングモデル
研究方向
- さらなる高速化のためのasync/await探索
- コスト削減のための小型モデル(Gemini Flash 8B)調査
- セッション間のメモリ/コンテキスト保持の追加
参考資料
💡 コントリビューション
このシステムはClaude Opus 4.5とGemini Flashをペアプログラミングパートナーとして反復的に構築されました。すべての設計判断は将来の参照のためにspecs/に文書化されています。
質問や改善については、メインリポジトリをご覧ください。