LESSON

推薦エージェントの設計

「推薦モデルができた。だが、ユーザーが『赤いワンピースが欲しい』と言ったら、どう応える?」

田中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分