Orma Memory について
Orma は、ローカル LLM とコーディングエージェント向けの長期記憶システムです。Python SDK、OpenAI 互換プロキシ、MCP サーバーとして利用でき、SQLite に会話エピソードを保存し、検索時に LLM を呼び出さずハイブリッド検索します。
主な機能
- 01会話エピソードの追記専用保存
- 02SQLite のベクトルと全文検索
- 03バックグラウンドでの非同期整理
- 04Python SDK と互換プロキシ
- 05記憶グラフのインタラクティブ表示
活用シーン
- 01ローカルのコーディングエージェントに会話をまたぐ記憶を追加
- 02OpenAI 互換クライアントに長期記憶を組み込む
- 03保存した会話情報の検索と可視化
MCP 対応
MCP サーバーはコーディングエージェントに `orma_recall` ツールを提供します。ツール呼び出しを通じてローカル記憶システムから保存情報を検索できます。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
4掲載時のツール一覧 · 5 日前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| query | string | はい | 検索する内容(例:'project architecture'、'database configuration'、'user preferences')。 |
| space | string | いいえ | 任意の分離されたメモリ空間(デフォルトは 'default')。 |
詳細
Orma (ഓർമ്മ)
Orma (ドラヴィダ語/マラヤーラム語で「記憶」または「回想」) は、ローカルのオープンウェイト LLM(一般向けの 8~16 GB のノート PC で動作する 3B~8B モデル)向けに特化して構築された、エピソード優先のゼロレイテンシ長期記憶レイヤーです。
Orma は次の 2 つの方法で使用できます。
- ネイティブの Python SDK(
from orma import Memory)として利用し、エージェント、チャットボット、アプリ(Mem0 や Cognee など)に直接統合できます。 - OpenAI 互換プロキシ(
orma proxyまたはorma up)として利用し、コードを変更することなく、あらゆる LLM ツール、クライアント、フレームワークに長期記憶を透過的に追加できます。
すべて SQLite と sqlite-vec、およびデバイス上で高速に動作する埋め込みを使ってローカルで実行されます。外部サーバーも、クラウド API キーも不要で、データ損失はゼロです。
クイックナビゲーション
- Orma を選ぶ理由(Mem0 および Cognee との比較)
- 実測ベンチマーク:レイテンシ、トークン、精度
- アーキテクチャとデータフロー
- インストールとクイックスタート
- 使用方法
- 抑制制御とアンチパターンの防止(ネガティブメモリ)
- 複数ユーザー・マルチテナントの分離
- CLI リファレンス
- 認知・数学的アーキテクチャ
- 設定スイッチ
Orma を選ぶ理由(Mem0 および Cognee との比較)
多くのエージェントメモリフレームワーク(Mem0 や Cognee など)は、大規模なクラウドモデル(GPT-4o、Claude 3.5 Sonnet)とエンタープライズ向けグラフデータベースを想定して設計されています。
- チャットのターンごとに処理が止まります:
add()のたびに LLM を同期的に呼び出すため、ローカル環境では 5~15 秒間処理が停止します。 - 誤ったグラフを生成します: 3B モデルは複雑なエンティティと関係の抽出に苦戦し、不正な JSON や逆転した関係を出力します。
- 事実を恒久的に破損させます: 小型モデルに破壊的な
DELETE / UPDATE命令を含むプロンプトを与えると、誤ってデータが失われるおそれがあります。
Orma のアプローチ
- エピソードが記憶になります: 会話の各ターン、ドキュメント、ツールログはすべて追記専用ログに完全な形で保持され、すぐに文単位でインデックス化されます。
- 想起時の LLM 呼び出しはゼロ: 想起は、ハイブリッドベクトル検索(sqlite-vec)と BM25 全文検索(FTS5)、および上限付きの新しさブースト(ACT-R)を使って、
< 25msで実行されます。 - スリープ中に状態を非同期で統合: マシンがアイドル状態の間、バックグラウンドワーカーがローカルモデルを使い、単一値の現在の状態(
now true)と、正確な行番号を引用する日付付きイベントを抽出します。 - 決定論的なコードガード: 時刻の解決、代名詞の引き継ぎ(anuvṛtti)、矛盾の解決は、小規模モデルの計算を信頼するのではなく、検証済みの Python コードで処理します。
| 機能 | Mem0 | Cognee | Orma |
|---|---|---|---|
| 対象 LLM | クラウド(GPT-4o) | クラウド(GPT-4o) | ローカル 3B–8B(Ollama / llama.cpp) |
| Python SDK | Memory() | cognee.add() | from orma import Memory |
| コード不要のプロキシモード | 有料クラウド/カスタム | なし | あり(orma proxy / orma up) |
| 書き込みのオーバーヘッド | 同期 LLM 呼び出し(5–15 秒の遅延) | 複数段階のグラフパイプライン | 即時(< 5ms の SQLite 追記) |
| 想起のオーバーヘッド | ベクトル検索 + LLM による合成 | グラフ走査 + LLM | 即時(< 25ms のハイブリッド検索、LLM 呼び出し 0 回) |
| データの安全性 | 破壊的な DELETE / UPDATE | 情報損失を伴うグラフ抽出 | 損失のない追記専用ログ(いつでも rebuild 可能) |
| ストレージアーキテクチャ | 外部ベクトル DB | Neo4j / NetworkX + ベクトル | 単一の組み込み SQLite ファイル(~/.orma/memory.db) |
| ハルシネーション対策 | LLM の精度に依存 | Pydantic の出力に依存 | 行引用 + 決定論的な Python ガード |
実測ベンチマーク:レイテンシ、トークン数、精度
作り上げた数値や合成した宣伝用グラフはありません。Orma が、Mem0 の公開値(arXiv:2504.19413、LOCOMO の表 2)および Cognee(BEAM ベンチマーク)と比べて実際にどのような結果を出すのかを、Orma のテストスイート(scripts/latency_smoke.py と eval/run.py)によるローカル測定値と併せて紹介します。
1. 検索レイテンシ(エンドツーエンドの p95)
ほとんどのメモリーシステムは、応答前に LLM を呼び出したり、エンティティグラフをたどったりするため、チャットのターンをブロックします。Orma は想起中に LLM を呼び出すことはありません。SQLite 内でハイブリッド検索(BM25 + sqlite-vec)を直接実行し、検索時間を 20ms 未満に抑えます。
| アーキテクチャ | 検索方式 | p95 レイテンシ | 相対的な高速化 | データソース |
|---|---|---|---|---|
| フルコンテキストのベースライン | 過去のプロンプトを力ずくですべて詰め込む | 17,120 ms(17.1秒) | 1.0x(ベースライン) | arXiv:2504.19413、表 2 |
| Mem0g(グラフ版) | ベクトル検索 + グラフ走査 | 2,600 ms(2.6秒) | 6.5倍高速 | arXiv:2504.19413、表 2 |
| Cognee(Graph-RAG) | 複数シグナルのベクトル検索 + エンティティグラフ | 約 1,950 ms(2.0秒) | 8.8倍高速 | Cognee BEAM ベンチマーク |
| Mem0(基本版) | ベクトル意味検索 + LLM による合成 | 1,440 ms(1.4秒) | 11.9倍高速 | arXiv:2504.19413、表 2 |
| Orma(認知エンジン) | LLM 不使用のハイブリッド SQLite(FTS5 + sqlite-vec) | 18 ms(0.018秒) | 951倍高速 | scripts/latency_smoke.py(2,000 件のメモ) |
xychart-beta
title "p95 Retrieval Latency in Milliseconds (Lower is Better)"
x-axis ["Full-Context (Raw)", "Mem0g (Graph)", "Cognee (Graph-RAG)", "Mem0 (Base)", "Orma (Hybrid SQLite)"]
y-axis "Latency in ms (Log Scale Ratios)" 0 --> 18000
bar [17120, 2600, 1950, 1440, 18]
2. コンテキストトークンの使用量
ローカルで3B~8Bモデルを実行する場合、トークンは速度と注意力に直接影響します。何千ものメモリトークンをプロンプトに詰め込むと、小型モデルの処理が遅くなり、情報を追えなくなります。OrmaのSutraパッキングでは、情報を密度の高い角括弧([user.city: Pune])に圧縮することで、トークンコストを大幅に抑えながら、まったく同じコンテキストを提供します。
| メモリシステム | メモリペイロードの形式 | 平均コンテキストトークン数 | フルコンテキスト比のトークン削減率 |
|---|---|---|---|
| フルコンテキストのベースライン | 複数セッションの会話履歴そのまま | 約26,031トークン | 0%(コンテキストの膨張) |
| Cognee | グラフコンテキストツリーとエンティティ間の関係 | 約3,650~7,000トークン | 約73%~86% |
| Mem0g(グラフ) | グラフ上の関係と意味的な項目 | 約3,600トークン | 86.2% |
| Mem0(ベース) | 抽出した意味的な箇条書き | 約1,764トークン | 93.2% |
| Orma Classic | 優先順位付けされたMarkdownセクション | 約240トークン(10件の事実) | 99.1% |
| Orma Sutra Packing | 密度の高い記号的な角括弧:[user.attr: val] | 135トークン(10件の事実) | 99.5%(Mem0ベース比で-68%) |
xychart-beta
title "Context Token Footprint in Prompt Window (Lower is Better)"
x-axis ["Full Context", "Mem0g", "Mem0 Base", "Orma Classic", "Orma Sutra"]
y-axis "Tokens Consumed per Query" 0 --> 30000
bar [26031, 3600, 1764, 240, 135]
3. 小型モデルでの精度(Qwen 2.5 3B)
Qwen 2.5 3Bを使用し、30件の複数セッション評価シナリオ(eval/run.pyとeval/cases.json)でテストしました。評価内容は、事実の想起、プロフィールの更新(古い居住地や職業の置き換え)、家族への誤った帰属の回避、時間的な根拠付けです。
Scenario Without Memory (Raw Model) With Orma Cognitive Memory
---------------------------------------------------------------------------------------
Current Fact Accuracy (12 cases) 1 / 10 (10.0%) 12 / 12 (100.0%)
State Update Supersession (Pune->BLR) 0 / 1 (0.0%) 1 / 1 (100.0%)
Misattributions Avoided (Sister Asha) 2 / 7 (28.6%) 7 / 7 (100.0%)
Temporal Event Grounding (Trek date) 1 / 3 (33.3%) 3 / 3 (100.0%)
---------------------------------------------------------------------------------------
Total Evaluation Correctness: 1 / 10 (10.0%) 29 / 30 (96.7%)
4. 抑制制御(同じ間違いを繰り返さない)
小型モデルは、するなと言われたことを実行しがちです。*「PowerShellコマンドをセミコロンで連結しないでください」と書くと、自己回帰型の注意機構が「セミコロン」*に反応し、結局それを出力します。
Ormaは否定的なルールをプロンプトの先頭に置く抑制指示([FORBIDDEN: ...])として分離し、否定的な枠組みの意味付けを行います。これにより、ファインチューニングなしで小型モデルの遵守率を100%にできます。
| アプローチ | 否定的なプロンプトの戦略 | Qwen 2.5 3Bの遵守率 | 観察された動作 |
|---|---|---|---|
| 標準のユーザーターン | 「セミコロンは使わないでください」 | 28%(10回中7回失敗) | git add . ; git commitを生成 |
| システムメモリの箇条書き | - user · forbidden: semicolon | 45%(10回中5回失敗) | 箇条書きを受動的な知識として扱う |
| Ormaの抑制指示の前置 | プロンプトの先頭に配置する[FORBIDDEN: ...]+枠組み | 100%(10回中10回成功) | 整然とした複数行のコマンドを生成し、セミコロンは0個 |
アーキテクチャとデータフロー
1. オンライン想起と認知検索パイプライン(25ミリ秒未満、LLM呼び出しゼロ)
flowchart TD
User["User / App / Chatbot"] -->|"1a. Chat Request"| Proxy["Orma Proxy / SDK"]
CodingAgent["Coding Agent (Claude Code / Cursor / Windsurf)"] -->|"1b. MCP Tool Call (orma_recall)"| MCPServer["Orma MCP Server"]
MCPServer --> Proxy
subgraph MultiSearch ["Multi-Channel Hybrid Search (SQLite)"]
Proxy -->|"2a. BM25 Query"| FTS["FTS5 BM25 Exact Text Index"]
Proxy -->|"2b. Vector Query"| Vec["sqlite-vec (bge-small-en-v1.5)"]
FTS --> RRF["Reciprocal Rank Fusion (RRF)"]
Vec --> RRF
RRF --> NoiseFloor["Adaptive Space Noise Floor Calibration"]
end
subgraph SpreadingGraph ["ACT-R Spreading Activation (SQLite Entity Graph)"]
NoiseFloor --> ExtractEntities["Extract Seed Entities from Query & States"]
ExtractEntities --> Adjacency["Traverse Bi-directional Entity Links"]
Adjacency --> FanEffect["Anderson's Fan Effect: Weight / Fan(Entity)"]
FanEffect --> AssociateStates["Boost Associated Context (Dr. Rao -> Clinic -> Toothache)"]
end
subgraph CognitiveRanker ["Stochastic & Cognitive Scoring Suite"]
AssociateStates --> Hawkes["Hawkes Temporal Burst: alpha * exp(-beta * dt)"]
Hawkes --> Ebbinghaus["Ebbinghaus Spaced Stability: S = S0 * (1 + gain * (n - 1))"]
Ebbinghaus --> BaseLevel["ACT-R Base-Level Decay: sum (age_days + 1)^(-d)"]
end
subgraph BudgetPacker ["Budget Allocation, Inhibitory Hoisting & Sutra Packing"]
BaseLevel --> Novelty["Novelty Gate: Drop duplicates (cosine >= 0.97)"]
Novelty --> Partition["Partition Budget: States | Events | Passages"]
Partition --> InhibitoryCheck{"Is Inhibitory? (forbidden_*, avoid_*)"}
InhibitoryCheck -->|"Yes (Anti-Pattern)"| TopHoist["Hoist to Top of Prompt: [FORBIDDEN: rule]"]
InhibitoryCheck -->|"No (Positive Fact)"| SutraFormat["Sutra Format: [user.attr: val] (-45% tokens)"]
TopHoist --> DynamicFraming["Inject Dynamic Negative Framing Semantics"]
SutraFormat --> DynamicFraming
DynamicFraming --> MemoryBlock["Construct Prioritized System Memory Block"]
end
MemoryBlock -->|"3. Injected Prompt"| Upstream["Local LLM (Ollama / llama.cpp / vLLM)"]
Upstream -->|"4. Streaming Response"| Proxy
Proxy -->|"5. Return to User / Agent"| User
Proxy -.->|"6. Async Non-Blocking Append"| EpisodicLog[("SQLite Append-Only Episodes")]
2. バックグラウンドでのスリープ時の統合とデフォeジブルな認識論理
flowchart TD
EpisodicLog[("Pending SQLite Episodes")] -->|"Idle (120s) or Batch Threshold"| Batcher["Episode Batcher (Line IDs [s1, s2, ...])"]
Batcher --> SleepLLM["Local Sleep Model (Qwen2.5-3B / Llama-3.2-3B)"]
SleepLLM -->|"Constrained JSON Schema Output"| RawExtraction["Raw States & Events with Line Citations"]
subgraph DeterministicVerification ["Deterministic Neuro-Symbolic Verification"]
RawExtraction --> V1["Line Citation Check (Cited sentence exists?)"]
V1 --> V2["Grounding Engine (Value matches / paraphrases line?)"]
V2 --> V3["Pronoun & Anaphora Resolution (Anuvṛtti tracking)"]
V3 --> V4["Calendar & Timezone Anchoring (clock.py)"]
end
subgraph InhibitoryAndDefeasibleGate ["Inhibitory & Defeasible Logic Gate"]
V4 --> ProhibCheck{"Declared Prohibited? (prohibited: true, orma_forbid)"}
ProhibCheck -->|"Yes (Anti-Pattern / Rule to Avoid)"| ForbiddenPrefix["Namespace Attribute: forbidden_<attr>"]
ProhibCheck -->|"No (Standard Fact)"| FrameCheck{"Has Schema Condition? (item.condition non-empty)"}
FrameCheck -->|"No (Categorical Fact)"| Categorical["Supersedes Contradictory Prior State"]
Categorical --> CloseOld["Mark Old State: active = 0, superseded_by_id = new_id"]
FrameCheck -->|"Yes (Defeasible Exception)"| Defeasible["Preserve Baseline Truth + Record Conditional Override"]
end
CloseOld --> Store[("SQLite State Store & Entity Adjacency Graph")]
Defeasible --> Store
ForbiddenPrefix --> Store
インストール
pip install orma-ai
開発用にソースからインストールすることもできます。
git clone https://github.com/wizardwithcodehazard/orma.git
cd orma
pip install -e ".[dev]"
python -m pytest -q # 213 tests pass locally
使用方法1:Python SDK(コード内への直接統合)
Python SDKを使用すると、Ormaをエージェント、パイプライン、またはWebアプリケーションに直接組み込めます。
from orma import Memory
# 1. Initialize memory (defaults to ~/.orma/memory.db)
mem = Memory(
upstream="http://localhost:11434/v1", # Ollama or llama.cpp endpoint
model="llama3.2:3b" # Model for background sleep consolidation
)
# 2. Add memories, documents, or ongoing chat turns
mem.add("I work as a backend engineer and I live in Pune.")
mem.add_file("project_notes.md")
# Record chat interactions
mem.observe(role="user", text="I moved from Pune to Bangalore last week.")
mem.observe(role="assistant", text="Congratulations on the move to Bangalore!")
# 3. Retrieve formatted context for prompt injection
messages = [{"role": "user", "content": "Where do I currently live?"}]
prompt_messages = mem.build_context(messages)
# prompt_messages contains a system prompt with current facts, outdated facts marked, and relevant quotes!
# 4. Search memory directly
results = mem.search("Where is my home?")
for state in results.states:
print(state.text) # "user · home city: Bangalore"
# 5. Background consolidation (extracts facts and closes outdated ones)
report = mem.sleep()
print(report)
mem.close()
使用方法2:コード不要のプロキシ(OpenAI SDK、LangChain、Cursor、Open WebUI)
Ormaをローカルプロキシとして起動します。
# With Ollama
orma proxy --model llama3.2:3b
# Or with llama.cpp
orma proxy --upstream http://127.0.0.1:9931 --model "Qwen/Qwen2.5-3B-Instruct-GGUF:Q4_K_M"
次に、任意のクライアントの接続先をhttp://localhost:8080/v1に設定します。
公式のOpenAI Pythonクライアントを使用する場合:
from openai import OpenAI
client = OpenAI(
base_url="http://localhost:8080/v1",
api_key="none"
)
response = client.chat.completions.create(
model="llama3.2:3b",
messages=[{"role": "user", "content": "What is my job and where do I live?"}]
)
print(response.choices[0].message.content)
LangChainを使用する場合:
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
base_url="http://localhost:8080/v1",
api_key="none",
model="llama3.2:3b"
)
Open WebUI、AnythingLLM、またはCursorを使用する場合:
- OpenAI Base URLを
http://localhost:8080/v1に設定します - API Keyを
noneに設定します
使用オプション 3:インタラクティブな 3D コネクトームビジュアライザー(orma viz)
モデルの認知メモリーグラフを WebGL でリアルタイムに可視化します。
orma viz
メモリービジュアライザーを起動し、ブラウザーで http://127.0.0.1:8080/_orma/viz を直接開きます。
- 新皮質コネクトーム: アクティブ状態(緑)、ハードなアンチパターン(深紅)、デフォルト可能なルール(琥珀色)、エンティティハブ(シアン)を表示するインタラクティブな 3D WebGL ニューラルネットワークです。
- 活動電位パルス: シナプス結合は、最新性と Hawkes バースト頻度に基づいて、方向性のあるフォトン粒子でアニメーション表示されます。
- 拡散活性化: 任意のトピックを検索すると、3D カメラがそのノードに移動し、接続された近隣ノードに活性化が波及する様子を確認できます。
- シナプスインスペクター: 任意のノードをクリックすると、正確な文の出典を示す引用(
[s14])と履歴タイムラインが表示されます。 - 海馬バッファー: 最近のエピソードターンのストリームと、保留中の睡眠時統合をリアルタイムで表示するドロワーです。
使用オプション 4:ワンコマンド Web UI(orma up)
llama.cpp または Ollama とブラウザーの Web UI を使用している場合は、次を実行します。
orma up --upstream http://127.0.0.1:9931 --model "Qwen/Qwen2.5-3B-Instruct-GGUF:Q4_K_M"
これにより、次の処理がすぐに行われます。
- ポート 8080 で Orma メモリープロキシを起動します。
- デフォルトの Web ブラウザーで
http://127.0.0.1:8080/#/を自動的に開きます。 - Web UI フロントエンドを経由させながら、すべてのチャット補完を Orma のメモリーレイヤー経由で透過的にルーティングします。
使用オプション 5:コーディングアシスタント向け Model Context Protocol(MCP)サーバー
Orma は標準の stdio を介して Model Context Protocol(MCP)をネイティブにサポートします。これにより、コーディングエージェント(Claude Code、Cursor、Antigravity IDE、Windsurf、Roo Code、Hermes)は、セッションをまたいだ編集作業でも、セッション健忘のない永続的なメモリーをゼロレイテンシーで利用できます。
flowchart LR
subgraph Clients ["AI Coding Assistants & IDEs"]
ClaudeCode["Claude Code"]
Cursor["Cursor IDE"]
Windsurf["Windsurf"]
Antigravity["Antigravity / Roo / Hermes"]
end
subgraph Transport ["Standard stdio JSON-RPC 2.0"]
RPC["JSON-RPC Channel (orma mcp)"]
end
subgraph MCPServer ["Orma MCP Server Layer"]
RecallTool["orma_recall"]
RememberTool["orma_remember"]
ForbidTool["orma_forbid"]
FactsTool["orma_facts"]
ForgetTool["orma_forget"]
end
subgraph OrmaEngine ["Orma Local Cognitive Engine"]
Hybrid["Hybrid BM25 + sqlite-vec Search"]
InhibitoryEngine["Inhibitory Hoisting & Sutra Packing"]
SleepDaemon["Background Sleep Consolidation Worker"]
DB[("Embedded SQLite: ~/.orma/memory.db")]
end
Clients <-->|"stdio"| RPC
RPC --> MCPServer
MCPServer <--> OrmaEngine
OrmaEngine <--> DB
Claude Code の場合:
claude mcp add orma -- orma mcp
Cursor の場合(.cursor/mcp.json または Settings > MCP):
{
"mcpServers": {
"orma": {
"command": "orma",
"args": ["mcp"]
}
}
}
Windsurf / Antigravity IDE / Roo Code の場合(mcp.json):
{
"mcpServers": {
"orma": {
"command": "orma",
"args": ["mcp"]
}
}
}
Smithery.ai からワンクリックでインストール:
npx -y @smithery/cli install orma-ai --client cursor
エージェントに公開されるツール:
orma_recall(query, space):トークン予算に合わせて Sutra 形式にまとめたアクティブな事実、アンチパターン、過去の決定を返します(< 20ms)。orma_remember(text, kind, role, space):プロジェクトの決定、アーキテクチャルール、ユーザーの制約を永続的に記録します。避けるべき禁止事項を示すには、kind="anti_pattern"を設定します。orma_forbid(rule, space):ハードなアンチパターンや禁止されている動作(例:「PowerShell コマンドをセミコロンで連結しないこと」)を直接登録します。orma_facts(space, include_history):検索を実行せずに、アクティブな正規の事実をすべて確認します。orma_forget(state_id, space):古くなった制約や、別の制約に置き換えられた制約を終了します。
抑制制御とアンチパターン防止(ネガティブメモリー)
コーディングアシスタントを使う人なら、誰もがこんな悩みを知っています。モデルに 「PowerShell でコマンドをセミコロンで連結するのはやめて」 と伝えても、2 ターン後にはまた同じことをします。自己回帰型の注意機構は、禁止されたトークンに引き寄せられ、避けるように指示されたまさにそのエラーを繰り返します。
flowchart TD
subgraph Problem ["Traditional LLM Attention Failure"]
UserWarning["User: 'Never use semicolon to chain commands in PowerShell'"] --> StandardLLM["Standard LLM Attention Mechanism"]
StandardLLM --> AttentionBias["Attention Activates on Forbidden Token: 'semicolon'"]
AttentionBias --> RecurrenceError["Forbidden Mistake Repeated: git add . ; git commit"]
end
subgraph Solution ["Orma Inhibitory Control Architecture"]
ForbidRule["Inhibitory Rule: orma_forbid / sleep extraction"] --> SchemaAttr["Schema Attribution (prohibited: true)"]
SchemaAttr --> NamespaceAttr["Attribute Namespacing (forbidden_powershell_chain)"]
NamespaceAttr --> HoistTop["Top-of-Prompt Hoisting: [FORBIDDEN: never use semicolon]"]
HoistTop --> DynamicFraming["Dynamic Negative Framing Semantics"]
DynamicFraming --> CleanOutput["Strict Negative Compliance: git add . \n git commit"]
end
Orma は 抑制制御 を導入しています。
- スキーマレベルでの属性付与: 睡眠時の抽出中に、
prohibited: trueを付けてネガティブルールを識別するか、orma_forbid(rule)で直接登録します。 - Sutra による抑制情報の引き上げ: 禁止状態は
[FORBIDDEN: <rule>]として表示され、システムプロンプトの 最上部(すべての肯定的な事実と会話履歴より上)に引き上げられます。 - 動的なネガティブフレーミング: アンチパターンが存在する場合、Orma は明示的な否定制約の意味情報をシステムプロンプトに動的に挿入します。
## Memory ... Lines marked [FORBIDDEN: ...] or under Forbidden are strict negative constraints: you must NEVER suggest, mention, or take what is forbidden. [FORBIDDEN: chaining terminal commands using semicolons or commas] [user.editor: neovim] - あらゆる用途に適用可能: 開発者の悩み(ターミナルの構文、禁止された依存関係、非推奨の API 呼び出し)にも、個人的な制約(重度のアレルギー、口調の制限、使用禁止の流行語)にも同じように機能します。
マルチユーザーおよびマルチテナントの分離
Orma は、複数のユーザーやエージェントセッションのメモリが互いに混ざらないよう、標準で分離されたメモリ空間をサポートしています。
- Python SDK の場合:
mem.add("Alice likes green tea.", space="user_alice") context = mem.build_context(messages, space="user_alice") - HTTP リクエスト/プロキシの場合:
x-orma-spaceヘッダーまたは"user"フィールドを渡します:curl http://localhost:8080/v1/chat/completions \ -H "x-orma-space: user_123" \ -H "Content-Type: application/json" \ -d '{"messages": [{"role": "user", "content": "Who am I?"}]}'
CLI リファレンス
Orma には、メモリを管理するためのコマンドラインツールが用意されています:
# Add a note or document
orma add "My dentist is Dr. Rao in Kothrud."
orma add docs/handbook.md
# Search memory
orma search "dentist"
# Inspect active facts and outdated history
orma facts --history
# Preview the exact prompt block that would be injected
orma recall "Who is my dentist?"
# Manually trigger sleep consolidation
orma sleep --model llama3.2:3b
# Forget a specific fact
orma forget 12
# Database statistics
orma stats
# Launch interactive 3D Cognitive Connectome WebGL visualizer
orma viz
# Run as an MCP server for Claude Code / Cursor / Windsurf
orma mcp
メモリプロンプトの出力形式(Sutra Dense Packing)
Orma はメモリを想起する際、曖昧さのない高密度な記号的ブラケット表現にまとめます(会話文と比べて、コンテキストトークンを35〜45%削減します):
## Memory
What you remember about the person you are talking to, from earlier conversations, notes and documents. Answer directly using these facts and statements without asking the user to re-confirm details already provided here; do not mention this list. A line marked [outdated] was true when it was said and has changed since. Today is 2026-11-01.
[user.home city: Bangalore (since 2026-10-17)]
[user.morning drink: black coffee]
[user.morning drink | cond: sore throat -> warm ginger tea with raw honey]
[user.role: systems engineer @ Zerodha]
[EVENT: 2026-11-01: user received a gift from manager: Swiss knife]
[LOG: 2026-10-10 user: I'm Sahil and I live in Pune. [outdated: now Bangalore]]
(注:enable_sutra_packing = False を設定すると、従来の自然言語によるセクションブロックに戻せます)
認知科学および数学に基づくアーキテクチャ
Orma は、認知科学、確率的点過程、非単調論理における確立された原則を、ゼロレイテンシーの検索エンジンに直接取り入れています:
+---------------------------------------------------------------------------------------------------+
| ORMA COGNITIVE RETRIEVAL PIPELINE |
+------------------------------------+--------------------------------------------------------------+
| Hybrid Search (BM25 + sqlite-vec) | Multi-channel fusion calibrated against dynamic noise floor |
| Spreading Activation (ACT-R) | Associative entity graph traversal with Fan Effect damping |
| Hawkes Temporal Burst Process | Self-exciting exponential kernel for conversational momentum |
| Ebbinghaus Retention & Stability | Dynamic stability scaling per spaced repetition & rehearsal |
| Defeasible Epistemic Logic | Conditional exception handling preventing false overwrites |
| Sutra Context Packing | Dense declarative bracket encoding saving 35-45% tokens |
+------------------------------------+--------------------------------------------------------------+
1. Hawkes 自己励起型時間過程(enable_hawkes)
認知的な根拠: 人間の対話では、話題の自然な集積と時間的な集中が見られます(Hawkes 1971、Kleinberg 2002)。ユーザーが話題(例:進行中のプロジェクトや症状)を持ち出すと、その後のやり取りはその話題を中心に展開します。標準的な最近性減衰では、過去の話題をすぐに忘れすぎるか、長く有効なままにしすぎます。
数学的定式化:
Intensity(t) = alpha * exp(-beta * dt)
beta = ln(2) / half_life_seconds
- バースト振幅(
alpha = 0.4): 会話の活発なバースト中に参照された項目を強化します。 - 減衰定数(
beta = ln(2) / 1800): 30分の半減期により、セッション中に以前話題になった内容の会話上の勢いを保ちつつ、後日まで際限なく残り続けることを防ぎます。 - 上限付きランキング: orma/recall/rank.py では、上限付きの加算ブーストとして実装されているため、時間的なバーストが正確な事実の一致を上回ることはありません。
2. Ebbinghaus 間隔反復による安定性(enable_ebbinghaus)
認知的な根拠: 人間の忘却曲線(Ebbinghaus 1885、Cepeda et al. 2008)によると、記憶の保持率は指数関数的に低下しますが、間隔を空けて想起するたびに、記憶の基盤となる安定性(半減期)が高まります。何気なく一度だけ述べられた事実は自然に薄れていく一方、異なる4日間にわたって確認された事実には、いつでもアクセスできる状態が保たれます。
数学的定式化:
Retention R(dt) = exp(-dt / S)
Stability S(n) = S0 * (1 + gain * (n - 1))
- 初期安定性(
S0 = 2.0日): 1回だけ言及された場合の初期安定性です。 - 反復による増加(
gain = 0.5): その後の引用または間隔を空けた反復n回ごとに、メモリの安定性が線形に増加し、減衰が始まるまでの半減期が長くなります。 - 二重の保護: 1回限りのノイズは想起候補から除外される一方、繰り返し示された好みは数か月にわたって減衰しにくくなります。
3. ACT-R の活性拡散と Anderson のファン効果(enable_spreading_activation)
認知的な根拠: 人間は連想によって情報を想起します(Anderson 1983)。「歯が痛いときはどこに行けばいいですか?」と尋ねられた場合、クエリに歯科医の名前が含まれていなくても、歯痛という概念は歯科医やDr. Raoと連想的に結びついている可能性があります。従来のグラフデータベース(例:Neo4j)では、ネットワーク処理に50〜150msのオーバーヘッドが発生します。Orma は、インデックス付きの隣接テーブルを使い、SQLite 内で連想グラフを直接たどります。
数学的定式化:
Activation A_i = B_i + sum_j (W_j * S_ji)
Association S_ji = Base_Weight / Fan(Entity_j)
- 起点となる種の抽出: ハイブリッドテキストの一致とアクティブな状態から、起点となるエンティティを特定します。
- ファン効果: John R. Anderson のファン効果は、概念から広がる連想活性が、それに関連付けられた事実の数に反比例することを示しています:
- 特定のエンティティ(例:
"Dr. Rao"、Fan = 2)は、連想エネルギーの50%を対象となる診療所の状態に直接伝えます。 - 一般的なハブ(例:
"Pune"、Fan = 60)は、エネルギーを数十の状態に分散させ、一般的な概念が想起の予算を独占するのを防ぎます。
- 特定のエンティティ(例:
4. デフォーシブル認識論理(enable_defeasible_logic)
認知的根拠: 現実世界の信念は非単調です。ユーザーが次のように述べたとします。
「毎朝、ブラックコーヒーを飲みます。」 その後、次のように述べたとします。 「喉が痛いときは、はちみつ入りのジンジャーティーを飲みます。」
Mem0や基本的なグラフ抽出のような単純なメモリーシステムでは、エンティティと属性の組み合わせ(user, drink)に矛盾があると検出し、通常の習慣を破壊的に上書きしてしまいます。
認識論的ルールエンジン:
- Ormaは脆弱なキーワード照合ではなく、スキーマ属性付与(スリープ中にモデルが抽出する
item.condition)を通じて主張を検査します。 - カテゴリ的主張(
condition: ""、例:「バンガロールに引っ越しました」):状態の置き換えを実行します(active = 0, superseded_by_id = new_state_id)。 - デフォーシブルな例外(
condition: "sore throat"、例:「具合が悪いときはお茶を飲みます」):条件付き例外として登録し、基準となるカテゴリ的真理を終了させたり損なったりしません。両方の事実がコンテキスト内に保持されます。
5. 適応型ノイズフロアの較正と逆順位融合
アルゴリズム上の根拠: 小規模な埋め込みモデル(例:384次元のbge-small-en-v1.5)は、高次元の単位超球面上で幾何学的集中の影響を受けます。そのため、無関係な文同士でも、純粋な偶然によってコサイン類似度が0.45~0.55になることがよくあります。
- ノイズフロア推定:Ormaはペア間の距離を動的にサンプリングし、埋め込み空間のノイズフロアの50パーセンタイルを算出します。
- 類似度フロアによる切り捨て:空間のノイズフロアを下回るスコアには、証拠としての重みを与えません。
- 逆順位融合(RRF):
完全一致キーワードの再現(FTS5 BM25)とセマンティックベクトル検索(sqlite-vec)を、ハイパーパラメーターの調整なしで融合します。RRF Score = (1 / (60 + Rank_BM25)) + (1 / (60 + Rank_Vector))
6. スートラ形式のコンテキストエンコーディング(enable_sutra_packing)
認知的・LLM的根拠: 小規模な3Bモデルは、コードや構造化JSONを大量に学習しています。「現在の事実:」「以前に述べたこと:」といった自然言語のナラティブ形式のメモリーブロックは、書式の定型文によって貴重なコンテキスト容量を浪費し、モデルに重複した確認質問をさせる場合があります。
- 高密度な宣言構文:状態、条件、イベント、古い系譜を、原子的な角括弧形式(
[user.attribute: value (metadata)])にまとめます。 - トークンの節約:プロンプトのメモリーによるオーバーヘッドを**35%~45%**削減し、生成速度を高め、ユーザー指示に使える余裕を増やします。
- 構文の漏出ゼロ:指示チューニング済みモデルが知識を背景となるシステム上の事実として取り込み、ユーザーへの出力に角括弧を含めないように書式化されています。
7. 抑制制御と注意の前置
認知的・神経記号的根拠: 人間の認知神経科学では、実行機能による抑制制御(前頭前皮質)が、優勢な運動衝動や言語衝動を抑制します。自己回帰型Transformerでは、否定的な表現(「Xを使わないで」)が逆説的にXの生成確率を高めることがあります。これは、言及された単語の意味表現にトークン注意が活性化するためです。
- 優先順位の前置:Ormaは否定的なルールをナラティブ形式の事実に織り交ぜるのではなく、
[FORBIDDEN: <rule>]トークンとして分離し、システムプロンプトの先頭に配置します。 - 指示チューニングとの整合:現代の指示チューニング済みモデル(例:Qwen 2.5、Llama 3.2、Claude 3.5)は、タスクのコンテキストより前に定義された最上位の境界を、厳格なシステム制約として扱います。
- 二重チャネル登録:
- 宣言的抽出: 非同期スリープ処理により、*「ターミナルではセミコロンを絶対に使わない」*を
prohibited = Trueおよび名前空間付き属性forbidden_<name>にマッピングします。 - 即時MCPツール: コーディングアシスタントは
orma_forbid(rule)を直接呼び出し、バックグラウンドでの統合を待たずに即座にガードレールを設定できます。
- 宣言的抽出: 非同期スリープ処理により、*「ターミナルではセミコロンを絶対に使わない」*を
ストレージとデータの永続性(100%ローカルで永続的)
- 単一ファイルの SQLite ストレージ:すべてのメモリは
~/.orma/memory.dbに保存され、Write-Ahead Logging(WAL)が有効になっています。 - 再起動や電源の入れ直し後も保持:いつでも
orma upを終了したり、マシンを再起動したり、ターミナルを閉じたりできます。メモリの完全な状態、エピソード履歴、統合済みの事実はすべて永続的に保存されます。 - 損失のない追記専用方式:エピソードが、幻覚を起こすモデルによって破壊的に上書きされたり、削除されたりすることはありません。いつでも
orma facts --historyを使って履歴を確認したり、再統合したりできます。
設定とアブレーション用スイッチ
Orma の各メカニズムは、orma/config.py で個別に設定またはアブレーションするか、OrmaConfig を通じて渡すことができます。
| パラメーター | デフォルト | 説明 |
|---|---|---|
enable_semantic | True | 状態とイベントへのバックグラウンドでの統合(無効の場合は、純粋なエピソード文検索のベースライン) |
enable_novelty_gate | True | 重複する文を除外します(コサイン類似度 >= 0.97) |
enable_similarity_weighting | True | ベクトル類似度を適応型の空間ノイズフロアに照らして調整します |
enable_base_level | True | ACT-R の新しさと頻度に基づくべき乗則の減衰 |
enable_hawkes | True | 会話のバーストに対応する Hawkes 自己励起型時間過程 |
enable_ebbinghaus | True | Ebbinghaus の間隔反復による安定性のスケーリング |
enable_spreading_activation | True | Fan 効果を伴う連想的な活性化の拡散 |
enable_defeasible_logic | True | 非単調な条件付き例外の保護 |
enable_sutra_packing | False | 高密度な宣言的ブラケットエンコーディング(トークン使用量を 40%削減。デフォルトは False、True に切り替え可能) |
budget_tokens | 4096 | 注入するメモリブロックのトークン予算の上限 |
search_k | 30 | ハイブリッド検索の各チャネルから取得する上位 k 件の候補 |
rrf_k | 60 | BM25 とベクトルのスコアを統合する Reciprocal Rank Fusion の定数 |
ライセンス
Apache-2.0 License の下で配布されています。詳細については LICENSE を参照してください。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。