Skip to content

ClasCat® AI Research

クラスキャット – AgentOS, AI エージェント, MCP, LangChain, AutoGen, AG2, Agno

Menu
  • ホーム
    • ClassCat® AI Research ホーム
    • クラスキャット・ホーム
  • OpenAI API
    • OpenAI Python ライブラリ 1.x : 概要
    • OpenAI ブログ
      • GPT の紹介
      • GPT ストアの紹介
      • ChatGPT Team の紹介
    • OpenAI platform 1.x
      • Get Started : イントロダクション
      • Get Started : クイックスタート (Python)
      • Get Started : クイックスタート (Node.js)
      • Get Started : モデル
      • 機能 : 埋め込み
      • 機能 : 埋め込み (ユースケース)
      • ChatGPT : アクション – イントロダクション
      • ChatGPT : アクション – Getting started
      • ChatGPT : アクション – アクション認証
    • OpenAI ヘルプ : ChatGPT
      • ChatGPTとは何ですか?
      • ChatGPT は真実を語っていますか?
      • GPT の作成
      • GPT FAQ
      • GPT vs アシスタント
      • GPT ビルダー
    • OpenAI ヘルプ : ChatGPT > メモリ
      • FAQ
    • OpenAI ヘルプ : GPT ストア
      • 貴方の GPT をフィーチャーする
    • OpenAI Python ライブラリ 0.27 : 概要
    • OpenAI platform
      • Get Started : イントロダクション
      • Get Started : クイックスタート
      • Get Started : モデル
      • ガイド : GPT モデル
      • ガイド : 画像生成 (DALL·E)
      • ガイド : GPT-3.5 Turbo 対応 微調整
      • ガイド : 微調整 1.イントロダクション
      • ガイド : 微調整 2. データセットの準備 / ケーススタディ
      • ガイド : 埋め込み
      • ガイド : 音声テキスト変換
      • ガイド : モデレーション
      • ChatGPT プラグイン : イントロダクション
    • OpenAI Cookbook
      • 概要
      • API 使用方法 : レート制限の操作
      • API 使用方法 : tiktoken でトークンを数える方法
      • GPT : ChatGPT モデルへの入力をフォーマットする方法
      • GPT : 補完をストリームする方法
      • GPT : 大規模言語モデルを扱う方法
      • 埋め込み : 埋め込みの取得
      • GPT-3 の微調整 : 分類サンプルの微調整
      • DALL-E : DALL·E で 画像を生成して編集する方法
      • DALL·E と Segment Anything で動的マスクを作成する方法
      • Whisper プロンプティング・ガイド
  • Gemini API
    • Tutorials : クイックスタート with Python (1) テキスト-to-テキスト生成
    • (2) マルチモーダル入力 / 日本語チャット
    • (3) 埋め込みの使用
    • (4) 高度なユースケース
    • クイックスタート with Node.js
    • クイックスタート with Dart or Flutter (1) 日本語動作確認
    • Gemma
      • 概要 (README)
      • Tutorials : サンプリング
      • Tutorials : KerasNLP による Getting Started
  • Keras 3
    • 新しいマルチバックエンド Keras
    • Keras 3 について
    • Getting Started : エンジニアのための Keras 入門
    • Google Colab 上のインストールと Stable Diffusion デモ
    • コンピュータビジョン – ゼロからの画像分類
    • コンピュータビジョン – 単純な MNIST convnet
    • コンピュータビジョン – EfficientNet を使用した微調整による画像分類
    • コンピュータビジョン – Vision Transformer による画像分類
    • コンピュータビジョン – 最新の MLPモデルによる画像分類
    • コンピュータビジョン – コンパクトな畳込み Transformer
    • Keras Core
      • Keras Core 0.1
        • 新しいマルチバックエンド Keras (README)
        • Keras for TensorFlow, JAX, & PyTorch
        • 開発者ガイド : Getting started with Keras Core
        • 開発者ガイド : 関数型 API
        • 開発者ガイド : シーケンシャル・モデル
        • 開発者ガイド : サブクラス化で新しい層とモデルを作成する
        • 開発者ガイド : 独自のコールバックを書く
      • Keras Core 0.1.1 & 0.1.2 : リリースノート
      • 開発者ガイド
      • Code examples
      • Keras Stable Diffusion
        • 概要
        • 基本的な使い方 (テキスト-to-画像 / 画像-to-画像変換)
        • 混合精度のパフォーマンス
        • インペインティングの簡易アプリケーション
        • (参考) KerasCV – Stable Diffusion を使用した高性能画像生成
  • TensorFlow
    • TF 2 : 初級チュートリアル
    • TF 2 : 上級チュートリアル
    • TF 2 : ガイド
    • TF 1 : チュートリアル
    • TF 1 : ガイド
  • その他
    • 🦜️🔗 LangChain ドキュメント / ユースケース
    • Stable Diffusion WebUI
      • Google Colab で Stable Diffusion WebUI 入門
      • HuggingFace モデル / VAE の導入
      • LoRA の利用
    • Diffusion Models / 拡散モデル
  • クラスキャット
    • 会社案内
    • お問合せ
    • Facebook
    • ClassCat® Blog
Menu

LangChain 1.0 α : コアコンポーネント – 短期メモリ

Posted on 09/25/2025 by Masashi Okumura

メモリは以前のインタラクションに関する情報を記憶するシステムです。AI エージェントにとって、メモリは以前のインタラクションを記憶し、フィードバックから学習し、ユーザの好みに適応するために不可欠です。

LangChain 1.0 alpha : コアコンポーネント – 短期メモリ

作成 : クラスキャット・セールスインフォメーション
作成日時 : 09/25/2025
バージョン : 1.0.0a9

* 本記事は docs.langchain.com の以下のページを独自に翻訳した上で、補足説明を加えてまとめ直しています。スニペットはできる限り日本語を使用しています :

  • LangChain OSS (v1-alpha) : Core Components – Short-term memory

* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。

 

 

LangChain 1.0 alpha : コアコンポーネント – 短期メモリ

概要

メモリは以前のインタラクションに関する情報を記憶するシステムです。AI エージェントにとって、メモリは以前のインタラクションを記憶し、フィードバックから学習し、ユーザの好みに適応するために不可欠です。エージェントはユーザインタラクションを伴うより複雑なタスクに取り組むようになると、この機能は効率性とユーザ満足度の両方で重要になります。

短期メモリはアプリケーションが単一のスレッドや会話内の以前のインタラクションを記憶することを可能にします。

Info : スレッドは、電子メールが単一の会話内のメッセージをグループ化するのと同様に、セッション内の複数のインタラクションをまとめて整理します。

会話履歴は、短期メモリの最も一般的な形式です。長い会話は現代の LLM に課題を与えます ; 完全な履歴は LLM のコンテキスト・ウィンドウに収まらない場合があり、コンテキストの喪失やエラーという結果になります。

モデルが完全なコンテキスト長をサポートする場合でさえ、殆どの LLM は依然として長いコンテキストに対してはパフォーマンスが劣化します。それらは古くなったり話題から外れたコンテンツにより「気を散らかされ (distracted)」、遅い応答時間や高いコストに悩まされることになります。

チャットモデルは メッセージ を使用してコンテキストを受け取ります、これは指示 (システムメッセージ) と入力 (人間のメッセージ) を含みます。チャットアプリケーションでは、メッセージは人間の入力とモデルのレスポンスが交互に現れるので、時間とともにメッセージのリストが長くなるという結果になります。コンテキストウィンドウは制限されていますので、多くのアプリケーションは古くなった情報を削除または「忘れる」テクニックを使用することでメリットを享受できます。

 

使用方法

エージェントに短期メモリ (スレッドレベルの永続性) を追加するには、エージェントを作成する際にチェックポインタを指定する必要があります。

Info : LangChain のエージェントは短期メモリをエージェントの状態の一部として管理します。

これらをグラフの状態に保存することで、エージェントは異なるスレッド間で分離を維持しながら、特定の会話について完全なコンテキストにアクセスできます。

状態はチェックポインタを使用してデータベース (or メモリ) に永続化されるので、スレッドはいつでも再開できます。

短期メモリは、エージェントが呼び出される (invoked) ときか、(ツール呼び出しのような) ステップが完了されるときに更新され、状態は各ステップの最初に読まれます。

from langchain.agents import create_agent
from langgraph.checkpoint.memory import InMemorySaver

agent = create_agent(
    "openai:gpt-5",
    [get_user_info],
    checkpointer=InMemorySaver(),
)

agent.invoke(
    {"messages": [{"role": "user", "content": "Hi! My name is Bob."}]},
    {"configurable": {"thread_id": "1"}},
)

 

本番環境

本番環境では、データベースをバックエンドとするチェックポインタを使用します :

from langchain.agents import create_agent
from langgraph.checkpoint.postgres import PostgresSaver

DB_URI = "postgresql://postgres:postgres@localhost:5442/postgres?sslmode=disable"
with PostgresSaver.from_conn_string(DB_URI) as checkpointer:
    agent = create_agent(
        "openai:gpt-5",
        [get_user_info],
        checkpointer=checkpointer,
    )

 

エージェントメモリのカスタマイズ

デフォルトでは、エージェントは AgentState を使用して短期メモリ (具体的にはメッセージキー経由の会話履歴) を管理します。

ユーザは AgentState をサブクラス化して、状態に追加フィールドを追加します。

そしてカスタム状態は、ツールや動的プロンプト / モデル関数経由でアクセスできます。

from langchain.agents import create_agent, AgentState
from langgraph.checkpoint.memory import InMemorySaver

class CustomAgentState(AgentState):
    user_id: str

agent = create_agent(
    "openai:gpt-5",
    [get_user_info],
    state_schema=CustomAgentState,
    checkpointer=InMemorySaver(),
)

 

コモンパターン

短期メモリ が有効にされると、長い会話は LLM のコンテキストウィンドウを超える可能性があります。一般的な解決策は :

  • メッセージのトリミング – (LLM を呼び出す前に) 最初か最後の N メッセージを除去します。

  • メッセージの削除 – LangGraph 状態から永続的にメッセージを削除します。

  • メッセージの要約 – 履歴の以前のメッセージを要約して、要約で置き換えます。

  • カスタム・ストラテジー – カスタム・ストラテジー (e.g., メッセージフィルタリング 等)

これは LLM のコンテキストウィンドウを超えることなく、エージェントが会話を追跡し続けることを可能にします。

 

メッセージのトリミング

殆どの LLM は (トークンベースで) サポートされるコンテキストウィンドウの最大数があります。

いつメッセージを切り捨てる (truncate) かを決める一つの方法は、メッセージ履歴のトークンをカウントして制限に近づいた時点で切り捨てることです。LangChain を使用している場合、trim メッセージユーティリティを使用して、リストから保持するトークン数や境界を処理するために使用する strategy (e.g., 最後の maxTokens を保持) を指定することができます。

エージェントのメッセージ履歴をトリミングするには、trim_messages 関数とともに @[pre_model_hook][create_agent] を使用します :

from langchain_core.messages.utils import trim_messages, count_tokens_approximately
from langchain_core.messages import BaseMessage
from langgraph.checkpoint.memory import InMemorySaver
from langchain.agents import create_agent
from langchain_core.runnables import RunnableConfig

def pre_model_hook(state) -> dict[str, list[BaseMessage]]:
    """
    This function will be called prior to every llm call to prepare the messages for the llm.
    """
    trimmed_messages = trim_messages(
        state["messages"],
        strategy="last",
        token_counter=count_tokens_approximately,
        max_tokens=384,
        start_on="human",
        end_on=("human", "tool"),
    )
    return {"llm_input_messages": trimmed_messages}


checkpointer = InMemorySaver()
agent = create_agent(
    "openai:gpt-5-nano",
    tools=[],
    pre_model_hook=pre_model_hook,
    checkpointer=checkpointer,
)

config: RunnableConfig = {"configurable": {"thread_id": "1"}}

agent.invoke({"messages": "hi, my name is bob"}, config)
agent.invoke({"messages": "write a short poem about cats"}, config)
agent.invoke({"messages": "now do the same but for dogs"}, config)
final_response = agent.invoke({"messages": "what's my name?"}, config)

final_response["messages"][-1].pretty_print()
"""
================================== Ai Message ==================================

Your name is Bob. You told me that earlier.
If you'd like me to call you a nickname or use a different name, just say the word.
"""

 

メッセージの削除

メッセージ履歴を管理するためにグラフ状態からメッセージを削除できます。

これは、特定のメッセージを削除したりメッセージ履歴全体をクリアしたい場合に役立ちます。

グラフ状態からメッセージを削除するには、RemoveMessage が使用できます。

RemoveMessage が機能するためには、add_messages reducer とともに状態キーを使用する必要があります。

デフォルトの AgentState がこれを提供します。

特定のメッセージを削除するには :

from langchain_core.messages import RemoveMessage

def delete_messages(state):
    messages = state["messages"]
    if len(messages) > 2:
        # remove the earliest two messages
        return {"messages": [RemoveMessage(id=m.id) for m in messages[:2]]}

すべてのメッセージを削除するには :

from langgraph.graph.message import REMOVE_ALL_MESSAGES

def delete_messages(state):
    return {"messages": [RemoveMessage(id=REMOVE_ALL_MESSAGES)]}

Info : メッセージを削除する際には、結果としてのメッセージ履歴が有効であることを確認してください。使用している LLM プロバイダーの制限を確認してください。例えば :

  • 一部のプロバイダーは、メッセージ履歴がユーザメッセージから始まることを想定しています。
  • 殆どのプロバイダーはツール呼び出しを含むアシスタントメッセージの後に、対応するツール結果メッセージが続くことを必要としています。
from langchain_core.messages import RemoveMessage
from langchain.agents import create_agent
from langgraph.checkpoint.memory import InMemorySaver
from langchain_core.runnables import RunnableConfig


def delete_messages(state):
    messages = state["messages"]
    if len(messages) > 2:
        # remove the earliest two messages
        return {"messages": [RemoveMessage(id=m.id) for m in messages[:2]]}


agent = create_agent(
    "openai:gpt-5-nano",
    tools=[],
    prompt="Please be concise and to the point.",
    post_model_hook=delete_messages,
    checkpointer=InMemorySaver(),
)

config: RunnableConfig = {"configurable": {"thread_id": "1"}}

for event in agent.stream(
    {"messages": [{"role": "user", "content": "hi! I'm bob"}]},
    config,
    stream_mode="values",
):
    print([(message.type, message.content) for message in event["messages"]])

for event in agent.stream(
    {"messages": [{"role": "user", "content": "what's my name?"}]},
    config,
    stream_mode="values",
):
    print([(message.type, message.content) for message in event["messages"]])

出力例

[('human', "hi! I'm bob")]
[('human', "hi! I'm bob"), ('ai', 'Hi Bob! Nice to meet you. How can I help you today? I can answer questions, brainstorm ideas, draft text, explain things, or help with code.')]
[('human', "hi! I'm bob"), ('ai', 'Hi Bob! Nice to meet you. How can I help you today? I can answer questions, brainstorm ideas, draft text, explain things, or help with code.'), ('human', "what's my name?")]
[('human', "hi! I'm bob"), ('ai', 'Hi Bob! Nice to meet you. How can I help you today? I can answer questions, brainstorm ideas, draft text, explain things, or help with code.'), ('human', "what's my name?"), ('ai', 'Your name is Bob. How can I help you today, Bob?')]
[('human', "what's my name?"), ('ai', 'Your name is Bob. How can I help you today, Bob?')]

 

メッセージの要約

上記のメッセージのトリミングや削除に伴う問題は、メッセージキューの間引き (culling) により情報が失われる可能性があることです。そのため、一部のアプリケーションはチャットモデルを使用して、メッセージ履歴を要約するという、より洗練されたアプローチからメリットを受けます。

エージェントのメッセージ履歴を要約するには、事前構築済み SummarizationNode 抽象化とともに @[pre_model_hook][create_agent] を使用します :

from langmem.short_term import SummarizationNode, RunningSummary
from langchain_core.messages.utils import count_tokens_approximately
from langchain.agents import create_agent, AgentState
from langgraph.checkpoint.memory import InMemorySaver
from langchain_openai import ChatOpenAI
from langchain_core.runnables import RunnableConfig

model = ChatOpenAI(model="gpt-4o-mini")

summarization_node = SummarizationNode(
    token_counter=count_tokens_approximately,
    model=model,
    max_tokens=384,
    max_summary_tokens=128,
    output_messages_key="llm_input_messages",
)

class State(AgentState):
    # Added for the SummarizationNode to be able to keep track of the running summary information
    context: dict[str, RunningSummary]


checkpointer = InMemorySaver()

agent = create_agent(
    model=model,
    tools=[],
    pre_model_hook=summarization_node,
    state_schema=State,
    checkpointer=checkpointer,
)

config: RunnableConfig = {"configurable": {"thread_id": "1"}}
agent.invoke({"messages": "hi, my name is bob"}, config)
agent.invoke({"messages": "write a short poem about cats"}, config)
agent.invoke({"messages": "now do the same but for dogs"}, config)
final_response = agent.invoke({"messages": "what's my name?"}, config)

print(final_response.keys())

final_response["messages"][-1].pretty_print()
print("\nSummary:", final_response["context"]["running_summary"].summary)

 

アクセス

エージェントの短期メモリに幾つかの方法でアクセスできます :

  • ツール

  • Pre モデルフック

  • Post モデルフック

 

ツール

ツール内で短期メモリを読む

InjectedState アノテーションを使用してエージェントの状態をツール・シグネチャに注入することで、ツール内で短期メモリ (状態) にアクセスできます。

このアノテーションはツール・シグネチャから状態を隠します (従ってモデルからは見えません) が、ツールはそれにアクセスできます。
​

from typing import Annotated
from langchain.agents import create_agent, AgentState
from langchain.agents.tool_node import InjectedState

class CustomState(AgentState):
    user_id: str

def get_user_info(
    state: Annotated[CustomState, InjectedState]
) -> str:
    """Look up user info."""
    user_id = state["user_id"]
    return "User is John Smith" if user_id == "user_123" else "Unknown user"

agent = create_agent(
    model="openai:gpt-5-nano",
    tools=[get_user_info],
    state_schema=CustomState,
)

result = agent.invoke({
    "messages": "look up user information",
    "user_id": "user_123"
})
print(result["messages"][-1].content)
# > User is John Smith.

 

ツールから短期メモリへの書き込み (更新)

実行中にエージェントの短期メモリ (状態) を変更するには、ツールから状態更新を直接返すことができます。

これは、中間結果を永続化したり、後に続くツールやプロンプトが情報にアクセスできるようにするために役立ちます

from typing import Annotated
from langchain_core.tools import InjectedToolCallId
from langchain_core.runnables import RunnableConfig
from langchain_core.messages import ToolMessage
from langchain.agents import create_agent, AgentState
from langchain.agents.tool_node import InjectedState
from langgraph.runtime import get_runtime
from langgraph.types import Command
from pydantic import BaseModel

class CustomState(AgentState):
    user_name: str

class CustomContext(BaseModel):
    user_id: str

def update_user_info(
    tool_call_id: Annotated[str, InjectedToolCallId],
) -> Command:
    """Look up and update user info."""
    runtime = get_runtime(CustomContext)
    user_id = runtime.context.user_id
    name = "John Smith" if user_id == "user_123" else "Unknown user"
    return Command(update={
        "user_name": name,
        # update the message history
        "messages": [
            ToolMessage(
                "Successfully looked up user information",
                tool_call_id=tool_call_id
            )
        ]
    })

def greet(
    state: Annotated[CustomState, InjectedState]
) -> str:
    """Use this to greet the user once you found their info."""
    user_name = state["user_name"]
    return f"Hello {user_name}!"

agent = create_agent(
    model="openai:gpt-5-nano",
    tools=[update_user_info, greet],
    state_schema=CustomState,
    context_schema=CustomContext,
)

agent.invoke(
    {"messages": [{"role": "user", "content": "greet the user"}]},
    context=CustomContext(user_id="user_123"),
)

 

プロンプト

エージェントの状態をプロンプト関数シグネチャに注入することで、動的プロンプト関数で短期メモリ (状態) にアクセスできます。

from langchain_core.messages import AnyMessage
from langchain.agents import create_agent, AgentState
from langgraph.runtime import get_runtime
from typing import TypedDict


class CustomContext(TypedDict):
    user_name: str


def get_weather(city: str) -> str:
    """Get the weather in a city."""
    return f"The weather in {city} is always sunny!"


def prompt(state: AgentState) -> list[AnyMessage]:
    user_name = get_runtime(CustomContext).context["user_name"]
    system_msg = f"You are a helpful assistant. Address the user as {user_name}."
    return [{"role": "system", "content": system_msg}] + state["messages"]


agent = create_agent(
    model="openai:gpt-5-nano",
    tools=[get_weather],
    prompt=prompt,
    context_schema=CustomContext,
)

result = agent.invoke(
    {"messages": [{"role": "user", "content": "What is the weather in SF?"}]},
    context=CustomContext(user_name="John Smith"),
)
for msg in result["messages"]:
    msg.pretty_print()

出力例

================================ Human Message =================================

What is the weather in SF?
================================== Ai Message ==================================
Tool Calls:
  get_weather (call_WFQlOGn4b2yoJrv7cih342FG)
 Call ID: call_WFQlOGn4b2yoJrv7cih342FG
  Args:
    city: San Francisco
================================= Tool Message =================================
Name: get_weather

The weather in San Francisco is always sunny!
================================== Ai Message ==================================

Hi John Smith, the weather in San Francisco is always sunny!

 

以上



クラスキャット

最近の投稿

  • LangChain 1.0 α : コアコンポーネント – 短期メモリ
  • LangChain 1.0 α : コアコンポーネント – ツール
  • LangChain 1.0 α : コアコンポーネント – メッセージ
  • LangChain 1.0 α : コアコンポーネント – モデル
  • LangChain 1.0 α : コアコンポーネント – エージェント

タグ

AG2 (14) Agno (46) AutoGen (13) ClassCat Press Release (20) ClassCat TF/ONNX Hub (11) DGL 0.5 (14) Eager Execution (7) Edward (17) FLUX.1 (16) Gemini (20) HuggingFace Transformers 4.5 (10) HuggingFace Transformers 4.29 (9) Keras 2 Examples (98) Keras 2 Guide (16) Keras 3 (10) Keras Release Note (17) Kubeflow 1.0 (10) LangChain (45) LangGraph (24) LangGraph 0.5 (9) MediaPipe 0.8 (11) Model Context Protocol (16) NNI 1.5 (16) OpenAI Agents SDK (8) OpenAI Cookbook (13) OpenAI platform (10) OpenAI platform 1.x (10) OpenAI ヘルプ (8) TensorFlow 2.0 Advanced Tutorials (33) TensorFlow 2.0 Advanced Tutorials (Alpha) (15) TensorFlow 2.0 Advanced Tutorials (Beta) (16) TensorFlow 2.0 Guide (10) TensorFlow 2.0 Guide (Alpha) (16) TensorFlow 2.0 Guide (Beta) (9) TensorFlow 2.0 Release Note (12) TensorFlow 2.0 Tutorials (20) TensorFlow 2.0 Tutorials (Alpha) (14) TensorFlow 2.0 Tutorials (Beta) (12) TensorFlow 2.4 Guide (24) TensorFlow Deploy (8) TensorFlow Probability (9) TensorFlow Programmer's Guide (22) TensorFlow Release Note (18) TensorFlow Tutorials (33) TF-Agents 0.4 (11)
2025年9月
月 火 水 木 金 土 日
1234567
891011121314
15161718192021
22232425262728
2930  
« 8月    
© 2025 ClasCat® AI Research | Powered by Minimalist Blog WordPress Theme