AI業務活用 2026.04.21
AIトークンを75%削減する方法|Cavemanと自前実装で入力コストを大幅カット【2026年版】
なぜトークン削減が重要か
Claude API・OpenAI APIは入力トークン数に応じて課金されます。コードレビューやドキュメント解析のように大きなファイルをAPIに送る作業では、送信内容の大半が「AIが読む必要のないノイズ」であることが珍しくありません。
| 削減前の典型的な無駄 | 割合目安 |
|---|---|
| HTMLタグ・属性・スクリプト | 40〜60% |
| JSONの空白・不使用フィールド | 20〜40% |
| コードのコメント・空行 | 10〜20% |
| Markdownの装飾記号 | 5〜10% |
これらを除去するだけで、同じ情報量を1/4〜1/2のトークンで送れます。
Cavemanの基本概念
Caveman はプロンプトに含まれるノイズを自動検出・除去するツールです。「原始人(caveman)でも理解できる最低限の情報だけにする」というコンセプトから名付けられています。
処理の流れ:
元テキスト(大)→ Caveman処理 → 圧縮テキスト(小) → Claude API
Pythonで実装するトークン削減ロジック
Cavemanと同等の処理をPythonで実装できます。
基本的な圧縮関数
import re
import json
from typing import Any
def compress_text(text: str) -> str:
"""テキストから不要な空白・記号を除去してトークンを削減"""
# 連続する空白行を1行に圧縮
text = re.sub(r'\n{3,}', '\n\n', text)
# 行末の空白を除去
text = re.sub(r'[ \t]+$', '', text, flags=re.MULTILINE)
# タブをスペース1つに変換
text = text.replace('\t', ' ')
# 連続するスペースを1つに圧縮
text = re.sub(r' {2,}', ' ', text)
return text.strip()
def compress_json(data: Any, exclude_keys: list[str] | None = None) -> str:
"""JSONを最小限の文字列に変換(不要フィールドを除外)"""
if exclude_keys:
if isinstance(data, dict):
data = {k: v for k, v in data.items() if k not in exclude_keys}
elif isinstance(data, list):
data = [{k: v for k, v in item.items() if k not in exclude_keys}
if isinstance(item, dict) else item
for item in data]
return json.dumps(data, ensure_ascii=False, separators=(',', ':'))
# 使用例
api_response = {
"id": "req_001",
"created_at": "2026-08-19T10:00:00Z",
"updated_at": "2026-08-19T10:00:00Z",
"user": {"id": 1, "name": "田中", "avatar_url": "https://..."},
"data": {"title": "バグ報告", "body": "ログイン後にクラッシュする"}
}
# AIに必要ない id・created_at・updated_at・avatar_urlを除外
compressed = compress_json(
api_response,
exclude_keys=["id", "created_at", "updated_at", "avatar_url"]
)
print(compressed)
# → {"user":{"id":1,"name":"田中"},"data":{"title":"バグ報告","body":"ログイン後にクラッシュする"}}
HTMLからテキスト本文だけを抽出する
from html.parser import HTMLParser
class HTMLTextExtractor(HTMLParser):
"""HTMLタグを除去してテキストだけを抽出"""
SKIP_TAGS = {'script', 'style', 'nav', 'footer', 'header', 'aside'}
def __init__(self):
super().__init__()
self.text_parts = []
self._skip = False
self._skip_tag = None
def handle_starttag(self, tag, attrs):
if tag in self.SKIP_TAGS:
self._skip = True
self._skip_tag = tag
def handle_endtag(self, tag):
if tag == self._skip_tag:
self._skip = False
self._skip_tag = None
def handle_data(self, data):
if not self._skip and data.strip():
self.text_parts.append(data.strip())
def get_text(self) -> str:
return ' '.join(self.text_parts)
def html_to_text(html: str) -> str:
"""HTMLページからテキスト本文だけを取り出す"""
parser = HTMLTextExtractor()
parser.feed(html)
text = parser.get_text()
return compress_text(text)
# 使用例
html = """<html><head><style>.btn{color:red}</style></head>
<body><nav>メニュー</nav><main><h1>タイトル</h1>
<p>本文テキストがここに入ります。重要な内容です。</p></main>
<script>console.log('tracking')</script></body></html>"""
print(html_to_text(html))
# → タイトル 本文テキストがここに入ります。重要な内容です。
Pythonコードから不要な部分を除去する
def compress_python_code(code: str, keep_comments: bool = False) -> str:
"""Pythonコードからコメント・余分な空行を除去"""
lines = []
for line in code.split('\n'):
stripped = line.strip()
# 空行を除去
if not stripped:
continue
# コメント行を除去(keep_comments=Falseの場合)
if not keep_comments and stripped.startswith('#'):
continue
# インラインコメントを除去
if not keep_comments and '#' in line:
line = line[:line.index('#')].rstrip()
if not line.strip():
continue
lines.append(line)
return '\n'.join(lines)
トークン削減効果の測定
実際にどれだけ削減できたか計測するコードです。
import tiktoken
def measure_token_reduction(original: str, compressed: str, model: str = "gpt-4o") -> dict:
"""トークン削減率を計測"""
enc = tiktoken.encoding_for_model(model)
orig_tokens = len(enc.encode(original))
comp_tokens = len(enc.encode(compressed))
reduction = (orig_tokens - comp_tokens) / orig_tokens * 100
return {
"original_tokens": orig_tokens,
"compressed_tokens": comp_tokens,
"reduction_rate": f"{reduction:.1f}%",
"saved_tokens": orig_tokens - comp_tokens
}
# 使用例
result = measure_token_reduction(original_html, compressed_text)
print(f"削減率: {result['reduction_rate']}")
print(f"節約トークン: {result['saved_tokens']}")
実際のコスト削減効果
月10,000回のAPIコール、平均入力5,000トークンの場合:
| 条件 | 月間入力トークン | gpt-4oコスト | gpt-4o-miniコスト |
|---|---|---|---|
| 圧縮なし | 50,000,000 | $250 | $7.5 |
| 50%削減 | 25,000,000 | $125 | $3.75 |
| 75%削減 | 12,500,000 | $62.5 | $1.88 |
gpt-4oで75%削減できれば、月$250→$62.5と年間約$2,250の節約になります。
注意点:削減しすぎに気をつける
コンテキストを削りすぎると回答精度が落ちます。実用的な基準:
- 削減率60%以下を目標に: 80%以上の削減は重要情報まで失うリスクあり
- 削減後の回答を比較: 同じ質問で削減前後の回答を比べて品質を確認
- コード・数値・固有名詞は削らない: ノイズより情報量が高い部分は保持
あわせて読みたい
- Claudeのトークンコストを最大78%削減する実践テクニック
- Claude Code のコスト削減術:システムプロンプトキャッシュとローカル MCP の実戦活用
- Claude APIで余分な文字数を95%カット。開発費を大きく減らせる工夫