Agent Architecture Audit (エージェントアーキテクチャ監査)
ラッパー層、古いメモリ、リトライループ、またはトランスポート/レンダリングの変更によって障害が見えにくくなっているエージェントシステム向けの診断ワークフローです。
実行タイミング
必須条件:
- エージェントまたはLLMを利用したアプリケーションを本番環境にリリースする場合
- ツール呼び出し、メモリ、またはマルチステップワークフローを含む機能をリリースする場合
- ラッパー層を追加した後にエージェントの動作が劣化した場合
- ユーザーから「エージェントが悪化している」「ツールの動作が不安定」との報告があった場合
- 同じモデルがプレイグラウンドでは正常に動作するが、ラッパー内では異常動作する場合
- エージェントの動作を15分以上デバッグしても根本原因が特定できない場合
特に重要な場合:
- 新しいプロンプト層、ツール定義、またはメモリシステムを追加した場合
- システム内の異なるエージェントの動作に一貫性がない場合
- モデルは昨日までは問題なかったのに、今日は幻覚を起こしている場合
- 隠れた修復/リトライループが静かに応答を変更している疑いがある場合
使用すべきでない場合:
- 一般的なコードデバッグ —
agent-introspection-debuggingを使用してください - コードレビュー — 言語固有のレビューエージェントを使用してください
- セキュリティスキャン —
security-reviewまたはsecurity-review/scanを使用してください - エージェントパフォーマンスベンチマーク —
agent-evalを使用してください - 新機能の作成 — 適切なワークフロースキルを使用してください
12層スタック
すべてのエージェントシステムには以下の層があります。どの層でも回答を破損させる可能性があります:
| # | 層 | 問題の内容 |
|---|---|---|
| 1 | システムプロンプト | 矛盾する指示、指示の肥大化 |
| 2 | セッション履歴 | 以前のターンからの古いコンテキストの混入 |
| 3 | 長期記憶 | セッションをまたがる汚染、新しい会話への古いトピックの混入 |
| 4 | 蒸留 | 圧縮された成果物が疑似事実として再混入 |
| 5 | アクティブリコール | 冗長な再要約層がコンテキストを浪費 |
| 6 | ツール選択 | 誤ったツールルーティング、モデルが必要なツールをスキップ |
| 7 | ツール実行 | 幻覚的な実行 — 呼び出しを主張するが実際には実行しない |
| 8 | ツール解釈 | ツール出力の誤読または無視 |
| 9 | 回答整形 | 最終応答におけるフォーマット破損 |
| 10 | プラットフォームレンダリング | トランスポート層での変更(UI、API、CLIが有効な回答を変更) |
| 11 | 隠れた修復ループ | 静かに動作するフォールバック/リトライエージェントによる2回目のLLMパス |
| 12 | 永続化 | 期限切れの状態、またはライブな証拠として再利用されるキャッシュされた成果物 |
一般的な障害パターン
1. ラッパー回帰
ベースモデルは正しい回答を生成するが、ラッパー層がそれを悪化させる。
症状:
- モデルはプレイグラウンドや直接API呼び出しでは正常に動作するが、エージェント内では動作しない
- 新しいプロンプト層を追加した後、既存の動作が劣化した
- エージェントは自信満々だが、自信を持って間違っている
- 「前回のアップデートまでは動いていた」
2. メモリ汚染
履歴、メモリ検索、または蒸留を通じて、古いトピックが新しい会話に漏れ込む。
症状:
- エージェントが無関係な過去のトピックを持ち出す
- ユーザーの修正が反映されない(古いメモリが新しい情報を上書きする)
- 同一セッションの成果物が疑似事実として再混入する
- メモリが無制限に増加し、時間の経過とともに応答品質が低下する
3. ツール規律違反
ツールがプロンプトで宣言されているが、コードで強制されていない。モデルがツールをスキップしたり、実行を幻覚したりする。
症状:
- プロンプトに「ツールXを必ず使用すること」とあるが、モデルがそれを呼び出さずに回答する
- ツールの結果は正しく見えるが、実際には実行されていない
- 異なるツールが同じ責任をめぐって競合する
- モデルが不必要なときにツールを使用したり、必要なときにスキップしたりする
4. レンダリング/トランスポート破損
エージェントの内部回答は正しいが、プラットフォーム層が配信中にそれを変更する。
症状:
- ログには正しい回答が記録されているが、ユーザーには壊れた出力が見える
- マークダウンレンダリング、JSONパース、またはストリーミングフラグメントが有効な応答を破損する
- 隠れたフォールバックエージェントが配信前に静かに回答を置き換える
- ターミナルとUIで出力が異なる
5. 隠れたエージェント層
明示的な契約なしに、サイレント修復、リトライ、要約、またはリコールエージェントが動作する。
症状:
- 内部生成時とユーザー配信時で出力が異なる
- 「自動修正」ループがユーザーに知られずに2回目のLLMパスを実行する
- 複数のエージェントが調整なしに同じ出力を変更する
- 回答が不可視の層によって「平滑化」または「修正」される
監査ワークフロー
フェーズ1: スコープ
監査対象を定義します:
- 対象システム — どのエージェントアプリケーションか?
- エントリポイント — ユーザーはどのように操作するか?
- モデルスタック — どのLLMとプロバイダーか?
- 症状 — ユーザーは何を報告しているか?
- 時間枠 — いつから発生しているか?
- 監査対象層 — 12層のうちどの層が該当するか?
フェーズ2: 証拠収集
コードベースから証拠を収集します:
- ソースコード — エージェントループ、ツールルーター、メモリアドミッション、プロンプトアセンブリ
- ログ — 過去のセッショントレース、ツール呼び出し記録
- 設定 — プロンプトテンプレート、ツールスキーマ、プロバイダー設定
- メモリファイル — SOP、ナレッジベース、セッションアーカイブ
rg を使用してアンチパターンを検索します:
# ツール要件がコードではなくプロンプトテキストでのみ表現されている
rg "must.*tool|必須.*工具|required.*call" --type md
# 検証なしのツール実行
rg "tool_call|toolCall|tool_use" --type py --type ts
# メインのエージェントループ外の隠れたLLM呼び出し
rg "completion|chat\.create|messages\.create|llm\.invoke"
# ユーザー修正優先順位なしのメモリアドミッション
rg "memory.*admit|long.*term.*update|persist.*memory" --type py --type ts
# 追加のLLM呼び出しを実行するフォールバックループ
rg "fallback|retry.*llm|repair.*prompt|re-?prompt" --type py --type ts
# 静かな出力変更
rg "mutate|rewrite.*response|transform.*output|shap" --type py --type ts
フェーズ3: 障害マッピング
各発見事項について、以下を文書化します:
- 症状 — ユーザーに何が見えるか
- メカニズム — ラッパーがどのようにそれを引き起こすか
- ソース層 — 12層のうちどれか
- 根本原因 — 最も深い原因
- 証拠 — ファイル:行 または ログ:行 の参照
- 確信度 — 0.0 から 1.0
フェーズ4: 修正戦略
デフォルトの修正順序(プロンプト優先ではなく、コード優先):
- ツール要件をコードでゲートする — プロンプトテキストだけでなく、コードで強制する
- 隠れた修復エージェントを削除または制限する — フォールバックを明示的な契約とする
- コンテキストの重複を減らす — 同じ情報をプロンプト+履歴+メモリ+蒸溜で持たない
- メモリアドミッションを厳格化する — ユーザー修正 > エージェントの主張
- 蒸留トリガーを厳格化する — 圧縮すべきでないものを圧縮しない
- レンダリングの変更を減らす — 変換せずにパススルーする
- 型付きJSONエンベロープに変換する — 自由形式の散文ではなく、構造化された内部フロー
重大度モデル
| レベル | 意味 | アクション |
|---|---|---|
critical | エージェントが自信を持って誤った運用上の振る舞いを生成する可能性がある | 次のリリース前に修正 |
high | エージェントが頻繁に正確性や安定性を低下させる | 今スプリントで修正 |
medium | 正確性は通常維持されるが、出力が脆弱または無駄が多い | 次のサイクルで計画 |
low | ほとんどが外観上または保守性の問題 | バックログ |
出力形式
所見を以下の順序でユーザーに提示します:
- 重大度順の所見(最も重大なものから順に)
- アーキテクチャ診断(どの層が何を破損したか、そしてその理由)
- 順序付き修正計画(プロンプト優先ではなく、コード優先)
賛辞や要約で始めないでください。システムが壊れている場合は、直接そのように述べてください。
クイック診断質問
エージェントシステムを監査する際は、以下の質問に答えてください:
| # | 質問 | はいの場合 → |
|---|---|---|
| 1 | モデルは必要なツールをスキップして回答できますか? | ツールがコードでゲートされていない |
| 2 | 古い会話の内容が新しいターンに出現しますか? | メモリ汚染 |
| 3 | 同じ情報がシステムプロンプトとメモリと履歴にありますか? | コンテキストの重複 |
| 4 | プラットフォームは配信前に2回目のLLMパスを実行しますか? | 隠れた修復ループ |
| 5 | 内部生成時とユーザー配信時で出力が異なりますか? | レンダリング破損 |
| 6 | 「ツールXを必ず使用」というルールがプロンプトテキストのみにありますか? | ツール規律違反 |
| 7 | エージェント自身の独白が永続メモリになりますか? | メモリ汚染 |
避けるべきアンチパターン
- ラッパー層の回帰を反証する前にモデルを非難するのは避けてください。
- 汚染経路を示さずにメモリを非難するのは避けてください。
- 現在の状態がきれいだからといって、過去の汚いインシデントを消し去らないでください。
- マークダウンの散文を信頼できる内部プロトコルとして扱わないでください。
- コードが決して強制しない場合に、プロンプトテキストの「必ずツールを使用」を受け入れないでください。
- 所見は直接的で、証拠に基づき、重大度順にランク付けしてください。
レポートスキーマ
監査は以下の構造に従った構造化レポートを生成する必要があります:
{
"schema_version": "ecc.agent-architecture-audit.report.v1",
"executive_verdict": {
"overall_health": "high_risk",
"primary_failure_mode": "string",
"most_urgent_fix": "string"
},
"scope": {
"target_name": "string",
"model_stack": ["string"],
"layers_to_audit": ["string"]
},
"findings": [
{
"severity": "critical|high|medium|low",
"title": "string",
"mechanism": "string",
"source_layer": "string",
"root_cause": "string",
"evidence_refs": ["file:line"],
"confidence": 0.0,
"recommended_fix": "string"
}
],
"ordered_fix_plan": [
{ "order": 1, "goal": "string", "why_now": "string", "expected_effect": "string" }
]
}
関連スキル
agent-introspection-debugging— エージェントのランタイム障害(ループ、タイムアウト、状態エラー)をデバッグagent-eval— エージェントのパフォーマンスを直接比較ベンチマークsecurity-review— コードと設定のセキュリティ監査autonomous-agent-harness— 自律エージェント運用のセットアップagent-harness-construction— エージェントハーネスをゼロから構築