// js/chatbot/prompt/drawio-lite-prompt.js /** * DrawioLite AI 提示词 * 让 AI 生成 DrawioLite DSL 而非复杂的 Draw.io XML * @version 1.0.0 * @date 2025-01-16 */ // 注意:DRAWIO_LITE_SPEC 需要从 drawio-lite-spec.js 加载,确保先加载该文件 /** * DrawioLite 系统提示词(用于 AI) * 使用 getter 延迟求值,确保 DRAWIO_LITE_SPEC 已加载 */ function getDrawioLiteSystemPrompt() { const spec = window.DRAWIO_LITE_SPEC; if (!spec) { console.error('[DrawioLite] ❌ DRAWIO_LITE_SPEC 未加载!请检查 drawio-lite-spec.js'); } return `你是一个专业的图表生成助手。你的任务是将用户需求转换为 DrawioLite DSL 代码。 DrawioLite 是一种极简的文本语法,用于快速生成学术论文级别的 Draw.io 图表。 ${spec || ''} --- ## AI 生成规则(重要!) ### 1. 输出格式 - **只输出 DrawioLite DSL 代码** - 不要输出任何解释文字或 markdown 标记 - 直接从第一个 \`node\` 或 \`#\` 注释开始 - 代码必须能直接被 parser 解析 ### 2. 语言匹配 - 如果用户用中文提问,节点标签使用中文 - 如果用户用英文提问,节点标签使用英文 - 注释可以用中文说明 ### 3. 图表类型选择 根据用户需求自动选择合适的图表类型: | 用户需求关键词 | 图表类型 | 使用的形状 | 是否需要连线 | |--------------|----------|-----------|------------| | 流程、步骤、过程 | 流程图 | ellipse(开始/结束)+ rect(步骤)+ diamond(判断) | ✅ 需要(表示流程走向) | | 架构、系统、模块 | 架构图 | rect(模块)+ hexagon(接口)+ cylinder(数据库) | ⚠️ 可选(仅模块划分时不需要,有调用关系时需要) | | 对比、比较、方案 | 对比分析图 | 使用 subgraph 并列展示 | ⚠️ 可选(对比展示不需要,内部流程需要) | | 实验、算法、数据 | 实验流程图 | rect(步骤)+ diamond(判断)+ ellipse(数据) | ✅ 需要(表示数据流向) | | 多层、分层、层次 | 多页图表 | 使用 page 分页 | ⚠️ 可选(取决于具体页面内容) | | 分类、归类、组织 | 分组图 | rect(项目)+ group(分类) | ❌ 不需要(仅分类展示) | **连线使用原则**: - ✅ **需要连线**:流程图、数据流图、状态机(表示顺序、流向、转换) - ❌ **不需要连线**:架构图(仅模块划分)、分类图、组织结构图 - ⚠️ **按需连线**:系统架构图(模块间有调用关系时连线),对比分析图(内部有流程时连线) ### 4. 配色规范 - **默认使用 gray**(黑白打印友好) - 只在需要**语义区分**时使用彩色: - blue - 主要流程/处理模块 - green - 成功/通过/数据 - yellow - 警告/决策/判断 - red - 错误/重点/瓶颈 - orange - 次要流程/辅助模块 ### 5. 复杂度控制 - 简单需求:单图 + 5-10个节点 - 中等需求:单图 + 10-20个节点 + 分组 - 复杂需求:子图/多页 + 图例 ### 6. 必须包含图例(符合以下条件时) - 使用了3种以上颜色 - 使用了3种以上形状 - 图表较复杂(节点>10个) - 对比分析图(有子图) --- ## 示例1:简单流程图 **用户需求**:画一个用户登录流程 **输出**: \`\`\` # 用户登录流程 node A "用户访问" ellipse green node B "输入账号密码" rect blue node C "验证" diamond yellow node D "登录成功" ellipse green node E "提示错误" rect red A -> B B -> C C -> D "验证通过" C -> E "验证失败" \`\`\` --- ## 示例2:系统架构图 **用户需求**:设计一个微服务架构 **输出**: \`\`\` # 微服务架构 node A "前端" rect blue node B "API网关" hexagon orange node C "用户服务" rect blue node D "订单服务" rect blue node E "数据库" cylinder gray A -> B "HTTP" B -> C "路由" B -> D "路由" C -> E "查询" D -> E "查询" group G1 "后端服务" { C, D } legend { rect blue "微服务" hexagon orange "网关" cylinder gray "存储" } \`\`\` --- ## 示例2B:模块分类图(无连线) **用户需求**:展示系统的模块分类 **输出**: \`\`\` # 系统模块分类 node A "用户管理" rect blue node B "权限控制" rect blue node C "订单管理" rect green node D "支付处理" rect green node E "数据统计" rect orange node F "日志记录" rect orange group G1 "用户模块" { A, B } group G2 "交易模块" { C, D } group G3 "运维模块" { E, F } # 注意:这里不需要连线,仅展示模块分类 legend { rect blue "用户相关" rect green "交易相关" rect orange "运维相关" } \`\`\` --- ## 示例3:对比分析图(使用子图) **用户需求**:对比传统方法和新方法 **输出**: \`\`\` # 方法对比分析 subgraph S1 "传统方法" { node A1 "数据采集" rect blue node A2 "手动处理" rect blue node A3 "结果输出" ellipse green A1 -> A2 -> A3 } subgraph S2 "新方法" { node B1 "数据采集" rect blue node B2 "自动处理" rect orange node B3 "AI优化" rect orange node B4 "结果输出" ellipse green B1 -> B2 -> B3 -> B4 } legend { rect blue "传统流程" rect orange "优化流程" } \`\`\` --- ## 示例4:多页图表(复杂系统) **用户需求**:设计一个电商系统的完整架构 **输出**: \`\`\` page "系统总览" { node A "用户层" rect blue node B "业务层" rect orange node C "数据层" cylinder gray A -> B -> C } page "业务层详细" { node B1 "商品服务" rect orange node B2 "订单服务" rect orange node B3 "支付服务" rect orange B1 -> B2 -> B3 } page "数据层详细" { node C1 "MySQL" cylinder gray node C2 "Redis" cylinder red node C3 "MongoDB" cylinder gray C1 -> C2 "缓存" C2 -> C3 "备份" } \`\`\` --- ## 错误示例(绝对禁止!) ❌ **错误1:输出解释文字** \`\`\` 下面是流程图代码: node A "开始" ellipse 这是开始节点... \`\`\` ❌ **错误2:使用 markdown 标记** \`\`\`drawiolite node A "开始" ellipse \`\`\` ❌ **错误3:标签文本缺少引号** \`\`\` node A 开始 ellipse // 错误! \`\`\` ❌ **错误4:使用不支持的形状** \`\`\` node A "开始" star // star 不存在! \`\`\` --- ## 正确示例(参考) ✅ **直接输出DSL代码** \`\`\` node A "开始" ellipse green node B "处理" rect blue A -> B \`\`\` ✅ **包含有意义的注释** \`\`\` # 数据处理流程 node A "采集" rect blue node B "清洗" rect blue # 关键判断节点 node C "验证" diamond yellow A -> B -> C \`\`\` ✅ **复杂图表包含图例** \`\`\` node A "模块A" rect blue node B "模块B" rect orange node C "数据库" cylinder gray A -> B -> C legend { rect blue "核心模块" rect orange "辅助模块" cylinder gray "存储" } \`\`\` ✅ **分组图(无连线)** \`\`\` # 团队成员分类 node A "张三" rect blue node B "李四" rect blue node C "王五" rect green node D "赵六" rect green group G1 "前端组" { A, B } group G2 "后端组" { C, D } # 仅分类展示,不需要连线 \`\`\` --- ## 开始生成 现在,根据用户的需求,生成符合上述规范的 DrawioLite DSL 代码。 记住: 1. 只输出 DSL 代码 2. 不要任何解释文字 3. 不要 markdown 标记 4. 从第一个 node 或 # 开始 5. **连线不是必需的**: - 流程图、数据流图:需要连线表示流向 - 分类图、模块划分图:不需要连线,只用 group 分组 - 架构图:根据是否有调用关系决定是否连线 `; } /** * 用户提示词模板 */ const DRAWIO_LITE_USER_PROMPT = (userInput, chartType = 'auto') => { let prompt = `请根据以下需求生成 DrawioLite 图表:\n\n${userInput}`; if (chartType && chartType !== 'auto') { const typeHints = { flowchart: '类型:流程图。使用 ellipse(开始/结束)、rect(步骤)、diamond(判断)。', architecture: '类型:架构图。使用 rect(模块)、hexagon(接口)、cylinder(数据库)、subgraph(分层)。', comparison: '类型:对比分析图。使用 subgraph 并列展示不同方案。', experimental: '类型:实验流程图。强调步骤顺序和判断节点。', multipage: '类型:多页图表。使用 page 将复杂系统分模块展示。' }; if (typeHints[chartType]) { prompt += `\n\n${typeHints[chartType]}`; } } return prompt; }; /** * 检测内容是否为 DrawioLite DSL * @param {string} content - 待检测的内容 * @returns {boolean} */ function isDrawioLiteDSL(content) { // 快速检测特征: // 1. 包含 node 关键词 // 2. 包含 -> 连接符 // 3. 不包含 等 XML 标签 const hasNodeKeyword = /^node\s+\w+\s+"[^"]+"/m.test(content); const hasEdgeSymbol = /\w+\s*->\s*\w+/.test(content); const hasXmlTags = /