haki について
Hakiは、AIエージェント向けの永続メモリ層です。やり取りを日付と出典付きの事実に変換し、更新済み情報を追跡して、各コンテキストに含めた記憶の理由を示します。
主な機能
- 01永続的な事実台帳
- 02有効日と更新状態の管理
- 03矛盾の検出
- 04出典付きコンテキスト追跡
- 05PythonとTypeScriptのSDK
- 06CLIとCursor MCPツール
活用シーン
- 01エージェントのセッション間で好みを保持
- 02古い事実の使用を回避
- 03コンテキスト選択の理由を追跡
MCP 対応
Hakiは、記憶の参照、記録、確認、削除を行うCursor MCPサーバーを提供します。Cursorのエージェントが呼び出した場合に使われ、すべての会話を傍受するものではありません。
設定
リモートサーバーはインストール不要です。クライアントを選んで設定をコピーするか、ワンクリックで導入できます。
https://api.gethaki.space/mcp/claude mcp add --transport http gethaki-haki https://api.gethaki.space/mcp/{"mcpServers":{"gethaki-haki":{"type":"http","url":"https://api.gethaki.space/mcp/"}}}Cursor で開く{"servers":{"gethaki-haki":{"type":"http","url":"https://api.gethaki.space/mcp/"}}}VS Code で開く{"mcpServers":{"gethaki-haki":{"type":"http","url":"https://api.gethaki.space/mcp/"}}}{"mcpServers":{"gethaki-haki":{"serverUrl":"https://api.gethaki.space/mcp/"}}}コマンドはターミナルで実行し、JSON は各クライアントの MCP 設定に貼り付けて再起動します。認可が必要なサーバーは初回接続時にログインを求めます。
ツール
詳細
Haki
AI エージェントのための信頼できるメモリ
根拠のあるコンテキスト:すべての事実に日付、ソース、ステータスが付いています。
Haki は、あらゆる AI エージェントに数か月持続するメモリを提供します。 現在の情報と古い情報を区別し、思い出した事実すべての根拠を示せます。
クイックスタート · コードで実装するエージェント · Cursor · n8n · ゲートウェイ · API · gethaki.space
Haki の機能
現在、AI エージェントは1回の会話を超えて何も記憶できません。新しいセッションは毎回最初から始まり、コンテキストを説明し直す必要があり、数か月前に古くなった好みを、それが古いと判断する方法もないまま適用することがあります。
Haki は、使用するモデルやフレームワークに依存しない、オープンソース(Apache-2.0)の永続メモリレイヤーです。エージェントとのやり取りから構造化された事実を抽出し、時間の経過とともに最新の状態に保ち、新しいリクエストごとに、関連性があり、日付とソースが明記されたコンテキストパケットを提供します。すべてをユーザーの管理下に置けます。docker compose up を1回実行するだけでインストールでき、既存のエージェント、モデル、インフラストラクチャは変更されません。
課題
本番環境で AI エージェントを構築するチームは、いつも同じ限界に直面します。
| 症状 | 結果 |
|---|---|
| ユーザーがすでに伝えた情報を繰り返す必要がある | 体験の悪化、利用者の離脱 |
| エージェントが、ずっと前に上書きされた好みを適用する | 誤った回答、信頼の損失 |
| 呼び出しのたびに履歴全体がプロンプトに再送される | 高コストと高レイテンシ、有用なコンテキストの希薄化 |
| ある情報が使われた理由を説明する方法がない | トレーサビリティがない、デバッグできない |
| ある顧客のデータが別の顧客のコンテキストに漏れる可能性がある | セキュリティインシデント |
既存のアプローチ(汎用ベクトルストア、会話の要約)はデモでは機能しますが、実際に数週間使うと劣化します。古い情報が最新の情報として提供され、矛盾が検出されず、説明可能性もありません。
アプローチ
会話履歴ではなく、事実の台帳です。 Haki は、あとで再生するために生のメッセージをアーカイブするのではなく、メッセージから好み、制約、決定などの構造化された事実を抽出します。それぞれの事実は、その根拠となるソースイベントに結び付けられています。
二時点管理と置き換え。 すべての事実に、明示的な有効日とステータスが付いています。情報が変わると、古い事実には 置き換え済み のマークが付けられます。ひそかに削除されることも、最新の情報として再び提供されることもありません。矛盾が解決されていない場合は、どちらかを無作為に提供するのではなく、両方のバージョンを保留してフラグを付けます。
体系的なトレーサビリティ。 挿入される各コンテキストパケットには、ソース、有効日、どのメモリが保持、除外、またはブロックされたか、その理由を説明するトレースが含まれています。「エージェントがこの情報を使ったのはなぜか?」という問いに、1分以内に検証可能な答えを得られます。
クイックスタート
前提条件:Docker と uv が必要です。
.env.exampleのデフォルト設定で開始できます。キーは不要です。カスタム設定(実際の LLM キーなど)を使用する場合は、このファイルを.envにコピーしてください。
# Infrastructure (PostgreSQL 16 + pgvector, Redis 7)
docker compose up -d
# Dependencies (uv installs Python 3.12 if needed)
uv sync
# Database
uv run alembic upgrade head
# API
uv run uvicorn app.main:app --port 8100
問題が発生した場合は、
bash scripts/doctor.shを実行すると、Docker、コンテナ、Postgres、.env、マイグレーション、API を 1 つのコマンドで診断できます。読み取り専用で副作用はなく、必要なだけ安全に再実行できます。
別のターミナルで、すべてが動作することを確認します。
uv run haki connect --api-url http://localhost:8100
uv run haki verify
haki verify は数秒で完全なシナリオを実行します。まず好みを記録し、同じ会話の中でその考えが変わったことを記録し、次に新しい会話でメモリを検索します。現在の値を返し、古い値を消去せずにステータス superseded のまま保持し、一連の処理全体をトレースに関連付ける必要があります。

haki verify — subject usr_verify_91d952a5e06f
✔ capture "Je préfère recevoir mes factures en français." thr_35bb7ecf
✔ consolidate 1 fact(s) extracted 0.2s
✔ capture "En fait, envoie-les moi en anglais plutôt, pa..." thr_35bb7ecf (same thread)
✔ consolidate 1 supersession 0.1s
✔ context NEW thread thr_3a21ef34 0.0s
recalled invoice_language = {"language": "en"} valid since 2026-08-11
hidden invoice_language = {"language": "fr"} superseded
trace 7c99a8de-4905-43b4-94df-21fb66492b3b
OK — your agent remembered across conversations, and it can prove it. 0.5s
古い値が引き続き返される場合、または古い値が superseded として見つからない場合、コマンドは 1 を返して終了します。たまたま正しい値を返しても、2 つの事実が関連付けられていなければ、実際に更新されるメモリとは言えません。
デフォルトで多言語に対応しています。ローカル埋め込みは多言語(フランス語、英語、スペイン語、その他約 50 言語)に対応しています。上記のデモシナリオは意図的にフランス語で記録されており、別の言語でクエリを実行しても見つかります。エンドツーエンドで検証済みです (
scripts/check_multilingual.py)。
Haki の 4 つの使い方
1. コーディングエージェント — SDK と CLI
Python または TypeScript の開発者向けです。既存の LLM 呼び出しに数行追加するだけです。
from haki import HakiClient
from haki.runtime import build_prompt_context, capture_turn
client = HakiClient("http://localhost:8100")
# Before the LLM call: memory becomes an instruction block
packet = client.context(subject_id="usr_42", query=user_msg, project_id="prj")
prompt = build_prompt_context(packet) + "\n" + system_prompt
answer = my_llm(prompt, user_msg) # your LLM and app code don't change
# After the LLM call: the conversation turn goes back into memory
capture_turn(client, "usr_42", "prj", user_msg, answer)
SDK の詳細(メソッド、非同期処理、エラー)
capture(events, idempotency_key)— 冪等な取り込みです。ネットワークの再試行で重複が作成されることはありません。context(subject_id, query, project_id, budget_tokens=2000)—trace_idを含む ContextPacket です。inspect(trace_id)— これらのメモリが選択された理由を確認します。timeline(subject_id, project_id)、consolidate_subject(...)、facts(...)、consolidate()、forget(...)、health()。- 非同期版:
AsyncHakiClient。 - 型付きエラー:
HakiApiError(error_type、field、status_code)、HakiConnectionError。
CLI:haki login(デバイスコードによるサインイン。以下を参照)、haki connect
(キーを用意して設定とテストを実行)、haki verify(時間を計測するメモリテスト)、
haki status(API のヘルス状態)、haki mcp(Cursor 用のパッケージング)。
haki login — Cloud アカウントでは、hk_ キーはプロビジョニング時に一度だけ表示されます。ターミナルから再取得する方法はありません。デバイスコードフロー(RFC 8628)を使えば、新しいシークレットを用意せずにこの問題を解決できます。CLI は XXXX-XXXX コードを表示し、コードが入力済みの状態で
<HAKI_CONSOLE_BASE_URL>/cli-auth を開きます
(verification_uri_complete)。コードは画面にも表示されたままなので、スマートフォンから手入力することもできます。サインイン済みの状態でコンソールから承認すると、ターミナルはコンソール自身のキーではなく、専用の新しいキーを受け取ります。Keys からそのターミナルを失効させても、ほかの接続は切断されません。キーは、それを消費するポーリングによって一度だけ提供されます。
サーバー側では、HAKI_CONSOLE_SERVICE_KEY を設定する必要があります(コンソールから /v1/cli/device/approve への認証に使用されます)。無効なコードに対するレート制限は、IP ごとではなくユーザーごとに適用されます。承認リクエストはすべて同じアドレス(コンソール自体のバックエンド)から届くため、IP 単位のカウンターでは全員で共有する枠になり、1 人のユーザーがほかのユーザー全員分を使い切れてしまうからです。
TypeScript SDK(Python SDK と同等)
同じメソッド、同じ型付きエラー、同じ <haki_memory> ブロックに対応し、実行時の依存関係はありません(ネイティブ fetch、Node 18 以降)。
cd sdk/typescript && npm install && npm run build && npm test
import { HakiClient, buildPromptContext, captureTurn } from "gethaki";
const client = new HakiClient({ baseUrl: "http://localhost:8100", apiKey: "hk_..." });
const { packet } = await client.context({ subjectId: "usr_42", query: userMsg, projectId: "prj" });
const prompt = buildPromptContext(packet) + "\n" + systemPrompt;
const answer = await myLlm(prompt, userMsg);
await captureTurn(client, { subjectId: "usr_42", projectId: "prj", userMsg, assistantMsg: answer });
CLI haki-ts(node dist/cli.js …):connect、verify、status に対応します。Python CLI と同じ ~/.haki/config.json ファイルを使うため、両者は相互に置き換えて使用できます。
実行可能な例:
sdk/typescript/examples/basic-agent.mjs。
2. Cursor — MCP サーバー
Cursor ユーザー向け。ワンクリックでインストールでき、キーを手動でコピーする必要はありません。
uv run haki mcp # prints the deeplink, the mcp.json, and the Project Rule
- 「Cursor に Haki を追加」ディープリンクで MCP サーバーをインストールします。
- プロジェクトルール(
.cursor/rules/haki.mdc)で、エージェントがいつ記憶し、いつ想起するかを指示します。 - これにより Cursor は、セッションをまたいで決定事項、規約、解決済みのバグを保持します。
Cursor には次の 4 つのツールが表示されます。
| ツール | 役割 |
|---|---|
haki_context | コーディング前にプロジェクトに関連するコンテキストを想起します |
haki_capture | 決定事項、規約、解決済みのバグを保存します |
haki_inspect | メモリが使用された理由を確認します |
haki_forget | 情報を忘れます |
既知の制限として、文書にも明記されています。MCP は Cursor のすべての会話を傍受できるわけではありません。サーバーに見えるのは、Cursor が呼び出すと判断したツール呼び出しだけです。プロジェクトルールでエージェントにツールを呼び出す「タイミング」を指示します。実際のカバレッジは測定され、完全なものとして示されることはありません。
3. n8n — テンプレートとノード
ノーコードで構築するユーザー向け。インポートするテンプレートが 1 つ、設定する項目が 3 つあります。
チェーン:Webhook → Haki Context → AI Agent → Haki Capture → Respond
integrations/n8n/ には 2 つの選択肢があります。
- ネイティブテンプレート
haki-persistent-support-agent.json— 標準の HTTP ノードを使用するため、追加のインストールなしで任意の n8n インスタンスにインポートできます。 - ノードパッケージ
n8n-nodes-haki— 検証機能を内蔵した、視覚的に操作できるHaki ContextノードとHaki Captureノードを提供します。
必要な設定は、Haki の認証情報、LLM の認証情報、相手の識別情報(subject)の 3 つだけです。識別情報のない呼び出しは拒否されます。安定した識別情報のないメモリは信頼できないためです。
実際の n8n インスタンス(Docker)で検証済みです。最初のメッセージで伝えた好みが、その出典とともに 2 つ目のメッセージで想起されます。
4. OpenAI 互換ゲートウェイ
すでに OpenAI API に対応しているアプリ向け。変更するのは base_url だけで、メモリが自動化されます。
import openai
client = openai.OpenAI(
base_url="http://localhost:8100/gateway/v1",
api_key="hk_...", # Haki key
default_headers={"X-Haki-Subject-Id": "usr_42"}, # who to remember
)
client.chat.completions.create(model="...", messages=[...])
POST /gateway/v1/chat/completions を呼び出すたびに、対象のメモリがシステムメッセージの先頭に挿入され(<haki_memory>…</haki_memory> ブロック)、設定済みのプロバイダーにリクエストが転送されます(HAKI_LLM_* — Haki キー自体が上流に送信されることはありません)。その後、やり取りが記録され(conversation.turn、冪等)、バックグラウンドで統合処理が再開されます。返されるレスポンスはプロバイダー自身のもので、変更はありません。加えて、次の 3 つのヘッダーが付与されます:X-Haki-Memory、X-Haki-Trace-Id、X-Haki-Context-Ms。
- 識別情報はリクエストボディではなくヘッダーで渡されます(何を記憶するかをモデルが選ぶことはありません):
X-Haki-Subject-Id(メモリに必須)、X-Haki-Thread-Id、X-Haki-Run-Id、X-Haki-Purpose、X-Haki-Idempotency-Key(デフォルト:ボディのハッシュ — 再試行しても重複は作成されません)。 - 制御された縮退動作:識別情報がない場合、リクエストは変更されずに通過します(
X-Haki-Memory: disabled)。コンテキストを構築できない場合も、リクエストは送信され、degradedとして示されます。Haki がエージェントをブロックすることはありません。 - ストリーミング:
stream: trueはそのまま通過します(X-Haki-Memory: disabled、挿入なし、記録なし)。これは意図的な選択です。最終レスポンスを記録できないまま挿入するとメモリのループが壊れ、ストリーム全体をバッファリングすると、そもそもストリーミングを行う意味がなくなります。 - 文書に明記された制限(プライベートリポジトリの
research/Haki_Memory_Runtime.mdを参照):ゲートウェイが観測するのはモデルへの呼び出しであり、エージェントが 2 回の呼び出しの間にローカルで実行するツールではありません。これらは SDK または API から直接記録されます。
httpx 版は SDK にも用意されています:haki.gateway.gateway_client(base_url, api_key, subject_id, ...)(および async_gateway_client)。メモリによるオーバーヘッドの大部分は build_context によるものです(ローカルで約 15 ms、/v1/context の p95 は 250 ms 未満)。再現可能なベンチマーク:
uv run python scripts/benchmark_gateway.py --api-key hk_...。
ホスト型クラウド
独自のインフラを運用したくありませんか? gethaki.space では同じ API に加え、メモリの閲覧、トレースの確認、競合の手動解決ができるウェブコンソールを利用できます。セルフホストも引き続き完全にサポートされ、無料です。このリポジトリの API は、Cloud が実行しているものと同じです。
仕組み
flowchart LR
A[Incoming message] --> B[CAPTURE<br/>raw evidence,<br/>append-only]
B --> C[CONSOLIDATION<br/>extraction, dedup,<br/>supersession, conflicts]
C --> D[(MEMORY<br/>active facts,<br/>dated, sourced)]
D --> E[CONTEXT<br/>relevant packet,<br/>under budget,<br/>249ms p95]
E --> F[Agent and LLM]
F --> B
E -.-> G[INSPECT<br/>decision trace]
D -.-> H[FORGET<br/>propagated erasure,<br/>with a receipt]
- CAPTURE — アプリケーションからイベント(メッセージ、アクション、ツールの結果)を送信します。Haki はそれを不変の証拠として記録し、数ミリ秒で応答します。ネットワークの再試行によって重複が発生することはありません(冪等性)。
- CONSOLIDATION — バックグラウンドで、Haki はイベントを読み取り、永続的な事実にする内容を判断します。重複を排除し、変更を検出し(古い事実は 置き換え済み になります)、矛盾を検出します(ステータスは 競合 となり、解決されるまで保留されます)。事実は (subject、predicate、qualifiers) によって識別されます。「平日の起床時刻」と「週末の起床時刻」は、矛盾するものではなく、共存する別々の事実です。また、表現がどれほど似ていても、異なる修飾子が別のものと混同されることはありません。
- CONTEXT — エージェントは応答の前に毎回、関連するメモリを要求します。Haki は有効で、適用範囲内にあるアクティブな事実のみを、厳格なトークン予算内で関連度順に返します。10,000 件の事実で測定した p95 は 249 ms です(
scripts/benchmark_context.pyを参照)。 - INSPECT — 情報が保持、除外、またはブロックされた理由は、いつでもトレースで確認できます。
- FORGET — 修正や消去は、そこから派生したすべての情報に伝播し、タイムスタンプ付きの受領証が発行されます。
概念
| 概念 | 定義 |
|---|---|
主体 (subject) | 記憶の対象となる人物またはエンティティです。安定した ID が必須であり、ID がなければメモリは作成されません。 |
| イベント | 生の証拠です。「この日にこのメッセージがやり取りされた」などを指します。不変です。 |
| 事実 | 特定の時点で真実と見なされる情報です。日付、バージョン、出典が記録されます。 |
| 置き換え | ある事実が別の事実に置き換わることです。古い事実は履歴に残りますが、現在の事実として再び提供されることはありません。 |
| 競合 | 自動的に調停できない、互いに矛盾する2つの事実です。両方とも保留され、フラグが付けられます。 |
| ContextPacket | 応答の前に挿入されるメモリパケットです。予算内の関連する事実と、その出典が含まれます。 |
| トレース | すべてのメモリ判断(保持、除外、ブロック)とその理由を説明するログです。 |
| スコープ | メモリの封じられた境界(組織 → プロジェクト → 主体)です。境界を越えることはありません。 |
位置付け
| 一般的なアプローチ | Haki | |
|---|---|---|
| 考えの変更 | 古い事実と新しい事実が共存し、矛盾の原因になります | 古い事実は置き換えられ、現在の事実のみが提供されます |
| 矛盾 | モデルにランダムに提供されます | 保留され、フラグが付けられ、明示的に解決できます |
| 説明可能性 | ブラックボックス | すべての事実について、トレースと出典を確認できます |
| 忘却 | 行を削除します | 受領証付きで連鎖的に伝播します |
| 検索レイテンシ | リクエストごとにネットワーク経由で埋め込みを呼び出します | ローカル埋め込みを使用するため、クリティカルパス上でネットワーク呼び出しはありません |
| 言語対応 | 英語のみを対象に最適化されていることがよくあります | ネイティブで多言語に対応しています(約50言語) |
| デプロイ | 複数のサービス(ベクトルストア、キューなど)を組み合わせる必要があります | 単一の docker compose up で実行できます |
実測パフォーマンス
再現可能なベンチマーク:uv run python scripts/benchmark_context.py(各サイズで100件のリクエスト、ローカル埋め込み、Windows 開発マシン)。
| メモリ内の事実数 | p50 | p95 | PRD 目標 |
|---|---|---|---|
| 100 | 60.5 ms | 80.6 ms | < 250 ms |
| 1,000 | 63.7 ms | 68.0 ms | < 250 ms |
| 10,000 | 27.8 ms | 42.5 ms | < 250 ms |
埋め込みはローカルで計算されます(CPU 上の ONNX、多言語対応の384次元モデル)。クリティカルパス上でネットワーク呼び出しはありません。検索ではベクトルインデックス(hnsw)と全文検索インデックス(GIN)を組み合わせ、その後、最適な候補のみをスコアリングします。LLM のコスト(抽出)は完全に非同期であり、応答が遅くなることはありません。
公開ベンチマーク
Haki が公開しているのは、都合よく選んだ数値ではなく、再現可能なベンチマークハーネスです。データセットとチェックサム、モデル、プロンプト、予算、価格を固定してバージョン管理した設定、まったく同じプロトコル(同じモデル、同じプロンプト、同じ判定者)で再実行したフルコンテキストのベースライン、そしてこの分野ではほとんど公開されていない指標(矛盾の漏出、棄権率、パケットあたりのトークン数、レイテンシ、コスト)を提供します。
- ハーネス:
eval/(LoCoMo と LongMemEval_S のローダー、パイプライン、判定者、レポート)。 - 結果は意図的にこのリポジトリにコミットされません。固定されたデータセットと設定を使ってハーネスを自分で実行してください。得られた数値(
eval/results/に書き込まれます。gitignore 対象です)は、こちらが見せたい数値ではなく、信頼するか異議を唱えるかを判断できるのはあなた自身です。 - 再現方法:
eval/README.mdに正確なコマンドを記載しています。
API の概要
| エンドポイント | 役割 |
|---|---|
POST /v1/capture | イベントを送信します(冪等で、即座に受領を確認します) |
POST /v1/context | ContextPacket を取得します(事実、警告、trace_id) |
GET /v1/inspect/{trace_id} | メモリーの判断に関する完全なトレース |
GET /v1/timeline | 対象のイベント(未加工の証拠) |
GET /v1/facts | 対象のすべての状態の事実(ソース、日付、バージョン) |
GET /v1/traces | プロジェクトの最近のトレース(直近 50 件) |
GET /v1/conflicts | 解決待ちの矛盾 |
POST /v1/conflicts/{id}/resolve | 矛盾を解決します |
POST /v1/feedback | メモリーを評価します(useful/irrelevant/incorrect) |
POST /v1/keys · GET · DELETE | API キーを管理します |
POST /v1/consolidate | 統合を実行します(開発/運用) |
POST /v1/forget | 受領証付きで、事実または対象を忘れさせます |
POST /gateway/v1/chat/completions | OpenAI 互換プロキシ:メモリーの自動注入と取得 |
GET /v1/stats/health | メモリーの健全性指標(鮮度、未解決の矛盾、カバレッジ) |
GET /health | API の健全性 |
/mcp | MCP サーバー(Cursor およびその他の MCP クライアント向け) |
以下の curl の例では、既存のキーを使うことを前提としています。
curl -X POST http://localhost:8100/v1/keys -d '{"org_id":"org_acme","project_id":"prj_support","label":"dev"}'で作成してください(最初のキーは無料で、それ以降は各キーが個別のプロジェクトを管理します)。次に、すべての呼び出しに-H "Authorization: Bearer hk_..."を追加してください。
エラーは型付けされ、対処方法が分かる内容です。
{"error": {"type": "missing_scope", "message": "...", "field": "..."}}
のように返され、汎用的なメッセージにはなりません。
完全な例:取得してからコンテキストを取得する
# Capture a preference
curl -X POST http://localhost:8100/v1/capture \
-H "Content-Type: application/json" \
-d '{
"idempotency_key": "demo-1",
"events": [{
"org_id": "org_acme", "project_id": "prj_support",
"subject_type": "user", "subject_id": "usr_42",
"kind": "conversation.message",
"occurred_at": "2026-07-15T10:00:00Z",
"payload": {"role": "user", "content": "I prefer my invoices in French."},
"classification": ["customer-data"]
}]
}'
# Consolidate (extracts the durable fact)
curl -X POST http://localhost:8100/v1/consolidate
# Ask for memory before a response
curl -X POST http://localhost:8100/v1/context \
-H "Content-Type: application/json" \
-d '{
"project_id": "prj_support", "subject_id": "usr_42",
"query": "what language should the invoice be in?",
"budget_tokens": 2000
}'
応答:事実 invoice_language: {"language": "fr"}、その有効日、ソースイベント ID、および trace_id。
セキュリティ、スコープ、忘却
- プロジェクトごとの API キー:デフォルトでは、すべての
/v1/*呼び出しにAuthorization: Bearer hk_...が必要です。キーは単一の プロジェクトに紐づいており、別のプロジェクトを要求すると、そのほかのプロジェクトが存在することを 明かすことなく、403 forbidden_scopeが返されます。管理にはPOST/GET/DELETE /v1/keysを使用します(詳細はdocs/SECURITY.mdを参照してください)。 - PostgreSQL の行レベルセキュリティ:分離はデータベース自体によって 保証されます(イベント、ファクト、トレース、競合に対する RLS)。アプリケーションの フィルターが漏れていても、クエリがプロジェクトをまたぐことはありません( 非開示テストで実証済みです)。
- 決定論的なポリシーエンジン:すべての読み取りと書き込みは、明示的な ルール(スコープの存在、キーとプロジェクトの一致、監査)を通過します。 言語モデルを介することはありません。
- モデルがスコープを選ぶことはありません:
project_idとsubject_idは、 呼び出し元のバックエンドまたはその設定から取得され、LLM から取得されることはありません。 - フィードバックと修正:
POST /v1/feedback(useful/irrelevant/incorrect— incorrect としてフラグ付けされたファクトはdisputedとなり、その後は提供されません)。POST /v1/conflicts/{id}/resolveは、完全な履歴を保持しながら矛盾を解決します。 - シークレット:LLM キーは
.env(Git の追跡対象外で、テンプレートは.env.exampleにあります)に保管し、コード、ターミナル、 フロントエンドには置きません。 - 実際の忘却:
POST /v1/forgetは、ファクト、 埋め込み、イベント、トレースに消去を反映し、タイムスタンプ付きの受領記録をforget_receiptsに残します。 - ローカル利用専用のオープンな開発モード(
HAKI_AUTH_REQUIRED=false)があり、 起動時に明示的な警告が表示されます。
アーキテクチャ
スタックとモジュール(技術的な詳細に興味がある方向け)
スタック:FastAPI · SQLAlchemy 2.0 async · PostgreSQL 16 + pgvector (hnsw) · Alembic · Redis 7 · fastembed (ONNX CPU) · 公式 MCP SDK。
モジュール:
- Memory Ledger (
app/ledger/) — 双時制の追記専用イベント (occurred_at= 業務上の時刻、recorded_at= システム時刻)、バージョン管理された ファクト、明示的なステータス遷移:candidate → active → superseded/disputed/disabled → deleted(終端)。 - Memory Consolidator (
app/consolidator/) — Pydantic で検証された LLM 抽出 (バッチによってクラッシュすることはありません)、コンテンツベースの重複排除 (冪等な再実行)、置き換え、競合セットに対応しています。プロバイダーの障害時は イベントに触れることなくジョブをfailedにし、イベントは再処理可能な状態に保たれます。 - Context Assembler (
app/context/) — 厳密なフィルター(active、スコープ、 有効性)を適用した後、ハイブリッドスコアを算出します:0.6 × コサイン類似度 + 0.25 × 全文検索 + 0.15 × 新しさ。さらに クロスエンコーダーによる再ランキング、マルチホップのエンティティ展開、 時間的グラウンディングの処理を行います(これらの連携方法については、プライベートリポジトリのresearch/Haki_Livre_Construction_2026-08-15.mdを参照してください)。二段階検索 (インデックスの選択、その後のスコアリング)により、メモリのサイズにかかわらず コストが安定します。 - 交換可能なプロバイダー (
app/providers/) — 抽出器 (HAKI_LLM_PROVIDER=fake|openai) と埋め込み生成器 (HAKI_EMBED_PROVIDER=local|fake、デフォルトは local) を 個別に設定できます。特定ベンダーの SDK はハードコードされていません。 - MCP サーバー (
app/mcp_server/) — API 内にマウントされ、Streamable HTTP トランスポートを使用します。 - ゲートウェイ (
app/gateway/) — OpenAI 互換のプロキシです。SDK のbuild_prompt_context(単一の共有実装)で生成された<haki_memory>ブロックを挿入し、HAKI_LLM_*を通じて上流に転送します(Haki キー自体は転送しません)。応答後に 冪等にデータを取り込み、ストリーミングのパススルーについても文書化されています。
データベース(Alembic マイグレーション):events、facts(vector(384)
埋め込み、GIN を使用する tsvector の search_vector)、jobs、conflict_sets、
context_traces、forget_receipts、organizations、subject_aliases、
predicate_aliases。
品質とテスト
実際の PostgreSQL データベースを使った Python テスト 376 件と Node テスト 14 件です(データベースのモックは使用しません)。uv run pytest および cd sdk/typescript && npm test を実行してください。
テストでは、実装の詳細ではなく、動作上の保証を検証します。
- 置き換えられた事実がアクティブなものとして返されることはありません。
- あるサブジェクトが、別のサブジェクトのメモリを参照することはありません。
- ネットワークの再試行によって重複が作成されることはありません。
- 未解決の競合がある場合、関係する両方の事実が保留されます。
- 忘却後、その内容が再び提供されることはありません。
- 不正なステータス遷移は拒否されます。
- ゲートウェイはメモリを挿入し、決してブロックすることなく機能を縮退させ、上流エラーを転送し、冪等性キーごとに一度だけ取得します。
実際の環境でエンドツーエンドの検証をすでに実施しています。LLM による抽出(OpenRouter)、MCP サーバー(公式クライアント)、n8n ワークフロー(Docker)、レイテンシーベンチマークが含まれます。
現在の保証について、それぞれに仕組みと保証を証明するテストを示したドキュメントは、docs-site/en/production-guarantees.mdx にあります。
ロードマップ
| マイルストーン | ステータス |
|---|---|
| Memory Ledger と冪等な取得 | 完了 |
| Consolidator(置き換え、競合)と ContextPacket | 完了 |
| ローカル埋め込みと 250 ms 未満の p95 ベンチマーク | 完了 |
Python SDK と haki CLI | 完了 |
| MCP サーバーと Cursor の統合 | 完了 |
| n8n の統合(テンプレートとノード) | 完了 |
| セキュリティ:API キー、RLS、ポリシーエンジン、フィードバック | 完了 |
OpenAI 互換ゲートウェイ(base_url によるメモリの自動利用) | 完了 |
| TypeScript SDK | 完了 |
| 公開 LoCoMo および LongMemEval ベンチマークハーネス(再現可能で、自分で実行可能) | 完了 |
| そのハーネスでの Haki 独自の精度数値(調整済み、再現可能) | 完了 |
| 公開 Reliability Report ページ(推移、方法論、未解決の問題) | 予定 |
CLI のデバイスコード認証(haki login) | 完了 |
複数チャネルの ID 解決(/v1/subjects/resolve、/merge) | 完了 |
| クロスエンコーダーによる再ランキング、時間的グラウンディング、エンティティ/PRF 拡張 | 完了 |
メモリ健全性メトリクス(/v1/stats/health) | 完了 |
| セルフホスト可能なメモリ健全性ダッシュボード(Cloud コンソールとは独立) | 予定 |
リポジトリ構成
haki/
├── app/ # FastAPI API (ledger, consolidator, context, gateway, MCP)
├── sdk/python/ # SDK + haki CLI
├── sdk/typescript/ # TypeScript SDK + haki-ts CLI (Python parity)
├── integrations/n8n/ # Native template + e2e workflow (node package: github.com/GetHaki/n8n-nodes-haki)
├── alembic/ # PostgreSQL migrations
├── tests/ # Behavioral tests (incl. eval harness tests)
├── eval/ # Public benchmark harness (LoCoMo + LongMemEval)
├── scripts/ # Benchmarks and diagnostics
├── docs-site/ # Product documentation (Mintlify)
└── docker-compose.yml # Postgres + pgvector + Redis
これはセルフホスト可能な OSS コアです。API、両方の SDK、MCP サーバー、n8n 統合、公開評価ハーネスが含まれます。ホスト型のウェブコンソール(メモリの閲覧、クリックによる競合の解決、請求)はCloud の提供サービスの一部で、別の非公開リポジトリにあります。Haki のセルフホストにこれが必要になることはありません。
ドキュメント
製品ドキュメント(ガイド、完全な API リファレンス、本番環境保証の契約)は、docs-site/en/ にあります。Mintlify サイトで、該当フォルダーから mint dev を実行するとローカルで起動できます(Node 18/20/22 LTS が必要です)。フランス語訳は、docs-site/fr/ で並行して管理しています。
Haki — エージェントは重要なことを記憶し、それを証明できます。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。