LangGraph x Nowledge Mem
LangGraphエージェントに、チェックポインターを置き換えることなく、アイデンティティを認識するContext、Memoryツール、および冪等なThreadキャプチャを追加します。
LangGraphは、ステートフルなワークフロー、単一エージェントグラフ、およびマルチエージェントグラフを構築するためのエージェントフレームワーク兼ランタイムです。 実行を管理します。 チェックポイント、割り込み、リトライ、およびグラフの状態です。 Nowledge Memは、エージェントがグラフやツールをまたいで引き継ぐべき永続的な状態を管理します。 すなわち、そのアイデンティティ、アクティブなSpace、Working Memory、ガバナンスされたメモリ、および検索可能な会話です。
nowledge-mem-langgraph Pythonコネクターは、どちらか一方を他方に見せかけることなく、これら2つのシステムを接続します。
所有権の境界
LangGraphのチェックポインターはそのままにしてください。
Nowledge MemはチェックポインターでもBaseStoreの代替でもありません。
一時的なコンテキストを注入し、アイデンティティにスコープされたMCPツールを提供し、完了した会話をMem Threadとしてインポートします。
インストール
pip install nowledge-mem-langgraphリモートのMemサーバーまたはNowledge Cloudワークスペースの場合は、他のMemクライアントで使用しているものと同じエンドポイントとキーを設定します。
export NMEM_API_URL=https://your-mem-server
export NMEM_API_KEY=nmem_...
export NMEM_LANGGRAPH_APP_ID=customer-supportNMEM_LANGGRAPH_APP_IDは安定したアプリケーションスラッグであり、リリースバージョンではありません。
デプロイをまたいで変更しないでください。
そうすることで、同じLangGraph thread_idが引き続き同じMem Threadに解決されます。
LangChain create_agent
from dataclasses import dataclass
from langchain.agents import create_agent
from nowledge_mem_langgraph import NowledgeClient, NowledgeMiddleware
@dataclass
class AgentContext:
user_id: str
nowledge: dict[str, str]
mem = NowledgeClient()
agent = create_agent(
model="openai:gpt-5.4",
tools=await mem.tools(),
middleware=[NowledgeMiddleware(mem)],
context_schema=AgentContext,
)
result = await agent.ainvoke(
{"messages": [{"role": "user", "content": "What did we decide last week?"}]},
config={"configurable": {"thread_id": "ticket-1842"}},
context=AgentContext(
user_id="auth-user-42",
nowledge={
"agent_id": "support-triage",
"space_id": "customer-acme",
},
),
)このパスは完全な統合を提供します。
- 選択されたAgentのContext Bundleは、トップレベルのターンごとに1回読み取られます。
- Contextはモデルリクエストに追加され、チェックポイントされたメッセージには決して追加されません。
- Memの境界付けられた外部エージェントMCPツールがモデルで利用可能になります。
- すべてのツール呼び出しは、信頼された呼び出し元のAgentとSpaceに強制的に戻されます。
- 完了したトップレベルの会話は
POST /threads/importを通じてインポートされます。 - 完全なリプレイはno-opになります。 以降のターンでは、欠けているメッセージのみが追加されます。
- Memの検索出力はThread内で引き続き表示されますが、蒸留からは除外され、リコールが新しいメモリとして再び学習されるのを防ぎます。
invoke()とainvoke()の両方がコンテキスト注入とThread同期をサポートします。
Mem MCPツールは非同期のlangchain-mcp-adaptersインターフェースを通じて読み込まれるため、これらのツールを使用するエージェントはainvoke()またはastream()で実行する必要があります。
アイデンティティモデル
これらの値にはそれぞれ異なる役割があります。
| 値 | 識別する対象 | セキュリティ上の役割 |
|---|---|---|
| APIキー | ワークスペース/メンバーのアクセス | 認可 |
agent_id | ポータブルなNowledge AI Identity | コンテキスト、来歴、ルーティング |
host_agent_id | LangGraphデプロイのアイデンティティ | ホストの来歴 |
space_id | メモリと検索のスコープ | 認可されたアクセス内のスコープ |
LangGraph thread_id | 正規の会話 | Mem Threadのアイデンティティ |
LangGraph assistant_id | サーバーデプロイ/設定インスタンス | メタデータのみ |
| LangGraphの認証済みユーザー | 人間/サービスのプリンシパル | LangGraphの認可。Agentのアイデンティティとして推測されることはありません |
呼び出し固有のセレクターはcontext.nowledgeの下に渡します。
コネクターはアイデンティティについてプロンプトを検査しません。
呼び出しがどちらかのAgentセレクターを指定した場合、実行時のagent_idを無関係なデフォルトのhost_agent_idと組み合わせるのではなく、静的なAgentタプルを置き換えます。
LangGraph Serverがgraph_idとassistant_idを提供する場合、コネクターはlanggraph:<graph_id>:<assistant_id>をホストの来歴として記録できます。
その値を資格情報として使用したり、1つの会話を複数のThreadに分割したりすることはありません。
静的なデフォルトは、単一のAgent専用のデプロイでは引き続き有用です。
export NMEM_AGENT_ID=support-triage
export NMEM_HOST_AGENT_ID=langgraph:support:prod
export NMEM_SPACE=customer-acmeマルチテナントアプリケーションでは、正しいワークスペース権限を持つキーを使用し、信頼されたサーバー側のコンテキストからAgent/Spaceセレクターを渡してください。 検証されていないクライアントJSONから直接受け入れないでください。
Threadとサブエージェントのセマンティクス
1つのLangGraph thread_idは1つのMem Threadにマッピングされます。
langgraph:<application_id>:<thread_id>assistant_idは、そのキーから意図的に除外されています。
LangGraphでは複数のアシスタントが同じThread上で実行できます。
モデル設定を変更しても、ユーザーの会話履歴を分岐させてはなりません。
サブグラフは親Threadを共有し、ネストされたチェックポイント名前空間を受け取ります。 ミドルウェアはトップレベルの名前空間のみを同期し、親と各サブエージェントごとに1つずつコピーするのではなく、1つの読み取り可能な会話を生成します。
別のThreadを使用するのは、サブエージェントが独立してアドレス可能であり、永続的な会話を所有する場合のみです。
その場合は、それ専用のLangGraph thread_idを付与し、その動作を異ならせるべき場合は専用のMem agent_idも付与します。
生のStateGraph
生のグラフでは、モデル呼び出しと完了境界をどこにでも配置できるため、コネクターは推測しません。 自分が所有する境界で明示的なヘルパーを使用してください。
from nowledge_mem_langgraph import NowledgeClient, NowledgeIdentity
mem = NowledgeClient()
identity = NowledgeIdentity(agent_id="researcher", space_id="project-atlas")
bundle = await mem.acontext_bundle(identity)
tools = await mem.tools()
# At the graph's real completion boundary:
await mem.async_thread(
thread_id=runtime.execution_info.thread_id,
messages=state["messages"],
identity=identity,
runtime=runtime,
)bundle["rendered_markdown"]をモデルリクエストに注入します。
チェックポイントされたメッセージチャネルに追加しないでください。
信頼性
コンテキストの読み取りとThread同期は、デフォルトでフェイルオープンします。
一時的なMemの停止によって顧客向けエージェントがダウンすることはありませんが、ログには記録されます。
メモリの可用性がワークフローの厳格な要件である場合は、fail_open=Falseを設定してください。
障害によってスコープが広がったり、認証が削除されたりすることは決してありません。 Thread同期は追跡されないバックグラウンドタスクを通じて送信されるのではなく待機されるため、サーバーレスワーカーがインポートの完了前に終了することはありません。
既存のデプロイ
コネクターをインストールしても、LangGraphのチェックポイントは変更されません。 状態にまだ存在するメッセージからキャプチャを開始します。 コネクターをインストールする前に要約ポリシーが古いメッセージを削除していた場合、それらの削除されたメッセージを再構築することはできません。 原本のトランスクリプトが存在する場合は、別途インポートしてください。
LangSmithのトレースをトランスクリプトのバックフィルとして使用しないでください。 トレースにはネストされた実行、リトライ、およびツール実行の詳細が含まれており、正規のユーザー会話ではありません。
検証
- 安定したLangGraph
thread_idで1ターン実行します。 - モデルリクエストが期待されるAgentとSpaceのContext Bundleを受け取ることを確認します。
- Mem検索ツールを呼び出し、リクエストが同じアイデンティティスコープを保持していることを確認します。
- Nowledge Mem Threadsを開き、1つの
LangGraphThreadを見つけます。 - 同じ状態を再度実行します。 インポートは重複メッセージを報告しないはずです。
- ネストされたサブグラフを実行します。 2つ目のMem Threadを作成してはなりません。
