package permission // 混合安全分类器 -- 核心接口和编排逻辑. // // 安全分类器是权限系统的 AI 增强层,用于在规则无法明确判断时, // 通过 AI 模型判断工具调用是否安全. // // 架构:白名单快速放行 + 规则只 deny + AI 两阶段分类 // - 白名单命中 → 直接 allow(零延迟,不调 API) // - 规则引擎只做 deny(宁可漏 deny 也不误 allow) // - AI 分类器两阶段:Stage 1 快速判断,Stage 2 深度推理 // // 精妙之处(CLEVER): 三层分类器的级联设计--白名单过滤掉 ~70% 的只读操作, // 规则引擎拦截已知危险模式,只有 ~10% 的请求需要调 AI API. // 这使得分类器在保持安全性的同时,对延迟和成本的影响极小. import ( "context" "time" ) // SecurityClassifier 安全分类器接口 - 模型无关. // 任何实现此接口的分类器都可以被 HybridClassifier 使用. // // Shape: pull. Consumer synchronously calls Classify(ctx, req) and receives // a *ClassifyResult; the 6 fields (Decision / Reason / Thinking / Stage / // Usage / DurationMs) are the pull payload. // // 形态: 调取 (pull). 消费者同步调 Classify(ctx, req) 拿 *ClassifyResult; // 6 字段 (Decision / Reason / Thinking / Stage / Usage / DurationMs) 即 // pull payload. type SecurityClassifier interface { Classify(ctx context.Context, req *ClassifyRequest) (*ClassifyResult, error) } // ClassifyRequest 是分类器的输入请求. type ClassifyRequest struct { ToolName string // 工具名称 ToolInput map[string]any // 工具输入参数 Transcript []TranscriptEntry // 对话历史投影 UserIntent string // FLYTO.md 内容(用户意图) } // ClassifyResult 是分类器的输出结果. type ClassifyResult struct { Decision Decision // Allow / Deny Reason string // 原因(Stage 2 时有) Thinking string // 推理过程 Stage string // "whitelist" / "rule" / "ai_stage1" / "ai_stage2" Usage *ClassifierUsage // token 使用统计 DurationMs int64 // 耗时(毫秒) } // ClassifierUsage 记录分类器的 token 使用情况. type ClassifierUsage struct { InputTokens int OutputTokens int CacheReadTokens int } // TranscriptEntry 对话历史的投影条目. type TranscriptEntry struct { Role string // "user" / "assistant" Content string // 压缩后的内容 } // HybridClassifier 混合分类器 - 白名单 + 规则 + AI. // // 升华改进(ELEVATED): 三层分类器各司其职,不互相越权. // 白名单只 allow,规则只 deny,AI 做最终裁决. // 这种分离确保每一层的逻辑都是单向的,不会出现冲突. // 替代方案:单一 AI 分类器处理所有请求(延迟高,成本高,无法离线工作). type HybridClassifier struct { whitelist map[string]bool // 安全工具白名单 ruleEngine *RuleDenyEngine // 规则引擎(只 deny) aiFactory ClassifierFactory // AI 分类器工厂 // aiClassifier 缓存的 AI 分类器实例(首次使用时通过工厂创建) aiClassifier SecurityClassifier } // NewHybridClassifier 创建混合分类器. // whitelist 为安全工具白名单,rules 为 deny 规则,factory 为 AI 分类器工厂. // 如果 whitelist 为 nil,使用 DefaultSafeTools. func NewHybridClassifier(whitelist map[string]bool, rules []DenyRule, aiClassifier SecurityClassifier) *HybridClassifier { if whitelist == nil { whitelist = copyWhitelist(DefaultSafeTools) } return &HybridClassifier{ whitelist: whitelist, ruleEngine: NewRuleDenyEngine(rules), aiClassifier: aiClassifier, } } // copyWhitelist 复制白名单,避免外部修改影响分类器. func copyWhitelist(src map[string]bool) map[string]bool { dst := make(map[string]bool, len(src)) for k, v := range src { dst[k] = v } return dst } // Classify 执行混合分类. // // 流程: // 1. 白名单检查 → 命中直接 allow // 2. 规则引擎检查 → 命中直接 deny // 3. AI 分类器 → 两阶段判断 func (h *HybridClassifier) Classify(ctx context.Context, req *ClassifyRequest) (*ClassifyResult, error) { start := time.Now() // 1. 白名单快速放行 if h.whitelist[req.ToolName] { return &ClassifyResult{ Decision: DecisionAllow, Reason: "safe tool (whitelisted)", Stage: "whitelist", DurationMs: time.Since(start).Milliseconds(), }, nil } // 2. 规则引擎(只 deny) if h.ruleEngine != nil { if denied, reason := h.ruleEngine.Check(req.ToolName, req.ToolInput); denied { return &ClassifyResult{ Decision: DecisionDeny, Reason: reason, Stage: "rule", DurationMs: time.Since(start).Milliseconds(), }, nil } } // 3. AI 分类器 if h.aiClassifier != nil { result, err := h.aiClassifier.Classify(ctx, req) if err != nil { // AI 分类器出错时,保守返回 deny return &ClassifyResult{ Decision: DecisionDeny, Reason: "ai classifier error: " + err.Error(), Stage: "ai_error", DurationMs: time.Since(start).Milliseconds(), }, nil } result.DurationMs = time.Since(start).Milliseconds() return result, nil } // 没有 AI 分类器,保守返回 deny return &ClassifyResult{ Decision: DecisionDeny, Reason: "no ai classifier configured", Stage: "no_ai", DurationMs: time.Since(start).Milliseconds(), }, nil }