OMEM について
OMEMは、信念や根拠、判断の変化を記録したいエージェント開発者向けのメモリーサーバーです。矛盾する情報を上書きせず、対立と出典の履歴を保持します。
主な機能
- 01時間に応じた信念状態
- 02矛盾の明示的な追跡
- 03根拠と出典の履歴
- 04エージェント間の記憶共有設定
- 05セマンティック検索と学習
- 06ポリシーに基づく修復フロー
活用シーン
- 01信念を持つに至った理由の追跡
- 02矛盾する顧客情報の確認
- 03チーム内で選択した記憶を共有
- 04エージェントの修復操作を承認・監査
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
uvx omem-infrastructureOMEM_API_KEYシークレットAPI key from the OMEM server. It is printed on first run of `omem-server`.OMEM_PROJECTProject id to read and write memory in, also printed on first run.OMEM_BASE_URLURL of the OMEM server.OMEM_AGENTThe agent whose memory this process reads and writes. Fixed here rather than passed as a tool argument, so the model cannot act as a different agent.OMEM_USERThe end user this process is acting for. Also fixed here, not a tool argument. Leave unset and no user-scoped memory is visible.ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。
ツール
5掲載時のツール一覧 · 2 週間前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| task | string | いいえ | エージェントが達成しようとしていること |
| limit | integer | いいえ | |
| context | string | いいえ | 現在の会話/状況 |
詳細
OMEM
AI エージェントが何を信じ、何をしたのかを記録するシステムです。 追記専用で、 すべての信念の根拠を保持し、矛盾する両方の見解を残し、リスクを伴うすべての行動に 担当者を記録します。エージェントが行動した後に誰かから「なぜそうしたのか」と 尋ねられても、調査ではなく記録で答えられます。
OMEM はメモリレイヤーが担う場所で、異なる役割を果たします。テキストを ベクトルストアに放り込んで、うまくいくことを期待するのではなく、各エージェントが 時間の経過とともに何を信じているかを追跡し、すべての信念の根拠を保持し、 矛盾を明示的に処理します。そのためエージェントは、自分が何を知っているか、 いつそれを学んだか、なぜそう考えるのかを推論できます。
しかも、何もないところから始まるわけではありません。人々について一般的に 明らかになったことを、誰も特定できない件数として共有することを選んだ インストール環境があれば、新しい環境はその知見を初日から借りることができ、 それを得るために半年を費やす必要はありません。提供するのは件数で、 受け取るのは他のすべての環境が提供したものです。借りたパターンは、自ら学んだ パターンよりも弱いものとして扱われ、本人に関する根拠が食い違えばすぐに 効力を失います。そのため、一般的な傾向が個人の情報を覆すことはありません。
現在、データバンクは空です。まだデータを提供したインストール環境はなく、 最初の環境が学習内容を決めることになります。また、人々の規則性を集めた コーパスには、それを構築した人々の偏見が反映される可能性があることも 知っておく必要があります。パターンがベースレートに便乗せず、それを上回る 必要があるように、マイニングルールを再構築しました (ワーキングペーパー第 1 号)。 データ提供者の集団が代表性を備えているかどうかは、別の問題であり、未解決です。
外部サービスもインストールが必要な依存関係もなく、ローカルで動作します。
pip install omem-infrastructure && omem-server
または、ワンクリックでプライベートサーバーをデプロイできます。
ブループリントは、永続ディスクを備えた小規模なサービスを 1 つ構成します。
パスワード認証が有効になっており、最初にサインアップしたアカウントが
運用者アカウントとなります。また、マスターキーも自動生成されます。
Fly.io も利用できます。付属の fly.toml を使って fly launch --copy-config を
実行してください。
ドキュメント:infrastructure.omem-cloud.com · クイックスタート · セキュリティ · コントリビューション
クライアント向けにエージェントを提供していますか?監査証跡と承認ゲートが重要です。 クライアントのセキュリティ審査で問われることをご覧ください。 また、少数の設計パートナー向け実地パイロットを募集中です。
先を読む前に、この一連の仕組みが動くところを見たいですか? refund-deskはリファレンス統合です。 返金を処理するサポートエージェントが、領収書を残します。 1 つのファイルで 1 分以内に実行でき、主張するすべての内容を検証します。
これは scripts/demo_reasoning.py の抜粋です。すべての行は CI で実行される
動作の検証であり、この図がいつの間にか事実と異なるものになることはありません。
2つの情報源が食い違っても、どちらも上書きされません。 実際の動作をご覧ください。
他との違い
ほとんどのエージェントメモリは、事実のリストです。2つの事実が矛盾すると、一方がひそかに 上書きされ、履歴が失われます。OMEM は両方を保持し、現在どちらが信じられているかを追跡し、 その理由を説明できます。単純なベクトルストアにはない機能をいくつか紹介します。
- 時間経過に伴う信念の状態。 すべての事実は状態(信じられている、矛盾している、 不明)を持ちます。これは静的な行ではなく、証拠からエンジンが計算します。
- 矛盾への対処。 矛盾する情報を失わずに表面化します。
Xとnot:Xという名前の 主張は自動的に対立するものとして扱われます。それ以外の場合は、mem.contradict("prefers_annual", "prefers_monthly")で一度指定します。OMEM は 2つの主張を読み取って意見の食い違いを判断することはありません。同じ質問に1年後も 同じ答えを返せるようにするには、まさにその判断を避ける必要があるためです。 - 出所情報。 なぜ何かが信じられているのかを尋ねると、そこに至る経緯を確認できます。
- エージェント間のメモリ。 メモリはデフォルトでエージェントごとに非公開です。チームや プロジェクト全体と共有する内容は、自分で選択できます。
- セマンティック検索。 保存時とは異なる表現でも、関連するメモリを見つけます。
依存関係のない埋め込み機能を使ってオフラインでも動作します。プロバイダーの実際の
埋め込みモデルを使うには
OMEM_EMBED_MODELを設定してください。ベクトルはキャッシュされ、 プロバイダーが停止した場合は自動的にフォールバックします。 - 学習ループ。 有用だと確認されたメモリは、時間の経過とともに順位が上がります。
- 実行を拒否する自己修復。 OMEM は失敗を記録し、ポリシーに基づいて修復を実行します。 権限を与えられていない修復は実行しません。モデルは計画を提案できますが、実行されるのは コードに登録されたアクションだけです。また、リスククラスは計画が自ら申告するのではなく、 OMEM のレジストリに基づいて決まります。自己修復をご覧ください。
クイックスタート
Python 3.9 以降が必要です。ほかに依存関係はありません。
オプション 1:PyPI からインストールします(サーバーを同梱)。
pip install omem-infrastructure
omem-server
以前のバージョンからアップグレードする場合は、pip install --upgrade omem-infrastructure を実行します。すでにインストール済みのパッケージに対して pip install を実行すると、「Requirement already satisfied」と表示され、何も行われません。使うのをやめようとしていたバージョンをそのまま実行し続けることになるので、ご注意ください。実際にインストールされているバージョンは、python -c "import omem; print(omem.__version__)" で確認できます。
これでサーバーが http://127.0.0.1:8787 で起動し、初回起動時にプロジェクト ID と API キーが表示されます。サインアップの呼び出しも、ダッシュボードへのアクセスも、設定も必要ありません。表示された情報をそのまま貼り付けてください。
from omem import Memory
mem = Memory(api_key="omem_sk_...", base_url="http://127.0.0.1:8787",
project="proj_...")
mem.remember(agent="support", about="customer:1", claim="prefers_annual_billing")
print(mem.believes(about="customer:1", claim="prefers_annual_billing"))
# -> BELIEVED_TRUE
QUICKSTART.md では、約 5 分で矛盾と来歴チェーンまで扱います。ここでベクトルストアとの違いが実際にわかります。
オプション 2:このリポジトリから実行します。
cd server
python api.py # or: python api.py 9000 for a different port
同じサーバーが同じ初回起動時のプロジェクト ID とキーを表示し、ソースから起動します。どちらの方法でもセットアップにかかる時間は約 1 分です。知っておくべき違いが 2 つあります。
- データベースの保存場所が異なります。 ソースから実行すると
server/data/omem.dbに保存されます。omem-serverは実行したディレクトリに./omem-data/omem.dbを書き込みます。どちらもOMEM_DBで上書きできます。 - ダッシュボードは一度ビルドする必要があります。 wheel にはビルド済みのコピーが含まれますが、clone には含まれないため、
cd web && OMEM_STATIC=1 npm run buildを実行するまで、サーバーに「dashboard not bundled」と表示されます。どちらの場合も API は同じです。
オプション 3:Docker。
docker run -p 127.0.0.1:8787:8787 -p 127.0.0.1:3000:3000 \
-v omem-data:/app/server/data ghcr.io/troybrandonc-bit/omem
API は 8787、ダッシュボードは 3000 で利用でき、データは名前付きボリュームに保存されます。コンテナはローカルモードで実行され、パスワードがないため、ポートは意図的にループバックに公開しています。到達可能性がアクセス制御になります。ネットワーク上に公開する場合は、最初に OMEM_AUTH=password と OMEM_MASTER_KEY を設定してください。このリポジトリの docker-compose.yml に、その構成例があります。
自己修復
OMEM は、何が壊れたかを記録し、ポリシーに従って修復します。これはエージェントのためのインフラストラクチャであり、OMEM 自身が自分を修復するものではありません。コンポーネントと、修復に使えるフックを登録すると、メモリ、安全性の境界、ライフサイクルは OMEM が管理します。
重要なのは、OMEM が何を拒否するかです。モデルは修復計画を 提案 できますが、何が許可されるかを判断するのは OMEM です。実行できるのはコードに登録されたアクションタイプだけで、リスククラスは計画ではなく登録情報から決まり、高リスクのアクションには明示的な承認が必要です。また、検証が完了するまでは修復成功とみなされません。
mem.healing.report_health("vector-index", "healthy", "12,400 vectors")
result = mem.healing.handle(
error={"component": "vector-index", "error_type": "StaleShard"},
plan={"diagnosis": "replica fell behind after a partition",
"confidence": 0.8,
"actions": [{"type": "rebuild_index"}, {"type": "exec_shell"}]},
)
result["status"] # -> "denied"
result["decisions"] # rebuild_index: permitted (low risk)
# exec_shell: unknown action type (not registered)
何も実行されませんでした。各アクションを許可または拒否した理由とともに計画が保存されるため、拒否は沈黙ではなく記録として残ります。ここではエラーテキストもモデル出力もデータとして扱われ、どちらも存在しないアクションを作り出すことはできません。
そのほかに必要な保護策もすべて適用されます。同一のエラーが千件発生しても 1 件にまとめられるよう、失敗にはフィンガープリントが付与されます。修復が集中する事態はコンポーネントごとに制限され、データベースの claim によってコンポーネントごとに同時に実行できる復旧は 1 件に制限されます。保存前にシークレットは削除され、内部エラーが発生した場合は無作為な再試行をせず、上位にエスカレーションします。
ダッシュボードの 自己修復 画面には、コンポーネントの健全性、失敗の記録、各修復の進捗が表示されます。停止したステップと、実行の根拠となった診断も示されます。サブシステム全体を確認するには server/healing.py をお読みください。信頼性を判断するうえで参考になります。
ダッシュボード
ダッシュボードはパッケージに同梱されています。サーバーを起動し、同じアドレス http://127.0.0.1:8787 を開いてください。メモリ、競合、信念グラフ、タイムライン、ログ、監査証跡がすべて表示されます。Node も、別プロセスも、別ポートも必要ありません。
デフォルトのローカルモードではログインは不要で、サーバーが作成したプロジェクトが開きます。OMEM_AUTH=password を指定してサーバーを実行している場合は、代わりにサインインフォームが表示されます。
これは、このリポジトリ唯一の UI である web/ を静的エクスポートし、ビルド時に wheel にコピーしたものです。開発する場合は、次を実行してください。
cd web
npm install
npm run dev # http://localhost:3000, proxying to the API on 8787
同梱版を再ビルドするには、OMEM_STATIC=1 npm run build を実行します。
認証
OMEM は 2 つのモードのいずれかで動作します。自分のマシン以外で使う場合は、その違いが重要です。
OMEM_AUTH=local:デフォルトで、クイックスタートを 1 分で済ませられるモードです。
ログインはありません。ダッシュボードは、認識できるサーバーに対してセッションを作成します。これは、ほかからサーバーにアクセスできない場合に限り安全です。そのため、ローカルモードではループバック以外のアドレスへのバインドを拒否します。その意図がある場合(ポートを 127.0.0.1 に公開するコンテナーやシングルユーザー VM など)は、
OMEM_ALLOW_INSECURE_BIND=1 を設定してください。
OMEM_AUTH=password:ほかの人がアクセスできるサーバーでは必須です。
アカウントにはパスワードがあり、PBKDF2-SHA256 でハッシュ化されます。すでにパスワードが設定されているアドレスでサインアップすると、セッションではなく 409 が返されます。TOTP に登録している場合は TOTP が必須となり、OMEM_MASTER_KEY が開発用のデフォルト値以外に設定されていないと、サーバーは起動を拒否します。
export OMEM_AUTH=password
export OMEM_MASTER_KEY="$(python3 -c 'import secrets;print(secrets.token_urlsafe(32))')"
omem-server
TLS
OMEM_TLS_CERT と OMEM_TLS_KEY に証明書を指定すると、サーバー自体が HTTPS(TLS 1.2 以上)で通信します。片方だけ設定すると、平文通信にひそかにフォールバックするのではなく、起動エラーになります。大規模運用では終端プロキシを使うほうが適していますが、プロキシなしでも、暗号化されていない通信で運用する必要はなくなりました。
メモリの保存時暗号化
pip install "omem-infrastructure[encryption]"
export OMEM_ENCRYPT_AT_REST=1
export OMEM_MASTER_KEY="$(python3 -c 'import secrets;print(secrets.token_urlsafe(32))')"
オペレーションログ、取り込んだソースのペイロード、各メモリの根拠となる引用を AES-GCM で暗号化します。既存の平文の行も引き続き使用できるため、すでにデータがあるデータベースでも有効にできます。開発用マスターキーでは起動を拒否します。また、OAuth トークンに使用される標準ライブラリのキーストリームへフォールバックせず、実際の AEAD ライブラリがない場合は実行を拒否します。
キーを失うとデータも失われます。復旧手段はなく、キーのローテーションツールもまだありません。
2 つのエンティティが同一人物である場合
形成処理は、認識できる情報からエンティティ ID を生成するため、1 人の人物が重複して登録されることがあります。たとえば、メッセージ本文の文から person:sarah_chen が、メールの署名から person:sarah_chen@acme が生成されます。それぞれの ID には同一人物に関する信念が半分ずつ保持され、互いを裏付けることも、矛盾を示すこともできません。
curl -X POST "$OMEM/v1/memory/resolve?project=$PROJECT" \
-H "Authorization: Bearer $KEY" -d '{}'
決定的な証拠がある場合は統合されます。同じ組織に同じフルネームの人物がいる場合が該当し、これは形成処理自体がすでに 1 つのパス内で適用しているルールです。統合は agent:omem-resolution による記録済みの共参照として保存され、根拠への導出情報も記録されます。そのため、/why で説明を確認でき、分割によって取り消すこともできます。示唆的な証拠(acme における「Sarah」と「Sarah Chen」など)は、
GET /v1/memory/merge-proposals の提案になります。人物が承認するまでは何も変更されず、承認は機械ではなく承認者の名前で記録されます。
拒否する条件がこの機能の要です。組織をまたぐ統合、組織がない場合、姓や役職の語彙に矛盾がある場合、曖昧な場合、分割済みのものを再統合する場合は、決して統合されません。何も記録しないドライランでは {"apply": false} を渡してください。SDK からは mem.resolve()、mem.merge_proposals()、mem.approve_merge(id, agent=...) を使います。ダッシュボードの 提案 画面も、ボタン付きの同じキューです。
結論を導き、取り消すルール
矛盾は宣言するものであり、テキストから推論するものではありません。推論も同じように機能します。ルールは宣言するデータであり、マシンはあなたが述べたことだけを、そのまま組み合わせます。
curl -X POST "$OMEM/v1/rules?project=$PROJECT" -H "Authorization: Bearer $KEY" \
-d '{"when": [{"rel": "works_at", "dir": "fwd"}, {"rel": "owns", "dir": "rev"}],
"then": {"rel": "involves", "dir": "rev"}}'
curl -X POST "$OMEM/v1/memory/infer?project=$PROJECT" \
-H "Authorization: Bearer $KEY" -d '{}'
Sarah が Beta で働き、Acme が Beta を所有している場合、OMEM は Acme の関係領域に Sarah が含まれると結論づけます。これは、使用した正確な前提から導かれた通常のアサーションなので、/why を使えば結論から証拠までたどれます。また、実際のグラフエッジでもあるため、想起は 1 ホップで到達します。
これを望む理由は、取り消しの際にわかります。所有関係を取り消すと、同じリクエスト内で結論も撤回されます。その結論に基づく結論があれば、それも続いて取り消されます。すべての撤回は、操作ログ上の通常の取り消しです。証拠は一度だけ使われます。いったん閉じた結論が、同じ前提から再び審議されることはありません。無効化されたルールの結論は、次のパスで撤回されます。
そのすべてを段落ではなくスクリプトにします。以下の拒否のデモと同じ契約です。すべての振る舞いをアサーションで検証し、どれかが成り立たなくなればゼロ以外の終了コードを返し、CI で実行します。
python3 scripts/demo_reasoning.py
問いを投げかける形
信念が衝突するのは、対象が同じ場合だけです。これにより信念の状態を再現可能に保てます。つまり、「Sarah は Acme で働いている」と「Sarah は Beta で働いている」は決して矛盾しません。それで問題ないかどうかはドメイン知識なので、あなたが宣言します。
mem.declare_constraint("works_at", "one_dst_per_src") # one employer at a time
mem.check()
違反があると、提案キューに緊張として表示されます。OMEM が新しい勤務先を選ぶことはありません。残すものをあなたが指定します(残りはあなたの名義で撤回され、ルールエンジンがそれらから導いたものも同じリクエスト内で取り消されます)。または、その証拠に限って恒久的に却下することもできます。すでに人が回答した問いで、マシンが何度も催促することはありません。
ケースファイル付きの勘
人間は、ひとつの例から結論へ飛躍して学びます。その反射が、人間の記憶に作話を生じさせる原因でもあります。OMEM はその速さを保ちながら、作話を取り除きます。飛躍はしますが、その飛躍をあなた以上に厳しく疑います。
mem.leap() # one similar case is enough
mem.expects(about="customer:gamma")
# -> wants_pdf_invoices, strength 0.35, "beta holds it; gamma resembles
# beta (both prefer annual billing, both use crm)", docket attached
mem.interrogate() # the skeptic works every open case
仮説が信念になることは決してありません。エンジンに入ることはなく、勘がどれほど優れていても believes() は UNKNOWN のままです。また、仮説を支持または反証できるのは対象に関する現実の情報だけであり、類似例は確信度を動かすだけです。判定は学習に活かされます。飛躍が繰り返し裏付けられる情報源は、より強い勘を生み、繰り返し誤る情報源は、より弱い勘を生みます。そして、一度反証された飛躍が、同じ証拠から再び行われることはありません。解決しないケースは問いを投げかけ始め、その問いがダッシュボードに表示されます。そこでは、はい/いいえの回答が、あなたの名義による実際の証拠になります。判定はあくまで問いかけによって得られるものであり、命令によるものではありません。
類似性の働き方は、人間の類推と同じです。共有する珍しい特性がひとつあれば、よくある特性が 3 つある場合より強く結び付きます。エンベディングモデルが設定されている場合は、言い回しの異なる経験も同じ経験として数えられます。また、共有する文脈より共有する性質のほうが重視されます。そして mem.calibration() はメタ認知です。OMEM は、どの種類の主張をうまく推測できるかを把握しており、その確信の強さは実績に応じて変わります。
事前知識:人々全般について学習した内容
飛躍は、似た人を一人見て推測します。事前知識は、多くの人に見られる規則性から推測します。「Pを持つ人はQも持つ傾向がある」というものです。OMEMはすでに知っていることからこうした規則性を掘り起こし、ごくわずかな情報から新しい人を解釈するために使います。
ある組み合わせが採用されるのは、Pを持つことで、Qが単独でどれほど一般的かを超えて、Qを持つ確率が測定可能なほど高まる場合に限られます。また、この検定は率そのものではなく率の下限に適用されます。そのため、ほんの一握りの人に基づくパターンは、数百人に基づくものより、はるかに明確でなければなりません。
mem.learn_priors() # mine regularities across everyone
mem.priors()
# -> holds likes_dashboards -> holds wants_pdf_invoices
# in_population: 41 of 52 wants_pdf_invoices on its own: 0.29
# kept because the lower bound of that rate clears 0.29, not
# because wants_pdf_invoices happens to be common
# when_applied: supported 3, refuted 0
このルールは、Pを持つ人の60%がQも持つかどうかだけを尋ねるルールに置き換わりました。潜在構造が既知の実際の回答者19,668人を対象に測定すると、以前のルールによる構造の再現率は、偶然の0.184に対して0.185でした。つまり、Qを持つ人がどれほど一般的かによって帰結を選んでいたのです。現在のルールでは、以前より94%少ない事前知識を使いながら、より多くの主張をカバーして、再現率は0.875に達します。この研究は
Working Paper No. 1にあり、ハーネスは
benchmarks/external/にあります。
重要なのは、事前知識が人に優先することは決してないということです。事前知識が働くのは、何も語られていない部分だけです。ある人がPを持っていて、Qについて何も述べていなければ、OMEMは推測としてQをその人に当てはめます。その人自身の証拠が示された時点で、事前知識は退けられます。また、その人の証拠が後になって採用済みの推測と矛盾すれば、質問ループがそれを覆し、事前知識は誤りとして扱われます。それぞれの事前知識には、正直な数値が二つ付随します。学習元の集団でそのパターンが成り立っていた率と、実際に適用されたときの別個の記録です。対象者が少なすぎるパターンは、そもそも適用されません。
事前知識が保存するのは人ではなく、件数です。そこには誰か一人についての事実は含まれず、人々全般についての知識だけが含まれています。そのため、全体を読んだり、誰かに渡したりしても、個人情報が漏れることはありません。一般的なパターンが個人に常に譲るのは、方針によるのではなく、仕組みそのものによるものです。
日々の習慣も記憶の一部です
覚えておく価値のあるものは、契約だけではありません。「朝のほうが仕事がはかどります」「連絡はメールが一番です」「金曜日は働きません」といった、日常的なやり取りで繰り返される小さな好みを、OMEMはLLMを必要とせずオフラインで抽出します。一人称の文は、それを書いた人に結び付けられます。その人の雇用先は、送信元のアドレスから推定され、同じノードに結び付きます。一方、「私たちは非同期を好みます」は会社についての事実として残ります。support@のような役割用アドレスから架空の人物が作られることはなく、すべての習慣には、根拠となった文が付随します。これらは、事前知識の層が一般化する規則性そのものです。「朝を好む人は、たいていメールも好む」は学習されたパターンであり、推測ではありません。
忘れられる権利を実行する
撤回は消去ではありません。追記専用ログは履歴を保持しますが、実際の消去要求では個人データを削除します。POST /v1/entities/{id}/forgetは、実際に操作ログを書き換えます。その人を参照するすべての記録、それらから連鎖的に生じたすべてのもの、その人の言葉だけを含むイベント、そして根拠となる引用、エッジ、仮説、元のソースメッセージもすべて対象です。存続する信念の下に引用されている本人の文は、信念が会社のものであっても、文そのものは本人のものなので、墨消しされます。剪定後のログは、何かに手を加える前にスクラッチエンジンで再生検証されます。その後に残るのは、ハッシュ、件数、日付を保持する1行だけです。消去が行われた証拠を残しつつ、何も保持しません。これは管理者の操作であり、明示的な確認を求め、取り消すことはできません。
コモンズと、決して持ち出さないもの
初めて開くと、ダッシュボードに一つの質問が表示されます。匿名のパターンを共有のOMEMコモンズに提供しますか?「はい」と答えた場合に端末の外へ送られるのは、「7件中5件で保持」のような集計値です。名前、会社名、メッセージ、データ内の数値は一切送信されません。正確なファイルは確認できるよう、お使いの端末内に保存されます。どちらの回答も設定でいつでも変更できます。何も選ばなければ、今後も送信されません。
コモンズは、同意したインストール環境から集計値を集め、人間の一般的な働き方を調査します。匿名性は両方の入り口で構造的に担保されています。個人を特定できる情報を含む投稿は到着時に拒否されるため、プールが一度も保持していない情報が漏れることはありません。
人々のあり方をAIに教える
コモンズの目的は一つです。AIが人間の性質や行動をより深く理解できるようにし、人間とAIをつなぐことです。現在のモデルは、提供されたことがなく、そこに登場する全員の名前が含まれているスクレイピングテキストから、人々について学習しています。コモンズはそれとは正反対の提案です。人々が実際に働く方法に見られる規則性を、意図的に提供し、誰の情報も保持しません。
コモンズは学習用コーパスとして提供されます。各パターンは、集計値と平易な英語での説明(「朝の会議を好む人は、メールでの連絡も好む傾向があります。態度が確認できた31人中24人、77%」)を含むJSONの1行として記録されます。また、出所、同意の経緯、ライセンス(OMEMコモンズへの帰属表示を条件とするCC BY 4.0)を記したデータセットカードも付属します。これを使って学習したモデルが学ぶのは割合であり、個人ではありません。データセットカードには、運用上の重要な一文が明記されています。割合は集団の傾向であって、個人についての規則ではありません。実在する人は誰でも、これらの傾向に反することがあり、実際に反することもあります。人々を尊重するシステムは、OMEM自身と同じように、すべてのパターンを、個人に応じて覆される事前情報として扱います。
不在の間に変わったこと
すべてのエージェントがセッション開始時に尋ねる質問に、すべてのクエリがすでに使用している同じas_ofの仕組みで答えます。
d = mem.changes(since=last_seen)
新たに現れた信念、終了した信念とその理由(置き換えられた場合は何に置き換えられたか、または撤回されたか)、新たに発生した競合と解決した競合、統合または分割された参照先を示します。読み取り専用で、決定的で、スコープが安全です。差分に含まれるのは、思い出せる可能性があったことだけです。
拒否する動作を確認する
自己修復の境界は、説明文だけでは信じがたい部分です。そのため、段落ではなくスクリプトで示します。
python3 scripts/demo_refusal.py
このスクリプトは、修復計画で実際に問題が起こる2つのケースを通じて、実サーバーを動作させます。モデルが、登録済みのreload_configと、どこにも登録されていないexec_shellを提案します。前者は内容に基づいて許可され、後者は名前によって拒否され、計画全体も拒否されます。計画が自らのリスククラスを申告しても、無視されます。リスククラスはレジストリから決まるためです。モデルが読んだエラーメッセージに埋め込まれた指示が実行されることはありません。すべての判定は保存され、後から読み取れます。また、エラーコンテキスト内の秘密情報がストレージに保存されることもありません。
登録はコード内で行います。実行可能なアクションタイプを追加するAPIはないため、どんな計画やプロンプトを使っても、許可される内容が広がることはありません。
スクリプト内のすべての拒否はアサーションで確認され、一つでも拒否されなくなるとゼロ以外の終了コードを返すため、CIで実行できます。いつの間にか正しくなくなる可能性のあるデモは、ないよりも悪いものです。
The Witness ベンチマーク
メモリのベンチマークは想起を測定します。Witness はその反対の責務を測定します。メモリシステムは、誰も伝えていないことを断言するか、撤回されたことを繰り返し続けるか、意見の相違を密かに解決するか、同じ名前の二人を混同するか、あるいは前提が崩れた結論を保持し続けるかを測定します。
6 つのシナリオ、10 の軸、決定論的な採点で、LLM による判定はありません。OMEM、Mem0、Graphiti 用のアダプターが含まれています。各システムには、それぞれのネイティブな経路を通して入力し、システムが表現できないプローブは合格または不合格ではなく、未対応として報告します。このリポジトリは、実行していない数値を公開しません。すべての軸ですべてのプローブに合格するという OMEM の評価結果は、コミットのたびに実サーバーに対して server/tests_witness_benchmark.py で検証されます。他のシステムは、ご自身のキーを使って実行し、ご自身の評価結果をご確認ください。
クレーム台帳
失敗する可能性のないマーケティングは、虚偽のマーケティングと区別がつきません。CLAIMS.md では、このプロジェクトについて述べる重要な各文を、それが真実でなくなった場合に失敗する実行可能な記述に対応づけています。また、この台帳自体も CI で保護されています。参照先のファイルが見つからない行があると、ビルドが失敗します。
この分野では他の誰にも書けないため、特に触れておきたい行が 2 つあります。外部に一切通信しません:tests_airgap.py はソケット層にガードを設定し、実サーバーを通して主要な機能をすべて実行します。ループバック以外への接続または DNS ルックアップが 1 回でも発生すると失敗します。アップグレードによって過去が書き換えられることはありません:2026-08-29 に固定されたログを再生し、すべてのコミットでバイト単位で同一の状態ダイジェストが得られるため、将来のバージョンが記録済みの履歴をひそかに再解釈することはありません。
状態がログから導かれることを証明する
メモリは追記専用ログを再生して再構築されます。これは主張するのは簡単ですが、外部から確認できませんでした。これは、エージェントが何を信じていたのか、そしてその理由を再構築できることをプロジェクトの根拠とするうえで、脆弱な点です。
omem-verify
proj_a14ce3f94fab My first project
replayed 4 operations -> 2 assertions, 2 propositions
state digest cd95d761079a2388...
deterministic yes
ログを 2 つの独立した新しいエンジンに再生し、得られた状態を比較します。差異があれば、再生がログ以外の何かに依存していること、そして同じ問いに同じ答えが返らないことを意味します。
書き換えられたログも、それ自体とは完全に整合した状態で再生されるため、このチェックでは改ざんを検出できません。そのためには、ダイジェストを記録し、OMEM が書き込めない場所に保管します。
omem-verify --record # writes .omem-state.json
omem-verify --anchor kept-elsewhere.json
anchor DOES NOT MATCH cd95d761079a2388... the log has changed
audit chain org_f4f3bdfa7a82 MISMATCH
同じファイルは、同じ理由から 監査チェーンの先頭 も固定します。このチェーンは改ざんの証拠を示すものであり、改ざんを防止するものではありません。書き込みアクセス権を持つ人は、編集箇所以降を書き換えても、内部整合性を保つことができます。それを検出できるのは、OMEM がアクセスできない場所に保管した先頭ハッシュだけです。2 か所に固定するには、2 つの習慣が必要です。そして、怠ったほうが重要だった習慣です。
状態がログから導かれること、そしてログも監査チェーンも固定時点以降に変更されていないことを証明します。信念が正しいことや、最初の固定より前に何も削除されていないことを証明するものではありません。
部品表
python3 scripts/gen_sbom.py > sbom.json # CycloneDX
python3 scripts/gen_sbom.py --check # fails if a runtime dep appears
サーバーと SDK には 実行時依存関係がありません。そのため、SBOM は 1 つのコンポーネントで構成され、推移的な依存関係は標準ライブラリです。任意の追加機能も一覧にしてオプションと明記しています。そうしなければ、「依存関係なし」という主張は半分だけ真実になってしまうためです。--check は CI で実行されるため、この主張がひそかに真実でなくなることはありません。
根拠のない書き込みを拒否する
すべての信念には根拠の判定が付与されます。出所が記録されたイベントにたどり着く場合は GROUNDED、ほかの主張だけに基づいている場合は UNGROUNDED です。この判定は読み取りのたびに返されるため、呼び出し側でフィルタリングできます。
フィルタリングが役立つのは、呼び出し側が忘れずにフィルタリングした場合だけです。OMEM_REQUIRE_GROUNDED=1 を設定すると、代わりにOMEMが書き込みを拒否します。
OMEM_REQUIRE_GROUNDED=1 omem-server
mem.remember(agent="support", about="customer:1", claim="prefers_annual")
# -> 422 R_UNGROUNDED: cite `because` evidence that reaches a recorded event
mem.remember(agent="support", about="customer:1", claim="prefers_annual",
because=["evt_call_2026_08_26"]) # accepted
証拠として認められるのは、記録されたイベント、またはそれ自体に根拠がある主張です。そのため、観測された事実に行き着く推論の連鎖は受け入れられますが、何にも行き着かない連鎖は受け入れられません。
これは直接書き込みに適用されます。置き換えと撤回は、すでに受け入れられた主張を置き換え、その出所を引き継ぎます。また、取り込み経路には常に独自のゲートがあります。すべての候補はエンジンに渡される前に評価され、DO_NOT_STORE と LOW はアサーションになりません。
デフォルトでは無効です。書き込み方に実質的な制約が加わるため、既存の呼び出し元がアップグレードで動作しなくならないようにしています。
このリポジトリの内容
-
server/はOMEMサーバーです。メモリエンジンをラップするHTTP APIです。エンジン自体はserver/omem_engine/にあり、すべてのメモリに関する判断の信頼できる情報源です。 -
sdk/python/はPython SDKとomem-server/omem-mcpコマンドです。公開されているのはこちらです:pip install omem-infrastructure。 -
sdk/typescript/はTypeScript SDKで、npm install @omem/sdkとして公開されています。Python SDKより遅れており、実際のサーバーを使ってビルドとテストを行います。cd sdk/typescript npm install && npm test # builds, then runs test_parity.mjs against a live servertest_parity.mjsはPythonサーバーを起動し、ビルド済みSDKをそれに接続して、不足しているものを報告します。現在、最も有益な貢献はこの差を埋めることです。 -
web/はダッシュボードです。
LangChainから使う
OMEMはLangGraphの BaseStore を実装しています。これはLangChainのエージェントが長期記憶を保持するためのものです。
pip install "omem-infrastructure[langgraph]"
from omem import Memory
from omem.integrations.langgraph_store import OmemStore
store = OmemStore(Memory(api_key="omem_sk_...", project="proj_..."))
store.put(("memories", "alice"), "pref", {"text": "prefers annual billing"})
store.get(("memories", "alice"), "pref").value
# -> {"text": "prefers annual billing"}
InMemoryStore と同じように、create_react_agent(..., store=store) または任意のLangGraphグラフに渡してください。

組み込みストアとの違いは、2回目の書き込み時の動作です。組み込みストアでは上書きされ、delete で消去されます。ここでは、既存のキーに対する put は置き換えになります。以前の値は、信じられなくなった時点とともに記録に残り、delete は破棄ではなく撤回になります。すべての書き込みには出所が記録されるため、mem.why(assertion_id) でメモリの出所を確認できます。その代わり、操作ごとにネットワーク往復が必要です。
ストアでのベクトル検索はまだ実装されていません。search() は名前空間とフィールドでフィルタリングします。query= を渡すと、意味検索を装った部分文字列検索を黙って返すのではなく、例外が発生します。
MCP クライアントから使用する
パッケージをインストールすると、stdio 経由で MCP を使用する omem-mcp コマンドが利用できるようになります。そのため、Claude Desktop などの MCP クライアントで、OMEM をメモリツールとして使用できます。
pip install omem-infrastructure
次に、MCP クライアントの設定に、次のエントリー全体を追加します。
{ "mcpServers": { "omem": { "command": "omem-mcp" } } }
キーも URL も、別途起動するサーバーも必要ありません。初回の実行時に、同梱のサーバーが自動的に起動し、プロジェクトを作成して ~/.omem に保存します。クライアントを再起動すると、同じメモリが再利用されます。
ツールは 10 個あります。5 個は記録用です。omem_recall、omem_observe、omem_remember、omem_why、omem_believes です。残りの 5 個は直感レイヤーで、すべて読み取り専用です。omem_expects(OMEM が疑っていることと信じていないことを、ケースファイルとともに表示します)、omem_priors(一般の人々に関して学習した規則性を表示します)、omem_brief(ほかの 4 つの情報から同じ全体像を組み立てる代わりに、タスクの開始時に 1 回呼び出します)、omem_ask(1 つの質問に対し、まずこのインストール自体が見てきた内容から、次にコモンズから回答します。それぞれ、その根拠となる人々とインストールを明示します)、omem_weigh(すでに持っている信念を母集団と照らし合わせて評価します)です。
回答を支持する人が少なすぎる場合、omem_ask は何も返さずに済ませるのではなく、回答を拒否します。「そのようなパターンはない」と「判断するには人が少なすぎる」は異なる回答であり、エージェントはそれぞれに異なる行動を取るためです。読み取り元はディスクです。コモンズのスナップショットはすでにここにあるため、コモンズにアクセスできない場合や、これまで一度も接続したことがない場合でも質問できます。
仮説を昇格させたり、その未解決の問いに答えたり、飛躍を引き起こしたりするツールはありません。直感は、検証の際に現実から判定を受けます。また、モデルがそう宣言するだけで真実と判定するための手段を、モデルに与えることはありません。omem_expects に表示される内容は、omem_believes では引き続き UNKNOWN として読み取られます。テストでも、まさにそれを確認しています。
observe は、会話の生データを OMEM に渡し、何が長期的に重要かを判断させます。これは会話の記録を扱う際に適しています。remember は、すでに特定した事実を記録します。
{"about": "customer:acme", "claim": "prefers_dark_mode",
"because": "said on the 3 Nov call"}
事実がわかっている場合は、remember を使用してください。抽出では、決定とコミットメントを対象とした決定論的な語彙を使います。その範囲外の主張はまったく記録されません。また、モデルが主張に名前を付けることと、モデルが何を真実とするか決めることは別です。信念の状態、矛盾、来歴は引き続き OMEM が管理します。
メモリの適用範囲を定める 2 つの軸の識別情報は、ツールの引数ではなく環境変数によって固定されます。OMEM_AGENT は、このメモリの所有者であるエージェントを示し、OMEM_USER は、そのエージェントが支援するエンドユーザーを示します。MCP 経由でやり取りするモデルは、どちらも指定できないため、別のエージェントや別のユーザーのプライベートメモリを要求できません。OMEM_USER は省略可能です。設定しなければ、ユーザー単位のメモリは一切表示されません。誰のために動作するかを知らされていないプロセスでは、これが適切なデフォルトです。
Claude Desktop に接続するには、まず omem-server を一度起動してプロジェクト ID とキーを取得し、claude_desktop_config.json に次の内容を追加して、アプリを再起動します。
{
"mcpServers": {
"omem": {
"command": "omem-mcp",
"env": { "OMEM_AGENT": "claude", "OMEM_USER": "[email protected]" }
}
}
}
どちらも省略可能です。OMEM_AGENT はこのメモリの所有者であるエージェントを示し、OMEM_USER はそのエージェントが支援するエンドユーザーを示します。どちらもツールの引数ではないため、モデルは指定できません。OMEM_API_KEY、OMEM_BASE_URL、OMEM_PROJECT を設定すると、すでに稼働しているサーバーを指定できます。明示的な設定は、常に同梱の設定より優先されます。
設定ファイルの場所は、macOS では ~/Library/Application Support/Claude/claude_desktop_config.json、Windows では %APPDATA%\Claude\claude_desktop_config.json です。
ステータスと料金
無料です。ベータ期間中は無料でご利用いただけます。プラン、カード登録、利用上限はありません。
現在も活発に開発中の初期段階のソフトウェアです。現時点では、テストとフィードバックを目的としています。 **セキュリティページ**では、保護されるものと、同じくらい重要な、まだ保護されないものを説明しています。SSO、認証、キーのローテーションはありません。監査チェーンは改ざんを防ぐのではなく検知します。また、現在は権威ある状態を保持するプロセスは1つで、2つ目のプロセスは状態が分岐するのではなく、起動を拒否します。これは高可用性を実現しているのではなく、実現していないことを率直に示しています。利用を計画する前にお読みください。試してみて、何かが壊れたり、違和感を覚えたりした場合は、そのフィードバックがまさに今の段階で役立ちます。
ライセンス
MIT。LICENSEをご覧ください。
開発履歴とエンジンの詳細な説明は、CHANGELOG-dev-notes.md、ENGINE.md、ENGINE_VALIDATION.mdをご覧ください。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。