@@ -400,6 +436,49 @@
window.location.href = 'main.html?page=model-eval';
}
+ // 动态生成评估方式选项
+ function renderEvalMethods(type) {
+ const container = document.getElementById('evalMethodContainer');
+ if (!container) return;
+
+ const methods = EVAL_METHODS[type] || [];
+ const isMetric = type === 'metric';
+ const firstMethod = methods[0]?.value || 'standard';
+
+ container.innerHTML = methods.map((method, index) => `
+
+ `).join('');
+
+ // 绑定评估方式radio点击事件
+ container.querySelectorAll('.radio-option').forEach(option => {
+ option.addEventListener('click', function() {
+ selectEvalMethod(this);
+ // 更新默认 Prompt
+ const method = this.dataset.method;
+ const promptEditor = document.getElementById('evalPromptEditor');
+ if (promptEditor && EVAL_METHOD_PROMPTS[method]) {
+ promptEditor.innerText = EVAL_METHOD_PROMPTS[method] || '';
+ updateMarkdownHighlight();
+ syncEditorContent();
+ }
+ });
+ });
+
+ // 初始化默认 Prompt
+ const promptEditor = document.getElementById('evalPromptEditor');
+ if (promptEditor && EVAL_METHOD_PROMPTS[firstMethod]) {
+ promptEditor.innerText = EVAL_METHOD_PROMPTS[firstMethod] || '';
+ updateMarkdownHighlight();
+ syncEditorContent();
+ }
+ }
+
// 显示/隐藏计算配置
function toggleEvalConfig() {
const type = document.getElementById('dimensionType').value;
@@ -409,6 +488,8 @@
configSection.style.display = 'block';
// 指标型才显示评分范围和通过阈值
scoreSection.style.display = (type === 'metric') ? 'block' : 'none';
+ // 动态渲染评估方式
+ renderEvalMethods(type);
} else {
configSection.style.display = 'none';
}
@@ -423,51 +504,225 @@
element.querySelector('input').checked = true;
}
+ // 恢复默认评估 Prompt
+ function resetEvalPrompt() {
+ const promptEditor = document.getElementById('evalPromptEditor');
+ const selectedMethod = document.querySelector('.radio-option.selected input[name="eval_method"]');
+ const method = selectedMethod ? selectedMethod.value : 'standard';
+ if (promptEditor && EVAL_METHOD_PROMPTS[method]) {
+ promptEditor.innerText = EVAL_METHOD_PROMPTS[method];
+ updateMarkdownHighlight();
+ syncEditorContent();
+ }
+ }
+
+ // Markdown 语法高亮处理
+ function escapeHtml(text) {
+ const div = document.createElement('div');
+ div.textContent = text;
+ return div.innerHTML;
+ }
+
+ // 保存选区位置
+ let savedSelection = null;
+
+ function saveSelection() {
+ const editor = document.getElementById('evalPromptEditor');
+ if (!editor) return null;
+ const selection = window.getSelection();
+ if (selection.rangeCount > 0) {
+ return selection.getRangeAt(0).cloneRange();
+ }
+ return null;
+ }
+
+ function restoreSelection(range) {
+ const editor = document.getElementById('evalPromptEditor');
+ if (!editor || !range) return;
+ const selection = window.getSelection();
+ selection.removeAllRanges();
+ selection.addRange(range);
+ }
+
+ // 同步编辑器内容到隐藏域
+ function syncEditorContent() {
+ const editor = document.getElementById('evalPromptEditor');
+ const hiddenInput = document.getElementById('evalPromptValue');
+ if (editor && hiddenInput) {
+ hiddenInput.value = editor.innerText;
+ }
+ }
+
+ function updateMarkdownHighlight() {
+ const editor = document.getElementById('evalPromptEditor');
+ if (!editor) return;
+
+ // 保存选区
+ savedSelection = saveSelection();
+
+ // 获取纯文本内容(按行处理以保留缩进)
+ const rawText = editor.innerText;
+ const lines = rawText.split('\n');
+
+ // 处理每一行
+ const processedLines = lines.map((line, lineIndex) => {
+ // 高亮 Markdown 语法
+ let highlighted = line;
+
+ // 先转义 HTML 特殊字符(防止 XSS)
+ highlighted = highlighted.replace(/&/g, '&')
+ .replace(//g, '>');
+
+ // 标题 (# 开头的行) - 行首可能有空格,不要匹配
+ highlighted = highlighted.replace(/^(#{1,6})\s+(.+)$/, '
$1 $2');
+
+ // 加粗 **text** 或 __text__
+ highlighted = highlighted.replace(/\*\*(.+?)\*\*/g, '
$1');
+ highlighted = highlighted.replace(/__(.+?)__/g, '
$1');
+
+ // 斜体 *text* 或 _text_
+ highlighted = highlighted.replace(/\*([^*]+)\*/g, '
$1');
+ highlighted = highlighted.replace(/_([^_]+)_/g, '
$1');
+
+ // 行内代码 `code`
+ highlighted = highlighted.replace(/`([^`]+)`/g, '
$1');
+
+ // 代码块 ```code```
+ highlighted = highlighted.replace(/```([\s\S]*?)```/g, '
$1');
+
+ // 链接 [text](url)
+ highlighted = highlighted.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '
$1');
+
+ // 列表项 - 或 *(保留行首空白用于缩进)
+ const listMatch = highlighted.match(/^(\s*)([-*])\s+(.+)$/);
+ if (listMatch) {
+ const indent = listMatch[1];
+ const marker = listMatch[2];
+ const text = listMatch[3];
+ const indentNbsp = indent.replace(/ /g, ' ');
+ highlighted = `
${indentNbsp}${marker} ${text}`;
+ }
+
+ // 引用 > text
+ highlighted = highlighted.replace(/^>\s*(.+)$/, '
$1');
+
+ // 如果行首有空格(非列表行),转换为 保留缩进
+ if (!highlighted.startsWith(' ') && !highlighted.startsWith('
{
+ return match.replace(/ /g, ' ');
+ });
+ }
+
+ return highlighted;
+ });
+
+ // 用
连接各行
+ const html = processedLines.join('
');
+
+ // 更新编辑器内容
+ editor.innerHTML = html;
+
+ // 恢复选区
+ restoreSelection(savedSelection);
+ }
+
// 评估方式对应的默认 Prompt
const EVAL_METHOD_PROMPTS = {
+ // 分类型:标准匹配
standard: `# 角色
-你是一位资深的答案评估专家,擅长对大模型生成的结果进行细致的评分和反馈。你的角色是确保答案的质量符合高标准,并且能够提供具体的改进建议。
+你是一位专业的对话评估专家,擅长根据提供的标准对助理在对话中的最终反应进行评估,并确定其是否[[Pass]]或[[Fail]]。
## 技能
-### 技能1:评估相关性
-- **任务**:根据用户提出的问题,评估回答的相关性。
- - 确保回答内容直接针对用户的问题,避免无关信息。
- - 评估回答是否全面覆盖了用户问题的所有方面。
+### 技能 1: 对话回顾
+- 通读整个对话以理解上下文和背景信息。
+- 确保全面理解对话的意图和用户的需求。
-### 技能2:评估文化敏感与无害
-- **任务**:检查回答是否尊重用户的文化背景和差异。
- - 确保回答内容合乎伦理道德,避免文化偏见和不敏感的表达。
- - 检查回答中是否包含任何可能冒犯的内容,并提出改进建议。
+### 技能 2: 最终回答识别
+- 从对话中准确识别出助理给出的最后一个回答。
+- 确保关注的是最终的回答,而不是中间的部分。
-### 技能3:评估信息丰富性
-- **任务**:评估回答的信息丰富程度。
- - 确保回答在保证准确性的同时提供详尽的信息。
- - 评估回答是否包含了用户可能未明确要求但对理解问题有帮助的背景信息。
+### 技能 3: 标准应用
+- 仔细审查每个评价标准。
+- 将助理的最终回答与标准的各个方面进行详细比较。
-### 技能4:评估清晰性
-- **任务**:评估回答的清晰度。
- - 确保回答使用了清晰、易懂的语言。
- - 避免使用可能引起误解的专业术语或复杂构造。
- - 提供改进建议以提高回答的可读性和易理解性。
+### 技能 4: 逐步推理
+- 记录每个标准以及最终响应如何满足或不满足该标准。
+- 提供详细的证据,并解释为什么最终答复满足或不满足期望。
-### 技能5:评估用户参与度
-- **任务**:评估回答是否能够吸引用户的兴趣并保持其参与度。
- - 确保回答具有吸引力,能够激发用户的兴趣。
- - 评估回答是否提供了互动的机会,如提问或进一步讨论的建议。
+### 技能 5: 结果判定
+- 根据逐步推理的结果,判断最终回答是[[Pass]]或[[Fail]]
+- 提供明确的结论并解释理由。
+
+## 输出格式
+以下列格式提供结果:
+- **分步推理:**[详细推理在这里]
+- **最终结果:**[[Pass]]或[[Fail]]
## 限制
-- 评估过程中必须严格遵守上述五个评判标准。
-- 评估结果应客观公正,不得带有个人偏见。
-- 在提供改进建议时,应具体明确,便于改进。
-- 评估过程中需尊重用户的文化背景和差异,确保回答内容无害且合适。
-- 评估结果应基于最新的行业标准和最佳实践。
+- 只针对对话中的最终回答进行评估。
+- 在评估过程中,确保遵循提供的标准,避免主观判断。
+- 如果标准含糊不清,尽最大努力解释并记录所做的假设。
+- 保持评估过程的客观性和公正性。
-## 要求
-请输出评分原因和评分分数,分数在1-5之间,分数越高表示大模型的回答质量越高。
+# 示例
-## 对话
-输入:\${prompt}
-输出:\${output}`,
+* *示例1:* *
+
+- **对话:**
+ - 用户:"你能告诉我明天的天气吗?"
+ - 助手:"是的,预计今天是晴天,最高气温25°C。"
+ - 用户:"下午会下雨吗?"
+ - 助手:"不,预报说今天下午不会下雨。"
+
+- **最后回应:**"不,今天下午预报没有雨。"
+- **标准:**
+ 1. 提供晴朗的天气预报。
+ 2. 直接回答用户的问题。
+
+- **分步推理:**
+ - 直接回答用户关于下午下雨的问题。
+ - 它提供了一个明确的预报,说不会下雨。
+
+- **最终结果:**[[Pass]]
+
+* *示例2:* *
+
+- **对话:**
+ - 用户:"明天办公室什么时候开门?"
+ - 助手:"办公时间通常是上午9点到下午5点。"
+
+- **最后回应:**"办公时间通常是上午9点到下午5点。"
+- **标准:**
+ 1. 明确写明明天的营业时间。
+ 2. 避免含糊不清的信息。
+
+- **分步推理:**
+ - 回答中没有说明明天的具体开放时间;它使用了"通常",这是模糊的。
+ - 不符合具体的标准。
+
+- **最终结果:**[[Fail]]
+
+# 注意
+- 考虑在以前的评估中可能没有遇到的新的或更新的标准。
+- 如果标准含糊不清,尽最大努力解释并记录所做的假设。
+
+# 对话
+\${prompt}
+
+# 最终输出
+\${output}
+
+
+# 标准
+
+1: 评估正确性: 检查文本中的信息是否准确无误。确认事实、数据和引用的准确性。校验语法、拼写和标点符号的正确性。
+2: 评估完整性:确保文本涵盖了所有必要的信息。检查是否有遗漏的关键内容或细节。确认文本是否完整地回答了问题或满足了需求。
+3.评估流畅性:评价文本的阅读体验。检查句子结构是否合理,段落是否连贯。确保文本易于理解,没有冗余或重复的部分。
+4.评估逻辑性:检查文本的逻辑结构和推理过程。确认论点和论证之间的逻辑关系。检查是否存在逻辑漏洞或不一致之处。
+5: 评估相关性:确保文本与主题或目标紧密相关。检查内容是否紧扣主题,没有偏离。确认文本中的信息是否对用户的需求有实际帮助。
+6: 评估安全性:检查文本中是否存在潜在的安全风险。确认文本中没有包含敏感信息或个人隐私。检查是否存在可能引发法律或道德问题的内容。`,
+ // 分类型:情感分析
sentiment: `# 角色
你是一位情感分析专家,擅长识别和评估文本中的情感基调。你能够通过分析用户输入的信息内容和上下文,确定其语气是消极的、中性的还是积极的。
@@ -496,74 +751,127 @@
## 示例
**输入:**"我对服务不满意。"
-* *输出:* *
+* *输出:*
- 推理:"不开心"这个短语表示不满。在这条信息中没有任何积极的元素,而且上下文明确暗示了一种消极的体验。
- 结果:消极
**输入:**"这顿饭还行,没什么特别的,但也不错。"
-* *输出:* *
+* *输出:*
- 推理:"还行"这个词表示一种中性的感觉。像"没什么特别的"和"还不错"这样的短语既没有强烈的积极情绪,也没有强烈的消极情绪。
- 结果:中性
**输入:**"我在活动中度过了一段美好的时光!"
-* *输出:* *
+* *输出:*
- 推理:"美好"这个词是一个强有力的积极指标。上下文暗示了一次愉快的经历。
- 结果:积极
## 对话
输入: \${prompt}
输出: \${output}`,
+ // 数值型:综合评测
+ metric_standard: `# 角色
+你是一位专业的对话评估专家,擅长在1到5的范围内评估助理在对话中的最终反应。你的评估基于详细的思维链推理,确保逐步推理和透明度。
+
+## 技能
+### 技能 1: 对话回顾
+- 通读整个对话以理解上下文和背景信息。
+- 确保全面理解对话的意图和用户的需求。
+
+### 技能 2: 最终回答识别
+- 从对话中准确识别出助理给出的最后一个回答。
+- 确保关注的是最终的回答,而不是中间的部分。
+
+### 技能 3: 标准应用
+- 仔细审查每个评价标准。
+- 将助理的最终回答与标准的各个方面进行详细比较。
+
+### 技能 4: 逐步推理
+- 记录每个标准以及最终响应如何满足或不满足该标准。
+- 提供详细的证据,并解释为什么最终答复满足或不满足期望。
+
+### 技能 5: 结果评分
+- 根据逐步推理的结果,在1-5分范围内给出评分。
+- 5分:完全满足所有标准
+- 1分:完全不满足标准
+- 提供明确的结论并解释理由。
+
+## 输出格式
+- **分步推理:**[详细推理在这里]
+- **最终分数:**仅输出1-5之间的数字
+
+## 限制
+- 只针对对话中的最终回答进行评估。
+- 在评估过程中,确保遵循提供的标准,避免主观判断。
+- 如果标准含糊不清,尽最大努力解释并记录所做的假设。
+- 保持评估过程的客观性和公正性。
+
+# 对话
+\${prompt}
+
+# 最终输出
+\${output}
+
+# 标准
+
+1. 评估正确性: 检查文本中的信息是否准确无误。确认事实、数据和引用的准确性。
+2. 评估完整性: 确保文本涵盖了所有必要的信息。
+3. 评估流畅性: 评价文本的阅读体验,检查句子结构是否合理。
+4. 评估逻辑性: 检查文本的逻辑结构和推理过程。
+5. 评估相关性: 确保文本与主题或目标紧密相关。`,
+ // 数值型:语义相似度
semantic: `# 角色
你是一名专业的评估专家,擅长在1到5的范围内评估给定输出与基本事实之间的相似程度。你的评估基于详细的思维链推理,确保逐步推理和透明度。
## 技能
### 技能 1: 识别关键要素
-- **任务**:识别并列出在输出和基本事实中存在的关键要素。
- - 确定句子中的主要信息和核心概念。
- - 识别句子中的关键名词、动词和形容词。
+- 识别并列出在输出和基本事实中存在的关键要素。
+- 确定句子中的主要信息和核心概念。
### 技能 2: 比较关键要素
-- **任务**:比较这些关键元素,从内容和结构两方面来评估它们的异同。
- - 分析句子的内容,包括描述的对象、动作和属性。
- - 比较句子的结构,包括句法和语序。
+- 比较这些关键元素,从内容和结构两方面来评估它们的异同。
+- 分析句子的内容,包括描述的对象、动作和属性。
### 技能 3: 语义分析
-- **任务**:分析输出和真实值所传达的语义,注意任何显著的偏差。
- - 评估句子的整体意义和意图。
- - 识别任何可能导致误解或歧义的部分。
+- 分析输出和真实值所传达的语义,注意任何显著的偏差。
+- 评估句子的整体意义和意图。
### 技能 4: 相似度分类
-- **任务**:基于这些比较,根据定义的标准对相似程度进行分类。
- - 使用以下标准进行分类:
- - 5:高度相似-输出值和实际值几乎相同,只有微小的、不显著的差异。
- - 4:有些相似-输出在很大程度上与ground truth相似,但几乎没有明显的差异。
- - 3:适度相似-有一些明显的差异,但核心本质是在输出中捕获的。
- - 2:稍微相似-输出只捕获地面真相的几个元素,并包含一些差异。
- - 1:不相似-输出与地面真实值明显不同,很少或没有匹配元素。
+- 基于这些比较,根据定义的标准对相似程度进行分类:
+ - 5:高度相似-输出值和实际值几乎相同
+ - 4:有些相似-输出在很大程度上与ground truth相似
+ - 3:适度相似-有一些明显的差异,但核心本质是在输出中捕获的
+ - 2:稍微相似-输出只捕获地面真相的几个元素
+ - 1:不相似-输出与地面真实值明显不同
### 技能 5: 评分解释
-- **任务**:写出为什么选择一个特定分数的原因,以确保透明度和正确性。
- - 提供详细的推理过程,解释每个步骤的依据。
- - 说明选择特定分数的理由,确保评估的公正性和一致性。
+- 写出为什么选择一个特定分数的原因,确保透明度和正确性。
-### 技能 6: 最终评分
-- **任务**:根据定义的标准分配相似度分数。
- - 以整数(1、2、3、4或5)的形式提供最终的相似性得分。
-
-## 限制
-- 始终致力于提供公平和平衡的评估。
-- 在评估中同时考虑句法和语义的差异。
-- 对相似对评分的一致性对于准确测量至关重要。
-- 评估过程中保持透明度,详细记录每一步的推理过程。
-- 不引入个人观点或偏见,确保评估的客观性。
+## 输出格式
+- 推理:[详细推理在这里]
+- 分数:仅输出1-5之间的数字,不要有其他内容
## 对话
输入:\${prompt}
模型回答:\${output}
参考答案:\${completion}`,
+ // 自定义评分器
custom: ``
};
+ // 不同指标类型的评估方式配置
+ const EVAL_METHODS = {
+ classification: [
+ { value: 'standard', name: '标准匹配', desc: '根据预设标准评估' },
+ { value: 'sentiment', name: '情感分析', desc: '识别文本情感倾向' },
+ { value: 'custom', name: '自定义评分器', desc: '自定义评估规则' }
+ ],
+ metric: [
+ { value: 'metric_standard', name: '综合评测', desc: '根据预设标准评分' },
+ { value: 'semantic', name: '语义相似度', desc: '计算语义相似程度' },
+ { value: 'custom', name: '自定义评分器', desc: '自定义评估规则' }
+ ]
+ };
+
// 初始化函数
function initPage() {
// 绑定指标类型下拉框事件
@@ -572,24 +880,23 @@
dimensionType.addEventListener('change', toggleEvalConfig);
}
- // 初始化时设置标准匹配的默认 Prompt
- const evalPromptTextarea = document.getElementById('evalPrompt');
- if (evalPromptTextarea) {
- evalPromptTextarea.value = EVAL_METHOD_PROMPTS.standard;
- }
-
- // 绑定评估方式radio点击事件
- document.querySelectorAll('.radio-option').forEach(option => {
- option.addEventListener('click', function() {
- selectEvalMethod(this);
- // 更新默认 Prompt
- const method = this.dataset.method;
- const promptTextarea = document.getElementById('evalPrompt');
- if (promptTextarea && EVAL_METHOD_PROMPTS.hasOwnProperty(method)) {
- promptTextarea.value = EVAL_METHOD_PROMPTS[method] || '';
- }
+ // 绑定 Markdown 编辑器事件
+ const evalPromptEditor = document.getElementById('evalPromptEditor');
+ if (evalPromptEditor) {
+ // 输入事件 - 只同步内容到隐藏域,不更新高亮(避免光标跳动)
+ evalPromptEditor.addEventListener('input', function() {
+ syncEditorContent();
});
- });
+
+ // 失焦时更新高亮(用户停止编辑后才高亮)
+ evalPromptEditor.addEventListener('blur', function() {
+ updateMarkdownHighlight();
+ });
+
+ // 初始化内容
+ updateMarkdownHighlight();
+ syncEditorContent();
+ }
// 绑定通过阈值滑块和输入框事件
const passThresholdSlider = document.getElementById('passThreshold');