feat(adr-082): Phase 2 多 Agent 協作 — 5 角色辯證系統骨架上線

新增 5 個 Agent + Orchestrator + DecisionManager 接線:
- protocol.py: DiagnosisReport / ActionPlan / ReviewVerdict / CriticReport / DecisionPackage 型別系統
- DiagnosticianAgent: RCA 根因分析,confidence < 0.4 → ABSTAIN
- SolverAgent: 修復方案軍師,blast_radius 評分 + 降級 rule-based mock
- ReviewerAgent: 安全審查,HARD_RULES 靜態 pattern + blast_radius 閾值 (>50 revision, >80 reject)
- CriticAgent: 刻意唱反調,強制 3 問批判性思維,critical challenge → REJECT
- CoordinatorAgent: 純規則聚合,6 級決策閘,REQUEST_REVISION → 強制人工
- AgentOrchestrator: 30s 全局超時,Reviewer ‖ Critic 並行,DB Immutable Event Sourcing + Redis Streams
- DecisionManager: AIOPS_P2_ENABLED gate + _package_to_proposal_data 橋接既有 proposal_data 格式
- AgentSession DB table + 4 個複合 index
- ADR-082 決策記錄

Gate 2 修復(7 項):
- CRITICAL: DELETE FROM regex lookahead 位置錯誤(移至 FROM 後)
- CRITICAL: REQUEST_REVISION 可抵達 auto-execute 路徑(改回 requires_human_approval=True)
- IMPORTANT: _extract_json flat regex 不支援巢狀 JSON(改 find/rfind 邊界提取)
- IMPORTANT: all_degraded 遺漏 verdict.degraded(補全 4 個 Agent)
- IMPORTANT: Solver ABSTAIN guard 放行降級假設(改為無論 hypotheses 有無均跳過)
- IMPORTANT: dataclasses.asdict() Enum 未序列化導致 DB 寫入靜默失敗(加 json.dumps default handler)
- IMPORTANT: P2 gate 直讀屬性繞過父 Phase 守衛(改用 is_phase_enabled(2))

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
OG T
2026-04-15 13:33:13 +08:00
parent d51705b4ec
commit 5ddba6d6e0
11 changed files with 2171 additions and 4 deletions

View File

@@ -833,3 +833,79 @@ class IncidentEvidence(Base):
Index("ix_incident_evidence_collected_at", "collected_at"),
Index("ix_incident_evidence_playbook_id", "matched_playbook_id"),
)
# =============================================================================
# AgentSession — Phase 2 多 Agent 辯證 Audit Trail
# =============================================================================
class AgentSession(Base):
"""
ADR-082 Phase 2: 多 Agent 辯證 Immutable Event Log
每個 Agent 每次「發言」寫一行。
session_id 串連同一次 Incident 決策的所有 Agent turns。
不可刪除 — 只能新增Immutable Event Sourcing
Phase 3 學習閉環依賴此表Critic 挑戰成功作為負向學習信號)。
ADR-082: 多 Agent 協作架構
2026-04-15 ogt + Claude Sonnet 4.6(亞太): Phase 2 初始建立
"""
__tablename__ = "agent_sessions"
id: Mapped[str] = mapped_column(
String(36), primary_key=True, default=lambda: str(uuid4()),
comment="行主鍵UUID"
)
session_id: Mapped[str] = mapped_column(
String(36), nullable=False,
comment="辯證 Session ID一次 Incident 決策的所有 turns 共用同一 session_id"
)
incident_id: Mapped[str] = mapped_column(
String(50), nullable=False,
comment="關聯 Incident ID"
)
agent_role: Mapped[str] = mapped_column(
String(20), nullable=False,
comment="Agent 角色diagnostician / solver / reviewer / critic / coordinator"
)
# 輸入指紋sha256[:16])— 用於查重、快取命中追蹤
input_hash: Mapped[str] = mapped_column(
String(16), nullable=False, default="",
comment="sha256(input_json)[:16],供查重與快取命中追蹤"
)
# Agent 輸出(完整 JSON供 Phase 3 學習 + 事後複盤)
output_json: Mapped[dict] = mapped_column(
JSON, nullable=False, default=dict,
comment="Agent 原始輸出DiagnosisReport / ActionPlan / 等序列化 dict"
)
# 品質指標
latency_ms: Mapped[int] = mapped_column(
Integer, nullable=False, default=0,
comment="此 Agent 的執行耗時ms"
)
vote: Mapped[str] = mapped_column(
String(20), nullable=False, default="abstain",
comment="Agent 投票approve / reject / request_revision / abstain / degraded"
)
degraded: Mapped[bool] = mapped_column(
nullable=False, default=False,
comment="True = 此 Agent 因熔斷/超時降級,輸出為 rule-based mock"
)
# 時間戳(台北時區)
created_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True), default=taipei_now, nullable=False
)
__table_args__ = (
Index("ix_agent_sessions_session_id", "session_id"),
Index("ix_agent_sessions_incident_id", "incident_id"),
Index("ix_agent_sessions_created_at", "created_at"),
# 查詢某 session 中特定 role 的 turnCoordinator 聚合時常用)
Index("ix_agent_sessions_session_role", "session_id", "agent_role"),
)