fix(phase25): I2 NIM system prompt + I4 field_path 正則匹配修正
Some checks failed
CD Pipeline / Deploy Prometheus Alert Rules (push) Has been cancelled
CD Pipeline / build-and-deploy (push) Has been cancelled

I2: nemotron.analyze() 補上 system role (NIM 標準 message format)
    - 舊: messages=[{role:user, ...}]
    - 新: messages=[{role:system, ...}, {role:user, ...}]
    - 效果: K8s operator 角色定義,改善 tool calling 品質

I4: drift_detector._is_allowlisted/_is_critical 用正則取代 strip
    - 舊: replace('[*]','') 後 startswith/in → 無法匹配 containers[0]
    - 新: [*] → \[\d+\] 正則,正確匹配所有索引
    - 修復: containers[*].image 現在能匹配 containers[0].image
This commit is contained in:
OG T
2026-04-05 12:11:05 +08:00
parent 73577f7c5d
commit 53e1ae7ad7
2 changed files with 36 additions and 12 deletions

View File

@@ -171,9 +171,21 @@ class NemotronProvider:
timeout = getattr(settings, "NEMOTRON_TIMEOUT_SECONDS", 45)
nvidia = self._get_nvidia()
# 2026-04-05 Claude Code: I2 修正 — 補上 system prompt (NIM 標準 message format)
# NIM API 要求 system role 先定義模型角色,否則 tool calling 品質下降
result = await asyncio.wait_for(
nvidia.tool_call(
messages=[{"role": "user", "content": tool_prompt}],
messages=[
{
"role": "system",
"content": (
"你是 Kubernetes 操作專家。根據 AI 診斷結果,"
"使用提供的工具生成精確的 kubectl 操作指令。"
"優先選擇最安全、最小影響範圍的操作。"
),
},
{"role": "user", "content": tool_prompt},
],
tools=_K8S_TOOLS,
),
timeout=timeout,

View File

@@ -296,22 +296,34 @@ class DriftDetector:
return diffs
@staticmethod
def _pattern_matches(pattern: str, field_path: str) -> bool:
"""
匹配 field_path 是否符合 pattern。
支援兩種萬用字元:
- [*] → 任意索引 (e.g. containers[*] 匹配 containers[0], containers[1])
- * → 任意字串段
2026-04-05 Claude Code: I4 修正 — 舊邏輯直接 strip [*] 導致
containers[*].image 無法匹配 containers[0].image (首席架構師 Review I4)
"""
import re as _re
# 將 pattern 轉為正則:[*] → \[\d+\]* → [^.]+
regex = _re.escape(pattern)
regex = regex.replace(r"\[\*\]", r"\[\d+\]")
regex = regex.replace(r"\*", r"[^.]+")
# 允許 pattern 是前綴field_path 可能更深,. 或 [ 或字串結尾均可)
return bool(_re.match(f"^{regex}(\\.|\\[|$)", field_path))
def _is_allowlisted(self, field_path: str) -> bool:
"""判斷欄位是否在白名單(靜默記錄不告警)"""
for pattern in self._allowlist:
# 簡單前綴匹配(*替換為粗略包含)
clean_pattern = pattern.replace("[*]", "")
if field_path.startswith(clean_pattern.replace("*", "")):
return True
return False
return any(self._pattern_matches(p, field_path) for p in self._allowlist)
def _is_critical(self, field_path: str) -> bool:
"""判斷欄位是否為關鍵欄位HIGH 等級)"""
for pattern in self._critical_fields:
clean_pattern = pattern.replace("[*]", "")
if clean_pattern.replace("*", "") in field_path:
return True
return False
return any(self._pattern_matches(p, field_path) for p in self._critical_fields)
# =============================================================================