本記事は arXiv:2309.02427 Cognitive Architectures for Language Agents の解説記事です。
論文概要(Abstract)
著者ら(Theodore Sumers, Shunyu Yao, Karthik Narasimhan, Thomas L. Griffiths, Princeton University, 2023年9月)は、認知科学のACT-R理論とProduction Systemsの知見に基づき、LLMエージェントのアーキテクチャを統一的に分類するフレームワーク「CoALA(Cognitive Architectures for Language Agents)」を提案している。CoALAはエージェントのメモリをWorking Memory(作業記憶)、Episodic Memory(エピソード記憶)、Semantic Memory(意味記憶)、Procedural Memory(手続き記憶)の4種類に分類し、既存の25以上のLLMエージェントシステムをこの枠組みで整理・比較している。
この記事は Zenn記事: LangGraph Store APIで実装するマルチエージェントRAGの共有メモリと長期記憶 の深掘りです。
情報源
- arXiv ID: 2309.02427
- URL: https://arxiv.org/abs/2309.02427
- 著者: Theodore Sumers, Shunyu Yao, Karthik Narasimhan, Thomas L. Griffiths
- 発表年: 2023
- 分野: cs.AI, cs.CL
背景と動機(Background & Motivation)
2023年以降、ReAct、Reflexion、Generative Agents、AutoGPT等、多数のLLMエージェントシステムが提案されている。しかし、これらのシステムは個別に設計されており、メモリ管理、行動選択、学習メカニズムの設計原則が体系化されていない。著者らは、認知科学における認知アーキテクチャ(ACT-R, Soar等)の知見を応用することで、LLMエージェントの設計空間を整理し、既存システムの分類と将来の設計指針を提供することを目指している。
特にメモリ管理については、多くのLLMエージェントが「短期メモリ」と「長期メモリ」という曖昧な2分類を使用しているのに対し、CoALAは認知科学の知見に基づくより精密な4分類を提案し、各メモリタイプの読み書き操作を形式化している。
主要な貢献(Key Contributions)
- 貢献1: LLMエージェントのメモリを4種類(Working / Episodic / Semantic / Procedural)に分類する体系的フレームワークの提案
- 貢献2: 各メモリタイプに対するREAD / WRITE / FORGET操作の形式的定義
- 貢献3: 既存25以上のLLMエージェントシステム(ReAct, Reflexion, Generative Agents, MemGPT, Voyager等)をCoALAフレームワークに当てはめた包括的分析
技術的詳細(Technical Details)
4種類のメモリ分類
CoALAは認知科学のACT-R理論に基づき、以下の4種類のメモリを定義している。
1. Working Memory(作業記憶) — LLMのコンテキストウィンドウ内
\[\text{WM} = \{\text{system\_prompt}, \text{recent\_messages}, \text{retrieved\_info}, \text{intermediate\_results}\}\]- 容量: コンテキストウィンドウサイズに制約(GPT-4: 128K, Claude: 200K)
- 永続性: セッション内のみ
- 操作: READ(コンテキスト参照)、WRITE(メッセージ追加)、FORGET(コンテキスト圧縮/切り詰め)
2. Episodic Memory(エピソード記憶) — 過去の経験・イベントの記録
\[\text{EM} = \{(e_i, t_i, c_i) \mid e_i \in \text{Events}, t_i \in \text{Timestamps}, c_i \in \text{Contexts}\}\]ここで、
- $e_i$: イベント内容(例: 「ユーザーがRAGの質問をした」)
- $t_i$: タイムスタンプ
$c_i$: コンテキスト情報(例: セッションID、ユーザーID)
- 容量: 外部ストレージにより制限なし
- 永続性: セッションを跨いで永続化
- 操作: READ(類似経験の検索)、WRITE(新しい経験の記録)、FORGET(古い経験の削除/要約)
3. Semantic Memory(意味記憶) — 事実・概念・知識
\[\text{SM} = \{(k_i, v_i) \mid k_i \in \text{Concepts}, v_i \in \text{Descriptions}\}\]- 容量: 外部ストレージにより制限なし
- 永続性: 半永久的
- 操作: READ(知識検索)、WRITE(新知識の蓄積)、FORGET(古い知識の更新/統合)
4. Procedural Memory(手続き記憶) — 操作手順・ルール・スキル
\[\text{PM} = \{(s_i, a_i, c_i) \mid s_i \in \text{States}, a_i \in \text{Actions}, c_i \in \text{Conditions}\}\]- 容量: LLMのパラメータ + プロンプト内のルール/Few-shot例
- 永続性: モデル重み(学習済み)+ プロンプト(更新可能)
- 操作: READ(ルール適用)、WRITE(新ルールの追加)、FORGET(非効果的ルールの削除)
既存システムのCoALAマッピング
著者らは25以上の既存システムをCoALAフレームワークにマッピングしている。以下は代表的なシステムの分類である。
| システム | Working | Episodic | Semantic | Procedural |
|---|---|---|---|---|
| ReAct | コンテキスト | なし | なし | プロンプト内のFew-shot |
| Reflexion | コンテキスト | 反省ログ | なし | プロンプト更新 |
| Generative Agents | コンテキスト | メモリストリーム | なし | なし |
| MemGPT | Core Memory | Recall Storage | Archival Storage | システムプロンプト |
| Voyager | コンテキスト | なし | なし | スキルライブラリ |
| ExpeL | コンテキスト | 経験ログ | 抽出された知見 | なし |
LangGraph Store APIへのCoALAマッピング
CoALAの4メモリ分類は、LangGraph Store APIの名前空間設計に直接マッピングできる。
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
# CoALAの4メモリ分類をLangGraph Store名前空間にマッピング
def coala_to_langgraph_namespaces(
user_id: str,
agent_id: str,
) -> dict[str, tuple[str, ...]]:
"""CoALAメモリ分類 → LangGraph Store名前空間"""
return {
# Working Memory → Checkpointer(コンテキスト内)
# LangGraph Stateとして管理、名前空間不要
# Episodic Memory → Store(経験ログ)
"episodic_user": ("memory", "episodic", user_id),
"episodic_agent": ("memory", "episodic", agent_id),
"episodic_shared": ("memory", "episodic", "shared"),
# Semantic Memory → Store(知識ベース)
"semantic_entities": ("memory", "semantic", "entities"),
"semantic_facts": ("memory", "semantic", "facts"),
"semantic_user_profile": ("memory", "semantic", user_id, "profile"),
# Procedural Memory → Store(ルール・スキル)
"procedural_rules": ("memory", "procedural", agent_id, "rules"),
"procedural_skills": ("memory", "procedural", agent_id, "skills"),
"procedural_shared": ("memory", "procedural", "shared", "best_practices"),
}
マッピングの詳細:
| CoALAメモリ | LangGraph名前空間 | 保存内容 | TTL |
|---|---|---|---|
| Working Memory | Checkpointer State | 現在のセッション状態 | セッション終了まで |
| Episodic(ユーザー) | ("memory", "episodic", user_id) | 過去の質問・回答履歴 | 90日 |
| Episodic(共有) | ("memory", "episodic", "shared") | 成功パターン | 永続 |
| Semantic(エンティティ) | ("memory", "semantic", "entities") | ドキュメントメタデータ | 永続 |
| Semantic(プロファイル) | ("memory", "semantic", user_id, "profile") | ユーザー嗜好 | 90日 |
| Procedural(ルール) | ("memory", "procedural", agent_id, "rules") | エージェント動作ルール | 永続 |
| Procedural(スキル) | ("memory", "procedural", agent_id, "skills") | 学習済みスキル | 永続 |
LangMem SDKとの対応関係
Zenn記事で解説したLangMem SDKの3種メモリ(セマンティック・エピソード・手続き)は、CoALAの分類から直接派生している。
| CoALA | LangMem SDK | 備考 |
|---|---|---|
| Semantic Memory | create_manage_memory_tool(namespace=(..., "semantic")) | 事実・知識の蓄積 |
| Episodic Memory | BackgroundMemoryManager(episodic_namespace=...) | セッション要約の自動保存 |
| Procedural Memory | BackgroundMemoryManager(procedural_namespace=...) | プロンプト改善ルール |
| Working Memory | LangGraphのState + Checkpointer | コンテキスト内情報 |
実装のポイント(Implementation)
各メモリタイプの実装パターン
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
from langgraph.store.postgres import AsyncPostgresStore
from langchain_anthropic import ChatAnthropic
import uuid
# Semantic Memory: 事実・知識の保存
async def store_semantic_memory(
store: AsyncPostgresStore,
fact: str,
category: str,
source: str,
) -> None:
"""意味記憶に新しい知識を保存
Args:
store: LangGraph Store
fact: 保存する事実
category: カテゴリ(entity, concept, rule等)
source: 情報源
"""
await store.aput(
("memory", "semantic", category),
str(uuid.uuid4()),
{
"content": fact,
"metadata": {
"source": source,
"category": category,
},
},
)
# Episodic Memory: 経験の記録
async def store_episodic_memory(
store: AsyncPostgresStore,
user_id: str,
episode_summary: str,
outcome: str,
quality_score: float,
) -> None:
"""エピソード記憶に経験を記録
Args:
store: LangGraph Store
user_id: ユーザーID
episode_summary: エピソードの要約
outcome: 結果(success/failure)
quality_score: 品質スコア
"""
await store.aput(
("memory", "episodic", user_id),
str(uuid.uuid4()),
{
"content": episode_summary,
"metadata": {
"outcome": outcome,
"quality_score": quality_score,
},
},
)
# Procedural Memory: ルールの蓄積
async def store_procedural_memory(
store: AsyncPostgresStore,
agent_id: str,
rule: str,
effectiveness: float,
) -> None:
"""手続き記憶にルールを蓄積
Args:
store: LangGraph Store
agent_id: エージェントID
rule: 学習したルール
effectiveness: 有効性スコア
"""
await store.aput(
("memory", "procedural", agent_id, "rules"),
str(uuid.uuid4()),
{
"content": rule,
"metadata": {
"effectiveness": effectiveness,
},
},
)
メモリの優先順位制御
著者らはCoALAフレームワークにおいて、Working Memoryのコンテキストウィンドウ制約下でのメモリ優先順位付けが重要であると指摘している。
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
45
46
47
48
49
async def build_context_with_priority(
store: AsyncPostgresStore,
query: str,
user_id: str,
agent_id: str,
max_tokens: int = 4096,
) -> str:
"""CoALA優先順位に基づくコンテキスト構築
優先順位:
1. Procedural Memory(ルール、最高優先)
2. Semantic Memory(関連知識)
3. Episodic Memory(過去の経験)
"""
context_parts = []
remaining_tokens = max_tokens
# 1. Procedural: エージェント動作ルール(最高優先)
rules = await store.asearch(
("memory", "procedural", agent_id, "rules"),
query=query, limit=3,
)
for rule in rules:
context_parts.append(f"[RULE] {rule.value['content']}")
remaining_tokens -= estimate_tokens(rule.value['content'])
# 2. Semantic: 関連知識
if remaining_tokens > 500:
facts = await store.asearch(
("memory", "semantic", "entities"),
query=query, limit=5,
)
for fact in facts:
if remaining_tokens > 100:
context_parts.append(f"[KNOWLEDGE] {fact.value['content']}")
remaining_tokens -= estimate_tokens(fact.value['content'])
# 3. Episodic: 過去の類似経験
if remaining_tokens > 500:
episodes = await store.asearch(
("memory", "episodic", user_id),
query=query, limit=3,
)
for ep in episodes:
if remaining_tokens > 100:
context_parts.append(f"[EXPERIENCE] {ep.value['content']}")
remaining_tokens -= estimate_tokens(ep.value['content'])
return "\n\n".join(context_parts)
注意点
- Working Memoryのオーバーフロー: コンテキストウィンドウの制約により、全メモリをWorking Memoryに入れることは不可能。著者らは優先順位付けとサマリゼーションの組み合わせを推奨している
- Episodic → Semantic変換: 多数のエピソード記憶から共通パターンを抽出してSemantic Memoryに統合する「記憶の統合(memory consolidation)」プロセスが有効。LangMem SDKのバックグラウンドマネージャーがこの役割を担う
- Procedural Memoryの更新: ルールの有効性スコアに基づくフィルタリングが重要。低スコアのルールはFORGET操作で削除すべき
実験結果(Results)
CoALAは概念論文であり、独自のベンチマーク評価は含まれていない。代わりに、著者らは既存25以上のシステムの評価結果をCoALAフレームワークで再分析している。
メモリ分類の充実度と性能の関係(著者らの分析に基づく):
| メモリ充実度 | 代表システム | 特徴 |
|---|---|---|
| WMのみ | ReAct, Chain-of-Thought | 単発タスクに限定 |
| WM + EM | Reflexion, Generative Agents | 経験から学習可能 |
| WM + EM + SM | ExpeL, ChatDB | 知識蓄積が可能 |
| WM + EM + SM + PM | MemGPT, Voyager | 全メモリ活用で最も柔軟 |
著者らは、4種すべてのメモリを活用するシステムが最も高い汎用性と適応性を示すと分析しているが、実装の複雑さとのトレードオフがあることも指摘している。
実運用への応用(Practical Applications)
CoALAの4メモリ分類は、Zenn記事で解説したLangGraph Store APIのマルチエージェントRAGアーキテクチャに直接適用できる。
- 名前空間設計の理論的根拠: CoALAの分類に基づいてStore名前空間を設計することで、メモリの可視性と永続性を理論的に正当化できる
- LangMem SDKの設計理解: LangMem SDKのセマンティック・エピソード・手続きの3分類はCoALAの直接的な実装であり、CoALAを理解することでSDKの設計意図が明確になる
- メモリ統合パイプライン: Episodic → Semantic変換(記憶の統合)をバックグラウンドジョブとして実装することで、エージェントの長期学習能力を向上できる
関連研究(Related Work)
- ACT-R(Anderson, 2007): CoALAの理論的基盤となる認知アーキテクチャ。宣言的記憶(Semantic + Episodic)と手続き的記憶(Procedural)の分類を提供
- MemGPT(Packer et al., 2023): CoALAの4メモリすべてを実装した先行システム。Core Memory(WM + SM)、Archival Memory(SM)、Recall Memory(EM)の対応関係が明確
- LangMem SDK: CoALAの3メモリタイプ(Semantic / Episodic / Procedural)を直接実装したLangGraph公式ツールキット
まとめと今後の展望
CoALAは、認知科学の知見に基づいてLLMエージェントのメモリシステムを体系的に分類するフレームワークを提供している。Working / Episodic / Semantic / Proceduralの4分類は、LangGraph Store APIの名前空間設計やLangMem SDKのメモリタイプ設計の理論的基盤として機能する。
今後の研究方向として、メモリ統合(Episodic → Semantic変換)の自動化、マルチエージェント間でのメモリ共有プロトコルの標準化、およびメモリの有効性を自動評価するベンチマークの開発が挙げられる。
参考文献
- arXiv: https://arxiv.org/abs/2309.02427
- ACT-R Theory: Anderson, J. R. (2007). How Can the Human Mind Occur in the Physical Universe?
- Related Zenn article: https://zenn.dev/0h_n0/articles/3901eb498f526c