Skip to main content
Glama

蒸留蔵 — distill-kura

エージェントのための長期記憶で、蓄積ではなく蒸留によって作られます。 想起は 意味 によって機能し、書き込みは 証拠 によって制御され、1つのサーバーは複数の独立した記憶を保持できます — エージェントのモードごとに1つ — そのためモードを切り替えるとエージェントが覚えている内容も切り替わります。

DeepSeek Harness プラグイン、その他のホスト向け MCP サーバー、HTTP サービス、そして Python ライブラリとして提供されます。標準ライブラリのみを使用し、ベクターデータベースも、埋め込みも、フレームワークもありません。

        ┌── recall ──────────────────────────────────────────────┐
        │  question → whole index in one prompt → picked slugs   │
        │           → walk [[links]] → the neighbourhood         │  ~0.4 s
        └────────────────────────────────────────────────────────┘
        ┌── distil ──────────────────────────────────────────────┐
        │  journal → classed evidence → candidates → GATE        │
        │  → new? → composed → draft → judged → poured           │
        └────────────────────────────────────────────────────────┘

存在理由

エージェントの長期記憶を損なう失敗は2つあり、その2つは正反対の方向から記憶を損なわせます。

キーワードによる検索は、必要なものを見逃します。 「SSD推論チップ」 についての質問は、「SSD階層から2.6Tモデルを実行する」 というタイトルの記憶と単語を共有していません — しかしこれらは同じ主題です。単語検索では何も返らず、エージェントは根拠なく答えます。ここでの修正は埋め込みではなく 認識 です。インデックス全体(記憶ごとに1行、認識トリガーとして書かれる)を1つのプロンプトに入れ、小さなモデルが質問に関係するものを名指しします。約500件の記憶のインデックスは約6kトークンで、現代のコンテキストウィンドウの数パーセントであり、プレフィックスキャッシュに載ります。

すべてを書き込むとストアが汚染されます。 エージェントがあることを主張し、素朴な蒸留器がその主張を事実として記録し、次のエージェントがそれを正真正銘の事実として読み戻し、より強い確信で繰り返します。そのループは自己強化型であり、プロンプトの指示では止められません — 推測ではなく、測定されています。そのため書き込み経路は決定論的なPythonで制御されます。候補となる記憶はそれぞれ、生の素材に 文字単位で 存在する引用を、出典を示すタグ付きで保持しなければなりません。

class

説明

許可されること

[USER]

人間自身の言葉

「彼らが決めた」「彼らが尋ねた」

[TOOL]

機械の出力

数値 — 唯一の情報源

[ACT]

呼び出されたツール

「これが実行された」

[SELF]

エージェント自身の散文

一人称による判断であり、決して裸の事実ではない

逐語的に見つからない引用は破棄されます。生き残った引用がない候補は捨てられます。背後に [TOOL] のない数値は削除されます。[USER] の引用が残っていないのに、人間が決定したとするテキストは、最後の関門で拒否されます。アイデアは歓迎されます — それらはシードファイルに行き、ストアには決して入らず、後の証拠が確認したときだけ昇格します。


Related MCP server: Memsolus MCP Server

クイックスタート

git clone https://github.com/lna-lab/distill-kura && cd distill-kura
pip install -e .                       # or just run: python3 -m distill_kura.cli

cp kura.example.toml kura.toml         # edit: one model endpoint is enough to start
kura init main --path ~/kura/main      # create an empty store
kura serve                             # http://127.0.0.1:8085
curl -s -X POST localhost:8085/recall -H 'content-type: application/json' \
     -d '{"question":"what did we decide about the archive disk?","hops":1}'

インデックスを装着させ、エージェントが常に何が既知かを把握できるようにします:

kura weave                             # build the three-layer cloth
kura prefill                           # the block to put in the system prompt

エージェントのトランスクリプトを投入します:

kura distill run      # drink a batch → candidates → gate → drafts
kura distill drafts   # look at what it wants to write
kura distill drain    # the scribe re-reads each draft cold: pour / fix / toss
kura distill night    # stay resident and do it whenever things go quiet

drain(または手動実行の pour)まで、ストアに何も入りません。下書きは証拠をHTMLコメントとして保持するため、なぜ記憶が存在するのかを常に確認できます。


常駐マップ

ツールによる想起は 「Xについて何を知っていますか?」 に答えます — しかしそれはエージェントが質問しようと決めた場合だけです。エージェントが思いつかない質問には決して答えません:そもそもここに何かあるのか? マップを見られないエージェントは、自分が何を見逃しているのかを知らず、推測します。そしてあなたの家庭についての自信に満ちた推測こそ、このプロジェクトが防ぐために存在する失敗です。

そのためインデックスも装着されます。毎ターン、システムプロンプト内の常設ブロックとして。

kura weave      # re-weave the index into the three-layer cloth
kura prefill    # print the block a host should inject

3つの層、詳細は最近のことにしか報われないから

盲検のA/Bテスト — 20問、太いインデックス対スリムなインデックス、どちらか分からない状態で採点 — によって形状が決まりました:

帯域

太い

スリム

全体

9

11

最近の出来事

4

1

ドクトリン

1

4

分野をまたぐ飛躍

1

4

ドクトリンの行は両方のインデックスでバイト単位で同一でしたが、スリムなインデックスがその帯域でも勝ちました:周囲が軽いほど、常設の行はより良く機能します。 詳細は洞察の源泉ではありません。詳細が居場所を得るのは、物事がまだ動いている場所だけです。

層

ルール

行

pinned

frontmatter の type が pinned_types にある

完全な形で保持

fresh

fresh_days 以内に変更された

完全な形で保持

trigger

それ以外のすべて

約 trigger_tokens に圧縮

トリガー行は scribe モデルが書き、説明 と 予算をキーとする台帳にキャッシュされるため、定常状態での織り直しはコストがかかりません。モデルに到達できない場合、織機は代わりに機械的にトリミングします — 記憶システムはGPUが停止したからといって空白になってはなりません。

経過時間はmtimeではありません。 cp -r、リストア、チェックアウトはすべてのタイムスタンプをリセットし、インデックス全体が "fresh" になり、何もトリミングされず、機構は静かにオフになります。そのため織機は記憶 の中に 書かれた日付を好み、ストアの5分の1が1暦日と共有するmtimeは信用しません。

それがどこに行くのか、そしてなぜそれがキャッシュの決定なのか

- id: kura
  name: distill-kura
  config: { store: eq, promptOrder: -50 }   # before the persona

プレフィックスキャッシュは、最初に変更されたバイト以降すべて失われます — 1つのローカルサーバーでの測定では、同一の4,029トークンのプリアンブルは0.68秒から0.14秒に再価格化され、末尾 への追加は0.14秒のままですが、先頭に1語追加するとキャッシュ全体が失われます(0.66秒)。ペルソナは通常クロックを保持するため、毎分変わります。マップはプロンプト内で最大のブロックであり、1日に数回変わります。大きくて安定したものを、刻々と変わるものの前に置きます。

したがって、ブロック自体には日付も時計もカウンターも含まれません — そして build() はそれらを含むヘッダーを、3週間後の不可解に遅いターンではなく、ビルド時に拒否します。

半分のマップを渡すことは決してない

状況

エージェントが受け取るもの

すべて正常

<<<KURA-MAP>>> マーカーで囲まれたマップ

budget_fraction 超過

全体 のマップと、JSON内の警告(テキスト内には決してない — バナーは揮発性コンテンツだから)

hard_fraction 超過

インデックス行のないスタブで、空ではなくマップが欠落していると示す

kura 到達不能

マップが欠落しているという明示的な注記であり、決して空文字列ではない

切り詰められたマップは、利用可能な最悪の成果物です。完全に見え、カット位置より下のすべての記憶が存在しないように見えます。weave は収まるように fresh ウィンドウを短縮しますが、行を落とすことは決してありません — そしてどの設定も予算に達しない場合は、その旨を伝え、より良いマップを保持し、重みがどこにあるかを教えます。

ホストへの組み込み

ホスト

仕組み

DSH

ネイティブプラグイン — バックグラウンドで更新される systemPrompt.section

Claude Code, VS Code, Goose

MCP の instructions は短いポインタを運びます(2KB上限)。マップ自体は kura_map ツール、または kura prefill を実行するセッションフックから取得します

Claude Desktop, claude.ai

instructions を完全に無視 — kura_map を使用

その他

GET /prefill?format=text、またはシェルフック内の kura prefill

MCP の instructions フィールドは仕様上 MAY であり、9,000トークンのインデックスはそもそも2KBの上限を通れないため、このプロジェクトはそうでないふりをしません。


モード:kuraはひとつではない

「これをビルドするのを手伝って」と「これをじっくり考えさせて」の両方に役立つ単一の記憶は、どちらにもうまく役立ちません。デバッグに役立つ想起は、次に何をするかの会話ではノイズです。そこで、ストアはディレクトリであり、モードはストアに対応付けられます。

[stores.maker]
path = "~/kura/maker"
label = "maker mode — building things"

[stores.eq]
path = "~/kura/eq"
label = "EQ mode — talking things through"

[modes]
maker = "maker"
eq    = "eq"

すべてのルートはセレクタを受け取るため、1つのプロセスがすべてを提供します:

curl -s -X POST localhost:8085/recall -d '{"question":"...","mode":"eq"}'
curl -s localhost:8085/index?store=maker
curl -s localhost:8085/s/eq/doctor          # path form, for clients that only vary a base URL

ストアは記憶も、インデックスも、蒸留器のウォーターマークも共有しません。モードを切り替えると、本当に記憶される内容が変わります — 同じ記憶が別の声で語られるのではありません。

部屋は会話の前に選ばれます。 モードとはホストが送るものです — DSHプリセット、MCP環境の KURA_STORE、CLIの -s — そしてそれがセッション全体の家です。このプロジェクトでは、メッセージを読んでどのストアに属するかを決定するものはありません。ビルドから感情へと漂流する会話は、開始した場所に留まり、ホストは次のセッションのために別の部屋を提供することができます。未知のセレクタは入り口でエラーになり、静かにデフォルトへ落ちることは決してありません。

1つの部屋、多くのタグ。 記憶は正確に1つのストアに存在し、その性格を説明する複数のタグ(decision、landmine、emotion-carried、…)を持つことができます。タグは単語であり、重みではありません。タグでランク付けされるものも、数えられるものもありません。emotion-carried とタグ付けされた Develop の記憶は、依然として Develop の記憶です。記憶を別のストアに移動またはコピーするコマンドはなく、モード変更は将来のセッションにのみ影響します。同じ話題が2つの部屋で出された場合、2つの記憶が生まれ、それぞれがその部屋自身の証拠から蒸留されます。Research の「私たちが学んだこと」と Develop の「私たちがやったこと」は異なる事実であり、それらを重複排除するために境界を越えるものはありません。

広い部屋は少し柔らかく想起します。 固定された憲章を持つ狭いストアは鋭く認識します。何でも受け入れるストア — 目的ではなく人に従う USER ルーム — はより緩やかになると予想され、その代わりに理解が成長しうるストアです。憲章の隣に profile.md を文単位で置き、憲章の後に読まれ、自身の記憶から下書きされ、人間によって適用されます。そのような5つの部屋(憲章と設定付き)が examples/rooms/ にあります。

ルーティングとしては独立しているが、機密性としては独立していない。 サーバーには認証がないため、そのポートに到達できるプロセスは、保持している任意のストアを指定できます。エージェントをバインドすることで、モデル をレーンに留めておくことができます。プロセス を締め出すわけではありません。プロセスごとに1つの信頼レベル — docs/TRUST.md は短く、プライベートストアを置く前に読む価値があります。また、見逃しやすい2つの境界についても説明しています。1つのジャーナルルートから飲む2つのストアと、1つのモデルエンドポイントの背後にある2つのストアです。

DeepSeek Harness の場合

DSH はエージェントプリセットによってペルソナとツールを切り替えます。distill-kura はストアによって記憶を切り替えます。それらを結びつければ、1つのプリセット変更で自己全体が動きます:

# .agent-presets/eq/agent.cordis.yml
- id: kura-eq
  name: distill-kura
  config:
    url: http://127.0.0.1:8085
    store: eq            # this preset's memory
    readonly: true       # the CLIENT's own switch: do not even offer a write tool
    # (the store's own `write_policy` is the authority; this just keeps the tool
    #  out of the model's hands. Naming a store already binds the preset.)

依存関係は1つ、そしてそれがなぜpeerなのか。 プラグインは @deepseek-ai/dsh-tools から defineTool をインポートします。プロファイルローカルな2番目のコピーは、同じバージョンであっても、パッケージのモジュールローカルな Symbol の同一性を分割し、最初のツール呼び出しを undefined.prepare で失敗させる可能性があります。そのためプラグインは、プロファイルがバージョンの不一致なくコピーを供給できるように、パッケージを "*" の peer として宣言します。古い物理的な重複は依然として重複排除が必要な場合があります。examples/dsh-presets/ のインストールチェックを参照してください。

allowSwitch をデフォルトのままにすると、エージェントは kura_use も取得し、プリセット変更なしで会話中に kura 間を移動できます。ツール:kura_recall、kura_read、kura_doctor、kura_list、kura_use、そして kura_remember(ストアが書き込み可能な場合のみ)。MCP ブリッジとサービス行のための isolate レルムルールを含む完全な配線は、examples/dsh-presets/ にあります。

ペルソナはホスト側のビジネスであり、当プロジェクトの管轄外です。 このプロジェクトはペルソナをレンダリングも注入もせず、ストアごとにどのペルソナファイルが対応するかを記録するだけです。GET /profile?store=eq で読み取れるので、プリセットの所有者が両者を同期させられます。エージェントの指示も同様にホスト側の AGENTS.md メカニズムに委ねます。このコードベース 上で 作業するエージェントが従うべき規約については、このリポジトリの AGENTS.md を参照してください。

任意の MCP ホストで

{ "mcpServers": { "kura": {
    "command": "python3", "args": ["-m", "distill_kura.mcp"],
    "env": { "KURA_URL": "http://127.0.0.1:8085", "KURA_STORE": "eq", "KURA_READONLY": "1" }
}}}

フリーモードでは KURA_STORE を未設定のままにします。ツールは任意の store 引数を受け取り、kura_use がセッション中に切り替えます。


モデル: デフォルトは1つ、ロール単位でアップグレード

3つのロールであり、3台のマシンではありません:

ロール

実行されるタイミング

求められるもの

thinker

すべてのリコール

小型で高速。意味で関連性を判断できなければならない

brain

蒸留時: ジャーナルのバッチ全体を読む

コンテキスト長と忍耐

scribe

蒸留時: メモリを書き、ドラフトを判定する

あなたの言語での優れた散文、判断力

[models.thinker] だけを宣言すれば、1つのモデルが3つすべてを担います — あなたが話しているモデルが、メモリを書き判定する編集者でもあるのです。それがデフォルトであり、妥当なものです。高性能な GPU モデルは、アイドル時間に編集者の仕事を十分にこなせます。そして kura tend はあなたが戻ってきた瞬間にそれを停止します(後述の「無人運転」を参照)。

アップグレードの道は、編集者に専用の席を与えることです — より大きなモデル、オンライン API、あるいはGPU をまったく競合しない CPU モデルで、会話中もメンテナンスを続けられます。この家で構築された環境では、CPU 上で約3トークン/秒の1兆パラメータ MoE を編集者として実行しています。遅いですが、会話が使う席には一切触れず、5日間で書いたメモリは今日のストアの3分の1を占めています。他のロールはそれぞれ独立してアップグレードできます — より大きなローカルモデル、またはオンライン API(OpenAI 互換の /chat/completions であれば何でも。キーはあなたが指定した環境変数から読み取られ、設定に保存されることはありません):

[models.thinker]                       # always-on, local, small
url = "http://127.0.0.1:8000/v1"
model = "local-small"

[models.scribe]                        # upgrade just the writing
url = "https://api.example.com/v1"
model = "big-model"
api_key_env = "EXAMPLE_API_KEY"

これが自動で処理してくれる2つのこと: 推論努力の方言はモデルファミリーごとに異なるため(reasoning_effort、thinking_effort、enable_thinking)、すべてが送信されます — 未知のものはテンプレートが無視し、一方でデフォルトで深い思考に設定されたモデルは予算全体を推論に費やして何も返さない可能性があります。また、憲章テキストはすべてのロールのプロンプトの先頭にバイト単位で同一に配置されるため、遅いローカルモデルでは3つのロールが1つのキャッシュ済みプレフィックスを共有でき、3回のプリフィルを支払う代わりになります。

遅い編集者にはプレフィックスが必要です。 憲章はすべての呼び出しの先頭にバイト単位で同一に配置されるため、3トークン/秒の CPU 編集者は、ドラフトごとではなく、沈黙ごとに1回だけプリフィルを支払います。llama.cpp では、リカレントモデルには --cache-reuse 0 をテーブルから外し、サーバーのスロットを温かいままに保ちます(--slot-save-path)。編集者の呼び出しは、意図的に1時間待つもの(timeout=3600)です。

thinker がダウンしても、リコールは沈黙しません — 単語の重複にフォールバックし、回答に how=words とラベル付けします。ツールはこれを ⚠ degraded として表示します。静かな劣化は、劣化よりも悪いのです。

無人運転: kura tend

蒸留器、注ぎ手、織機は静かな時間に実行されることを意図しており、そのタイミングを判断する監視役はモデルを必要としません:

kura distill catchup -s maker   # first: start from today, do not drink a year of history
kura tend -s maker              # stays resident; one process per store
kura tend -s maker --once       # one tick, for a scheduler or a test

蒸留器を一度も見たことのないジャーナルに向けるときは、catchup を一度実行してください — そうしないと、最初の行動が履歴全体を飲み込むことになり、1年前のジャーナルでは、ストアがすでに知っているかもしれないことを再学習するために数日分のモデル時間がかかります。マーカーを前方に動かすだけなので、進捗を失うことはありません。

「静か」とは、最新のジャーナルファイルの mtime です。idle_min(10)の沈黙の後、待機中のドラフトを排出し(編集者はそれぞれをコールドで読みます: 注ぐ / 修正 / 捨てる)、ない場合は1回の蒸留パスを実行します。何かが注がれた場合は、常駐マップを1回再織りし、沈黙ごとにインデックスを1回整理します。何もすることがなかったトラックは終了コード2で終了し、backoff_min(20)の間休止するため、空のジャーナルがスピンすることはありません。作業(注いだ、捨てた、修正した、ドラフトした)を数えますが、起動は数えません。各トラックの出力は _still/tend.log に保持されます。また、kura doctor が読み取るハートビート(tending.alive)を書き込みます。静かに死ぬ監視役こそ、監視役が絶対に起こしてはならない唯一の失敗だからです。

ジャーナルが変更されると、実行中のトラックは停止されます。編集者は通常、あなたがまさに話そうとしている GPU と同じだからです。編集者を別の席(CPU モデル、別のマシン)に置く場合は、[distill] の下で yield_on_return = false を設定すると、進行中の判定は完了まで残されます。これは、この家が CPU 編集者を5日間実行した監視役であり、その教訓を基に再構築されたものです。docs/OPERATING.md に systemd ユニットがあります。

このプロジェクトが提供しないもの: 論文を読んでストアを自律的に成長させる自律研究ループ。家にはありますが、質問1つにつき1時間放置できるモデルが必要であり、その結果はゲートが使用する意味での証拠ではありません。それは家側の線の内側に留まります。


メモリの外観

1ファイル、1事実。

---
name: archive-on-slow-disk
description: the archive lives on the slow disk; the fast one stays scratch
metadata:
  type: project          # user | feedback | project | reference
  tags: ["decision", "landmine"]
  evidence_manifest: sha256:…
belongs_because: this store keeps how the machine is laid out and why
keep: which disk, and the reason
may_fade: the df figures from that afternoon
---

The archive goes on the slow disk. The fast disk is scratch space.

**Why:** the other way round burns write endurance for nothing.
**How to apply:** check which disk a target directory is on before writing there.
Related: [[disk-layout]]

そして MEMORY.md の1行:

- [Archive on the slow disk](archive-on-slow-disk.md) — the archive lives on the slow disk; the fast one stays scratch

その行だけが毎回読まれるものです。これは認識トリガーであり、要約ではありません: 固有名詞、数字、⚠️ 地雷、到達した結論。ある行を別のメモリの行と交換しても問題なく読めるなら、それは役割を果たしていません — kura distill tidy が機械的に検出可能なケースを見つけて書き換えます。

metadata の下/先頭の4行はキュレーションであり、事実ではありません: tags はメモリの性質に関する言葉です — 複数あるのが普通で、タグが存在する前に書かれたメモリには単にありません — そして3つの文は、なぜこのストアに属するのか、どのような意味が後の間引きを生き残らなければならないのか、どのような詳細が不要かを述べます。蒸留器はストアの憲章に照らしてこれらを提案します。人間について何かを主張するタグ(entrusted、emotion-carried、recurred)は引用と照合され、そのチェックはマニフェストに記録されます。recurred は、人間が別のセッションから再び話題を持ち出したときに、蒸留器によって一度だけ書かれます — これはプロパティであり、カウンターではなく、背後に数字はありません。

kura doctor は、件数、壊れたリンク、島(何もリンクしていないメモリ)、インデックスのドリフト、読み取れないタグ行、メモリが指しているが存在しないマニフェスト、学習済みプロファイルの状態、そしてストアの容量を4つの単位で並べて報告します — メモリ数、インデックストークン、ボディトークン、バイト — limit と pressure は None のままです。これは代謝に必要な目です。棚がいっぱいになったときに何が起こるかはまだ決定されていません: docs/DESIGN.md §8 を参照してください。


HTTP サーフェス

ルート

機能

POST /recall

{question, hops, top, chars, total_chars, store|mode} → 選択、走査、コンテキスト。chars はメモリごと。total_chars はコンテキスト全体のハード上限

POST /remember

{slug, description, body, type, title, tags, belongs_because, keep, may_fade} — 直接書き込み。write_policy = "direct-allowed" でない限り拒否

POST /annotate

{slug, tags, belongs_because, keep, may_fade} — 既存のメモリにタグ/3つの文をマージ。直接の扉。/remember と同じ拒否。何も追加しないマージは何にも触れません

GET /index

生のインデックス

GET /prefill

常駐ブロック。注入準備済み(フック用に &format=text)

GET /memory/<slug>

1つのメモリを完全に、tags と annotations 付きで

GET /doctor

1つのストアの健全性(?all=1 ですべてのストア)

GET /stores

ストア、モード、各ロールを担うモデル

GET /profile

ストアの憲章、状態(不在 / 存在 / 破損)付きの学習済みプロファイル、およびペルソナへのポインタ(ここでは決してレンダリングされません)

GET /health

生存確認

任意のルートは ?store= / ?mode=、ボディ内の store/mode フィールド、または /s/<name>/… パスプレフィックスを受け付けます。認証はありません: ループバックにバインドするか、前面に何かを置いてください。


変更前に読む価値のある設計ノート

  • docs/DESIGN.md — なぜ認識が検索に勝るのか、ゲートがもたらすもの、各メカニズムを動機づけた失敗。

  • docs/OPERATING.md — 常駐実行、スケジューラと終了コード、バックアップ、監視すべきもの。

  • docs/TRUST.md — ストア境界とは何か、何でないか、書き込みポリシー、見落としやすい2つの境界(共有ジャーナル、共有モデル)。プライベートストアを導入する前に読んでください。

それが防ぐ問題に直面するまで奇妙に見えるいくつかの決定:

  • 飲む前に予約。 蒸留器はジャーナルの区間を読む前にロックの下で確保し、ウォーターマークは前方にしか進みません。それぞれが自分のスナップショットを書き戻す2つの蒸留器は、互いの進捗を消し去り、同じ水を十数回飲み直しました。

  • ウォーターマークはアダプター単位。 追記専用トランスクリプトにはバイトオフセット、書き換えられるアーカイブにはシーケンス番号(再圧縮されたファイルへのバイトオフセットは嘘です)。

  • エコー抑制。 ストアにすでに存在する引用は新しい素材ではありません — ツールの結果を通してストアが自分自身を読み返しているだけです。これがないと、メモリシステムは自分の内容を永遠に再発見して再記録し続けます。

  • 最後のゲートはモデルであり、人間ではありません。 人間がすべてのドラフトを承認しなければならないなら、システムは静かにその人間をボトルネックにし、ドラフトは永遠に積み上がります。ループ内の何も、常に存在しない誰かを必要としてはいけません。

  • kura distill run は何もすることがなかったときに終了コード2で終了します。 スケジューラは「仕事をした」と「何も見つからなかった」を区別できなければなりません。そうしないと、ウォッチドッグが空のキューでスピンし、アイドル時間を必要とするステップを飢えさせます。

主張する代わりに測定する

2つの質問が1つの数字で答えられており、そうあるべきではありません。

どれだけ小さくなったか? store_ratio = メモリとインデックスのトークン / 実際に消費された生ジャーナルのトークン。何が失われたか? それは別の測定であり、100件に1件のメモリしか保持しないストアは、前者では見事なスコアを出しながら役に立たないのです。

kura bench compress                       # what this store cost, from the distiller's own metrics
kura bench compress --tokenizer-command "./count-tokens"   # exact, not estimated
kura bench retention --questions bench/fixtures/questions.json

ここでは、同梱のフィクスチャと組み込みの推定器で測定されています:

corpus

store_ratio

scripts/demo-clean-room.sh(普通聊天,大部分是填充内容)

0.18

bench/fixtures/corpus.jsonl(密集:每一行都是信号)

1.14

第二个不是 bug。在没有填充内容的材料上,蒸馏并不会压缩——每条记忆都会增加其原因和应用方法,存储结果会比转录内容略大。该比率是语料库的属性,而非此工具的属性,因此这里没有醒目的数字,命令也会报告它统计了什么。

保留率是无模型评分的:每个植入的事实都带有一个标记,该标记必须出现在召回返回的内容中,因此该分数可以在其他人的机器上复现。干扰项则相反——如果存储保留了标记为 must_not_store 的事实,则会扣分,因为记忆系统的评判标准既在于它保留了什么,也在于它拒绝了什么。

score 1.0 (10/10)   decision 1/1  number 2/2  negation 1/1  reversal 1/1
                    conditional 1/1  landmine 1/1  returning 1/1  distractor 2/2

这是合成夹具中的十个植入事实,由本地 Qwen3.8-27B(NVFP4)作为大脑和记录员进行蒸馏,使用 max_items = 8, coverage_passes = 2,并由同一模型作为思考者进行评分。不同的模型会给出不同的分数:该分数衡量的是流水线加模型,而夹具的存在是为了让模型成为唯一变化的因素。它衡量的是事实是否可找到,而不是答案是否读起来通顺——评判散文需要模型,那样基准测试就不再可复现。

kura distill run 每批次向 _still/metrics.jsonl 写入一行,原始数据就来自这里。规范侧只统计证据清单指向已记录批次的记忆——将整个存储除以少数批次的原始材料,是一个数量级方向错误的数字,而这个命令的第一个版本正是这样做的。早于清单的记忆被报告为 unattributed,而不是被静默包含。原始侧始终是蒸馏器在饮用时的估计,因此使用 --tokenizer-command 时,比率会被标记为 mixed。

运行环境

要求

Python

3.11+(无依赖;pip install -e ".[dev]" 仅添加 pytest)

Node

20+,仅用于 DSH 插件

zstd

仅用于读取 DSH 会话存档

模型端点

任何以 OpenAI 格式响应 POST <url>/chat/completions 的服务

“兼容 OpenAI”比“任何提供商”更窄。 供应商的原生 API 需要在其前面放置一个兼容 OpenAI 的网关;其自身的 URL 无法满足要求。严格的服务还会拒绝未知的顶层字段,因此请设置 dialect = "openai"(或 "generic")——默认的 "vllm" 会发送 chat_template_kwargs,本地服务器需要这些参数,而严格的服务会返回 400 错误。客户端会使用普通请求体重试一次,并记录调用失败的原因,而不是将所有原因归结为静默的 None。

测试

python3 -m pytest tests -q                              # 145 tests, no model required
cd dsh-plugin && npm test                               # 24 more for the plugin

该门禁是经过对抗性测试的:每个案例都是真实模型试图绕过它的方式。test_containment.py 的编写方式相同——每个案例都是一次逃逸尝试,而不是正常路径——因为它守护的是一个真实存在的漏洞:存储曾会响应任何你能拼出路径的文件。端到端测试针对脚本化的模型服务器在真实套接字上运行完整的蒸馏→排空循环。

许可证

MIT。

Available Tools

6 tools
kura_doctorA

Health check of the kura: how many memories, resolved and dead [[links]], islands (memories nothing links to), index drift. Call when recall behaves oddly, or when asked about the memory system itself.

ParametersJSON Schema
NameRequiredDescriptionDefault
storeNoWhich kura. Omit for the current one.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It does well by naming the diagnostic nature ('health check'), the categories of data inspected, and the symptom-triggered use case. It does not explicitly state whether the tool is read-only or whether any repair/reindexing occurs, but 'health check' strongly implies diagnostic rather than mutating behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact: two sentences, front-loaded with the core purpose, followed by a concise list of diagnostic metrics and explicit usage triggers. Every clause earns its place, with no filler or redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple tool with zero required parameters and a fully documented optional parameter, the description provides enough context to select and invoke the tool correctly. It explains what will be inspected and when to use it. The only gap is that it does not describe the return format or explicitly confirm the absence of side effects, but neither is critical for a diagnostic health-check tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and the description provides no additional parameter-level meaning beyond what the schema already states. The optional 'store' parameter is fully documented in the schema, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb-resource pairing: 'Health check of the kura', and enumerates concrete diagnostic outputs (memory counts, resolved/dead links, islands, index drift). This clearly differentiates it from the sibling tools like kura_read or kura_recall, which focus on reading or retrieving memories rather than diagnosing system health.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly states when to use the tool: 'Call when recall behaves oddly, or when asked about the memory system itself.' This provides clear invocation context. However, it does not explicitly mention alternatives or when not to use it, so it stops just short of full routing guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

kura_listA

List the kura this server holds and which agent mode each one belongs to. Call it when you are unsure which memory you are speaking from, or before switching.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It states the operation (list) and the output (kura and agent modes) but does not mention side effects, read-only nature, performance, or any edge cases. Adequate but not rich for a tool without annotation safety signals.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, zero wasted words. The first sentence states the core function; the second provides immediate usage context. Information is front-loaded and every word serves a purpose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a no-parameter list tool with no output schema, the description explains what is listed and exactly when to invoke it. It could mention what 'kura' refers to or if results are ordered, but the definition is sufficient for an agent to decide and call it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, and the schema coverage is trivially 100%. Per the rubric, 0 params earns a baseline of 4. The description does not need to add parameter details since none exist.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb 'list', the resource 'kura', and what is listed (which agent mode each belongs to). It implies a distinction from siblings like kura_read or kura_recall by focusing on the server's collection and mode mapping, though it does not explicitly name alternatives.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit when-to-use guidance: 'Call it when you are unsure which memory you are speaking from, or before switching.' It lacks explicit when-not-to-use or named alternative tools, but the usage context is concrete and helpful.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

kura_mapA

Show the whole index of the kura — every memory's one-line recognition trigger, in one answer. Use it when you need to see WHAT EXISTS rather than look something up: before claiming a topic was never discussed, when choosing which memory to open, or right after switching kura. It is a map, not the contents: open a memory with kura_read for the detail.

ParametersJSON Schema
NameRequiredDescriptionDefault
storeNoWhich kura. Omit for the current one.

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are present, so the description carries the full burden. It clearly frames a display operation ('Show the whole index... in one answer') and sets output expectations ('map, not the contents'). It does not discuss permissions or exact formatting, but for a non-mutating index tool the core behavioral disclosure is present.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, each earning its place: the first states the action and scope, the second gives concrete use cases, and the third clarifies depth and names the sibling for details. It is front-loaded and free of filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a low-complexity tool with one optional parameter and no output schema, the description provides the essential context: what it returns, when to use it, what it is not, and where to go for detail. Nothing needed to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the single 'store' parameter is already documented as 'Which kura. Omit for the current one.' The description adds no parameter-level detail beyond that, so it meets the baseline but does not exceed it.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Show the whole index of the kura - every memory's one-line recognition trigger.' It also distinguishes itself from siblings by saying it is 'a map, not the contents' and explicitly directs details to kura_read, so an agent can tell it apart from the other tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit when-to-use conditions ('when you need to see WHAT EXISTS... before claiming a topic was never discussed, when choosing which memory to open, or right after switching kura') and an explicit alternative ('open a memory with kura_read for the detail'). This is clear routing guidance rather than leaving usage to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

kura_readA

Read one whole memory from the kura by its slug (e.g. 'storage-doctrine'). Use after kura_recall when a summary is not enough and you need the full text.

ParametersJSON Schema
NameRequiredDescriptionDefault
slugYesMemory slug, without .md
storeNoWhich kura. Omit for the current one.

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations available, the description carries the burden of behavior. It clearly indicates a read operation fetching the full memory text, which is sufficient for this simple tool. It could add detail about return format or failure behavior, but the core behavior is transparent enough.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with no filler. The primary behavior is front-loaded, and the usage guidance, alternative, and selection condition are packed efficiently into the second sentence.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-by-slug tool with only two parameters, no output schema, and full schema coverage, the description is complete. It tells the agent what it does, when to use it, and provides an example. Nothing essential is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description adds a useful example slug ('storage-doctrine') but otherwise does not need to add much beyond what the schema already documents for 'slug' and 'store'.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('Read'), the resource ('one whole memory'), and the retrieval key ('by its slug'), with a concrete example. It also names the sibling tool it complements, distinguishing it from kura_recall without needing to inspect the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly states when to use this tool: 'Use after kura_recall when a summary is not enough and you need the full text.' This directly routes the agent to the appropriate alternative and gives a clear selection condition.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

kura_recallA

Recall from the kura — long-term memory retrieved by MEANING rather than keyword, then following [[links]] between memories. Call it whenever the question touches past decisions, measurements, people, machines, or anything done before — prefer it over guessing. An empty result means it is simply not remembered yet: say so plainly and never fill the gap with invention. Pass store to reach a different kura, or call kura_use to switch for the session.

ParametersJSON Schema
NameRequiredDescriptionDefault
hopsNoHow many [[link]] hops to walk (default 1)
storeNoWhich kura to ask (store or mode name). Omit for the current one.
questionYesWhat you want to remember, as a natural question

TDQS

A4.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations are absent, so the description carries the full burden of behavioral disclosure. It does reveal important behavior: it retrieves by meaning, follows links, and emphasizes not to fabricate when no result is found. However, it does not disclose potential side effects, rate limits, or what happens with the hops parameter (e.g., how deep the search goes and whether more hops affect latency). It also doesn't specify if the tool is read-only, though recall implies reading. Overall, it gives useful context but leaves some behavioral aspects unmentioned.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, dense paragraph but contains no filler. It front-loads the core purpose and usage guidance, then addresses edge cases and parameter use. It is appropriately sized for a tool with multiple interconnected behaviors (meaning-based recall, link-following, empty result handling). It could be slightly more structured (e.g., bullet points for handling empty results or parameter variants), but it is efficient and every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool has 3 parameters (1 required), no output schema, and moderate complexity due to link-following and alternate stores, the description covers the essential aspects: what it does, when to use it, how to handle empty results, and how to use parameters. It does not explicitly describe return format (e.g., whether it returns text or a list of memories), but with no output schema, it could have provided more on that. Missing details on hops behavior and potential limitations are minor gaps. Overall, it is fairly complete for an agent to use it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already documents all three parameters (question, hops, store) with descriptions, and coverage is 100%, so the baseline for parameter semantics is 3. The description adds value by explaining the semantics of 'store' ('reach a different kura') and hints that 'question' should be phrased as a natural question. It also implies the meaning of 'hops' (following [[links]]). It doesn't detail the format or constraints beyond the schema, but it enriches the meaning of each parameter sufficiently.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: 'Recall from the kura — long-term memory retrieved by MEANING rather than keyword, then following [[links]] between memories.' It differentiates itself from siblings by emphasizing meaning-based retrieval over keyword, which distinguishes it from tools like kura_read or kura_list. It also mentions specific use cases, making it easy for an agent to understand what it does.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly tells the agent when to use this tool: 'Call it whenever the question touches past decisions, measurements, people, machines, or anything done before — prefer it over guessing.' It also explains what to do on empty results ('An empty result means it is simply not remembered yet: say so plainly and never fill the gap with invention') and mentions alternatives or related actions ('Pass store to reach a different kura, or call kura_use to switch for the session'). This provides clear guidance on selection and behavior.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

kura_useA

Switch which kura the following calls read from, for the rest of this session. Use when the conversation moves to a different mode of work (for example from building things to talking things through). Has no effect on a bridge that was bound to a single kura at startup — it will say so.

ParametersJSON Schema
NameRequiredDescriptionDefault
storeYesStore or mode name

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the burden of behavioral disclosure. It does this well by revealing that the switch persists for the session, affects subsequent calls, and has no effect on a single-kura bridge (and that it will say so). It does not cover every possible error or side effect, but the key stateful behavior is disclosed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three sentences with no wasted words. The main effect and scope are front-loaded, the usage condition follows, and the edge case is placed last. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple one-parameter state-switching tool with no annotations and no output schema, this description is complete enough. It explains what the tool does, when to invoke it, how long the effect lasts, and the one major exception an agent needs to know about.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% — 'store' is already described as 'Store or mode name.' The description adds some context by suggesting that stores correspond to modes of work, but it does not enumerate valid values or add meaningful parameter detail beyond the schema. This is the baseline for high schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Switch') and names both the resource ('which kura the following calls read from') and the scope ('rest of this session'). This clearly distinguishes it from the sibling read/analysis tools like kura_read and kura_map, which retrieve data rather than change the active context.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly says when to use it: 'Use when the conversation moves to a different mode of work,' with a concrete example. It also discloses a limitation about bridges bound to a single kura. It does not explicitly name sibling alternatives or state when not to use it, but the intended context is clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 6 tool updatesv0.1.0
    • First observedkura_doctor
    • First observedkura_list
    • First observedkura_map
    • First observedkura_read
    • First observedkura_recall
    • First observedkura_use

TDQS

A4.3/5.0

Scored across 6 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: reading a specific memory, recalling by meaning, viewing the index, health checking, listing available kuras, and switching the active kura. There is no overlap or ambiguity between them.

Naming Consistency5/5

All tools follow a consistent pattern: a 'kura_' prefix followed by a lowercase verb (read, recall, map, doctor, list, use). The naming is uniform, predictable, and readable.

Tool Count5/5

Six tools is well-scoped for a memory management server. Each tool covers an essential operation without redundancy, fitting the typical ideal range of 3-15 tools.

Completeness4/5

The set covers all core retrieval and management operations: listing, switching, recalling, reading, mapping, and health checking. It could benefit from a write/update operation, but the server appears intentionally read-focused, so the surface is nearly complete for its stated purpose.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Provides AI agents with persistent, searchable memory that survives across conversations using semantic search, temporal versioning, and smart organization. Enables long-term context retention and cross-session continuity for AI assistants.
    14
    -
  • A
    license
    A
    quality
    D
    maintenance
    Provides persistent long-term memory for AI agents through semantic search and automated knowledge graph extraction. It enables agents to store, recall, and reason over facts, preferences, and relationships across multiple conversations and sessions.
    14
    7 npm
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI agents to store, search, and recall semantic memories with three memory types (semantic, episodic, procedural) and auto-consolidation, compounding intelligence over time.
    7 npm
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    Provides long-term memory for agents with meaning-based recall, evidence-gated writing, and separate stores per agent mode.
    6
    MIT