課題12: AIマッチング非同期処理システム構築
難易度: 🟡 中級
分類情報
| 項目 | 内容 |
|---|---|
| 難易度 | 中級 |
| カテゴリ | バッチ処理 / AI / 人材サービス |
| 処理タイプ | 非同期 / イベント駆動 |
| 使用IaC | CloudFormation |
| 所要時間 | 5〜6時間 |
シナリオ
企業プロフィール
〇〇株式会社は、IT・Web業界に特化した人材紹介サービスを運営しています。
| 項目 | 内容 |
|---|---|
| 業種 | 人材紹介(IT特化) |
| 設立 | 2016年 |
| 従業員数 | 100名(うちキャリアアドバイザー40名) |
| 登録求職者数 | 2万人 |
| 掲載求人数 | 5,000件 |
| 月間マッチング件数 | 1万件 |
| 成約数 | 月150件 |
| 年間売上 | 20億円 |
| 平均紹介手数料 | 年収の30%(約130万円) |
現状の課題
求職者と求人のマッチングを人手とルールベースで行っていますが、マッチング精度が低く、成約率が上がりません。また、日次1万件のマッチング処理がピーク時にシステム負荷を与え、レスポンス低下を招いています。
数値で示された問題
| 指標 | 現状 | 業界平均 |
|---|---|---|
| マッチング精度 | 15%(推薦→応募) | 25% |
| 日次マッチング処理 | 1万件 | - |
| マッチング処理時間 | 4時間(夜間バッチ) | - |
| 成約率 | 1.5% | 3% |
| キャリアアドバイザー工数 | 30%がマッチング確認 | - |
| システム負荷(ピーク時) | CPU 90%超 | - |
現状のマッチングロジック
ルールベースマッチング:
1. 勤務地: 求職者希望 ∩ 求人勤務地
2. 職種: 求職者経験職種 = 求人職種
3. 年収: 求職者希望年収 ≤ 求人提示年収
4. スキル: 求職者スキル ⊇ 求人必須スキル
問題点:
- 単純なルールでは潜在的なマッチが見落とされる
- スキルの類似性が考慮されない
- 求職者の成長可能性が考慮されない解決したいこと
- AIによる高精度なマッチングスコア算出
- 日次マッチング処理の非同期・分散処理
- リアルタイムの新着求人マッチング通知
- マッチング理由の説明生成(キャリアアドバイザー支援)
- 処理のスケーラビリティ確保
成功指標(KPI)
| KPI | 現状 | 目標 | 達成期限 |
|---|---|---|---|
| マッチング精度 | 15% | 30%以上 | 3ヶ月後 |
| 処理時間 | 4時間 | 30分以内 | 1ヶ月後 |
| 成約率 | 1.5% | 3%以上 | 6ヶ月後 |
| システム負荷 | ピーク90% | ピーク50%以下 | 1ヶ月後 |
| CA工数削減 | - | 50%削減 | 3ヶ月後 |
達成目標
この演習で習得できるスキル:
技術的な学習ポイント
SQS + Lambdaによる非同期処理
- メッセージキューイング
- 並列処理とスケーリング
- デッドレターキュー
Amazon Bedrockによるマッチングスコア算出
- 埋め込みベクトル生成
- 類似度計算
- 説明生成
DynamoDBの設計パターン
- 複合キー設計
- GSIの活用
- クエリパターンの最適化
イベント駆動アーキテクチャ
- 疎結合な設計
- イベントソーシング
実務で活かせる知識
- 大量データの非同期処理設計
- AIを活用したマッチングシステム
- スケーラブルなバッチ処理
GCPとの比較
| 機能 | AWS | GCP |
|---|---|---|
| メッセージキュー | SQS | Pub/Sub |
| サーバーレス関数 | Lambda | Cloud Functions |
| NoSQL | DynamoDB | Firestore / Bigtable |
| 生成AI | Bedrock | Vertex AI |
使用するAWSサービス
メインサービス
| サービス | 役割 | 選定理由 |
|---|---|---|
| Amazon SQS | マッチング処理キュー | 大量メッセージのバッファリング |
| AWS Lambda | マッチング処理実行 | 並列スケーリング |
| Amazon Bedrock | AIマッチングスコア算出 | 高精度な類似度計算 |
| Amazon DynamoDB | 求職者・求人・マッチング結果保存 | 高速読み書き |
| Amazon SNS | 通知配信 | プッシュ通知 |
補助サービス
| サービス | 役割 |
|---|---|
| Amazon S3 | レジュメファイル保存 |
| Amazon EventBridge | 日次バッチトリガー |
| Amazon CloudWatch | 監視・ログ |
前提条件
必要な事前知識
- AWSの基本操作(S3, Lambda, DynamoDB)
- Pythonの基礎
- メッセージキューの概念
準備するもの
AWSアカウント
- Bedrock有効化(Claude 3 / Titan Embeddings)
- 適切なIAM権限
開発環境
- AWS CLI v2
- Python 3.9以上
テストデータ
- サンプル求職者データ
- サンプル求人データ
最終構成図
| コンポーネント | 役割 |
|---|---|
| EventBridge | 日次バッチのスケジュール起動 |
| Lambda Enqueue | マッチングジョブをキューに登録 |
| SQS Queue | マッチング処理キュー |
| Lambda Process | マッチング処理(N並列) |
| Lambda NewJob | 新着求人のリアルタイムマッチング |
| DynamoDB | 求職者・求人・マッチング結果データ |
| Bedrock | AI によるマッチングスコア算出 |
| SNS | マッチング通知配信 |
| User / CA | 求職者・キャリアアドバイザー(通知受信) |
データフロー
- 日次バッチ: 全求職者に対してマッチング処理をキューイング
- 並列処理: Lambdaが自動スケールして並列にマッチング実行
- スコア算出: Bedrockで求職者と求人の類似度を計算
- 結果保存: マッチング結果をDynamoDBに保存
- 通知: 高スコアマッチングをSNS経由で通知
トラブルシューティング課題
問題1: Lambdaがタイムアウト
症状:
Task timed out after 120.00 seconds
マッチング処理が完了しないヒント:
- Bedrock呼び出し回数を確認
- 求人数が多すぎないか確認
- バッチサイズの調整
解決方法:
python
# 求人数を制限
jobs = jobs_response.get('Items', [])[:50] # 上位50件のみ
# 埋め込み生成をキャッシュ(DynamoDB/ElastiCache)
def get_cached_embedding(key: str, text: str) -> list:
# キャッシュから取得、なければ生成してキャッシュ
pass問題2: SQSメッセージが処理されない
症状:
メッセージがDLQに溜まる
Lambda呼び出しエラーヒント:
- Lambda実行ロールの権限を確認
- イベントソースマッピングの設定を確認
- VisibilityTimeoutとLambda Timeoutの関係
解決方法:
bash
# イベントソースマッピング確認
aws lambda list-event-source-mappings --function-name talentbridge-process-matching-dev
# VisibilityTimeoutはLambda Timeoutの6倍以上推奨
aws sqs set-queue-attributes \
--queue-url <QUEUE_URL> \
--attributes '{"VisibilityTimeout": "720"}'問題3: マッチングスコアが全体的に低い
症状:
全てのマッチングスコアが閾値以下
高スコアマッチングが出ないヒント:
- 埋め込み生成のテキストを確認
- スコアの重み付けを調整
- 閾値を下げて検証
解決方法:
python
# スコア計算の調整
total_score = (
semantic_score * 0.5 + # 意味的類似度を重視
skill_score * 0.35 +
salary_score * 0.15
)
# 閾値を調整
SCORE_THRESHOLD = 0.6 # 0.7から下げる設計の考察ポイント
1. SQS + Lambda パターンの利点
考察ポイント:
- 疎結合による耐障害性
- 自動スケーリング
- リトライ・DLQによるエラー処理
- コスト効率(アイドル時ゼロ)
2. 埋め込みベクトルの活用
考察ポイント:
- ルールベース vs セマンティック検索
- 埋め込みのキャッシング戦略
- 次元数とコストのトレードオフ
3. マッチングスコアの設計
考察ポイント:
- 複数指標の重み付け
- ビジネス要件との整合性
- 説明可能性の確保
4. リアルタイム vs バッチ
考察ポイント:
- 新着求人の即時マッチング
- 日次バッチの必要性
- ハイブリッドアプローチ
5. スケーラビリティ
考察ポイント:
- 求職者・求人数が10倍になった場合
- Bedrockのレート制限
- コストのスケール
発展課題(オプション)
1. 埋め込みベクトルのキャッシング
- DynamoDBに埋め込みを保存
- 更新時のみ再計算
- コスト削減と高速化
2. ストリーミングマッチング
- 新着求人投稿時の即時マッチング
- DynamoDB Streamsの活用
- リアルタイム通知
3. フィードバックループ
- 応募/不応募の結果収集
- マッチングモデルの改善
- A/Bテスト
4. レコメンデーションUI
- APIエンドポイント追加
- マッチング結果の表示
- フィルタリング・ソート
5. 類似求職者検索
- 企業向け機能
- 条件に合う求職者のサジェスト
想定コストと削減方法
月額概算コスト(日次1万件マッチング想定)
| サービス | 内訳 | 月額コスト |
|---|---|---|
| Amazon Bedrock (Titan Embeddings) | 30万回 × $0.0001/1K tokens | $30 |
| Amazon Bedrock (Claude Haiku) | 5万回 × $0.00025/1K tokens | $15 |
| AWS Lambda | 30万回 × 60秒 × 512MB | $50 |
| Amazon SQS | 60万メッセージ | $0.30 |
| Amazon DynamoDB | オンデマンド | $20 |
| Amazon SNS | 通知 | $1 |
| CloudWatch | ログ | $5 |
| 合計 | 約$121(約18,000円) |
コスト削減のポイント
埋め込みキャッシング
- 求人の埋め込みを事前計算して保存
- → Bedrock呼び出し50%削減
バッチ処理の最適化
- 変更のあった求職者のみ処理
- 増分マッチング
理由生成の選択的実行
- 高スコアマッチングのみ理由生成
- → Claude呼び出し70%削減
Lambda ARM64
- Graviton2プロセッサ使用
- → Lambda コスト20%削減
リソース削除手順
bash
# CloudFormation削除
aws cloudformation delete-stack --stack-name talentbridge-matching
# DynamoDBテーブル(CloudFormation外で作成した場合)
aws dynamodb delete-table --table-name talentbridge-candidates
aws dynamodb delete-table --table-name talentbridge-jobs
aws dynamodb delete-table --table-name talentbridge-matches
# SQS(CloudFormation外)
aws sqs delete-queue --queue-url <MATCHING_QUEUE_URL>
aws sqs delete-queue --queue-url <DLQ_URL>
# SNS(CloudFormation外)
aws sns delete-topic --topic-arn <TOPIC_ARN>学習のポイント
1. SQS + Lambda の非同期処理パターン
大量データを効率的に処理する基本パターン。キューによるバッファリング、自動スケーリング、DLQによるエラー処理を組み合わせる。
2. 埋め込みベクトルを使ったセマンティック検索
テキストの意味的類似度を計算する手法。ルールベースでは捕捉できない潜在的なマッチングを発見できる。
3. 複合スコアリング
複数の指標を組み合わせて総合スコアを算出する設計。ビジネス要件に応じた重み付けが重要。
4. イベント駆動アーキテクチャ
EventBridge、SQS、SNSを組み合わせた疎結合なシステム設計。スケーラビリティと耐障害性を両立。
5. MLとビジネスロジックの統合
AI/MLの出力をビジネスロジック(年収マッチ等)と組み合わせて、実用的なシステムを構築する方法。