先に結論だけ
エージェント環境ではログ取得が事実上無料になり、人間の介入がもっともコストの高い操作になります。この非対称性を認識すると、「安価なログを使って人間の介入を減らす」という設計方針が自然に導かれます。
本記事では、この方針を具体化する2つのパターン(セルフフィードバックと事前チェックエージェント)を解説し、Claude Codeでの実現方法を紹介します。
はじめに
LLMエージェントが自律的にタスクを実行する環境では、ログのコスト構造が従来の開発と異なります。以前はログの設計、実装、運用のすべてに人的コストがかかっていましたが、エージェント環境ではセッション全体が自動的に記録されます。
この変化は単なる効率化ではありません。ログが事実上無料になったことで、ワークフロー全体のコスト構造が逆転し、人間の介入がもっとも高価な操作になります。本記事では、この逆転を認識したうえで、安価なログを活かして人間の介入を減らす設計パターンを解説します。
本記事の検証環境はClaude Code v2.1.92です。具体例としてClaude Codeを使用しますが、コスト構造の逆転という概念自体はエージェントフレームワーク全般に適用できます。
ログコスト構造の逆転
従来のログコスト
従来のソフトウェア開発では、ログには3段階のコストがかかります。
- 設計コスト: 何をどのレベルで記録するかを決める
- 実装コスト: ロガーの導入とコードへの埋め込み
- 運用コスト: 保存基盤の維持と分析ツールの運用
いずれも人間の判断と作業が必要であり、「ログを取る」という行為自体が投資対象でした。ログは有益ですが、無料ではありません。
エージェント環境でのログコスト
エージェント環境では、このコスト構造が変わります。LLMエージェントのセッションでは、ツール呼び出し、入出力、エラー、判断の過程がすべて自動的に記録されます。
たとえばClaude Codeでは、セッションごとにJSONL形式のtranscriptが自動保存されます。1つのツール呼び出しは以下のような構造で記録されます。
{"type": "tool_use", "name": "Bash", "input": {"command": "npm test"}}
{"type": "tool_result", "is_error": false, "content": "Tests passed"}
人間がログの設計や実装を行う必要はありません。エージェントが動作する限り、ログは自動的に蓄積されます。ログ取得の追加コストは事実上ゼロです。
両者のコスト構造を対比すると、以下のようになります。
| コスト項目 | 従来の開発 | エージェント環境 |
|---|---|---|
| 設計 | 人間が設計(何を記録するか判断) | 不要(全操作が自動記録) |
| 実装 | 人間が実装(ロガー導入、コード埋め込み) | 不要(フレームワークが提供) |
| 運用 | 人間が運用(保存基盤、分析ツール) | 自動(ローカルファイルに保存) |
| 分析 | 人間が分析(ダッシュボード、アラート) | LLMが分析(ログを読んで改善案を提示) |
人間の介入がもっとも高価な操作になる
上の表で示したとおり、エージェント環境ではログに関するコストがほぼ消滅します。では、ワークフロー全体でもっともコストが高い操作は何か。それは人間による承認や確認です。
エージェントを並列に実行する環境では、この問題が顕著です。筆者の経験では、複数のClaude Codeセッションを同時に走らせると、承認待ちのダイアログがボトルネックになります。ワークフローが複雑になるほど確認ポイントが増え、人間側の認知負荷も増大します。エージェントの処理速度ではなく、人間の応答速度がスループットの上限を決めます。
この認識が、次のセクションで解説する2つの設計パターンの出発点です。「ログが安いなら、そのログを使って人間の介入を減らす方向で設計すべき」という発想です。
安価なログの活用パターン
セルフフィードバック:スキルが自身のログから学んで育つ
エージェントのセッションログを分析し、スキルやルールの改善に活用するパターンです。実行ログをフィードバックとして自身の定義に反映する、自己改善のループです。
このパターンのループは以下のとおりです。
- エージェントが処理を実行し、セッションログが自動記録される
- 蓄積されたログを分析し、エラー率の高いツールや失敗パターンを特定する
- 分析結果に基づいてスキル定義やルールを改善する
- 改善されたスキルとルールで再びタスクを実行する
「ログから学んで行動を改善する」という自己改善ループ自体は、LLMエージェント研究の初期から提案されている古典的な概念です。
- Reflexion(NeurIPS 2023): 失敗トレースを言語フィードバックに変換してメモリに蓄積する手法。パラメーター更新なしでエージェントの性能を向上させる
- ERL(arXiv 2025): トラジェクトリからヒューリスティックを蒸留して永続プールに保存する手法。実行ログから改善ルールを抽出する構造
従来これらの手法は研究環境での実装が前提でしたが、エージェントハーネスの性能向上により状況が変わりました。現在ではSKILL.mdに数行の定義を書くだけで、同じ構造のフィードバックループを手元の環境で回せます。後述するtranscript-analyzerはその実例です。
事前チェックエージェント:人間の前にフィルターを置く
HITL(Human-in-the-Loop)構成において、人間がレビューする前にエージェントが事前チェックを行うパターンです。
従来のHITL構成では、エージェントの出力をすべて人間が確認します。しかし、確認すべき項目には機械的に検査できるものと、判断が必要なものがあります。
- Linterやフォーマッターで検査できる項目: 命名規則の遵守、コードスタイルの統一、型チェックなど
- エージェントによる監査が適する項目: セキュリティルールの適用状況、テストカバレッジの妥当性、設計意図との整合性など
事前チェックエージェントは、これらの機械的検査とエージェント監査を組み合わせて、人間のレビュー前にフィルタリングします。さらに、蓄積したレビューログから繰り返される指摘の傾向を検出します。その結果をLinterルールの追加や監査基準の更新にフィードバックし、事前チェックの精度を継続的に改善します。人間のレビュー対象は、自動チェックを通過した項目に徐々に絞られていきます。
事前チェックエージェントは試行錯誤中のパターンです。筆者の環境ではまだ試験運用中ですが、ログの蓄積が進むほど有効性が高まると考えています。
Claude Codeでの実現
セッションログとhookによるログ基盤
Claude Codeはセッションの全操作をtranscript(JSONL形式)として~/.claude/projects/配下に自動保存します。保存期間はcleanupPeriodDays設定で制御でき、デフォルトは30日です。
さらにhook機能により、ツール呼び出しの前後で任意のスクリプトを実行できます。hookにはPreToolUse(ツール実行前)とPostToolUse(ツール実行後)の2種類があり、追加のログ処理を組み込めます。
この2つの仕組み(自動保存されるtranscriptと、カスタマイズ可能なhook)が、前セクションで解説したセルフフィードバックや事前チェックを実現するためのログ基盤です。
transcript-analyzerスキルの実装
セルフフィードバックパターンを実際に動かしている例として、筆者が運用しているtranscript-analyzerスキルを紹介します。このスキルはSKILL.mdとPythonスクリプト1本で構成されています。
SKILL.mdでは、スキルの役割と実行コマンドを定義しています。
---
name: transcript-analyzer
description: >-
Analyze Claude Code session transcripts for tool usage patterns, failure rates,
and skill improvement opportunities.
allowed-tools: Bash, Read
---
Pythonスクリプトは~/.claude/projects/配下のJSONLファイルを走査し、tool_useとtool_resultのペアを集計します。以下はセッション解析の中核部分です。
def parse_session(session_info):
"""Parse a single session JSONL and extract tool call data."""
filepath = session_info["path"]
tool_uses = {}
tool_results = {}
with open(filepath, "r") as f:
for line in f:
obj = json.loads(line.strip())
msg = obj.get("message", {})
for c in msg.get("content", []):
if c.get("type") == "tool_use":
tool_uses[c["id"]] = {
"name": c["name"],
"input": c.get("input", {}),
}
elif c.get("type") == "tool_result":
tool_results[c["tool_use_id"]] = {
"is_error": c.get("is_error", False),
}
entries = []
for tid, tu in tool_uses.items():
tr = tool_results.get(tid, {})
entries.append({
"tool": tu["name"],
"is_error": tr.get("is_error"),
})
return entries
実行すると、以下のようなレポートが出力されます。
=== Skill Invocations (156 calls, 23 unique) ===
Name Total OK Fail ? Fail%
----------------------------------------------------------------------
agent-commit 18 16 2 0 11%
article-writer 12 12 0 0 0%
smart-label 9 8 1 0 11%
このレポートから「エラー率の高いスキルはどれか」「利用頻度に対して失敗が多いツールはどれか」を把握し、スキル定義やルールの改善につなげます。SKILL.mdとPythonスクリプト1本という軽量な構成で、セルフフィードバックループが回り始めます。
セルフフィードバックの適用例:記事執筆ワークフロー
transcript-analyzerはツール呼び出しの成功率を分析対象としていますが、セルフフィードバックの対象はツール分析に限りません。筆者の記事執筆ワークフローを例に、より複雑な適用例を紹介します。
記事執筆には2つのスキルが関与します。
- プランナースキル: 記事のアイデアをセクション構成や対象読者を含むプランファイルに変換する
- ライタースキル: プランファイルと執筆ルールにしたがって記事本文を生成する
ライタースキルが記事を出力した後、筆者が内容を確認し、表現の修正や構成の調整、追加調査を行ってコミットします。このとき、ライタースキルの出力(セッションログ)と筆者が修正したコミットログを突き合わせると、修正の傾向を分析できます。
たとえば「冗長な導入文を毎回削っている」「専門用語の説明が不足して毎回補っている」といったパターンが見つかれば、以下のようにフィードバック先を振り分けられます。ここでは、フィードバックを受け止める層として、人間のレビュー前に問題を検出する事前チェックエージェントも加えています。
- プランナースキルへのフィードバック: セクション構成の粒度や対象読者の前提知識の設定を調整する
- ライタースキルへのフィードバック: 執筆ルールに「導入文は簡潔にする」「専門用語には初出時に説明を付ける」を追加する
- 事前チェックエージェントへのフィードバック: 人間のレビュー前に「冗長な導入文」「説明なしの専門用語」を検出するチェック項目を追加する
ライタースキルにすべてのチェックルールを組み込む方法もありますが、ルールが増えるほどライタースキルのプロンプトが肥大化し、本来の執筆パフォーマンスが低下します。執筆と検査を別のエージェントに分離することで、それぞれの役割に集中させています。
分析対象が変わっても、「ログを読み、改善案を導出し、定義に反映する」という構造は同じです。
まとめ
本記事では、エージェント環境におけるログコスト構造の逆転と、その非対称性を活かした設計パターンを解説しました。
要点は以下の3つです。
- エージェント環境ではログ取得コストが事実上ゼロになり、人間の介入がもっとも高価な操作になる
- この非対称性を活かし、安価なログを分析してスキル自体を改善するセルフフィードバックパターンが成立する
- HITL構成では、蓄積したログから事前チェックエージェントを強化し、人間の介入回数と認知負荷を削減できる
人間とLLMエージェントの能力は非対称です。ログの取得と分析はLLMが圧倒的に得意な領域であり、この強みを活かして人間が判断に集中する設計が、エージェント時代の協業パターンです。