2026-06-04 10:04:23 +08:00

42 lines
1.9 KiB
Python

"""LLM 结构化输出的校验和安全护栏。"""
from __future__ import annotations
from pam_deploy_graph.constants import ALLOWED_ACTIONS
from pam_deploy_graph.models import LlmDeployPlan, LlmIntentResult, LlmModeDecision
VALID_INTENTS = {"deploy", "show_usage", "preview", "query_node_ips", "rollback"}
VALID_EXECUTION_MODES = {"fixed_runtime", "agentic_skill"}
VALID_RISK_LEVELS = {"low", "medium", "high"}
FORBIDDEN_TEXT = ("bash ", "powershell ", "deploy.sh", "deploy.ps1", "CLIENT_SECRET=")
def validate_intent_result(result: LlmIntentResult) -> None:
"""校验意图识别结果是否合法。"""
if result.intent not in VALID_INTENTS:
raise ValueError(f"非法意图: {result.intent}")
if not 0 <= result.confidence <= 1:
raise ValueError("意图置信度必须在 0 到 1 之间")
def validate_deploy_plan(plan: LlmDeployPlan) -> None:
"""校验部署计划中的 action 和文本安全性。"""
invalid = [action for action in plan.planned_actions if action not in ALLOWED_ACTIONS]
if invalid:
raise ValueError(f"计划包含非法 action: {', '.join(invalid)}")
combined_text = "\n".join([plan.summary, *plan.risk_notes])
lowered = combined_text.lower()
forbidden = [item for item in FORBIDDEN_TEXT if item.lower() in lowered]
if forbidden:
raise ValueError(f"计划包含禁止出现的可执行文本: {', '.join(forbidden)}")
def validate_mode_decision(result: LlmModeDecision, allowed_modes: list[str] | None = None) -> None:
"""校验模式决策结果是否合法。"""
if result.mode not in VALID_EXECUTION_MODES:
raise ValueError(f"非法执行模式: {result.mode}")
if result.risk_level not in VALID_RISK_LEVELS:
raise ValueError(f"非法风险等级: {result.risk_level}")
if allowed_modes and result.mode not in allowed_modes:
raise ValueError(f"模式 {result.mode} 不在允许集合内")