Atlas Agent Engine メモリ用のスタンドアロンPython SDK - Atlas Agent Engine 内または外部で使用可能なAIエージェントの長期メモリ。
これレコード、エージェントに1 つのオブジェクト(パッケージは単独でインストールされ、 と のみに依存するため、Memorypydantic httpxプラットフォームスタックをプルすることなく任意のエージェントにドロップされます。
プラットフォームに配置されたエージェントは、この同じ SDK を使用します。構築はされません。ランタイムは、クラスター内のトランスポートと処理されている呼び出しの agent_engine_sdk_memory.MemoryID にすでに接続されている をエージェントに渡します。これは同じクラスと同じメソッド署名です。下のトランスポートのみが異なります。したがって、外部エージェントに対して記述したコードは、プラットフォームに配置しても変更されず、この READMEから得られた内容は両方の場所で適用されます。
2つの違いがあります。1 つは、ID が から取得される場所( の接続を参照)と、アプリバウンド トランスポートが処理できず、MemoryNotSupportedError を発生させる少数の呼び出しは各接続がサポートする内容にリストされています。
これが初めての場合は、メモリの動作方法から始めます。システムの形状がAPIのほとんどを説明します。その後を統合するには、インストール、接続、使用の 3 つのステップで行われます。サーバーサイドの設定については、 メモリサーバーの構成 で説明されています。 ID、エラー、モデルに関する参考資料は次のとおりで、パッケージ内部は最後に構成されています。
内容
メモリの仕組み
解決される問題
メモリは、エージェントが LM を使用して行った対話から永続的な学習者向けに結果を抽出することで、重要な結果、対話、手順、語彙の永続的な保存をエージェントに提供し、それ自体を保存するものを入力します。抽出自体は、構成した LM によって行われます。
プラットフォームに配置されたエージェントの場合、これには接続はいずれも必要ありません。ランタイムは、エージェントワークフローが実行される際に短期間メモリにされる各設定を記録し、昇格と抽出がバックグラウンドで非同期に進行されるため、ファクターが抽出されている間は応答をブロックするものはありません。耐久性があるものをすでに認識しているエージェントは、それを見つけるために抽出を待つ必要はありません。save_semantic やその他のタイプの書込み (write) を使用して、係数を直接書込むことができます。
バックグラウンドでの読み取りはいずれの方法で行われます。エージェントは一度に 1 種類の結果を追跡できます。学習した内容は search_semantic、その前に発生したことは search_episodes、タームが意味する内容は search_taxonomic、どのように行われたかは discover_procedures になります結果自体。
あるいは、ジョブ全体を渡すこともできます。 build_context_from_sources はソースごとに 1 つの仕様を採用し、それぞれが独自の 取得モード、フィルター、候補数を宣言し、その後はすべてのソースから独自のタームですべてのソースから検索し、結果をランク付けして重複を除外し、それらをトークンバケットに削除します。次のプロンプトにドロップするコンテキストの単一ブロック。 build_context は、すべてのソースに対して 1 つのモードと 1 つのフィルターで同じを行います。それぞれが異なる必要がある場合、ソースごとの形式は に達します。
2 つのレイヤー
メモリは、ものが存在する時間とその作成方法によって分裂。
短縮メモリ(SPM)は、未加工の通信です。つまり、1 回の実行ごとに 1 回のレコードで、セッションにスコープが設定され、発生時に書込まれます。記載されたすべての内容を順番に書込み (write) して完了するのはコストがかかります。
長期記憶は、異なる質問に答えるため、4 つの形状に分割されます。
タイプ | 保持しています | 答え |
|---|---|---|
| ラベルの付いたファセット | 「これについて詳しいことは? 」 |
| 要約された例え | その前に何が起こるでしたか? |
| 再利用可能な手順 | どうすればよいですか? |
| タームとその定義 | 「この単語はここで何を平均するか」 |
プロジェクトは、4 つの形状に収まらないドメイン レコードのカスタムタイプを宣言することもできます。
書込みがメモリになる方法
長期メモリを手動で書き込むことはありませんが、可能です。通常のパスは次のとおりです。
record_turn(...) you write turns as the conversation happens │ ▼ turns accumulate into a session snapshot a contiguous run of turns, summarised │ ▼ an LLM reads the snapshot and extracts what is durable semantic · episodic · procedural · taxonomic
抽出は非同期であり、バックグラウンドで実行されるため、record_turn は高速書込みを維持します。そのため、ある対話で学習された係数は、次のオンではなく、次のユーザで利用できます。
以降に設計に値する影響は、最近の状況は SPM を通じてすぐに表示され、抽出された知識は若干後で表示されます。先ほど選んだ内容が必要な場合は、 stmに質問してください。
抽出に失敗した場合
バックグラウンド抽出は埋め込みサービス、抽出 LM、およびデータベースに依存しており、これらのいずれかは失敗する可能性があります。書込み (write) は、以下のものから分離されています。返されたときに record_turn が成功し、下流で発生した状況にかかわらず、
バックグラウンドでは、失敗したステップは 1 つの質問によって分類されます。リクエストが変更されずに条件が変化するか?環境障害(ネットワークエラー、プロバイダーの停止、レート制限、ローテーション中のAPIキー)は、障害に合わせてバックオフで自動的に再試行されます。ネットワーク バックアップは 秒以内に再試行され、キーは人間によってローテーションされるため、より遅くなります。コンテンツによって決まります失敗は、再試行によって結果が変更されないため、再試行されません。これらは永久にループするのではなく、サーバー側に記録され、演算子が確認できるようにします。
これは、その外側のエッジだけでなく、抽出パス全体に適用されます。失敗するステップが、暗黙的に空の結果を生成することはなくなりました。再試行されるか、演算子がそのステップを実行できる場所で記録されます。
使用できない項目が 1 つある場合でも、残りは破棄されません。メモリを1つ埋め込むことができない場合でも(その内容がモデルに対して長すぎるか、プロバイダーが拒否した場合)、そのメモリは引き続き保存され、同じバッチする内の他のメモリには影響しません。保存されたメモリに欠落しているものはベクトルです。実際には、次のとおりです。
ただし、
text検索では引き続き見つかり、hybridでは両方のランキングが組み合わされているため、テキスト側には引き続き表示されます。semanticベクトルのみを比較する 検索では見つかりません。
これは、デフォルトの取得モードとして hybrid を使用するのに十分な理由です。正確な識別子やまれに単語を指定した場合はすでにこの方法が最適であり、埋め込むことができなかったメモリも引き続きユーザーに到達することを意味します。
これはエージェントにとってどのような意味がありますか:
プロバイダーが停止時と、抽出された知識が遅延します。オンになっている場合は、カウントはありません。 SPM は同期的に書き込まれ、影響を受けません。検索結果の内容が必要な場合は、常に
stmを要求し、再試行には制限があります。依存停止時が停止してから、無期限にループ処理するのではなく再試行が停止し、失敗は破棄されるのではなく記録されます。
これはいずれ SDK を介してエラーとして表示されることはありません。抽出の失敗はサーバー側の問題です。 SDKが可視的なシグナルは、検索では(まだ)表示されないメモリ、またはテキスト検索とハイブリッド検索では表示されるがセマンティック検索ではないメモリを抽出します。
読み取りの仕組み
、またはレコード自体に が適用されるか、2 つの異なる質問が含まれます。
``Build_context_from_sources(...)`` は、デフォルトで に到達する 1 つです。クエリとトークンの予算を指定します。名前を付けたメモリ型全体で検索され、結果がランク付けされ、ほぼ重複が削除され、予算が削減され、プロンプトに直接入力できるものが返されます。これは 1 つの呼び出しの背後にある取得パイプライン全体であり、ソースごとに 1 つの仕様を必要とするため、モードとフィルターはすべてに 1 回ではなく、ソースごとに設定されます。
取得は 3 つの方法に一致します。semantic は埋め込みを比較し、同じ平均ものを見つけます。text は単語を照合し、同じ意味を含むものを見つけます。 hybridは と の両方を実行し、ランキングを統合します。ハイブリッドは通常、正しいデフォルトです。ベクトル検索のみでは完全な識別子とまれな単語が欠落し、テキスト検索のみではパラフレーズが欠落します。
``Build_context(...)`` は、より単純なビルダであり、同じパイプラインですが、読み取られるすべてのソースに 1 つのモードと 1 つのフィルターが適用されます。
``search(...)`` およびタイプごとの検索(search_semantic 、search_episodes など)では、自分で検査または後処理したい場合に、構築されたプロトタイプではなく、ランク付けされたレコードが返されます。
メモリの範囲
すべてのレコードには書き込みが行われた ID が記載され、すべての読み取りはその後ではなくデータベースクエリでその ID によってフィルタリングされます。フィールドは、組織、 ユーザー 、プロジェクト、 セッション 、およびオプションのエージェントと、レコードがユーザーのプライベートか、より一般的に読み取れるかを決定する可視性です。
これは実質的な理由で、ユーザーにスコープが設定された検索や build_context では、別のユーザーのプライベートメモリは表示されません。制約は結果に適用されるフィルターではなく、クエリの一部であるためです。したがって、bind(...) は便宜的ではありません。これは、後続の読み取りと書込みがその内で動作するスコープを宣言し、それが別のユーザーの ID の下であるユーザーのメモリを誤って書込む方法です。
user_id とvisibility は異なる質問に答えます
user_id は、レコードが であるメモリを含みます。visibility は、以下に達する距離です。
可視性 | 誰がそれを読み取ることができます |
|---|---|
| で指定されたユーザーのみ |
| プロジェクト内の任意のユーザー (非推奨)。以下を参照してください |
| プロジェクト内の任意のユーザー |
レコードが書き込まれたプロジェクト外で可視性値に達することはありません。メモリはプロジェクトごとに 保存されるため、プロジェクト境界は可視性を超えるものではありません。org は履歴名であり、1 人のユーザーに制限されていないことを意味します。他のプロジェクトに表示されます)。
警告
✅ ``shared`` は非推奨であり、将来のリリースで削除される予定です。単一ユーザーを超える知識については orgprivatesharedorgを使用し、所有者にスコープが設定された知識には を使用します。shared orgと の両方はすでに同じ到達点に解決されているため、既存のレコードを から に切り替えても、それを読み取るユーザーは変更されません。shared としてすでに書き込まれたレコードは引き続き読み取りを行います。
この 2 つのは独立しており、読み取りでは と として結合され、 または としては使用されません。指定するフィールドごとに、クエリに等価条件が 1 つずつ追加されます。省略する各フィールドはその次元を制約しないままにします。
読み取りのスコープを設定する | 返される |
|---|---|
| ユーザーが所有するすべての可視性 |
| その可視性を持つすべてのレコード |
両方 | 両方に一致するレコードのみ (最小読み取り |
どちらもありません | プロジェクト内のすべてのこと |
3 行目は、すべてをリッスンする配列です。search_semantic(query, user_id="user_1", visibility="org") は、user_1 のメモリと組織の を平均ではありません。これは「user_1 が所有する org に表示されるメモリ」を意味します。これは制約のみを含む場合よりも小さいです。和集合はありません 。共有知識とユーザーのプライベートメモリを読み取るには、2 回の呼び出しを行い、結果を自分でマージします。
インストール
pip install agent-engine-sdk-memory
from agent_engine_sdk_memory import Memory, MemoryRequestContext
次への接続:
エージェントが実行される場所によって接続方法が決まります。その違いは主に ID を提供するユーザーによって異なります。
エージェントが実行する | 構築する | ID は からのものです | 詳細は、次を参照してください: |
|---|---|---|---|
プラットフォーム上で | 何もランタイムが挿入しない | 呼び出しごとの ランタイム | |
他の場所で |
| サービスのアカウント トークンと | |
ローカル、開発環境 |
| 設定が |
API は3 つすべてで同じです。外部に配置されたエージェントに対して記述されたコードは、プラットフォームに移動しても変更されません。コンストラクター呼び出しを削除し、ランタイムが代わりにオブジェクトを提供します。
プラットフォームに配置されたエージェントは無料で ID を取得しますが、これは実質的な違いです。ランタイムは、処理されている呼び出しについて、組織、プロジェクト、ユーザー、およびセッションをすでに認識しているため、それらをバインドします。外部エージェントは、サービスアカウントトークンが意味するもの(プロジェクト)のみを認識しているため、各呼び出しがどのユーザーとセッションに属しているかをメモリに指示する必要があります。誤りがあり、あるユーザーのメモリを別のユーザーの ID の下に書込むため、外部パスは明示的に指定する必要があります。
ホストされたプラットフォーム
マネージド サービス。サービスアカウント アクセス トークンとプロジェクトID を渡します。
agentengine CLI を使用してトークンを最小化します。サービス アカウントを一度だけ作成します。クライアントシークレットは 1 回だけ表示されるため、すぐに保存します。
agentengine service-account create my-agent --project-id <your-project-id> --role AGENT_DEVELOPER
次に、クライアントIDとシークレットを交換し、有効期間の短い(1 時間)のアクセス トークンを交換します(クライアントシークレットのプロンプトをカーソルが非表示になるため、 シェル履歴からは非表示になります)。
ACCESS_TOKEN=$(curl --fail-with-body --silent --show-error --user <client-id> --data grant_type=client_credentials https://agentengine.mongodb.com/api/v1/oauth/token | jq -er .access_token)
memory = Memory(service_account_token="<your-access-token>", project_id="<your-project-id>")
入力 | フォールバック | ノート |
|---|---|---|
|
| ベアラー認証情報として送信される、サービスアカウントアクセストークン。有効期限が切れたときに再保存します。 |
|
| 読み取りと書込みのプロジェクト。ホストされたサービスに必要です。 |
|
| 任意。非本番環境のスタック をターゲットにするようにホストを上書きします。 |
プラットフォームは認証情報をプロジェクトに固定するため、一致しない project_id は拒否されます。空白の service_account_token では ValueError が発生します。
api_key (および AGENTIC_MEMORY_API_KEY)は、引き続き非推奨のエイリアスとして受け入れられ、DeprecationWarning を出力します。新しい入力とレガシー入力の両方を渡すと、ValueError が発生します。プロジェクトAPIキーはHTTP経由で最小化できなくなったため、新しい統合にはサービス アカウント トークンを使用する必要があります。
地域開発
スタックagentengine dev up の起動など、ユーザーが実行するバックエンドにポイントします。
memory = Memory(base_url="http://localhost:8080")
入力 | フォールバック | ノート |
|---|---|---|
|
| バックエンドのURL。 |
|
| 任意。ローカル開発では省略します。 ( |
ローカル開発では、project_id を空のままにします。
プラットフォームエージェント内(アプリバウンド)
エージェントがAtlas Agent EngineMemory で実行されている場合、 の構築や接続は一切 されません 。プラットフォームは、ID、テナンシー、トランスポートがすでにバインドされている、準備ができた、ワイヤ済みのインスタンスを挿入します。アプリケーション コードは、上記の入力をいずれも渡しません。ランタイムが渡す ハンドルを使用します。 ID(ユーザー、セッション、組織、プロジェクト)は周囲のランタイム コンテキストから解決されるため、操作は直接呼び出せます。
# `memory` is supplied by the platform runtime — do not construct it. memory.record_turn(role="user", content="I'm allergic to penicillin.") context = memory.build_context(query="What medications should I avoid?") # bind(...) is still available to scope a call chain to a specific identity.
アプリバインドされたパスには、いくつかの機能的なギャップがあります(ツール呼び出し / モデルはメタデータを変換し、一部のリスト形式の読み取り)。 「各接続がサポートする内容」の アプリバウンド 列と、`docs/capability-matrix.md
Env 変数はフォールバックです
引数を省略すると、各入力も AGENTIC_MEMORY_* 環境変数にフォールバックします。明示的な引数は常に選出されます。引数なしの Memory() は、環境から 3 つすべてを読み取ります。
ルーティングの仕組み
project_id は、呼び出しの場所を決定します。認証は行われません。
project_idを設定すると、SDK はプロジェクトのルート/api/v1/projects/{project_id}/memory/*を呼び出します。空のままにすると、SDK はバックエンドを直接
/api/v1/memory/*呼び出します。
project_id が設定されているが、ローカルバックエンドなどのバックエンドに一致するルートがない場合、呼び出しは `MemoryRouteNotFoundError <:#errors+gt: を、設定解除のヒントとともに発生させます。その逆も保持されます。 project_id を使用せずにホストされているサービスをターゲットにし、それを設定するヒント付きで 404s を呼び出します。
高度: 認証済み直接バックエンド
認証とルーティングは独立しているため、project_id が空の状態で service_account_token を渡すことができます。その後 SDK は認証済み呼び出しを直接ルートで base_url のバックエンドに直接送信し、プロジェクトパスをスキップします。これは、ホストされているオーケストレーション エンジン(UE)が直接アクセスするのに適しています。
各接続がサポートする内容
機能は、認証ではなく呼び出しがルーティングされる場所に基づきます。
操作 | ホスト型(project_id セット) | Direct(project_id empty) | アプリバウンド |
|---|---|---|---|
| ✓ | ✓ | ✓ |
| ✓ | ✓ | ✓ |
| ✓ | ✓ | ✗ |
| ✓ | ✓ | ✓ |
| ✓ | ✓ | ✓ |
| ✓ | ✓ | ✓ |
型固有CRUD ( | ✓ | ✓ | ✓ ギャップあり |
カスタムタイプ | ✓(フラグ付き) | ✅ 実行コンテキストなし | ✓ |
`MemoryNotSupportedErrorサポートされていない呼び出しでは、既知のバックエンドごとのギャップに対するネットワークリクエストの前、またはプラットフォームのみが報告できる機能の相違に関する応答後に、 <:#errors+gt:__s が発生します。( エラー を参照)、サイレント障害または未加工のHTTPエラー。タイプ固有のCRUDに関するアプリバウンド ギャップを含む、バックエンドごとの完全な参照は、`docs/capability-matrix.md <.docs/Capability-matrix.md> にあります。
アプリバウンドエージェントは、上記すべての例外です。配置された プラットフォームエージェント内では、プラットフォームは準備ができた runtime を挿入するため、アプリケーションコードはこれらの入力をいずれも渡しません。
使用する
完全なラウンドトリップ: メモリの構築、交信 ID のバインド、タームのレコード、コンテキストの取得。
from agent_engine_sdk_memory import Memory, MemoryRequestContext memory = Memory(service_account_token="<your-access-token>", project_id="<your-project-id>") # Scope every call to a user and conversation. session = memory.bind(MemoryRequestContext(user_id="user_1", session_id="thread_123")) # Record what happened. session.record_turn(role="user", content="I'm allergic to penicillin.") session.record_turn(role="assistant", content="Noted — I'll avoid it.") # Later, pull back the relevant context for a new prompt. Include "stm" # to surface the turns just recorded (the default is episodic, semantic). # max_tokens is an optional gross context-construction budget. context = session.build_context( query="What medications should I avoid?", enabled_sources={"stm", "episodic", "semantic"}, max_tokens=2048, ) # context is a ContextResponse — inject its content into the next prompt.
bind(ctx) は、元のハンドルをミューテーションせずに ctx にスコープが設定された新しいハンドルを返すため、1 つの Memory は多くのユーザーとセッションを同時に処理できます。
`` build_context`` のデフォルトソース。 を省略した場合、デフォルトは enabled_sourcesepisodicと になります。semantic stmtaxonomic、 、procedural には明示的なセットが必要です。
``max_tokens``任意の正のコンテキスト構築予算。これは取得コストや保証された出力サイズではありません。検索とランク付け後に、サーバーは 500トークンの形式予約を減算し、残りに収まるメモリ チャンク全体を必要に応じて選択します。500 以下の正の値では、メモリの予算はありません。500 を超える値では、チャンクが収まらない場合でも空のコンテキストが生成されることがあります。metadata.token_count は形式が設定された出力のみを報告し、予約を除外します。以前の動作を維持するには、max_tokens を省略します。
``format_system`` と ``include_memory`` build_context と build_context_from_sources は 2 つの応答作成オプションを受け入れます。 format_style("openai"、"claude"、または "jinja2"。FormatStyle列挙はタイプ注釈用にエクスポートされます)は formatted_context の形式を選択し、無効な値はローカルで ValueError を発生させます。省略した場合、サーバーは構成されたモデルから形式を推測します。 1 つの注意事項:サーバーは現在、明示的な値がデフォルトのモデルタイプと一致する場合に再推論するため、明示的な "openai" は OpenAI ファミリーのモデルが設定されているサーバーでのみ冗長性を尊重されます。 "claude" と "jinja2" は常に尊重されます。 include_memories=True はレスポンスの selected_memories に変更後のバケット MemoryChunk リストを入力するため、どのメモリが選択されたかを正確に検査できます。どちらもホスト型または直接HTTP接続が必要です。アプリバウンドモードでは、いずれかが設定されている場合に MemoryNotSupportedError が発生します。
ソースごとのコンテキスト — ``Build_context_from_sources`` がbuild_context 1 つのフィルターとセマンティック検索をすべてのソースに適用するのに対し、このメソッドでは各ソースが独自の検索mode (text semantic、 、またはhybrid )、metadata_filter 、 をtop_k SourceSpec経由で宣言できます。は です。結果はソース間でマージされ重複が除外され、オプションにより関連性 順に並べ替えられた後、rerank build_contextのようにフォーマットされ、バケット化されます。metadata.ranking_strategy と は、最終順序がどのように生成されたか、各ソースがどのように実行されたかを報告します。 は空であってはなりません。また、各ソースを最大metadata.source_outcomes sources1 回リストでき、各ソースのtop_k 1は と の間である必要があります。200 session_idは、stm ソースが含まれている場合にのみ必要です。
ハイブリッドは通常、テキストを含むソースに適したデフォルトです。ベクトル検索のみでは完全な識別子と稀な単語が欠落し、テキスト検索のみではパラフレーズが欠落します。 mode は、指定が省略されている場合、デフォルトは semantic になります。
フィルタ可能なメタデータ の宣言。 metadata_filterは、プロジェクトが宣言したメタデータのみに名前を付けることができます。これは、フィルターが検索インデックスの結果ではなく検索インデックス内に適用されるためです。属性と、それを提供する必要があるインデックスラグを で宣言します。project-config.yaml
metadata_partition_key: # Filterable metadata attributes (max 10) - name: tier type: string # string | number | boolean | date - name: confidence type: number metadata_partition_index: semantic: [both] # both legs, so a hybrid source can filter short_term: [both] # stm is searchable only once listed here short_term: embed_on_write: true # required to give stm a vector leg
注意
メモリサーバー0.0.81 以上が必要です。パーティションキーは、それをサポートするランタイムによってのみ尊重され、メモリサーバーはスタートアップ時にその構成を読み取る(構成を保存しても適用されない)。 project-config.yamlagentengine memory configureを編集した後、 でアップロードし、ランタイムを現在のイメージにロールバックします。
agentengine memory apply --upgrade
--upgrade ランタイムを環境が現在固定されているイメージに移動します。これにより、新しいメモリ サーバーを選択します。それがない場合、ランタイムはすでに存在するイメージを保持します。変更する前に確認したい場合は、agentengine memory apply --dry-run --waitが使用中のイメージを報告し、ランタイムが準備完了と報告するまでブロックします。
フィルターを作成する前に、次の 4 つの影響があります。
フィルターキーは、宣言された名前ではなく、修飾インデックスパスです。
tierとして宣言された属性はmetadata.tierにインデックス付けされます。これはフィルターに表示される必要があるものです。プレフィックスはありません。キーは、リストしたレプリカセットでのみフィルタリングできます。
metadata_partition_indexソースを[vector]、[text]、または[both]にマッピングし、hybridソースには[both]が必要です。このフィルタは、暗黙的に を返す前に拒否されるのではなく、クエリが実行される前に拒否されるようにします。間違ったキーは大多数のキーで失敗します。
build_contextの単一の最上位metadata_filterとは異なり、ソースごとのキーは宣言されたセットに対して検証されます。宣言されていないパス、またはスペルのないパスでは が発生します。このメッセージには受け入れ可能なパスが一覧表示されるため、絞り込まれた結果セットが静かに返されるのではなくMemoryBadRequestError呼び出しで type は失敗します。短期間メモリには独自のインデックスがありません。このメソッドではフィルタリングと検索が可能ですが、プロジェクトが
short_termmetadata_partition_indexにstmをリスト した場合に限定されます。その後、errormetadata.source_outcomesstmソースは何も返すことなく失敗します。検索エラーが発生し、ソースは に503 として報告されます。 が要求された唯一のソースであった場合、すべてのソースは失敗し、呼び出しは空のコンテキストではなく を返します。これは、空の結果と空のコレクションに対する正常な検索と区別がなくなるためです。ベクトル引数([vector]または[both])を付与するためにも が必要であり、埋め込まれていない場合は構成が拒否されます。これは、埋め込まれていないタームを超えるベクトルインデックスはデッドshort_term.embed_on_write: true重みになるためです。テキストレプリカセットには埋め込みは必要ありません。
宣言された type は、一致するセマンティクスを設定します。 string キーはトークンとしてインデックス付けされるため、一致は完全値で大文字と小文字を区別します。"gold" は Gold でも gold-tier のいずれとも一致しません。範囲演算子には number または date キーが必要です。
サポートされている句: 等価性。 $gt / $gte / $lt / $lte、結合された限界が 1 つの範囲に統合されます。セットの場合は $in / $nin です。 $ne: $exists:構成用の および $and / $or / $nor 。
agent_id は宣言せずにフィルタリング可能です。テナンシー フィールド org_id、user_id、project_id、session_id、visibility、deleted、is_latest、has_embedding のテナンシー フィールドはアクセス制御用に予約されており、呼び出し元でフィルタリングすることはできません。
それをまとめています。上記の構成では次のようになります。
from agent_engine_sdk_memory import SourceSpec context = session.build_context_from_sources( query="what did we decide about the refund policy?", sources=[ # Exact match on a string key, and a range on a numeric one. SourceSpec( source=MemorySource.SEMANTIC, mode=RetrievalMode.HYBRID, metadata_filter={ "metadata.tier": "gold", "metadata.confidence": {"$gt": 0.8}, }, top_k=20, ), # Sources without a filter are unrestricted. SourceSpec(source=MemorySource.EPISODIC, mode=RetrievalMode.HYBRID, top_k=5), SourceSpec(source=MemorySource.STM, mode=RetrievalMode.TEXT, top_k=10), ], rerank=True, )
このメソッドは、3 つの接続モードすべてでバックエンドに到達します。ホストされたプロジェクトルート(project_id セット)では、Gateway は認証されたセッションから org/プロジェクトをスタンプして、同じソースごとのハンドラーにプロキシします。直接ルート(project_id空)では、UEプロキシはそれを転送します。 (アプリバウンド)ランタイムでは、プラットフォームはテナンシーをスタンプし、永続的な実行を通じて完全な応答を返します。
record_turn と build_context に加えて、Memoryオブジェクトは次の情報を公開します。
検索 -
search(query, sources=[...])はメモリ型全体で関数を使用し、ランク付けされた 1 つのlist[MemoryChunk]を返します。search_semantic、 、search_episodes、search_taxonomicはdiscover_procedures1 つのタイプをターゲットにしています。タイプ固有の書込みと読み取り(接続がCRUDをサポートする場合) —
save_semantic/get_semantic、save_episode/list_episodes、save_taxonomic/get_taxonomic_term/list_domains、およびsave_procedure/get_procedure。カスタム メモリ型
save(memory_type, content, tags=...)retrieve(memory_type, query, tags=..., top_k=...)- と は、プロジェクトのメモリ構成で宣言された型で動作します。組み込み型名は拒否されます - 上記の専用メソッドを使用してください。これらの呼び出しには ID フィールドは含まれません。プラットフォームは、リクエストから組織、プロジェクト、およびユーザーをスタンプします。カスタムタイプ ルートを提供していないプラットフォーム、または機能が無効になっているプラットフォームでは、呼び出しは`MemoryNotSupportedError"#errors">`__ で発生します。
上記のバウンド session を使用する短い例では、ファクターを書き込み、ラベルで再度読み取り、型全体を検索します。
# Save a semantic fact (user_id is inherited from the bound session). session.save_semantic(text="Prefers window seats on flights.", label="seat-preference") # Read it straight back by label. fact = session.get_semantic("seat-preference") # Search across memory types; returns one ranked list[MemoryChunk]. hits = session.search("travel preferences", sources=["semantic", "episodic"], top_k=5)
Memory は、コンテキスト マネージャーでもあります。 with Memory(service_account_token=...) as memory: は終了時に基礎となるトランスポートを解放します。
メモリサーバーの構成
SDK はメモリの読み取りと書込みを行います。サーバー は構成されません。設定、埋め込み、抽出 LM(抽出されるメモリ型)、フィルタ可能なメタメタデータ- プロジェクトの project-config.yaml の memory: ブロックに配置され、CLI で適用されます。そのサブドキュメントのみがアップロードされます。ファイルの残りの部分は無視されます。
agentengine memory configure # store the memory: block for this project agentengine memory apply --wait # roll the memory server so it takes effect
保存は適用されていません。 configure は構成を保存し、プラットフォームはそれを独自にプロジェクトのメモリサーバーに提供しますが、サーバーがその構成を読み取るのはスタートアップのみ です。ポッドが再起動するまで、新しい設定は読み取られずにディスク上に残ります。agentengine memory apply はその再起動 — を実行し、プロジェクトにまだメモリ ランタイムがない場合は最初にメモリ ランタイムをプロビジョニングします。
agentengine memory apply --upgrade は、環境が現在固定されているメモリ サーバー イメージにランタイムを追加します。これは、新しいサーバーを選択する方法 です。 --upgrade を持たない場合、イメージは単独で残ります。 agentengine memory status はいつでもランタイム状態を報告します。 apply 上の --wait は、準備ができるまでブロックします。
後で変更することはできません
構成の一部の部分は実質的に書込み (write) オンス ので、メモリの書込みを開始する前に決定します。
メタデータ パーティション キー - 宣言されたフィルタ可能な属性。一度宣言されたキーは、削除したり、そのタイプを変更したりすることはできません。
カスタム メモリ型宣言 - 型が受け入れられると、そのコレクションとタグセットはconfig APIを通じて編集または削除できなくなります。代わりに新しい型名を宣言します。
検索インデックス - は、インデックスがまだ存在しない場合にのみプロビジョニングされます。サーバーが起動した後にパーティションキーを追加しても、既存のインデックスは再構築されません。ドリフトがログに記録され、その後新しいキーのフィルターは暗黙で無視されるのではなく、データベースで失敗します。インデックスの再作成は 手動操作です。
ログ レベル、抽出 LVM、および有効な抽出タイプは変更して再適用できます。埋め込みモデルまたは次元を変更するには、既存のメモリを移行して再埋め込みする必要があります。次元の変更にはベクトル検索インデックスの再構築も必要です。
ID の解決方法
メモリ操作は、user_id、agent_id、session_id によって範囲され、MemoryRequestContext で実行されます。呼び出しごとに、すべてのフィールドは3 つの階層を通じて解決され、最も優先順位が高いのは次のとおりです。
呼び出し引数 - メソッドに直接渡される値(例:
search_semantic(query, user_id="user_2"))。限界のあるコンテキスト。
MemoryRequestContextが に渡されました。bind(...)ランタイム コンテキスト。ランタイムによって提供され、アプリバウンド パスで使用されるオープン ID です。
空白または空白のみの値は、すべての階層で設定されていないとしてカウントされます。agent_id は常に任意です。save_semantic save_taxonomicsave_procedureuser_idsave_episodeuser_idsession_idIDMemoryIdentityError は、タイプ固有の書込みrecord_turn build_context(write) に対してのみクライアント側で検証されます。 、 、 には が必要で、 には と の両方が必要です(それぞれ 8 が発生しますフィールドを解決できない場合は、 }。ワークフロー操作( 、 、検索)およびget_* /list_* の読み取りは、ローカルでは ID を強制しません。バックエンド に解決されたものをバックエンドに転送します。バックエンドは、トランスポート エラーとしてリクエストを拒否する可能性があります。
``session_id`` は操作によってスコープ設定されます。これはスレッドを識別するため、セッション bindI/O: とrecord_turn の短縮メモリ リージョンに対してのみ継承されます(build_context /ランタイムから)。エポック検索とセマンティック検索はそれを継承しません。 search_episodes、 、および のエポックlist_episodes レガシー演算子は、呼び出し引数のみからsearch() session_idを解決します。エポック メモリはセッション単位で保存されるため(集約された回では )、バインドされたセッションではすべての耐久メモリが暗黙的にフィルタリングされ、エラーのない空のリストが返されます。セッション範囲のエポック読み取りが必要な場合は、検索呼び出しにsession_id: null session_id=を明示的に渡します。 (これにより、SDK はプラットフォームagent-engine-sdk-langgraph / のパスと一致します。このパスではすでにエポック検索で明示的なTenantRuntime session_idが必要です。user_id とagent_id は影響を受けず、bind /runtime から引き続き継承されます。読み取りの場合。
書込みの可視性の設定
すべての書き込みには visibility が必要です。タイプは異なる方法で使用されるため、デフォルトはメモリタイプによって異なります。
書込み (write) | デフォルトの可視性 |
|---|---|
|
|
|
|
分類メモリのデフォルトは org です。ドメイン語彙は定義で共有されているためです。タームとその意味は、1 人のユーザーのプライベートプロジェクトであることはほぼありません。その他のすべてのデフォルトは private であるため、特に明示がない限り、保存する ファセット は学習されたユーザーに限定されます。
record_turn は例外です。visibility は必要ありませんが、user_id も必要ありません。セッションの結果は常にバインドされたユーザーとセッションの下に書き込まれるため、 が記録される前に bind(...) ください。呼び出しごとにユーザーをオンに設定する方法はありません。
# Private to user_1 — the default. session.save_semantic(text="Prefers window seats.", label="seat-preference") # Readable across the whole organization. session.save_semantic( text="Refunds over $500 need manager approval.", label="refund-policy", visibility="org", )
読み取りのスコープ設定
読み取りでは、visibility が設定されていない状態のままになるため、解決される ID によってのみ制約されます(通常はバインドされた user_id)。これはパーソナライズに適したデフォルトです。どの可視性でも、ユーザーが所有するすべてを取得します。
共有知識にアクセスするには、可視性とを渡し、ここでは と ルール バイトを渡します。 にバインドされたハンドルも引き続きuser_id="user_1" user_idに貢献するため、ユーザー_1 が所有する org に表示されるレコードのみが読み取られます。
session = memory.bind(MemoryRequestContext(user_id="user_1", session_id="thread_123")) session.search_semantic("refund policy", visibility="org") # user_1 AND org
user_id=NoneNoneを渡しても、拡大はありません。 または空白の引数はすべての階層で指定されていないとしてカウントされるため、限界値に該当します。 の境界がないハンドルを持つすべてのユーザーで読み取ります。user_id
# The original handle is unbound, so it carries no user_id. memory.search_semantic("refund policy", visibility="org") # Or bind only the parts you want. thread = memory.bind(MemoryRequestContext(session_id="thread_123")) thread.search_semantic("refund policy", visibility="org")
したがって、ユーザー自分の履歴とチームの共有知識の両方を必要とする支援は、2 回の読み取りを発行し、それらをマージします。
personal = session.search_semantic(query, top_k=5) # user_1, any visibility shared = memory.search_semantic(query, visibility="org", top_k=5) # org-wide, any owner
Errors
エラーは 2 つのファミリーに分類されます。クライアント側のエラー サブクラス ValueError と は、通常、ネットワーク呼び出しの前に発生します。
MemoryClientError使用エラーの場合は「」に相当します。MemoryIdentityError— 必須 IDフィールドを解決できませんでした。サブクラスValueErrorを直接サブクラス化します(MemoryClientErrorの同義語であるため、except MemoryClientErrorにはキャッチされません)。MemoryNotSupportedError- アクティブな接続では操作は使用できません(「 の接続 」を参照してください)。メッセージには、操作と理由が付けられています。カスタムタイプ メソッド(save/retrieve)の場合、レスポンスでプラットフォームの機能が欠落していることが示されている場合は、 HTTP呼び出しの後に発生することもできます:ルート)またはゲートウェイの構造化された は、配置で無効になっているカスタム404 405400メモリ タイプを報告します。構造化された不明タイプ404 はリクエストエラーであり、機能ギャップではなく、MemoryBadRequestErrorを発生させます。
トランスポート エラーは MemoryAPIError から派生し、 HTTP status とレスポンス本体を含みます。
MemoryAuthError認証または認可に失敗しました(401/403)。MemoryBadRequestErrorリクエストが拒否されました(認証以外の 4x またはプロビジョニングされていない場合)。MemoryRouteNotFoundError— コアループリクエスト404 の に該当するため、ルート形状はバックエンド と一致しない可能性が高くなります。メッセージには、project_idを設定または設定解除するための方向のヒントが記載されています。サブクラスMemoryBadRequestError。MemoryNotProvisionedErrorプロジェクトのメモリ実行時間にまだ到達できません。MemoryServerError-バックエンドがエラー(5x)または解析不可または予期しないボディを返しました。MemoryConnectionErrorバックエンドにアクセスできませんでした。
モデル
リクエスト タイプとレスポンス タイプはパッケージルートからエクスポートされ、agent_engine_sdk_memory.models から再エクスポートされます。検索では MemoryChunk と ContextResponse が返されます。書込みでは、WriteTurnResult、CreateSemanticResult、CreateEpisodicResult などの型指定された結果が返されます。 SearchSource は検索可能なタイプを列挙します。コンテキスト構築は、別の構成モデルではなく、Memory.build_context の kwards で構成されます(例、enabled_sources と max_tokens)。これらを agent_engine_sdk ではなく agent_engine_sdk_memory からインポートします。ここに存在するために使用され、ここに移動されたモデルです。
自分のメタデータを読む
record_turn は任意の metadata ディレクティブを受け取り、短期間の検索では、チャンクの独自のスロットにそれが返されます(chunk.metadata["metadata"])。キーはプラットフォームの有効フィールド(session_id、role、turn_seq、...)とは別に保持されるため、 のキーは他のキーのキーと競合することはありません。キーに名前を付けることができます role または session_id を使用し、自分の値を返します。
衝突安全性がカバーしない 2 つの制限。値はラウンドトリップに耐えられる必要があるため、 JSONでシリアル化可能で、正のサイズである必要があります。また、キーをフィルタリング可能にするには、メタデータパーティションキーとして宣言可能である必要があります。ドットで区切られた各セグメントは ^[a-z][a-z0-9_]{0,63}$と一致する必要があり、最大 1 つのドットが許可され、いくつかの名前が予約されます(org_id 、 、 、project_id user_idagent_idcontent、embedding 、embedding_model_id 、 、created_at )。その形状の外側にあるキーTier $foo( 、 、a.b.c )は引き続き保存および返されますが、フィルタリングはできません。
空のディレクティブはメタデータなしとして扱われます。metadata={} はチャンクに metadata スロットなしでタームを記録するため、呼び出し元で何も提供されない場合は chunk.metadata.get("metadata", {}) でそれを読み取ります。セマンティック メモリは同じように動作するため、1 つの読み取りパスが両方をカバーできます。時系列、分類、手順は同じように動作します。書き込んだディレクティブは chunk.metadata["metadata"] の下に返され、空の はスロットが存在しないことを意味します。エポックは 1 つの例外です。互換性フィルターは、citation_score、llm_confidence_score、および combined_score がまとめて含まれている場合、その形状は移行前の内部ブロブと一致するため、関連のないキーを含むディレクティブ全体を削除します。取得には、chunk.metadata["contextual_metadata"] が含まれる場合もあります。これはユーザーのデータではなく、プラットフォーム独自の抽出アーティファクトであり、依存する必要がある契約の一部ではありません。
短期間メモリはセッションにスコープが設定されているため、書込みと読み取りは同じ名前を付ける必要があります(一度バインドしてそれを渡します)。
from agent_engine_sdk_memory import ( Memory, MemoryRequestContext, MemorySource, RetrievalMode, SourceSpec, ) session_id = "session-42" memory = Memory(base_url="http://localhost:8080").bind( MemoryRequestContext(user_id="user-1", session_id=session_id) ) memory.record_turn( role="user", content="The engagement is green and the rollout continues.", metadata={"engagement_id": "eng-alpha", "tier": 2}, ) context = memory.build_context_from_sources( query="what is the engagement status?", sources=[ SourceSpec( source=MemorySource.STM, mode=RetrievalMode.HYBRID, metadata_filter={"metadata.engagement_id": "eng-alpha"}, ) ], session_id=session_id, include_memories=True, ) for chunk in context.selected_memories or []: print(chunk.metadata["metadata"]["engagement_id"])
Atlas Search は書き込みを非同期にインデックス化するため、 の直後に発行された読み取りでは、タームがまだ表示されない可能性があります。
スペルの違いを 1 つ認識する必要があります。これはネストされたディレクティブやchunk.metadata["metadata"]["engagement_id"] 内で読み取りますが、修飾インデックスパス でフィルタリングします。ネストを確認します。このフィルターは保存済みドキュメントに対処します。ここでのディレクティブは実際に{"metadata.engagement_id": ...}metadata の下に存在します。
要求されるパスを一覧表示するエラーで拒否されるため、このエラーが答えを提供します。
フィルタ可能なメタデータは最初にプロジェクトに対して宣言する必要があります。上記のengagement_id metadata_partition_keyは の下に表示され、 はshort_term metadata_partition_indexにリストされている必要があります。 「 フィルタ可能なメタデータの使用 」で「 フィルタ可能なメタデータの宣言 」を参照してください。
内部構造
以下のセクションでは、パッケージが構築方法について説明します。使用する必要はありません。
パッケージ レイアウト
agent_engine_sdk_memory/ ├── memory.py # Memory — the public, transport-free facade ├── protocol.py # MemoryRequestContext, MemoryRuntime + MemoryCrudClient seams ├── identity.py # resolve_identity — call arg > bind ctx > runtime ctx ├── errors.py # MemoryIdentityError + the typed transport-error family ├── models.py # Pydantic models for memory requests/responses ├── validation.py # require_positive_max_tokens — public build_context guard ├── _transport.py # _HttpTransport — shared retry / error-mapping / lifecycle ├── _http_runtime.py # _HttpMemoryRuntime — the workflow ops + per-backend profiles ├── _direct_crud.py # empty-tenancy MemoryCrudClient over the shared transport ├── _wire.py # custom-type request-body builders shared by the CRUD clients ├── _tag_syntax.py # client-side custom-type name + tag-syntax checks ├── _client.py # MemoryClient — internal HTTP client for the Memory Server API └── _denylist.py # do-not-add dependency denylist (see below)
Memory はトランスポートフリーです。ワークフロー操作(record_turn、build_context、検索、discover_procedures)を挿入された MemoryRuntime に、タイプ固有のCRUDを挿入された MemoryCrudClient に委任します。パブリック サーバーは tests/test_package_contract.py のスナップショット テストによって固定されています。 MemoryClient は内部のままです。呼び出しごとのテナンシー(org_id、ボディレベル project_id)は公開署名に表示されることはありません。パブリック サーバー上でのみの project_id は、リクエスト本文ではなくURLに入力されるオプションのコンストラクターのルートシェイプ セレクターです。
依存関係拒否リスト
pydantic + httpx のみの制約は強制されており、強制されています。 _denylist.py は既知の重いディストリビューションとインポート名(lang、fastapi、pymongo、...)を一覧表示します。パッケージをインポートするとそれらが sys.modules にプルされると、tests/test_package_contract.py は失敗します。
使用しています。
agent-engine-runner-shared はこのパッケージをワークスペース依存関係として宣言し、agent_engine_runner_shared/memory.py に内部 MemoryClient を構築して、その実行コンテキスト検索を execution_id_provider 呼び出し可能として渡します。これにより、このパッケージがプラットフォーム コードをインポートしなくても、リクエストごとの実行 ID ヘッダーは動作します。