mcpField
F
ForkMind

ForkMind

ローカル
medhovarsh.github.ioAI・エージェント311 週間前に更新

ForkMind について

ForkMindは、LLM呼び出しを会話グラフとして記録・確認するローカルファーストのツールです。開発者やエージェント構築者向けに、実行の分岐、比較、再生、回帰テストを提供し、データをローカルに保存します。

主な機能

  1. 01LLM呼び出しをローカルJSONに記録
  2. 02会話履歴をDAGで可視化
  3. 03実行の分岐・比較・再生
  4. 04新しいノードをダッシュボードに配信
  5. 05出力と軌跡の回帰テスト
  6. 06暗号化コンテキストカプセルの保存

活用シーン

  1. 01エージェントの過去の試行を追跡
  2. 02プロンプト・応答・トークン使用量を比較
  3. 03プロンプト編集後に会話を再生
  4. 04CIで出力や経路の変化を検出

MCP 対応

MCPサーバーを備え、エージェントがローカルの`.forkmind/`履歴を照会できます。過去の試行や、現在の状態に至った経緯を確認できます。

設定

ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。

mcp.json · 共通設定
{
"mcpServers": {
"forkmind": {
"command": "npx",
"args": [
"-y",
"forkmind"
]
}
}
}
起動コマンドnpx -y forkmind

ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。

パッケージ
npmforkmind0.9.0

ツール

15

掲載時のツール一覧 · 3 週間前に更新

パラメーター型必須説明
limitintegerいいえ

詳細

ForkMind 🧠

ローカルファーストの LLM 分岐、デバッグ、コンテキストのオフロード

AI との会話履歴を Git リポジトリのように扱えます。すべての呼び出しを記録し、任意のターンから分岐して、結果を並べて差分を確認できます。すべてお使いのマシン上で完結します。

npm License: MIT CI Node MCP Live site

10 秒で試す · 機能 · インストール · クイックスタート · MCP · カプセル

ForkMind のデモ — 会話 DAG の移動、ノードの確認、2 つの分岐の差分を並べて表示

表示されている内容: デバッグターンから分岐した会話 DAG、 ノードインスペクター(リクエスト/レスポンス、トークン、来歴)、そして ⇄ Compare ビューで、2 つの分岐の差分をトークンごとに確認できます。緑色の ● streaming バッジは、記録と同時にノードが表示されるライブキャプチャを示しています。

ForkMind はすべての LLM 呼び出しをローカルの .forkmind/ ディレクトリに記録し、 会話を有向非巡回グラフ(DAG)として可視化します。履歴の任意の時点から分岐、 差分の確認、再生ができます。OpenAI 互換 API であれば何でも利用でき、 Ollama 経由の無料のオープンソースモデルがデフォルトです。 Anthropic、Groq、OpenRouter、Together、vLLM、LM Studio にも対応しています。

静的スクリーンショット

ForkMind のダッシュボード — 分岐、ストリームバッジ、ノードインスペクターを備えた会話 DAG


なぜ ForkMind なのか

エージェント型のワークフローやツール呼び出しのデバッグでは、わずかな変更を加えて同じプロンプトを何度も実行し、何が変わったのかを確認するためにターミナルのログをスクロールする必要があります。ForkMind は各実行を会話ツリーのノードとして記録するため、ログを読み返す代わりに、履歴全体を確認し、任意のターンから分岐して、結果を視覚的に比較できます。

すべてディスク上のプレーンな JSON です。データベースもアカウントもテレメトリーも不要です。すでに実行している LLM 呼び出し以外に、お使いのマシンから外部へ送信されるものはありません。


機能

  • キャプチャ — すべての LLM 呼び出しを、.forkmind/ 配下のプレーンな JSON ノードに記録します。 OpenAI 互換プロキシを介してあらゆる言語から利用でき、ストリーミング応答も再構成されます(テキストと断片化されたツール呼び出しの引数)。
  • DAG ダッシュボード — React Flow のキャンバスに、会話全体をツリーとして描画します。各ターン、ツール呼び出し、モデル、トークン数を表示し、ワンクリックでノードインスペクターを開けます。
  • ライブキャプチャストリーム — 記録されたノードがすぐに DAG に表示されます(Server-Sent Events)。エージェントの思考をリアルタイムで確認できます。
  • 分岐 — 過去の任意のターンから分岐できます。プロンプトを編集するかモデルを切り替えて再実行すると、元のターンにリンクされた分岐として表示されます。
  • ⇄ 比較 — 任意の 2 つのノードを選び、プロンプトと応答を単語単位で並べて差分比較できます。フィールドごとの差分を含むトークン使用量の表も表示します。「LLM 出力の Git diff」です。
  • ⏪ タイムトラベル再生 — 編集したノードからチェーン全体を再実行できます。再生成されたターンは兄弟分岐に記録され、元のユーザーターンとツールの結果は順番どおりに再適用されます。
  • MCP サーバー — エージェントはタスクの途中で自身の .forkmind/ 履歴を検索できます(試したことを思い出す、目的地にたどり着いた経緯をたどる、自己修正する)。
  • 回帰テスト — 正常な出力をベースラインとして固定し、プロンプトやモデルを変更した後に再実行して、無料のオフラインチェック(包含/正規表現/類似度)、ツール呼び出しのアサーション、または独自のルーブリックに基づいて採点するオプトインの LLM ジャッジで変化を検出できます。CI に対応しています。
  • 軌跡の回帰テスト — キャプチャしたグラフから複数ターンにわたるエージェントの経路全体を固定して再生できます。最終回答に問題がなく見える場合でも、実行途中でエージェントの経路を変えるプロンプト変更を検出できます。
  • コンテキストカプセル — コンテキストを暗号化された不変の DAG カプセルに退避できます。すべて、またはセグメントごとに復元でき、複製(RAID)、エクスポート/インポート、暗号学的消去にも対応します。
  • forkmind demo — 1 つのコマンドで、サンプル DAG が事前に読み込まれたダッシュボードを開きます。セットアップも API キーも不要です。

10 秒で試す

npx forkmind demo

API キーもセットアップも不要です。事前に読み込まれた会話 DAG がダッシュボードに表示されます。コーディングエージェントのデバッグセッションが、失敗した修正と成功した修正に分岐し、さらにアーカイブ済みのコンテキストカプセルも含まれています。すべて使い捨ての一時ディレクトリに保存されるため、プロジェクトには一切触れません。ローカルで Ollama が起動していれば、ここから分岐を選んでローカルモデルで実際に動作させられます。

起動したら、次を試してください。

  • ⇄ 比較 任意の 2 つのノードを選び、プロンプト、応答、トークン使用量を単語単位で並べて差分比較できます。「LLM 出力の git diff」です。
  • ⏪ ここから再生 編集したノードからチェーン全体を再実行できます。再生成されたターンは兄弟分岐に記録されます。
  • ライブキャプチャ — 記録されたノードがすぐに DAG に表示されるため、エージェントの思考をリアルタイムで確認できます。

インストール

# Run without installing (published on npm)
npx forkmind init
npx forkmind start

# …or install the CLI globally
npm install -g forkmind
forkmind start

npm レジストリも不要です。ForkMind は Git リンクから直接実行でき、インストール時にダッシュボードも自動的にビルドされます。

# Run without installing, from GitHub
npx github:medhovarsh/forkmind init
npx github:medhovarsh/forkmind start

# …or clone to hack on it
git clone https://github.com/medhovarsh/forkmind
cd forkmind && npm install
Claude Code プラグインとしてインストール

ForkMind には Claude Code プラグイン(スキル + /forkmind コマンド)が含まれており、Claude が ForkMind をいつ、どのように使うかを認識できます。他のマーケットプレイスプラグインと同じ手順でインストールできます。

/plugin marketplace add Medhovarsh/forkmind
/plugin install forkmind

プラグインには次のものが含まれます。

  • forkmind スキル — プロンプトのデバッグ、モデルの比較、過去のターンからの分岐、呼び出しの回帰テストを頼むと、Claude は ForkMind を使います。
  • /forkmind コマンド — 必要に応じて、開始/分岐/テスト/MCP を実行します。
  • forkmind-debugger エージェント — 分離されたコンテキストでモデル/プロンプトの比較を実行し、トランスクリプトを大量に出力する代わりに、簡潔な判定を返します。
  • MCP サーバー、自動接続 — エージェントは手動設定なしで自身の .forkmind/ 履歴を検索できます(試したことを思い出す、系譜をたどる、自己修正する)。

プロキシとダッシュボードを実行するのは引き続き CLI です。プラグインは Claude にその使い方を教えるための連携役です。

クイックスタート(無料、API キー不要)

# 1. Install a free local model
#    (install Ollama from https://ollama.com first)
ollama pull llama3

# 2. Init + start ForkMind
npx github:medhovarsh/forkmind init    # create .forkmind/ in your project
npx github:medhovarsh/forkmind start   # proxy on http://localhost:4500 + dashboard

# 3. Point your code at the proxy (see SDK below), make some calls

# 4. Open the dashboard
open http://localhost:4500
ドロップイン SDK(ツリーを自動構築)
npm i openai            # the wrapper extends the official SDK
const { ForkMindOpenAI } = require('forkmind');

const client = new ForkMindOpenAI({
  apiKey: 'ollama',                       // ignored by Ollama; required by SDK
  upstream: 'http://localhost:11434',     // free local open-source models
});

// Each call is recorded; sequential calls auto-chain into a conversation tree.
const res = await client.chat.completions.create({
  model: 'llama3',
  messages: [{ role: 'user', content: 'Explain backpropagation simply.' }],
});

サンプル全体を実行します。

node examples/chain.js
あらゆる言語 — クライアントをプロキシに向ける

SDK ラッパーは便利ですが、必須ではありません。ForkMind のプロキシは OpenAI 互換のワイヤープロトコルを使用するため、あらゆる言語からキャプチャできます。クライアントの ベース URL を http://localhost:4500/v1 に設定すれば、記録が開始されます。前の レスポンスの x-forkmind-node-id を次のリクエストの x-forkmind-parent ヘッダーとして渡すことで、 ターンをツリーに連結できます(JS ラッパーがこれを自動化します)。

# Python — official openai client, zero ForkMind code
from openai import OpenAI

client = OpenAI(base_url="http://localhost:4500/v1", api_key="ollama")
res = client.chat.completions.create(
    model="llama3",
    messages=[{"role": "user", "content": "Explain backpropagation simply."}],
    extra_headers={"x-forkmind-upstream": "http://localhost:11434"},
)
# read res via .with_raw_response to grab x-forkmind-node-id and chain the next call
# curl — anything that can POST JSON
curl http://localhost:4500/v1/chat/completions \
  -H 'content-type: application/json' \
  -H 'x-forkmind-upstream: http://localhost:11434' \
  -d '{"model":"llama3","messages":[{"role":"user","content":"hi"}]}' -i
# response header `x-forkmind-node-id: <id>` → pass as `x-forkmind-parent` next call

Go、Ruby、Rust、Java でも同じです。ベース URL と 2 つのヘッダーを設定するだけです。ダッシュボード、 分岐、MCP、回帰テストは、ソース言語に関係なくすべて動作します。


フレームワーク連携

ForkMind は、2 大 JS LLM エコシステム向けに薄いアダプターを提供しています。どちらも 同じプロキシを経由するため、キャプチャ、分岐、ダッシュボード、MCP、回帰テストは変更なしで動作します。 モデルクラスの置き換えもコールバックも不要です。

LangChain.js
npm i @langchain/openai @langchain/core
const { ChatOpenAI } = require('@langchain/openai');
const { forkmind } = require('forkmind/langchain');

const fm = forkmind({ upstream: 'http://localhost:11434' }); // free local Ollama
const model = new ChatOpenAI({
  apiKey: 'ollama',
  model: 'llama3',
  configuration: fm.configuration, // baseURL → proxy + chaining fetch
});

await model.invoke('Explain backpropagation simply.');
// sequential calls on `fm` auto-chain; fm.setParent(id) to branch from a node.
Vercel AI SDK
npm i ai @ai-sdk/openai
const { generateText } = require('ai');
const { forkmindOpenAI } = require('forkmind/vercel');

const openai = forkmindOpenAI({ upstream: 'http://localhost:11434' });
const { text } = await generateText({
  model: openai('llama3'),
  prompt: 'Explain backpropagation simply.',
});
// openai.setParent(id) / openai.resetParent() control the branch point.

どちらも FORKMIND_PROXY(プロキシのベース URL)に対応しており、インスタンスごとに明示的な baseURL / upstream を指定できます。


その他の無料/オープンプロバイダーの利用

ForkMind はプロバイダーに依存せず、認証ヘッダーをそのまま転送し、クライアントごとにアップストリームを 設定できます。OpenAI 互換のものなら何でも動作します。

プロバイダーupstreamapiKey
Ollama(ローカル)http://localhost:11434任意の文字列
LM Studio(ローカル)http://localhost:1234任意の文字列
Groq(無料枠)https://api.groq.com/openaigsk_...
OpenRouterhttps://openrouter.ai/apisk-or-...
Togetherhttps://api.together.xyzご自身のキー
OpenAIhttps://api.openai.com(デフォルト)sk-...
new ForkMindOpenAI({ apiKey: process.env.GROQ_API_KEY,
                     upstream: 'https://api.groq.com/openai' });

SDK 経由ではなくプロキシを直接呼び出す場合は、x-forkmind-upstream ヘッダーを使って リクエストごとに上書きすることもできます。

Anthropic(Claude)
npm i @anthropic-ai/sdk
const { ForkMindAnthropic } = require('forkmind');
const client = new ForkMindAnthropic({ apiKey: process.env.ANTHROPIC_API_KEY });
await client.messages.create({ model: 'claude-3-5-sonnet-latest', max_tokens: 512,
                               messages: [{ role: 'user', content: 'hi' }] });

仕組み

your app ──▶ ForkMindOpenAI (baseURL = localhost:4500/v1)
                │  injects x-forkmind-parent
                ▼
         ForkMind proxy (Express, :4500)
                │  forwards verbatim (your key, your upstream)
                ▼
         provider (Ollama / Groq / OpenAI / ...)
                │  response
                ▼
         proxy reconstructs + saveNode()  ──▶  .forkmind/nodes/<id>.json
                │  returns x-forkmind-node-id
                ▼
         wrapper chains it as the next call's parent
  • 決定論的なノード ID。 sha256(request + parentId) → 先頭 12 個の 16 進文字です。 同じ親の下にある同じプロンプトは 1 つのノードに統合されます。ID はレスポンスに依存 しないため、ストリーミングされた本文の完了前でもヘッダーとして返せます。
  • ストリーミング。 バイト列は変更されずにアプリへ渡されます(実際の SSE)。プロキシは それを分岐し、完全なメッセージ(テキストと断片化されたツール呼び出し引数)を再構築して、 ストリーム終了時にノードを保存します。
  • 分岐。 各ノードにはプロバイダーとアップストリームが記録されるため、ダッシュボードの「ここから フォーク」では、編集したリクエストが同じホストに再送され、過去の親にリンクされます。
  • 比較。 任意の 2 つのノードを並べて差分表示できます。単語単位のプロンプト/レスポンスの 変更と、符号付きの差分を含むトークン表を、キャプチャした JSON からクライアント側で計算します (dashboard/src/lib/diff.js)。
  • 再生。 POST /api/replay は、編集したノードから選択したリーフまで、キャプチャ済みの系譜をたどります。 元のユーザーターンとツールの結果をそのまま再適用しながら、変更した履歴に対して各アシスタントターンを 再生成します。新しいチェーンは兄弟ブランチとして保存されます。
  • ライブストリーム。 saveNode はプロセス内バスでイベントを発行します。GET /api/stream は 各新規ノードを SSE 経由でダッシュボードに中継するため、ポーリングなしでキャンバスが更新されます。

MCP — エージェントが自身の履歴を検索できるようにする

ForkMind には MCP サーバーが付属しており、AI エージェントはタスクの途中で自身の .forkmind/ 履歴を読み取り、自己修正できます。すでに試したことを思い出したり、ある状態に至った経緯を確認したり、過去の試行を検索したりできます。

forkmind mcp          # stdio MCP server (or: forkmind-mcp)

Smithery を使ったワンライナーでインストールできます(smithery.yaml で設定済みです)。.forkmind/ を参照できるよう、プロジェクトのルートから実行してください。

npx -y @smithery/cli install forkmind --client claude

…または、任意の MCP クライアント(Claude Desktop/Claude Code/Cursor/Cline)に手動で登録してください。

{
  "mcpServers": {
    "forkmind": {
      "command": "npx",
      "args": ["-y", "github:medhovarsh/forkmind", "mcp"]
    }
  }
}

公開されるツール:

ツール目的
forkmind_recentキャプチャされた最新のターン(簡潔版)
forkmind_get_node1 つのノードのリクエストとレスポンス全体
forkmind_lineageルートからノードまでのパス — 状態を生成した正確なコンテキスト
forkmind_childrenあるノードから分岐した兄弟ブランチ
forkmind_searchすべてのリクエスト/レスポンスを対象とした部分文字列検索
forkmind_statsツリーの合計:ノード、ルート、リーフ、プロバイダー
forkmind_context_saveコンテキストを暗号化された DAG カプセルに退避
forkmind_context_list保存されたカプセルの一覧(タイトル、ダイジェスト、サイズ、経過時間)
forkmind_context_digestダイジェスト + セグメントマップ — 低コストの復元前確認
forkmind_context_restore全体またはセグメント単位で復元し、整合性を検証
forkmind_context_forget元に戻せない暗号消去(ID のエコーが必要)
forkmind_context_replicasレプリカ(RAID)の状態確認、任意で同期
forkmind_context_stats集計統計:件数、バイト数、推定トークン数
forkmind_context_exportパスフレーズで暗号化されたポータブルバンドル
forkmind_context_importバンドルをインポートして再検証し、ローカルで再ラップ

サーバーは作業ディレクトリ内の .forkmind/ を読み取ります。クライアントの cwd をプロジェクトに設定してください。

コンテキストカプセル — コンテキストを暗号化された DAG として退避する

多くのコンテキストマネージャーは、ウィンドウ全体をキャッシュ削除の問題として扱い、切り詰めて失います。ForkMind のカプセルはその考え方を逆転させます。まず永続化し、検証してから、コンパクト化します。カプセルは不変でコンテンツアドレス方式のコンテキストセグメント DAG で、ディスク上では AES-256-GCM で暗号化され、全体または一度に 1 セグメントずつ復元できます。

# Save (items JSON from a file or stdin), get back a 12-char handle
echo '{"title":"auth debug","items":[{"role":"user","content":"..."}]}' \
  | forkmind context save --digest "oauth loop root-caused; fix in token.js"

forkmind context list                 # all capsules, newest first
forkmind context show 9f3ac21b7e04    # decrypt + verify + print
forkmind context verify 9f3ac21b7e04  # DAG integrity: parents, acyclicity, hashes
forkmind context forget 9f3ac21b7e04 --confirm 9f3ac21b7e04   # crypto-shred

同じエンジンを HTTP(POST/GET/DELETE :4500/api/context…)と 5 つの MCP ツール経由で利用できるため、エージェントはタスクの途中で自身のコンテキストをアーカイブし、後から取り戻せます。Claude Code プラグインには、コンテキスト退避の契約を Claude に教える forkmind-archivist スキル + サブエージェントが付属しています。契約は、保存 → ディスク上で検証 → その後に限りウィンドウから削除です。

保証事項:

  • 設計上、不変かつ非巡回 — セグメント ID はコンテンツと親ノードに基づくハッシュです(Git 方式)。循環を作るには、ハッシュ自身を含める必要があります。
  • 保存時に平文なし — カプセルごとの鍵は、.forkmind/ の 外部(~/.forkmind-keys/)に保存されたマスターキーでラップされます。.forkmind/ を誤ってコミットしても、漏れるのは暗号文と構造だけです。
  • ダイジェストは任意 — エージェントは 5 行以内の取得用要約を記述するか、プライベートカプセルでは完全に省略できます。
  • 忘却は確実 — 削除時にまず鍵を破棄して暗号消去し、その後 ID を墓標化するため、同一のコンテンツが再び現れることはありません。
  • モデルには一切触れない — カプセルはクライアントが送信した内容に対して動作します。プロバイダー、重み、KV キャッシュは設計上対象外です。
RAID — 独立 DAG の冗長アレイ

カプセルを任意の数の追加ファイルシステムターゲット(2 台目のディスク、同期フォルダー、ネットワークマウント)にミラーリングします。レプリカに保存されるのは 暗号文 + マニフェストのみで、キーは複製されません。プライマリコピーが失われたり、ビットロットが発生したりした場合、検証に合格した最初のレプリカから復元して自己修復します。修復されたコピーに信頼の近道は適用されず、完全な整合性チェックが引き続き実行されます。

forkmind context replicas add D:\backup\forkmind   # add target + sync
forkmind context replicas list                     # coverage per target
forkmind context replicas sync                     # catch up offline targets,
                                                   # propagate tombstones

忘却はすべてのコピーに及びます。アクセス可能なレプリカはすぐに消去されます。オフラインだったレプリカでは、次回の sync 時に古い暗号文が削除されます(トゥームストーンの伝播)。忘却時にカプセルキーは破棄されているため、そもそも読み取り不能でした。トゥームストーンによって、修復時に忘却されたものが復活することもありません。

ポータブルなエクスポート/インポート

カプセルを別のマシンやプロジェクトに移動できます。このプロジェクトの ~/.forkmind-keys/ マスターキーを共有していないノートパソコン、チームメイト、コールドストレージなどが対象です。

forkmind context export 9f3ac21b7e04 --passphrase "correct horse battery staple" --out capsule.json
# ... move capsule.json anywhere ...
forkmind context import capsule.json --passphrase "correct horse battery staple"

バンドルには、独自の scrypt 由来のキーマテリアル(N=32768)が含まれます。これは、弱いパスフレーズに対するオフラインの総当たり攻撃を防ぐため、意図的に処理を遅くしています。ソースマシンのマスターキーには依存せず、パスフレーズがバンドル自体に書き込まれることもありません。インポート時には、セグメントごとに再検証(ID の再計算、ハッシュの再計算、親の解決、循環のない DFS)を行い、ディスクに何かを書き込む前にすべてを確認します。バンドルを盲目的に信頼することはなく、正当性が証明されたものだけを扱います。インポートは冪等で、新規保存時と同様にトゥームストーンを尊重します。

キャプチャ DAG から直接アーカイブ

2 つの仕組みが連携します。プロキシがキャプチャした会話は、手作業で JSON を組み立てることなく、1 回の操作でカプセルにアーカイブでき、後からプロバイダー向けの messages[] 配列として復元して、次のリクエストにそのまま挿入できます。

# archive the whole lineage ending at a captured turn
forkmind context save --from-node a1b2c3d4e5f6 --digest "auth debug, resolved"

# restore as chat messages (or GET /api/context/:id/messages)
forkmind context show 9f3ac21b7e04 --messages

MCP 経由でも同様です。forkmind_context_save { fromNodeId } と forkmind_context_restore { asMessages: true } を使えば、エージェントはタスクの途中で自分がキャプチャした履歴をアーカイブし、必要なときにいつでも挿入し直せます。カプセルには、ターン DAG に戻る sourceNodeIds リンクが保持されます。

トークンの節約

forkmind context save と forkmind context stats は、コンテキストウィンドウから解放されたトークン数の推定値(標準的な概算値である ~4 bytes/token)を報告します。これにより、カプセルによって実際にどれだけ節約できたかを具体的な数値で確認できます。

回帰テスト — 良好な出力を固定し、劣化を検出

システムプロンプトを調整したり、モデルを入れ替えたりすると、結果が気付かないうちに劣化することがあります。ForkMind では、良好であることが分かっているキャプチャ済みノードをベースラインとして固定し、後から同じリクエストを再実行して、新しい出力に逸脱がないか確認できます。

# 1. Pin a good node (grab its id from the dashboard or forkmind_recent)
forkmind regression pin a1b2c3d4e5f6 \
  --name octopus-fact \
  --contains "hearts" \
  --regex "blue|copper" \
  --min-similarity 0.5

# 2. List / remove cases
forkmind regression list
forkmind regression remove octopus-fact

# 3. Re-run after changing prompts/models (exit code 1 if any case fails — CI-ready)
forkmind regression run                 # keyless local (Ollama)
forkmind regression run --key $GROQ_API_KEY --upstream https://api.groq.com/openai
機械的なチェック — 無料、オフライン、決定論的
  • contains — 出現しなければならない部分文字列
  • not-contains — 出現してはならない部分文字列
  • regex — 一致しなければならないパターン
  • min-similarity — ベースラインとの Jaccard 単語重複率(逸脱ガード。既定値は 0.3 で、明示的なアサーションがなくても、回答が大きく異なれば失敗します)。LLM の出力は非決定的なので、完全一致よりアサーションを優先してください。

これらはいずれも意味を読み取りません。答えるのは「このテキストはまだあのテキストのように見えるか」であり、「この回答はまだ正しいか」ではありません。contains と regex は正確な代理指標です。必要な事実がなくなれば、毎回検出します。類似度は意図的に低コストな警報です。何かが変わったことを知らせますが、完全に正しい書き換えに対して誤警報を出すこともあります。

ツール呼び出しのチェック — エージェントが言ったことではなく、実際に行ったこと

テキストチェックでは、回答が今も正しく読めるかどうかを確認します。エージェントの場合、それは適切な問いではありません。間違った文章は厄介ですが、間違ったツール呼び出しは誰かのシステムに書き込みます。これらのチェックは呼び出し自体を検証します。構造化データなので、無料で、オフラインで、正確です。

forkmind regression pin a1b2c3d4e5f6 \
  --name refund-flow \
  --tool 'create_ticket:{"priority":"high"}' \  # must call it, with these args
  --not-tool issue_refund \                     # must never call this
  --tools-exact                                 # and must call nothing else
  • --tool name / --tool 'name:{json}' — 呼び出しが含まれている必要があります。 引数はサブセットとして照合されるため、重要なフィールドだけを指定し、残りは無視できます。
  • --not-tool name — 破壊的な操作を防ぐガードです。プロンプトの調整によってエージェントが必要以上に大胆になったとき、最も重要なチェックです。
  • --tools-exact — 呼び出しの不足だけでなく、余分な呼び出しがあった場合も失敗します。 --toolを指定しない場合は、エージェントが何も実行しなかったことを検証します。

OpenAI の tool_calls ブロックでも Anthropic の tool_use ブロックでも同じように動作し、どちらも { name, args } に正規化されます。モデルが不正な引数 JSON を出力した場合、黙って破棄するのではなく、生のテキストを args._raw に含めて報告するため、呼び出しが消えてしまうことなく、アサーションが明確に失敗します。

このチェックが必要な失敗パターンは、**テキストが一言一句同じでも、実行されたアクションが間違っていることです。**すべてのテキストチェックに合格し、類似度スコアが 1.0 でも、エージェントが間違ったアカウントに請求していることがあります。それを検出できるのはツールチェックだけです。

LLM ジャッジ — オプトイン、API 呼び出しが必要、意味を読み取る

表現は変わってもよいものの、内容は変わってはいけないケースでは、評価基準を指定し、モデルにリプレイを照合して採点させます。

forkmind regression pin a1b2c3d4e5f6 \
  --name refund-policy \
  --judge "The answer must state the 30-day window and must not promise an exception." \
  --judge-threshold 0.8 \
  --judge-model gpt-4o          # optional: grade with a stronger model than the case uses

forkmind regression run --judge-key $OPENAI_API_KEY
forkmind regression run --no-judge   # mechanical checks only — free, offline, no API calls

ジャッジには評価基準、承認済みのベースライン、候補が渡され、言い換えを減点せず、間違っている、欠けている、または矛盾している内容だけを減点するよう明示的に指示されます。0-1 のスコアが返され、--judge-threshold(デフォルトは 0.7)を下回ると、そのケースは失敗します。

信頼する前に知っておきたい、重要な特性が 3 つあります。

  • フェイルクローズです。ジャッジでエラーが発生した場合、タイムアウトした場合、または解析できない出力が返された場合、チェックはスキップではなく失敗として記録されます。採点器が壊れていてもゲートが黙って合格するのは、ゲートがないよりも悪いことです。
  • スキップは明示されます。--no-judge を指定した場合もチェックの記録は残り、レポートにはスキップとして表示されるため、スイートが評価基準の適用をひっそりと止めることはありません。
  • **証明ではありません。**ジャッジの判定は非決定的で、記述した評価基準の質に左右されます。単語の一致率より強い指標ですが、正しさを保証するものではありません。

ケースは .forkmind/regressions/ 内の JSON です。ベースラインを共有し、CI でプロンプトの変更をゲートできるよう、コミットしてください。

軌跡の回帰テスト — ターンではなく経路を固定する

ここまでのすべてのテストは1 ターンを対象にしています。エージェントでは、それは適切な単位ではありません。エージェントは実行の途中で失敗します。検索を飛ばしたり、確認前に書き込んだり、プロンプトの調整で経路がまったく変わったりします。そして最終的には、まったく問題のない文章を出力することもあります。最後のメッセージに対するアサーションでは何も検出できません。

ForkMind は実際のトラフィックを親リンク付きの DAG として記録するため、経路全体はすでにそこにあります。それを固定します。

# Pin the path ending at this node (walks up to the root)
forkmind trajectory pin f4e5d6c7b8a9 \
  --name refund-run \
  --sequence exact \                 # same actions, same order
  --not-tool issue_refund \          # never, anywhere in the run
  --tool-order verify_identity,charge_card

forkmind trajectory list
forkmind trajectory run              # exit 1 on any failure — CI-ready

実行全体を通してチェックされる内容:

  • --sequence exact — フラット化されたアクションのシーケンスが、ベースラインと各ステップで一致する必要があります。subsequence では、ベースラインのアクションが順番どおりに出現する限り、追加のアクションが許可されます。none では経路を固定しません。
  • --not-tool — 軌跡のどこであっても、禁止されたアクションを検出します。
  • --tool-order before,after — 順序の制約です。書き込む前に検索したこと。請求する前に確認したこと。
  • --judge — 最終回答に対する任意の評価基準です。上記と同じジャッジを使います。
  • --from <nodeId> — ルートではなく祖先ノードから経路を開始するため、長い実行の中から注目したい末尾だけを固定できます。

**テキストは意図的に制約されません。**言い換えられた出力でも合格します。固定するのは経路だけです。他の人のシステムに影響を及ぼすのが、その部分だからです。

制限事項を率直に説明すると

パスを再生すると、記録済みのツール結果がそのまま再適用されます。ツールがリアルタイムで実行されるわけではありません。これは意図的な仕様です。環境を固定することで、モデルの判断だけを変数にできるためです。ただし、重大な影響があります。エージェントが異なるアクションを実行した時点で、エージェントを待っている記録済みの結果は、エージェントが尋ねてもいない質問への答えになってしまいます。その時点以降はすべて作り話になります。

そのため、実行は最初の分岐点で停止し、正確な場所を報告します。

  ✗ FAIL  refund-run  (2/3 steps)
         path: verify_identity → issue_refund
         ↳ failed divergence: step 2/3: expected [charge_card], got [issue_refund]
           — replay stopped (recorded tool results no longer apply)

この失敗こそ、この機能の要点です。最終メッセージには問題がなかったでしょう。

軌跡は .forkmind/trajectories/ にある JSON です。単一ターンのケースと一緒にコミットしてください。

コストゼロ、ローカル実行

  • 有料 API は不要です — デフォルトでは Ollama 経由の無料ローカルモデルを使用します。
  • データベースは不要です — 各ターンは .forkmind/ 内の通常の JSON ファイルです。
  • アカウント不要、テレメトリーなし — すでに実行している LLM 呼び出し(選択したプロバイダーにそのまま中継されるもの)以外に、マシンの外へ情報が送られることはありません。

.forkmind/ の構成

.forkmind/
├── nodes/
│   ├── a1b2c3d4e5f6.json     # one node per turn
│   └── ...
├── contexts/                 # encrypted context capsules
│   └── 9f3ac21b7e04/
│       ├── manifest.json     # public: DAG shape, hashes, opt-in digest
│       └── seg-<id>.enc      # AES-256-GCM ciphertext per segment
├── tombstones.json           # forgotten capsule ids (never resurrected)
└── manifest.json            # version + root node ids

ノードスキーマ:

{
  "id": "a1b2c3d4e5f6",
  "parentId": null,           // null = root
  "timestamp": "2026-01-01T00:00:00.000Z",
  "request":  { /* the exact request body */ },
  "response": { /* full or stream-reconstructed response */ },
  "meta": { "provider": "openai", "upstream": "http://localhost:11434", "stream": true },
  "children": ["..."]         // child node ids
}

CLI

コマンド内容
forkmind demoセットアップ不要のショーケース:一時ディレクトリ内のサンプル DAG とダッシュボード
forkmind initカレントディレクトリに .forkmind/ を作成
forkmind startプロキシ(:4500)を起動し、ビルド済みの場合はダッシュボードを提供
forkmind mcpエージェント向けに stdio MCP サーバーを起動
forkmind regression pin/list/remove/runベースラインを固定し、再実行してドリフトを検出
forkmind trajectory pin/list/remove/run複数ターンのエージェントパスを固定し、別の経路への振り分けを検出
forkmind context save/list/show/verify/forget暗号化コンテキストカプセル(上記を参照)

環境変数:FORKMIND_PORT、FORKMIND_HOST(デフォルトは 127.0.0.1 — ループバックのみ。LAN 上に公開する場合は、自己責任で 0.0.0.0 を設定してください)、 FORKMIND_OPENAI_UPSTREAM、FORKMIND_ANTHROPIC_UPSTREAM、FORKMIND_PROXY (SDK のターゲットベース URL)、FORKMIND_KEY_DIR(カプセルのマスターキーの保存場所、 デフォルトは ~/.forkmind-keys)。


開発

npm install            # installs proxy + dashboard (npm workspaces)
npm test               # jest: hashing, storage, stream reconstruction, API
npm run dashboard:dev  # vite dev server on :5173, proxies API to :4500
npm run dashboard:build
npm run lint
npm へのリリース

公開は .github/workflows/release.yml によるタグ駆動です(公開権限を持つ NPM_TOKEN リポジトリシークレットが必要です)。

npm version patch        # bumps package.json + tags
git push --follow-tags   # tag push → CI lints, tests, builds dashboard, publishes

prepack によって dashboard/dist が再ビルドされるため、tarball には必ず UI が含まれます。

CONTRIBUTING.md を参照してください。


ロードマップ

  • CLI と決定論的ストレージエンジン
  • ストリーミング対応のプロバイダー非依存プロキシ(OpenAI 互換 + Anthropic)
  • 自動チェーン対応のドロップイン SDK ラッパー
  • React Flow ダッシュボードとブランチ実行
  • MCP 統合 — エージェントが自身の .forkmind/ の履歴を照会できるようにする
  • 自動回帰テスト:「良好」なブランチを固定し、プロンプトの編集時に再実行
  • コンテキストカプセル — コンテキストを暗号化された不変の DAG として退避し、 全体またはセグメント単位で復元、暗号シュレッディングで忘却
  • RAID — 独立 DAG の冗長アレイ:セルフヒーリング復元とトゥームストーンの伝播により、 ファイルシステムのターゲット間でカプセルを複製
  • カプセルのエクスポート/インポート — マシンやプロジェクト間でコンテキストを移動できる、 移植可能なパスフレーズ暗号化バンドル。インポート時に個別に再検証
  • ダッシュボードのカプセルパネル — カプセルの閲覧、DAG セグメントマップの確認、 UI からの整合性検証の実行(設計上、読み取り専用)
  • forkmind demo — API キー不要、セットアップ不要のサンプル DAG とダッシュボード
  • ブランチ差分ビュー — 単語単位のハイライトとトークンごとの差分を備えたノードの並列比較
  • タイムトラベル再生 — 編集したノードからチェーン全体を兄弟ブランチとして再実行
  • ライブキャプチャストリーム — SSE プッシュにより、ノードを DAG にリアルタイムで表示

ライセンス

MIT

コメント

MCP は初めてですか?

プロトコルの概要から最初のサーバーの導入まで、よくある疑問にまとめて答えます。

AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。