feat(evaluation): 重构评估配置处理逻辑

- 将前端传递的 retrieval_config 改为 model_config 并合并到检索配置
- 从知识库元数据中获取检索配置作为基础配置
- 在评估结果中显示使用的检索配置
- 优化配置保存流程,先保存到服务器再存本地
- 统一知识库查询参数存储结构
This commit is contained in:
Wenjie Zhang 2025-12-09 21:11:51 +08:00
parent 83e0caae7d
commit e5a06405ba
6 changed files with 90 additions and 29 deletions

View File

@ -149,7 +149,7 @@ async def run_evaluation(db_id: str, params: dict = Body(...), current_user: Use
task_id = await service.run_evaluation(
db_id=db_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,
)
return {"message": "success", "data": {"task_id": task_id}}

View File

@ -702,13 +702,20 @@ async def update_knowledge_base_query_params(
if db_id not in knowledge_base.global_databases_meta:
knowledge_base.global_databases_meta[db_id] = {}
# 保存查询参数到元数据
# 初始化 query_params 结构
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"].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()
logger.info(f"更新知识库 {db_id} 查询参数: {params}")
return {"message": "success", "data": params}
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"}
except Exception as e:

View File

@ -241,7 +241,7 @@ class EvaluationService:
raise NotImplementedError("自动生成基准功能暂时不可用,请手动上传基准文件。")
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:
"""运行RAG评估"""
try:
@ -253,6 +253,21 @@ class EvaluationService:
with open(meta_file_path, encoding="utf-8") as 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)
result_dir = self._get_result_dir(db_id)
result_file_path = os.path.join(result_dir, f"{task_id}.json")
@ -581,6 +596,8 @@ class EvaluationService:
"total_questions": data.get("total_questions"),
"completed_questions": data.get("completed_questions"),
"overall_score": data.get("overall_score"),
# 包含检索配置
"retrieval_config": data.get("retrieval_config", {}),
# 也可以带上部分 metrics 摘要
"metrics": data.get("metrics"),
}

View File

@ -390,7 +390,7 @@ export const evaluationApi = {
return apiAdminPost(`/api/evaluation/databases/${dbId}/run`, params)
},
/**
* 获取评估结果
* @param {string} taskId - 任务ID

View File

@ -183,6 +183,13 @@
</a-descriptions-item>
</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">
<h4 style="margin-bottom: 16px">整体评估报告</h4>
@ -417,22 +424,10 @@ const startEvaluation = async () => {
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 = {
benchmark_id: selectedBenchmark.value.benchmark_id,
retrieval_config: {
...retrievalConfig, // top_k, similarity_threshold
model_config: {
answer_llm: configForm.answer_llm, //
judge_llm: configForm.judge_llm //
}
@ -544,9 +539,15 @@ const viewResults = async (taskId) => {
completed_at: resultData.completed_at,
total_questions: resultData.total_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) {
const startTime = new Date(resultData.started_at);
@ -705,6 +706,7 @@ const formatDuration = (seconds) => {
}
};
//
onMounted(() => {
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>

View File

@ -197,21 +197,19 @@ const saveConfig = async () => {
// include_distances true
meta['include_distances'] = true;
// localStorage
localStorage.setItem(`search-config-${props.databaseId}`, JSON.stringify(meta));
//
//
try {
const { knowledgeApi } = await import('@/apis/knowledge_api');
const response = await knowledgeApi.updateKnowledgeBaseQueryParams(props.databaseId, meta);
const response = await queryApi.updateKnowledgeBaseQueryParams(props.databaseId, meta);
if (response.message === 'success') {
message.success('配置已保存到知识库');
// localStorage
localStorage.setItem(`search-config-${props.databaseId}`, JSON.stringify(meta));
message.success('配置已保存');
} else {
message.warning('配置已保存到本地,但同步到知识库失败');
throw new Error(response.message || '保存失败');
}
} catch (error) {
console.error('保存配置到知识库失败:', error);
message.warning('配置已保存到本地,但同步到知识库失败');
message.error('保存配置失败:' + error.message);
}
// store