refactor: 评估系统重构 - 前端 API 及评估组件适配

- API 层方法名和路径统一为 dataset/run 语义
- RAGEvaluationTab 重写为全屏面板、支持列宽拖拽
- EvaluationBenchmarks 重写为数据集管理视图
- 生成模态框增加并发数配置;上传模态框适配新接口
This commit is contained in:
Wenjie Zhang 2026-05-19 14:52:54 +08:00
parent 1efbf86bf0
commit a7f894691e
5 changed files with 1193 additions and 601 deletions

View File

@ -423,141 +423,64 @@ export const typeApi = {
}
}
// =============================================================================
// === RAG评估分组 ===
// =============================================================================
export const evaluationApi = {
/**
* 上传评估基准文件
* @param {string} dbId - 知识库ID
* @param {File} file - JSONL文件
* @param {Object} metadata - 基准元数据
* @returns {Promise} - 上传结果
*/
uploadBenchmark: async (dbId, file, metadata = {}) => {
uploadDataset: async (dbId, file, metadata = {}) => {
const formData = new FormData()
formData.append('file', file)
formData.append('name', metadata.name || '')
formData.append('description', metadata.description || '')
return apiAdminPost(`/api/evaluation/databases/${dbId}/benchmarks/upload`, formData)
return apiAdminPost(`/api/evaluation/databases/${dbId}/datasets/upload`, formData)
},
/**
* 获取评估基准列表
* @param {string} dbId - 知识库ID
* @returns {Promise} - 基准列表
*/
getBenchmarks: async (dbId) => {
return apiAdminGet(`/api/evaluation/databases/${dbId}/benchmarks`)
listDatasets: async (dbId) => {
return apiAdminGet(`/api/evaluation/databases/${dbId}/datasets`)
},
/**
* 获取评估基准详情
* @param {string} benchmarkId - 基准ID
* @returns {Promise} - 基准详情
*/
getBenchmark: async (benchmarkId) => {
return apiAdminGet(`/api/evaluation/benchmarks/${benchmarkId}`)
},
/**
* 获取评估基准详情带db_id
* @param {string} dbId - 知识库ID
* @param {string} benchmarkId - 基准ID
*/
getBenchmarkByDb: async (dbId, benchmarkId, page = 1, pageSize = 50) => {
getDataset: async (dbId, datasetId, page = 1, pageSize = 50) => {
const params = new URLSearchParams({
page: page.toString(),
page_size: pageSize.toString()
})
return apiAdminGet(`/api/evaluation/databases/${dbId}/benchmarks/${benchmarkId}?${params}`)
return apiAdminGet(`/api/evaluation/databases/${dbId}/datasets/${datasetId}?${params}`)
},
/**
* 删除评估基准
* @param {string} benchmarkId - 基准ID
* @returns {Promise} - 删除结果
*/
deleteBenchmark: async (benchmarkId) => {
return apiAdminDelete(`/api/evaluation/benchmarks/${benchmarkId}`)
deleteDataset: async (datasetId) => {
return apiAdminDelete(`/api/evaluation/datasets/${datasetId}`)
},
/**
* 下载评估基准
* @param {string} benchmarkId - 基准ID
* @returns {Promise} - Response对象
*/
downloadBenchmark: async (benchmarkId) => {
return apiAdminGet(`/api/evaluation/benchmarks/${benchmarkId}/download`, {}, 'blob')
downloadDataset: async (datasetId) => {
return apiAdminGet(`/api/evaluation/datasets/${datasetId}/download`, {}, 'blob')
},
/**
* 自动生成评估基准
* @param {string} dbId - 知识库ID
* @param {Object} params - 生成参数
* @param {number} params.count - 生成问题数量
* @param {string} params.llm_model_spec - LLM模型配置
* @returns {Promise} - 生成结果
*/
generateBenchmark: async (dbId, params) => {
return apiAdminPost(`/api/evaluation/databases/${dbId}/benchmarks/generate`, params)
generateDataset: async (dbId, params) => {
return apiAdminPost(`/api/evaluation/databases/${dbId}/datasets/generate`, params)
},
/**
* 运行RAG评估
* @param {string} dbId - 知识库ID
* @param {Object} params - 评估参数
* @param {string} params.benchmark_id - 基准ID
* @param {Object} params.retrieval_config - 检索配置
* @returns {Promise} - 评估任务ID
*/
runEvaluation: async (dbId, params) => {
return apiAdminPost(`/api/evaluation/databases/${dbId}/run`, params)
return apiAdminPost(`/api/evaluation/databases/${dbId}/runs`, params)
},
/**
* 获取评估结果
* @param {string} taskId - 任务ID
* @returns {Promise} - 评估结果
*/
getEvaluationResults: async (taskId) => {
// 已废弃:请改用 getEvaluationResultsByDb
return apiAdminGet(`/api/evaluation/${taskId}/results`)
listRuns: async (dbId) => {
return apiAdminGet(`/api/evaluation/databases/${dbId}/runs`)
},
/**
* 删除评估结果
* @param {string} taskId - 任务ID
* @returns {Promise} - 删除结果
*/
deleteEvaluationResult: async (taskId) => {
// 已废弃:请改用 deleteEvaluationResultByDb
return apiAdminDelete(`/api/evaluation/${taskId}`)
},
// 新接口:带 db_id 的评估结果查询与删除
getEvaluationResultsByDb: async (dbId, taskId, params = {}) => {
getRunResults: async (dbId, runId, params = {}) => {
const queryParams = new URLSearchParams()
if (params.page) queryParams.append('page', params.page)
if (params.pageSize) queryParams.append('page_size', params.pageSize)
if (params.errorOnly !== undefined) queryParams.append('error_only', params.errorOnly)
const url = `/api/evaluation/databases/${dbId}/results/${taskId}${queryParams.toString() ? '?' + queryParams.toString() : ''}`
const url = `/api/evaluation/databases/${dbId}/runs/${runId}${queryParams.toString() ? '?' + queryParams.toString() : ''}`
return apiAdminGet(url)
},
deleteEvaluationResultByDb: async (dbId, taskId) => {
return apiAdminDelete(`/api/evaluation/databases/${dbId}/results/${taskId}`)
},
/**
* 获取知识库的评估历史记录
* @param {string} dbId - 知识库ID
* @returns {Promise} - 评估历史列表
*/
getEvaluationHistory: async (dbId) => {
return apiAdminGet(`/api/evaluation/databases/${dbId}/history`)
deleteRun: async (dbId, runId) => {
return apiAdminDelete(`/api/evaluation/databases/${dbId}/runs/${runId}`)
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -4,6 +4,10 @@
title="自动生成评估基准"
width="600px"
:confirmLoading="generating"
:ok-button-props="{ disabled: generating }"
:cancel-button-props="{ disabled: generating }"
:mask-closable="!generating"
:closable="!generating"
@ok="handleGenerate"
@cancel="handleCancel"
>
@ -54,6 +58,23 @@
/>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item
label="构建并发数"
name="concurrency_count"
:labelCol="{ span: 24 }"
:wrapperCol="{ span: 24 }"
extra="同时生成评估题目的 worker 数,过高可能触发模型服务限流"
>
<a-input-number
v-model:value="formState.concurrency_count"
:min="1"
:max="20"
style="width: 100%"
placeholder="默认 10"
/>
</a-form-item>
</a-col>
</a-row>
</a-form-item>
@ -113,6 +134,7 @@ const formState = reactive({
description: '',
count: 10,
neighbors_count: 1,
concurrency_count: 10,
llm_model_spec: configStore.config?.default_model || ''
})
@ -122,7 +144,8 @@ const rules = {
{ required: true, message: '请输入基准名称', trigger: 'blur' },
{ min: 2, max: 100, message: '基准名称长度应在2-100个字符之间', trigger: 'blur' }
],
count: [{ required: true, message: '请输入生成问题数量', trigger: 'blur' }]
count: [{ required: true, message: '请输入生成问题数量', trigger: 'blur' }],
concurrency_count: [{ required: true, message: '请输入构建并发数', trigger: 'blur' }]
}
// visible
@ -149,6 +172,8 @@ const extraText = computed(() =>
//
const handleGenerate = async () => {
if (generating.value) return
try {
//
await formRef.value.validate()
@ -160,28 +185,31 @@ const handleGenerate = async () => {
description: formState.description,
count: formState.count,
neighbors_count: formState.neighbors_count,
concurrency_count: formState.concurrency_count,
llm_model_spec: formState.llm_model_spec
}
const response = await evaluationApi.generateBenchmark(props.databaseId, params)
const response = await evaluationApi.generateDataset(props.databaseId, params)
if (response.message === 'success') {
message.success('生成任务已提交,请稍后查看结果')
handleCancel()
message.success('生成任务已提交')
visible.value = false
resetForm()
emit('success')
} else {
generating.value = false
message.error(response.message || '生成失败')
}
} catch (error) {
console.error('生成失败:', error)
message.error('生成失败')
} finally {
generating.value = false
message.error('生成失败')
}
}
//
const handleCancel = () => {
if (generating.value) return
visible.value = false
resetForm()
}
@ -194,6 +222,7 @@ const resetForm = () => {
description: '',
count: 10,
neighbors_count: 1,
concurrency_count: 10,
llm_model_spec: configStore.config?.default_model || ''
})
generating.value = false
@ -206,7 +235,7 @@ const handleSelectLLMModel = (modelSpec) => {
// visible
watch(visible, (val) => {
if (val) {
if (val && !generating.value) {
resetForm()
}
})

View File

@ -172,7 +172,7 @@ const handleUpload = async () => {
uploading.value = true
const response = await evaluationApi.uploadBenchmark(props.databaseId, formState.file, {
const response = await evaluationApi.uploadDataset(props.databaseId, formState.file, {
name: formState.name,
description: formState.description
})