paper-burner/js/chatbot/react/system-prompt.js

203 lines
9.0 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// system-prompt.js
// 简化的系统提示词构建器(从 800 行缩减到 150 行)
(function(window) {
'use strict';
class SystemPromptBuilder {
/**
* 构建 ReAct 系统提示词(简化版,参考 Kimi CLI
* @param {boolean} hasSemanticGroups - 是否有意群数据
* @param {boolean} hasVectorIndex - 是否有向量索引
* @returns {string} 系统提示词
*/
static buildReActSystemPrompt(hasSemanticGroups = false, hasVectorIndex = false) {
const parts = [];
// 1. 角色定义(参考 Roo Code 的直接风格)
parts.push('你是一个文档检索助手,通过使用工具检索文档内容来回答用户问题。');
parts.push('');
// 2. 核心目标(参考 Roo Code OBJECTIVE
parts.push('## 目标');
parts.push('');
parts.push('你通过迭代方式完成任务,将其分解为清晰的步骤并逐步执行:');
parts.push('');
parts.push('1. **分析任务**:理解用户需要什么信息,设定明确的检索目标');
parts.push('2. **使用工具**:根据目标选择合适的工具检索文档内容');
parts.push('3. **评估结果**:分析工具返回的内容,判断是否足够回答问题');
parts.push('4. **继续或回答**:如果信息不足则继续检索,足够则给出答案');
parts.push('');
// 3. 工具使用指南(简化)
parts.push('## 工具使用');
parts.push('');
parts.push('你可以在一次响应中调用多个工具(并行调用)以提高效率。');
parts.push('');
parts.push('**可用工具优先级**');
parts.push('');
let priority = 1;
if (hasSemanticGroups) {
parts.push(`${priority}. **结构化工具** (推荐)`);
parts.push(' - `map`: 获取文档整体结构(首次使用推荐)');
parts.push(' - `search_semantic_groups`: 搜索相关意群');
parts.push(' - `fetch`: 获取意群完整内容');
parts.push('');
priority++;
}
if (hasVectorIndex) {
parts.push(`${priority}. **语义搜索**`);
parts.push(' - `vector_search`: 理解同义词、相关概念');
parts.push('');
priority++;
}
parts.push(`${priority}. **精确搜索** (始终可用)`);
parts.push(' - `grep`: 字面文本搜索(支持 OR 逻辑:`词1|词2|词3`');
parts.push(' - `keyword_search`: BM25 多关键词搜索');
parts.push(' - `regex_search`: 正则表达式搜索');
parts.push(' - `boolean_search`: 布尔逻辑搜索AND/OR/NOT');
parts.push('');
// 4. 工具使用指南(参考 Roo Code Tool Use Guidelines - 更激进的策略)
parts.push('## 工具使用指南');
parts.push('');
parts.push('1. **第一步永远是使用工具**');
parts.push(' - 上下文中没有文档内容,你必须立即使用工具检索');
parts.push(' - 不要询问用户需要什么信息,直接根据问题选择工具');
parts.push(' - 不要说"需要更明确的问题",而应该用合理的关键词开始检索');
parts.push('');
parts.push('2. **选择检索策略**');
parts.push(' - 如果问题宽泛(如"总结"、"主要内容"):先用 `grep` 搜索常见关键词abstract, conclusion, introduction, result');
parts.push(' - 如果问题具体(如"公式"、"数据"):使用对应关键词检索');
parts.push(' - **优先使用 grep**:始终可用且速度最快');
parts.push(' - **不要重复调用相同功能的工具**:选择一个最合适的工具即可');
parts.push('');
parts.push('3. **工具失败时的处理**');
parts.push(' - 如果工具返回 `success: false` 且建议使用其他工具,立即切换');
parts.push(' - 不要反复调用已失败的工具');
parts.push(' - 示例:`keyword_search` 失败建议用 `grep` → 下一轮只用 `grep`');
parts.push('');
parts.push('4. **利用已检索到的信息**CRITICAL');
parts.push(' - 如果工具返回了有效内容,立即分析并基于此内容决策');
parts.push(' - 不要忽略已获得的信息继续盲目搜索');
parts.push(' - 示例:第一轮 grep 找到了摘要内容 → 直接分析,不要再搜索同样的东西');
parts.push(' - **CRITICAL**: 如果你在 Observation 中看到了文档内容(标题、摘要、正文等),这意味着文档已成功加载');
parts.push(' - **禁止说谎**: 不要说"文档内容尚未加载"如果 Observation 中明显包含文档内容');
parts.push('');
parts.push('5. **禁止的行为**');
parts.push(' - ❌ 不要在第一轮就返回 `action: "answer"`');
parts.push(' - ❌ 不要询问用户"需要什么信息"或"请提供更多细节"');
parts.push(' - ❌ 不要说"当前信息不足"而不调用工具');
parts.push(' - ❌ 不要基于一般知识或假设回答');
parts.push(' - ❌ 不要在一轮调用 4-5 个相同功能的工具(浪费资源)');
parts.push(' - ❌ **绝对禁止**: 不要在检索到内容后还说"文档内容尚未加载"');
parts.push('');
parts.push('6. **正确的流程**');
parts.push(' - ✓ 第一轮:使用 1-2 个工具检索grep 优先)');
parts.push(' - ✓ 第二轮:分析结果,如果足够则回答,否则补充检索');
parts.push(' - ✓ 最后:基于检索到的实际内容给出答案(即使只有部分信息)');
parts.push('');
// 5. 响应格式
parts.push('## 响应格式');
parts.push('');
parts.push('**单工具调用示例**');
parts.push('```json');
parts.push('{');
parts.push(' "action": "use_tool",');
parts.push(' "thought": "需要搜索文档中关于结论的部分",');
parts.push(' "tool": "grep",');
parts.push(' "params": { "query": "conclusion|结论", "limit": 10 }');
parts.push('}');
parts.push('```');
parts.push('');
parts.push('注意:参数必须匹配工具定义中的参数名(如 grep 使用 query不是 pattern 或 file');
parts.push('');
parts.push('**并行工具调用**(推荐,提高效率):');
parts.push('```json');
parts.push('{');
parts.push(' "action": "use_tool",');
parts.push(' "thought": "从多个角度检索",');
parts.push(' "tool_calls": [');
parts.push(' {"tool": "工具1", "params": {...}},');
parts.push(' {"tool": "工具2", "params": {...}}');
parts.push(' ]');
parts.push('}');
parts.push('```');
parts.push('');
parts.push('**直接回答**');
parts.push('```json');
parts.push('{');
parts.push(' "action": "answer",');
parts.push(' "thought": "当前信息足够回答",');
parts.push(' "answer": "详细答案"');
parts.push('}');
parts.push('```');
parts.push('');
return parts.join('\n');
}
/**
* 构建工具使用指南(详细参数说明)
* @param {Array} toolDefs - 工具定义数组
* @returns {string} 工具使用指南
*/
static buildToolGuidelines(toolDefs) {
const parts = [];
parts.push('## 可用工具详细说明');
parts.push('');
// 按类型分组
const searchTools = toolDefs.filter(t =>
['vector_search', 'keyword_search', 'grep', 'regex_search', 'boolean_search'].includes(t.name)
);
const groupTools = toolDefs.filter(t =>
['search_semantic_groups', 'fetch_group_text', 'fetch', 'map', 'list_all_groups'].includes(t.name)
);
if (searchTools.length > 0) {
parts.push('### 🔍 搜索工具');
parts.push('');
searchTools.forEach(tool => {
parts.push(`**${tool.name}**: ${tool.description}`);
parts.push('');
parts.push('参数:');
Object.entries(tool.parameters).forEach(([key, param]) => {
const defaultStr = param.default !== undefined ? ` (默认: ${param.default})` : '';
parts.push(`- \`${key}\` (${param.type})${defaultStr}: ${param.description}`);
});
parts.push('');
});
}
if (groupTools.length > 0) {
parts.push('### 📚 意群工具');
parts.push('');
groupTools.forEach(tool => {
parts.push(`**${tool.name}**: ${tool.description}`);
parts.push('');
parts.push('参数:');
Object.entries(tool.parameters).forEach(([key, param]) => {
const defaultStr = param.default !== undefined ? ` (默认: ${param.default})` : '';
parts.push(`- \`${key}\` (${param.type})${defaultStr}: ${param.description}`);
});
parts.push('');
});
}
return parts.join('\n');
}
}
// 导出到全局
window.SystemPromptBuilder = SystemPromptBuilder;
console.log('[SystemPromptBuilder] 模块已加载');
})(window);