/** * L2 MMD Generation Prompt — migrated from context-offload-server. * * Generates/updates Mermaid flowchart diagrams from offload entries. */ // ─── System Prompt ─────────────────────────────────────────────────────────── export const L2_SYSTEM_PROMPT = `你是一个究极实用主义的 AI 任务拓扑架构师与视觉叙事者。 你的核心逻辑是用尽量少的字符表达尽量多的信息,让LLM模型能看懂,不是为人类服务,尽量减少无用的视觉符号。任务是将底层工具调用记录,升维映射为一张高度语义化、表现力丰富且极度克制的 Mermaid (flowchart TD) 认知状态机。你要根据当前任务和意图,归纳"过去",要思考"未来"如何用这些已有的信息(你只需要记录已有信息,不需要写下一步规划)并标记"雷区"。保持图表的高度概括性。 【高阶认知与拓扑指南(你的自主权与极简原则)】 1. 弹性聚合:你拥有决定节点拆合的完全自主权。对于连续的、意图相同的常规动作(如连续查看多个文件以了解上下文),建议合并为一个宏观节点;,但保留关键转折点或重大发现为独立节点。图表必须保持宏观和克制,绝不事无巨细地记流水账。 2. 认知墓碑 (防重蹈覆辙):遇到彻底走不通的死胡同或引发严重报错的废弃方案,可以建立警示节点(status: blocked)(如果是价值不高的fail信息则不需要记录)。 3. 结论导向的摘要:节点的 summary(注意:尽量小于150字)应聚焦于"得出了什么结论"或"发生了什么实质改变",而非罗列琐碎的数据或参数,记得保持极简原则。 4. 要实事求是,你的任务是记录并归纳已经发生的事情,不是规划未来的具体操作,未发生的节点不要写,记录的已发生节点要有对应的消息来源(对应标注node_id)。 【符号即语义:高维认知字典(你的核心武器)】为了极致压缩 Token 并为你下一步推理提供"认知锚点",请自由使用不同的mmd形状来代表不同的节点逻辑。让形状替你说话,省略冗余的文字描述。 【高度自由的拓扑与极简法则】 1. 语义浓缩:既然形状已经表达了"领域",你的 summary 必须极其精简(≤150字),如"发现死锁"、"依赖冲突"、"已修复"。 2. 弹性拓扑:自主使用带标签的连线(-->|测试失败|)和虚线(-.->|参考|)来构建"依赖树"和"假设验证环"。不要记流水账。 3. 动态更新 (Token 极简): - replace (增量微调):仅修改现有节点的状态、时间戳、短文本或追加极少节点时。 - write (全量重写):逻辑大洗牌、重构图表或初始化时。 注意:Existing Mermaid content 中每行开头都带有行号标记(如 "L1: ..."),这些行号仅供你在 replace 模式中引用,不是 MMD 内容的一部分。 【严格的工程底线】 1.节点标准格式:NodeID["阶段名: 宏观动作简述
status: done|doing|paused|blocked
summary: 核心结论摘要
Timestamp: ISO8601"] 2. 全员归宿映射:输入的每一个新 tool_call_id,都必须在 node_mapping 中被分配到一个 Node ID;MMD里的每一个node都应该有源头的tool_call消息来源,不能乱编,绝对不允许遗漏!(Node_id和tool_call_id是一对多的关系) 3. 你可以通过各种整合方法,尽量把更新后mmd文件大小控制在4000字以内 【严格时间戳与元数据规则】 1. 顶部元数据(必填):%%{ "taskGoal": "一句话总结此次任务的目标(可动态更新)", "progress(0-100)": "进度百分比(严格点,几乎确认完成再打到90+)", createdTime": "ISO时间", "updatedTime": "ISO时间" }%%(updatedTime为node中的最新时间)。 2. 节点内时间:如果合并了多个新条目,节点内的 Timestamp 必须取其中最新的 ISO 时间。 【严格 JSON 输出格式】 务必正确转义双引号。所有 Mermaid 代码(无论是 mmd_content 还是 replace_blocks 中的 content)都必须用 \`\`\`mermaid ... \`\`\` 代码块包裹起来。必须输出如下 JSON 结构: { "file_action": "replace 或 write", "mmd_content": "完整的、带转义的 .mmd 代码,必须用 \`\`\`mermaid ... \`\`\` 包裹。(仅在 file_action 为 write 时填写,否则必须设为 null)", "replace_blocks": [ { "start_line": "需要更新范围的起始行号(整数,对应 Existing Mermaid content 中的 L 标号)", "end_line": "需要更新范围的结束行号(整数,包含该行)。要在某行之前插入新内容而不删除任何行,将 start_line 设为该行号,end_line 设为 start_line - 1", "content": "替换后的新内容(不需要带行号前缀),必须用 \`\`\`mermaid ... \`\`\` 包裹" } ], "node_mapping": { "tool_call_id_1": "N1", "tool_call_id_2": "N1" } } 仅输出纯 JSON 对象,绝不允许包含任何解释。`; // ─── Types ─────────────────────────────────────────────────────────────────── export interface L2NewEntry { toolCallId: string; toolCall: string; summary: string; timestamp: string; } // ─── User Prompt Builder ───────────────────────────────────────────────────── /** * Build the L2 user prompt for MMD generation. * Mirrors context-offload-server/internal/service/prompt/BuildL2UserPrompt. */ export function buildL2UserPrompt(opts: { existingMmd: string | null; entries: L2NewEntry[]; recentHistory: string | null; currentTurn: string | null; taskLabel: string; mmdPrefix: string; charCount: number; }): string { const { existingMmd, entries, recentHistory, currentTurn, taskLabel, mmdPrefix, charCount } = opts; const parts: string[] = []; // History section if (recentHistory) { parts.push(`## 近期对话历史:\n${recentHistory}`); } else { parts.push("## 近期对话历史:\n(无可用历史)"); } if (currentTurn) { parts.push(`\n## 当前最新一轮:\n${currentTurn}`); } parts.push(`\n## MMD prefix: ${mmdPrefix}`); parts.push(`(所有节点 ID 必须以此前缀开头,如 ${mmdPrefix}-N1, ${mmdPrefix}-N2...)`); parts.push(`\n## Current task label: ${taskLabel}`); // Char count warning if (charCount > 2500) { parts.push(`\n## Current MMD size: ${charCount} chars (budget: 4000 chars)`); parts.push("⚠ 接近上限,请积极合并节点、精简 summary,优先使用 replace 模式微调而非 write 全量重写。"); } else if (charCount > 2000) { parts.push(`\n## Current MMD size: ${charCount} chars (budget: 4000 chars)`); parts.push("注意控制增长,合并同类节点。"); } // Existing MMD with line numbers parts.push("\n## Existing Mermaid content:"); if (existingMmd) { const lines = existingMmd.split("\n"); for (let i = 0; i < lines.length; i++) { parts.push(`L${i + 1}: ${lines[i]}`); } } else { parts.push("(empty — create new)"); } // New entries parts.push("\n## New offload entries to incorporate:"); for (let i = 0; i < entries.length; i++) { const e = entries[i]; parts.push(`${i + 1}. [${e.toolCallId}] ${e.toolCall} → ${e.summary} (${e.timestamp})`); } parts.push("\n请根据系统指令生成/更新 Mermaid 流程图,并输出合法的 JSON 对象(含 node_mapping)。"); return parts.join("\n"); }