ジェネラティブエージェンツの大嶋です。
運営している勉強会コミュニティStudyCoで「【LangChainゆる勉強会#14】LangGraphの短期記憶・長期記憶をキャッチアップ」というイベントを開催しました。
アーカイブ動画はこちらです。
今回は「LangGraphの短期記憶・長期記憶をキャッチアップ」というテーマでした。
LangChain/LangGraphの公式ドキュメントや公式ブログを参照しながら、とくに新しく追加された長期記憶に関する機能を重点的に見ていきました。
今回のポイント
公式ブログ - Launching Long-Term Memory Support in LangGraph
まずは公式ブログの「Launching Long-Term Memory Support in LangGraph」という記事を読んでいきました。
このブログでは、LangGraphでの長期記憶(long-term memory)サポートの第一歩となる機能のリリースが紹介されています。
LangGraphにはもともとスレッド内で短期記憶を管理する「Checkpointer」という機能があります。
Checkpointerに加えて、スレッドを横断した長期記憶を管理する「Store」が導入されたことが紹介されています。
BaseStore、InMemoryStore
LangGraphの長期記憶のための機能として、現在提供されているのは主にBaseStoreとInMemoryStoreの2つです。
BaseStoreはStoreの抽象基底クラスで、その実装のひとつとしてInMemoryStoreが提供されています。
ソースコードは以下のあたりから参照できます。
前述の通り、まずは第一歩としてInMemoryにデータを保存するStoreが提供されているだけとなっています。
実際には長期記憶はデータベースに永続化したいことが多いと思いますが、その場合は独自で実装する必要があります。
公式ブログ - Memory for agents
続いて、公式ブログの「Memory for agents」という記事を読んでいきました。
この記事ではまず、Memoryはapplication-specific、つまりアプリケーションによってMemoryに求められる仕様が異なることが強調されています。
LangChainはMemoryのための軽量な抽象化だけを提供し、必要に応じて自在にカスタマイズできる方向で機能を提供しようとしているとのことです。
Memoryの種類
さて、上記の記事では、「Cognitive Architectures for Language Agents」という論文をベースに、Memoryの種類として、以下の3つが挙げられています。
(1)Procedural Memory - 手続き記憶
人間で言えば、自転車の乗り方を記憶するようなもの
AIエージェントでいえば、(見たことはないが)LLMの重みやコードを自動で更新するようなもの
見かける例だと、システムプロンプトを自動で更新するようなもの
(2)Semantic Memory - 意味記憶
人間で言えば、学校で学ぶような物事や、概念の意味や関係のようなもの
AIエージェントでいえば、LLMが会話から抽出して保存しておいた情報を検索してシステムプロンプトに入れるようなもの
(3)Episodic Memory - エピソード記憶
人間でいば、過去の出来事やエピソードを思い出すようなもの
AIエージェントで言えば、過去に成功したアクションをFew-shotプロンプティングの例としてプロンプトにいれるようなもの
このように、AIエージェントのMemoryといってもいくつかの種類があることが分かりやすく整理されていました。
Memoryの更新
上記の記事ではもうひとつ、Memoryの更新についても大きく2つの方法があると書かれています。
(1)in the hot path
ChatGPTのMemory機能のように、人間とAIの会話中に同期的にMemoryを更新していく
(2)in the background
人間とAIの会話とは別途、何らかのタイミングで非同期にMemoryを更新する
実際には、これら2つに加えて、この両方を実施する場合もあると思います。
公式ドキュメント - Memory
LangGraphの公式ドキュメントでも、上記のブログ記事に近い内容がまとめられています。
Memoryの保存方法(更新型と追記型)
上記の公式ドキュメントには、もう1つの観点としてMemoryの保存方法に更新型と追記型があることが書かれています。
(1)更新型
たとえばある人物の記憶をするときに、以下のような特定のデータ構造を更新していくことで記憶する方法が考えられます。
{ "name": "Tom", "age": None, "friends": ["Bob"] }
(2)追記型
一方で、以下のように記憶のレコードを次々追記していく方法も考えられます。
[ "記憶レコード1", "記憶レコード2", "記憶レコード3" ]
ドキュメントの中では、これらのトレードオフなども書かれています。
Memoryのパターンのまとめ
以上をまとめると、AIエージェントのMemoryには以下のようなパターンがあると整理されています。
- Memoryの種類
- Memoryの更新
- in the hot path ... 人間とAIの会話中に同期的にMemoryを更新していく
- in the background ... 人間とAIの会話とは別途、何らかのタイミングで非同期にMemoryを更新する
- Memoryの保存方法
- 更新型 ... 特定のデータ構造を更新していく
- 追記型 ... 記憶のレコードを次々追記していく
これらの組み合わせは状況に応じて多様だと思いますが、ベースとしてこのような理解を持っているとヒントになることも多いのではないでしょうか。
おわりに
以上、LangGraphのMemory、とくに長期記憶についてみていきました。
MemoryはLangChainがかなり力を入れようと分野だと思うので、このタイミングでキャッチアップできてよかったです。
LangChain / LangGraph、その他のテーマで引き続き勉強会を開催していきます。 もしも「こんな話が聞きたい」というテーマがあれば、ぜひお声がけください!