UNPKG

autosnippet

Version:

Extract code patterns into a knowledge base for AI coding assistants

172 lines (171 loc) 6.98 kB
import Logger from '../../infrastructure/logging/Logger.js'; /** * ConfidenceRouter — 知识条目自动审核路由器 * * 根据 KnowledgeEntry 的 reasoning.confidence、质量评分、 * 内容完整性等信号判断是否可自动审核通过。 * * 路由结果: * auto_approve — 置信度高、内容完整,自动通过 + fastTrack * pending — 需要人工审核 * reject — 置信度过低或不满足基本要求 */ const DEFAULT_CONFIG = { /** 自动通过的最低 confidence 阈值 */ autoApproveThreshold: 0.85, /** 自动驳回的 confidence 阈值 */ rejectThreshold: 0.2, /** 需要的最少内容字符数 */ minContentLength: 20, /** 自动通过要求 reasoning.isValid() */ requireReasoning: true, /** 来源白名单(这些来源可以适用更宽松的阈值) */ trustedSources: ['bootstrap', 'cursor-scan', 'mcp'], /** 可信来源的自动通过阈值 */ trustedAutoApproveThreshold: 0.7, /** 极高置信度阈值 (≥0.90 → 24h Grace) */ highConfidenceThreshold: 0.9, /** 标准 Grace Period(72h)— staging → active */ standardGracePeriod: 72 * 60 * 60 * 1000, /** 高置信度 Grace Period(24h) */ highConfidenceGracePeriod: 24 * 60 * 60 * 1000, }; export class ConfidenceRouter { _config; _qualityScorer; logger; /** @param [config] 路由配置 */ constructor(config = {}, qualityScorer = null) { this._config = { ...DEFAULT_CONFIG, ...config }; this._qualityScorer = qualityScorer; this.logger = Logger.getInstance(); } /** * 路由决策 * @returns >} */ async route(entry) { const confidence = entry.reasoning?.confidence ?? 0; const source = entry.source || 'manual'; const isTrusted = this._config.trustedSources.includes(source); // ── 阶段 1: 基本过滤 — 内容不完整直接 pending ── if (!entry.isValid()) { return { action: 'pending', reason: 'Content incomplete (title or content missing)', confidence, }; } // ── 阶段 2: 低置信度驳回 ── if (confidence < this._config.rejectThreshold && confidence > 0) { return { action: 'reject', reason: `Confidence too low: ${confidence.toFixed(2)} < ${this._config.rejectThreshold}`, confidence, targetState: 'deprecated', }; } // ── 阶段 3: 内容最短长度检查 ── const contentLength = this._estimateContentLength(entry); if (contentLength < this._config.minContentLength) { return { action: 'pending', reason: `Content too short: ${contentLength} chars < ${this._config.minContentLength}`, confidence, }; } // ── 阶段 4: Reasoning 检查 ── if (this._config.requireReasoning && !entry.reasoning?.isValid?.()) { // 无 reasoning 不驳回,但进入人工审核 return { action: 'pending', reason: 'Reasoning not provided or invalid', confidence, }; } // ── 阶段 5: 质量评分(可选) ── let qualityScore = null; if (this._qualityScorer) { try { const content = entry.content && typeof entry.content === 'object' ? entry.content : {}; const reasoning = entry.reasoning && typeof entry.reasoning === 'object' ? entry.reasoning : {}; const scorerInput = { title: entry.title, trigger: entry.trigger, description: entry.description || '', language: entry.language, category: entry.category, doClause: entry.doClause || '', dontClause: entry.dontClause || '', whenClause: entry.whenClause || '', coreCode: entry.coreCode || '', usageGuide: entry.usageGuide || content.markdown || '', contentMarkdown: content.markdown || '', contentRationale: content.rationale || '', reasoningWhyStandard: reasoning.whyStandard || '', reasoningSources: reasoning.sources || [], reasoningConfidence: reasoning.confidence || 0, source: entry.source || '', headers: entry.headers || [], tags: entry.tags || [], }; const result = this._qualityScorer.score(scorerInput); qualityScore = result.score; } catch { // 评分失败不阻塞路由 } } // ── 阶段 6: 自动通过判定 ── const threshold = isTrusted ? this._config.trustedAutoApproveThreshold : this._config.autoApproveThreshold; if (confidence >= threshold) { // 如果有质量评分且太低,降级到 pending if (qualityScore !== null && qualityScore < 0.3) { return { action: 'pending', reason: `Confidence OK (${confidence.toFixed(2)}) but quality low (${qualityScore.toFixed(2)})`, confidence, targetState: 'pending', }; } // 分级 Grace Period: ≥0.90 → 24h, 0.85-0.89 → 72h const gracePeriod = confidence >= this._config.highConfidenceThreshold ? this._config.highConfidenceGracePeriod : this._config.standardGracePeriod; return { action: 'auto_approve', reason: `Confidence ${confidence.toFixed(2)} >= threshold ${threshold} (source: ${source})`, confidence, targetState: 'staging', gracePeriod, }; } // ── 默认: 需要人工审核 ── return { action: 'pending', reason: `Confidence ${confidence.toFixed(2)} < threshold ${threshold}`, confidence, }; } /** 估算内容长度 */ _estimateContentLength(entry) { const content = entry.content; if (!content) { return 0; } const parts = [ content.pattern, content.rationale, content.markdown, ...(content.steps || []).map((s) => typeof s === 'string' ? s : s?.description || ''), ].filter(Boolean); return parts.reduce((sum, p) => sum + p.length, 0); } } export default ConfidenceRouter;