|
@@ -0,0 +1,294 @@
|
|
|
+<template>
|
|
|
+ <CzrDialog
|
|
|
+ :show="show"
|
|
|
+ title="召回设置"
|
|
|
+ @onClose="$emit('update:show', false)"
|
|
|
+ @onSubmit="onSubmit"
|
|
|
+ width="62.5rem"
|
|
|
+ height="auto"
|
|
|
+ >
|
|
|
+ <div class="bm-form">
|
|
|
+ <CzrForm ref="ref_form" label-width="6.1rem">
|
|
|
+ <div
|
|
|
+ class="rounded-2.5 search-method-active w-full bg-[#ffffff]"
|
|
|
+ style="border: var(--czr-border); border-width: 0.13rem"
|
|
|
+ >
|
|
|
+ <div class="h-full w-full px-[1.5rem] py-4">
|
|
|
+ <div class="flex items-center">
|
|
|
+ <img
|
|
|
+ src="@/assets/images/model/model-icon-6.png"
|
|
|
+ class="mr-2.5 h-[3.25rem] w-[3.25rem]"
|
|
|
+ />
|
|
|
+ <div class="text-xl font-bold text-[#2E3238]">召回设置</div>
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ class="mt-2 text-sm text-[#606266]"
|
|
|
+ style="line-height: 1.3rem"
|
|
|
+ >
|
|
|
+ 默认情况下使用多路召回。从多个知识库中检索知识,然后重新排序。
|
|
|
+ </div>
|
|
|
+ <div class="mt-4 flex w-full gap-4">
|
|
|
+ <div
|
|
|
+ class="__hover rounded-2.5 h-[8.38rem] flex-1 bg-[#ffffff] px-[1.5rem] py-4"
|
|
|
+ style="border: var(--czr-border); border-width: 0.13rem"
|
|
|
+ :class="{
|
|
|
+ 'index-method-active': state.config.indexMethod === 'weight',
|
|
|
+ }"
|
|
|
+ @click="() => (state.config.indexMethod = 'weight')"
|
|
|
+ >
|
|
|
+ <div class="flex items-center">
|
|
|
+ <img
|
|
|
+ src="@/assets/images/model/model-icon-8.png"
|
|
|
+ class="mr-2.5 h-[3.25rem] w-[3.25rem]"
|
|
|
+ />
|
|
|
+ <div class="text-xl font-bold text-[#2E3238]">权重设置</div>
|
|
|
+ <img
|
|
|
+ src="@/assets/images/model/model-icon-3.png"
|
|
|
+ class="h-[1.27rem] w-[2.88rem]"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ class="mt-2 text-sm text-[#606266]"
|
|
|
+ style="line-height: 1.3rem"
|
|
|
+ >
|
|
|
+ 通过调整分配的权重,重新排序策略确定是优先进行语义匹配还是关键字匹配。
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ class="__hover rounded-2.5 h-[8.38rem] flex-1 bg-[#ffffff] px-[1.5rem] py-4"
|
|
|
+ style="border: var(--czr-border); border-width: 0.13rem"
|
|
|
+ :class="{
|
|
|
+ 'index-method-active': state.config.indexMethod === 'rerank',
|
|
|
+ }"
|
|
|
+ @click="() => (state.config.indexMethod = 'rerank')"
|
|
|
+ >
|
|
|
+ <div class="flex items-center">
|
|
|
+ <img
|
|
|
+ src="@/assets/images/model/model-icon-9.png"
|
|
|
+ class="mr-2.5 h-[3.25rem] w-[3.25rem]"
|
|
|
+ />
|
|
|
+ <div class="text-xl font-bold text-[#2E3238]">
|
|
|
+ Rerank 模型
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ class="mt-2 text-sm text-[#606266]"
|
|
|
+ style="line-height: 1.3rem"
|
|
|
+ >
|
|
|
+ 重排序模型将根据候选文档列表与用户问题语义匹配度进行重新排序,从而改进语义排序的结果。
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ class="text-4 mt-4 flex flex-col gap-2 rounded-[0.25rem] bg-[#ffffff] p-2.5 font-bold text-[#2E3238]"
|
|
|
+ >
|
|
|
+ <template v-if="state.config.indexMethod === 'weight'">
|
|
|
+ <div>
|
|
|
+ <el-slider
|
|
|
+ v-model="state.config.weight"
|
|
|
+ :min="0"
|
|
|
+ :max="1"
|
|
|
+ :step="0.1"
|
|
|
+ class="weight-slider"
|
|
|
+ />
|
|
|
+ <div class="flex justify-between">
|
|
|
+ <div class="text-[var(--czr-main-color)]">
|
|
|
+ 语义
|
|
|
+ {{ state.config.weight }}
|
|
|
+ </div>
|
|
|
+ <div class="text-[var(--czr-success-color)]">
|
|
|
+ {{ (1 - state.config.weight).toFixed(1) }}
|
|
|
+ 关键词
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <template v-else-if="state.config.indexMethod === 'rerank'">
|
|
|
+ <CzrFormColumn
|
|
|
+ required
|
|
|
+ class="__czr-table-form-column"
|
|
|
+ :span="24"
|
|
|
+ label-width="0px"
|
|
|
+ v-model:param="state.config.rerank"
|
|
|
+ link="select"
|
|
|
+ :options="state.optionsRerank"
|
|
|
+ :clearable="false"
|
|
|
+ default-error-msg="请选择Rerank模型"
|
|
|
+ />
|
|
|
+ </template>
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ class="text-4 mt-4 flex flex-col gap-2 rounded-[0.25rem] bg-[#ffffff] p-2.5 font-bold text-[#2E3238]"
|
|
|
+ >
|
|
|
+ <div class="flex gap-4">
|
|
|
+ <div class="flex-1">
|
|
|
+ <div class="flex h-4 items-center gap-2">
|
|
|
+ TOP K
|
|
|
+ <el-tooltip
|
|
|
+ content="用于筛选与用户问题相似度最高的文本片段。系统同时会根据选用模型上下文窗口大小动态调整分段数量。"
|
|
|
+ placement="top"
|
|
|
+ >
|
|
|
+ <SvgIcon name="czr_tip" size="14" />
|
|
|
+ </el-tooltip>
|
|
|
+ </div>
|
|
|
+ <div class="mt-4">
|
|
|
+ <el-slider
|
|
|
+ v-model="state.config.topK"
|
|
|
+ show-input
|
|
|
+ class="re-slider"
|
|
|
+ :min="1"
|
|
|
+ :max="10"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="flex-1">
|
|
|
+ <div class="flex h-4 items-center gap-2">
|
|
|
+ <el-switch
|
|
|
+ size="small"
|
|
|
+ v-model="state.config.isScore"
|
|
|
+ :active-value="1"
|
|
|
+ :inactive-value="0"
|
|
|
+ />
|
|
|
+ Score 阈值
|
|
|
+ <el-tooltip
|
|
|
+ content="用于设置文本片段筛选的相似度阈值。"
|
|
|
+ placement="top"
|
|
|
+ >
|
|
|
+ <SvgIcon name="czr_tip" size="14" />
|
|
|
+ </el-tooltip>
|
|
|
+ </div>
|
|
|
+ <div class="mt-4">
|
|
|
+ <el-slider
|
|
|
+ v-model="state.config.score"
|
|
|
+ show-input
|
|
|
+ class="re-slider"
|
|
|
+ :max="1"
|
|
|
+ :min="0"
|
|
|
+ :step="0.01"
|
|
|
+ :disabled="!state.config.isScore"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </CzrForm>
|
|
|
+ </div>
|
|
|
+ </CzrDialog>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup lang="ts">
|
|
|
+import {
|
|
|
+ computed,
|
|
|
+ getCurrentInstance,
|
|
|
+ nextTick,
|
|
|
+ onMounted,
|
|
|
+ reactive,
|
|
|
+ ref,
|
|
|
+ watch,
|
|
|
+} from 'vue'
|
|
|
+import { ElMessage, ElMessageBox } from 'element-plus'
|
|
|
+import { useDialogStore, useDictionaryStore } from '@/stores'
|
|
|
+import { pluginGetListByType } from '@/api/modules/model'
|
|
|
+
|
|
|
+const DictionaryStore = useDictionaryStore()
|
|
|
+const DialogStore = useDialogStore()
|
|
|
+const emit = defineEmits(['update:show', 'refresh'])
|
|
|
+const { proxy } = getCurrentInstance()
|
|
|
+const props = defineProps({
|
|
|
+ show: { default: false },
|
|
|
+ transfer: <any>{},
|
|
|
+})
|
|
|
+const state: any = reactive({
|
|
|
+ config: {
|
|
|
+ indexMethod: 'weight',
|
|
|
+ weight: 0.7,
|
|
|
+ rerank: '',
|
|
|
+ topK: 5,
|
|
|
+ isScore: 1,
|
|
|
+ score: 0.5,
|
|
|
+ },
|
|
|
+ optionsRerank: [],
|
|
|
+})
|
|
|
+const ref_form = ref()
|
|
|
+watch(
|
|
|
+ () => props.show,
|
|
|
+ (n) => {
|
|
|
+ if (n) {
|
|
|
+ reset()
|
|
|
+ if (props.transfer.config) {
|
|
|
+ state.config = JSON.parse(JSON.stringify(props.transfer.config))
|
|
|
+ }
|
|
|
+ nextTick(() => {
|
|
|
+ ref_form.value.reset()
|
|
|
+ })
|
|
|
+ }
|
|
|
+ },
|
|
|
+)
|
|
|
+const reset = () => {
|
|
|
+ state.config = {
|
|
|
+ indexMethod: 'weight',
|
|
|
+ weight: 0.7,
|
|
|
+ rerank: '',
|
|
|
+ topK: 5,
|
|
|
+ isScore: 1,
|
|
|
+ score: 0.5,
|
|
|
+ }
|
|
|
+}
|
|
|
+const onSubmit = () => {
|
|
|
+ ref_form.value
|
|
|
+ .submit()
|
|
|
+ .then(() => {
|
|
|
+ emit('refresh', state.config)
|
|
|
+ emit('update:show', false)
|
|
|
+ })
|
|
|
+ .catch((e) => {
|
|
|
+ ElMessage({
|
|
|
+ message: e[0].message,
|
|
|
+ grouping: true,
|
|
|
+ type: 'warning',
|
|
|
+ })
|
|
|
+ })
|
|
|
+}
|
|
|
+onMounted(() => {
|
|
|
+ initDictionary()
|
|
|
+})
|
|
|
+const initDictionary = () => {
|
|
|
+ pluginGetListByType({ type: 'RERANK' })
|
|
|
+ .then(({ data }: any) => {
|
|
|
+ state.optionsRerank = data.map((v) => {
|
|
|
+ v.label = v.name
|
|
|
+ v.value = v.id
|
|
|
+ return v
|
|
|
+ })
|
|
|
+ })
|
|
|
+ .catch(() => {})
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+.index-method-active {
|
|
|
+ box-shadow: 0rem 0.25rem 0.63rem 0rem rgba(40, 83, 247, 0.05);
|
|
|
+ border-color: var(--czr-main-color) !important;
|
|
|
+ background-color: rgba(var(--czr-main-color-rgb), 0.1);
|
|
|
+}
|
|
|
+.search-method-active {
|
|
|
+ box-shadow: 0rem 0.25rem 0.63rem 0rem rgba(40, 83, 247, 0.05);
|
|
|
+ background-image: url('@/assets/images/model/model-icon-7.png');
|
|
|
+ background-size: 100% 100%;
|
|
|
+ background-repeat: no-repeat;
|
|
|
+}
|
|
|
+:deep(.re-slider) {
|
|
|
+ flex-direction: row-reverse;
|
|
|
+ .el-slider__runway {
|
|
|
+ margin-left: 10px;
|
|
|
+ margin-right: 0;
|
|
|
+ }
|
|
|
+}
|
|
|
+:deep(.weight-slider) {
|
|
|
+ .el-slider__runway {
|
|
|
+ background-color: var(--czr-success-color);
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|