AIエージェント入門

Letta完全ガイド2026|記憶を持つAIエージェントをPythonで実装

この記事の結論

Letta(旧MemGPT)の使い方を完全解説。Core・Recall・Archivalの3層メモリ構造、Python SDKでのエージェント定義、PostgreSQL永続化まで実装コードつきで紹介します。

「AIエージェントって、会話が終わったら全部忘れるんでしょ?」

実際に10社以上のAIエージェント導入を支援する中で、最もよく聞かれる質問のひとつです。LangChainやCrewAIで試作したエージェントが「毎回ゼロから始まる」問題にぶつかり、諦めてしまったチームも少なくありません。

この記事で紹介するLetta(旧MemGPT後継)は、その課題をアーキテクチャレベルで解決するOSSフレームワークです。GitHubスター22,400以上(2026年3月時点)を獲得し、ステートフルエージェントのデファクトスタンダードとして急速に普及しています。本記事はLettaフレームワークの実装ガイドです。記憶設計の理論についてはAIエージェント記憶設計パターン記憶タイプ実装ガイドを参照してください。

この記事では、Lettaのインストールから3層メモリ構造、Python SDKでのエージェント定義、PostgreSQL本番構成まで、コードつきで全工程を解説します。5分でローカル動作を確認できますので、ぜひ試してみてください。

この記事でわかること

  • LettaのCore・Recall・Archivalメモリ3層の違いと使い分け
  • Python SDK(letta-client)でのエージェント作成・メモリ操作の実装方法
  • SQLite(開発)→ PostgreSQL(本番)への移行手順
  • LangGraph・CrewAIとの設計思想の違い
  • 本番運用でやりがちな失敗パターン4選と回避策

対象読者: PythonでAIエージェントを構築したい開発者・ML Engineer

今日やること: pip install letta-client → ローカルでエージェントを1つ作成する


Letta(旧MemGPT)とは何か:MemGPTからの進化

Lettaは、UC BerkeleyのSky Computing Labが発表した論文「MemGPT」をベースに開発されたAIエージェントプラットフォームです。2024年にMemGPTがLettaとしてブランド変更・商業化され、2026年3月時点でv0.16.7がリリースされています。

MemGPTの核心的なアイデアは「LLMをOSのように使う」というものでした。従来のLLMはコンテキストウィンドウという有限のRAMしか持ちませんでしたが、MemGPTはOSがRAMとディスクを管理するように、LLMがコンテキストとストレージを自律的に管理する仕組みを実現しました。

Lettaはこのアーキテクチャを引き継ぎつつ、以下を追加しています:

  • REST API + Python/TypeScript SDK:マネージドサービスとしても使える
  • Agent File (.af) 形式:ステートフルエージェントをファイルとしてシリアライズ・共有
  • マルチエージェント対応:Shared Blocksで複数エージェントが記憶を共有
  • MCP(Model Context Protocol)ツール統合:外部ツールとの連携

LangGraph・CrewAIとの設計思想の違い

フレームワーク 主な設計思想 記憶の扱い 向いているユースケース
Letta 記憶を持つステートフルエージェント Core/Recall/Archivalの3層管理。エージェントが自律的に書き換え 長期継続会話、パーソナライズBot、学習するアシスタント
LangGraph ワークフロー管理・グラフ型DAG StateGraphで短期状態を管理。長期記憶は外付けが必要 複雑な多段ワークフロー、Human-in-the-loop処理
CrewAI 役割分担型マルチエージェント 組み込み記憶なし。タスク完了型のため状態管理は最小限 分業タスク自動化、レポート生成、リサーチパイプライン

一言でまとめると、「エージェントが何かを覚えて学習していく」設計が必要なら Letta、ワークフローの制御が主目的なら LangGraph、複数エージェントの役割分担なら CrewAIという選び方が基本です。

LangGraphとの詳細比較はLangGraph v1.0完全ガイドを参照してください。


Lettaのメモリ3層アーキテクチャ:Core / Recall / Archival

Lettaを理解するうえで最も重要なのが、このメモリ階層です。OSのメモリ管理になぞらえると理解しやすいです。

Core Memory(コアメモリ):常時コンテキストにあるRAM

Core Memoryは常にLLMのコンテキストウィンドウに含まれる「カーネルメモリ」です。エージェントのペルソナ定義、ユーザーの基本情報、重要な設定値などを保持します。

  • サイズが小さい(トークン制限あり)が、常に参照可能
  • エージェントが自律的に書き換える(core_memory_append / core_memory_replace ツール)
  • デフォルトで persona(エージェント人格)と human(ユーザー情報)の2ブロックが存在

Recall Memory(リコールメモリ):会話履歴DB

Recall Memoryは全会話ログを格納するデータベースです。コンテキストウィンドウには入りきらないが、日時・内容での検索で取り出せます。

  • エージェントが conversation_search ツールで検索
  • 「先週の会議で決まったことは?」といった問いに対応できる
  • PostgreSQL使用時は全文検索インデックスが効く

Archival Memory(アーカイバルメモリ):ベクトル検索付き長期ストレージ

Archival Memoryはベクトル埋め込みを使ったセマンティック検索が可能な外部ストレージです。

  • エージェントが archival_memory_insert / archival_memory_search ツールで操作
  • ドキュメントや過去の知識を大量に格納できる
  • 類似度検索で関連情報を引き出す

補足: メモリ分類の理論的背景(エピソード記憶・意味記憶・手続き記憶)についてはAIエージェントのメモリ分類設計(短期・長期・エピソード)で解説しています。本記事は Letta の実装に集中します。


インストールと初期設定

Lettaには2つの使い方があります。マネージドAPI(app.letta.com)を使う方法と、セルフホストする方法です。ここではPython SDKを使ったAPIアクセスから始めます。

Step 1: Python SDKのインストール

LettaのPython SDKは letta-client パッケージです(旧 letta パッケージと別物)。

# Python SDKインストール
pip install letta-client

# 動作環境: Python 3.9+, letta-client 0.16.x

Step 2: APIキーの設定

app.letta.com/api-keys でAPIキーを発行し、環境変数に設定します。

# .env ファイルを使う場合
LETTA_API_KEY=your-api-key-here
OPENAI_API_KEY=your-openai-api-key

# シェルに直接設定する場合
export LETTA_API_KEY="your-api-key-here"
export OPENAI_API_KEY="your-openai-api-key"

Step 3: セルフホスト(Dockerを使う場合)

ローカル環境でセルフホストしたい場合は、Docker Composeを使います。

# セルフホスト(SQLite使用 — 開発用)
docker run -p 8283:8283 letta/letta:latest

# PostgreSQL使用(本番推奨)
docker run -p 8283:8283 \
  -e LETTA_PG_URI="postgresql://postgres:PASSWORD@your-db-host:5432/postgres" \
  -e OPENAI_API_KEY="your-openai-api-key" \
  letta/letta:latest
# セルフホスト環境に接続する場合のクライアント初期化
from letta_client import Letta

client = Letta(base_url="http://localhost:8283")

# マネージドAPI(app.letta.com)を使う場合
import os
client = Letta(api_key=os.getenv("LETTA_API_KEY"))

動作環境: Docker 24.x+, Python 3.9+, letta-client 0.16.x

注意: 本番環境で使用する前に、必ずテスト環境で動作確認してください。


エージェント定義:Python SDKで作るはじめてのステートフルエージェント

Lettaのエージェント作成は、モデル指定とメモリブロックの初期値を渡すだけです。ここでは「プロジェクト管理アシスタント」を例に作ってみましょう。

基本的なエージェント作成

import os
from letta_client import Letta

# クライアント初期化
client = Letta(api_key=os.getenv("LETTA_API_KEY"))

# ステートフルエージェントを作成
agent = client.agents.create(
    name="project-assistant",
    model="openai/gpt-4o",
    # Core Memory の初期値を定義
    memory_blocks=[
        {
            "label": "persona",
            "value": (
                "あなたはプロジェクト管理の専門家です。"
                "ユーザーのタスク、締め切り、進捗状況を継続的に把握し、"
                "次のアクションを提案します。"
            )
        },
        {
            "label": "human",
            "value": (
                "ユーザー名: 未設定\n"
                "所属チーム: 未設定\n"
                "現在のプロジェクト: 未設定\n"
                "優先事項: 未設定"
            )
        }
    ],
    # 利用するツールを指定
    tools=["core_memory_append", "core_memory_replace",
           "archival_memory_insert", "archival_memory_search",
           "conversation_search"]
)

print(f"エージェントID: {agent.id}")
# 出力例: エージェントID: agent-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

エージェントにメッセージを送る

# エージェントに自己紹介させてユーザー情報を記憶させる
response = client.agents.messages.create(
    agent_id=agent.id,
    messages=[
        {
            "role": "user",
            "content": "こんにちは。私は田中と申します。ECサイトのリニューアルプロジェクトを担当しています。今週の金曜日が要件定義のデッドラインです。"
        }
    ]
)

# 応答メッセージを表示
for message in response.messages:
    if hasattr(message, "text") and message.text:
        print(f"[{message.message_type}] {message.text}")

# 次のセッションでもユーザー情報を覚えている
response2 = client.agents.messages.create(
    agent_id=agent.id,
    messages=[{"role": "user", "content": "私の名前覚えていますか?"}]
)
# → 「田中さんですね。ECサイトのリニューアルプロジェクトのデッドラインが金曜日でしたね」と返答する

ポイント: agent.id を保存しておけば、セッションをまたいでも同じエージェントに接続できます。エージェントの状態はLettaのサーバー(またはDB)に永続化されているため、プロセスを再起動しても記憶は消えません。


メモリ操作の基礎:pin / search / archive

Lettaのメモリ操作は「エージェント自身が行う(ツール経由)」と「開発者がAPIで直接行う」の2種類があります。ここでは開発者がAPIで直接操作する方法を紹介します。

Core Memoryの読み取りと更新

# Core Memoryブロックを取得
human_block = client.agents.blocks.retrieve(
    agent_id=agent.id,
    block_label="human"
)
print(human_block.value)
# 出力: エージェントが自律的に更新した最新のユーザー情報

# Core Memoryを開発者が直接更新(エージェントを介さない方法)
client.agents.blocks.modify(
    agent_id=agent.id,
    block_label="human",
    value=(
        "ユーザー名: 田中\n"
        "所属チーム: Webチーム\n"
        "現在のプロジェクト: ECサイトリニューアル\n"
        "優先事項: 要件定義(金曜日締め切り)"
    )
)

Archival Memoryへの挿入と検索

# Archival Memoryに知識を追加する
client.agents.archival_memory.create(
    agent_id=agent.id,
    text=(
        "2026-05-01 キックオフMTG議事録: "
        "ECサイトリニューアルの目標はモバイル転換率を現状の2.3%から5%に引き上げること。"
        "主要機能: カート改善、決済フロー短縮、レコメンド強化。"
        "予算: 300万円。スケジュール: 3ヶ月。"
    )
)

# Archival Memoryをセマンティック検索
results = client.agents.archival_memory.list(
    agent_id=agent.id,
    query="ECサイトの目標転換率",
    limit=5
)
for passage in results.passages:
    print(f"スコア: {passage.score:.3f}")
    print(f"内容: {passage.text[:100]}...")

Recall Memory(会話履歴)の検索

# 会話履歴を日時フィルタで検索
messages = client.agents.messages.list(
    agent_id=agent.id,
    limit=20,
    # 最新20件を取得
)

for msg in messages.messages:
    print(f"[{msg.created_at}] {msg.role}: {str(msg.content)[:80]}")

注意: 本番環境で使用する前に、必ずテスト環境で動作確認してください。APIの仕様は letta-client のバージョンによって変わる場合があります(本記事は v0.16.x 時点の情報です)。


永続化バックエンドの設定:SQLite(開発)→ PostgreSQL(本番)

LettaはデフォルトでSQLiteを使いますが、本番環境ではPostgreSQLへの移行が必須です。SQLiteはデータマイグレーションが公式にサポートされていないため、バージョンアップ時のデータ継続性が保証されません。

PostgreSQL環境の準備

-- PostgreSQLにpgvector拡張をインストール(Archival Memory用)
-- Aurora PostgreSQL または PostgreSQL 15+ で実行
CREATE EXTENSION IF NOT EXISTS vector;
CREATE DATABASE letta_db;

環境変数の設定

# .env ファイル(本番用)
LETTA_PG_URI=postgresql://letta_user:secure_password@your-db-host:5432/letta_db
OPENAI_API_KEY=your-openai-api-key

# Docker起動コマンド(本番構成)
docker run -d \
  --name letta-server \
  -p 8283:8283 \
  --env-file .env \
  letta/letta:latest

Kubernetes本番構成(Horizontal Scaling)

# letta-deployment.yaml(Kubernetes)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: letta-server
spec:
  replicas: 3
  selector:
    matchLabels:
      app: letta
  template:
    metadata:
      labels:
        app: letta
    spec:
      containers:
      - name: letta
        image: letta/letta:latest
        ports:
        - containerPort: 8283
        env:
        - name: LETTA_PG_URI
          valueFrom:
            secretKeyRef:
              name: letta-secrets
              key: pg-uri
        - name: OPENAI_API_KEY
          valueFrom:
            secretKeyRef:
              name: letta-secrets
              key: openai-key
        resources:
          requests:
            memory: "512Mi"
            cpu: "250m"
          limits:
            memory: "2Gi"
            cpu: "1000m"

AWSを使う場合はAWS公式ブログ(Aurora PostgreSQL + Letta)が詳しいです。Letta公式でもAuroraとの構成が推奨されており、最小構成(0.5 ACU)から始められます。

注意: 本番環境で使用する前に、必ずテスト環境で動作確認してください。セキュリティグループでDBへのアクセスを制限し、接続文字列は必ずシークレット管理に入れてください。


マルチエージェントでのShared Memory設計

Lettaのユニークな機能のひとつが「Shared Blocks」です。複数のエージェントが同一のCore Memoryブロックを共有することで、チーム知識を同期できます。

import os
from letta_client import Letta

client = Letta(api_key=os.getenv("LETTA_API_KEY"))

# 共有メモリブロックを作成(チームナレッジ)
shared_block = client.blocks.create(
    label="team_knowledge",
    value=(
        "チームナレッジ v1.0\n"
        "- 主要顧客: A社(自動車)、B社(小売)、C社(金融)\n"
        "- 共通技術スタック: Python 3.11, FastAPI, PostgreSQL\n"
        "- エスカレーション先: 田中(PM)、鈴木(Tech Lead)"
    ),
    limit=2000  # トークン上限
)

# 複数エージェントに同じブロックをアタッチ
sales_agent = client.agents.create(
    name="sales-agent",
    model="openai/gpt-4o",
    memory_blocks=[
        {"label": "persona", "value": "営業支援AIです。"},
        {"label": "human", "value": ""}
    ],
    block_ids=[shared_block.id]  # 共有ブロックをアタッチ
)

support_agent = client.agents.create(
    name="support-agent",
    model="openai/gpt-4o",
    memory_blocks=[
        {"label": "persona", "value": "カスタマーサポートAIです。"},
        {"label": "human", "value": ""}
    ],
    block_ids=[shared_block.id]  # 同じブロックを共有
)

print(f"営業エージェント: {sales_agent.id}")
print(f"サポートエージェント: {support_agent.id}")
# → 両エージェントが同じ team_knowledge を参照・更新できる

この設計により、一方のエージェントが顧客情報を更新すると、もう一方も即座に最新情報を参照できます。CRMボットのような「複数チャネルで統一した顧客理解」が必要なシステムに効果的です。


【要注意】本番で踏みがちな失敗パターン4選

失敗1: SQLiteのままバージョンアップしてデータが消える

開発環境のSQLiteをそのまま本番で使い続け、letta パッケージをアップグレードしたらマイグレーションが失敗してエージェントのメモリが全消滅するパターンです。

docker run letta/letta:latest(デフォルトのSQLite)を本番で継続使用

⭕ 開発段階からPostgreSQLを使うか、本番切り替え前に LETTA_PG_URI を設定してデータを移行する

失敗2: Core Memoryのトークン上限を無視して詰め込みすぎる

Core Memoryは常時コンテキストに乗るため、過度に大きくするとLLMのトークン使用量が増加し、レスポンス速度低下とコスト増加を招きます。

❌ ユーザーの全会話履歴をCore Memoryに書き込む

⭕ Core Memoryには「現在の最重要情報のみ」を置き、詳細はArchival Memoryに入れる。limitパラメータで上限を明示的に設定する

失敗3: エージェントIDを管理せずにエージェントを量産する

ユーザーごとにエージェントを作成する設計で、エージェントIDをDBに保存せずにいると、同一ユーザーへの2回目のリクエストで新規エージェントが作られ、記憶が消えます。

❌ リクエストのたびに client.agents.create() を呼ぶ

⭕ ユーザーIDとエージェントIDのマッピングを自前DBに保存し、2回目以降は既存のエージェントIDを使って client.agents.messages.create() を呼ぶ

import os
from letta_client import Letta

client = Letta(api_key=os.getenv("LETTA_API_KEY"))

def get_or_create_agent(user_id: str, user_db: dict) -> str:
    """ユーザーのエージェントIDを取得、なければ作成する"""
    if user_id in user_db:
        return user_db[user_id]  # 既存のエージェントIDを返す

    agent = client.agents.create(
        name=f"agent-{user_id}",
        model="openai/gpt-4o",
        memory_blocks=[
            {"label": "persona", "value": "あなたは親切なアシスタントです。"},
            {"label": "human", "value": f"ユーザーID: {user_id}"}
        ]
    )
    user_db[user_id] = agent.id  # DBに保存(実際はRDBMS等を使う)
    return agent.id

# 使用例
user_db = {}  # 実際はPostgresやRedisに保存
agent_id = get_or_create_agent("user_001", user_db)
response = client.agents.messages.create(
    agent_id=agent_id,
    messages=[{"role": "user", "content": "こんにちは"}]
)

失敗4: pgvector拡張なしでArchival Memoryを使う

PostgreSQLにpgvector拡張をインストールせずにArchival Memoryを使おうとすると、セマンティック検索が機能しません(エラーになるかテキスト検索のみになる)。

CREATE EXTENSION vector; を実行する前にLettaを接続する

⭕ DB初期化スクリプトに必ず CREATE EXTENSION IF NOT EXISTS vector; を含める。Amazon Auroraではインスタンス作成後にこの操作が必要


LangGraph・CrewAI との詳細比較

「どのフレームワークを使うべきか」の判断を数値で示します。

観点 Letta LangGraph CrewAI
GitHub Stars(2026年3月) 22.4k ~40k(LangChain含む) ~30k
長期記憶(built-in) ◎ 3層構造(コア機能) △ 外付けが必要 △ 外付けが必要
学習曲線 ○ メモリ概念の理解が必要 △ グラフ設計の学習が必要 ◎ ロール定義だけでOK
マルチエージェント ○ Shared Blocks対応 ◎ Subgraph設計が強力 ◎ 役割分担が得意
本番スケーリング ○ REST API + K8s対応 ◎ LangGraph Platform ○ CrewAI Platform
向いているユースケース 長期継続ボット、学習AI 複雑ワークフロー制御 分業タスク自動化

「記憶」が本質的に重要なユースケース(パーソナルアシスタント、長期プロジェクト管理、継続学習Bot)ではLettaが最も適合します。Lettaについての詳細はLetta公式サイトLettaドキュメントGitHub (letta-ai/letta)を参照してください。

またGoogle ADKと組み合わせたエージェント設計についてはGoogle ADK v1.0完全ガイドも参考になります。


参考・出典


まとめ:今日から始める3つのアクション

  1. 今日やること: pip install letta-client を実行し、APIキーを取得してローカルでエージェントを1つ作成する
  2. 今週中: Core Memoryのpersona/humanブロックを自分のユースケースに合わせてカスタマイズし、Archival Memoryに業務ドキュメントを挿入してセマンティック検索を試す
  3. 今月中: PostgreSQL + Dockerで本番構成を組み、ユーザーIDとエージェントIDのマッピング管理をアプリに組み込む

あわせて読みたい:


この記事を読んでLettaの導入イメージが固まってきた方へ

UravationではAIエージェント導入の研修・コンサルを行っています。Letta・LangGraph・CrewAIの選定支援から実装サポートまで、お気軽にご相談ください。


著者: 佐藤傑(さとう・すぐる)
株式会社Uravation代表取締役。X(@SuguruKun_ai)フォロワー10万人超。100社以上の企業向けAI研修・導入支援。著書累計3万部突破。SoftBank IT連載7回執筆(NewsPicks最大1,125ピックス)。

ご質問・ご相談は お問い合わせフォーム からお気軽にどうぞ。

Need help moving from reading to rollout?

この記事を読んで導入イメージが固まってきた方へ

Uravationでは、AIエージェントの要件整理、PoC設計、社内導入、研修まで一気通貫で支援しています。

この記事をシェア

X Facebook LINE

※ 本記事の情報は2026年5月時点のものです。サービスの料金・仕様は変更される可能性があります。最新情報は各サービスの公式サイトをご確認ください。

関連記事