知识库rerank设置

This commit is contained in:
2025-11-07 11:21:27 +08:00
parent d9947e273c
commit b98450df96
8 changed files with 360 additions and 34 deletions

View File

@@ -25,14 +25,32 @@
<span class="label">索引方式</span>
<span class="value">{{ getIndexingText(knowledge?.difyIndexingTechnique) }}</span>
</div>
<div class="meta-item" v-if="knowledge?.difyIndexingTechnique == 'high_quality'">
<span class="label">Embedding模型</span>
<span class="value">{{ knowledge?.embeddingModel || '-' }}</span>
</div>
<div class="meta-item">
<span class="label">文档数量</span>
<span class="value">{{ knowledge?.documentCount || 0 }}</span>
</div>
<div class="meta-item" v-if="knowledge?.difyIndexingTechnique == 'high_quality'">
<span class="label">Embedding模型</span>
<span class="value">{{ knowledge?.embeddingModel || '-' }}</span>
</div>
<div class="meta-item">
<span class="label">Rerank状态</span>
<el-tag :type="knowledge?.rerankingEnable ? 'success' : 'info'" size="small">
{{ knowledge?.rerankingEnable ? '已启用' : '未启用' }}
</el-tag>
</div>
<div class="meta-item" v-if="knowledge?.rerankingEnable && knowledge?.rerankModel">
<span class="label">Rerank模型</span>
<span class="value">{{ knowledge.rerankModel }}</span>
</div>
<div class="meta-item">
<span class="label">检索Top K</span>
<span class="value">{{ knowledge?.retrievalTopK || 2 }}</span>
</div>
<div class="meta-item" v-if="(knowledge?.retrievalScoreThreshold || 0) > 0">
<span class="label">检索阈值</span>
<span class="value">{{ knowledge?.retrievalScoreThreshold }}</span>
</div>
<div class="meta-item">
<span class="label">文档数量</span>
<span class="value">{{ knowledge?.documentCount || 0 }}</span>
</div>
<div class="meta-item">
<span class="label">创建时间</span>
<span class="value">{{ formatDate(knowledge?.createTime) }}</span>
@@ -138,6 +156,81 @@
</div>
</el-form-item>
<!-- Rerank模型配置 -->
<el-form-item label="启用Rerank" prop="rerankingEnable">
<el-switch
v-model="formData.rerankingEnable"
:active-value="true"
:inactive-value="false"
active-text="启用"
inactive-text="禁用"
/>
<div class="form-tip">
Rerank可以对检索结果进行重新排序提高精确度
</div>
</el-form-item>
<el-form-item v-if="formData.rerankingEnable" label="Rerank模型" prop="rerankModel">
<el-select
v-model="formData.rerankModel"
placeholder="请选择Rerank模型"
clearable
filterable
:loading="rerankModelsLoading"
@change="handleRerankModelChange"
>
<el-option-group
v-for="provider in rerankModels"
:key="provider.provider"
:label="provider.label || provider.provider"
>
<el-option
v-for="model in provider.models"
:key="model.model"
:label="getModelLabel(model)"
:value="model.model"
:data-provider="model.provider"
>
<span>{{ getModelLabel(model) }}</span>
<span v-if="model.contextSize" style="float: right; color: var(--el-text-color-secondary); font-size: 13px">
上下文: {{ model.contextSize }}
</span>
</el-option>
</el-option-group>
</el-select>
<div class="form-tip">
选择用于重新排序的Rerank模型
</div>
</el-form-item>
<!-- 检索参数配置 -->
<el-form-item label="检索Top K" prop="retrievalTopK">
<el-input-number
v-model="formData.retrievalTopK"
:min="1"
:max="20"
:step="1"
placeholder="返回前K个结果"
/>
<div class="form-tip">
返回前K个最相关的检索结果建议范围2-10
</div>
</el-form-item>
<el-form-item label="检索分数阈值" prop="retrievalScoreThreshold">
<el-input-number
v-model="formData.retrievalScoreThreshold"
:min="0"
:max="1"
:step="0.01"
:precision="2"
placeholder="分数阈值"
/>
<div class="form-tip">
只返回分数高于此阈值的结果0.00-1.000表示不启用
</div>
</el-form-item>
<el-form-item label="Dify数据集ID" prop="difyDatasetId">
<el-input
v-model="formData.difyDatasetId"
@@ -199,7 +292,9 @@ const emit = defineEmits<{
const formRef = ref<FormInstance>();
const submitting = ref(false);
const modelsLoading = ref(false);
const rerankModelsLoading = ref(false);
const embeddingModels = ref<any[]>([]);
const rerankModels = ref<any[]>([]);
// 表单数据
const formData = reactive<Partial<AiKnowledge>>({
@@ -209,6 +304,11 @@ const formData = reactive<Partial<AiKnowledge>>({
difyIndexingTechnique: 'high_quality',
embeddingModel: '',
embeddingModelProvider: '',
rerankModel: '',
rerankModelProvider: '',
rerankingEnable: false,
retrievalTopK: 2,
retrievalScoreThreshold: 0.0,
difyDatasetId: '',
status: 1
});
@@ -221,6 +321,18 @@ const rules: FormRules = {
],
difyIndexingTechnique: [
{ required: true, message: '请选择索引方式', trigger: 'change' }
],
rerankModel: [
{
validator: (rule: any, value: any, callback: any) => {
if (formData.rerankingEnable && !value) {
callback(new Error('启用Rerank后必须选择Rerank模型'));
} else {
callback();
}
},
trigger: 'change'
}
]
};
@@ -235,12 +347,25 @@ watch(() => props.knowledge, (newVal) => {
difyIndexingTechnique: newVal.difyIndexingTechnique || 'high_quality',
embeddingModel: newVal.embeddingModel,
embeddingModelProvider: newVal.embeddingModelProvider,
rerankModel: newVal.rerankModel,
rerankModelProvider: newVal.rerankModelProvider,
rerankingEnable: newVal.rerankingEnable ?? false,
retrievalTopK: newVal.retrievalTopK ?? 2,
retrievalScoreThreshold: newVal.retrievalScoreThreshold ?? 0.0,
difyDatasetId: newVal.difyDatasetId,
status: newVal.status ?? 1
});
}
}, { immediate: true });
// 监听 rerankingEnable 变化,触发表单验证
watch(() => formData.rerankingEnable, () => {
if (formRef.value) {
// 触发 rerankModel 字段的验证
formRef.value.validateField('rerankModel', () => {});
}
});
// 处理头像更新
function handleAvatarUpdate(val: string) {
formData.avatar = val;
@@ -295,12 +420,43 @@ async function loadEmbeddingModels() {
}
}
// 加载Rerank模型列表
async function loadRerankModels() {
try {
rerankModelsLoading.value = true;
const result = await knowledgeApi.getAvailableRerankModels();
if (result.success && result.data) {
// 按提供商分组
const providers = result.data.providers || [];
rerankModels.value = providers.map((provider: any) => ({
provider: provider.provider,
label: provider.label?.zh_Hans || provider.label?.en_US || provider.provider,
models: (provider.models || []).map((model: any) => ({
model: model.model,
provider: model.provider || provider.provider,
label: model.label?.zh_Hans || model.label?.en_US || model.model,
contextSize: model.model_properties?.context_size,
status: model.status
}))
}));
} else {
ElMessage.warning('获取Rerank模型列表失败');
rerankModels.value = [];
}
} catch (error: any) {
console.error('加载Rerank模型列表失败:', error);
rerankModels.value = [];
} finally {
rerankModelsLoading.value = false;
}
}
// 获取模型显示标签
function getModelLabel(model: any): string {
return model.label || model.model;
}
// 处理模型变化
// 处理Embedding模型变化
function handleModelChange(modelName: string) {
if (!modelName) {
formData.embeddingModelProvider = '';
@@ -312,7 +468,25 @@ function handleModelChange(modelName: string) {
const foundModel = providerGroup.models.find((m: any) => m.model === modelName);
if (foundModel) {
formData.embeddingModelProvider = foundModel.provider;
console.log('选择模型:', modelName, '提供商:', foundModel.provider);
console.log('选择Embedding模型:', modelName, '提供商:', foundModel.provider);
break;
}
}
}
// 处理Rerank模型变化
function handleRerankModelChange(modelName: string) {
if (!modelName) {
formData.rerankModelProvider = '';
return;
}
// 查找选中模型的提供商
for (const providerGroup of rerankModels.value) {
const foundModel = providerGroup.models.find((m: any) => m.model === modelName);
if (foundModel) {
formData.rerankModelProvider = foundModel.provider;
console.log('选择Rerank模型:', modelName, '提供商:', foundModel.provider);
break;
}
}
@@ -320,6 +494,7 @@ function handleModelChange(modelName: string) {
// 组件挂载时加载模型列表
loadEmbeddingModels();
loadRerankModels();
// 提交表单
async function handleSubmit() {