Waggle-mcp
なぜwaggle-mcpなのか?
ほとんどのLLMは会話が終わるとすべてを忘れてしまいます。
waggle-mcpは、MCP互換クライアントを通じて読み書き可能な永続的なナレッジグラフをAIに提供することで、この問題を解決します。
Waggleの主な利点は、構造化されたコンテキストによるトークンの効率化です:
waggle-mcpなし | waggle-mcpあり |
200kトークンのプロンプトにコンテキストを詰め込む | 約4分の1のトークン数 — コンパクトなサブグラフ、関連するノードのみを取得 |
「DBスキーマについて何を決めたっけ?」 → ❌ セッション終了時に消失 | ✅ 決定ノード、決定時期、矛盾する内容を想起 |
フラットな箇条書きメモリ | 型付きエッジ: |
1セッション、1エージェント | マルチテナント、マルチセッション、マルチエージェント |
取得に関する注意: Waggleは、生の想起範囲を犠牲にする代わりに、トークンコストを劇的に下げ、リレーショナルコンテキストを豊かにします。正確な数値についてはベンチマークセクションを参照してください。
クイックスタート — 30秒
pip install waggle-mcp
waggle-mcp initinitウィザードがMCPクライアントを検出し、設定ファイルを書き込み、データベースディレクトリを作成します。JSONの編集は不要です。Claude Desktop、Cursor、Codex、および汎用JSONフォールバックをサポートしています。
初期化後、MCPクライアントを再起動すれば、AIは永続的なメモリを持つようになります。 クラウドサービス不要。APIキー不要。セマンティック検索は完全にローカルで実行されます。
動作の様子
AIを日常的に使用する開発者の具体的なビフォー/アフターです:
セッション1 — 4月10日
User: Let's use PostgreSQL. MySQL replication has been painful.
Agent: [calls observe_conversation()]
→ stores decision node: "Chose PostgreSQL over MySQL"
→ stores reason node: "MySQL replication painful"
→ links them with a depends_on edgeセッション2 — 4月12日(新しいコンテキストウィンドウ、履歴なし)
User: What did we decide about the database?
Agent: [calls query_graph("database decision")]
→ retrieves the decision node + linked reason from April 10
"You decided on PostgreSQL on April 10. The reason recorded was
that MySQL replication had been painful."セッション3 — 4月14日
User: Actually, let's reconsider — the team is more familiar with MySQL.
Agent: [calls store_node() + store_edge(new_node → old_node, "contradicts")]
→ conflict is flagged automatically; both positions are preserved in the graphエージェントは、記憶や取得のために明示的な指示を必要としませんでした。会話に基づいて適切なツールを呼び出し、グラフが適切なコンテキストを提供しました。
仕組み
メモリは単に保存されるだけでなく、ライフサイクルを通じて流れます:
You talk to your AI
│
▼
observe_conversation() ← AI drops the turn in; facts extracted via structured LLM (regex fallback)
│
▼
Graph nodes are created ← "Chose PostgreSQL" becomes a decision node
Edges are inferred ← linked to the "database" entity node
│
▼
Future conversation starts
│
▼
query_graph("DB schema") ← semantic search finds the node from 3 sessions ago
│
▼
AI answers with full context ← "You decided on PostgreSQL on Apr 10, here's why…"すべてのノードは、all-MiniLM-L6-v2を使用してローカルで計算されたセマンティック埋め込みを持ちます。これは、APIキーやネットワーク呼び出しを必要とせず、デバイス上で完全に動作する高速で軽量なモデルです。つまり、セマンティック検索はオフラインで動作し、クエリごとのコストはゼロで、データをプライベートに保ちます。
魔法のツール: observe_conversation
これが最もよく使うツールです。 事実を手動で保存する必要はありません。エージェントに会話の各ターンを観察するように指示するだけで、残りは自動的に処理されます。
observe_conversation(user_message, assistant_response)内部的には以下の処理を行います:
会話の両側から原子的な事実を抽出する
セマンティック類似性を使用して既存のノードとの重複を排除する
関連する概念間に型付きエッジを作成する
既存の保存された信念との矛盾にフラグを立てる
指示は不要。スキーマ定義も不要。ただ観察するだけです。
内部的には、すべての呼び出しでPydanticで検証されたLLM抽出パス(正規表現フォールバック付き)が実行され、雑多な対話から構造化された事実を抽出します。
例: "MySQLのレプリケーションは面倒すぎるから、PostgreSQLを使おう。"
{
"facts": [
{
"label": "PostgreSQL for generic events",
"content": "Chose PostgreSQL over MySQL because MySQL replication is too painful.",
"node_type": "decision",
"confidence": 0.95,
"tags": ["llm-extracted", "confidence:0.95"]
}
]
}confidence < 0.5の抽出や無効なスキーマは、ハルシネーション(幻覚)ノイズを防ぐために黙って破棄されます。
メモリモデル
ノードタイプ — 保存されるもの:
タイプ | 例 |
| "APIはJWTトークンを使用する" |
| "ユーザーはダークモードを好む" |
| "MySQLではなくPostgreSQLを選択" |
| "プロジェクト: waggle-mcp" |
| "レート制限" |
| "GraphQLを追加すべきか?" |
| "TODO: 統合テストを追加" |
エッジタイプ — ノードの接続方法:
relates_to · contradicts · depends_on · part_of · updates · derived_from · similar_to
MCPツール
AIがこれらを直接呼び出します。手動で使用する必要はありません。
ツール | 内容 |
| 会話のターンを入力 — 事実を抽出、保存、リンク |
| グラフ全体に対するセマンティックおよび時間的検索 |
| 事実、好み、決定、メモを手動で保存 |
| 2つのノードを型付き関係でリンク |
| 特定のノードからエッジを辿る |
| 既存ノードのコンテンツやタグを更新 |
| ノードとそのすべてのエッジを削除 |
| 長いコンテンツを自動的に原子的なノードに分解 |
| 過去N時間に何が変更されたかを確認 |
| 新しい会話のためのコンパクトな概要を生成 |
| コミュニティ検出によるトピッククラスターの検出 |
| ノード/エッジ数および最も接続されたノード |
| インタラクティブなブラウザ可視化 |
| ポータブルなJSONバックアップ |
| JSONバックアップからの復元 |
パフォーマンスとベンチマーク
以下のすべての数値は、scripts/benchmark_extraction.pyのハーネスを使用してbenchmarks/fixtures/内のフィクスチャから再現可能です。保存された出力アーティファクトはtests/artifacts/にあります。
1つのコマンドで以下のすべてのテーブルが生成されます(抽出正規表現ベースライン、取得、重複排除、および比較トークン効率パイロット):
PYTHONPATH=src .venv/bin/python scripts/benchmark_extraction.py \
--extraction-backend regex \
--systems waggle rag_naive \
--output tests/artifacts/benchmark_current.jsonLLM抽出行(75%)はローカルのOllamaインスタンスでの個別の実行が必要であり、benchmark_current.jsonには含まれていません:
# Requires Ollama running locally with qwen2.5:7b pulled
PYTHONPATH=src .venv/bin/python scripts/benchmark_extraction.py \
--extraction-backend llm --ollama-model qwen2.5:7b --ollama-timeout-seconds 30抽出精度
コーパス:単純な想起、中断、逆転、曖昧な発言、矛盾する信号をカバーする12の対話ペア(benchmarks/fixtures/extraction_cases.json)。
バックエンド | ケース | 精度 |
正規表現 (フォールバック) | 12 | 33% |
LLM ( | 12 | 75% |
取得精度
コーパス:18ノード、18クエリ — 6つの簡単(直接的な言い換え)と12の難しい(敵対的:セマンティック一般化、時間的曖昧性解消、間接的なドメイン翻訳、プライバシーフレーミング)。ソース:benchmarks/fixtures/retrieval_cases.json。
難易度 | クエリ | Hit@k |
簡単 | 6 | 6/6 = 100% |
難しい (敵対的) | 12 | 9/12 = 75% |
全体 | 18 | 15/18 = 83% |
トークン効率 vs. 単純なチャンク化ベクトルRAG
上記の取得精度テーブルはWaggleのスタンドアロン検索品質を測定しています。以下の比較は、チャンク化ベクトルベースラインに対するトークン効率をテストするために設計された別のマルチセッションコーパスを使用しています。
コーパス:24のマルチセッションシナリオ、7つのタスクファミリーにわたる66の取得クエリ(benchmarks/fixtures/comparative_eval.json)。
タスクファミリー | クエリ | Waggle Hit@k | RAG Hit@k |
| 18 | 18/18 = 100% | 100% |
| 19 | 17/19 = 89% | 100% |
| 11 | 10/11 = 91% | 100% |
| 8 | 8/8 = 100% | 100% |
| 4 (小規模) | 4/4 = 100% | 100% |
| 4 (小規模) | 2/4 = 50% | 100% |
| 2 (小規模) | 1/2 = 50% | 100% |
全体 | 66 | 60/66 = 91% | 100% |
システム | 平均トークン | 中央値トークン | p95トークン | Hit@k | 正確なサポート |
Waggle | 36.9 | 37.0 | 42.0 | 91% | 74% |
単純なチャンク化ベクトルRAG | 152.8 | 155.0 | 162.8 | 100% | 100% |
Waggleは、このコーパスにおいて単純なチャンク化ベースラインよりも約4倍少ないトークンを使用します。
WaggleのHit@k(91%)と正確なサポート(74%)の間のギャップは、グラフ取得が正しいトピックを見つけるものの、十分な裏付け詳細を返さない場合があることを示しています。これはcross_scenario_synthesisクエリで最も顕著です(8/8ヒット、1/8正確)。コンテキストアセンブリの改善(特にエッジトラバーサルの深さとマルチホップサブグラフ展開)が次のステップとして追跡されています。
トレードオフは正直です:チャンク化ベースラインは、top_k=5においてすべての事実が自身のセッションチャンクから取得可能であるため、このコーパスで100%のHit@kを達成します。トークン効率の利点は本物であり再現可能です。取得の優位性の主張には、チャンクのカバー範囲が欠落したリレーショナルコンテキストを補えないコーパスが必要です。コーパスの強化は進行中です。
抽出が失敗した場合
ユーザー: 「そうだな、例の話のやつをやっておこう。」
LLMは曖昧な入力に対して低い信頼度(confidence < 0.5)を割り当てます。Waggleは推測を保存するのではなく、抽出を黙って破棄します。パイプラインはタイムアウト時に黙って正規表現にフォールバックすることはありません。バックエンドの失敗は、ログに記録される明示的なエラーとして表面化します。
コーパス:22のノードペア — 11の真の重複(同義語、言い換え、ドメイン等価性)と11の偽の友人(同じ技術カテゴリ、異なる技術)。ソース:benchmarks/fixtures/dedup_cases.json。
パイプラインは5つのレイヤーを実行します:
レイヤー0 — エンティティキーのハードブロック — 両方のノードが同じカテゴリで異なる技術を指名している場合(例:
postgresqlvsmysql)、マージは無条件にブロックされます。レイヤー0b — 数値競合ガード — 同じエンティティだが異なる重要な数値(例:
jwt15分 vs 1時間) → ブロック。同じ技術を共有しているがキー値が異なる別個の事実をマージするのを防ぎます。レイヤー1 — 完全な文字列一致 — 正規化されたコンテンツまたはラベルの等価性。
レイヤー2 — 部分文字列包含 — 一方の文がもう一方の厳密なサブセットである場合。
レイヤー3 — セマンティック類似性 —
all-MiniLM-L6-v2によるコサイン類似度:同一エンティティの積極的パス:両方が同じエンティティトークンを参照している場合、コサイン類似度≥ 0.60でマージ(「fastapiが選ばれた」/「非同期のためfastapiを選んだ」のような言い換えの真の重複をキャッチ)
型認識しきい値:
decision/preference→ 0.82;fact→ 0.92;entity→ 0.97Jaccardブーストパス:単語の重複≥ 0.35 かつ コサイン類似度≥ (型しきい値 − 0.05)
保守的なグローバルフォールバック
測定結果:しきい値0.82で18/22 = 82%。すべてのしきい値でfp=0 — テストされたどのしきい値でも偽の友人のマージはありませんでした。
残りの4つの偽陰性は、認識可能なエンティティアンカーのない純粋な言い換えペアです(「ユーザーはダークモードを好む」/「ユーザーはダークモードUIを望む」、「非同期は譲
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/Abhigyan-Shekhar/Waggle-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server