mirror of
http://112.124.100.131/ebiz-ai/ebiz-ai-knowledge-manage.git
synced 2025-12-09 10:56:50 +08:00
feat(knowledge): 优化 hit-test 功能
- 新增 Rerank 模型支持 - 添加权重设置功能 - 优化界面布局和交互 - 增加内容详情弹窗 - 调整样式,提升可读性
This commit is contained in:
12
src/api/knowledge/hit-test.js
Normal file
12
src/api/knowledge/hit-test.js
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import request from '@/assets/js/utils/request'
|
||||||
|
import getUrl from '@/assets/js/utils/get-url'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 获取所有的 rerank 模型列表
|
||||||
|
*/
|
||||||
|
export function getRerankModels() {
|
||||||
|
return request({
|
||||||
|
url: getUrl("/third/models/rerank"),
|
||||||
|
method: 'get',
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -258,6 +258,29 @@ h3 {
|
|||||||
@include text-overflow;
|
@include text-overflow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 多行文本省略 */
|
||||||
|
.multi-ellipsis-2 {
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
-webkit-line-clamp: 2;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.multi-ellipsis-3 {
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
-webkit-line-clamp: 3;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 可以根据需要添加更多行数 */
|
||||||
|
.multi-ellipsis-4 {
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
-webkit-line-clamp: 4;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
//颜色
|
//颜色
|
||||||
.green {
|
.green {
|
||||||
color: $green !important;
|
color: $green !important;
|
||||||
|
|||||||
@@ -80,7 +80,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import Cropper from 'cropperjs'
|
// import Cropper from 'cropperjs'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'index',
|
name: 'index',
|
||||||
|
|||||||
65
src/components/RenderSlider/Index.vue
Normal file
65
src/components/RenderSlider/Index.vue
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import Vue from 'vue'
|
||||||
|
export default Vue.extend({
|
||||||
|
name: 'RenderSlider',
|
||||||
|
props: {
|
||||||
|
/**
|
||||||
|
* @description 当前值
|
||||||
|
*/
|
||||||
|
value: {
|
||||||
|
type: Number,
|
||||||
|
default: 0,
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* @description 是否显示 tooltip
|
||||||
|
*/
|
||||||
|
showTooltip: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
max: {
|
||||||
|
type: Number,
|
||||||
|
default: 1,
|
||||||
|
},
|
||||||
|
step: {
|
||||||
|
type: Number,
|
||||||
|
default: 0.1,
|
||||||
|
},
|
||||||
|
min: {
|
||||||
|
type: Number,
|
||||||
|
default: 0,
|
||||||
|
},
|
||||||
|
marks: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {},
|
||||||
|
},
|
||||||
|
hitTest: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
model: {
|
||||||
|
prop: 'value',
|
||||||
|
event: 'input',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="grid grid-cols-3 grid-rows-2">
|
||||||
|
<el-slider
|
||||||
|
class="col-span-3 row-span-1"
|
||||||
|
v-model="value"
|
||||||
|
:show-tooltip="showTooltip"
|
||||||
|
@input="$emit('input', $event)"
|
||||||
|
:marks="hitTest ? marks : {}"
|
||||||
|
:step="step"
|
||||||
|
:min="min"
|
||||||
|
: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-1 row-span-1" style="justify-self: end">关键词 {{ value.toFixed(1) }}</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
@@ -410,19 +410,23 @@ export default {
|
|||||||
padding: 5px;
|
padding: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/deep/.el-table {
|
/deep/ .el-table {
|
||||||
.el-radio__label {
|
.el-radio__label {
|
||||||
padding: unset;
|
padding: unset;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-form-item__error {
|
.el-form-item__error {
|
||||||
position: unset;
|
position: unset;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-form-item__content {
|
.el-form-item__content {
|
||||||
line-height: unset;
|
line-height: unset;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-form-item__error {
|
.el-form-item__error {
|
||||||
position: unset;
|
position: unset;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-form-item {
|
.el-form-item {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import RenderSwiper from './components/RenderSwiper'
|
|||||||
import VueEditor from './components/VueEditor'
|
import VueEditor from './components/VueEditor'
|
||||||
import MavonEditor from './components/MavonEditor'
|
import MavonEditor from './components/MavonEditor'
|
||||||
import RenderMinerU from '@/components/RenderMinerU/index.vue'
|
import RenderMinerU from '@/components/RenderMinerU/index.vue'
|
||||||
|
import RenderSlider from '@/components/RenderSlider/Index.vue'
|
||||||
import utils from '@/assets/js/common'
|
import utils from '@/assets/js/common'
|
||||||
// 生成的数据交互api
|
// 生成的数据交互api
|
||||||
import generatedFormat from '@/assets/js/generatedFormat'
|
import generatedFormat from '@/assets/js/generatedFormat'
|
||||||
@@ -40,7 +41,8 @@ Vue.component('RMinerU', RenderMinerU)
|
|||||||
Vue.component('VEditor', VueEditor)
|
Vue.component('VEditor', VueEditor)
|
||||||
// 富文本编辑器 可视化代码
|
// 富文本编辑器 可视化代码
|
||||||
Vue.component('MEditor', MavonEditor)
|
Vue.component('MEditor', MavonEditor)
|
||||||
Vue.prototype.$messageBox = function(isOk, message, type, title) {
|
Vue.component('RSlider', RenderSlider)
|
||||||
|
Vue.prototype.$messageBox = function (isOk, message, type, title) {
|
||||||
this.$confirm(
|
this.$confirm(
|
||||||
message ? message : '是否确认删除当前数据',
|
message ? message : '是否确认删除当前数据',
|
||||||
title ? title : '提示',
|
title ? title : '提示',
|
||||||
|
|||||||
@@ -1,53 +1,132 @@
|
|||||||
<script>
|
<script>
|
||||||
import { hitTest } from '@/api/generatedApi'
|
import { hitTest } from '@/api/generatedApi'
|
||||||
|
import { getRerankModels } from '@/api/knowledge/hit-test'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'hitTest',
|
name: 'hitTest',
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
testForm: {
|
|
||||||
isRanking: true
|
|
||||||
},
|
|
||||||
datasetId: void 0,
|
datasetId: void 0,
|
||||||
|
params: {
|
||||||
|
search_method: 'hybrid_search',
|
||||||
|
score_threshold_enable: false,
|
||||||
|
score_threshold: 0,
|
||||||
|
top_k: 5,
|
||||||
|
reranking_enable: false,
|
||||||
|
reranking_model: {
|
||||||
|
reranking_provider_name: '',
|
||||||
|
reranking_model_name: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
paramsConfig: {
|
paramsConfig: {
|
||||||
|
weights: 0,
|
||||||
visible: false,
|
visible: false,
|
||||||
searchMode: 'hybrid_search', // 默认选择向量检索
|
/**
|
||||||
score_threshold: 0.6, // 默认相似度
|
* @description 是否启用 Rerank 模型
|
||||||
|
*/
|
||||||
|
reranking_enable: true,
|
||||||
|
/**
|
||||||
|
* @description 检索方法
|
||||||
|
*/
|
||||||
|
search_method: 'hybrid_search', // 默认选择混合检索
|
||||||
|
/**
|
||||||
|
* @description score 阈值
|
||||||
|
*/
|
||||||
|
score_threshold: 0,
|
||||||
|
/**
|
||||||
|
* @description TOPK 设置
|
||||||
|
*/
|
||||||
top_k: 5, // 默认引用分段数,
|
top_k: 5, // 默认引用分段数,
|
||||||
reranking_model: ''
|
/**
|
||||||
|
* @description rerank 模型名称
|
||||||
|
*/
|
||||||
|
reranking_model: '',
|
||||||
|
/**
|
||||||
|
* @description 模型列表
|
||||||
|
*/
|
||||||
|
rerankModelOptions: []
|
||||||
},
|
},
|
||||||
inputMessage: '',
|
inputMessage: '',
|
||||||
loading: false,
|
loading: false,
|
||||||
messages: []
|
messages: [],
|
||||||
|
// 对话框配置
|
||||||
|
dialogConfig: {
|
||||||
|
visible: false,
|
||||||
|
title: '查看详情',
|
||||||
|
width: '500px',
|
||||||
|
isShowFooter: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
'paramsConfig.reranking_enable': {
|
||||||
|
handler() {
|
||||||
|
// 如果 isRanking 为 false,清空 reranking_model, 防止错误提交
|
||||||
|
if (!this.paramsConfig.reranking_enable) {
|
||||||
|
// 删除 params 中的 reranking_model
|
||||||
|
delete this.params.reranking_model
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.paramsConfig.reranking_model = void 0
|
||||||
|
},
|
||||||
|
deep: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
// 从 路由参数中获取datasetId
|
// 从 路由参数中获取datasetId
|
||||||
this.datasetId = this.$route.query.datasetId
|
this.datasetId = this.$route.query.datasetId
|
||||||
|
|
||||||
|
// 获取 rerank 模型列表
|
||||||
|
getRerankModels().then(res => {
|
||||||
|
const { content } = res.content
|
||||||
|
this.paramsConfig.rerankModelOptions = content.flatMap(
|
||||||
|
item => item.models
|
||||||
|
)
|
||||||
|
})
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
sendMessage() {
|
handleEnsureClick() {
|
||||||
if (!this.inputMessage.trim()) return
|
// 关闭内容
|
||||||
|
this.paramsConfig.visible = false
|
||||||
|
|
||||||
|
// 更新 params
|
||||||
|
this.params = {
|
||||||
|
search_method: this.paramsConfig.searchMode,
|
||||||
|
score_threshold: this.paramsConfig.score_threshold,
|
||||||
|
top_k: this.paramsConfig.top_k,
|
||||||
|
reranking_model: this.paramsConfig.reranking_model,
|
||||||
|
reranking_enable: this.paramsConfig.reranking_enable
|
||||||
|
}
|
||||||
|
},
|
||||||
|
sendMessage() {
|
||||||
|
const contentArea = this.$refs.contentArea
|
||||||
|
if (!this.inputMessage.trim()) return
|
||||||
// 显示骨架屏
|
// 显示骨架屏
|
||||||
this.loading = true
|
this.loading = true
|
||||||
|
|
||||||
// 发送请求
|
// 发送请求
|
||||||
hitTest({
|
hitTest({
|
||||||
datasetsId: this.datasetId,
|
datasetsId: this.datasetId,
|
||||||
query: this.inputMessage
|
query: this.inputMessage,
|
||||||
|
retrieval_model: this.params
|
||||||
}).then(res => {
|
}).then(res => {
|
||||||
const { content } = res.content
|
const { content } = res.content
|
||||||
|
|
||||||
this.messages.push(content)
|
this.messages.push(content)
|
||||||
|
|
||||||
this.loading = false
|
this.loading = false
|
||||||
|
|
||||||
|
this.$nextTick(() => {
|
||||||
|
// 滚动到底部
|
||||||
|
contentArea.scrollTop = contentArea.scrollHeight
|
||||||
|
})
|
||||||
})
|
})
|
||||||
// 清空输入框
|
// 清空输入框
|
||||||
this.inputMessage = ''
|
this.inputMessage = ''
|
||||||
},
|
},
|
||||||
formatScore(score) {
|
formatScore(score) {
|
||||||
return score.toFixed(3)
|
return score.toFixed(3)
|
||||||
|
},
|
||||||
|
handleCardClick(contentItem) {
|
||||||
|
this.dialogConfig.visible = true
|
||||||
|
this.dialogConfig.content = contentItem
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -56,7 +135,7 @@ export default {
|
|||||||
<template>
|
<template>
|
||||||
<div class="hit-test-container">
|
<div class="hit-test-container">
|
||||||
<!-- 中间内容区域 -->
|
<!-- 中间内容区域 -->
|
||||||
<div class="content-area">
|
<div ref="contentArea" class="content-area">
|
||||||
<div class="empty-state" v-if="messages.length === 0">
|
<div class="empty-state" v-if="messages.length === 0">
|
||||||
<el-image alt="当前会话尚无记录"></el-image>
|
<el-image alt="当前会话尚无记录"></el-image>
|
||||||
<p>这里会显示命中测试的记录</p>
|
<p>这里会显示命中测试的记录</p>
|
||||||
@@ -64,60 +143,85 @@ export default {
|
|||||||
<div
|
<div
|
||||||
class="messages mb10"
|
class="messages mb10"
|
||||||
v-else
|
v-else
|
||||||
v-for="content in messages"
|
v-for="(content, index) in messages"
|
||||||
:key="content"
|
:key="index"
|
||||||
>
|
>
|
||||||
<!-- 对话区域 -->
|
<!-- 对话区域 -->
|
||||||
<el-card>
|
<el-card>
|
||||||
<!-- 头像 和 会话内容 -->
|
<!-- 头像 和 会话内容 -->
|
||||||
<div class="flex align-items-c mb10">
|
<div class="flex align-items-c mb10">
|
||||||
<el-avatar :size="40" class="user-avatar" shape="square">
|
<!-- <el-avatar
|
||||||
|
:size="40"
|
||||||
|
class="user-avatar"
|
||||||
|
shape="square"
|
||||||
|
>
|
||||||
admin
|
admin
|
||||||
</el-avatar>
|
</el-avatar> -->
|
||||||
|
|
||||||
<div style="margin: 0 10px;">
|
<div style="margin: 0 10px">根据您的问题,我们为你提供以下建议</div>
|
||||||
根据您的问题,我们为你提供以下建议
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-card
|
<el-card
|
||||||
v-for="(contentItem, index) in content"
|
v-for="contentItem in content"
|
||||||
:key="index"
|
:key="contentItem.segment.content"
|
||||||
shadow="hover"
|
shadow="hover"
|
||||||
body-style="padding: 10px;backgroundColor: f2f2f2"
|
body-style="padding: 10px;backgroundColor: f2f2f2"
|
||||||
class="mb10"
|
class="mb10"
|
||||||
>
|
>
|
||||||
<div class="flex justify-content-b">
|
<div
|
||||||
|
class="flex justify-content-b"
|
||||||
|
@click="handleCardClick(contentItem)"
|
||||||
|
>
|
||||||
<!-- 内容详情 -->
|
<!-- 内容详情 -->
|
||||||
<section>
|
<section>
|
||||||
<p class="mb10">{{ contentItem.segment.content }}</p>
|
<p class="mb10 fs13 multi-ellipsis-2">
|
||||||
|
{{ contentItem.segment.content }}
|
||||||
|
</p>
|
||||||
<el-tag
|
<el-tag
|
||||||
type="success"
|
class="mr5 mb5"
|
||||||
|
type="info"
|
||||||
size="small"
|
size="small"
|
||||||
v-for="(keyword, index) in contentItem.segment.keywords"
|
v-for="(keyword, index) in contentItem.segment.keywords"
|
||||||
:key="index"
|
:key="index + keyword"
|
||||||
>
|
>
|
||||||
{{ keyword }}
|
{{ index + keyword }}
|
||||||
|
#{{ keyword }}
|
||||||
</el-tag>
|
</el-tag>
|
||||||
</section>
|
</section>
|
||||||
<!-- score -->
|
<!-- score -->
|
||||||
<span class="score">{{ contentItem.score.toFixed(3) }}</span>
|
<span class="score"
|
||||||
|
><el-tag type="success"
|
||||||
|
>score: {{ contentItem.score.toFixed(3) }}</el-tag
|
||||||
|
></span
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
</el-card>
|
</el-card>
|
||||||
<!-- 加载状态 -->
|
<!-- 加载状态 -->
|
||||||
<div v-if="loading" class="loading-message">
|
<!-- <div
|
||||||
<el-skeleton style="width: 100%" animated>
|
v-if="loading"
|
||||||
|
class="loading-message"
|
||||||
|
>
|
||||||
|
<el-skeleton
|
||||||
|
style="width: 100%"
|
||||||
|
animated
|
||||||
|
>
|
||||||
<template slot="template">
|
<template slot="template">
|
||||||
<el-skeleton-item
|
<el-skeleton-item
|
||||||
variant="p"
|
variant="p"
|
||||||
style="width: 100%; height: 60px;"
|
style="width: 100%; height: 60px"
|
||||||
|
/>
|
||||||
|
<el-skeleton-item
|
||||||
|
variant="p"
|
||||||
|
style="width: 90%; height: 20px"
|
||||||
|
/>
|
||||||
|
<el-skeleton-item
|
||||||
|
variant="p"
|
||||||
|
style="width: 80%; height: 20px"
|
||||||
/>
|
/>
|
||||||
<el-skeleton-item variant="p" style="width: 90%; height: 20px;" />
|
|
||||||
<el-skeleton-item variant="p" style="width: 80%; height: 20px;" />
|
|
||||||
</template>
|
</template>
|
||||||
</el-skeleton>
|
</el-skeleton>
|
||||||
</div>
|
</div> -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -136,17 +240,17 @@ export default {
|
|||||||
<h3>检索模式</h3>
|
<h3>检索模式</h3>
|
||||||
|
|
||||||
<el-radio-group
|
<el-radio-group
|
||||||
v-model="paramsConfig.searchMode"
|
v-model="paramsConfig.search_method"
|
||||||
class="search-mode-options"
|
class="search-mode-options"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="search-mode-option"
|
class="search-mode-option"
|
||||||
:class="{
|
:class="{
|
||||||
active: paramsConfig.searchMode === 'semantic_search'
|
active: paramsConfig.search_method === 'semantic_search'
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<el-radio
|
<el-radio
|
||||||
v-model="paramsConfig.searchMode"
|
v-model="paramsConfig.search_method"
|
||||||
label="semantic_search"
|
label="semantic_search"
|
||||||
key="semantic_search"
|
key="semantic_search"
|
||||||
>
|
>
|
||||||
@@ -160,11 +264,11 @@ export default {
|
|||||||
<div
|
<div
|
||||||
class="search-mode-option"
|
class="search-mode-option"
|
||||||
:class="{
|
:class="{
|
||||||
active: paramsConfig.searchMode === 'full_text_search'
|
active: paramsConfig.search_method === 'full_text_search'
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<el-radio
|
<el-radio
|
||||||
v-model="paramsConfig.searchMode"
|
v-model="paramsConfig.search_method"
|
||||||
label="full_text_search"
|
label="full_text_search"
|
||||||
key="full_text_search"
|
key="full_text_search"
|
||||||
>
|
>
|
||||||
@@ -178,11 +282,11 @@ export default {
|
|||||||
<div
|
<div
|
||||||
class="search-mode-option"
|
class="search-mode-option"
|
||||||
:class="{
|
:class="{
|
||||||
active: paramsConfig.searchMode === 'hybrid_search'
|
active: paramsConfig.search_method === 'hybrid_search'
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<el-radio
|
<el-radio
|
||||||
v-model="paramsConfig.searchMode"
|
v-model="paramsConfig.search_method"
|
||||||
label="hybrid_search"
|
label="hybrid_search"
|
||||||
key="hybrid_search"
|
key="hybrid_search"
|
||||||
>
|
>
|
||||||
@@ -201,7 +305,7 @@ export default {
|
|||||||
<el-button
|
<el-button
|
||||||
type="primary"
|
type="primary"
|
||||||
size="small"
|
size="small"
|
||||||
@click="paramsConfig.visible = false"
|
@click="handleEnsureClick"
|
||||||
>确定
|
>确定
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
@@ -211,9 +315,15 @@ export default {
|
|||||||
<!-- 具体的参数内容 -->
|
<!-- 具体的参数内容 -->
|
||||||
<section>
|
<section>
|
||||||
<div class="grid grid-cols-2">
|
<div class="grid grid-cols-2">
|
||||||
<div class="col-span-1 flex align-items-c">
|
<div class="col-span-1 flex align-items-c ">
|
||||||
<span class="param-label mr5">Score 阈值</span>
|
<span class="mr5 flex" style="flex-flow: column nowrap">
|
||||||
|
<el-switch
|
||||||
|
v-model="paramsConfig.score_threshold_enable"
|
||||||
|
></el-switch>
|
||||||
|
<span>Score 阈值</span>
|
||||||
|
</span>
|
||||||
<el-input-number
|
<el-input-number
|
||||||
|
v-if="paramsConfig.score_threshold_enable"
|
||||||
v-model="paramsConfig.score_threshold"
|
v-model="paramsConfig.score_threshold"
|
||||||
:precision="3"
|
:precision="3"
|
||||||
:step="0.001"
|
:step="0.001"
|
||||||
@@ -236,45 +346,80 @@ export default {
|
|||||||
</div>
|
</div>
|
||||||
<!-- 参数设置 -->
|
<!-- 参数设置 -->
|
||||||
<section
|
<section
|
||||||
class="mt10 flex fs12"
|
class="mt10"
|
||||||
v-if="paramsConfig.searchMode === 'hybrid_search'"
|
v-if="paramsConfig.search_method === 'hybrid_search'"
|
||||||
>
|
>
|
||||||
<el-card shadow="never" class="mr5">
|
<el-radio-group
|
||||||
<div>权重设置</div>
|
v-model="paramsConfig.reranking_enable"
|
||||||
<div>
|
class="search-mode-options"
|
||||||
通过调整分配的权重,重新排序策略确定是优先进行语义匹配还是关键字匹配。
|
>
|
||||||
|
<div
|
||||||
|
class="search-mode-option"
|
||||||
|
:class="{ active: !paramsConfig.reranking_enable }"
|
||||||
|
>
|
||||||
|
<el-radio :label="false">
|
||||||
|
权重设置
|
||||||
|
<p class="option-desc">
|
||||||
|
通过调整分配的权重,重新排序策略确定是优先进行语义匹配还是关键字匹配。
|
||||||
|
</p>
|
||||||
|
</el-radio>
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
<div
|
||||||
<el-card shadow="never">
|
class="search-mode-option"
|
||||||
<div>Rerank 模型</div>
|
:class="{ active: paramsConfig.reranking_enable }"
|
||||||
<div>
|
>
|
||||||
重排序模型将根据候选文档列表与用户问题语义匹配度进行重新排序,从而改进语义排序的结果
|
<el-radio :label="true">
|
||||||
|
Rerank 模型
|
||||||
|
<p class="option-desc">
|
||||||
|
重排序模型将根据候选文档列表与用户问题语义匹配度进行重新排序,从而改进语义排序的结果
|
||||||
|
</p>
|
||||||
|
</el-radio>
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-radio-group>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="mt10">
|
<!-- 当选择了 rerank 模型之后或者不是混合搜索的选项时显示 -->
|
||||||
<el-form>
|
<section
|
||||||
<el-form-item>
|
class="mt15"
|
||||||
<template #label>
|
v-if="
|
||||||
<el-switch v-model="testForm.isRanking"></el-switch>
|
paramsConfig.reranking_enable ||
|
||||||
Rerank 模型
|
paramsConfig.search_method !== 'hybrid_search'
|
||||||
</template>
|
"
|
||||||
<el-select
|
>
|
||||||
v-model="paramsConfig.rerank_model"
|
<!-- 当没有设置权重或者不是混合检索时显示-->
|
||||||
size="medium"
|
<div
|
||||||
placeholder="选择一个模型"
|
class="mb15"
|
||||||
>
|
v-if="
|
||||||
<el-option
|
paramsConfig.reranking_enable ||
|
||||||
v-for="item in rerankModelOptions"
|
paramsConfig.search_method !== 'hybrid_search'
|
||||||
:key="item.value"
|
"
|
||||||
:label="item.label"
|
>
|
||||||
:value="item.value"
|
<el-switch v-model="paramsConfig.reranking_enable"></el-switch>
|
||||||
>
|
<span> Rerank 模型</span>
|
||||||
</el-option>
|
</div>
|
||||||
</el-select>
|
<el-select
|
||||||
</el-form-item>
|
v-if="paramsConfig.reranking_enable"
|
||||||
</el-form>
|
v-model="paramsConfig.rerank_model"
|
||||||
|
size="medium"
|
||||||
|
placeholder="选择一个模型"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="item in paramsConfig.rerankModelOptions"
|
||||||
|
:key="item.model"
|
||||||
|
:label="item.model"
|
||||||
|
:value="item.value"
|
||||||
|
>
|
||||||
|
{{ item.model }}
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
</section>
|
||||||
|
<!-- 权重设置 -->
|
||||||
|
<section v-else>
|
||||||
|
<RSlider
|
||||||
|
v-model="paramsConfig.weights"
|
||||||
|
:hit-test="true"
|
||||||
|
:show-tooltip="false"
|
||||||
|
/>
|
||||||
</section>
|
</section>
|
||||||
</section>
|
</section>
|
||||||
</el-popover>
|
</el-popover>
|
||||||
@@ -298,11 +443,27 @@ export default {
|
|||||||
</template>
|
</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<el-drawer
|
||||||
|
append-to-body
|
||||||
|
:modal="false"
|
||||||
|
:visible.sync="dialogConfig.visible"
|
||||||
|
:title="dialogConfig.title"
|
||||||
|
:width="dialogConfig.width"
|
||||||
|
:is-show-footer="dialogConfig.isShowFooter"
|
||||||
|
>
|
||||||
|
<div class="flex">
|
||||||
|
<div>{{ dialogConfig.content }}</div>
|
||||||
|
</div>
|
||||||
|
</el-drawer>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.hit-test-container {
|
.hit-test-container {
|
||||||
|
font-family: 'PingFang SC', sans-serif;
|
||||||
|
transition: all 0.5s;
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
height: 86vh;
|
height: 86vh;
|
||||||
@@ -312,7 +473,7 @@ export default {
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
.header {
|
.header {
|
||||||
padding: 10px 20px;
|
// padding: 10px 20px;
|
||||||
border-bottom: 1px solid #e4e7ed;
|
border-bottom: 1px solid #e4e7ed;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
}
|
}
|
||||||
@@ -320,7 +481,7 @@ export default {
|
|||||||
.content-area {
|
.content-area {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
padding: 20px;
|
padding: 10px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
@@ -493,6 +654,31 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.search-mode-options {
|
||||||
|
width: 100%;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
|
||||||
|
.search-mode-option {
|
||||||
|
padding: 10px;
|
||||||
|
border: 1px solid #e4e7ed;
|
||||||
|
border-radius: 4px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
border-color: #409eff;
|
||||||
|
background-color: #ecf5ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.option-desc {
|
||||||
|
margin: 5px 0 0 24px;
|
||||||
|
font-size: 12px;
|
||||||
|
text-wrap: wrap;
|
||||||
|
color: #909399;
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 参数设置弹窗样式
|
// 参数设置弹窗样式
|
||||||
.search-params-container {
|
.search-params-container {
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
@@ -504,31 +690,6 @@ export default {
|
|||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-mode-options {
|
|
||||||
width: 100%;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
|
|
||||||
.search-mode-option {
|
|
||||||
padding: 10px;
|
|
||||||
border: 1px solid #e4e7ed;
|
|
||||||
border-radius: 4px;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
|
|
||||||
&.active {
|
|
||||||
border-color: #409eff;
|
|
||||||
background-color: #ecf5ff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.option-desc {
|
|
||||||
margin: 5px 0 0 24px;
|
|
||||||
font-size: 12px;
|
|
||||||
text-wrap: wrap;
|
|
||||||
color: #909399;
|
|
||||||
line-height: 1.4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.action-buttons {
|
.action-buttons {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
@@ -538,8 +699,4 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.ts {
|
|
||||||
transition: all 0.5;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ import {
|
|||||||
import RenderFile from '@/components/RenderFile/Index.vue'
|
import RenderFile from '@/components/RenderFile/Index.vue'
|
||||||
import knowledgePng_2 from '@/assets/images/konwledge/knowledge-2.png'
|
import knowledgePng_2 from '@/assets/images/konwledge/knowledge-2.png'
|
||||||
import MetadataOperator from '@/views/knowledge/detail/components/metaData/MetadataOperator.vue'
|
import MetadataOperator from '@/views/knowledge/detail/components/metaData/MetadataOperator.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
MetadataOperator,
|
MetadataOperator,
|
||||||
|
|||||||
@@ -36,7 +36,8 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
proxy: {
|
proxy: {
|
||||||
[DIFY_URL]: {
|
[DIFY_URL]: {
|
||||||
target: 'http://localhost:3000',
|
// target: 'http://localhost:3000',
|
||||||
|
target: 'http://10.147.17.115:3000',
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
onProxyRes: (proxyRes, req, res) => {
|
onProxyRes: (proxyRes, req, res) => {
|
||||||
delete proxyRes.headers['x-frame-options']
|
delete proxyRes.headers['x-frame-options']
|
||||||
|
|||||||
Reference in New Issue
Block a user