feat(knowledge): 重构知识库命中测试功能

- 更新命中测试弹窗样式和布局
-增加新的检索模式选项,包括语义检索和混合检索- 添加权重设置和重排序模型选择功能
- 优化参数配置界面,提高用户体验
-调整知识库列表和搜索功能布局
- 移除不必要的组件引用
This commit is contained in:
Huangzhe
2025-04-28 18:05:45 +08:00
parent 3c8d0e9e6a
commit 464a6b1735
2 changed files with 185 additions and 197 deletions

View File

@@ -5,12 +5,16 @@ export default {
name: 'hitTest', name: 'hitTest',
data() { data() {
return { return {
testForm: {
isRanking: true
},
datasetId: void 0, datasetId: void 0,
paramsConfig: { paramsConfig: {
visible: false, visible: false,
searchMode: 'vector', // 默认选择向量检索 searchMode: 'hybrid_search', // 默认选择向量检索
similarity: 0.6, // 默认相似度 score_threshold: 0.6, // 默认相似度
topK: 5 // 默认引用分段数 top_k: 5, // 默认引用分段数,
reranking_model: ''
}, },
inputMessage: '', inputMessage: '',
loading: false, loading: false,
@@ -121,92 +125,160 @@ export default {
<div class="footer"> <div class="footer">
<!-- 参数内容 --> <!-- 参数内容 -->
<el-popover placement="top" width="480" v-model="paramsConfig.visible"> <el-popover placement="top" width="480" v-model="paramsConfig.visible">
<div class="search-params-container"> <el-popover
<h3>检索模式</h3> trigger="manual"
placement="right"
v-model="paramsConfig.visible"
width="450"
>
<div slot="reference">
<div class="search-params-container">
<h3>检索模式</h3>
<el-radio-group <el-radio-group
v-model="paramsConfig.searchMode" v-model="paramsConfig.searchMode"
class="search-mode-options" class="search-mode-options"
> >
<div <div
class="search-mode-option" class="search-mode-option"
:class="{ active: paramsConfig.searchMode === 'vector' }" :class="{
> active: paramsConfig.searchMode === 'semantic_search'
<el-radio v-model="paramsConfig.searchMode" label="vector" }"
>向量检索 >
</el-radio> <el-radio
<p class="option-desc"> v-model="paramsConfig.searchMode"
向量检索是一种基于向量相似度的检索方式适用于知识库中的大数据量场景 label="semantic_search"
</p> key="semantic_search"
</div> >
向量检索
<p class="option-desc">
通过生成查询嵌入并查询与其向量表示最相似的文本分段
</p>
</el-radio>
</div>
<div <div
class="search-mode-option" class="search-mode-option"
:class="{ active: paramsConfig.searchMode === 'fulltext' }" :class="{
> active: paramsConfig.searchMode === 'full_text_search'
<el-radio v-model="paramsConfig.searchMode" label="fulltext" }"
>全文检索 >
</el-radio> <el-radio
<p class="option-desc"> v-model="paramsConfig.searchMode"
全文检索是一种基于文本相似度的检索方式适用于知识库中的小数据量场景 label="full_text_search"
</p> key="full_text_search"
</div> >
全文检索
<p class="option-desc">
索引文档中的所有词汇从而允许用户查询任意词汇并返回包含这些词汇的文本片段
</p>
</el-radio>
</div>
<div <div
class="search-mode-option" class="search-mode-option"
:class="{ active: paramsConfig.searchMode === 'hybrid' }" :class="{
> active: paramsConfig.searchMode === 'hybrid_search'
<el-radio v-model="paramsConfig.searchMode" label="hybrid" }"
>混合检索 >
</el-radio> <el-radio
<p class="option-desc"> v-model="paramsConfig.searchMode"
混合检索是一种基于向量和文本相似度的检索方式适用于知识库中的中等数据量场景 label="hybrid_search"
</p> key="hybrid_search"
</div> >
</el-radio-group> 混合检索
<p class="option-desc">
同时执行全文检索和向量检索并应用重排序步骤从两类查询结果中选择匹配用户问题的最佳结果用户可以选择设置权重或配置重新排序模型
</p>
</el-radio>
</div>
</el-radio-group>
<div class="params-settings"> <div class="action-buttons">
<div class="param-item"> <el-button size="small" @click="paramsConfig.visible = false"
<span class="param-label">相似度高于</span> >取消
<el-input-number </el-button>
v-model="paramsConfig.similarity" <el-button
:precision="3" type="primary"
:step="0.001" size="small"
:min="0" @click="paramsConfig.visible = false"
size="small" >确定
controls-position="right" </el-button>
></el-input-number> </div>
</div>
<div class="param-item">
<span class="param-label">引用分段数 TOP</span>
<el-input-number
v-model="paramsConfig.topK"
:min="1"
:max="20"
size="small"
controls-position="right"
></el-input-number>
</div> </div>
</div> </div>
<div class="action-buttons"> <!-- 具体的参数内容 -->
<el-button size="small" @click="paramsConfig.visible = false" <section>
>取消 <div class="grid grid-cols-2">
</el-button> <div class="col-span-1 flex align-items-c">
<el-button <span class="param-label mr5">Score 阈值</span>
type="primary" <el-input-number
size="small" v-model="paramsConfig.score_threshold"
@click="paramsConfig.visible = false" :precision="3"
>确定 :step="0.001"
</el-button> :min="0"
</div> size="small"
</div> controls-position="right"
<el-button />
icon="el-icon-setting" </div>
size="small"
slot="reference" <div class="col-span-1 flex align-items-c">
v-if="false" <span class="param-label mr5">TOP K</span>
<el-input-number
v-model="paramsConfig.top_k"
:min="1"
:max="20"
size="small"
controls-position="right"
/>
</div>
</div>
<!-- 参数设置 -->
<section
class="mt10 flex fs12"
v-if="paramsConfig.searchMode === 'hybrid_search'"
>
<el-card shadow="never" class="mr5">
<div>权重设置</div>
<div>
通过调整分配的权重重新排序策略确定是优先进行语义匹配还是关键字匹配
</div>
</el-card>
<el-card shadow="never">
<div>Rerank 模型</div>
<div>
重排序模型将根据候选文档列表与用户问题语义匹配度进行重新排序从而改进语义排序的结果
</div>
</el-card>
</section>
<section class="mt10">
<el-form>
<el-form-item>
<template #label>
<el-switch v-model="testForm.isRanking"></el-switch>
Rerank 模型
</template>
<el-select
v-model="paramsConfig.rerank_model"
size="medium"
placeholder="选择一个模型"
>
<el-option
v-for="item in rerankModelOptions"
:key="item.value"
:label="item.label"
:value="item.value"
>
</el-option>
</el-select>
</el-form-item>
</el-form>
</section>
</section>
</el-popover>
<el-button icon="el-icon-setting" size="small" slot="reference"
>参数设置 >参数设置
</el-button> </el-button>
</el-popover> </el-popover>
@@ -433,6 +505,7 @@ export default {
} }
.search-mode-options { .search-mode-options {
width: 100%;
margin-bottom: 20px; margin-bottom: 20px;
.search-mode-option { .search-mode-option {
@@ -449,28 +522,13 @@ export default {
.option-desc { .option-desc {
margin: 5px 0 0 24px; margin: 5px 0 0 24px;
font-size: 12px; font-size: 12px;
text-wrap: wrap;
color: #909399; color: #909399;
line-height: 1.4; line-height: 1.4;
} }
} }
} }
.params-settings {
display: flex;
justify-content: space-between;
margin-bottom: 20px;
.param-item {
display: flex;
align-items: center;
.param-label {
margin-right: 10px;
white-space: nowrap;
}
}
}
.action-buttons { .action-buttons {
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-end;
@@ -480,4 +538,8 @@ export default {
} }
} }
} }
.ts {
transition: all 0.5;
}
</style> </style>

View File

@@ -7,36 +7,16 @@
<div class="mr20 header" v-if="!editKnowledge"> <div class="mr20 header" v-if="!editKnowledge">
{{ knowledgeName }} {{ knowledgeName }}
</div> </div>
<el-input <el-input class="mr20 w400" size="small" v-else v-model="copyKnowledgeName">{{ knowledgeName }}</el-input>
class="mr20 w400" <el-icon class="fs16 el-icon-edit-outline cursor-pointer" @click.native="editKnowledgeName"
size="small" v-if="!editKnowledge" />
v-else
v-model="copyKnowledgeName"
>{{ knowledgeName }}</el-input
>
<el-icon
class="fs16 el-icon-edit-outline cursor-pointer"
@click.native="editKnowledgeName"
v-if="!editKnowledge"
/>
<div v-else> <div v-else>
<el-button <el-button type="primary" size="medium" class="render-button" @click="saveKnowledgeName">保存</el-button>
type="primary" <el-button size="medium" class="render-button" @click="cancelKnowledgeName">取消</el-button>
size="medium"
class="render-button"
@click="saveKnowledgeName"
>保存</el-button
>
<el-button
size="medium"
class="render-button"
@click="cancelKnowledgeName"
>取消</el-button
>
</div> </div>
<span class="segment-content">{{ <span class="segment-content">{{
segmentedMode | filterSegmentedMode segmentedMode | filterSegmentedMode
}}</span> }}</span>
</div> </div>
<p class="mt10 fs14" style="line-height: 20px"> <p class="mt10 fs14" style="line-height: 20px">
描述{{ knowledgeDesc }} 描述{{ knowledgeDesc }}
@@ -55,8 +35,7 @@
<el-button type="primary" icon="el-icon-s-promotion" size="medium" class="line-button" <el-button type="primary" icon="el-icon-s-promotion" size="medium" class="line-button"
@click="handleHitTestClick">命中测试 @click="handleHitTestClick">命中测试
</el-button> </el-button>
<el-button <el-button type="primary" icon="el-icon-edit-outline" size="medium" class="line-button"
type="primary" icon="el-icon-edit-outline" size="medium" class="line-button"
@click="handleMetaData">元数据 @click="handleMetaData">元数据
</el-button> </el-button>
</div> </div>
@@ -64,52 +43,29 @@
<div class="mt20 card-body"> <div class="mt20 card-body">
<el-empty v-if="!hasList"> <el-empty v-if="!hasList">
<div class="mt20"> <div class="mt20">
<el-button <el-button type="primary" size="medium" class="fs14" @click="jumpAddKnowledge">立即添加</el-button>
type="primary"
size="medium"
class="fs14"
@click="jumpAddKnowledge"
>立即添加</el-button
>
</div> </div>
</el-empty> </el-empty>
<div class="table-container" v-else> <div class="table-container" v-else>
<div class="flex align-items-c justify-content-b"> <div class="flex align-items-c justify-content-b">
<el-form <el-form :model="form" label-width="100px" label-position="top" inline>
:model="form"
label-width="100px"
label-position="top"
inline
>
<el-form-item label="知识文件名称" prop="fileName"> <el-form-item label="知识文件名称" prop="fileName">
<el-input <el-input v-model="form.knowledgeNameLike" size="medium" placeholder="请输入知识文件名称"
v-model="form.knowledgeNameLike" @keydown.enter.native="search"></el-input>
size="medium"
placeholder="请输入知识文件名称"
@keydown.enter.native="search"
></el-input>
</el-form-item> </el-form-item>
<el-form-item label="知识文件来源" prop="documentSource"> <el-form-item label="知识文件来源" prop="documentSource">
<el-select v-model="form.documentSource" size="medium"> <el-select v-model="form.documentSource" size="medium">
<el-option label="全部" value=""></el-option> <el-option label="全部" value=""></el-option>
<el-option <el-option v-for="item in documentSourceOptions" :label="item.label" :value="item.value"
v-for="item in documentSourceOptions" :key="item.value"></el-option>
:label="item.label"
:value="item.value"
:key="item.value"
></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="上传用户" prop="createdUserLike"> <el-form-item label="上传用户" prop="createdUserLike">
<el-select v-model="form.createdUserLike" size="medium"> <el-select v-model="form.createdUserLike" size="medium">
<el-option label="全部" value=""></el-option> <el-option label="全部" value=""></el-option>
<el-option <el-option v-for="item in createdUserOptions" :label="item.label" :value="item.value"
v-for="item in createdUserOptions" :key="item.value"></el-option>
:label="item.label"
:value="item.value"
:key="item.value"
></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<!-- <el-form-item label="关键字">--> <!-- <el-form-item label="关键字">-->
@@ -121,57 +77,27 @@
<!-- ></el-input>--> <!-- ></el-input>-->
<!-- </el-form-item>--> <!-- </el-form-item>-->
<el-form-item label="上传时间" prop="times"> <el-form-item label="上传时间" prop="times">
<el-date-picker <el-date-picker size="medium" style="width:100%" v-model="form.times" value-format="yyyy-MM-dd"
size="medium" start-placeholder="开始时间" end-placeholder="结束时间" type="daterange"></el-date-picker>
style="width:100%"
v-model="form.times"
value-format="yyyy-MM-dd"
start-placeholder="开始时间"
end-placeholder="结束时间"
type="daterange"
></el-date-picker>
</el-form-item> </el-form-item>
</el-form> </el-form>
<div class="mt15 flex align-items-c justify-content-b"> <div class="mt15 flex align-items-c justify-content-b">
<el-button size="medium" type="primary" @click="search" <el-button size="medium" type="primary" @click="search">查询</el-button>
>查询</el-button
>
<el-button size="medium" @click="reset">重置</el-button> <el-button size="medium" @click="reset">重置</el-button>
</div> </div>
</div> </div>
<r-table <r-table :columns="columns" :data="list" :deletion="false" :total="total" @page-change="pageChange"
:columns="columns" @current-change="currentChange" :current-page="page" :page-size="pageSize"></r-table>
:data="list"
:deletion="false"
:total="total"
@page-change="pageChange"
@current-change="currentChange"
:current-page="page"
:page-size="pageSize"
></r-table>
</div> </div>
</div> </div>
<document-drawer <document-drawer :visible.sync="drawer" :descriptions="descriptions" :document-detail="documentDetail"
:visible.sync="drawer" :active-segment="activeSegment" @update:visible="val => (drawer = val)" />
:descriptions="descriptions"
:document-detail="documentDetail"
:active-segment="activeSegment"
@update:visible="val => (drawer = val)"
/>
<knowledgeForm <knowledgeForm :visible.sync="drawerForm" :datasetId="$route.query.datasetId" @update:visible="getKnowledgeDetail">
:visible.sync="drawerForm"
:datasetId="$route.query.datasetId"
@update:visible="getKnowledgeDetail"
>
</knowledgeForm> </knowledgeForm>
<!-- 命中测试抽屉弹窗 --> <!-- 命中测试抽屉弹窗 -->
<el-drawer <el-drawer :title="hitTestConfig.title" :visible.sync="hitTestConfig.visible" size="80%">
:title="hitTestConfig.title"
:visible.sync="hitTestConfig.visible"
size="60%"
>
<hitTest></hitTest> <hitTest></hitTest>
</el-drawer> </el-drawer>
@@ -479,7 +405,7 @@ export default {
return item ? item.label : '否' return item ? item.label : '否'
} }
}, },
created() {}, created() { },
async mounted() { async mounted() {
this.getKnowledgeDetail() this.getKnowledgeDetail()
// 获取知识库文件列表 // 获取知识库文件列表