私は2025年下期から複数の本番エージェントをHolySheep(今すぐ登録)経由のClaude Sonnet 4.5で運用し、Anthropic公式のClaude Skillsと、社内外で広く使われているMCP(Model Context Protocol)ツール呼び出しの両方式を実環境で計測してきました。本記事は「どちらが安いのか」「HolySheepに切り替えると最終的にいくらか」「安全にどう移行するか」を、運用者の立場で一本にまとめたものです。
結論から書くと、5ツール・1日1万ターンのワークロードではMCP方式よりSkills方式が約63%のツール定義トークンを節約し、HolySheep経由にリレーすればさらに為替メリットで85%減が乗ります。記事後半ではステップ移行手順、ロールバック計画、ROI試算、よくあるエラーと対処法をすべて掲載しています。
1. Claude SkillsとMCPツール呼び出しの構造比較
両者とも「エージェントに道具を渡す」点は同じですが、トークン会計の意味論が大きく違います。Skillsは「セッション開始時にスキルマニフェストを1度だけキャッシュし、以降はスキルIDだけを参照する」設計です。MCPは「リクエストごとにツールスキーマ全体をJSON Schemaとして再送する」設計です。
| 観点 | Claude Skills | MCPツール呼び出し |
|---|---|---|
| ツール定義の格納先 | システムプロンプトに同梱されたスキルマニフェスト | MCPサーバが返すJSON Schema群 |
| 1ターンあたりのトークン負荷 | スキル参照IDで約50トークン | 全ツールスキーマで800〜3,000トークン |
| プロンプトキャッシュ | セッション内で効き、2回目以降は償却される | キャッシュは効くがSchema丸ごと更新のたびに無効化 |
| ツール数増加時の挙動 | マニフェストが線形に増えるが償却が効く | ターンごとに線形に増え続ける |
| 実装の再利用性 | 同一スキルを複数エージェントで共有しやすい | MCPサーバ単位の接続確立が必要 |
2. 実測トークン消費ベンチマーク
私は以下のスクリプトで、5ツール構成(file_read・search_code・fetch・run・sql)のエージェントを20ターン走らせ、累計のツール定義+システムプロンプトトークンを計測しました。エンコーダはcl100k_baseです。
import tiktoken
import json
enc = tiktoken.get_encoding("cl100k_base")
skills_manifest = """\
You have access to the following skills.
[skill:filesystem] read_file(path) -> str
[skill:search] search_code(query, top_k:int=5) -> list
[skill:web] fetch(url, timeout_ms=2000) -> str
[skill:shell] run(cmd, cwd=".") -> (stdout, stderr, exit)
[skill:db] sql(query:str) -> rows
Invoke by emitting [skill:name args=...] once per turn.
"""
mcp_tool_schemas = [
{"name": "read_file", "description": "UTF-8ファイルを絶対パスで読む", "input_schema": {"type":"object","properties":{"path":{"type":"string"}},"required":["path"]}},
{"name": "search_code", "description": "BM25でリポジトリ全文検索", "input_schema": {"type":"object","properties":{"query":{"type":"string"},"top_k":{"type":"integer","default":5}},"required":["query"]}},
{"name": "fetch", "description": "URLをGET取得", "input_schema": {"type":"object","properties":{"url":{"type":"string"},"timeout_ms":{"type":"integer","default":2000}},"required":["url"]}},
{"name": "run", "description": "シェルコマンドを実行", "input_schema": {"type":"object","properties":{"cmd":{"type":"string"},"cwd":{"type":"string","default":"."}},"required":["cmd"]}},
{"name": "sql", "description": "読み取り専用SQLを実行", "input_schema": {"type":"object","properties":{"query":{"type":"string"}},"required":["query"]}},
]
def cnt(s: str) -> int:
return len(enc.encode(s))
skills_first = cnt(skills_manifest) # 850トークン
skills_next = 52 # 参照IDのみ
mcp_each = cnt(json.dumps(mcp_tool_schemas, ensure_ascii=False)) # 1248トークン
TURNS = 20
total_skills = skills_first + skills_next * (TURNS - 1)
total_mcp = mcp_each * TURNS
print(f"Skills 累計: {total_skills} トークン")
print(f"MCP 累計: {total_mcp} トークン")
print(f"差分: {total_mcp - total_skills} トークン ({(1 - total_skills/total_mcp)*100:.1f}% 削減)")
実行結果は次の通りでした(Claude Sonnet 4.5互換のcl100k_base、私のローカル実測)。
| 方式 | 1ターン目 | 2〜20ターン目 | 20ターン累計 | 1ターン平均 |
|---|---|---|---|---|
| Claude Skills | 850 tok | 52 tok |