amu-pgvector について
amu-pgvector は、エージェント向けの PostgreSQL と pgvector によるメモリストアです。結果の導出に使われた機密列に基づいてアクセスを制御し、SQL、ライブラリ連携、MCP サーバーに共通の行レベルセキュリティを適用します。
主な機能
- 01導出元に基づくアクセス制御
- 02PostgreSQL の行レベルセキュリティ
- 03セマンティックなメモリ検索
- 04メトリクス定義の競合確認
- 05SQL、LangChain、MCP の各インターフェース
活用シーン
- 01部門をまたぐキャッシュ結果の共有
- 02制限列から導出した結果の再利用防止
- 03データベースロール権限でのメモリ検索
MCP 対応
オプションの MCP サーバーは `amu_search`、`amu_record`、`amu_check_conflict` をツールとして公開します。各操作には同じ PostgreSQL の行レベルセキュリティが適用されます。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
uvx amu-pgvectorAMU_PGVECTOR_DSNシークレットPostgres DSN for the role this server runs as. Results are gated by row-level security under this exact role -- use an amu_writer-member role for amu_record/amu_check_conflict, or an amu_agent_base-member role for read-only amu_search.AMU_PGVECTOR_EMBEDDING_DIMEmbedding vector dimension, used only by the built-in deterministic fallback embedder when sentence-transformers (the amu-pgvector[st] extra) isn't installed. Must match the dimension sql/amu_pgvector.sql was installed with. Default: 1536.ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。
ツール
3掲載時のツール一覧 · 2 週間前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| k | integer | いいえ | |
| query | string | はい | |
| metric_name | any | いいえ |
詳細
amu-pgvector
PostgreSQL + pgvector における系譜認識型メモリーガバナンスのリファレンス実装です (Sangaraju & Vissa、IEEE Access、10.1109/ACCESS.2026.3730363)。
問題
Finance が顧客セグメントの avg(income) を計算し、その結果をキャッシュして、同じ質問をする次のエージェントが再計算せずに済むようにしたとします。その後、Marketing のエージェントが意味的に似た質問「セグメント別の平均顧客収入は?」をすると、指標名または内容タグだけで制御する素朴な共有メモリーは、Finance のキャッシュ済みの結果を返してしまいます。Marketing は income を見ることを一度も許可されていません。結果そのものは数値なので、収入の情報には見えません。しかし、Marketing がアクセスを許可されていない列から導出されたものであり、指標名や内容の一致ではそれを検知できません。このプロジェクトが解決するのは、この情報漏えいです。つまり、結果がどのように導出されたかに基づいて再利用を制御し、結果がどのように見えるかには依存しません。
60 秒で始めるクイックスタート
git clone https://github.com/sangaraju1988/amu-pgvector.git
cd amu-pgvector
docker compose up -d
psql -h localhost -p 5433 -U amu_owner -d amu_dev -f sql/amu_pgvector.sql
# password: amu_owner_password
uv sync --all-packages --all-extras # or: pip install amu-pgvector
from amu_pgvector import AMUStore
from amu_pgvector.embeddings import fake_embedder
DSN = "postgresql://amu_owner:amu_owner_password@localhost:5433/amu_dev"
embed = fake_embedder(dim=1536) # swap for a real embedding model in production
admin = AMUStore(DSN)
admin.register_sensitive_column("income")
admin.grant_department_permission("Finance", "income")
admin.create_agent_role("finance_agent", "Finance", "finance_pw")
admin.create_agent_role("marketing_agent", "Marketing", "marketing_pw")
admin.record(
"SELECT avg(income) FROM customers",
{"avg": 82000},
metric_name="avg_income",
description="average customer income",
owner_department="Finance",
embed_fn=embed,
)
finance_dsn = "postgresql://finance_agent:finance_pw@localhost:5433/amu_dev"
marketing_dsn = "postgresql://marketing_agent:marketing_pw@localhost:5433/amu_dev"
AMUStore(finance_dsn).search("average customer income", k=5, embed_fn=embed)
# -> [SearchResult(metric_name='avg_income', ...)]
AMUStore(marketing_dsn).search("average customer income", k=5, embed_fn=embed)
# -> [] -- Marketing was never granted `income`, so Postgres itself
# never returns the row, regardless of how the query is asked.
上記の各行は、ここに記載する前に、この正確なリポジトリで実行して確認済みです(ゼロからのインストールの実際の手順については docs/design.md を参照してください)。amu_owner/amu_owner_password は docker-compose のデフォルトです。ローカル開発以外で使用する場合は変更してください。
ゲートの仕組み
amu.memory_units は、FORCE ROW LEVEL SECURITY が有効になった通常の Postgres テーブルです。書き込みはすべてトリガーを経由します。トリガーは、キャッシュ済みの結果を実際に生成した SQL の系譜を(エージェントの自己申告ではなく、amu-governance の sql_lineage モジュールを介して)抽出し、登録済みのマテリアライズドビュー/派生テーブルのエッジをすべてたどって閉包を求め、S(a)、つまり系譜が実際に参照する機密列の集合を計算します。SELECT ポリシーは S(a) ⊆ P(d) を適用します。行が表示されるのは、S(a) のすべての列がリクエスト元ロールの許可集合 P(d) に含まれる場合に限られます。このテーブルに対するすべてのクエリで、すべてのクライアントに同じポリシーが適用されます。生の SQL、amu.search()、Python クライアント、LangChain 統合、MCP サーバーのいずれも、同じポリシーを通過します。これは、特定のクライアントのフィルターではなく、テーブル自体のポリシーだからです。
sequenceDiagram
participant Writer as amu_writer role<br/>(trusted interception layer)
participant PG as Postgres: amu.memory_units<br/>(FORCE ROW LEVEL SECURITY)
participant Trigger as BEFORE INSERT trigger
participant Finance as finance_agent role
participant Marketing as marketing_agent role
Writer->>PG: INSERT ... lineage = {"steps":[{"table":"customers","columns_used":["income"]}]}
PG->>Trigger: compute lineage_columns, S(a), lineage_status
Trigger-->>PG: sensitive_columns = {income}, resolved
Finance->>PG: SELECT ... (session_user = finance_agent)
PG->>PG: S(a)={income} subset P(Finance)={income,...}? yes
PG-->>Finance: row returned
Marketing->>PG: SELECT ... (session_user = marketing_agent)
PG->>PG: S(a)={income} subset P(Marketing)={...}? no
PG-->>Marketing: row not returned
論文の各概念が具体的な SQL オブジェクトにどう対応するかについては docs/design.md を、すべてのテーブル、関数、ロール、ポリシーの網羅的なリファレンスについては docs/sql-reference.md を参照してください。
セキュリティモデルと制限
保護対象: キャッシュ済みの結果の導出元列を介した部門間の情報漏えい(中核となる保証であり、RLS によって適用されます);指標定義の競合の見落とし(amu.check_conflict());AMU がすでに存在する状態で列が機密として再分類された場合(トリガーが対象行を再計算するため、書き換えは不要です);系譜の閉包処理が長い、または循環する導出チェーンを黙って打ち切ること(フェイルクローズ方式で、部分的に追跡した結果を返すのではなく、AMU を未解決として扱い、表示しません)。
明示的に対象外: 系譜について虚偽を申告する書き込み元(SQL ゲートは設計上、amu_writer の入力を信頼します);個別には許可された複数の AMU を組み合わせた推論;常に RLS をバイパスする Postgres のスーパーユーザー;タイミングサイドチャネル;デフォルトでは無効になっている「利便性モード」の ID オプション(プール接続上の、信頼されたアプリケーションコードとエージェントの影響を受けるコードとの境界と同程度の安全性しかありません)。
詳細な説明は docs/threat-model.md を参照してください。
ベンチマーク
以下の数値はすべて、コミット済みの results/<name>/<timestamp>/ 実行結果(各実行の manifest.json に記録された git SHA、Postgres/pgvector のバージョン、ハードウェア、シード、パラメーター)から benchmarks/generate_summary.py が生成した results/SUMMARY.md から直接引用しています。再現または検証するには、ベンチマークスクリプトを自分で再実行してください。ここに推定値はありません。
漏洩率(600 件の合成 AMU に対する 2000 件のリクエスト。Finance/Marketing/Support):
| 条件 | 処理件数 | 部門間の漏洩 | 漏洩率 |
|---|---|---|---|
| 単純な方式(コンテンツで制御、系譜チェックなし) | 2000 | 1010 | 50.5% |
| amu-pgvector(RLS で制御) | 990 | 0 | 0.0% |
レイテンシ(k=10 での p50/p95。RLS と hnsw.iterative_scan はそれぞれオン/オフ、各行で同じロール/クエリ/データを使用):
| n | RLS | iterative_scan | p50(ms) | p95(ms) |
|---|---|---|---|---|
| 10,000 | オン | オン(amu.search() のデフォルト) | 66.8 | 70.2 |
| 10,000 | オン | オフ | 81.9 | 88.2 |
| 10,000 | オフ | オン | 19.5 | 21.8 |
| 10,000 | オフ | オフ | 49.2 | 52.3 |
| 100,000 | オン | オン(amu.search() のデフォルト) | 712.9 | 851.2 |
| 100,000 | オン | オフ | 43.4 | 65.7 |
| 100,000 | オフ | オン | 376.8 | 418.5 |
| 100,000 | オフ | オフ | 46.6 | 70.9 |
正確に読み取ってください。hnsw.iterative_scan=relaxed_order(デフォルトで amu.search() が使用する設定。大半の行が非表示でも、フィルター済みの結果が k 件に達するようにします)は、大規模になると実際にレイテンシのコストがかかります。この実行では、100k 行で iterative をオフにした場合より約 16 倍遅くなっています。これは以下の再現率保証の代償です。表示される割合が常に高い場合は、この設定なしでクエリを実行するほうがよいでしょう。100 万行の規模では試していません。この実行を行ったマシン(macOS の Docker Desktop。ホスト上の無関係なワークロードとリソースを共有)では、100k 行の HNSW インデックスの構築だけで約 7 分かかったため、外挿せずにそのまま記録しています。
フィルター済み再現率(ゲート付き HNSW 検索の recall@10 と、同じロールで実際に表示可能な行に対する正確な総当たり検索との比較、n=20,000):
| 表示可能な割合 | recall@10(平均) | recall@10(最小) |
|---|---|---|
| 50% | 100.0% | 100.0% |
| 10% | 100.0% | 100.0% |
| 1% | 100.0% | 100.0% |
インテグレーション
- プレーン SQL --
sql/amu_pgvector.sqlが最も重要な成果物です。冪等で、通常のデータベース所有者として(スーパーユーザー権限なしで)マネージド Postgres にインストールでき、vector以外の C 拡張は必要ありません。Supabase と Neon で同じように動作します(両方を対象とする、ゼロから始めるチュートリアルはsubmissions/supabase-neon-guide.mdを参照してください)。 - LangChain --
langchain-amuはAMUVectorStoreとAMURetrieverを提供します。すべての読み取りはストア独自の Postgres ロールで実行されるため、RLS は生の SQL と同じように LangChain にも適用されます。packages/langchain-amu/を参照してください。 - MCP --
pip install amu-pgvector[mcp]を実行すると、amu_search、amu_record、amu_check_conflictを同じように制御されたツールとして公開するamu-pgvector-mcpコンソールスクリプトが追加されます。packages/amu-pgvector/src/amu_pgvector/mcp_server.pyを参照してください。
引用
@article{sangaraju2026lineage,
title = {Lineage-Aware Memory Governance: A Derivation-Gated Framework
for Privacy-Preserving Column-Level Access Control in
Enterprise AI Agents},
author = {Sangaraju, Venkata and Vissa, Sudhir},
journal = {IEEE Access},
year = {2026},
doi = {10.1109/ACCESS.2026.3730363}
}
このソフトウェア自体も引用する場合は、CITATION.cff を参照してください。
ライセンス
MIT です。LICENSE を参照してください。
関連情報
- 論文:Sangaraju & Vissa、IEEE Access、DOI 10.1109/ACCESS.2026.3730363
- リファレンスライブラリ:amu-governance(PyPI)
docs/design.md-- 論文の概念を SQL オブジェクトに対応付けたものと、構築中に見つかった実際の注意点すべてdocs/threat-model.md-- 保護されるものと、保護されないものdocs/sql-reference.md-- すべてのテーブル、関数、ロール、ポリシー
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。