feat(knowledge): 添加检索设置功能

- 新增 SearchSetting 组件用于检索设置
- 在知识库详情页面添加检索设置按钮和弹窗
- 实现了向量检索、全文检索和混合检索的设置功能
- 添加了重排序模型、Top K 和 Score
This commit is contained in:
du.meimei
2025-05-06 16:44:54 +08:00
parent 0b3ad1d37c
commit ebc98af45d
8 changed files with 334 additions and 30 deletions

View File

@@ -39,6 +39,7 @@ export function hitTest(data) {
return request({
url: getUrl('/datasetsEx/hit/test'),
method: 'post',
noLoading: true,
data
})
}

View File

@@ -6,7 +6,7 @@ import getUrl from '@/assets/js/utils/get-url'
*/
export function getRerankModels() {
return request({
url: getUrl("/third/models/rerank"),
method: 'get',
url: getUrl('/third/models/rerank'),
method: 'get'
})
}

View File

@@ -8,40 +8,40 @@ export default Vue.extend({
*/
value: {
type: Number,
default: 0,
default: 0
},
/**
* @description 是否显示 tooltip
*/
showTooltip: {
type: Boolean,
default: true,
default: true
},
max: {
type: Number,
default: 1,
default: 1
},
step: {
type: Number,
default: 0.1,
default: 0.1
},
min: {
type: Number,
default: 0,
default: 0
},
marks: {
type: Object,
default: () => {},
default: () => {}
},
hitTest: {
type: Boolean,
default: false,
},
default: false
}
},
model: {
prop: 'value',
event: 'input',
},
event: 'input'
}
})
</script>
@@ -58,8 +58,16 @@ export default Vue.extend({
:max="max"
/>
<!-- 靠左显示 -->
<div v-if="hitTest" class="col-span-2 row-span-1" style="justify-self: start">语义 {{ (max - value).toFixed(1) }}</div>
<div
v-if="hitTest"
class="col-span-2 row-span-1"
style="justify-self: start"
>
语义 {{ (max - value).toFixed(1) }}
</div>
<!-- 靠右显示 -->
<div v-if="hitTest" class="col-span-1 row-span-1" style="justify-self: end">关键词 {{ value.toFixed(1) }}</div>
<div v-if="hitTest" class="col-span-1 row-span-1" style="justify-self: end">
关键词 {{ value.toFixed(1) }}
</div>
</div>
</template>

View File

@@ -42,7 +42,7 @@ Vue.component('VEditor', VueEditor)
// 富文本编辑器 可视化代码
Vue.component('MEditor', MavonEditor)
Vue.component('RSlider', RenderSlider)
Vue.prototype.$messageBox = function (isOk, message, type, title) {
Vue.prototype.$messageBox = function(isOk, message, type, title) {
this.$confirm(
message ? message : '是否确认删除当前数据',
title ? title : '提示',

View File

@@ -119,7 +119,7 @@ export default {
})
})
// 清空输入框
this.inputMessage = ''
// this.inputMessage = ''
},
formatScore(score) {
return score.toFixed(3)
@@ -137,7 +137,7 @@ export default {
<!-- 中间内容区域 -->
<div ref="contentArea" class="content-area">
<div class="empty-state" v-if="messages.length === 0">
<el-image alt="当前会话尚无记录"></el-image>
<!-- <el-image alt="当前会话尚无记录"></el-image>-->
<p>这里会显示命中测试的记录</p>
</div>
<div
@@ -174,7 +174,7 @@ export default {
>
<!-- 内容详情 -->
<section>
<p class="mb10 fs13 multi-ellipsis-2">
<p class="mb10 fs13 multi-ellipsis-2 mr20">
{{ contentItem.segment.content }}
</p>
<el-tag
@@ -191,7 +191,10 @@ export default {
<!-- score -->
<span class="score"
><el-tag type="success"
>score: {{ contentItem.score.toFixed(3) }}</el-tag
>score:
{{
contentItem.score ? contentItem.score.toFixed(3) : '0.000'
}}</el-tag
></span
>
</div>
@@ -313,7 +316,7 @@ export default {
</div>
<!-- 具体的参数内容 -->
<section>
<section class="mr20">
<div class="grid grid-cols-2">
<div class="col-span-1 flex align-items-c ">
<span class="mr5 flex" style="flex-flow: column nowrap">
@@ -346,7 +349,7 @@ export default {
</div>
<!-- 参数设置 -->
<section
class="mt10"
class="mt10 mr10"
v-if="paramsConfig.search_method === 'hybrid_search'"
>
<el-radio-group
@@ -423,7 +426,12 @@ export default {
</section>
</section>
</el-popover>
<el-button icon="el-icon-setting" size="small" slot="reference"
<el-button
icon="el-icon-setting"
size="small"
class="mr20"
slot="reference"
style="padding:11px 15px"
>参数设置
</el-button>
</el-popover>
@@ -432,7 +440,9 @@ export default {
v-model="inputMessage"
placeholder="请输入"
class="message-input"
size="medium"
@keyup.enter.native="sendMessage"
style="border-radius: 0px"
>
<template slot="append">
<el-button
@@ -650,6 +660,9 @@ export default {
.message-input {
flex: 1;
/deep/ .el-input__inner {
border-radius: 0 !important;
}
}
}
}

View File

@@ -0,0 +1,161 @@
<template>
<div>
<el-drawer
title="搜索设置"
:visible.sync="visible"
size="50%"
@close="handleClose"
>
<el-form ref="form" :model="form" label-width="80%" label-position="top">
<el-row>
<el-col :span="12">
<el-form-item label="Embedding模型">
<el-select v-model="form.embeddingModel" placeholder="请选择">
<el-option
v-for="item in modelList"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<!-- <el-form-item label="检索设置">
<div class="flex justify-content-b">
<div
v-for="(item, index) in settingList"
:key="item.name"
class="setting_item flex"
:class="{ activeItem: index === activeIndex }"
@click="handleClick(index)"
>
<img
src="@/assets/images/konwledge/knowledge-5.png"
alt=""
style="height: 40px"
/>
<div class="ml10">
<p class="fwb label fs15">
{{ item.name }}
<span v-if="index === 2" class="point fs12 ml10">推荐</span>
</p>
<p class="desc">{{ item.desc }}</p>
</div>
</div>
</div>
</el-form-item>-->
<el-collapse v-model="activeName" accordion>
<el-collapse-item
v-for="(item, index) in settingList"
:key="item.name"
:title="item.name"
:name="index"
>
<template slot="title">
<div class="flex align-items-c">
<img
src="@/assets/images/konwledge/knowledge-5.png"
alt=""
style="height: 20px"
/>
<div class="ml10">
<p class="fwb label fs15">
{{ item.name }}
<span v-if="index === 2" class="point fs12 ml10">推荐</span>
</p>
<p class="desc">{{ item.desc }}</p>
</div>
</div>
</template>
<div>
<search-form :activeIndex="activeName"></search-form>
</div>
</el-collapse-item>
</el-collapse>
</el-form>
</el-drawer>
</div>
</template>
<script>
import SearchForm from '@/views/knowledge/detail/components/SearchSetting/SearchForm.vue'
export default {
name: 'SearchSetting',
components: { SearchForm },
props: {},
data() {
return {
activeName: 0,
visible: false,
form: {
embeddingModel: '',
modelOpen: false
},
modelList: [],
activeIndex: 0,
settingList: [
{
name: '向量检索',
desc: '通过生成查询嵌入并查询与其向量表示最相似的文本分段'
},
{
name: '全文检索',
desc:
'索引文档中的所有词汇,从而允许用户查询任意词汇,并返回包含这些词汇的文本片段'
},
{
name: '混合检索',
desc:
'同时执行全文检索和向量检索,并应用重排序步骤,从两类查询结果中选择匹配用户问题的最佳结果,用户可以选择设置权重或配置重新排序模型。'
}
],
marks: {
// 20: '0',
// 80: '100'
}
}
},
methods: {
init() {
this.visible = true
},
handleClose() {
this.$emit('close')
},
handleClick(index) {
this.activeIndex = index
}
}
}
</script>
<style scoped lang="scss">
.point {
color: #296dff;
border-radius: 4px;
border: 1px solid #296dff;
padding: 2px 5px;
}
.label {
color: #354052;
font-size: 15px;
}
.desc {
color: #676f83;
}
/deep/ .el-collapse-item__header {
height: 85px;
line-height: 23px;
border: 1px solid #ebeef5;
border-radius: 5px;
padding: 10px 20px;
margin-top: 10px;
}
/deep/ .is-active {
.el-collapse-item__header {
background-color: #f5f5fb;
}
}
</style>

View File

@@ -0,0 +1,103 @@
<template>
<div class="pl10 searchForm_cont">
<el-form :model="form" label-width="80%" label-position="top">
<el-form-item label="">
<el-switch v-model="form.modelOpen"></el-switch>
<span>Rerank 模型</span>
<el-tooltip
class="item"
effect="dark"
content="重排序模型将根据候选文档列表与用户问题予以匹配程度进行重新排序,从而改进语义排序的结果"
placement="top"
>
<i class="el-icon-info ml5" style="color: #909399;"></i>
</el-tooltip>
</el-form-item>
<el-row v-if="activeIndex === 2">
<el-slider v-model="value" :marks="marks"> </el-slider
></el-row>
<el-row v-else>
<el-col :span="8">
<el-form-item label="">
<el-select v-model="form.embeddingModel" placeholder="请选择">
<el-option
v-for="item in modelList"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="10" class="flex">
<el-form-item label="Top K">
<el-input-number
v-model="form.topK"
:min="1"
:max="10"
label="Top K"
controls-position="right"
size="mini"
></el-input-number>
</el-form-item>
<div style="width: 300px;">
<el-slider v-model="value" :min="1" :max="10" :step="1"></el-slider>
</div>
</el-col>
</el-row>
<el-row>
<el-col :span="10">
<el-form-item label="Score阈值">
<el-slider
v-model="value"
show-input
show-input-controls
:min="0"
:max="1"
:step="0.01"
:precision="2"
></el-slider>
</el-form-item>
</el-col>
</el-row>
</el-form>
</div>
</template>
<script>
export default {
name: 'SearchForm',
props: {
activeIndex: {
type: Number
}
},
data() {
return {
form: {
modelOpen: true,
embeddingModel: 'sentence-transformers/all-MiniLM-L6-v2',
topK: 3,
scoreThreshold: 0.5
},
modelList: [
{
value: 'sentence-transformers/all-MiniLM-L6-v2',
label: 'sentence-transformers/all-MiniLM-L6-v2'
},
{}
]
}
}
}
</script>
<style scoped lang="scss">
.searchForm_cont {
border-left: 1px solid #ebeef5;
border-right: 1px solid #ebeef5;
border-bottom: 1px solid #ebeef5;
border-radius: 0 5px 5px 0;
}
</style>

View File

@@ -49,14 +49,6 @@
<div>
<!-- <el-button type="primary" size="medium" class="normal-button" @click="jumpEditKnowledge">修改知识库</el-button>-->
<el-button
type="primary"
size="medium"
icon="el-icon-edit-outline"
class="primary-button"
@click="jumpEditKnowledge"
>修改知识库
</el-button>
<el-button
type="primary"
size="medium"
@@ -65,6 +57,22 @@
@click="jumpAddKnowledge"
>上传知识
</el-button>
<el-button
type="primary"
size="medium"
icon="el-icon-edit-outline"
class="primary-button"
@click="jumpEditKnowledge"
>修改知识库
</el-button>
<!-- <el-button-->
<!-- type="primary"-->
<!-- size="medium"-->
<!-- icon="el-icon-search"-->
<!-- class="line-button"-->
<!-- @click="searchSetting"-->
<!-- >检索设置-->
<!-- </el-button>-->
<el-button
type="primary"
icon="el-icon-s-promotion"
@@ -219,6 +227,8 @@
@close="close"
></metadata-operator>
</el-drawer>
<!--检索设置弹窗-->
<search-setting ref="searchSetting"></search-setting>
</div>
</template>
<script>
@@ -241,6 +251,7 @@ import knowledgePng_1 from '@/assets/images/konwledge/knowledge-1.png'
import hitTest from '@/views/knowledge/detail/components/HitTest/Index.vue'
import MetaData from '@/views/knowledge/detail/components/metaData/Index.vue'
import MetadataOperator from '@/views/knowledge/detail/components/metaData/MetadataOperator.vue'
import SearchSetting from '@/views/knowledge/detail/components/SearchSetting/Index.vue'
export default {
name: 'index',
@@ -295,6 +306,7 @@ export default {
props: {},
watch: {},
components: {
SearchSetting,
MetaData,
hitTest,
knowledgeForm,
@@ -358,6 +370,12 @@ export default {
// }
// })
},
/**
* 检索设置
*/
searchSetting() {
this.$refs.searchSetting.init()
},
/**
* @name 根据id 获取知识内容详情
* @author Chen Yuda