Domain 5: Context Management & Reliability
配点 15% — Task 5.1〜5.6
5.1 コンテキスト管理
| 課題 | 対策 |
|---|---|
| 重要な数値データ(金額・日付)が要約で失われる | 要約履歴とは別に、transactional ファクトを永続的な「case facts」ブロックとして各プロンプトに含める |
| ツール出力が大量のトークンを消費 | 関連フィールドのみにトリミングしてからコンテキストに追加(例: order lookup の 40+ フィールド → 5 フィールド) |
| コードベース探索でのコンテキスト劣化 | scratchpad ファイルに重要な発見を記録し、後続の質問でそのファイルを参照する |
5.2 エスカレーション設計
エスカレーションは 「いつ」「何を」「どのように」 人間に渡すかを設計する問題です。試験では「シナリオ X で最も適切なエスカレーション戦略は?」が頻出します。以下の 4 分類はタイミングで整理したものです。
| 分類 | タイミング | 典型シナリオ | 引き継ぎ内容 |
|---|---|---|---|
| 即時 | 調査を先行させず即対応 | 顧客が人間を明示的に要求した・暴言・自殺予兆・法的請求の予告 | 元の発話・直前の会話履歴・顧客 ID |
| 解決試行後 | エージェントが 1〜2 回試した上で進捗が出ない場合 | 複雑なリファンド計算で必要な情報が欠落・ツール失敗が連鎖 | 試した手順・各ステップの結果・残った不明点 |
| 段階的 | 認識 → 解決試行 → 失敗 → エスカレーション、の順で踏む | 通常のサポート問い合わせがエージェントの能力を超えていることが判明 | 認識した問題・試したアプローチ・なぜ失敗したか |
| ポリシーギャップ | エージェントの権限・ポリシーに例外が必要 | $500 超の返金、規約に明示されていない例外請求、新規ポリシー策定が必要なケース | 顧客の要求・該当する既存ポリシー・例外を許容すべき理由 |
即座にエスカレーションすべき 3 条件(試験頻出)
- 顧客が人間エージェントを 明示的に要求した(調査を先行させず即座に対応)
- ポリシーに ギャップや例外が存在する(複雑さだけでなくポリシーの曖昧さ)
- エージェントが 意味のある進捗を生み出せない
センチメントスコアや自己報告型信頼スコアはエスカレーション基準として使えない(複雑度と相関しない)
構造化引き継ぎプロトコル
エスカレーション時にエージェントが人間オペレーターに渡す情報は、自然言語の要約ではなく 構造化された JSON にすると、ハンドオフの取りこぼしが減ります。試験では「自由形式のサマリーで引き継ぎ」が誤答として出ます。
// ✅ 構造化引き継ぎペイロードの最小一式
type EscalationHandoff = {
escalation_type: 'immediate' | 'after_attempt' | 'progressive' | 'policy_gap'
reason: string // なぜエスカレーションが必要か(1 文)
case_facts: { // transactional facts(圧縮しない)
customer_id: string
case_id: string
amounts?: { currency: string; value: number }[]
dates?: { kind: string; iso: string }[]
}
conversation_summary: string // 直前 N ターンの要約(人間が読む用)
attempted_actions: { // 試したアクションと結果
action: string
result: 'success' | 'failure' | 'partial'
error?: { errorCategory: string; message: string }
}[]
policy_references: string[] // 関連ポリシー条項の ID
open_questions: string[] // 解決していない論点
suggested_next_action?: string // エージェントの推奨(人間が override 可能)
}
// 即時エスカレーション例
const immediate: EscalationHandoff = {
escalation_type: 'immediate',
reason: '顧客が "人間と話したい" と明示的に要求',
case_facts: { customer_id: 'cust_123', case_id: 'case_456' },
conversation_summary: '...',
attempted_actions: [], // 即時は試行なし
policy_references: [],
open_questions: ['顧客の元の問い合わせ内容']
}引き継ぎ JSON は「圧縮対象外」
5.4 コンテキスト圧縮戦略 で扱う case_facts ブロックと、この EscalationHandoff.case_facts は 同じ思想(金額・日付・ID は要約で失わない)です。長時間のセッションをまたいでエスカレーションする場合、case_facts を永続化しておくと、新しいオペレーター(あるいは新しいエージェントセッション)が文脈をゼロから再構築せずに引き継げます。
5.3 マルチエージェントエラー伝播
| ❌ Anti-patterns | ✅ 正しいエラー伝播 |
|---|---|
| ① タイムアウトを空リストで成功として返す → コーディネーターが「結果なし」と誤解 ② 単一失敗でワークフロー全体終了 → 部分結果が失われる ③ “search unavailable” と汎用エラー返却 → 回復判断に必要な情報がない | 構造化エラーコンテキストを返す: • 失敗タイプ(transient / permission 等) • 試みたクエリ • 部分的な結果(あれば) • 代替アプローチの提案 → コーディネーターが適切に回復判断 |
5.4 コンテキスト圧縮戦略
長時間のセッションではコンテキストが肥大化します。Claude Code の /compact コマンドや手動の構造化サマリーで圧縮しますが、「何を残し、何を捨てるか」の設計が試験で問われます。
| 戦略 | 方法 | 使いどころ |
|---|---|---|
/compact コマンド | 会話履歴を要約に置き換え。Claude 自身がサマリー生成 | Claude Code セッションが長くなりすぎたとき |
| Scratchpad パターン | 重要な発見をファイルに書き出し、後で必要なときだけ参照 | コードベース探索・大量ドキュメント分析 |
| Case Facts ブロック | 各プロンプト先頭に永続的な事実ブロック(金額・ID・期日)を再注入 | カスタマーサポートエージェントの長時間セッション |
| ツール出力トリミング | 関連フィールドのみ抽出してコンテキストに追加 | order lookup API が 40 フィールド返すが必要なのは 5 フィールドだけのとき |
| Fresh start + structured summary | 新セッション開始時に前セッションの構造化サマリーを注入 | 古いツール結果が陳腐化した場合 |
圧縮の罠:要約で数値が失われる
/compact のような自動要約は、金額・日付・ID などの transactional facts を失いやすい。「返金額は $487.32」が「返金処理を行った」に要約されると、後続の判断ができなくなる。要約とは別に、構造化された “case facts” ブロックを永続的に保持 することが重要。
5.5 失敗からのリカバリーパターン
本番環境では失敗は避けられません。「失敗をどう扱うか」がアーキテクチャの品質を決めます。試験では特定のシナリオで「最も適切なリカバリー戦略は?」が頻出します。
| 失敗タイプ | 正しいリカバリー | 誤ったリカバリー(罠) |
|---|---|---|
| transient(タイムアウト・5xx) | 指数バックオフでリトライ。複数回失敗後はエスカレーション | 即座にエスカレーション(一時的な問題なのに人間負荷) |
| validation(不正入力) | 失敗内容を含めてリトライ(retry-with-error-feedback) | 盲目的に同じ入力でリトライ(無限リトライループ) |
| permission(権限不足) | 即座にエスカレーション。リトライしない | リトライ(同じ結果になる) |
| business(ポリシー違反) | 代替アクションを提示してエスカレーション | ポリシーを無視して実行 |
| information not present(情報不在) | 「情報なし」を構造化して報告。リトライしない | 「frame 変えれば見つかるかも」とリトライを繰り返す |
部分的成功の活用(マルチエージェント特有)
マルチエージェントシステムでは、1 つのサブエージェントが失敗しても他は成功している ことが多い。コーディネーターは:
- 成功した部分結果は 採用して合成 する
- 失敗した部分は 明示的にカバレッジギャップとして注釈 する
- 必要に応じて 代替手段で再委譲(別のサブエージェント・別のクエリ)
「1 つでも失敗したら全体終了」は試験で必ず誤答として出る anti-pattern。
// 部分的成功を活用するコーディネーターの実装例
const results = await Promise.allSettled(subagentTasks);
const successful = results.filter(r => r.status === "fulfilled");
const failed = results.filter(r => r.status === "rejected");
// ✅ 部分結果を採用しつつ、失敗を明示
return {
partial_results: successful.map(r => r.value),
coverage_gaps: failed.map(r => ({
attempted_query: r.reason.query,
error_type: r.reason.errorType,
suggested_alternatives: r.reason.alternatives
})),
is_complete: failed.length === 0
};
// ❌ Anti-pattern: if (failed.length > 0) throw new Error("全体失敗");5.6 情報出所(Provenance)の保持
| 課題 | 解決策 |
|---|---|
| 要約時に claim-source マッピングが失われる | サブエージェントに source URL・document 名・関連抜粋を含む構造化出力を返させ、合成エージェントが保持する |
| 複数ソースが競合する数値を示す | どちらかを選択せず、両方を帰属付きで明示的に注釈。conflict_detected フラグを追加 |
| 時系列データの矛盾 | 出版日・収集日を構造化出力に含めて時系列の差異と矛盾を区別 |