UNPKG

vibe-cli-tool

Version:

VibeCLI v1.9 - 模板商店生态,智能部署生成,多语言支持,交互式学习系统,企业级Web全栈应用CLI工具

463 lines 23.5 kB
export class IntentAnalyzer { constructor() { this.projectTypeKeywords = { ecommerce: [ { keywords: ['电商', '商城', '购物', '支付', '订单', '商品', 'shop', 'cart', 'payment', 'store', '网店', 'ecommerce', 'e-commerce', '在线商店', '零售', 'marketplace', '电商平台', 'platform', '平台', '购买', '销售', '交易'], weight: 10, category: 'type' }, { keywords: ['库存', '商品管理', 'inventory', '商户', '多商户', '供应商', '分销', '仓储', '物流', 'logistics'], weight: 8, category: 'feature' }, { keywords: ['stripe', 'paypal', '支付宝', '微信支付', 'alipay', 'wechat pay', '收银台', '结算'], weight: 6, category: 'tech' }, { keywords: ['优惠券', '促销', '折扣', 'coupon', 'discount', '营销', 'marketing'], weight: 7, category: 'feature' }, { keywords: ['购物车', '结账', '下单', 'checkout', 'order', '配送', 'shipping', '结算', '购买流程', '支付处理', '支付集成'], weight: 9, category: 'type' } ], saas: [ { keywords: ['saas', '订阅', '多租户', '仪表板', 'dashboard', 'subscription', 'tenant', '企业级', 'software as a service', '软件服务'], weight: 10, category: 'type' }, { keywords: ['计费', '订阅管理', 'billing', '团队管理', '权限', 'rbac', '角色', 'role', '定价', 'pricing'], weight: 8, category: 'feature' }, { keywords: ['api', '集成', 'webhook', 'integration', '接口', 'rest api', 'graphql'], weight: 6, category: 'tech' }, { keywords: ['工作流', 'workflow', '自动化', 'automation', '流程', 'process'], weight: 7, category: 'feature' }, { keywords: ['企业', '组织', 'organization', '部门', 'department', '协作', 'collaboration'], weight: 8, category: 'type' } ], blog: [ { keywords: ['博客', '文章', '内容管理', 'cms', '发布', 'blog', 'post', '写作', 'content', '新闻', 'news'], weight: 10, category: 'type' }, { keywords: ['评论', 'seo', '搜索', '标签', '分类', 'comment', 'tag', 'category', '归档', 'archive'], weight: 8, category: 'feature' }, { keywords: ['markdown', '富文本', 'editor', 'wysiwyg', '编辑器', 'tinymce', 'quill'], weight: 6, category: 'tech' }, { keywords: ['订阅', '推送', '通知', 'subscription', 'notification', 'rss', '邮件列表'], weight: 7, category: 'feature' }, { keywords: ['作者', 'author', '编辑', '审核', 'review', '发布流程'], weight: 6, category: 'feature' } ], portfolio: [ { keywords: ['作品集', '个人网站', '展示', 'portfolio', '简历', 'resume', '个人主页', 'personal website', '个人品牌'], weight: 10, category: 'type' }, { keywords: ['项目展示', '技能', '联系表单', '关于我', 'about', 'contact', '经历', 'experience', '成就'], weight: 8, category: 'feature' }, { keywords: ['动画', 'animation', '响应式', 'responsive', '交互', 'interactive', 'parallax'], weight: 6, category: 'tech' }, { keywords: ['设计师', 'designer', '开发者', 'developer', '创意', 'creative', '艺术家', 'artist'], weight: 7, category: 'type' }, { keywords: ['案例研究', 'case study', '展示页', 'showcase', '画廊', 'gallery'], weight: 6, category: 'feature' } ], dashboard: [ { keywords: ['仪表板', '管理后台', '数据可视化', '图表', '分析', 'admin', 'dashboard', '后台', 'analytics', '控制台'], weight: 10, category: 'type' }, { keywords: ['用户管理', '权限', '数据表格', '统计', 'statistics', '报表', 'report', '监控', 'monitoring'], weight: 8, category: 'feature' }, { keywords: ['echarts', 'chart.js', 'd3', '图表库', 'recharts', 'plotly', 'highcharts'], weight: 6, category: 'tech' }, { keywords: ['kpi', '指标', 'metrics', '绩效', 'performance', '趋势', 'trend'], weight: 7, category: 'feature' }, { keywords: ['实时', 'real-time', '刷新', '更新', 'live data', '数据源'], weight: 6, category: 'tech' } ] }; this.featureKeywords = { auth: ['登录', '注册', '认证', '用户', 'login', 'register', 'auth', 'user', '用户系统', '认证系统'], payment: ['支付', '付款', '交易', 'payment', 'pay', 'transaction', 'stripe'], admin: ['管理', '后台', '管理员', 'admin', 'management'], upload: ['上传', '文件', '图片', 'upload', 'file', 'image'], email: ['邮件', '邮箱', '通知', 'email', 'mail', 'notification'], realtime: ['实时', '即时', '聊天', 'realtime', 'chat', 'websocket'], search: ['搜索', '查找', 'search', 'find'], analytics: ['分析', '统计', '数据', 'analytics', 'statistics', 'data'] }; this.complexityIndicators = { simple: ['简单', '基础', '入门', 'simple', 'basic', '个人用'], medium: ['中等', '标准', '企业', 'medium', 'standard', '团队'], complex: ['复杂', '大型', '企业级', 'complex', 'enterprise', '高级', 'advanced'] }; } /** * 分析用户意图 */ async analyzeUserIntent(config) { const description = config.userDescription.toLowerCase(); // 1. 识别项目类型 const projectType = this.identifyProjectType(description); // 2. 提取核心功能(合并已有检测结果) const extractedFeatures = this.extractCoreFeatures(description); const mergedFeatures = Array.from(new Set([...(config.detectedFeatures || []), ...extractedFeatures])); // 3. 评估复杂度 const complexityLevel = this.assessComplexity(description, mergedFeatures); // 4. 识别技术偏好 const techPreferences = Array.from(new Set([ ...this.extractTechPreferences(description), ...(config.techStack || []) ])); // 5. 计算置信度 const confidence = this.calculateConfidence(description, projectType, mergedFeatures); // 确保关键项目默认包含 auth if (!mergedFeatures.includes('auth') && ['ecommerce', 'saas', 'dashboard'].includes(projectType)) { mergedFeatures.push('auth'); } return { projectType, coreFeatures: mergedFeatures, complexityLevel, techPreferences, confidence }; } /** * 识别项目类型 - 增强版算法 */ identifyProjectType(description) { const scores = {}; const lowerDescription = description.toLowerCase(); // 如果描述明确包含电商相关关键字,直接返回电商(优先级最高) const ecommerceHint = /(电商|ecommerce|购物|商城|购物车|shop|store|购买|支付)/; if (ecommerceHint.test(description)) { return 'ecommerce'; } // 遍历所有项目类型的关键词 Object.entries(this.projectTypeKeywords).forEach(([type, mappings]) => { scores[type] = 0; mappings.forEach(mapping => { mapping.keywords.forEach(keyword => { if (lowerDescription.includes(keyword.toLowerCase())) { // 根据类别给予不同权重加成 let weightMultiplier = 1; if (mapping.category === 'type') weightMultiplier = 1.5; // 类型关键词最重要 else if (mapping.category === 'feature') weightMultiplier = 1.2; // 功能关键词次重要 else if (mapping.category === 'tech') weightMultiplier = 0.8; // 技术关键词权重较低 scores[type] += mapping.weight * weightMultiplier * (1 + lowerDescription.split(keyword.toLowerCase()).length - 2) * 0.2; } }); }); }); // 找到得分最高的项目类型 const bestMatch = Object.entries(scores).reduce((best, [type, score]) => { return score > best.score ? { type, score } : best; }, { type: 'blog', score: 0 }); // 如果最高分太低,说明识别不够准确 if (bestMatch.score < 10) { return this.fallbackProjectTypeIdentification(lowerDescription); } // 当电商得分接近最高分时,优先选择电商(因为通常优先级更高) if (bestMatch.type !== 'ecommerce' && scores['ecommerce'] >= bestMatch.score * 0.9) { return 'ecommerce'; } return bestMatch.type; } /** * 提取核心功能 */ extractCoreFeatures(description) { const features = []; Object.entries(this.featureKeywords).forEach(([feature, keywords]) => { const hasFeature = keywords.some(keyword => description.includes(keyword)); if (hasFeature) { features.push(feature); } }); return features; } /** * 评估复杂度 */ assessComplexity(description, features) { // 基于关键词的复杂度评估 const priority = ['complex', 'medium', 'simple']; for (const level of priority) { const keywords = this.complexityIndicators[level]; if (keywords.some(k => description.includes(k))) { return level; } } // 基于功能数量的复杂度评估 if (features.length >= 5) return 'complex'; if (features.length >= 3) return 'medium'; return 'simple'; } /** * 提取技术偏好 */ extractTechPreferences(description) { const techKeywordMap = { 'React': ['react'], 'TypeScript': ['typescript', 'ts'], 'PostgreSQL': ['postgres', 'postgresql'], 'MySQL': ['mysql'], 'MongoDB': ['mongodb', 'mongo'], 'Stripe': ['stripe'], 'Supabase': ['supabase'], 'Firebase': ['firebase'] }; const preferences = []; Object.entries(techKeywordMap).forEach(([tech, keywords]) => { if (keywords.some(k => description.includes(k))) { preferences.push(tech); } }); return preferences; } /** * 备选项目类型识别算法(基于关键词频次) */ fallbackProjectTypeIdentification(description) { // 简单的关键词计数方法 const typeKeywordCounts = { ecommerce: 0, saas: 0, blog: 0, portfolio: 0, dashboard: 0 }; // 电商强特征词 const ecommerceWords = ['电商', 'ecommerce', '购物', '商城', '支付', '订单', '商品', '购买', '结算', '购物车']; ecommerceWords.forEach(word => { if (description.includes(word)) typeKeywordCounts.ecommerce += 1; }); // SaaS强特征词 const saasWords = ['saas', '订阅', '企业级', '多租户', '仪表板', 'dashboard', '计费']; saasWords.forEach(word => { if (description.includes(word)) typeKeywordCounts.saas += 1; }); // 博客强特征词 const blogWords = ['博客', 'blog', '文章', '内容管理', 'cms', '发布']; blogWords.forEach(word => { if (description.includes(word)) typeKeywordCounts.blog += 1; }); // 作品集强特征词 const portfolioWords = ['作品集', 'portfolio', '个人网站', '展示', '简历']; portfolioWords.forEach(word => { if (description.includes(word)) typeKeywordCounts.portfolio += 1; }); // 后台管理强特征词 const dashboardWords = ['管理后台', '数据可视化', '图表', '分析', 'admin', '控制台']; dashboardWords.forEach(word => { if (description.includes(word)) typeKeywordCounts.dashboard += 1; }); // 找到最高频次的类型 const maxType = Object.entries(typeKeywordCounts).reduce((max, [type, count]) => { return count > max.count ? { type, count } : max; }, { type: 'blog', count: 0 }); return maxType.type; } /** * 计算置信度 - 增强版算法 */ calculateConfidence(description, projectType, features) { let confidence = 60; // 再次提高基础置信度 // 1. 项目类型关键词匹配度(权重最高) const typeScore = this.calculateTypeMatchScore(description, projectType); confidence += typeScore; // 2. 功能特征一致性评分 const featureScore = this.calculateFeatureConsistencyScore(description, projectType, features); confidence += featureScore; // 3. 描述质量评分 const qualityScore = this.calculateDescriptionQualityScore(description); confidence += qualityScore; // 4. 技术术语专业度评分 const techScore = this.calculateTechnicalTermsScore(description); confidence += techScore; // 5. 语义完整性评分 const semanticScore = this.calculateSemanticCompletenessScore(description, projectType); confidence += semanticScore; // 6. 功能数量与项目类型匹配度评分 const featureCountScore = this.getFeatureCountScore(features.length, projectType); confidence += featureCountScore; // 7. 功能与项目类型一致性评分 (增强) const featureTypeMatchScore = this.calculateFeatureProjectTypeMatch(features, projectType); confidence += featureTypeMatchScore; // 如果推荐功能都已包含,额外奖励 const recFeatures = this.getRecommendedFeatures(projectType); if (recFeatures.every(f => features.includes(f))) { confidence += 10; } const finalConfidence = Math.min(100, confidence); return finalConfidence; } /** * 计算项目类型匹配评分 */ calculateTypeMatchScore(description, projectType) { const typeKeywords = this.projectTypeKeywords[projectType] || []; let score = 0; let maxPossibleScore = 0; typeKeywords.forEach(mapping => { if (mapping.category === 'type') { const matchCount = mapping.keywords.filter(keyword => description.toLowerCase().includes(keyword.toLowerCase())).length; // 按权重计算得分 score += matchCount * mapping.weight; maxPossibleScore += mapping.keywords.length * mapping.weight; } }); // 归一化到0-35分 return maxPossibleScore > 0 ? Math.min(35, (score / maxPossibleScore) * 35) : 0; } /** * 计算功能一致性评分 */ calculateFeatureConsistencyScore(description, projectType, features) { const recommendedFeatures = this.getRecommendedFeatures(projectType); const detectedFeatures = features; // 推荐功能命中率 const hitRate = detectedFeatures.filter(f => recommendedFeatures.includes(f)).length / recommendedFeatures.length; // 功能数量合理性(避免过少或过多) const featureCountScore = this.getFeatureCountScore(detectedFeatures.length, projectType); // 功能与项目类型的匹配度 const matchScore = this.calculateFeatureProjectTypeMatch(detectedFeatures, projectType); return Math.min(20, hitRate * 10 + featureCountScore * 5 + matchScore * 5); } /** * 计算描述质量评分 */ calculateDescriptionQualityScore(description) { let score = 0; const text = description.toLowerCase(); // 长度合理性(不要太短也不要太长) const wordCount = description.split(/\s+/).filter(word => word.length > 0).length; if (wordCount >= 5 && wordCount <= 50) score += 5; if (wordCount >= 10 && wordCount <= 30) score += 3; // 包含具体的动词(表明明确的行动意图) const actionVerbs = ['开发', '创建', '构建', '设计', '实现', 'build', 'create', 'develop', 'design', 'implement']; if (actionVerbs.some(verb => text.includes(verb))) score += 3; // 包含领域词汇 const domainWords = ['网站', '平台', '系统', '应用', '工具', 'website', 'platform', 'system', 'application', 'tool']; if (domainWords.some(word => text.includes(word))) score += 2; // 描述结构化程度(包含逗号、顿号等表示列举) if (/[,,、。;;]/.test(description)) score += 2; // 避免过于简单的描述 if (wordCount < 3) score -= 5; return Math.max(0, Math.min(15, score)); } /** * 计算技术术语专业度评分 */ calculateTechnicalTermsScore(description) { let score = 0; const text = description.toLowerCase(); // 技术栈术语 const techTerms = [ 'react', 'vue', 'angular', 'nextjs', 'typescript', 'javascript', 'postgresql', 'mysql', 'mongodb', 'redis', 'docker', 'aws', 'api', 'rest', 'graphql', 'websocket', 'microservice', 'tailwind', 'bootstrap', 'prisma', 'stripe', 'oauth' ]; const techCount = techTerms.filter(term => text.includes(term)).length; score += Math.min(8, techCount * 2); // 业务术语专业度 const businessTerms = { ecommerce: ['订单', '库存', '支付', '购物车', '商品', 'inventory', 'payment', 'cart'], saas: ['租户', '订阅', '计费', '多租户', 'tenant', 'subscription', 'billing'], blog: ['文章', '评论', 'seo', '标签', '分类', 'post', 'comment', 'tag'], portfolio: ['作品', '展示', '简历', 'portfolio', 'showcase', 'resume'], dashboard: ['图表', '统计', '分析', '可视化', 'chart', 'analytics', 'visualization'] }; // 检查是否使用了相关的业务术语 Object.entries(businessTerms).forEach(([type, terms]) => { const termCount = terms.filter(term => text.includes(term)).length; if (termCount > 0) score += 2; }); return Math.min(12, score); } /** * 计算语义完整性评分 */ calculateSemanticCompletenessScore(description, projectType) { let score = 0; const text = description.toLowerCase(); // 包含目标受众信息 const audienceTerms = ['用户', '客户', '企业', '个人', '团队', 'user', 'customer', 'enterprise', 'team']; if (audienceTerms.some(term => text.includes(term))) score += 2; // 包含功能描述 const functionTerms = ['功能', '特性', '模块', '系统', 'feature', 'function', 'module', 'system']; if (functionTerms.some(term => text.includes(term))) score += 2; // 包含业务场景 const scenarioTerms = ['管理', '展示', '处理', '集成', '分析', 'manage', 'display', 'process', 'integrate', 'analyze']; if (scenarioTerms.some(term => text.includes(term))) score += 2; // 项目名称或明确标识 const hasProjectName = /[A-Za-z][A-Za-z0-9]*|[\u4e00-\u9fff]+(?:系统|平台|网站|应用)/.test(description); if (hasProjectName) score += 2; // 包含需求层次(基础需求 vs 高级需求) const basicNeeds = ['基础', '简单', '基本', 'basic', 'simple']; const advancedNeeds = ['高级', '企业级', '复杂', '专业', 'advanced', 'enterprise', 'complex', 'professional']; if (basicNeeds.some(term => text.includes(term)) || advancedNeeds.some(term => text.includes(term))) { score += 2; } return Math.min(10, score); } /** * 获取功能数量评分 */ getFeatureCountScore(featureCount, projectType) { const optimalCounts = { ecommerce: { min: 3, max: 8, optimal: 5 }, saas: { min: 3, max: 7, optimal: 4 }, blog: { min: 1, max: 5, optimal: 3 }, portfolio: { min: 1, max: 4, optimal: 2 }, dashboard: { min: 2, max: 6, optimal: 4 } }; const config = optimalCounts[projectType] || { min: 1, max: 5, optimal: 3 }; if (featureCount === config.optimal) return 2; if (featureCount >= config.min && featureCount <= config.max) return 1; if (featureCount < config.min || featureCount > config.max) return -1; return 0; } /** * 计算功能与项目类型匹配度 */ calculateFeatureProjectTypeMatch(features, projectType) { const typeSpecificFeatures = { ecommerce: ['payment', 'cart', 'inventory'], saas: ['billing', 'tenant', 'subscription'], blog: ['search', 'seo', 'comment'], portfolio: ['showcase', 'contact'], dashboard: ['analytics', 'visualization', 'admin'] }; const specificFeatures = typeSpecificFeatures[projectType] || []; const matchCount = features.filter(f => specificFeatures.includes(f)).length; return specificFeatures.length > 0 ? matchCount / specificFeatures.length : 0; } /** * 获取项目类型的推荐功能 */ getRecommendedFeatures(projectType) { const recommendations = { ecommerce: ['auth', 'payment', 'admin', 'upload', 'email'], saas: ['auth', 'admin', 'analytics', 'email'], blog: ['auth', 'upload', 'search', 'email'], portfolio: ['upload', 'email'], dashboard: ['auth', 'admin', 'analytics'] }; return recommendations[projectType] || ['auth']; } /** * 验证用户意图分析结果 */ validateIntent(intent) { const warnings = []; // 检查置信度 if (intent.confidence < 60) { warnings.push('⚠️ 置信度较低,建议提供更多项目细节'); } // 仅当置信度较低时提示缺失功能 if (intent.confidence <= 70) { const optionalFeatures = ['upload', 'email', 'analytics']; const missingFeatures = this.getRecommendedFeatures(intent.projectType).filter(f => !intent.coreFeatures.includes(f) && !optionalFeatures.includes(f)); if (missingFeatures.length) { warnings.push(`建议考虑添加以下功能:${missingFeatures.join(', ')}`); } } return { valid: intent.confidence >= 40, warnings }; } } /** * 单例模式的意图分析器实例 */ export const intentAnalyzer = new IntentAnalyzer(); //# sourceMappingURL=intent-analyzer.js.map