エージェントのメモリ3種類と保存・再埋め込みコスト
意味・エピソード・手続き記憶の違いを表で整理し、VPSで保存と再埋め込みにかかるコスト、増え続けるログの容量と運用上の注意点を解説します。
エージェントの3種類のメモリとは
エージェントのメモリは3種類に分かれ、それぞれが有料のハードウェアに異なる負荷をかけます。意味記憶は事実を保持し、エピソード記憶は何が起きたかを保持し、手続き記憶は作業の実行方法を保持します。以下の表では、サーバーの例を添えてそれぞれを定義します。その後に続く内容は、通常は書かれないもう半分の話です。つまり、各種類を保存するコストと、再構築するコストについて説明します。
The data behind this chart
[
{
"label": "Semantic",
"what_it_holds": "Facts the agent should treat as currently true",
"server_example": "The database listens on 10.8.0.4:5432 and the nightly dump runs at 03:15 UTC"
},
{
"label": "Episodic",
"what_it_holds": "A record of one past event or session",
"server_example": "On 2026-08-11 the deploy failed because the disk was full, and rotating logs fixed it"
},
{
"label": "Procedural",
"what_it_holds": "How to carry out a task, as steps the agent can run",
"server_example": "The restore runbook: stop the service, load the dump, run migrations, start the service"
}
]名称は人間の心理学から借用していますが、厳密な対応関係ではありません。この分類に実用的な意味があるのは、3種類でサイズと復旧経路が異なるためです。すべてを1つのベクトルストアに入れると、それぞれの特性が損なわれます。
意味記憶は小規模に保ち、手動で編集できるようにする
自分のサーバーに関する数百件の事実は、テキスト数十 KB 程度です。ここで問題になるのは保存容量ではありません。訂正です。意味記憶に誤った事実があると、その後にエージェントが生成するすべての回答が誤ります。そのため、保存先では名前で事実を1件検索し、変更し、古い値が確実に消えたことを確認できなければなりません。
この用途には、キー付きストアが適しています。たとえば、主キーを持つ Postgres のテーブルや、git で管理する小さな markdown ファイルのディレクトリです。どちらも1回のクエリで値を表示し、その場で編集できます。類似度検索では、これを実現できません。キーではなく類似性で取得するためです。「データベースのポートを変更する」は、「データベースのポートに言及しているすべてのチャンクを探す」という処理になります。しかし、すべて見つけたことを証明できません。事実にはキーを付けてください。曖昧な想起も必要なら、事実を埋め込みデータとしても保存します。ただし、正しい情報として扱うのはキー付きのコピーです。
古くなった事実は、自動的には通知されません。ポートを変更しても行が残っていれば、エージェントは6月には正しかった番号を回答し続けます。エージェントメモリの陳腐化と削除のポリシーは、このページのもう一方の要素です。テーブルがまだ小さい段階で設計しておくほうが、はるかに低コストです。
エピソード記憶が際限なく増える理由
エピソード記憶はログであり、ログは増え続けます。すべてのセッション、すべてのツール呼び出し、すべての失敗したコマンドがエピソードの候補になります。1 ターンごとに 1 行を書き込むエージェントは、1 か月で誰も読み切れないほど多くの行を書き込みます。コストはディスク容量だけではありません。埋め込み済みの各エピソードも、検索が走査するインデックスに追加されます。
削除がまだ容易な、テーブルを作成する時点で保持ルールを決めてください。大半は 2 つの質問で決まります。1 つ目は、何をそもそも書き込む価値があるかです。通常、セッションの要約には価値がありますが、1 回の ls -la の完全な出力にはないことが多いです。2 つ目は、各エピソードの種類をどのくらい保持するかです。例えば、生のエピソードは 30 日間、セッションの要約は 1 年間とします。
すべてのエピソード行に created_at のタイムスタンプと source 列を追加してください。created_at がなければ、経過時間で削除できません。source がなければ、1 つの問題のある発生元から追加されたデータをすべて削除できません。これは、Web ページやチケットがメモリへの書き込み命令を埋め込んでいたと判明した日に必要になります。
DELETE FROM episodes WHERE created_at < now() - interval '30 days';これを systemd timer から実行し、その後に行数とテーブルサイズが実際に変化しているか確認してください。誰も実行しない保持ポリシーは、コメントにすぎません。
psql -d agentmem -c "SELECT count(*) FROM episodes;"
psql -d agentmem -c "SELECT pg_size_pretty(pg_total_relation_size('episodes'));"手続き的記憶はリポジトリで管理する
手続き的記憶とは、エージェントが作業を実行する方法です。シェルスクリプト、skill file、番号付き手順の runbook などが該当します。これはコードであり、コードはコードを置く場所、つまりレビュー、バージョン管理、差分確認ができる git repository に置くべきです。
runbook を分割したチャンクとして埋め込んで保存すると、近似的なコピーしか取得できません。検索ではスコアが最も高いチャンクが返されるため、エージェントが step 2 と step 5 に基づいて処理し、step 3 は取得されないことがあります。また、どのバージョンの手順を実行したかも記録されません。git では、git log によってこの2つの問題を解決できます。保存コストはほぼゼロです。これも、手続き的記憶に vector の料金を支払うべきではない理由です。
ディスク上で embedding が実際に占める容量
The data behind this chart
[
{
"label": "bge-small-en-v1.5 (384 dims)",
"bytes_per_vector": 1544,
"mib_per_100k_rows": 147.2
},
{
"label": "bge-base-en-v1.5 (768 dims)",
"bytes_per_vector": 3080,
"mib_per_100k_rows": 293.7
},
{
"label": "bge-large-en-v1.5 (1024 dims)",
"bytes_per_vector": 4104,
"mib_per_100k_rows": 391.4
},
{
"label": "text-embedding-3-small (1536 dims)",
"bytes_per_vector": 6152,
"mib_per_100k_rows": 586.7
},
{
"label": "text-embedding-3-large (3072 dims)",
"bytes_per_vector": 12296,
"mib_per_100k_rows": 1172.6
}
]pgvector は vector を、1 次元あたり 4 bytes と 8 byte のヘッダーで格納します。そのため、この容量は事前に計算でき、データを読み込む前に見積もれます。384 dimension のベクトル 1 件は 1544 bytes です。100,000 件の chunk では、ベクトルだけで 147.2 MiB になります。同じ corpus を 3,072 dimensions で embedding すると、1 行あたり 12296 bytes で、容量は 1172.6 MiB です。同じテキストでも、必要なストレージは約 8 倍になります。
これは vector column だけの容量です。chunk text、primary key、行のオーバーヘッド、index も加わります。特に忘れられやすいのが index です。HNSW(hierarchical navigable small world。pgvector が構築する graph index)は、リンク先のベクトルを独自に保持します。そのため、index 付きのストレージは、上記の数値の 2 倍を十分に超えます。推測せず、実際の環境で測定してください。
SELECT pg_size_pretty(pg_total_relation_size('memories')) AS total,
pg_size_pretty(pg_relation_size('memories_embedding_idx')) AS idx;検索が高速に感じられるかどうかは RAM で決まります。graph はメモリ上にある間だけ高速に走査できるためです。index が Postgres のメモリに収まる容量を超えると、検索はディスクからの読み取りを開始し、latency が上昇します。構築処理にも maintenance_work_mem という上限があります。graph がこの上限を超えると、構築処理はそのことを示して速度を落とします。
NOTICE: hnsw graph no longer fits into maintenance_work_mem after 61440 tuples
HINT: Increase maintenance_work_mem to speed up builds.同じ corpus の容量を減らす方法は 2 つあります。1 つ目は、より小さい model を選ぶ方法です。384 dimensions は 1,536 dimensions の 4 分の 1 の容量で済みます。自分のメモを再検索する用途では、精度の差が許容できる程度に小さいこともよくあります。2 つ目は、half precision で保存する方法です。halfvec type は 1 次元あたり 2 bytes と同じ 8 byte のヘッダーを使います。そのため、column と index を合わせた容量をほぼ半分にできます。
model を選ぶ前に知っておくべき上限があります。2026 年 8 月時点では、vector column に index を作成できるのは最大 2,000 dimensions までです。そのため、3,072 dimensions の embedding は column には格納できますが、index では拒否されます。
ERROR: column cannot have more than 2000 dimensions for hnsw indexhalfvec は最大 4,000 dimensions まで index を作成できます。そのため、通常は cast した値に index を作成します。
CREATE INDEX ON memories USING hnsw ((embedding::halfvec(3072)) halfvec_cosine_ops);PostgreSQL では別のメモリサービスより pgvector が適する場合
すでにそのサーバーで Postgres を実行している場合、ベクトル処理に必要なのは 1 つのパッケージと 1 つの文だけです。
psql -V
sudo apt install postgresql-16-pgvectorCREATE EXTENSION vector;パッケージ名の数字は Postgres のメジャーバージョンです。Ubuntu 24.04 では 16 なので、入力する前に psql -V を確認してください。
メモリをそのデータベースに保持すると、メモリとアプリケーションデータを同時に対象にするバックアップが 1 つで済み、接続プールも 1 つに統一できます。さらに、トランザクションを利用できます。事実とそれを説明する行を同時にコミットするか、両方とも失敗させられます。別のサービスでは、これを保証できません。
次のいずれかに該当する場合は、専用のメモリサービスへ移行してください。検索負荷がアプリケーションと競合し、専用マシンを必要とする場合。複数のホスト上にある複数のエージェントで 1 つのメモリを共有する場合。あるいは、完成した製品に含まれる抽出および重複排除ロジックが必要な場合です。これは 自己ホスト型 Mem0 メモリサーバーを選ぶ理由になります。1 つのエージェントで、チャンク数が数百万件未満のコーパスを扱う場合は、すでに運用しているサーバー上の pgvector のほうが、運用の手間も障害の発生要因も少なくなります。エンジン自体の選択と、各エンジンが RAM に求める容量については、VPS でベクトルデータベースを運用するで説明しています。
モデルを変更すると再埋め込みにかかるコスト
異なるモデルが生成したベクトルは比較できません。そのため、新しいモデルで新しいメモリだけを埋め込み、古い行をそのまま残すことはできません。異なる座標系間で計算した距離には意味がないため、混在したテーブルは無意味な結果を返します。モデルを変更する場合は、コーパス全体を再埋め込みする必要があります。
費用は、トークン(API の料金、または自分のサーバーで使用する CPU と GPU の時間)、実行中の経過時間、バックフィル中に両方のカラムを同時に保持するためのディスク容量、最後のインデックス再構築の 4 つに分かれます。安全な手順は、新しいカラムを追加し、バッチ単位でバックフィルし、クエリの参照先を切り替え、その後に古いカラムとインデックスを削除することです。
公開されている数値をそのまま信頼せず、自分のハードウェアで処理速度を測定してください。小規模な VPS で CPU のみを使って埋め込みを実行すると、同じモデルでも GPU 上より大幅に遅くなるためです。代表的なチャンク 1 つの処理時間を測定し、それにコーパスのサイズを掛けます。
ollama pull nomic-embed-text
time curl -s http://localhost:11434/api/embed \
-d '{"model": "nomic-embed-text", "input": "one representative chunk of your corpus"}' > /dev/nullローカルの埋め込みモデルでは、メモリストアと同じディスクにモデルの重みも保存されます。Ollama が取得したモデルを保存する場所では、その容量がどこで消費されるかを説明しています。
これを可能にする要件が 1 つあります。すべてのベクトルの隣に元のテキストを保持してください。ベクトルだけを保持するストアは、再埋め込みできません。新しいモデルに渡すテキストが残っていないためです。「この行を生成したテキストは何か」に答えられない場合、移行するには、最初にテキストを取得した場所から完全に再構築する必要があります。
メモリ稼働後に監視する項目
ストアの容量が増えると変わるのはコストだけではありません。古い事実は現状と合わなくなり、古いエピソードが有用な結果を押し出します。これは再びプルーニングの問題になります。メモリストアは、エージェントの将来の動作に影響を与えられる書き込み可能な入力でもあります。そのため、ストアへの書き込みを許可した対象は、後からエージェントの動作を誘導できます。Web ページやチケットのテキストがメモリに取り込まれる場合は、書き込み可能な対象を広げる前に、エージェントのメモリポイズニングの仕組みを確認してください。検索結果の件数は、すべてのリクエストで消費するトークン数にも影響します。ここから、エージェントの運用コストを予測可能に保つ方法を検討します。
FAQ
エージェントのメモリにベクトルデータベースは必要ですか?
事実の保存には必要ありません。意味メモリは小さく、名前を指定して修正する必要があるため、キー付きテーブルや git で管理する Markdown ファイルのディレクトリのほうが適しています。個々の値を確認して編集できるためです。コーパスが大きすぎて一覧化できず、意味に基づいて検索する必要がある場合は、埋め込みの導入効果があります。通常はエピソードメモリやドキュメントがこの対象です。すでに Postgres を運用している場合は、別のサービスを追加して管理しなくても CREATE EXTENSION vector で対応できます。
エージェントのメモリストアにはどの程度のディスク容量が必要ですか?
ベクトルの容量は予測できます。pgvector では、次元ごとに 4 bytes、ヘッダーに 8 bytes を使用します。768 次元では、100,000 行あたり 293.7 MiB です。384 次元では 147.2 MiB です。さらにチャンクテキスト、行のオーバーヘッド、ベクトルの独自コピーを保持する HNSW インデックスの容量が必要です。そのため、少なくともベクトル容量の 2 倍を見積もり、実際の容量は pg_total_relation_size で測定してください。
手続きメモリはどこに置くべきですか?
git リポジトリに置き、エージェントが直接実行するスクリプトまたはスキルファイルとして管理します。手続きには正確な再現性とバージョン履歴が必要ですが、類似度検索ではそのどちらも得られません。チャンク化したランブックを検索すると、スコアの高い部分だけが返されます。その結果、step 2 と step 5 は返されても step 3 が欠落することがあり、どのバージョンを実行したかも記録されません。
埋め込みモデルの変更にはどの程度のコストがかかりますか?
コーパス全体の再埋め込みが必要です。異なるモデルのベクトル同士は比較できないためです。トークン料金または GPU 時間、古い列と新しい列を同時に保持するためのディスク容量、インデックスの再構築に必要なコストを見積もってください。新しい列を追加し、バッチ単位でデータを埋め戻し、クエリを切り替えてから、古い列を削除します。これらの処理には、各ベクトルの横に元のテキストを保持していることが前提となります。