Claude Agent Teamsの責任分離YAMLテンプレート
はじめに
これは「エージェントの判断を“監査可能&再発防止”にする最小アーキテクチャ」の提案です。人とAIの役割を4つに分け、入出力の型、監査ログ、署名・アンカー、受け入れ検査をひとつのYAMLで束ねます。
AIエージェントの自律実行で怖いのは「誰が何を根拠に決めたか」が残らないことです。4ロール分担と署名・アンカー付きYAMLで判断を監査可能にし、失敗を再発防止ルールへ昇格できます。
なぜ必要か
生成AIが「いつ・誰が・何を根拠に決めたか」を曖昧にすると、事故対応も改善学習も止まります。
判断の“理由”と“権限境界”を分離し、決定→署名→実行を段階化すると、失敗の再発防止(RuleCandidate化)とCIゲートが機械可読になります。
全体像(4ロール+型+監査)
reasoner: 候補と根拠を束ねた DecisionObject を提案
adjudicator: スコアリングと最終決定(or エスカレーション)
operator: 署名&アンカー確認後のみ副作用を実行
auditor: 週次でアンカーと有効性を点検(再発率を監視)
ドロップインYAML(そのまま使える最小形)
version: "1.0"
roles:
- name: reasoner
id: reasoner
purpose: "propose DecisionObject (candidates + evidence_refs)"
- name: adjudicator
id: adjudicator
purpose: "score/vote candidates, emit finalDecision or FailureRecord"
- name: operator
id: operator
purpose: "perform side-effects only after finalDecision + signed_anchor"
- name: auditor
id: auditor
purpose: "periodic review of append_only anchors + RuleCandidate efficacy"
io_contracts:
DecisionObject:
type: object
required: [id, actor_id, timestamp, request_hash, evidence_refs, candidates]
properties:
id: {type: string, format: uuid}
actor_id: {type: string}
timestamp: {type: string, format: date-time}
request_hash: {type: string, pattern: "^[0-9a-f]{64}$"}
evidence_refs: {type: array, minItems: 1, items: {type: string, format: uri}}
candidates:
type: array
items:
type: object
required: [id, rule_snippet, score]
properties:
id: {type: string}
rule_snippet: {type: string}
score: {type: number, minimum: 0, maximum: 1}
AdjudicationResult:
required: [decision_id, chosen_candidate_id, votes, confidence, outcome, evidence_refs]
properties:
decision_id: {type: string}
chosen_candidate_id: {type: string}
votes: {type: array, items: {type: object}}
confidence: {type: number, minimum: 0, maximum: 1}
outcome: {type: string, enum: ["approved","rejected","escalate"]}
evidence_refs: {type: array, items: {type: string, format: uri}}
dsse_signature_uri: {type: string, format: uri}
merkle_anchor_uri: {type: string, format: uri}
logging_schema:
audit_event:
fields: [ts, agent_id, session_id, event_type, payload_hash, dsse_sig_uri, merkle_anchor_uri, immutable_blob_uri]
persistence_patterns:
RuleCandidateRecord:
fields: [rule_candidate_id, derived_from_failure_id, created_by, rationale_hash, dsse_signature_uri, merkle_anchor_uri, persisted_at]
persist_mode: "append_only_signed"
retention_days: 1825
acceptance_checks:
- id: A1
description: "Evidence required"
assert: "set(DecisionObject.evidence_refs) subset_of set(AdjudicationResult.evidence_refs)"
- id: A2
description: "Signature + anchor required for side-effects"
assert: "if AdjudicationResult.outcome == 'approved' then dsse_verify(AdjudicationResult.dsse_signature_uri) == true AND exists(AdjudicationResult.merkle_anchor_uri)"
- id: A3
description: "Conflict escalation when scores too close"
assert: "(top_score - second_score) <= 0.25 -> AdjudicationResult.outcome != 'approved'"
- id: A4
description: "RuleCandidate gating via CI"
assert: "RuleCandidate.test_cases.exist AND CI_signed_artifact == true"
operational_notes:
- "Gatewayはpayloadを正規化→sha256しrequest_hashと一致しない場合はfail-closed。"
- "DSSE署名はピン留め鍵で検証。公開鍵は月次ローテーション(root署名付き)。"
- "Merkleアンカーは署名付きルート+タイムスタンプ証人をappend-only保管。auditorが週次監査。"
- "operatorはA1/A2合格+finalDecision参照が揃うまで書き込み禁止。"実装のコツ(最短ルート)
I/Oを“型”で強制:LLM出力は必ず DecisionObject / AdjudicationResult にマップ。自由テキストは添付に退避。
副作用は鍵で封じる:approved ∧ (DSSE✔ ∧ Merkle✔) のときだけ実行キーを発行。
失敗は資産化:失敗→FailureRecord→RuleCandidateRecord に昇格。CIでテストが緑になったらだけ自動反映。
再発防止の計測:監査は「類似失敗の再発率」と「RuleCandidateのヒット率」を週次で可視化。
Claude Code / Agent Teamsへの当て込み例
reasoner=Claude Code(設計/ルール案生成)、adjudicator=別セッション(投票&信頼度統合)、operator=CI/Actions、auditor=週次ジョブ(アンカー検証+再発率集計)。
ゲートは YAMLの acceptance_checks をCIで機械評価すればOK。
まとめ
判断は reasoner→adjudicator→operator→auditor に分離し、提案・採択・実行・監査の境界を固定します。
入出力を DecisionObject と AdjudicationResult の型で縛り、証拠参照と監査ログを同じスキーマで残します。
署名とMerkleアンカーを満たした承認だけが副作用を起こし、失敗はRuleCandidateとしてCIで回帰テストに組み込みます。
次に、既存の自動化タスク1件を選び、このYAMLのA1〜A4をCIに30分で追加してください。
