AIエージェント活用実践編 / 状態管理とメモリ設計
会話履歴の保存と再開 — 実装編
無料公開レッスン / 読了目安 7 分
学習のねらい
設計編で整理した永続化の方針(JSON または SQLite)を、実際にコードに落とし込みます。 JSON ファイル / SQLite データベース / セッション再開 / ユーザーIDとの紐付け の4ステップを最小コードで体験します。
JSON 形式での保存
最もシンプルな方法です。json.dump() でリストを保存し、json.load() で読み込むだけです。
import json
conversation_history = [
{"role": "user", "content": "こんにちは"},
{"role": "assistant", "content": "ごきげんよう"}
]
# 保存
with open("conversation_123.json", "w", encoding="utf-8") as f:
json.dump(conversation_history, f, ensure_ascii=False, indent=2)
# 読み込み
with open("conversation_123.json", "r", encoding="utf-8") as f:
loaded_history = json.load(f)
print(loaded_history)
ensure_ascii=False を入れると日本語がそのまま読める形で保存されます。
SQLite データベースへの保存
各会話ターンを1レコードとして保存し、session_id で束ねる方式です。
SQLite はファイルベースなので、別途サーバを立てる必要がありません。
import sqlite3
import json # contentはJSON文字列として保存
def save_message(session_id, role, content):
conn = sqlite3.connect('conversations.db')
cursor = conn.cursor()
cursor.execute('''
CREATE TABLE IF NOT EXISTS messages (
id INTEGER PRIMARY KEY AUTOINCREMENT,
session_id TEXT NOT NULL,
role TEXT NOT NULL,
content TEXT NOT NULL,
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
)
''')
cursor.execute(
"INSERT INTO messages (session_id, role, content) VALUES (?, ?, ?)",
(session_id, role, json.dumps(content)),
)
conn.commit()
conn.close()
def load_messages(session_id):
conn = sqlite3.connect('conversations.db')
cursor = conn.cursor()
cursor.execute(
"SELECT role, content FROM messages WHERE session_id = ? ORDER BY timestamp",
(session_id,),
)
messages = [{"role": row[0], "content": json.loads(row[1])} for row in cursor.fetchall()]
conn.close()
return messages
content に辞書などが入る可能性があるので、json.dumps() で文字列化して保存します。
セッション再開時の復元
会話を再開するときは、保存しておいた履歴を読み込んで LLM の messages の冒頭に含めるだけです。
from anthropic import Anthropic
client = Anthropic()
# loaded_history に JSON か SQLite から読み込んだ履歴が入っているとする
loaded_history.append({"role": "user", "content": "昨日の続きですが、あの件はどうなりましたか?"})
response = client.messages.create(
model="claude-sonnet-4-5",
max_tokens=1024,
messages=loaded_history, # 過去の履歴を含めて送信
)
print(response.content[0].text)
ユーザーIDとの紐付け
複数のユーザーが使う場合、誰の会話かを識別するために ユーザーID と会話セッションを紐付けます。
- ファイル名にユーザーIDを含める(例:
conversation_user123.json) - データベースのテーブルに
user_idカラムを追加し、インデックスを張る
これにより、ユーザーごとに独立した履歴を管理し、パーソナライズされた応答が返せます。
まとめ
会話履歴の永続化は、JSON ファイル → SQLite と段階的に発展させるのが現実的です。
セッション再開時には保存された履歴を messages 冒頭に含めて送り、ユーザーIDとセッションを必ず紐付けましょう。
次のレッスンでは、LLM の知識を補完する「知識ベース(KB)統合」について学びます。