推薦エージェントの設計
「推薦モデルができた。だが、ユーザーが『赤いワンピースが欲しい』と言ったら、どう応える?」
田中VPoEが問いかける。
「単にスコア順に商品を並べるだけじゃない。ユーザーの意図を理解し、文脈に応じた推薦理由を生成し、対話的に絞り込んでいく。LangGraphで対話型推薦エージェントを作ろう。」
対話型推薦エージェントの要件
| 機能 | 入力 | 出力 |
|---|---|---|
| 嗜好理解 | 自然言語の要望 | 抽出された嗜好条件 |
| 商品推薦 | 嗜好条件 + ユーザー履歴 | 推薦リスト + 推薦理由 |
| 絞り込み | 追加条件 | フィルタ済み推薦リスト |
| 比較 | 複数アイテムID | 比較表 + おすすめ |
| 類似商品 | アイテムID | 類似アイテムリスト |
ツールの設計
tools = {
"parse_preference": {
"description": "自然言語からユーザーの嗜好条件を抽出する",
"input": "query: str",
"output": "dict (category, style, color, price_range, occasion)",
},
"get_user_history": {
"description": "ユーザーの購入・閲覧履歴を取得する",
"input": "user_id: str",
"output": "list[dict] (item_id, action, timestamp)",
},
"recommend_items": {
"description": "ハイブリッド推薦モデルで推薦を生成する",
"input": "user_id: str, preferences: dict, n_items: int",
"output": "list[dict] (item_id, score, features)",
},
"generate_reason": {
"description": "推薦理由を自然言語で生成する",
"input": "user_profile: dict, item: dict",
"output": "str (推薦理由)",
},
"filter_items": {
"description": "条件でアイテムをフィルタリングする",
"input": "items: list, conditions: dict",
"output": "list[dict] (フィルタ済みアイテム)",
},
"compare_items": {
"description": "複数アイテムを比較分析する",
"input": "item_ids: list[str]",
"output": "dict (comparison_table, recommendation)",
},
}
State設計
from typing import TypedDict, Optional, Annotated
from operator import add
class RecommendationState(TypedDict):
# 対話
messages: Annotated[list, add]
intent: Optional[str] # "recommend", "filter", "compare", "similar"
# ユーザー情報
user_id: Optional[str]
user_history: Optional[list]
preferences: Optional[dict]
# 推薦結果
recommended_items: Optional[list]
filtered_items: Optional[list]
reasons: Optional[list]
# 対話コンテキスト
turn_count: int
conversation_context: Optional[dict]
# エラー
error: Optional[str]
ワークフロー設計
ユーザー入力
↓
[意図分類]
↓
┌──────────────────────────────────────────┐
│ "recommend" の場合: │
│ 1. parse_preference(嗜好抽出) │
│ 2. get_user_history(履歴取得) │
│ 3. recommend_items(推薦生成) │
│ 4. generate_reason(理由生成) │
│ 5. 自然言語で推薦を提示 │
├──────────────────────────────────────────┤
│ "filter" の場合: │
│ 1. parse_preference(追加条件抽出) │
│ 2. filter_items(絞り込み) │
│ 3. 絞り込み結果を提示 │
├──────────────────────────────────────────┤
│ "compare" の場合: │
│ 1. compare_items(比較分析) │
│ 2. 比較結果を提示 │
└──────────────────────────────────────────┘
ノード設計
nodes = {
"classify_intent": "ユーザーの意図を分類する",
"parse_preference": "嗜好条件を自然言語から抽出する",
"fetch_history": "ユーザーの行動履歴を取得する",
"generate_recommendations": "推薦モデルで候補を生成する",
"apply_business_rules": "ビジネスルールでリランキングする",
"generate_reasons": "各推薦の理由を生成する",
"filter_results": "追加条件で結果を絞り込む",
"compare_items": "複数アイテムを比較する",
"respond": "自然言語で回答を生成する",
"handle_error": "エラーを処理する",
}
まとめ
| 項目 | ポイント |
|---|---|
| 対話型推薦 | 嗜好理解 → 推薦 → 絞り込みの対話ループ |
| ツール | 6つ(嗜好抽出/履歴/推薦/理由生成/フィルタ/比較) |
| State | 対話コンテキストを保持し文脈を活用 |
| ビジネスルール | リランキングで在庫・マージン・多様性を考慮 |
チェックリスト
- 対話型推薦エージェントの要件を定義できる
- 必要なツールを設計できる
- State構造を設計し対話コンテキストを管理できる
- 意図に応じたワークフロー分岐を設計できる
次のステップへ
推薦エージェントの設計ができた。次はコンテキスト理解の実装を学ぼう。
推定読了時間: 30分