LLMに全部読ませない。スクリプト同梱のエージェントスキルでトークンを減らす
本文の状態
日本語全文を表示中
詳細モードで約20分の本文を読めます。
同じ出来事の情報源
この情報源を基点に整理
Algomatic Tech Blog
Algomatic のエンジニアは、LLM に大量データを丸ごと渡す課題に対し、スクリプト同梱のエージェントスキルで前処理を行いトークン削減を実現する設計手法を提案している。
AI深層分析を開く2026年8月30日 00:02
AI深層分析
キーポイント
ローカル前処理によるトークン削減
LLM に直接大量の CSV やログ、コードを渡すのではなく、エージェントスキルに同梱したスクリプトで検索・抽出・集計を行い、必要な情報だけを LLM に渡す設計である。
コンテキスト削減の三要素
指示コンテキスト(SKILL.md 等)、観察履歴(過去ツール出力等)、データ本体(CSV やコード)の三つを区別し、それぞれに適した削減手段を適用する。
機械処理はコードへ戻す
手順が決まっている処理や中間データの絞り込みを LLM に考えさせるのではなく、実行環境上のスクリプトで完結させ、LLM の判断コストを減らす。
機械処理はコードへ実装する
CSVの集計やログ解析などLLMが読む必要のない計算はスクリプトで処理し、トークンを削減する。
必須証拠項目による評価基準の定義
正しい判断に必要なレコードやログを事前に定義し、トークン削減後の成功率と証拠項目の再現率を測定する。
重要な引用
エージェントスキルにローカル実行用のスクリプトを同梱し、検索、抽出、集計、重複除去、依存関係の解析を先に済ませます
LLM へ渡すのは、絞り込んだ結果と、判断に必要な根拠だけです
LLMが読む必要のない計算は、コードで済ませます
SKILL.mdには、利用条件、最小限の手順、スクリプトの入口だけを置きます
編集コメントを表示
編集コメント
LLM の利用コストが課題となる中、単純なプロンプトエンジニアリングを超えたシステム設計の視点が示されており、実務レベルでの応用価値が高い。Algomatic の提案するスクリプト同梱型アプローチは、RAG やエージェント開発における標準的なベストプラクティスとして今後注目される可能性を秘めている。
Source Article
元記事を日本語で読む
本文に関係しない購読案内、埋め込み通知、サイト内プロモーションは除いています。

こんにちは。AlgomaticでソフトウェアエンジニアをしているGo(@53able)です。
大量のデータを丸ごとLLMへ渡す方法には、二つの課題があります。質問に関係のない行まで入力トークンに含まれ、単純に途中で切れば判断に必要な根拠まで落としかねません。
大きなCSVやJSON、ログ、文書群、コードベースを、そのままLLMへ渡さない設計にします。
エージェントスキルにローカル実行用のスクリプトを同梱し、検索、抽出、集計、重複除去、依存関係の解析を先に済ませます。LLMへ渡すのは、絞り込んだ結果と、判断に必要な根拠だけです。

関連研究が扱う削減対象は、処理時の役割から、SKILL.mdや参照資料などの指示コンテキスト、過去のツール出力や中間ログなどの観察履歴、CSVやコード本文などのデータ・コード本体の三つに整理できます。同じログでも、生データとして扱うか、過去の観察として扱うかで分類は変わります。それぞれの研究結果を、スクリプト同梱スキルの設計仮説として組み合わせます。

機械処理はコードへ戻す
LLMが読む必要のない計算は、コードで済ませます。対象になるのは、次のような処理です。
- CSVやJSONの絞り込み、グループ化、結合、集計
- ログの頻度集計、エラー抽出、重複除去
- 文書の見出しやメタデータの抽出、全文検索
- コードのAST解析、シンボル検索、依存関係の抽出
- テスト結果や差分の機械的な整理
- ハッシュを使った既出データの再送防止
入力、スクリプトと依存関係のバージョン、実行環境を固定した決定論的な処理では、同じ入力から同じ結果を再現できます。スクリプト同梱スキルとしての効果は未測定なので、導入時に送信トークン、必須証拠項目のrecall、最終タスクの成功率を測ります。
必要な根拠を落とせば、トークンを減らしても失敗です。評価では、正しい判断に必要なレコード、ログ行、コード範囲を必須証拠項目として事前に定義します。最終タスクの成功率と、取得結果が必須証拠項目を覆った割合を測ります。
SKILL.mdは短く保つ
SKILL.mdには、利用条件、最小限の手順、スクリプトの入口だけを置きます。例、テンプレート、背景説明、詳しい参照資料は、必要になってから読みます。SkillReducerが採用したのも、次の二層構造です。
- 常に読み込む短い基本ルール
- 必要になったときだけ読む補足資料
この分け方が必要なのは、スキルに含まれる説明のすべてを常時読み込む必要はないからです。2026年のプレプリントSkillReducerは、Wild 55,315件、SkillHub 100件、Community 620件のスキル群から30件ずつ、計90件を抽出しました。15,107個の段落単位の項目をLLMで分類した結果、38.5%が「core rule(実行可能な指示)」に分類されました。これは項目を除去して実行性能を測った割合ではありません。
参照ファイルも初期コンテキストを増やします。SkillHubの100件には、合計505個、167万トークン分の参照ファイルが付属していました。スキルごとの内訳は論文本文にないため、すべてのスキルが同じ量を持つとは判断できません。
SkillReducerは600件のbodyを平均39%圧縮しました。descriptionの平均圧縮率48.0%は、既存の長いdescriptionを圧縮した171件と、bodyからdescriptionを生成した後に圧縮した429件を合わせた平均です。後者は元のdescriptionとの比較ではないため、すべてが同じ条件の圧縮率ではありません。
圧縮による品質改善の根拠は強くありません。600件のうち86.0%で圧縮後の評価点が元のスキル以上になり、Gate 2の平均点は0.722から0.742へ上がりました。しかし、Cohen's dは0.107で効果量は小さく、Gate 2は圧縮時のフィードバックにも使われています。86.0%は独立した検証用データでの成功率ではありません。
SkillsBenchでも差はほとんど出ていません。圧縮に成功したのは87タスク中84タスクでしたが、全87タスクを対象にした表では、元のスキルとSkillReducerがともに87問正解し、スキルなしでも86問正解しています。圧縮できなかった3タスクの扱いは論文本文に説明がなく、この結果だけでは圧縮による性能差を判断できません。
この研究から採用するのは、圧縮すれば性能が上がるという結論ではなく、常時読み込む内容と必要時に読む内容を分ける設計です。導入時には、トークン削減量だけでなく、必須証拠項目のrecallと最終タスクの成功率も測ります。
入力検証、集計、分岐条件など、正解を規則で決められる処理はスクリプトへ固定します。LLMに残すのは、曖昧な要求の解釈や、エラーログの意味判断など、文脈を読まなければ決められない処理です。
- 既知の手順はスクリプトに固定する
- 機械的に判定できる条件分岐や検証はLLMへ任せない
- LLMへ渡す仕事と出力形式を狭く定義する
- 同じ機械処理を毎回自然言語で考え直させない

この役割分担に近い設計例が、Blueprint First, Model Secondです。提案手法のSCA(Source Code Agent)は、手順、分岐、制約をExecution Blueprintというソースコードに定義し、意味の判断が必要な場面だけLLMを呼びます。
TravelPlannerの1,000件のテストタスクでは、同じClaude Sonnet 4を使い、制約に対応したマルチエージェント方式のATLASとSCAを比較しました。明示的なユーザー要件と、暗黙の実用上の制約の両方を満たした最終合格率は、ATLASの18.00%に対してSCAが35.56%でした。
ただし、制約別の結果は揃っていません。暗黙の実用上の制約違反はATLASの275件に対してSCAが11件でしたが、明示的なユーザー要件の違反はATLASの265件に対してSCAが336件でした。最終合格率は上がっても、すべての制約が改善したわけではありません。
別のベースラインであるReActは、LLMによる推論と行動を交互に繰り返します。3つの乱数シードで測った平均実行ステップは、ReActの14.0±0.8に対してSCAが10.2±0.7でした。±は乱数シード間の標準偏差です。ここで引用した総合比較とステップ数比較だけでは、手順をコードへ固定した効果だけを分離できません。
そのため、エージェントスキルへの転用は、手順と制約を事前に決められる作業に限定します。導入時には、送信トークン、最終タスクの成功率、再現性、デバッグ時間を全文方式と比較します。
古いツール出力は、まず隠す
古いツール出力を整理するときは、LLM要約を最初から標準にせず、単純な方法と比較します。Observation Maskingは古い出力をコンテキストから隠す方法です。LLM要約は、履歴を別のLLMで短くまとめて置き換えます。
The Complexity Trap: Simple Observation Masking Is as Efficient as LLM Summarization for Agent Context Managementは、SWE-bench Verifiedで両者を比較しました。SWE-agentによる5つのモデル設定では、コストと解決率のどちらでも、LLM要約がMaskingを一貫して上回りませんでした。
コストと解決率は分けて見る
5つのモデル設定と2手法の組み合わせでは、Raw Agentに対する平均インスタンスコストの削減率は0%から57.1%でした。ただし、最大の57.1%を記録したGemini 2.5 Flash thinkingのMasking条件では、解決率が40.4%から36.4%へ下がりました。コストが下がっても、解決率が維持されるとは限りません。
LLM要約には、要約処理そのものの費用もかかります。Qwen3-Coder 480Bの条件では、要約APIの利用料がインスタンス総費用の7.2%を占めました。
組み合わせ方式は設定に左右される
Maskingと要約を組み合わせた方式も試されています。SWE-agentとQwen3-Coder 480Bを使ったSWE-bench Verified-50の探索的評価では、設定を調整した組み合わせのコスト指標が、Masking単独より7%、要約単独より11%下がりました。
この結果は、組み合わせ方式が常に優れていることを意味しません。一度に要約するターン数をN、要約せず残す末尾ターン数をM、Maskingで保持する直近ターン数をWとしたとき、改善したのはN=43、M=W=10に調整した条件です。N=21、M=W=10をそのまま使った条件では、全体のコスト効率が悪化しました。違いを生んだのはモデルの変更ではなく、コンテキスト管理の設定です。
本稿では詳細を再取得できる形で残す
この研究から採用するのは、判断に不要な詳細を初期コンテキストへ入れないという原則です。ただし、本稿では古い出力を単に隠すのではなく、必要になったときに再取得できるアーティファクトへ保存します。次の構成は論文が直接評価した方法ではなく、個別に検証する設計仮説です。
- 成功したコマンドは終了コードと件数だけ返し、詳細ログは保存先を示す
- 同じ警告を、出現回数と代表例にまとめる
- 変更のないレコードは初期出力から除き、必要時に再取得できるようにする
- 上限を超えた結果は分割して返す
- 既読の結果は、保存先の識別子と内容ハッシュによる参照へ置き換える
大量の中間データは実行環境で絞り込む
AnthropicのCode execution with MCPは、この構想に近い実装例です。学術論文ではなく、ベンダーの技術記事です。
一般的なMCPクライアントは、利用可能なツールの定義を最初にコンテキストへ読み込みます。ツールの中間結果もLLMのコンテキストへ入ります。同じデータを次のツールへ渡すと、モデルがもう一度出力します。
コード実行方式では、エージェントが必要なAPIだけを読み、実行環境で絞り込み、結合、集計を済ませます。実行環境はローカルとは限りません。LLMへ返すのは処理後の結果だけです。
Anthropicの記事は、ツール定義による使用量を150,000トークンから2,000トークンへ減らせると説明しています。測定条件は記事にありません。スプレッドシートの例では、10,000行を実行環境で絞り込み、結果の件数と先頭5行だけを返します。
コードベースでも原則は同じです。RepoScopeは呼び出し関係と類似度から候補を選び、cASTはASTの境界を優先してコードを分け、LongCodeZipはトークン予算を超えたコードを圧縮します。「選ぶ、構造を保って分ける、それでも多い場合だけ縮める」という順序は、三研究を組み合わせた設計仮説として導入時に比較します。
スクリプトは概要と参照先だけを返す
検索で10ファイルが見つかっても、10ファイルの本文をすべてLLMへ渡しません。検索ツールは候補のファイル名、行番号、一致理由だけを返し、LLMが選んだ範囲の本文を追加取得します。
CodeGrepのSWE-bench Verified評価では、BM25の上位2ファイルを初期コンテキストへ加えた条件で、解決率が0.6ポイント下がりました。この一条件から、検索結果の自動追加が常に有効とは判断できません。候補一覧からの追加取得はCodeGrepで直接評価されていないため、全文方式、固定件数の自動追加、候補一覧からの追加取得を導入時に比較します。
スキルの最小構成は、短い指示、機械処理を行うスクリプト、出力形式の説明です。
my-data-skill/
├── SKILL.md
├── scripts/
│ ├── inspect.py
│ ├── filter.py
│ ├── aggregate.py
│ └── verify.py
└── references/
└── output-schema.mdSKILL.mdには利用条件、入力形式、スクリプトの入口、失敗時の手順、トークン上限を書きます。入力検証、絞り込み、集計、結合、重複除去、差分計算、出典位置の付与はスクリプトへ移します。LLMに残すのは、曖昧な要求の解釈、証拠の比較、次に読むデータの選択、結論の作成です。

CIログを集約する最小スクリプト
次の6行をci.logとして保存します。
2026-08-29T10:00:00Z INFO build started
2026-08-29T10:00:01Z WARN retry 1
2026-08-29T10:00:02Z WARN retry 2
2026-08-29T10:00:03Z ERROR connection refused port 5432
2026-08-29T10:00:04Z ERROR connection refused port 5433
2026-08-29T10:00:05Z INFO build failedscripts/inspect.pyは、WARNとERRORを抽出し、時刻や番号の違いを<n>へ正規化して集約します。
import argparse, hashlib, json, re
from collections import defaultdict
from pathlib import Path
LEVEL = re.compile(r"\b(?:ERROR|WARN)\b")
TIMESTAMP = re.compile(r"^\d{4}-\d{2}-\d{2}T\S+\s+")
VOLATILE = re.compile(r"\b(?:0x[0-9a-fA-F]+|\d+)\b")
parser = argparse.ArgumentParser()
parser.add_argument("log", type=Path)
parser.add_argument("--limit", type=int, default=5)
args = parser.parse_args()
raw = args.log.read_bytes()
sha256 = hashlib.sha256(raw).hexdigest()
lines = raw.decode("utf-8", errors="replace").splitlines()
groups = defaultdict(list)
for number, line in enumerate(lines, 1):
if LEVEL.search(line):
key = VOLATILE.sub("<n>", TIMESTAMP.sub("", line.strip()))
groups[key].append((number, line.strip()))
findings = []
for key, hits in sorted(groups.items(), key=lambda item: (-len(item[1]), item[0])):
first = hits[0][0]
findings.append({
"key": key,
"count": len(hits),
"line_numbers": [number for number, _ in hits[:5]],
"next": {
"sha256": sha256,
"start": max(1, first - 2),
"end": min(len(lines), first + 2),
},
})
print(json.dumps({
"source_file": args.log.name,
"sha256": sha256,
"total_lines": len(lines),
"matched_lines": sum(len(hits) for hits in groups.values()),
"groups": findings[:max(0, args.limit)],
"truncated": len(findings) > max(0, args.limit),
}, ensure_ascii=False, indent=2))
上位1グループだけを取得します。
python3 scripts/inspect.py ci.log --limit 1 > summary.jsonこの入力では6行のうち4行が対象になり、2グループへまとまります。--limit 1を指定した出力は次のとおりです。
{
"source_file": "ci.log",
"sha256": "b00d1ba48d81924a43fe4864e0a7b134a668c4594228bb2897b9255f1740b0d3",
"total_lines": 6,
"matched_lines": 4,
"groups": [
{
"key": "ERROR connection refused port <n>",
"count": 2,
"line_numbers": [
4,
5
],
"next": {
"sha256": "b00d1ba48d81924a43fe4864e0a7b134a668c4594228bb2897b9255f1740b0d3",
"start": 2,
"end": 6
}
}
],
"truncated": true
}
LLMはこの概要から読むグループのkeyを返します。アプリケーションは、同じ概要からそのグループのnext.sha256、next.start、next.endを取り出します。そのうえで、許可リストに登録したアーティファクトだけをsource_fileから解決し、sha256が変わっていないこと、取得行数とバイト数が上限内であることを確認します。取得した原文はマスキングを通してから外部LLMへ渡します。
ローカル処理の情報境界を閉じる
スクリプトをローカルで実行しても、エージェントが生ファイルの読み取りやシェル操作を自由に使えるなら、データは外へ出せます。

実行スクリプトは隔離実行環境(sandbox)で動かし、CPU、メモリ、実行時間、ファイル、子プロセス、ネットワークに上限を設けます。生データを返すツールは初期状態で許可せず、出力先を許可リスト(allowlist)で制限します。外部LLMへ送る前に送信データ(payload)を検査し、APIキー、個人情報、秘密情報をマスキングします。
監査ログには、入力ハッシュ、実行コマンド、出力ハッシュ、送信量を残します。処理に失敗しても全文送信へ切り替えません。採用前には、マスキング漏れ、参照先のアクセス権、失敗時の送信停止をテストします。
一つのCIログから試し、全文方式と比べる
ここまでの構成は、統合システムとしてまだ評価していません。ContextBenchは、最終タスクの成功率と、検索の適合率(precision)、再現率(recall)、F1を測ります。precisionは検索結果に正解文脈が占める割合、recallは必要な正解文脈を取得できた割合です。F1はこの二つの調和平均で、どちらか一方が低ければ値も低くなります。ContextBenchは、探索中に見つけた正解文脈が最終コンテキストへ残ったかも調べます。しかし、残った正解文脈が最終回答に使われたとは限りません。これらの指標からは費用と所要時間も分かりません。本記事では、まず成功率と必須証拠項目のrecallを確認し、両方が基準を満たした場合だけ費用と所要時間を判定します。

最初の動作確認には、同じconnection refusedと再試行の警告が繰り返されるCIログを一つ使います。全文をLLMへ渡す方式と、重複をまとめて件数、代表例、行番号だけを返すスクリプト方式に、同じ失敗原因と修正候補を答えさせます。1件目では、概要から必要なログ行を追加取得できるところまで確認し、採用判断はしません。
本採用の前には、原因や形式が異なる代表ログを複数用意します。各ログの必須証拠項目、期待する失敗原因、許容できる修正候補を先に記録します。同じ意味を持つ複数のログ行は同等な証拠として扱います。全文方式とスクリプト方式は、同じモデル、設定、ログ集合、反復回数、乱数条件で実行し、成功率の差は点推定と信頼区間で判断します。
採用条件は、次の順序で実験前に決めます。
- 成功率差を「スクリプト方式−全文方式」で計算する。低下を許容しない場合は、差の片側95%信頼区間の下限が0以上なら通過とする。低下を許容する場合は、障害や誤判断による損失から許容幅を先に決め、下限が
−許容幅以上なら通過とする
- 一つでも欠けると判断を誤る必須証拠項目には、recall 100%を求める。見落としを許容できる探索用途では、許容件数を先に決める
- 評価期間と想定実行回数を先に決める。費用は同じ通貨単位で比較し、その期間のトークン費用と計算費用の削減額が、初期実装費を期間按分した額と、スクリプトの実行、保守、再検証にかかる費用を上回る場合だけ通過とする。所要時間は実装、実行、保守、再検証を合計し、実験前に決めた上限内であることを別に確認する
品質に関する最初の二条件を満たしたうえで、費用対効果を判定します。トークン削減によって、成功率や必須証拠項目の不足を相殺しません。
処理手段を一度に増やすと、どの変更が結果へ影響したのかを切り分けにくくなります。そのため、実装も「選ぶ、分ける、縮める」の順に進めます。スクリプト、埋め込み、小型モデルは、各段階を実現する手段です。まず規則をスクリプトへ固定し、表記の違いを規則だけで扱えない場合にローカル埋め込みを加え、それでも候補が多すぎる場合に小型のローカルモデルで圧縮します。前の手段で基準を満たせなかった場合だけ次へ進みます。
まとめ:成功率を守れる場合だけ採用する
2025年以降の関連研究からは、スキルの段階的な読み込み、決められた処理のコード化、古いツール出力のマスキング、実行環境での絞り込みが、それぞれコンテキスト消費を抑える手段として研究されています。ただし、測っている対象と指標は異なり、スクリプト同梱型のエージェントスキル全体を直接評価した結果ではありません。
採用候補は、SKILL.mdを短く保ち、機械的な処理を同梱スクリプトへ移し、LLMには概要、代表例、根拠、参照先だけを渡す設計です。原文は必要になった範囲だけ追加取得します。生データをローカルに置くだけでは情報境界にならないため、実行権限、送信前検査、マスキング、監査ログも同時に設計します。
この構成によるトークン削減とタスク性能は、まだ統合システムとして測定していません。全文方式と同じタスクで比較し、最終タスクの成功率、必須証拠項目のrecall、同じ通貨単位で比較した費用、別に集計した所要時間が、実験前に決めた基準をすべて満たした場合だけ採用します。
最初に作るのは大規模なRAG基盤ではありません。全文を渡している処理を一つ選び、概要と追加取得手段を返すスクリプトへ置き換えます。まずは、送信トークン、必須証拠項目のrecall、最終タスクの成功率、費用、所要時間を全文方式と比べるところから始めます。
エンジニアを募集しています!
ここまで読んでいただきありがとうございました!
Algomatic では、「AI革命で人々を幸せにする」をミッションに、変化の速い領域でも 学びや試行錯誤を続けられる エンジニアを募集しています。
もし少しでもご興味をお持ちいただけましたら、カジュアル面談に足を運んでいただけるとうれしいです!
参考文献
関連記事
今日のまとめ
AIデイリーブリーフで今日の重要ニュースをまとめ読み