論文概要(Abstract)
本記事は Agent Workflow Memory(Zhu et al., 2024)の解説記事です。
Agent Workflow Memory(AWM)は、LLMエージェントが過去に成功したタスク実行から「再利用可能なワークフロースニペット」を抽出・記憶し、新しいタスクに適用するフレームワークである。ワークフローは有向グラフ構造(ノード=アクション、エッジ=条件遷移)として保存され、タスク実行時に類似ワークフローを検索して適用する。著者らはWebArenaおよびMind2Webベンチマークで評価を行い、ワークフロー記憶なしのベースライン比で最大14.9%のタスク成功率向上を報告している。
この記事は Zenn記事: LangGraph 1.2でステートマシン設計:条件分岐・並列実行・本番運用パターン の深掘りです。
情報源
- arXiv ID: 2406.14928
- URL: https://arxiv.org/abs/2406.14928
- 著者: Zihan Zhu et al.
- 発表年: 2024
- 分野: cs.AI, cs.CL
背景と動機(Background & Motivation)
LLMエージェントは個々のタスクを独立して処理するため、同種のタスクを繰り返し実行する場合でも毎回ゼロから推論を行う。人間のオペレーターは経験から「手順テンプレート」を学習し再利用するが、従来のLLMエージェントにはこの能力がなかった。
AWMが解決する課題:
- 経験の再利用不可: 過去の成功パターンが蓄積されない
- 一貫性の欠如: 同じタスクでも実行ごとに異なるアプローチを取る
- 効率の低下: 既知のパターンでも探索的な推論が必要
主要な貢献(Key Contributions)
- 貢献1: タスク実行トレースから再利用可能なワークフローを有向グラフとして自動抽出する手法の提案
- 貢献2: ワークフローの検索・適用メカニズム(embedding類似度ベース)の設計
- 貢献3: WebArenaで最大+14.9%、Mind2Webで有意な改善を実証
- 貢献4: ワークフローの粒度(granularity)が性能に与える影響の分析
技術的詳細(Technical Details)
ワークフローの有向グラフ表現
AWMではワークフローを以下の形式で表現する:
\[W = (V, E, \phi)\]ここで、
- $V = {v_1, v_2, \ldots, v_n}$: ノード集合(各ノードはアクション)
- $E \subseteq V \times V$: エッジ集合(遷移関係)
- $\phi: E \rightarrow \mathcal{C}$: エッジの条件ラベル(遷移条件)
この形式はLangGraph 1.2のStateGraph定義と構造的に同型である:
| AWM要素 | LangGraph 1.2対応 |
|---|---|
| ノード $v_i$ | add_node("name", function) |
| エッジ $e_{ij}$ | add_edge("src", "dst") |
| 条件ラベル $\phi(e)$ | add_conditional_edges(path=router) |
| ワークフロー $W$ | コンパイル済みStateGraph |
ワークフロー抽出アルゴリズム
成功したタスク実行トレース $\tau = (a_1, o_1, a_2, o_2, \ldots, a_n, o_n)$ からワークフローを抽出する手順:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
def extract_workflow(trace: list[tuple[str, str]]) -> Workflow:
"""成功トレースからワークフローを抽出
Args:
trace: (action, observation)のペア列
Returns:
有向グラフとしてのワークフロー
"""
nodes = []
edges = []
for i, (action, observation) in enumerate(trace):
# アクションをノードとして抽出(抽象化)
abstract_action = abstract(action)
nodes.append(abstract_action)
if i > 0:
# 遷移条件をobservationから抽出
condition = extract_condition(trace[i-1][1])
edges.append((nodes[i-1], nodes[i], condition))
# 重複ノードの統合(ループ検出)
workflow = merge_duplicate_nodes(nodes, edges)
return workflow
ワークフロー検索と適用
新タスク $q$ に対して、保存済みワークフロー集合 $\mathcal{W}$ から最も関連性の高いワークフローを検索する:
\[W^* = \arg\max_{W \in \mathcal{W}} \text{sim}(\text{embed}(q), \text{embed}(W.\text{description}))\]ここで $\text{sim}$ はコサイン類似度、$\text{embed}$ はテキスト埋め込み関数である。
著者らは検索のtop-k値について実験を行い、k=3が最適であることを報告している(論文Section 5.3)。k=1では汎化が不十分、k=5以上ではノイズが増加し性能が低下する。
LangGraphのCheckpointerとの関連
AWMのワークフロー記憶は、LangGraph 1.2のCheckpointerの概念を「タスク間」に拡張したものと解釈できる:
| 機能 | LangGraph Checkpointer | AWM |
|---|---|---|
| 保存対象 | 実行中の状態スナップショット | 成功した実行パターン全体 |
| 用途 | 中断・再開(同一タスク内) | パターン再利用(タスク間) |
| ストレージ | PostgreSQL / Redis | ベクトルDB + グラフDB |
| 検索 | thread_id(完全一致) | embedding類似度(近似検索) |
1
2
3
4
5
6
7
8
9
10
11
# LangGraph 1.2のCheckpointer: 同一セッションの中断・再開
config = {"configurable": {"thread_id": "session-001"}}
result = await graph.ainvoke(state, config=config)
# AWMの記憶: 過去の成功パターンの検索・適用
similar_workflows = memory.search(
query=current_task_description,
top_k=3,
)
# 検索されたワークフローをプロンプトに注入
enhanced_prompt = inject_workflows(base_prompt, similar_workflows)
実装のポイント(Implementation)
ワークフロー粒度の設計
著者らが報告する最も重要な設計判断は「ワークフローの粒度」である:
- 粗粒度: タスク全体を1つのワークフローとして保存。汎化しにくい(特定タスクへの過適合)
- 細粒度: 個々のアクションを保存。検索精度が低下(文脈不足)
- 中粒度(推奨): 3-7ステップのサブタスク単位で保存。汎化と特異性のバランスが最適
LangGraph 1.2でのサブグラフ分割の粒度設計にも同じ原則が適用される。サブグラフは「独立してテスト可能かつ再利用可能な単位」として設計すべきである。
失敗トレースからの学習
著者らは失敗トレースからのワークフロー抽出について警告している。失敗パターンを「避けるべきワークフロー」として負例に使用する試みは、実験では有意な改善を示さなかったと報告されている。
実験結果(Results)
WebArenaベンチマーク(論文Table 1より)
| 手法 | Task Success Rate |
|---|---|
| Zero-shot (GPT-4) | 14.4% |
| Few-shot (3 examples) | 17.2% |
| AWM (k=3) | 29.3% |
| AWM (k=1) | 25.8% |
| AWM (k=5) | 27.1% |
AWMによる改善: Zero-shot比 +14.9ポイント(相対+103%改善)
Mind2Webベンチマーク
| 手法 | Element Accuracy | Step Success Rate |
|---|---|---|
| Baseline | 41.6% | 34.2% |
| AWM | 48.3% | 41.7% |
著者らは「ワークフロー記憶の効果はタスクの反復性が高いドメインで顕著」と結論づけている。カスタマーサポート、定型業務処理、テスト自動化などが好適なドメインとして挙げられている。
実運用への応用(Practical Applications)
AWMの概念をLangGraph 1.2で実装する場合の応用例:
- カスタマーサポート: 頻出する問い合わせパターンをワークフローとして記憶し、類似問い合わせ時に自動適用
- CI/CDパイプライン: 過去の成功デプロイ手順をワークフローとして保存し、新規デプロイ時に再利用
- データ分析: 定型的な分析手順(EDA→前処理→モデリング→評価)をテンプレート化
LangGraph 1.2での実装アプローチ:
- Checkpointerで各実行の全状態を保存
- 成功完了したグラフ実行からワークフローパターンを事後抽出
- 新規タスク開始時にベクトル検索で類似ワークフローを取得
- 検索結果をシステムプロンプトに注入(few-shot的活用)
関連研究(Related Work)
- Voyager (Wang et al., 2023): Minecraftでスキルを自動獲得・再利用するLLMエージェント。AWMはVoyagerのスキルライブラリを有向グラフ構造に拡張
- MemGPT (Packer et al., 2023): 仮想メモリ管理によるLLMの長期記憶。AWMはタスクレベルの記憶に特化
- ExpeL (Zhao et al., 2023): 経験からの学習。AWMはExperienceをグラフ構造で保存する点が差別化
まとめと今後の展望
Agent Workflow Memoryは「エージェントの経験を有向グラフとして構造化し再利用する」というアプローチにより、LLMエージェントの効率と一貫性を向上させている。LangGraph 1.2のStateGraphが「実行時のワークフロー定義」であるのに対し、AWMは「経験から学習したワークフロー」であり、両者は補完関係にある。
今後の方向性として、LangGraphのCheckpointer保存データからワークフローパターンを自動抽出し、新規タスクの開始時にグラフ構造自体を動的に生成するアプローチが考えられる。
Production Deployment Guide
AWS実装パターン(コスト最適化重視)
AWMを組み込んだLLMエージェントシステムのAWS構成を示す。
トラフィック量別の推奨構成:
| 規模 | 月間リクエスト | 推奨構成 | 月額コスト | 主要サービス |
|---|---|---|---|---|
| Small | ~3,000 | Serverless | $150-350 | Lambda + Bedrock + OpenSearch Serverless |
| Medium | ~30,000 | Hybrid | $700-1,800 | ECS + OpenSearch + ElastiCache |
| Large | 300,000+ | Container | $4,000-9,000 | EKS + OpenSearch + Neptune |
ワークフロー記憶ストレージの選択:
- ベクトル検索: OpenSearch Serverless(小規模)またはOpenSearch Managed(大規模)
- グラフDB: Amazon Neptune(ワークフローの有向グラフ構造保存)
- キャッシュ: ElastiCache Redis(頻出ワークフローの高速アクセス)
上記は2026年6月時点のAWS ap-northeast-1料金概算。最新は AWS料金計算ツール で確認。
Terraformインフラコード
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
resource "aws_opensearchserverless_collection" "workflow_memory" {
name = "agent-workflow-memory"
type = "VECTORSEARCH"
}
resource "aws_opensearchserverless_access_policy" "workflow_access" {
name = "workflow-memory-access"
type = "data"
policy = jsonencode([{
Rules = [{
ResourceType = "index"
Resource = ["index/agent-workflow-memory/*"]
Permission = ["aoss:*"]
}]
Principal = [aws_iam_role.agent_lambda.arn]
}])
}
resource "aws_lambda_function" "workflow_extractor" {
function_name = "workflow-extractor"
role = aws_iam_role.agent_lambda.arn
handler = "extractor.handler"
runtime = "python3.12"
timeout = 300
memory_size = 2048
environment {
variables = {
OPENSEARCH_ENDPOINT = aws_opensearchserverless_collection.workflow_memory.collection_endpoint
EMBEDDING_MODEL = "amazon.titan-embed-text-v2:0"
TOP_K = "3"
}
}
}
resource "aws_dynamodb_table" "workflow_metadata" {
name = "workflow-metadata"
billing_mode = "PAY_PER_REQUEST"
hash_key = "workflow_id"
attribute { name = "workflow_id"; type = "S" }
ttl { attribute_name = "expire_at"; enabled = true }
}
コスト最適化チェックリスト
- OpenSearch Serverless: 低トラフィック時に最適(OCU自動スケール)
- Titan Embed v2: embedding生成コスト $0.02/1M tokens
- top-k=3: 検索精度とコストのバランス最適値
- ワークフローTTL: 90日未使用で自動削除
- キャッシュレイヤ: 頻出ワークフローをElastiCacheに保存
- バッチ抽出: 成功トレースからのワークフロー抽出は非同期バッチ処理
参考文献
- arXiv: https://arxiv.org/abs/2406.14928
- Related Zenn article: https://zenn.dev/0h_n0/articles/68254f67c81a10