OpenAIが「Dreaming」という名前でChatGPTの新しいメモリシステムを発表した。
会話をまたいでユーザーの好みやコンテキストをより自然に保持する、というやつだ。
読んだ瞬間に「あ、自分のアプリのメモリ設計、ぜんぜん甘かったな」と思った。
個人開発で作ってるチャットアシスタント、ざっくり言うと直近10ターン分のmessagesをそのままAPIに渡す設計になってる。
token数の上限に当たったら古い順にぶった切る、みたいな雑な実装だ。
これで半年ぐらい動かしてたけど、正直ずっと「まあ動いてるからいいか」で止まってた。
OpenAIのDreamingの発想は、会話が終わった後にバックグラウンドで情報を整理・要約して、次の会話に使えるかたちに変換しておく、というアプローチらしい。
人間が寝てる間に記憶を整理するのと同じイメージで「Dreaming」と呼んでる。
これ、自分のアプリに取り込めるかどうかをとりあえず考えてみた。
現状の実装イメージはこんな感じ。
これだと10ターン以前の情報は完全に消える。
たとえばユーザーが「Pythonよりもときいえず思っていて......」みたいな好みを話していても、11ターン目以降は忘れたことになる。えぐい損失だ。
Dreamingの考え方を真似るなら、会話セッションが終了したタイミングで要約を生成してDBに保存する処理を挟む設計に変える必要がある。
これをちゃんとやるには、「セッション終了を検知する仕組み」と「要約生成のプロンプト設計」と「コスト管理」の3つが必要になる。
要約生成で余計なAPIコールが増えるのが一番気になるところだ。
LLMまわりを触り始めてから、一番ハマってるのがコスト設計だ。
今月の個人開発のAPI費用、先月より1.4倍になってた。
メモリを豊かにすれば体験は上がるけど、要約生成ごとにgpt-4oを叩いてたら請求が怖い。
ここはgpt-4o-miniで要約だけ回す、という分離ができそうだ。
重い推論はminiに任せて、本番の応答品質は落とさない構成。
コスト対効果でいうと悪くない気がしてる。
彼女に「最近また課金増えてる?」ってツッコまれたのもあって、個人開発のコスト上限をちゃんとコードで管理しようと思い始めてる。
月ごとにtokenカウントを集計して、一定を超えたらフォールバックでminiに切り替えるガードを入れるだけでもだいぶ違うはずだ。
Dreamingの発表は、OpenAIがインフラ側でメモリを持つ話だから、自分たちのアプリとはレイヤーが違う。
でも「会話を終えた後に情報を圧縮・整理して保持する」という設計思想は、自分のアプリでも普通に使えるパターンだ。
ChatGPTが本番でやってることをOSSのフレームワークで再現するのが個人開発の醍醐味だとも思う。
とりあえず今週末、session終了フックと要約プロンプトだけ書いて、手元の環境で動かしてみる。
それが一番早い。
会話をまたいでユーザーの好みやコンテキストをより自然に保持する、というやつだ。
読んだ瞬間に「あ、自分のアプリのメモリ設計、ぜんぜん甘かったな」と思った。
いまの自分のメモリ実装ってどうなってたっけ
個人開発で作ってるチャットアシスタント、ざっくり言うと直近10ターン分のmessagesをそのままAPIに渡す設計になってる。
token数の上限に当たったら古い順にぶった切る、みたいな雑な実装だ。
これで半年ぐらい動かしてたけど、正直ずっと「まあ動いてるからいいか」で止まってた。
OpenAIのDreamingの発想は、会話が終わった後にバックグラウンドで情報を整理・要約して、次の会話に使えるかたちに変換しておく、というアプローチらしい。
人間が寝てる間に記憶を整理するのと同じイメージで「Dreaming」と呼んでる。
これ、自分のアプリに取り込めるかどうかをとりあえず考えてみた。
自分のコードのどこを直すか
現状の実装イメージはこんな感じ。
# 直近の会話履歴をそのまま詰め込んでいる
messages = conversation_history[-10:]
response = client.chat.completions.create(
model="gpt-4o",
messages=messages
)これだと10ターン以前の情報は完全に消える。
たとえばユーザーが「Pythonよりもときいえず思っていて......」みたいな好みを話していても、11ターン目以降は忘れたことになる。えぐい損失だ。
Dreamingの考え方を真似るなら、会話セッションが終了したタイミングで要約を生成してDBに保存する処理を挟む設計に変える必要がある。
# 新しい設計イメージ
memory_store:
session_summary: "各セッション終了後にLLMで要約生成"
user_preferences: "抽出したPreferenceをKV形式で保存"
retrieval: "次回セッション開始時にsummary+preferenceをsystem promptに注入"これをちゃんとやるには、「セッション終了を検知する仕組み」と「要約生成のプロンプト設計」と「コスト管理」の3つが必要になる。
要約生成で余計なAPIコールが増えるのが一番気になるところだ。
コストとのトレードオフが本番の悩みどころ
LLMまわりを触り始めてから、一番ハマってるのがコスト設計だ。
今月の個人開発のAPI費用、先月より1.4倍になってた。
メモリを豊かにすれば体験は上がるけど、要約生成ごとにgpt-4oを叩いてたら請求が怖い。
ここはgpt-4o-miniで要約だけ回す、という分離ができそうだ。
重い推論はminiに任せて、本番の応答品質は落とさない構成。
コスト対効果でいうと悪くない気がしてる。
彼女に「最近また課金増えてる?」ってツッコまれたのもあって、個人開発のコスト上限をちゃんとコードで管理しようと思い始めてる。
月ごとにtokenカウントを集計して、一定を超えたらフォールバックでminiに切り替えるガードを入れるだけでもだいぶ違うはずだ。
Dreamingの発表は、OpenAIがインフラ側でメモリを持つ話だから、自分たちのアプリとはレイヤーが違う。
でも「会話を終えた後に情報を圧縮・整理して保持する」という設計思想は、自分のアプリでも普通に使えるパターンだ。
ChatGPTが本番でやってることをOSSのフレームワークで再現するのが個人開発の醍醐味だとも思う。
とりあえず今週末、session終了フックと要約プロンプトだけ書いて、手元の環境で動かしてみる。
それが一番早い。