feat(evaluation): 重构评估配置处理逻辑
- 将前端传递的 retrieval_config 改为 model_config 并合并到检索配置 - 从知识库元数据中获取检索配置作为基础配置 - 在评估结果中显示使用的检索配置 - 优化配置保存流程,先保存到服务器再存本地 - 统一知识库查询参数存储结构
This commit is contained in:
parent
83e0caae7d
commit
e5a06405ba
@ -149,7 +149,7 @@ async def run_evaluation(db_id: str, params: dict = Body(...), current_user: Use
|
|||||||
task_id = await service.run_evaluation(
|
task_id = await service.run_evaluation(
|
||||||
db_id=db_id,
|
db_id=db_id,
|
||||||
benchmark_id=params.get("benchmark_id"),
|
benchmark_id=params.get("benchmark_id"),
|
||||||
retrieval_config=params.get("retrieval_config", {}),
|
model_config=params.get("model_config", {}),
|
||||||
created_by=current_user.user_id,
|
created_by=current_user.user_id,
|
||||||
)
|
)
|
||||||
return {"message": "success", "data": {"task_id": task_id}}
|
return {"message": "success", "data": {"task_id": task_id}}
|
||||||
|
|||||||
@ -702,13 +702,20 @@ async def update_knowledge_base_query_params(
|
|||||||
if db_id not in knowledge_base.global_databases_meta:
|
if db_id not in knowledge_base.global_databases_meta:
|
||||||
knowledge_base.global_databases_meta[db_id] = {}
|
knowledge_base.global_databases_meta[db_id] = {}
|
||||||
|
|
||||||
# 保存查询参数到元数据
|
# 初始化 query_params 结构
|
||||||
if "query_params" not in knowledge_base.global_databases_meta[db_id]:
|
if "query_params" not in knowledge_base.global_databases_meta[db_id]:
|
||||||
knowledge_base.global_databases_meta[db_id]["query_params"] = {}
|
knowledge_base.global_databases_meta[db_id]["query_params"] = {}
|
||||||
|
|
||||||
knowledge_base.global_databases_meta[db_id]["query_params"].update(params)
|
# 将参数保存到 options 下,与评估服务期望的结构一致
|
||||||
|
if "options" not in knowledge_base.global_databases_meta[db_id]["query_params"]:
|
||||||
|
knowledge_base.global_databases_meta[db_id]["query_params"]["options"] = {}
|
||||||
|
|
||||||
|
# 更新 options
|
||||||
|
knowledge_base.global_databases_meta[db_id]["query_params"]["options"].update(params)
|
||||||
knowledge_base._save_global_metadata()
|
knowledge_base._save_global_metadata()
|
||||||
|
|
||||||
|
logger.info(f"更新知识库 {db_id} 查询参数: {params}")
|
||||||
|
|
||||||
return {"message": "success", "data": params}
|
return {"message": "success", "data": params}
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@ -926,6 +933,22 @@ async def get_knowledge_base_query_params(db_id: str, current_user: User = Depen
|
|||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# 获取用户保存的配置
|
||||||
|
saved_options = {}
|
||||||
|
try:
|
||||||
|
if db_id in knowledge_base.global_databases_meta:
|
||||||
|
query_params_meta = knowledge_base.global_databases_meta[db_id].get("query_params", {})
|
||||||
|
saved_options = query_params_meta.get("options", {})
|
||||||
|
except Exception as saved_error:
|
||||||
|
logger.warning(f"获取保存的配置失败: {saved_error}")
|
||||||
|
|
||||||
|
# 将保存的值合并到默认配置中
|
||||||
|
if saved_options:
|
||||||
|
for option in params.get("options", []):
|
||||||
|
key = option.get("key")
|
||||||
|
if key in saved_options:
|
||||||
|
option["default"] = saved_options[key]
|
||||||
|
|
||||||
return {"params": params, "message": "success"}
|
return {"params": params, "message": "success"}
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
@ -241,7 +241,7 @@ class EvaluationService:
|
|||||||
raise NotImplementedError("自动生成基准功能暂时不可用,请手动上传基准文件。")
|
raise NotImplementedError("自动生成基准功能暂时不可用,请手动上传基准文件。")
|
||||||
|
|
||||||
async def run_evaluation(
|
async def run_evaluation(
|
||||||
self, db_id: str, benchmark_id: str, retrieval_config: dict[str, Any], created_by: str
|
self, db_id: str, benchmark_id: str, model_config: dict[str, Any] = None, created_by: str = "system"
|
||||||
) -> str:
|
) -> str:
|
||||||
"""运行RAG评估"""
|
"""运行RAG评估"""
|
||||||
try:
|
try:
|
||||||
@ -253,6 +253,21 @@ class EvaluationService:
|
|||||||
with open(meta_file_path, encoding="utf-8") as f:
|
with open(meta_file_path, encoding="utf-8") as f:
|
||||||
benchmark_meta = json.load(f)
|
benchmark_meta = json.load(f)
|
||||||
|
|
||||||
|
# 从知识库元数据中获取检索配置
|
||||||
|
retrieval_config = {}
|
||||||
|
try:
|
||||||
|
kb_meta = knowledge_base.global_databases_meta.get(db_id, {})
|
||||||
|
query_params = kb_meta.get("query_params", {})
|
||||||
|
retrieval_config = query_params.get("options", {})
|
||||||
|
logger.info(f"从知识库 {db_id} 加载检索配置: {list(retrieval_config.keys())}")
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"获取知识库检索配置失败: {e}")
|
||||||
|
# 使用空配置作为默认值
|
||||||
|
|
||||||
|
# 合并前端传递的模型配置
|
||||||
|
if model_config:
|
||||||
|
retrieval_config.update(model_config)
|
||||||
|
|
||||||
# 初始化结果文件 (Status: running)
|
# 初始化结果文件 (Status: running)
|
||||||
result_dir = self._get_result_dir(db_id)
|
result_dir = self._get_result_dir(db_id)
|
||||||
result_file_path = os.path.join(result_dir, f"{task_id}.json")
|
result_file_path = os.path.join(result_dir, f"{task_id}.json")
|
||||||
@ -581,6 +596,8 @@ class EvaluationService:
|
|||||||
"total_questions": data.get("total_questions"),
|
"total_questions": data.get("total_questions"),
|
||||||
"completed_questions": data.get("completed_questions"),
|
"completed_questions": data.get("completed_questions"),
|
||||||
"overall_score": data.get("overall_score"),
|
"overall_score": data.get("overall_score"),
|
||||||
|
# 包含检索配置
|
||||||
|
"retrieval_config": data.get("retrieval_config", {}),
|
||||||
# 也可以带上部分 metrics 摘要
|
# 也可以带上部分 metrics 摘要
|
||||||
"metrics": data.get("metrics"),
|
"metrics": data.get("metrics"),
|
||||||
}
|
}
|
||||||
|
|||||||
@ -390,7 +390,7 @@ export const evaluationApi = {
|
|||||||
return apiAdminPost(`/api/evaluation/databases/${dbId}/run`, params)
|
return apiAdminPost(`/api/evaluation/databases/${dbId}/run`, params)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取评估结果
|
* 获取评估结果
|
||||||
* @param {string} taskId - 任务ID
|
* @param {string} taskId - 任务ID
|
||||||
|
|||||||
@ -183,6 +183,13 @@
|
|||||||
</a-descriptions-item>
|
</a-descriptions-item>
|
||||||
</a-descriptions>
|
</a-descriptions>
|
||||||
|
|
||||||
|
<!-- 检索配置 -->
|
||||||
|
<a-card size="small" title="检索配置" style="margin-bottom: 20px" v-if="selectedResult.retrieval_config">
|
||||||
|
<div class="json-viewer-container">
|
||||||
|
<pre class="json-viewer">{{ JSON.stringify(selectedResult.retrieval_config, null, 2) }}</pre>
|
||||||
|
</div>
|
||||||
|
</a-card>
|
||||||
|
|
||||||
<!-- 整体评估报告 -->
|
<!-- 整体评估报告 -->
|
||||||
<div class="evaluation-report">
|
<div class="evaluation-report">
|
||||||
<h4 style="margin-bottom: 16px">整体评估报告</h4>
|
<h4 style="margin-bottom: 16px">整体评估报告</h4>
|
||||||
@ -417,22 +424,10 @@ const startEvaluation = async () => {
|
|||||||
|
|
||||||
startingEvaluation.value = true;
|
startingEvaluation.value = true;
|
||||||
|
|
||||||
// 获取检索配置
|
// 只传递模型配置,检索配置由服务器从知识库读取
|
||||||
let retrievalConfig = {};
|
|
||||||
try {
|
|
||||||
const savedConfig = localStorage.getItem(`search-config-${props.databaseId}`);
|
|
||||||
if (savedConfig) {
|
|
||||||
retrievalConfig = JSON.parse(savedConfig);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('获取检索配置失败:', error);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 合并配置,优先使用评估页面的模型配置
|
|
||||||
const params = {
|
const params = {
|
||||||
benchmark_id: selectedBenchmark.value.benchmark_id,
|
benchmark_id: selectedBenchmark.value.benchmark_id,
|
||||||
retrieval_config: {
|
model_config: {
|
||||||
...retrievalConfig, // 包含所有检索参数如 top_k, similarity_threshold 等
|
|
||||||
answer_llm: configForm.answer_llm, // 传递答案生成模型
|
answer_llm: configForm.answer_llm, // 传递答案生成模型
|
||||||
judge_llm: configForm.judge_llm // 传递评判模型
|
judge_llm: configForm.judge_llm // 传递评判模型
|
||||||
}
|
}
|
||||||
@ -544,9 +539,15 @@ const viewResults = async (taskId) => {
|
|||||||
completed_at: resultData.completed_at,
|
completed_at: resultData.completed_at,
|
||||||
total_questions: resultData.total_questions || 0,
|
total_questions: resultData.total_questions || 0,
|
||||||
completed_questions: resultData.completed_questions || 0,
|
completed_questions: resultData.completed_questions || 0,
|
||||||
overall_score: resultData.overall_score
|
overall_score: resultData.overall_score,
|
||||||
|
retrieval_config: resultData.retrieval_config
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 如果是从历史记录获取的,确保也有 retrieval_config
|
||||||
|
if (selectedResult.value && !selectedResult.value.retrieval_config) {
|
||||||
|
selectedResult.value.retrieval_config = resultData.retrieval_config;
|
||||||
|
}
|
||||||
|
|
||||||
// 计算总耗时
|
// 计算总耗时
|
||||||
if (resultData.started_at && resultData.completed_at) {
|
if (resultData.started_at && resultData.completed_at) {
|
||||||
const startTime = new Date(resultData.started_at);
|
const startTime = new Date(resultData.started_at);
|
||||||
@ -705,6 +706,7 @@ const formatDuration = (seconds) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// 组件挂载时加载数据
|
// 组件挂载时加载数据
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
loadBenchmarks();
|
loadBenchmarks();
|
||||||
@ -1137,4 +1139,25 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// JSON 查看器样式
|
||||||
|
.json-viewer-container {
|
||||||
|
max-height: 400px;
|
||||||
|
overflow: auto;
|
||||||
|
|
||||||
|
.json-viewer {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
font-family: 'SF Mono', 'Monaco', 'Consolas', 'Menlo', monospace;
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 1.5;
|
||||||
|
color: var(--gray-800);
|
||||||
|
white-space: pre-wrap;
|
||||||
|
word-wrap: break-word;
|
||||||
|
background: var(--gray-50);
|
||||||
|
border: 1px solid var(--gray-200);
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
@ -197,21 +197,19 @@ const saveConfig = async () => {
|
|||||||
// 确保 include_distances 始终为 true
|
// 确保 include_distances 始终为 true
|
||||||
meta['include_distances'] = true;
|
meta['include_distances'] = true;
|
||||||
|
|
||||||
// 保存到 localStorage(兼容性)
|
// 先保存到知识库元数据
|
||||||
localStorage.setItem(`search-config-${props.databaseId}`, JSON.stringify(meta));
|
|
||||||
|
|
||||||
// 保存到知识库元数据
|
|
||||||
try {
|
try {
|
||||||
const { knowledgeApi } = await import('@/apis/knowledge_api');
|
const response = await queryApi.updateKnowledgeBaseQueryParams(props.databaseId, meta);
|
||||||
const response = await knowledgeApi.updateKnowledgeBaseQueryParams(props.databaseId, meta);
|
|
||||||
if (response.message === 'success') {
|
if (response.message === 'success') {
|
||||||
message.success('配置已保存到知识库');
|
// 服务器保存成功后,再保存到 localStorage(兼容性)
|
||||||
|
localStorage.setItem(`search-config-${props.databaseId}`, JSON.stringify(meta));
|
||||||
|
message.success('配置已保存');
|
||||||
} else {
|
} else {
|
||||||
message.warning('配置已保存到本地,但同步到知识库失败');
|
throw new Error(response.message || '保存失败');
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('保存配置到知识库失败:', error);
|
console.error('保存配置到知识库失败:', error);
|
||||||
message.warning('配置已保存到本地,但同步到知识库失败');
|
message.error('保存配置失败:' + error.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新 store 中的配置
|
// 更新 store 中的配置
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user