From 938df7f291f969fe80dabfb770d345839328391b Mon Sep 17 00:00:00 2001 From: OG T Date: Sun, 29 Mar 2026 16:00:46 +0800 Subject: [PATCH] =?UTF-8?q?fix(api):=20=E5=85=A8=E9=9D=A2=E6=B8=85?= =?UTF-8?q?=E9=99=A4=E5=81=87=E4=BF=A1=E5=BF=83=E5=88=86=E6=95=B8=20-=20?= =?UTF-8?q?=E9=81=B5=E5=BE=AA=20feedback=5Fconfidence=5Ftruthfulness.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🔴 違規修正: 規則匹配/Expert System 不是 AI 分析,confidence 必須 = 0.0 修正檔案: - agents/action_planner.py: 0.9 → 0.0 - agents/blast_radius.py: 0.85/0.5/0.9 → 0.0 - agents/security.py: 計算公式 → 0.0 - signoz_webhook.py: 0.7 → 0.0 - auto_approve.py: default 0.5 → 0.0 - ci_auto_repair.py: 整個計算函數 → return 0.0 - error_analyzer_service.py: default 0.5 → 0.0 - intent_classifier.py: 計算公式 → 0.0 - openclaw.py: default 0.5 → 0.0 - resource_resolver.py: 0.8 → 0.0 - k8s_naming.py: 0.9/0.7 → 0.0 只有 LLM 真實分析返回的 confidence 才能 > 0 Co-Authored-By: Claude Opus 4.5 --- apps/api/src/agents/action_planner.py | 2 +- apps/api/src/agents/blast_radius.py | 7 +++-- apps/api/src/agents/security.py | 4 +-- apps/api/src/api/v1/signoz_webhook.py | 2 +- apps/api/src/services/auto_approve.py | 2 +- apps/api/src/services/ci_auto_repair.py | 30 +++++-------------- .../src/services/error_analyzer_service.py | 2 +- apps/api/src/services/intent_classifier.py | 16 +++------- apps/api/src/services/openclaw.py | 4 +-- apps/api/src/services/resource_resolver.py | 2 +- apps/api/src/utils/k8s_naming.py | 4 +-- 11 files changed, 27 insertions(+), 48 deletions(-) diff --git a/apps/api/src/agents/action_planner.py b/apps/api/src/agents/action_planner.py index 13d4a67c6..b7bd06376 100644 --- a/apps/api/src/agents/action_planner.py +++ b/apps/api/src/agents/action_planner.py @@ -389,7 +389,7 @@ class ActionPlannerAgent(BaseAgent[ActionPlan]): result = ActionPlan( agent_name=self.AGENT_NAME, status=AgentStatus.SUCCESS, - confidence=0.9, + confidence=0.0, # 🔴 規則匹配/模板,非 AI 分析 analysis=analysis, latency_ms=latency_ms, action_type=template["action_type"], diff --git a/apps/api/src/agents/blast_radius.py b/apps/api/src/agents/blast_radius.py index 352d72fc6..495914f07 100644 --- a/apps/api/src/agents/blast_radius.py +++ b/apps/api/src/agents/blast_radius.py @@ -270,7 +270,7 @@ class BlastRadiusAgent(BaseAgent[BlastRadiusResult]): result = BlastRadiusResult( agent_name=self.AGENT_NAME, status=AgentStatus.SUCCESS, - confidence=0.85, # 基於依賴圖的信心分數 + confidence=0.0, # 🔴 規則/圖譜分析,非 AI analysis=analysis, latency_ms=latency_ms, impact_level=impact_level, @@ -331,7 +331,7 @@ class BlastRadiusAgent(BaseAgent[BlastRadiusResult]): affected.append(AffectedService( name=target_service, impact_type="direct", - confidence=0.5, + confidence=0.0, # 🔴 規則推斷,非 AI reason="未知服務,無法確定依賴關係", )) return affected, 1000, [target_service] @@ -391,7 +391,8 @@ class BlastRadiusAgent(BaseAgent[BlastRadiusResult]): chain.append(dep) impact_type = "indirect" if depth == 0 else "transitive" - confidence = 0.9 - (depth * 0.1) + # 🔴 規則/圖譜推斷,非 AI 分析 + confidence = 0.0 affected.append(AffectedService( name=dep, diff --git a/apps/api/src/agents/security.py b/apps/api/src/agents/security.py index 5296e03af..05bb89477 100644 --- a/apps/api/src/agents/security.py +++ b/apps/api/src/agents/security.py @@ -279,8 +279,8 @@ class SecurityAgent(BaseAgent[SecurityResult]): risk_factors.append("未偵測到明顯風險因素") max_risk_score = 2.0 # 基礎低風險 - # 計算信心分數 (規則匹配越多,信心越高) - confidence = min(0.95, 0.7 + len(risk_factors) * 0.05) + # 🔴 規則匹配,非 AI 分析,信心度設 0 + confidence = 0.0 # 生成分析摘要 if max_risk_score >= 8.0: diff --git a/apps/api/src/api/v1/signoz_webhook.py b/apps/api/src/api/v1/signoz_webhook.py index c0c4f06ea..289dcaf68 100644 --- a/apps/api/src/api/v1/signoz_webhook.py +++ b/apps/api/src/api/v1/signoz_webhook.py @@ -330,7 +330,7 @@ async def send_signoz_telegram( root_cause=summary, suggested_action=description or "請檢查 SignOz 儀表板", primary_responsibility="BE", - confidence=0.7, # SignOz 自動檢測的信心度 + confidence=0.0, # 🔴 規則匹配/告警轉發,非 AI 分析 namespace="signoz", anomaly_frequency=anomaly_frequency, ) diff --git a/apps/api/src/services/auto_approve.py b/apps/api/src/services/auto_approve.py index d187d7c3c..f2656448c 100644 --- a/apps/api/src/services/auto_approve.py +++ b/apps/api/src/services/auto_approve.py @@ -180,7 +180,7 @@ class AutoApprovePolicy: """ # 基本資訊 risk_level = proposal_data.get("risk_level", "medium").lower() - confidence = proposal_data.get("confidence", 0.5) + confidence = proposal_data.get("confidence", 0.0) # 🔴 無信心度=規則匹配 action = proposal_data.get("action", "") or proposal_data.get("kubectl_command", "") action_pattern = self._extract_action_pattern(action) diff --git a/apps/api/src/services/ci_auto_repair.py b/apps/api/src/services/ci_auto_repair.py index 579a45313..3cc3d318f 100644 --- a/apps/api/src/services/ci_auto_repair.py +++ b/apps/api/src/services/ci_auto_repair.py @@ -362,29 +362,15 @@ class CIAutoRepairService: } return reasons.get(action, "Unknown action") - def _calculate_confidence(self, action: RepairAction, error_type: str) -> float: - """計算修復信心度""" - # 基礎信心度 - base_confidence = { - RepairAction.RETRY_WORKFLOW: 0.6, - RepairAction.CLEAR_CACHE: 0.7, - RepairAction.RESTART_RUNNER: 0.8, - RepairAction.SCALE_RESOURCE: 0.5, - RepairAction.ROLLBACK_COMMIT: 0.4, - RepairAction.FIX_CONFIG: 0.3, - RepairAction.FIX_DEPENDENCY: 0.5, - RepairAction.MANUAL_REQUIRED: 0.1, - } + def _calculate_confidence(self, _action: RepairAction, _error_type: str) -> float: + """ + 計算修復信心度 - confidence = base_confidence.get(action, 0.5) - - # 錯誤類型與動作的匹配度調整 - if error_type == "timeout" and action == RepairAction.RESTART_RUNNER: - confidence += 0.2 - elif error_type == "build" and action == RepairAction.CLEAR_CACHE: - confidence += 0.15 - - return min(confidence, 1.0) + 🔴 2026-03-29 修正: 規則匹配不是 AI 分析,統一返回 0.0 + 根據 feedback_confidence_truthfulness.md 鐵律 + """ + # 規則匹配/規則引擎判斷,非 AI 分析 + return 0.0 def _estimate_duration(self, action: RepairAction) -> int: """估算修復時間 (秒)""" diff --git a/apps/api/src/services/error_analyzer_service.py b/apps/api/src/services/error_analyzer_service.py index 9cc35ff63..55d7145cd 100644 --- a/apps/api/src/services/error_analyzer_service.py +++ b/apps/api/src/services/error_analyzer_service.py @@ -329,7 +329,7 @@ class ErrorAnalyzerService: fix_recommendation=fix_recommendation, prevention=prevention, related_files=data.get("related_files", []), - confidence=float(data.get("confidence", 0.5)), + confidence=float(data.get("confidence", 0.0)), # 🔴 無信心度=規則匹配 reasoning=data.get("reasoning", ""), ) diff --git a/apps/api/src/services/intent_classifier.py b/apps/api/src/services/intent_classifier.py index d909a32a4..f04ad3b8f 100644 --- a/apps/api/src/services/intent_classifier.py +++ b/apps/api/src/services/intent_classifier.py @@ -478,21 +478,13 @@ class IntentClassifier: best_intent = max(scores, key=lambda k: scores[k][0]) best_score, matched_keywords = scores[best_intent] - # 計算信心度 (基於匹配數量) - max_possible = len(INTENT_KEYWORDS.get(best_intent, [])) * 2 - confidence = min(1.0, best_score / max(max_possible, 1) + 0.5) - - # 如果有多個競爭意圖,降低信心度 - if len(scores) > 1: - second_best_score = sorted( - [s[0] for s in scores.values()], reverse=True - )[1] - if second_best_score > best_score * 0.7: - confidence *= 0.8 + # 🔴 2026-03-29 修正: 關鍵字匹配不是 AI 分析,信心度設 0 + # 根據 feedback_confidence_truthfulness.md 鐵律 + confidence = 0.0 result = IntentResult( intent=best_intent, - confidence=round(confidence, 2), + confidence=confidence, method="keyword", matched_keywords=matched_keywords, detected_resources=detected_resources, diff --git a/apps/api/src/services/openclaw.py b/apps/api/src/services/openclaw.py index 7342874d7..c82ac436f 100644 --- a/apps/api/src/services/openclaw.py +++ b/apps/api/src/services/openclaw.py @@ -1010,7 +1010,7 @@ class OpenClawService: raw_confidence=data.get("confidence"), forcing_collab=True, ) - data["confidence"] = 0.5 # 低信心分數 + data["confidence"] = 0.0 # 🔴 LLM 未返回信心度,設為 0 data["primary_responsibility"] = "COLLAB" # 強制協作處理 # Step 3: 使用 Pydantic 驗證 (會自動正規化 risk_level, data_impact 等) @@ -1204,7 +1204,7 @@ Trace URL: {signoz_trace_url} ## 🔍 Expert System Initial Diagnosis - **Matched Rule**: {expert_context.get('initial_diagnosis', 'unknown')} - **Diagnosis**: {expert_context.get('diagnosis_description', 'N/A')} -- **Confidence**: {expert_context.get('expert_confidence', 0.5):.0%} +- **Confidence**: {expert_context.get('expert_confidence', 0.0):.0%} - **Requires Human Review**: {'Yes' if expert_context.get('requires_human_review') else 'No'} - **Suggested Diagnosis Commands**: {diagnosis_cmds_str} diff --git a/apps/api/src/services/resource_resolver.py b/apps/api/src/services/resource_resolver.py index 847a6ed73..b2609b278 100644 --- a/apps/api/src/services/resource_resolver.py +++ b/apps/api/src/services/resource_resolver.py @@ -203,7 +203,7 @@ class ResourceResolver: resource_name=best_match, namespace=normalized.namespace or namespace, resource_type=normalized.resource_type, - confidence=0.8, + confidence=0.0, # 🔴 模糊匹配,非 AI note=f"Fuzzy matched from '{raw_resource}'", original_input=raw_resource, ) diff --git a/apps/api/src/utils/k8s_naming.py b/apps/api/src/utils/k8s_naming.py index 5fac32181..39a00b2b4 100644 --- a/apps/api/src/utils/k8s_naming.py +++ b/apps/api/src/utils/k8s_naming.py @@ -242,7 +242,7 @@ def normalize_resource_name(raw: str, default_namespace: str = "awoooi-prod") -> namespace=default_namespace, resource_type=ResourceType.DEPLOYMENT, is_k8s_resource=True, - confidence=0.9, + confidence=0.0, # 🔴 規則驗證,非 AI note="Already valid K8s name", ) @@ -262,7 +262,7 @@ def normalize_resource_name(raw: str, default_namespace: str = "awoooi-prod") -> namespace=default_namespace, resource_type=ResourceType.DEPLOYMENT, is_k8s_resource=True, - confidence=0.7, + confidence=0.0, # 🔴 規則轉換,非 AI note=f"Converted from '{raw}' (requires validation)", )