graph-tool-call
graph-tool-call
LLMエージェントは数千ものツール定義をコンテキストに収めることができません。 ベクトル検索は類似したツールを見つけますが、それらが属するワークフローを見逃してしまいます。 graph-tool-callはツールグラフを構築し、単なる一致ではなく、適切なチェーンを検索します。
検索なし | graph-tool-call | |
248ツール (K8s API) | 精度 12% | 精度 82% |
1068ツール (GitHubフルAPI) | コンテキストオーバーフロー | Recall@5 78% |
トークン使用量 | 8,192 tok | 1,699 tok (79% ↓) |
qwen3:4b (4-bit) で測定 — 完全なベンチマーク
なぜ必要なのか
LLMエージェントにはツールが必要です。しかし、ツールの数が増えるにつれて、2つの問題が発生します。
コンテキストオーバーフロー — 248個のKubernetes APIエンドポイント = 8,192トークンのツール定義。LLMは処理しきれず、精度は**12%**まで低下します。
ベクトル検索はワークフローを見逃す — 「注文をキャンセルして」と検索すると
cancelOrderが見つかりますが、実際のフローはlistOrders → getOrder → cancelOrder → processRefundです。ベクトル検索は1つのツールしか返しませんが、必要なのはチェーン全体です。
graph-tool-callはこれら両方を解決します。ツール間の関係をグラフとしてモデル化し、ハイブリッド検索(BM25 + グラフ探索 + 埋め込み + MCPアノテーション)を通じてマルチステップのワークフローを検索し、精度を維持または向上させながらトークン使用量を64〜91%削減します。
シナリオ | ベクトルのみ | graph-tool-call |
「注文をキャンセルして」 |
|
|
「ファイルを読み込んで保存して」 |
|
|
「古いレコードを削除して」 | 「削除」に一致するツールを返す | MCPアノテーションにより破壊的ツールを優先 |
「今すぐキャンセルして」 (リスト取得後) | 履歴からのコンテキストなし | 使用済みツールを降格、次のステップのツールを昇格 |
ツールが重複する複数のSwagger仕様 | 結果に重複ツールが含まれる | ソース間での自動重複排除 |
1,200個のAPIエンドポイント | 低速でノイズの多い結果 | カテゴライズ + グラフ探索による正確な検索 |
仕組み
OpenAPI / MCP / Python functions → Ingest → Build tool graph → Hybrid retrieve → Agent例 — ユーザーが「注文をキャンセルして返金処理をして」と言った場合
ベクトル検索は cancelOrder を見つけます。しかし、実際のワークフローは以下の通りです:
┌──────────┐
PRECEDES │listOrders│ PRECEDES
┌─────────┤ ├──────────┐
▼ └──────────┘ ▼
┌──────────┐ ┌───────────┐
│ getOrder │ │cancelOrder│
└──────────┘ └─────┬─────┘
│ COMPLEMENTARY
▼
┌──────────────┐
│processRefund │
└──────────────┘graph-tool-callは、単一のツールではなくチェーン全体を返します。検索は加重相互ランク融合 (wRRF) を通じて4つのシグナルを組み合わせます:
BM25 — キーワードマッチング
グラフ探索 — 関係ベースの拡張 (PRECEDES, REQUIRES, COMPLEMENTARY)
埋め込み類似度 — セマンティック検索 (オプション、任意のプロバイダー)
MCPアノテーション — 読み取り専用 / 破壊的 / 冪等性のヒント
インストール
コアパッケージは依存関係ゼロで、Python標準ライブラリのみを使用します。必要なものだけをインストールしてください:
pip install graph-tool-call # core (BM25 + graph) — no dependencies
pip install graph-tool-call[embedding] # + embedding, cross-encoder reranker
pip install graph-tool-call[openapi] # + YAML support for OpenAPI specs
pip install graph-tool-call[mcp] # + MCP server / proxy mode
pip install graph-tool-call[all] # everything追加機能 | インストール内容 | 用途 |
| pyyaml | YAML OpenAPI仕様 |
| numpy | セマンティック検索 (Ollama/OpenAI/vLLMに接続) |
| numpy, sentence-transformers | ローカルのsentence-transformersモデル |
| rapidfuzz | 重複検出 |
| langchain-core | LangChain統合 |
| pyvis, networkx | HTMLグラフエクスポート, GraphML |
| dash, dash-cytoscape | インタラクティブダッシュボード |
| ai-api-lint | 不適切なAPI仕様の自動修正 |
| mcp | MCPサーバー / プロキシモード |
クイックスタート
30秒で試す (インストール不要)
uvx graph-tool-call search "user authentication" \
--source https://petstore.swagger.io/v2/swagger.jsonQuery: "user authentication"
Source: https://petstore.swagger.io/v2/swagger.json (19 tools)
Results (5):
1. getUserByName — Get user by user name
2. deleteUser — Delete user
3. createUser — Create user
4. loginUser — Logs user into the system
5. updateUser — Updated userPython API
from graph_tool_call import ToolGraph
# Build a tool graph from the official Petstore API
tg = ToolGraph.from_url(
"https://petstore3.swagger.io/api/v3/openapi.json",
cache="petstore.json",
)
print(tg)
# → ToolGraph(tools=19, nodes=22, edges=100)
# Search for tools
tools = tg.retrieve("create a new pet", top_k=5)
for t in tools:
print(f"{t.name}: {t.description}")
# Search with workflow guidance
results = tg.retrieve_with_scores("process an order", top_k=5)
for r in results:
print(f"{r.tool.name} [{r.confidence}]")
for rel in r.relations:
print(f" → {rel.hint}")
# Execute an OpenAPI tool directly
result = tg.execute(
"addPet", {"name": "Buddy", "status": "available"},
base_url="https://petstore3.swagger.io/api/v3",
)ワークフロー計画
plan_workflow()は、前提条件を含む順序付けられた実行チェーンを返し、エージェントのラウンドトリップを3〜4回から1回に削減します。
plan = tg.plan_workflow("process a refund")
for step in plan.steps:
print(f"{step.order}. {step.tool.name} — {step.reason}")
# 1. getOrder — prerequisite for requestRefund
# 2. requestRefund — primary action
plan.save("refund_workflow.json")ワークフローの編集、パラメータ化、可視化については、Direct APIガイドを参照してください。
その他のツールソース
# From an MCP server (HTTP JSON-RPC tools/list)
tg.ingest_mcp_server("https://mcp.example.com/mcp")
# From an MCP tool list (annotations preserved)
tg.ingest_mcp_tools(mcp_tools, server_name="filesystem")
# From Python callables (type hints + docstrings)
tg.ingest_functions([read_file, write_file])MCPアノテーション (readOnlyHint, destructiveHint, idempotentHint, openWorldHint) は検索シグナルとして使用されます。クエリの意図は自動的に分類され、読み取りクエリは読み取り専用ツールを優先し、削除クエリは破壊的ツールを優先します。
統合方法の選択
graph-tool-callはいくつかの統合パターンを提供しています。スタックに合ったものを選んでください:
使用環境 | パターン | トークン削減効果 | ガイド |
Claude Code / Cursor / Windsurf | MCPプロキシ (N個のMCPサーバーを3つのメタツールに集約) | ~1,200 tok/turn | |
MCP互換クライアント | MCPサーバー (単一ソースをMCPとして) | 可変 | |
LangChain / LangGraph (50+ツール) | ゲートウェイツール (N個のツールを2つのメタツールに) | 92% | |
OpenAI / Anthropic SDK (既存コード) | ミドルウェア (1行のモンキーパッチ) | 76–91% | |
検索の直接制御 | Python API ( | 可変 |
MCPプロキシ (最も一般的)
多くのMCPサーバーがある場合、ツール名がすべてのLLMターンで蓄積されます。それらを1つのサーバーの背後にバンドルします:172ツール → 3メタツール。
# 1. Create ~/backends.json listing your MCP servers
# 2. Register the proxy with Claude Code
claude mcp add -s user tool-proxy -- \
uvx "graph-tool-call[mcp]" proxy --config ~/backends.json完全なセットアップ、パススルーモード、リモートトランスポートについては → MCPプロキシガイドを参照してください。
LangChainゲートウェイ
from graph_tool_call.langchain import create_gateway_tools
# 62 tools from Slack, GitHub, Jira, MS365...
gateway = create_gateway_tools(all_tools, top_k=10)
# → [search_tools, call_tool] — only 2 tools in context
agent = create_react_agent(model=llm, tools=gateway)62個すべてのツールをバインドする場合と比較して92%のトークン削減。自動フィルタリングと手動パターンの詳細についてはLangChainガイドを参照してください。
SDKミドルウェア
from graph_tool_call.middleware import patch_openai
patch_openai(client, graph=tg, top_k=5) # ← add this one line
# Existing code unchanged — 248 tools go in, only 5 relevant ones are sent
response = client.chat.completions.create(
model="gpt-4o",
tools=all_248_tools,
messages=messages,
)patch_anthropicを使用してAnthropicでも動作します。詳細はミドルウェアガイドを参照してください。
ベンチマーク
2つの疑問:(1) 検索されたサブセットのみを与えられた場合でも、LLMは正しいツールを選択できるか? (2) 検索エンジン自体が正しいツールを上位K件にランク付けできるか?
データセット | ツール数 | ベースライン精度 | graph-tool-call | トークン削減率 |
Petstore | 19 | 100% | 95% (k=5) | 64% |
GitHub | 50 | 100% | 88% (k=5) | 88% |
Mixed MCP | 38 | 97% | 90% (k=5) | 83% |
Kubernetes core/v1 | 248 | 12% | 82% (k=5 + オントロジー) | 79% |
重要な発見 — 248ツールの場合、ベースラインは(コンテキストオーバーフローにより)12%まで崩壊しますが、graph-tool-callは82%まで回復します。小規模なスケールではベースラインも強力であるため、graph-tool-callの価値は精度を損なわないトークン節約にあります。
→ 完全な結果(パイプライン / 検索のみ / 競合比較 / 1068スケール / 200ツールLangChainエージェントのGPTおよびClaudeでの比較):docs/benchmarks.md
# Reproduce
python -m benchmarks.run_benchmark # retrieval only
python -m benchmarks.run_benchmark --mode pipeline -m qwen3:4b # full pipeline高度な機能
埋め込みベースのハイブリッド検索
BM25 + グラフの上にセマンティック検索を追加します。重い依存関係は不要で、外部の埋め込みサーバーに接続するだけです。
tg.enable_embedding("ollama/qwen3-embedding:0.6b") # Ollama (recommended)
tg.enable_embedding("openai/text-embedding-3-large") # OpenAI
tg.enable_embedding("vllm/Qwen/Qwen3-Embedding-0.6B") # vLLM
tg.enable_embedding("sentence-transformers/all-MiniLM-L6-v2") # local
tg.enable_embedding(lambda texts: my_embed_fn(texts)) # custom callable重みは自動的に再調整されます。すべてのプロバイダー形式についてはAPIリファレンスを参照してください。
検索のチューニング
tg.enable_reranker() # cross-encoder rerank
tg.enable_diversity(lambda_=0.7) # MMR diversity
tg.set_weights(keyword=0.2, graph=0.5, embedding=0.3, annotation=0.2)履歴を考慮した検索
以前に呼び出されたツールを渡すことで、それらを降格させ、次のステップの候補を昇格させます。
tools = tg.retrieve("now cancel it", history=["listOrders", "getOrder"])
# → [cancelOrder, processRefund, ...]保存 / 読み込み (埋め込み + 重みを保持)
tg.save("my_graph.json")
tg = ToolGraph.load("my_graph.json")
# Or use cache= in from_url() for automatic save/load
tg = ToolGraph.from_url(url, cache="my_graph.json")LLM強化オントロジー
tg.auto_organize(llm="ollama/qwen2.5:7b")
tg.auto_organize(llm="litellm/claude-sonnet-4-20250514")
tg.auto_organize(llm=openai.OpenAI())よりリッチなカテゴリ、関係、検索キーワードを構築します。Ollama、OpenAIクライアント、litellm、および任意の呼び出し可能オブジェクトをサポートしています。APIリファレンスを参照してください。
その他の機能
機能 | API | ドキュメント |
仕様間の重複検出 |
| |
競合検出 |
| |
運用分析 |
| |
インタラクティブダッシュボード |
| |
HTML / GraphML / Cypherエクスポート |
| |
不適切なOpenAPI仕様の自動修正 |
|
ドキュメント
ドキュメント | 説明 |
すべての | |
| |
MCPサーバー / プロキシ、LangChain、ミドルウェア、Direct API | |
完全なパイプライン / 検索 / 競合比較 / スケールテーブル | |
システム概要、パイプラインレイヤー、データモデル | |
アルゴリズム設計 — 正規化、依存関係検出、オントロジー | |
競合分析、APIスケールデータ | |
リリースプロセス、変更ログフロー |
貢献
貢献を歓迎します。
git clone https://github.com/SonAIengine/graph-tool-call.git
cd graph-tool-call
pip install poetry pre-commit
poetry install --with dev --all-extras
pre-commit install # auto-runs ruff on every commit
# Test, lint, benchmark
poetry run pytest -v
poetry run ruff check . && poetry run ruff format --check .
python -m benchmarks.run_benchmark -vライセンス
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/SonAIengine/graph-tool-call'
If you have feedback or need assistance with the MCP directory API, please join our Discord server