#!/usr/bin/env node /** * 批量生成真实路由反馈数据 (v5.3) * * 基于 50 个技能的典型查询场景,使用 route-analyzer 实际评分, * 生成路由反馈记录,验证并训练自适应学习系统。 * * 用法: * node generate-routing-feedback.js 生成反馈 + 学习 * node generate-routing-feedback.js --dry-run 仅预览不写入 * node generate-routing-feedback.js --json JSON 输出 */ const fs = require('fs'); const path = require('path'); let PATHS; try { PATHS = require('./paths.config.js').PATHS; } catch { const ROOT = __dirname.replace(/[/\\]scripts$/, ''); PATHS = { root: ROOT, debugDir: path.join(ROOT, 'debug'), skillsIndexJson: path.join(ROOT, 'skills-index.json'), }; } const FEEDBACK_FILE = path.join(PATHS.debugDir, 'route-feedback.jsonl'); const WEIGHTS_FILE = path.join(PATHS.debugDir, 'route-weights.json'); // ─── 典型查询场景 (每个技能 1-2 条) ──────────────────── const SCENARIOS = [ // AI / 数据 { query: 'PyTorch 训练 BERT 模型微调', expected: 'ai-ml-expert' }, { query: 'LLM RAG 检索增强生成', expected: 'ai-ml-expert' }, { query: 'pandas 数据清洗 A/B 测试分析', expected: 'data-analyst-expert' }, { query: 'Spark ETL 数据管道 Kafka 消费', expected: 'data-engineer-expert' }, // 开发 { query: 'React 组件 Hooks useMemo 性能', expected: 'frontend-expert' }, { query: 'Vue3 Composition API Pinia 状态管理', expected: 'frontend-expert' }, { query: 'Node.js Express REST API 中间件', expected: 'backend-builder' }, { query: 'React Native 移动端适配 iOS Android', expected: 'mobile-expert' }, { query: '微信小程序 Taro 跨端开发', expected: 'miniprogram-expert' }, { query: '通用编程 算法 数据结构 代码解释', expected: 'developer-expert' }, { query: 'Bug 排查 错误诊断 堆栈分析', expected: 'debugger-expert' }, { query: 'OAuth 2.0 Webhook 第三方 API 集成', expected: 'api-integration-specialist' }, { query: '正则表达式 Shell 脚本 批量重命名', expected: 'regex-shell-wizard' }, { query: '双重审查 生产级代码 代码质量', expected: 'ultimate-code-expert' }, { query: 'Playwright 浏览器自动化 网页抓取', expected: 'browser-automation-expert' }, // 架构 { query: '系统架构设计 DDD 领域驱动 ADR', expected: 'architect-expert' }, { query: 'SQL 索引优化 慢查询 explain 分析', expected: 'database-tuning-expert' }, { query: 'Kubernetes Istio 服务网格 GitOps', expected: 'cloud-native-expert' }, { query: 'Cloudflare Workers 边缘函数 Deno Deploy', expected: 'edge-computing-expert' }, { query: 'Core Web Vitals LCP FCP 首屏优化', expected: 'performance-expert' }, { query: '变更影响分析 依赖图 爆炸半径', expected: 'impact-analyst' }, { query: 'Mermaid 流程图 PlantUML 架构图', expected: 'diagram-as-code-expert' }, { query: '零缺陷守护 Pinning Test 安全重构', expected: 'zero-defect-guardian' }, // DevOps { query: 'CI/CD 流水线 Docker 镜像构建', expected: 'devops-expert' }, { query: 'SAST DAST 容器安全扫描 SBOM', expected: 'devsecops-expert' }, { query: 'Git rebase 分支管理 merge 冲突', expected: 'git-operation-master' }, { query: 'SLI SLO 监控告警 事故响应 Postmortem', expected: 'sre-expert' }, // 安全 { query: 'OWASP XSS SQL注入 JWT 安全', expected: 'security-expert' }, // 质量 { query: 'Jest 单元测试 Vitest mock TDD', expected: 'tester-expert' }, { query: 'Code Review 代码审查 技术债评估', expected: 'reviewer-expert' }, { query: '项目全栈审计 上线前检查清单', expected: 'project-audit-expert' }, // 产品 / 设计 { query: 'PRD 需求文档 RICE KANO 路线图', expected: 'product-manager-expert' }, { query: 'UI UX 设计系统 Figma WCAG 无障碍', expected: 'designer-expert' }, { query: '用户访谈 可用性测试 Persona', expected: 'ux-researcher' }, { query: '甘特图 Sprint 计划 里程碑 风险管理', expected: 'project-coordinator' }, // 商业 / 研究 { query: '商业计划书 融资材料 商业模式画布', expected: 'business-plan-skill' }, { query: '记账 税务 现金流 报价单', expected: 'finance-advisor' }, { query: '销售漏斗 CRM 客户谈判技巧', expected: 'sales-consultant' }, { query: 'SaaS 定价策略 免费增值 提价', expected: 'pricing-strategist' }, { query: 'SLA 客户成功 Onboarding 流失预警', expected: 'customer-success-expert' }, { query: 'AARRR 增长模型 A/B 测试 裂变营销', expected: 'growth-hacker' }, { query: '投资评估 尽职调查 估值分析', expected: 'investor-review-guide' }, { query: '行业调研 市场规模 竞品分析', expected: 'industry-research-cn' }, { query: '合同审查 合规 知识产权 数据保护', expected: 'legal-review-skill' }, // 内容 / 传播 { query: 'API 文档 README 用户手册', expected: 'tech-writer-expert' }, { query: '营销文案 落地页 CTA 转化率', expected: 'copywriter-expert' }, { query: '商务邮件 冷邮件 催款邮件', expected: 'email-communicator' }, { query: '新媒体运营 内容日历 KOL 合作', expected: 'social-media-manager' }, { query: 'sitemap robots.txt JSON-LD SEO', expected: 'technical-seo-expert' }, // 元技能 { query: '从零开发新项目 全生命周期', expected: 'genesis-engine' }, { query: '提示词优化 结构化 Prompt', expected: 'prompt-optimizer' }, { query: '团队管理 1on1 晋升 招聘面试', expected: 'tech-lead-mentor' }, // 额外混合场景 (测试歧义处理) { query: 'Go 微服务 gRPC protobuf', expected: 'backend-builder' }, { query: 'Tailwind CSS 响应式布局', expected: 'frontend-expert' }, { query: 'PostgreSQL 分区表 索引优化', expected: 'database-tuning-expert' }, { query: '渗透测试 漏洞利用 安全审计', expected: 'security-expert' }, ]; // ─── 主流程 ────────────────────────────────────────── function main() { const args = process.argv.slice(2); const isDryRun = args.includes('--dry-run'); const jsonMode = args.includes('--json'); // 加载 route-analyzer let routeAnalyzer; try { routeAnalyzer = require('./route-analyzer.js'); } catch (e) { console.error('无法加载 route-analyzer.js:', e.message); process.exit(1); } const indexPath = PATHS.skillsIndexJson || path.join(PATHS.root, 'skills-index.json'); if (!fs.existsSync(indexPath)) { console.error('skills-index.json 未找到'); process.exit(1); } const index = JSON.parse(fs.readFileSync(indexPath, 'utf8')); const bm25Params = routeAnalyzer.buildBM25Params(index); // 评估每个场景 const results = []; let correct = 0; let incorrect = 0; for (const scenario of SCENARIOS) { const tokens = routeAnalyzer.tokenize(scenario.query); const scores = index.skills.map(skill => { const { totalScore } = routeAnalyzer.scoreSkill(skill, tokens, bm25Params); return { name: skill.name, score: totalScore }; }).sort((a, b) => b.score - a.score); const normalized = routeAnalyzer.normalizeScores(scores).slice(0, 5); const topSkill = normalized[0]?.name || 'none'; const topConfidence = normalized[0]?.confidence || 0; const isCorrect = topSkill === scenario.expected; if (isCorrect) correct++; else incorrect++; results.push({ query: scenario.query, expected: scenario.expected, routedTo: topSkill, confidence: topConfidence, correct: isCorrect, candidates: normalized.slice(0, 3).map(r => `${r.name}(${(r.confidence * 100).toFixed(0)}%)`), }); } const accuracy = (correct / SCENARIOS.length * 100).toFixed(1); if (!isDryRun) { // 写入反馈记录 if (!fs.existsSync(PATHS.debugDir)) fs.mkdirSync(PATHS.debugDir, { recursive: true }); // 清空旧种子数据,写入真实反馈 const feedbackEntries = []; for (const r of results) { const entry = { ts: new Date().toISOString(), query: r.query, routedTo: r.routedTo, correctedTo: r.expected, topConfidence: r.confidence, queryTokens: Array.from(routeAnalyzer.tokenize(r.query)), type: r.correct ? 'confirm' : 'correction', }; feedbackEntries.push(JSON.stringify(entry)); } fs.writeFileSync(FEEDBACK_FILE, feedbackEntries.join('\n') + '\n'); // 触发权重学习 try { const routeFeedback = require('./route-feedback.js'); routeFeedback.learnWeights(); } catch {} } // 输出 if (jsonMode) { console.log(JSON.stringify({ total: SCENARIOS.length, correct, incorrect, accuracy: accuracy + '%', misroutes: results.filter(r => !r.correct).map(r => ({ query: r.query, expected: r.expected, got: r.routedTo, candidates: r.candidates, })), }, null, 2)); } else { console.log(`\n=== 路由反馈生成 (${isDryRun ? '预览' : '已写入'}) ===\n`); console.log(`总场景: ${SCENARIOS.length}`); console.log(`正确: ${correct} (${accuracy}%)`); console.log(`错误: ${incorrect}`); if (incorrect > 0) { console.log('\n误路由:'); for (const r of results.filter(r => !r.correct)) { console.log(` "${r.query}"`); console.log(` 期望: ${r.expected}, 实际: ${r.routedTo} (${(r.confidence * 100).toFixed(0)}%)`); console.log(` 候选: ${r.candidates.join(', ')}`); } } if (!isDryRun) { console.log(`\n反馈已写入: ${FEEDBACK_FILE}`); console.log(`权重已学习: ${WEIGHTS_FILE}`); } } } if (typeof module !== 'undefined') { module.exports = { SCENARIOS, main }; } if (require.main === module) { main(); }