需要予測エージェントの設計
「予測モデルは完成した。だが、物流担当者がPythonを実行して予測結果を確認するのは現実的じゃない。」
田中VPoEがホワイトボードに図を描き始める。
「『来週のミネラルウォーターの需要は?』『店舗3の発注推奨量を教えて』と聞いたら、自然言語で答えてくれるAIエージェントが必要だ。LangGraphで設計しよう。」
需要予測エージェントの要件
| 機能 | 入力 | 出力 |
|---|---|---|
| 需要予測 | 商品カテゴリ、店舗、期間 | 予測売上、信頼区間 |
| 異常検知 | カテゴリ、期間 | 異常な需要変動の検知結果 |
| 発注推奨 | カテゴリ、店舗 | 推奨発注量、発注タイミング |
| トレンド分析 | カテゴリ | 成長率、季節パターンの説明 |
| アラート | 自動 | 急変動の通知、要対応リスト |
エージェントのアーキテクチャ
ユーザーの質問
↓
┌────────────────────────────┐
│ LangGraph ワークフロー │
│ │
│ ① 意図理解ノード │
│ ↓ │
│ ② ルーティングノード │
│ ↓ │
│ ③ Tool実行ノード │
│ ├── forecast_tool │
│ ├── anomaly_tool │
│ ├── ordering_tool │
│ └── trend_tool │
│ ↓ │
│ ④ 応答生成ノード │
└────────────────────────────┘
↓
自然言語の応答
LangGraphによるワークフロー設計
from langgraph.graph import StateGraph, END
from typing import TypedDict, Annotated, Literal
import operator
# 状態の定義
class AgentState(TypedDict):
messages: Annotated[list, operator.add]
query_type: str # forecast / anomaly / ordering / trend
parameters: dict # 抽出されたパラメータ
prediction_result: dict # 予測結果
response: str # 最終応答
# ワークフローの構築
workflow = StateGraph(AgentState)
# ノードの定義
workflow.add_node("parse_query", parse_query_node)
workflow.add_node("route", route_node)
workflow.add_node("forecast", forecast_node)
workflow.add_node("anomaly", anomaly_node)
workflow.add_node("ordering", ordering_node)
workflow.add_node("trend", trend_node)
workflow.add_node("generate_response", generate_response_node)
# エッジの定義
workflow.set_entry_point("parse_query")
workflow.add_edge("parse_query", "route")
# 条件分岐
workflow.add_conditional_edges(
"route",
lambda state: state["query_type"],
{
"forecast": "forecast",
"anomaly": "anomaly",
"ordering": "ordering",
"trend": "trend",
}
)
# 各Tool実行後は応答生成へ
for node in ["forecast", "anomaly", "ordering", "trend"]:
workflow.add_edge(node, "generate_response")
workflow.add_edge("generate_response", END)
# コンパイル
app = workflow.compile()
Tool分解の設計
各Toolが明確な責務を持つように設計する。
| Tool | 責務 | 入力 | 出力 |
|---|---|---|---|
| DataFetchTool | データ取得・前処理 | カテゴリ, 店舗, 期間 | 整形済みデータ |
| ForecastTool | 予測実行 | 整形済みデータ, モデル | 予測値, 信頼区間 |
| AnomalyTool | 異常検知 | 実績データ, 予測データ | 異常フラグ, 説明 |
| OrderingTool | 発注計算 | 予測値, 在庫状況 | 発注量, タイミング |
| TrendTool | トレンド分析 | 時系列データ | 成長率, 季節パターン |
Tool設計の原則
1. 単一責務: 各Toolは1つのことだけを行う
2. 冪等性: 同じ入力には同じ出力を返す
3. エラーハンドリング: 失敗時は明確なエラーメッセージを返す
4. ログ: 実行内容と結果を記録する
5. 型安全: 入出力の型を明確に定義する
クエリパーサーの設計
from langchain_core.prompts import ChatPromptTemplate
parse_prompt = ChatPromptTemplate.from_messages([
("system", """ユーザーの質問から以下を抽出してください:
- query_type: forecast / anomaly / ordering / trend のいずれか
- family: 商品カテゴリ名(GROCERY I, BEVERAGES等)。不明なら null
- store_nbr: 店舗番号。不明なら null
- start_date: 予測開始日。不明なら明日の日付
- horizon: 予測日数。不明なら 7
JSON形式で回答してください。"""),
("human", "{query}")
])
# 使用例:
# 入力: "来週のGROCERY Iの需要を予測して"
# 出力: {"query_type": "forecast", "family": "GROCERY I",
# "store_nbr": null, "start_date": "2017-08-16", "horizon": 7}
まとめ
| 項目 | ポイント |
|---|---|
| エージェント要件 | 需要予測、異常検知、発注推奨、トレンド分析 |
| アーキテクチャ | LangGraphで4ノード構成のワークフロー |
| Tool分解 | DataFetch, Forecast, Anomaly, Ordering, Trend |
| 設計原則 | 単一責務、冪等性、エラーハンドリング |
チェックリスト
- 需要予測エージェントの5つの機能要件を説明できる
- LangGraphのワークフロー構造を理解した
- Tool分解の設計原則を把握した
- クエリパーサーの役割を理解した
次のステップへ
エージェントの全体設計ができた。次は各Toolの詳細実装に進もう。
推定読了時間: 30分