Files
YG_FT/frontend/src/views/eval/DimensionCreateView.vue

159 lines
4.8 KiB
Vue
Raw Normal View History

<script setup lang="ts">
import { ref, reactive, computed, onMounted } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { ElMessage, type FormInstance, type FormRules } from 'element-plus'
import PageCard from '@/components/PageCard.vue'
import DimensionFormFields, { type DimensionFormDraft } from './create/DimensionFormFields.vue'
import {
createDimension,
updateDimension,
getDimension,
} from '@/api/modules/eval'
import { getModelList } from '@/api/modules/model'
import { EVAL_METHODS } from '@/constants/dimension'
import type { ModelItem } from '@/types'
const route = useRoute()
const router = useRouter()
const formRef = ref<FormInstance>()
const submitting = ref(false)
const isEdit = computed(() => !!route.params.id)
const editId = computed(() => route.params.id as string | undefined)
const evalModels = ref<ModelItem[]>([])
const form = reactive<DimensionFormDraft & { name: string }>({
name: '',
type: '',
description: '',
eval_model: '',
eval_method: '' as string | string[],
eval_prompt: '',
is_active: true,
is_default: false,
// text_similarity
bleu_n: 1,
output_precision: 3,
// metric
score_min: 0,
score_max: 5,
pass_threshold: 3,
})
const rules: FormRules = {
name: [
{ required: true, message: '请输入维度名称', trigger: 'blur' },
{ max: 50, message: '不超过 50 字符', trigger: 'blur' },
],
type: [{ required: true, message: '请选择指标类型', trigger: 'change' }],
eval_model: [{ required: true, message: '请选择大模型', trigger: 'change' }],
eval_method: [{ required: true, message: '请选择评估方式', trigger: 'change' }],
eval_prompt: [{ required: true, message: '请填写评估 Prompt', trigger: 'blur' }],
}
async function loadEditData() {
if (!editId.value) return
try {
const dim: any = await getDimension(editId.value)
// 补全所有字段回填(修复原项目回填不完整 bug
Object.assign(form, {
name: dim.name || '',
type: dim.type || '',
description: dim.description || '',
eval_model: dim.eval_model || '',
eval_method: dim.eval_method || (dim.type ? EVAL_METHODS[dim.type]?.[0]?.value : ''),
eval_prompt: dim.eval_prompt || '',
is_active: dim.is_active !== false,
is_default: !!dim.is_default,
bleu_n: dim.bleu_n ?? 1,
output_precision: dim.output_precision ?? 3,
score_min: dim.score_min ?? 0,
score_max: dim.score_max ?? 5,
pass_threshold: dim.pass_threshold ?? 3,
})
} catch {
// ignore
}
}
async function loadModels() {
try {
const all = (await getModelList()) || []
evalModels.value = all.filter(
(m) => m.purpose === 'evaluation' || (m.model_source === 'api' && !!m.api_url),
)
} catch {
evalModels.value = []
}
}
async function handleSubmit() {
if (!formRef.value) return
await formRef.value.validate(async (valid) => {
if (!valid) return
submitting.value = true
try {
const data: any = {
name: form.name,
type: form.type,
description: form.description,
eval_model: form.type === 'text_similarity' ? null : form.eval_model,
eval_method: form.eval_method,
eval_prompt: form.type === 'text_similarity' ? null : form.eval_prompt,
is_active: form.is_active,
is_default: form.is_default,
create_time: new Date().toISOString(),
}
if (form.type === 'text_similarity') {
data.bleu_n = form.bleu_n
data.output_precision = form.output_precision
}
if (form.type === 'metric') {
data.score_min = form.score_min
data.score_max = form.score_max
data.pass_threshold = form.pass_threshold
}
if (isEdit.value && editId.value) {
await updateDimension(editId.value, data)
ElMessage.success('更新成功')
} else {
await createDimension(data)
ElMessage.success('创建成功')
}
router.push('/model-eval')
} catch {
// ignore
} finally {
submitting.value = false
}
})
}
function handleCancel() {
router.back()
}
onMounted(() => {
loadModels()
loadEditData()
})
</script>
<template>
<PageCard :title="isEdit ? '编辑评测维度' : '添加评测维度'">
<el-form ref="formRef" :model="form" :rules="rules" label-width="130px" style="max-width: 760px">
<el-form-item label="维度名称" prop="name">
<el-input v-model="form.name" placeholder="请输入维度名称" maxlength="50" show-word-limit />
</el-form-item>
<DimensionFormFields v-model="form" :eval-models="evalModels" />
<el-form-item>
<el-button type="primary" :loading="submitting" @click="handleSubmit">
{{ isEdit ? '保存' : '创建' }}
</el-button>
<el-button @click="handleCancel">取消</el-button>
</el-form-item>
</el-form>
</PageCard>
</template>