Attestari について
Attestariは、事実の出典追跡、過去の状態の照会、検証可能な削除を必要とするチーム向けの、AIエージェント用監査可能な長期記憶レイヤーです。出典記録、二時点検索、改ざん検知可能な監査ログを備え、インメモリ、SQLite、Postgresに対応します。
主な機能
- 01各事実の出典とタイムスタンプを記録
- 02過去の日付時点で記憶を検索
- 03削除証明書を発行
- 04ハッシュチェーンの監査ログを検証
- 05競合の処理と重複エンティティの統合
- 06セマンティック検索とキーワード検索
活用シーン
- 01出典を追跡できるエージェント記憶の構築
- 02過去の特定時点での事実の再構成
- 03削除と監査ログの完全性の証明
- 04SQLiteまたはPostgresでの永続記憶の運用
MCP 対応
MCPサーバーはstdio経由で`add_memory`、`search_memory`、`get_provenance`を提供します。破壊的な`forget_subject`ツールは明示的に有効化した場合のみ利用できます。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
uvx attestariATTESTARI_KEKシークレットBase64 32-byte root key. Set it to enable encryption at rest and cryptographic erasure (forget() destroys the subject's key and signs the certificate). Without it, forget() is a logical delete and certificates are left unsigned.ATTESTARI_DATABASE_URLシークレットPostgres DSN. Set it to use Postgres + pgvector instead of the default local SQLite file (concurrent access, indexed hybrid search).ATTESTARI_SQLITE_PATHWhere the default SQLite ledger lives.ATTESTARI_MCP_ALLOW_FORGETSet to 1 to offer the forget_subject tool (off by default, since erasure is irreversible and an agent can be steered by what it reads). When on, it is flagged destructive and takes two calls: a preview that returns a manifest hash, then a confirmation that passes it back.ANTHROPIC_API_KEYシークレットEnables Claude-powered fact extraction; falls back to the built-in regex extractor when unset.ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。
ツール
3掲載時のツール一覧 · 2 週間前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| text | string | はい | |
| agent_id | any | いいえ | |
| source_ref | any | いいえ | |
| subject_id | any | いいえ |
詳細
Attestari
AI エージェントのための監査可能なメモリレイヤーです。 エージェントに長期記憶を与えます — 他のメモリレイヤーと同様ですが、すべての事実に出典と日時の記録が付き、通常の Postgres 上で動作し、監査証跡は改ざんを検知でき、あらゆるユーザーのデータを署名付き証明書で削除したことを証明できます。
from attestari import Memory
mem = Memory()
mem.add("Hi, I'm Alice. I live in Toronto and I work at Acme.",
subject_id="alice", valid_from="2021-06-01")
mem.add("Update: I moved to Berlin and I now work at Globex.",
subject_id="alice", valid_from="2026-01-01") # supersedes Acme + Toronto
mem.answer("where does the user work", subject_id="alice") # -> "Globex" (latest)
mem.answer("where did the user live", subject_id="alice",
as_of="2022-01-01") # -> "Toronto" (time-travel)
cert = mem.forget("alice") # right-to-be-forgotten -> a signed deletion certificate
これを実行するためにデータベースも API キーもモデルのダウンロードも必要ありません — コアエンジンに依存関係は一切ありません。
目次
- 他との違い
- できること
- クイックスタート(30 秒)
- Python API
- 実際に動かす — Postgres · サーバー + コンソール · MCP · TypeScript
- REST API
- 設定
- 削除の証明と改ざん検知可能な監査を1つのデモで
- すでに Mem0 または Zep を利用していますか?ラップして使えます
- 監査担当者と DPO 向け
- 仕組み — そしてアトラス。エンジンを1ページの図で解説します
- プロジェクトの構成
- ドキュメントとコントリビューション
他との違い
ホスト型のメモリはブラックボックスです。「メモリ」の出所を確認できず、特定のユーザーのデータを適切に削除できず、履歴が改変されていないことを証明できません。銀行、病院、保険会社にとって — また GDPR / EU AI Act の下では — これは導入できない理由になります。Attestari は、まさにこの問題を解決する、中立的でセルフホスト可能なレイヤーです。
| Attestari | 一般的なメモリレイヤー | |
|---|---|---|
| 通常の Postgres 上で動作(グラフ DB 不要) | ✅ | ✗(Neo4j / ベクトルサービスが必要) |
| すべての事実に出典情報を記録 | ✅ | 一部のみ |
| 双時間性(「日付 D に何が真実だったか?」) | ✅ | ✗ |
| 削除の証明 + 証明書(GDPR) | ✅ | ✗ |
| 改ざん検知可能な監査証跡(ハッシュチェーン) | ✅ | ✗ |
| モデルベンダーを問わず利用可能 | ✅ | 通常は1社に固定 |
最後の2行が優位性の源です。証明できる削除: 各ユーザーのデータは、そのユーザー専用のキーで暗号化されます。forget() はキーを破棄するため、コンテンツは復元できなくなります — その一方で、不変のログと署名付き証明書が証拠として残ります。検証できる履歴: すべてのイベントがハッシュで連結されるため、verify_audit() はあらゆる編集、挿入、削除を検出します — その証明は削除後も残ります。
得られるもの
- すべての事実の出所を追跡 — 各メモリは、文字範囲、信頼度、タイムスタンプとともに、正確な元メッセージまでさかのぼれます。
- 双時間によるタイムトラベル — 過去の任意の時点を
as_ofで指定してメモリを検索できます。訂正は古い事実を消去せずに置き換えるため、履歴をいつでも再構成できます。as_ofは有効時間(事実が真だった時点)を対象にフィルタリングします。システム時間(Attestari が記録した時点)もすべての事実に保存されますが、まだその時間で検索する機能はありません。 - 削除の証明 —
forget(subject_id)はユーザーデータを暗号学的に消去し、署名付きのDeletionCertificateを返します。コンテンツのバックアップとレプリカも対象です(鍵の保存には独自のバックアップポリシーが必要です。脅威モデルを参照してください)。 - 改ざん検知可能な監査 — ハッシュで連結されたイベントチェーンです。
verify_audit()は編集・挿入・削除を検知し、その証明は暗号学的消去後も保持されます。 - 競合の解決 — 単一値と複数値の述語に対応しています。競合は黙って破棄されず、
conflicts()で確認できます。 - エンティティ解決 —「同じエンティティのさまざまな表記」を可逆的に統合します。統合は記録されますが、読み取り時にはまだ適用されません。
search()とtimeline()は、引き続き各表記を個別に扱います。 - ハイブリッド検索 — セマンティック検索(pgvector)⊕ キーワード検索(全文検索)に、双時間フィルターが組み込まれています。
- どこでも実行可能 — 依存関係ゼロのインメモリエンジン、または Postgres + pgvector コンテナー 1 つで永続化できます。グラフデータベースは不要です。あらゆるモデルベンダーで動作します。
クイックスタート(30 秒)
git clone https://github.com/attestari/attestari && cd attestari
python examples/spike.py # zero-dep end-to-end loop
python examples/agent_with_memory.py # the "give an agent memory" pattern
時間の経過に伴う事実の変化、日付ごとに異なる双時間クエリの回答、ソースまでさかのぼる出所の追跡、証明書を発行する forget() を確認できます。インストール、API キー、データベースは不要です。
Python API
単一のファサード Memory で、すべての機能を利用できます。
from attestari import Memory
mem = Memory() # zero-dep, in-memory (tests, demos)
# mem = Memory.local() # durable in one local SQLite file — zero infrastructure
# mem = Memory.postgres() # durable on Postgres + pgvector (production service)
# --- write -------------------------------------------------------------
fact_ids = mem.add(
"I moved to Berlin and I now work at Globex.",
subject_id="alice", # whose memory this is
valid_from="2026-01-01", # when it became true (defaults to now)
source_ref="chat:msg-42", # where it came from (for provenance)
)
# --- read --------------------------------------------------------------
mem.search("where does the user work", subject_id="alice") # ranked SearchResults
mem.answer("where does the user work", subject_id="alice") # -> "Globex"
mem.answer("where did the user live", subject_id="alice",
as_of="2022-01-01") # time travel: recall as-of a past date
mem.timeline(subject_id="alice") # full bi-temporal history
mem.get_provenance(fact_ids[0]) # source episode + span
mem.conflicts(subject_id="alice") # surfaced conflicts
# --- govern ------------------------------------------------------------
report = mem.verify_audit() # AuditReport — is the hash chain intact?
cert = mem.forget("alice") # DeletionCertificate — provable erasure
| メソッド | 戻り値 | 動作 |
|---|---|---|
add(text, *, subject_id, valid_from=…, source_ref=…) | list[str] | メッセージを取り込み、事実を抽出、重複排除し、置き換えます。 |
search(query, *, subject_id, as_of=…, limit=5) | list[SearchResult] | 任意の時間フィルターを適用したハイブリッド検索です。 |
answer(query, **kwargs) | str | None | クエリに対する最上位のオブジェクトを 1 つ返します。 |
timeline(*, subject_id) | list[Edge] | 対象の存続中および置き換え済みのすべての事実です。 |
get_provenance(fact_id) | Provenance | None | 事実を、そのソースエピソードと範囲までさかのぼって追跡します。 |
conflicts(*, subject_id=None) | list[dict] | 述語の多重度に基づいて解決された競合です。 |
resolve_entities(names=None, *, auto=True) | ResolutionResult | 重複するエンティティを統合します(可逆)。 |
forget(subject_id) | DeletionCertificate | 対象を暗号学的に消去し、証明を返します。 |
verify_audit(deep=False) | AuditReport | 改ざん検知可能なハッシュチェーンを検証します。deep=True にすると、イベント内容への検知されない変更も検出します。 |
本格的に実行する
3 つのストレージ階層で、1 つのエンジンを利用できます。監査チェーン、暗号学的消去、詳細検証、タイムトラベルといったすべての保証は、どの階層でも有効です。
| 階層 | ストレージ | 用途 | セットアップ |
|---|---|---|---|
Memory() | インメモリ | テスト、デモ、決定性 | なし |
Memory.local() | SQLite ファイル 1 つ(~/.attestari/attestari.db) | パーソナルエージェント、MCP、プロトタイプ — 永続化、単一プロセス | なし(標準ライブラリ) |
Memory.postgres() | Postgres + pgvector | 本番環境:同時アクセス、インデックス付きハイブリッド検索 | コンテナー 1 つ |
インフラなしで永続化(再起動後も保持。インストールや実行は不要):
from attestari import Memory
mem = Memory.local() # or Memory.local("path/to/agent.db")
Postgres + pgvector で永続化(コンテナー 1 つ、グラフ DB 不要):
ATTESTARI_PG_PORT=5433 docker compose up -d # applies the schema on first boot
pip install -e ".[postgres,embeddings]"
export ATTESTARI_DATABASE_URL=postgresql://attestari:attestari@localhost:5433/attestari
Postgres(マネージドまたはローカル)をすでにお持ちですか?スキーマはpip パッケージに同梱されています。クローンは不要です。
python -m attestari.initdb postgresql://user:pass@host:5432/db # idempotent
from attestari import Memory
mem = Memory.postgres() # durable; materialized projections + pgvector + full-text search
REST API + ビジュアルコンソールとして実行:
pip install -e ".[server]"
uvicorn attestari.server:app # API at /v1/*, the memory-graph console at /
MCP サーバーとして(Claude などのエージェントや各種フレームワークから利用できます)— stdio 経由で
add_memory / search_memory / get_provenance を公開し、オプトインすると(下記参照)
forget_subject も公開します。
MCP クライアントの設定に登録してください(例:Claude Desktop の
claude_desktop_config.json)。プロセスはクライアントが起動します。
{
"mcpServers": {
"attestari": {
"command": "attestari-mcp",
"args": [],
"env": {
"ATTESTARI_SQLITE_PATH": "~/.attestari/attestari.db",
"ANTHROPIC_API_KEY": "sk-ant-...",
"ATTESTARI_KEK": "base64-kek-here"
}
}
}
}
command/args のみが必須です。デフォルトで永続化されます(メモリはローカルの
SQLite ファイルに保存されるため、アプリを再起動しても保持されます)。サーバーごとの
設定は env ブロックに記述します。SQLite の代わりに Postgres を使用するには
ATTESTARI_DATABASE_URL を、抽出機能を Claude に切り替えるには
ANTHROPIC_API_KEY を、暗号学的消去を有効にするには ATTESTARI_KEK を追加します。
単独で実行する場合(デバッグなど)は、attestari-mcp(または
python -m attestari.mcp)を実行します。ローカルにインストールしなくても、MCP クライアントから
PyPI 経由で直接起動できます:uvx --from "attestari[server]" attestari-mcp。
MCP 経由の消去はオプトインです。 エージェントは読み取ったテキストに誘導される可能性があり、
消去は元に戻せないため、env ブロックで
"ATTESTARI_MCP_ALLOW_FORGET": "1" を設定した場合に限り forget_subject が提供されます。
このツールには破壊的操作のフラグが付けられ(ツールの注釈に対応するクライアントは実行前に確認を求めます)、実行には
2 回の呼び出しが必要です。最初の呼び出しでは消去対象のプレビューと manifest_hash が返されます。
2 回目の呼び出しではそのハッシュを confirm_manifest_hash として渡し、対象の記録が
プレビュー時の内容と一致する場合にのみ消去します。エージェントに人の記録を消去させる場合を除き、
無効のままにしてください。Memory.forget() と POST /v1/forget には影響しません。
TypeScript から利用する場合 — TS クライアントは REST API と通信するため、先にサーバーを
起動してください(上記参照。デフォルトは http://localhost:8000)。次に
clients/ts(@attestari/client)を参照してください。これは Memory の
インターフェースに対応する、型付きの薄いクライアントです。
LangChain で利用する場合: clients/langchain(attestari-langchain)を参照してください。
AttestariRetriever(出典情報付きで事実を想起)と AttestariChatMessageHistory
(あらゆるチェーンやエージェントで RunnableWithMessageHistory にそのまま使えるメモリ)を提供します。
実際の Claude による抽出を使う場合(依存関係ゼロの決定論的な抽出器の代わり):
pip install -e ".[anthropic]"
export ANTHROPIC_API_KEY=sk-ant-...
python examples/spike.py --llm anthropic
暗号学的消去を有効にする場合(forget() を論理削除から暗号学的消去に切り替えます)。暗号化は
ルートの鍵暗号化鍵(KEK)を使ってオプトインで有効にします。KEK を設定しない場合も
forget() は機能しますが、読み取り対象からデータを除外するだけです。KEK を一度生成し、環境変数に設定してください:
pip install -e ".[crypto]"
export ATTESTARI_KEK=$(python -c "from attestari.crypto import generate_kek; print(generate_kek())")
これで各対象者の PII は、対象者ごとの鍵を使って保存時に暗号化されます。forget() はその鍵を破棄するため、
暗号文は復元できなくなりますが、監査証明は保持されます。KEK を設定すると、
DeletionCertificate にも署名が付与されます(KEK から派生した鍵を使う HMAC-SHA256)。KEK を保持する人は誰でも
オフラインで verify_certificate(cert, kek) により検証できます。また、フィールドが 1 つでも変更された証明書は
検証に失敗します。KEK がない場合、forget() は論理削除となり、証明書には署名が付与されません。
KEK はデータベースとそのバックアップに保存しないでください(環境変数または KMS に保存してください)。
データの隣に保存すると、消去の意味がなくなります。バックアップの境界については
docs/the-moat.md を参照してください。
forget() が対象とする範囲と、対象外のもの:指定した subject_id のもとに記録されたエピソードと、そこから抽出された事実を消去します。別の人のメッセージから抽出された、その人物に関する事実は、メッセージを送った人のスコープに属するため、消去後も残ります。暗号化されるのはメッセージ本文と事実の値のみです。消去後も、各イベントのその他のフィールド(subject_id、事実の主語と述語(Claude による抽出では、主語が人名になる場合があります)、スコープ ID、タイムスタンプ、値の長さがわかる文字範囲、source_ref)は読み取り可能なままです。そのため、推測されにくい疑似匿名の subject_id を使い、個人データを source_ref に含めないでください。
消去された subject_id は再び使用できません。その ID に対する add() は ForgottenSubjectError を発生させ、何も保存しません(POST /v1/add は 409 を返し、MCP ツールも拒否します)。戻ってきた人を記録する場合は、新しい ID を使ってください。
Postgres は証明書のレジストリを保持します。Memory() と Memory.local() は forget() から証明書を一度だけ返すため、そこで自分で保存してください。
本番環境へのデプロイ。 本番環境向けのチェックリスト:
- ストレージ: 同時アクセスには
Memory.postgres()を使用します。python -m attestari.initdb "$ATTESTARI_DATABASE_URL"でスキーマを適用し、アップグレードのたびに再実行してください(冪等性があります。再実行するまでは、書き込みはその旨の指示とともに停止しますが、読み取りは引き続き機能します)。Memory.local()(SQLite)は単一プロセス向けです。1 つのエージェントや MCP サーバーには最適ですが、共有サービスには適しません。 - サーバー: プロセスマネージャーのもとで実行します。たとえば、リバースプロキシの背後で
uvicorn attestari.server:app --host 0.0.0.0 --port 8000 --workers 4を実行します。API には認証機能がないため、手前に独自の認証を設けてください。 - 1 人の subject に対する書き込み: 0.0.7 以前では、アプリ内で書き込みを直列化してください。同じ subject に対する 2 つの
add()呼び出しが同時に行われると、どちらも同じ古い値を置き換え、単一値の述語に対して有効な値が 2 つ残ることがあります。それ以降のリリースでは、ストアの書き込みロック内で置き換え対象を決定するため、同時書き込みも安全です。 - 消去後の書き込み: 0.0.7 以前では、
add()の前にis_forgotten(subject_id)を確認してください。KEK を設定した状態で消去済みの subject に書き込むと、すべての subject について、その後のログ読み取りがInvalidTagで失敗します。復旧するには、keyringテーブルからその subject の行を削除してください。それ以降のリリースでは、書き込みが拒否されます。 - 抽出とエンベディング:
ANTHROPIC_API_KEYを設定すると(抽出機能が Claude に自動で切り替わります)、実際のセマンティックベクトルを利用するには[embeddings]をインストールしてください。 - 鍵: KMS/シークレットマネージャーから
ATTESTARI_KEKを環境変数として注入し、イメージや DB に埋め込まないでください。バックアップから消去済みの subject が復元されないよう、keyringテーブルは別の短期保持ポリシーでバックアップするか、KEK をローテーションしてください。docs/the-moat.md を参照してください。 - バックアップ: 派生プロジェクションテーブル(
edge、entity)も除外してください。これらには検索用の平文の事実テキストが含まれ、(暗号文の)イベントログから完全に再構築できるため、バックアップすると消去の効果が弱まります。これらのテーブルを含めずに復元した場合、最初の接続時に再構築されます。 - シークレット:
.envファイルから自動的に読み込まれる値はありません。プロセスを起動する前に環境変数をエクスポートするか、オーケストレーターのシークレット注入機能を使用してください。
REST API
uvicorn attestari.server:app で次のエンドポイントが提供されます。
| メソッドとパス | 目的 |
|---|---|
GET /healthz | 稼働確認。 |
POST /v1/add | メッセージを取り込みます。 |
GET /v1/search | ハイブリッド検索(q、subject_id、as_of、limit)。 |
GET /v1/timeline | subject の完全な双時制履歴。 |
GET /v1/provenance/{fact_id} | 事実の出典を追跡します。 |
POST /v1/forget/{subject_id} | 証明可能な削除 → 証明書。 |
GET /v1/conflicts | 表面化した競合。 |
GET /v1/audit/verify | 監査ハッシュチェーンを検証します。 |
GET /v1/graph | メモリーグラフ(コンソール用)。 |
GET / | ビジュアルグラフコンソール。 |
設定
環境変数(すべて省略可能です。エンジンはどれも設定しなくても動作します):
| 変数 | 効果 |
|---|---|
ATTESTARI_DATABASE_URL | Postgres DSNです。サーバー/MCPはローカルのSQLiteではなくPostgresを使用します。 |
ATTESTARI_SQLITE_PATH | Memory.local() ベースのサーバー/MCPがSQLiteファイルを保存する場所です(デフォルトは ~/.attestari/attestari.db)。 |
ATTESTARI_KEK | ルート鍵暗号化鍵です。有効にすると、暗号シュレッディングによる削除が有効になります。 |
ATTESTARI_MCP_ALLOW_FORGET | 1 にすると、MCP サーバーで forget_subject ツールが利用可能になります(デフォルトでは無効です。有効にした場合は2回呼び出します)。 |
ATTESTARI_PG_PORT | 同梱の docker compose Postgres のホストポートです(デフォルトは5432)。 |
ATTESTARI_WRAP_UPSTREAM | ガバナンス対象のメモリーサービスのベースURLです。/v1/wrap/* エンドポイントをマウントします(未設定の場合、wrapルートはありません)。 |
ATTESTARI_WRAP_UPSTREAM_TOKEN | Authorization: Bearer … としてアップストリームに送信されます。 |
ATTESTARI_WRAP_*_PATH | アップストリームのパス(ADD、SEARCH、DELETE、GET_ALL。デフォルトは /add、/search、/delete、/get_all)を上書きします。削除後の読み戻しを無効にするには、GET_ALL を空に設定します。 |
ANTHROPIC_API_KEY | Claudeによる事実抽出を有効にします。サーバー/MCPは正規表現抽出器から自動的にアップグレードされます。 |
ATTESTARI_EXTRACTOR_MODEL | 抽出モデルを上書きします(デフォルトは claude-opus-4-8)。 |
追加機能のインストール(pip install -e ".[extra]"):
| 追加機能 | 追加されるもの |
|---|---|
postgres | psycopg + pgvector — 永続イベントストアです。 |
embeddings | sentence-transformers — 実際のセマンティック埋め込みです。 |
crypto | cryptography — 暗号シュレッディングによる削除です。 |
server | FastAPI + uvicorn + MCP — REST サーバーと MCP サーバーです。 |
anthropic | Anthropic SDK — Claudeによる事実抽出です。 |
dev | pytest + ruff — テストとリンティングです。 |
検証可能な削除と改ざん検知監査を一度にデモ

箇条書きを鵜呑みにしないでください — 特性を破ろうとして、検出される様子を確認してください。
これはデータベースもAPIキーもモデルのダウンロードも不要で実行でき、自己検証します
(すべての主張は assert で終わり、いずれかの特性が偽であればクラッシュします):
python examples/prove_the_moat.py # tamper -> caught · crypto-shred -> unrecoverable · time-travel
このデモは、3つの差別化要素すべてを敵対的に実証します。密かに書き換えられた事実が
verify_audit(deep=True) によって正確なseqで検出され、暗号シュレッディングされた
対象者の暗号文は復元不可能であることが証明される一方で、監査証明は保持され、
修正された事実は履歴を消去せずに過去の時点でクエリできます。(素のクローンでも実行できます。pip install "attestari[crypto]" を実行すると、主張2は論理的消去から暗号学的な暗号シュレッディングにアップグレードされます。)脅威モデルと誠実な適用範囲については、
docs/the-moat.md を参照してください。
実際の暗号化されたPostgres行に対する完全な暗号シュレッディングについては:
ATTESTARI_DATABASE_URL=postgresql://attestari:attestari@localhost:5433/attestari \
python examples/audit_and_forget_demo.py # audit -> trace -> forget -> PROVE
事実の出典を追跡し、対象者を忘却し、生の行が読み取り不能な暗号文であることを確認し、想起で何も返らないことを示します — そして消去後も監査チェーンは有効なままです。
すでに Mem0 や Zep をお使いですか?ラップできます
監査証跡を得るために、メモリレイヤーを置き換える必要はありません。wrap() を使うと、すでにお使いのクライアントの前段に Attestari を配置できます。
from attestari.wrap import wrap
governed = wrap(mem0_client) # or zep, or your own
governed.add("I live in Berlin.", subject_id="u1") # recorded, then stored
governed.search("where do I live", subject_id="u1") # straight through
receipt = governed.forget("u1") # both stores + proof
receipt.complete # True only if BOTH halves succeeded
receipt.certificate # Attestari's signed deletion certificate
receipt.downstream_verified # True = we read the store back and it was empty
receipt.downstream_error # what the wrapped store said, if it refused
governed.verify_audit(deep=True) # the chain still holds
Python をお使いでない場合は? メモリサービスではなく Attestari サーバーをアプリの接続先にするだけで、REST 経由でも同じ保証が得られます。
ATTESTARI_WRAP_UPSTREAM=https://memory.internal uvicorn attestari.server:app
POST /v1/wrap/add {"text": …, "subject_id": …} # recorded, then forwarded
POST /v1/wrap/search {"query": …, "subject_id": …} # passthrough
POST /v1/wrap/forget/{id} # both stores + evidence
一部の消去しか完了していない場合は 200 ではなく 409 が返されます。ステータスコードだけを確認する呼び出し元が、削除の未完了を成功と判断することはありません。このルートは、アップストリームが設定されている場合にのみ表示されます。アップストリームに求められる小規模な JSON 契約については、attestari.wrap_http をご覧ください(標準ライブラリのみで動作し、新たな依存関係は不要です)。
削除呼び出しの申告をそのまま信頼するわけではありません。 forget() は削除後、ラップされたストアから対象を読み戻します。{"deleted": true} を返しながら行を残しているストアは、その場で検出されます。その場合、downstream_verified は False、complete は False となり、相違が監査チェーンに記録されます。アダプターに読み戻し操作がない場合、downstream_verified は True ではなく None になります。「誰も確認していない」と「確認済みで問題がない」は異なる主張であり、証拠になるのはそのうち一方だけです。
書き込みは、下流に渡す前に改ざん検知可能なチェーンに記録されます。読み取りはそのまま通過します(ストアを維持したのは検索のためです)。forget() は下流のデータを削除し、Attestari のコピーを暗号学的に破棄して、失敗も含め、下流のストアが実際に行ったことを記録します。メソッド名と対象のキーワード引数は Adapter で設定できるため、素のベクトルストアにも対応できます。
ラップで証明できること、できないこと。 Attestari は、他社サービス内のデータを暗号学的に破棄できません。そのサービスの鍵を保持していないためです。ラップしたデプロイメントで証明できるのは、削除が要求されたこと、下流の削除が呼び出され、その結果がどうだったか、Attestari 自身のコピーが復元不能であること、そしてそれらが後から改変されていないことです。これは「両システムにまたがる監査可能な削除記録」であり、あらゆる場所での暗号学的消去ではありません。ラップされたストアが消去可能であるかどうかは、その削除エンドポイントがどれだけ誠実に動作するかに左右されます。ラップによって、そのエンドポイントの動作を単なる約束ではなく証拠にできます。完全な暗号学的消去を行うには、データを Attestari 自体に保存する必要があります。
監査担当者と DPO 向け
AI システムのメモリについて責任を持って説明する必要がある人向けのドキュメントを、auditor/ に用意しています。平易な言葉で書かれた概要資料(保証されること、されないこと、自分で確認する方法)、EU AI Act 第 12 条との対応表、および暗号学的消去と、それが依拠するデプロイメントポリシーについてのGDPR 第 17 条に関する解説をご覧ください。
どのデプロイメントでも、検証可能な現在の状態を日付付きのスナップショットとして生成できます。
attestari evidence --deep --out ./evidence # EVIDENCE.md + evidence.json
バンドルには、監査チェーンの検証結果とヘッドハッシュ、現在の台帳と照合し直したすべてのリクエストを含む消去レジスター、および保持されている削除証明書が含まれます。バンドルの生成時には、すべての主張が稼働中の台帳から再導出されます。読み取りアクセスさえあれば、システムの運用者の協力がなくても再生成できるため、これは証拠となります。
attestari verify --deep # re-check the chain, re-hashing content
attestari verify --user u_123 # confirm one subject's erasure; non-zero exit if not
仕組み
信頼できる唯一の情報源は追記専用のイベントログです。クエリ対象となるすべてのもの(ナレッジグラフ、ベクトルインデックス、キーワードインデックス)は、そこから再構築できる投影です。そのため、監査、タイムトラベル、来歴、証明可能な削除は、後付けではなく設計から自然に実現されます。
- Attestari Atlas — エンジン全体を図解した 1 ページのガイドです。すべての書き込み、読み取り、消去、ブラウザー上で改ざんできる監査チェーン、適合する領域、そして注意すべき制約を説明しています。バージョン 0.0.7 向けです。
- ARCHITECTURE.md — 設計の全体像を最初から最後まで説明しています。
- LEARN.md — 初めての方向けに、同じ考え方を基礎から説明しています。
プロジェクトの構成
src/attestari/ the engine — events, store, projection, retrieve, memory,
crypto (shred), audit (hash chain), predicates, resolver
src/attestari/server.py, console.py FastAPI REST API + the graph console
src/attestari/mcp.py the MCP server
src/attestari/cli.py, evidence.py `attestari verify` + the evidence bundle
src/attestari/wrap.py, wrap_http.py govern an existing memory layer (Mem0,
Zep, or any HTTP service) instead of replacing it
auditor/ the auditor pack — DPO one-pager, AI Act + GDPR mappings
examples/ runnable demos — start with spike.py
eval/ quality + retrieval-latency harness
clients/ts/ the TypeScript SDK (@attestari/client)
clients/langchain/ the LangChain integration (attestari-langchain)
src/attestari/db/schema.sql the Postgres bi-temporal schema
docker-compose.yml Postgres + pgvector
ドキュメントとコントリビューション
- ARCHITECTURE.md — 設計
- auditor/ — DPO、コンプライアンス、内部監査向け
- LEARN.md — Attestari の仕組みを基礎から解説
- CONTRIBUTING.md — 開発環境のセットアップ、初めて取り組むのに適したイシュー
- SECURITY.md — 脆弱性の報告
ステータス
エンジンとその差別化要素である、検証可能な削除、改ざん検知可能な監査、二時点の来歴、Postgres ネイティブな検索は、構築・テスト済みです(テスト 122 件、Postgres の p95 は約 1 ms)。
ライセンス
Apache-2.0。コアは引き続き寛容なライセンスで提供され、ホスト型クラウドとエンタープライズ/ガバナンス機能が商用レイヤーとなります。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。