Files
YG_FT_Platform/web/pages/model-dimension-create.html

775 lines
37 KiB
HTML
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.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>添加评测维度 / 远光软件微调平台</title>
<script src="../lib/tailwindcss/tailwind.js"></script>
<link href="../lib/font-awesome/css/font-awesome.min.css" rel="stylesheet">
<style>
/* 侧边栏滑块动画 */
.sidebar-slider {
position: absolute;
width: 4px;
height: 0;
background-color: #1890ff;
border-radius: 0 2px 2px 0;
transition: top 0.3s cubic-bezier(0.4, 0, 0.2, 1),
height 0.3s cubic-bezier(0.4, 0, 0.2, 1);
pointer-events: none;
z-index: 10;
}
.sidebar-section-title {
padding: 0.5rem 1rem;
font-size: 0.75rem;
color: rgba(191, 203, 217, 0.7);
font-weight: 500;
text-transform: uppercase;
letter-spacing: 0.05em;
}
.nav-link:hover {
background-color: rgba(0, 21, 41, 0.2);
}
.nav-item-wrapper {
position: relative;
}
.nav-link {
position: relative;
z-index: 1;
}
.form-input {
width: 100%;
padding: 0.5rem 0.75rem;
border: 1px solid #d1d5db;
border-radius: 0.5rem;
font-size: 0.875rem;
transition: border-color 0.2s, outline 0.2s;
}
.form-input:focus {
border-color: #1890ff;
outline: none;
box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
}
.form-label {
display: block;
font-size: 0.875rem;
font-weight: 500;
color: #374151;
margin-bottom: 0.25rem;
}
.form-select {
width: 100%;
padding: 0.5rem 0.75rem;
border: 1px solid #d1d5db;
border-radius: 0.5rem;
font-size: 0.875rem;
transition: border-color 0.2s, outline 0.2s;
appearance: none;
background-color: white;
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e");
background-position: right 0.5rem center;
background-repeat: no-repeat;
background-size: 1.5em 1.5em;
padding-right: 2.5rem;
}
.form-select:focus {
border-color: #1890ff;
outline: none;
box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
}
textarea.form-input {
resize: vertical;
min-height: 100px;
}
.radio-option {
display: flex;
align-items: center;
padding: 0.75rem 1rem;
border: 1px solid #d1d5db;
border-radius: 0.5rem;
cursor: pointer;
transition: all 0.2s;
}
.radio-option:hover {
border-color: #1890ff;
}
.radio-option.selected {
border-color: #1890ff;
background-color: rgba(24, 144, 255, 0.05);
}
.radio-option input {
margin-right: 0.75rem;
}
.slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 100%;
height: 6px;
border-radius: 3px;
background: #e5e7eb;
outline: none;
background-image: linear-gradient(#1890ff, #1890ff);
background-repeat: no-repeat;
}
.slider-thumb::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 18px;
height: 18px;
border-radius: 50%;
background: #1890ff;
cursor: pointer;
box-shadow: 0 2px 6px rgba(24, 144, 255, 0.3);
transition: transform 0.2s;
border: 2px solid #fff;
}
.slider-thumb::-webkit-slider-thumb:hover {
transform: scale(1.1);
}
.bg-primary { background-color: #1890ff; }
.text-primary { color: #1890ff; }
.border-primary { border-color: #1890ff; }
.text-danger { color: #f5222d; }
:root { --primary: #1890ff; --danger: #f5222d; --success: #52c41a; }
</style>
</head>
<body class="antialiased bg-gray-50 flex h-screen overflow-hidden">
<!-- 侧边导航 -->
<aside class="w-64 text-[#bfcbd9] flex-shrink-0 hidden md:block flex flex-col h-full" style="background-color: #001529;">
<!-- 平台LOGO区域 -->
<div class="pt-5 pb-3 border-b border-[#001529]/30 flex items-center justify-center pl-2">
<img src="../assets/logo/logo.png" alt="Logo" class="w-8 h-8 object-contain mr-2">
<span class="text-white font-medium text-base">远光软件微调平台</span>
</div>
<!-- 导航主区域 -->
<nav class="flex-1 overflow-y-auto py-2 relative">
<!-- 滑块指示器 -->
<div class="sidebar-slider" id="sidebar-slider"></div>
<!-- 第一分区:模型服务 -->
<div class="sidebar-section-title">模型服务</div>
<div class="nav-item-wrapper">
<a href="main.html" data-page="fine-tune" class="nav-link flex items-center px-4 py-2.5 hover:bg-[#001529]/20 transition-colors">
<i class="fa fa-cogs w-5 text-center"></i>
<span class="ml-2">模型调优</span>
</a>
</div>
<div class="nav-item-wrapper">
<a href="main.html?page=my-models" data-page="my-models" class="nav-link flex items-center px-4 py-2.5 hover:bg-[#001529]/20 transition-colors">
<i class="fa fa-database w-5 text-center"></i>
<span class="ml-2">我的模型</span>
</a>
</div>
<div class="nav-item-wrapper">
<a href="main.html?page=model-eval" data-page="model-eval" class="nav-link flex items-center px-4 py-2.5 hover:bg-[#001529]/20 transition-colors">
<i class="fa fa-line-chart w-5 text-center"></i>
<span class="ml-2">模型评测</span>
</a>
</div>
<div class="nav-item-wrapper">
<a href="main.html?page=model-compare" data-page="model-compare" class="nav-link flex items-center px-4 py-2.5 hover:bg-[#001529]/20 transition-colors">
<i class="fa fa-server w-5 text-center"></i>
<span class="ml-2">模型对比</span>
</a>
</div>
<!-- 第二分区:资源管理 -->
<div class="sidebar-section-title mt-6">资源管理</div>
<div class="nav-item-wrapper">
<a href="main.html?page=model-manage" data-page="model-manage" class="nav-link flex items-center px-4 py-2.5 hover:bg-[#001529]/20 transition-colors">
<i class="fa fa-cube w-5 text-center"></i>
<span class="ml-2">模型管理</span>
</a>
</div>
<div class="nav-item-wrapper">
<a href="main.html?page=dataset-manage" data-page="dataset-manage" class="nav-link flex items-center px-4 py-2.5 hover:bg-[#001529]/20 transition-colors">
<i class="fa fa-file-text w-5 text-center"></i>
<span class="ml-2">数据集管理</span>
</a>
</div>
<div class="nav-item-wrapper">
<a href="main.html?page=data-generate" data-page="data-generate" class="nav-link flex items-center px-4 py-2.5 hover:bg-[#001529]/20 transition-colors">
<i class="fa fa-database w-5 text-center"></i>
<span class="ml-2">其他工具</span>
</a>
</div>
<!-- 第三分区:系统设置 -->
<div class="sidebar-section-title mt-6">系统设置</div>
<div class="nav-item-wrapper">
<a href="main.html?page=config" data-page="config" class="nav-link flex items-center px-4 py-2.5 hover:bg-[#001529]/20 transition-colors">
<i class="fa fa-bar-chart w-5 text-center"></i>
<span class="ml-2">平台性能</span>
</a>
</div>
</nav>
<!-- 底部信息区域 -->
<div class="p-4 border-t border-[#001529]/30 text-xs mt-auto">
<div class="mb-2 text-[#bfcbd9]/80">默认业务空间</div>
<div class="flex items-center justify-between">
<span class="text-[#bfcbd9]">版本 v1.0.0</span>
<i class="fa fa-question-circle-o text-[#bfcbd9]/70"></i>
</div>
</div>
</aside>
<!-- 主内容区 -->
<div class="flex-1 flex flex-col overflow-hidden">
<!-- 顶部导航 -->
<header class="bg-white border-b border-gray-200 shadow-sm">
<div class="flex items-center justify-between px-6 h-14">
<div class="flex items-center space-x-4">
<a href="#" onclick="goBack()" class="text-gray-500 hover:text-gray-700 flex items-center">
<i class="fa fa-arrow-left"></i>
<span class="ml-1">上一步</span>
</a>
</div>
<div class="flex items-center space-x-4">
<div class="relative group">
<img src="https://picsum.photos/id/1005/32/32" class="w-8 h-8 rounded-full cursor-pointer" alt="用户头像">
<div class="absolute right-0 top-full mt-2 bg-white rounded shadow-lg py-1 hidden group-hover:block border border-gray-100 min-w-[140px]">
<a href="login.html" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-50 whitespace-nowrap">
<i class="fa fa-sign-out mr-1"></i>退出登录
</a>
</div>
</div>
</div>
</div>
</header>
<!-- 内容区域 -->
<main class="flex-1 overflow-y-auto p-6 bg-gray-50">
<!-- 页面标题 -->
<div class="bg-white rounded-lg shadow-sm w-full p-4 border-b border-gray-100 mb-4">
<div class="flex items-center text-sm">
<a href="main.html?page=model-eval" class="text-primary hover:underline">模型评测</a>
<span class="mx-2 text-gray-300">/</span>
<span class="text-gray-800 font-medium">添加维度</span>
</div>
</div>
<!-- 表单内容 -->
<div class="bg-white rounded-lg shadow-sm w-full">
<div class="p-6">
<form id="dimensionForm">
<!-- 基本信息 -->
<div class="mb-6">
<h3 class="text-sm font-semibold text-gray-700 mb-4 pb-2 border-b border-gray-100">基本信息</h3>
<div class="space-y-4">
<div>
<label class="form-label">维度名称 <span class="text-red-500">*</span></label>
<input type="text" name="name" class="form-input" placeholder="请输入维度名称" maxlength="50" required>
<p class="text-xs text-gray-400 mt-1"><span id="nameCount">0</span> / 50</p>
</div>
<div>
<label class="form-label">指标类型 <span class="text-red-500">*</span></label>
<select name="type" id="dimensionType" class="form-select" required>
<option value="">请选择指标类型</option>
<option value="classification">大模型评估-分类型</option>
<option value="metric">大模型评估-指标型</option>
</select>
</div>
<div>
<label class="form-label">描述</label>
<textarea name="description" class="form-input" rows="3" placeholder="请输入维度描述" maxlength="200"></textarea>
<p class="text-xs text-gray-400 mt-1"><span id="descCount">0</span> / 200</p>
</div>
</div>
</div>
<!-- 计算配置 -->
<div id="evalConfigSection" style="display: none; margin-bottom: 1.5rem;">
<h3 class="text-sm font-semibold text-gray-700 mb-4 pb-2 border-b border-gray-100">计算配置</h3>
<div class="space-y-4">
<div>
<label class="form-label">选择大模型 <span class="text-red-500">*</span></label>
<select name="eval_model" id="evalModel" class="form-select">
<option value="">请选择评估使用的大模型</option>
<option value="gpt-4">GPT-4</option>
<option value="claude-3">Claude-3</option>
<option value="ernie">文心一言</option>
<option value="qwen">通义千问</option>
<option value="chatglm">ChatGLM</option>
</select>
</div>
<div>
<label class="form-label">评估方式 <span class="text-red-500">*</span></label>
<div class="grid grid-cols-3 gap-4">
<label class="radio-option selected" data-method="standard">
<input type="radio" name="eval_method" value="standard" checked>
<div>
<div class="font-medium text-gray-800">综合评测</div>
<div class="text-xs text-gray-500">根据预设标准评估</div>
</div>
</label>
<label class="radio-option" data-method="semantic">
<input type="radio" name="eval_method" value="semantic">
<div>
<div class="font-medium text-gray-800">语义相似度</div>
<div class="text-xs text-gray-500">计算语义相似程度</div>
</div>
</label>
<label class="radio-option" data-method="custom">
<input type="radio" name="eval_method" value="custom">
<div>
<div class="font-medium text-gray-800">自定义评测</div>
<div class="text-xs text-gray-500">自定义评估规则</div>
</div>
</label>
</div>
</div>
<div>
<label class="form-label">评估 Prompt <span class="text-red-500">*</span></label>
<textarea name="eval_prompt" id="evalPrompt" class="form-input" rows="12"
placeholder="请输入评估时使用的 Prompt"></textarea>
<p class="text-xs text-gray-400 mt-1">定义大模型评估时使用的提示词</p>
</div>
<!-- 评分范围和通过阈值(仅指标型显示) -->
<div id="scoreConfigSection" style="display: none;">
<div class="mb-6">
<label class="form-label">评分范围</label>
<div class="flex items-center space-x-2">
<div class="flex items-center">
<span class="text-sm text-gray-500 mr-2">最小分数</span>
<input type="number" name="score_min" id="scoreMin" class="form-input w-28" value="0" min="0" step="1">
</div>
<span class="text-gray-400">-</span>
<div class="flex items-center">
<span class="text-sm text-gray-500 mr-2">最大分数</span>
<input type="number" name="score_max" id="scoreMax" class="form-input w-28" value="5" min="0" step="1">
</div>
</div>
</div>
<div>
<label class="form-label">通过阈值</label>
<div class="flex items-center space-x-3">
<input type="range" name="pass_threshold" id="passThreshold" class="slider-thumb w-64" min="0" max="5" step="0.5" value="3">
<input type="number" id="passThresholdValue" class="form-input w-20 text-center" min="0" max="5" step="0.5" value="3">
</div>
<p class="text-xs text-gray-400 mt-1">评分大于等于此值视为通过</p>
</div>
</div>
</div>
</div>
<!-- 状态设置 -->
<div class="mb-6">
<h3 class="text-sm font-semibold text-gray-700 mb-4 pb-2 border-b border-gray-100">状态设置</h3>
<div class="space-y-4">
<div class="flex items-center">
<input type="checkbox" name="is_active" id="isActive" class="w-4 h-4 text-primary border-gray-300 rounded focus:ring-primary" checked>
<label for="isActive" class="ml-2 text-sm text-gray-700">启用该维度</label>
</div>
<div class="flex items-center">
<input type="checkbox" name="is_default" id="isDefault" class="w-4 h-4 text-primary border-gray-300 rounded focus:ring-primary">
<label for="isDefault" class="ml-2 text-sm text-gray-700">设为默认评测维度</label>
</div>
</div>
</div>
<!-- 底部按钮 -->
<div class="flex items-center justify-between pt-6 border-t border-gray-100">
<div class="flex items-center space-x-3">
<button type="button" onclick="submitForm()" class="px-4 py-2 bg-primary text-white rounded-lg text-sm hover:bg-primary/90 transition-colors">
保存维度
</button>
<button type="button" onclick="goBack()" class="px-4 py-2 bg-gray-200 text-gray-700 rounded-lg text-sm hover:bg-gray-300 transition-colors">
取消
</button>
</div>
</div>
</form>
</div>
</div>
</main>
</div>
<script>
// 动态获取 API 基础地址
const getApiBase = () => {
const protocol = window.location.protocol;
const hostname = window.location.hostname;
return `${protocol}//${hostname}:8080/api`;
};
const API_BASE = getApiBase();
// 返回列表页
function goBack() {
window.location.href = 'main.html?page=model-eval';
}
// 显示/隐藏计算配置
function toggleEvalConfig() {
const type = document.getElementById('dimensionType').value;
const configSection = document.getElementById('evalConfigSection');
const scoreSection = document.getElementById('scoreConfigSection');
if (type === 'classification' || type === 'metric') {
configSection.style.display = 'block';
// 指标型才显示评分范围和通过阈值
scoreSection.style.display = (type === 'metric') ? 'block' : 'none';
} else {
configSection.style.display = 'none';
}
}
// 选择评估方式
function selectEvalMethod(element) {
document.querySelectorAll('.radio-option').forEach(opt => {
opt.classList.remove('selected');
});
element.classList.add('selected');
element.querySelector('input').checked = true;
}
// 评估方式对应的默认 Prompt
const EVAL_METHOD_PROMPTS = {
standard: `# 角色
你是一位资深的答案评估专家,擅长对大模型生成的结果进行细致的评分和反馈。你的角色是确保答案的质量符合高标准,并且能够提供具体的改进建议。
## 技能
### 技能1评估相关性
- **任务**:根据用户提出的问题,评估回答的相关性。
- 确保回答内容直接针对用户的问题,避免无关信息。
- 评估回答是否全面覆盖了用户问题的所有方面。
### 技能2评估文化敏感与无害
- **任务**:检查回答是否尊重用户的文化背景和差异。
- 确保回答内容合乎伦理道德,避免文化偏见和不敏感的表达。
- 检查回答中是否包含任何可能冒犯的内容,并提出改进建议。
### 技能3评估信息丰富性
- **任务**:评估回答的信息丰富程度。
- 确保回答在保证准确性的同时提供详尽的信息。
- 评估回答是否包含了用户可能未明确要求但对理解问题有帮助的背景信息。
### 技能4评估清晰性
- **任务**:评估回答的清晰度。
- 确保回答使用了清晰、易懂的语言。
- 避免使用可能引起误解的专业术语或复杂构造。
- 提供改进建议以提高回答的可读性和易理解性。
### 技能5评估用户参与度
- **任务**:评估回答是否能够吸引用户的兴趣并保持其参与度。
- 确保回答具有吸引力,能够激发用户的兴趣。
- 评估回答是否提供了互动的机会,如提问或进一步讨论的建议。
## 限制
- 评估过程中必须严格遵守上述五个评判标准。
- 评估结果应客观公正,不得带有个人偏见。
- 在提供改进建议时,应具体明确,便于改进。
- 评估过程中需尊重用户的文化背景和差异,确保回答内容无害且合适。
- 评估结果应基于最新的行业标准和最佳实践。
## 要求
请输出评分原因和评分分数分数在1-5之间分数越高表示大模型的回答质量越高。
## 对话
输入:\${prompt}
输出:\${output}`,
sentiment: `# 角色
你是一位情感分析专家,擅长识别和评估文本中的情感基调。你能够通过分析用户输入的信息内容和上下文,确定其语气是消极的、中性的还是积极的。
## 技能
### 技能1情感关键字识别
- 识别表明情感或情绪的关键字或短语。
- 注意任何可能影响情绪基调的上下文线索。
### 技能2详细推理
- 清楚地说明信息中的证据。
- 解释为什么每个证据都有助于结论。
- 确保推理彻底,以验证结论的正确性。
### 技能3整体语境评估
- 考虑整体语境和用词来评估情绪。
- 将信息的情绪语气分为以下几个等级:消极、中性或积极。
## 限制
- 仅基于提供的文本内容进行情感分析。
- 不引入个人偏见或主观判断。
- 确保推理过程详细且逻辑严密。
## 输出格式
- 推理:[详细推理在这里]
- 结果:"消极"、"中性"或"积极"
## 示例
**输入:**"我对服务不满意。"
* *输出:* *
- 推理:"不开心"这个短语表示不满。在这条信息中没有任何积极的元素,而且上下文明确暗示了一种消极的体验。
- 结果:消极
**输入:**"这顿饭还行,没什么特别的,但也不错。"
* *输出:* *
- 推理:"还行"这个词表示一种中性的感觉。像"没什么特别的"和"还不错"这样的短语既没有强烈的积极情绪,也没有强烈的消极情绪。
- 结果:中性
**输入:**"我在活动中度过了一段美好的时光!"
* *输出:* *
- 推理:"美好"这个词是一个强有力的积极指标。上下文暗示了一次愉快的经历。
- 结果:积极
## 对话
输入: \${prompt}
输出: \${output}`,
semantic: `# 角色
你是一名专业的评估专家擅长在1到5的范围内评估给定输出与基本事实之间的相似程度。你的评估基于详细的思维链推理确保逐步推理和透明度。
## 技能
### 技能 1: 识别关键要素
- **任务**:识别并列出在输出和基本事实中存在的关键要素。
- 确定句子中的主要信息和核心概念。
- 识别句子中的关键名词、动词和形容词。
### 技能 2: 比较关键要素
- **任务**:比较这些关键元素,从内容和结构两方面来评估它们的异同。
- 分析句子的内容,包括描述的对象、动作和属性。
- 比较句子的结构,包括句法和语序。
### 技能 3: 语义分析
- **任务**:分析输出和真实值所传达的语义,注意任何显著的偏差。
- 评估句子的整体意义和意图。
- 识别任何可能导致误解或歧义的部分。
### 技能 4: 相似度分类
- **任务**:基于这些比较,根据定义的标准对相似程度进行分类。
- 使用以下标准进行分类:
- 5高度相似-输出值和实际值几乎相同,只有微小的、不显著的差异。
- 4有些相似-输出在很大程度上与ground truth相似但几乎没有明显的差异。
- 3适度相似-有一些明显的差异,但核心本质是在输出中捕获的。
- 2稍微相似-输出只捕获地面真相的几个元素,并包含一些差异。
- 1不相似-输出与地面真实值明显不同,很少或没有匹配元素。
### 技能 5: 评分解释
- **任务**:写出为什么选择一个特定分数的原因,以确保透明度和正确性。
- 提供详细的推理过程,解释每个步骤的依据。
- 说明选择特定分数的理由,确保评估的公正性和一致性。
### 技能 6: 最终评分
- **任务**:根据定义的标准分配相似度分数。
- 以整数1、2、3、4或5的形式提供最终的相似性得分。
## 限制
- 始终致力于提供公平和平衡的评估。
- 在评估中同时考虑句法和语义的差异。
- 对相似对评分的一致性对于准确测量至关重要。
- 评估过程中保持透明度,详细记录每一步的推理过程。
- 不引入个人观点或偏见,确保评估的客观性。
## 对话
输入:\${prompt}
模型回答:\${output}
参考答案:\${completion}`,
custom: ``
};
// 初始化函数
function initPage() {
// 绑定指标类型下拉框事件
const dimensionType = document.getElementById('dimensionType');
if (dimensionType) {
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] || '';
}
});
});
// 绑定通过阈值滑块和输入框事件
const passThresholdSlider = document.getElementById('passThreshold');
const passThresholdValue = document.getElementById('passThresholdValue');
// 更新滑块背景进度颜色
function updateSliderBackground(slider) {
const min = parseFloat(slider.min) || 0;
const max = parseFloat(slider.max) || 5;
const value = parseFloat(slider.value) || 0;
const percent = ((value - min) / (max - min)) * 100;
slider.style.backgroundSize = percent + '% 100%';
}
if (passThresholdSlider && passThresholdValue) {
// 初始化滑块背景
updateSliderBackground(passThresholdSlider);
// 滑块拖动时更新输入框
passThresholdSlider.addEventListener('input', function() {
passThresholdValue.value = parseFloat(this.value);
updateSliderBackground(this);
});
// 输入框输入时更新滑块
passThresholdValue.addEventListener('input', function() {
let val = parseFloat(this.value);
if (isNaN(val)) val = 0;
const maxVal = parseFloat(document.getElementById('scoreMax').value) || 5;
if (val > maxVal) val = maxVal;
if (val < 0) val = 0;
passThresholdSlider.value = val;
updateSliderBackground(passThresholdSlider);
});
}
// 绑定评分范围输入框事件(同步滑块最大值)
const scoreMaxInput = document.getElementById('scoreMax');
if (scoreMaxInput) {
scoreMaxInput.addEventListener('input', function() {
const maxVal = parseFloat(this.value) || 5;
passThresholdSlider.max = maxVal;
if (parseFloat(passThresholdSlider.value) > maxVal) {
passThresholdSlider.value = maxVal;
passThresholdValue.value = maxVal.toFixed(1);
}
updateSliderBackground(passThresholdSlider);
});
}
// 绑定侧边栏导航点击事件
document.querySelectorAll('.nav-link').forEach(link => {
link.addEventListener('click', function(e) {
if (!this.href.includes('model-dimension-create')) {
e.preventDefault();
window.location.href = this.href;
}
});
});
// 绑定输入事件
const nameInput = document.querySelector('input[name="name"]');
const descInput = document.querySelector('textarea[name="description"]');
if (nameInput) {
nameInput.addEventListener('input', () => {
document.getElementById('nameCount').textContent = nameInput.value.length;
});
}
if (descInput) {
descInput.addEventListener('input', () => {
document.getElementById('descCount').textContent = descInput.value.length;
});
}
// 设置侧边栏当前页高亮
const currentPage = 'model-eval';
document.querySelectorAll('.nav-link').forEach(link => {
if (link.dataset.page === currentPage) {
link.classList.add('bg-[#1890ff]/10', 'text-[#1890ff]');
link.classList.remove('hover:bg-[#001529]/20', 'transition-colors');
}
});
updateSidebarSlider();
// 初始化计算配置的显示状态
toggleEvalConfig();
}
// 页面加载完成后初始化
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initPage);
} else {
initPage();
}
// 更新侧边栏滑块位置
function updateSidebarSlider() {
const slider = document.getElementById('sidebar-slider');
if (!slider) return;
const activeLink = document.querySelector('.nav-link.bg-\\[\\#1890ff\\]\\/10');
if (activeLink) {
const wrapper = activeLink.closest('.nav-item-wrapper');
if (wrapper) {
slider.style.top = wrapper.offsetTop + 'px';
slider.style.height = wrapper.offsetHeight + 'px';
}
}
}
// 提交表单
async function submitForm() {
const form = document.getElementById('dimensionForm');
const formData = new FormData(form);
const name = formData.get('name').trim();
const type = formData.get('type').trim();
if (!name) {
alert('请输入维度名称');
return;
}
if (!type) {
alert('请选择指标类型');
return;
}
// 检查计算配置是否完整
if (type === 'classification' || type === 'metric') {
const evalModel = formData.get('eval_model').trim();
const evalPrompt = formData.get('eval_prompt').trim();
const evalMethod = formData.get('eval_method');
if (!evalModel) {
alert('请选择评估使用的大模型');
return;
}
if (!evalPrompt) {
alert('请输入评估 Prompt');
return;
}
}
const data = {
name: name,
type: type,
description: formData.get('description').trim(),
eval_model: formData.get('eval_model'),
eval_method: formData.get('eval_method'),
eval_prompt: formData.get('eval_prompt').trim(),
is_active: formData.get('is_active') === 'on',
is_default: formData.get('is_default') === 'on',
create_time: new Date().toLocaleString('zh-CN', { hour12: false }).replace(/\//g, '-')
};
// 指标型添加评分范围和通过阈值
if (type === 'metric') {
data.score_min = parseFloat(formData.get('score_min')) || 0;
data.score_max = parseFloat(formData.get('score_max')) || 5;
data.pass_threshold = parseFloat(formData.get('pass_threshold')) || 3;
}
try {
const response = await fetch(`${API_BASE}/model-eval/dimension`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
});
const result = await response.json();
if (result.code === 0) {
alert('评测维度创建成功!');
goBack();
} else {
alert('创建失败: ' + (result.message || '未知错误'));
}
} catch (error) {
alert('创建失败: ' + error.message);
}
}
</script>
</body>
</html>