エージェントアーキテクチャ監査 は何をしますか?
ラッパー層、古いメモリ、リトライループ、またはトランスポート/レンダリングの改変の背後に障害を隠すエージェントシステムのための診断ワークフロー。
いつ有効にするか
必須: 以下の場合
- エージェントまたは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. レンダリング/トランスポート破損
エージェントの内部回答は正しいが、プラットフォーム層が配信中にそれを改変する。
症状:
- ログには正しい回答が記録されているが、ユーザーには壊れた出力が表示される
- Markdownレンダリング、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 | ほとんどが外観上または保守性の問題 | バックログ |
出力形式
発見事項を次の順序でユーザーに提示:
- 深刻度順の発見事項(最も深刻なものから順)
- アーキテクチャ診断(どの層が何を、なぜ破損させたか)
- 順序付けられた修正計画(プロンプトファーストではなくコードファースト)
賛辞や要約で始めないでください。システムが壊れている場合は、直接そう言ってください。
クイック診断質問
エージェントシステムを監査するときは、以下に回答:
| # | 質問 | Yesの場合 → |
|---|---|---|
| 1 | モデルは必要なツールをスキップして回答できるか? | ツールがコードでゲートされていない |
| 2 | 古い会話の内容が新しいターンに現れるか? | メモリ汚染 |
| 3 | 同じ情報がシステムプロンプトとメモリと履歴にあるか? | コンテキスト重複 |
| 4 | プラットフォームは配信前に2回目のLLMパスを実行するか? | 隠れた修復ループ |
| 5 | 出力は内部生成とユーザー配信で異なるか? | レンダリング破損 |
| 6 | 「ツールXを必ず使用」というルールがプロンプトテキストのみにあるか? | ツール規律障害 |
| 7 | エージェント自身のモノローグが永続メモリになり得るか? | メモリ汚染 |
避けるべきアンチパターン
- ラッパー層の回帰を反証する前にモデルを非難しないこと。
- 汚染経路を示さずにメモリを非難しないこと。
- 現在のクリーンな状態で、過去の汚いインシデントを消し去らないこと。
- Markdownの散文を信頼できる内部プロトコルとして扱わないこと。
- コードが決して強制しないときに、プロンプトテキストの「必ずツールを使用」を受け入れないこと。
- 発見事項は直接的で、証拠に基づき、深刻度順に並べること。
レポートスキーマ
監査は次の形状の構造化レポートを生成する必要があります:
{
"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— ゼロからエージェントハーネスを構築