mirror of
http://112.124.100.131/ebiz-ai/ebiz-ai-knowledge-manage.git
synced 2025-12-10 03:16:49 +08:00
feat(knowledge): 实现知识库命中测试功能
- 新增 hitTest 函数以调用命中测试接口 - 创建 HitTest 组件以展示命中测试结果 - 在知识库详情页面添加命中测试按钮和相关功能 - 优化知识库详情页面布局和样式
This commit is contained in:
@@ -33,6 +33,16 @@ export function datasetCreate(data) {
|
|||||||
data
|
data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 命中测试
|
||||||
|
export function hitTest(data) {
|
||||||
|
return request({
|
||||||
|
url: getUrl('/datasetsEx/hit/test'),
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// 知识库删除
|
// 知识库删除
|
||||||
export function datasetDelete(data) {
|
export function datasetDelete(data) {
|
||||||
return request({
|
return request({
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ export default {
|
|||||||
},
|
},
|
||||||
handleClickAgent(agent) {
|
handleClickAgent(agent) {
|
||||||
this.agentConfig.agent = agent
|
this.agentConfig.agent = agent
|
||||||
this.agentConfig.title = '智能体详情'
|
this.agentConfig.title = agent.name + ' - 智能体详情'
|
||||||
this.agentConfig.visible = true
|
this.agentConfig.visible = true
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -152,7 +152,6 @@ export default {
|
|||||||
<div class="folder-content">
|
<div class="folder-content">
|
||||||
<div class="folder">
|
<div class="folder">
|
||||||
<!--listItem.name.获取字符串第一个-->
|
<!--listItem.name.获取字符串第一个-->
|
||||||
|
|
||||||
{{ listItem.imageId ? listItem.imageId : listItem.name[0] }}
|
{{ listItem.imageId ? listItem.imageId : listItem.name[0] }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -204,6 +203,7 @@ export default {
|
|||||||
</r-dialog>
|
</r-dialog>
|
||||||
|
|
||||||
<el-drawer
|
<el-drawer
|
||||||
|
v-if="agentConfig.visible"
|
||||||
:visible.sync="agentConfig.visible"
|
:visible.sync="agentConfig.visible"
|
||||||
:title="agentConfig.title"
|
:title="agentConfig.title"
|
||||||
size="90%"
|
size="90%"
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
<script>
|
<script>
|
||||||
|
import { hitTest } from '@/api/generatedApi'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'hitTest',
|
name: 'hitTest',
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
datasetId: void 0,
|
||||||
paramsConfig: {
|
paramsConfig: {
|
||||||
visible: false,
|
visible: false,
|
||||||
searchMode: 'vector', // 默认选择向量检索
|
searchMode: 'vector', // 默认选择向量检索
|
||||||
@@ -11,96 +14,33 @@ export default {
|
|||||||
},
|
},
|
||||||
inputMessage: '',
|
inputMessage: '',
|
||||||
loading: false,
|
loading: false,
|
||||||
messages: [
|
messages: []
|
||||||
{
|
|
||||||
id: 1,
|
|
||||||
type: 'question',
|
|
||||||
content: '黄金运用方式有哪些?',
|
|
||||||
time: new Date()
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 2,
|
|
||||||
type: 'answer',
|
|
||||||
content: '根据您的问题,我找到了以下相关信息:',
|
|
||||||
references: [
|
|
||||||
{
|
|
||||||
id: 1,
|
|
||||||
title: '-',
|
|
||||||
content:
|
|
||||||
'黄金可以作为投资者的资产配置:(1)把黄金作为储备资产的投资者;(2)被保险人投资在黄金的抵押品或非标资产债券的担保;(3)或者是投资者的避险资产。',
|
|
||||||
score: 0.709,
|
|
||||||
file: '北京人寿的准备金(样表版)_有关项.pdf'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 2,
|
|
||||||
title: '新增分说明一下',
|
|
||||||
content: '保险责任',
|
|
||||||
score: 0.705,
|
|
||||||
file: 'Sheet1'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 3,
|
|
||||||
title: '北京人寿承诺服务各项指标',
|
|
||||||
content:
|
|
||||||
'第二代保人寿保险营业执照人及行政管理人天津后勤保障处;5.第三代保人寿保险公司承诺为公司客户方案服力及运营提供客户服务力;6...',
|
|
||||||
score: 0.703,
|
|
||||||
file: '北京人寿承诺服务各项指标(有效版)102026.pdf'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 4,
|
|
||||||
title: '-',
|
|
||||||
content: '# 黄金的分:年金',
|
|
||||||
score: 0.7,
|
|
||||||
file: 'loma.md'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 5,
|
|
||||||
title: '第12讲年金 152',
|
|
||||||
content: '一、年金基础 153',
|
|
||||||
score: 0.698,
|
|
||||||
file: 'loma.md'
|
|
||||||
}
|
|
||||||
],
|
|
||||||
time: new Date()
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
created() {
|
||||||
|
// 从 路由参数中获取datasetId
|
||||||
|
this.datasetId = this.$route.query.datasetId
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
sendMessage() {
|
sendMessage() {
|
||||||
if (!this.inputMessage.trim()) return
|
if (!this.inputMessage.trim()) return
|
||||||
|
|
||||||
// 添加用户问题到消息列表
|
// 显示骨架屏
|
||||||
this.messages.push({
|
|
||||||
id: this.messages.length + 1,
|
|
||||||
type: 'question',
|
|
||||||
content: this.inputMessage,
|
|
||||||
time: new Date()
|
|
||||||
})
|
|
||||||
|
|
||||||
// 清空输入框
|
|
||||||
this.inputMessage = ''
|
|
||||||
|
|
||||||
// 模拟加载状态
|
|
||||||
this.loading = true
|
this.loading = true
|
||||||
|
|
||||||
// 模拟API请求延迟
|
// 发送请求
|
||||||
setTimeout(() => {
|
hitTest({
|
||||||
|
datasetsId: this.datasetId,
|
||||||
|
query: this.inputMessage
|
||||||
|
}).then(res => {
|
||||||
|
const { content } = res.content
|
||||||
|
|
||||||
|
this.messages.push(content)
|
||||||
|
|
||||||
this.loading = false
|
this.loading = false
|
||||||
// 这里可以添加实际的API调用逻辑
|
})
|
||||||
}, 1000)
|
// 清空输入框
|
||||||
},
|
this.inputMessage = ''
|
||||||
getTableData() {
|
|
||||||
// 根据之前的记忆,修复getTableData函数,确保正确返回Promise
|
|
||||||
return this.$api
|
|
||||||
.getDocByPage(this.queryParams)
|
|
||||||
.then(res => {
|
|
||||||
return res.data
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
console.error('获取数据失败:', err)
|
|
||||||
return []
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
formatScore(score) {
|
formatScore(score) {
|
||||||
return score.toFixed(3)
|
return score.toFixed(3)
|
||||||
@@ -117,62 +57,50 @@ export default {
|
|||||||
<el-image alt="当前会话尚无记录"></el-image>
|
<el-image alt="当前会话尚无记录"></el-image>
|
||||||
<p>这里会显示命中测试的记录</p>
|
<p>这里会显示命中测试的记录</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="messages" v-else>
|
<div
|
||||||
<div
|
class="messages mb10"
|
||||||
v-for="message in messages"
|
v-else
|
||||||
:key="message.id"
|
v-for="content in messages"
|
||||||
class="message-item"
|
:key="content"
|
||||||
:class="message.type"
|
>
|
||||||
>
|
<!-- 对话区域 -->
|
||||||
<!-- 问题消息 -->
|
<el-card>
|
||||||
<div v-if="message.type === 'question'" class="question-message">
|
<!-- 头像 和 会话内容 -->
|
||||||
<div class="message-header">
|
<div class="flex align-items-c mb10">
|
||||||
<el-avatar size="small" icon="el-icon-user"></el-avatar>
|
<el-avatar :size="40" class="user-avatar" shape="square">
|
||||||
<div class="message-info">
|
admin
|
||||||
<div class="message-title">用户提问</div>
|
</el-avatar>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="message-content">{{ message.content }}</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 回答消息 -->
|
<div style="margin: 0 10px;">
|
||||||
<div v-else-if="message.type === 'answer'" class="answer-message">
|
根据您的问题,我们为你提供以下建议
|
||||||
<div class="message-header">
|
|
||||||
<el-avatar size="small" icon="el-icon-s-custom"></el-avatar>
|
|
||||||
<div class="message-info">
|
|
||||||
<div class="message-title">AI 回复</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="message-content">{{ message.content }}</div>
|
|
||||||
|
|
||||||
<!-- 引用内容 -->
|
|
||||||
<div
|
|
||||||
class="references"
|
|
||||||
v-if="message.references && message.references.length"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
v-for="(ref, index) in message.references"
|
|
||||||
:key="index"
|
|
||||||
class="reference-item"
|
|
||||||
>
|
|
||||||
<div class="reference-header">
|
|
||||||
<div class="reference-index">{{ index + 1 }}</div>
|
|
||||||
<div class="reference-title">{{ ref.title }}</div>
|
|
||||||
<div class="reference-score">
|
|
||||||
{{ formatScore(ref.score) }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="reference-content">{{ ref.content }}</div>
|
|
||||||
<div class="reference-footer">
|
|
||||||
<el-tag size="mini" type="info">
|
|
||||||
<i class="el-icon-document"></i> {{ ref.file }}
|
|
||||||
</el-tag>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
|
<el-card
|
||||||
|
v-for="(contentItem, index) in content"
|
||||||
|
:key="index"
|
||||||
|
shadow="hover"
|
||||||
|
body-style="padding: 10px;backgroundColor: f2f2f2"
|
||||||
|
class="mb10"
|
||||||
|
>
|
||||||
|
<div class="flex justify-content-b">
|
||||||
|
<!-- 内容详情 -->
|
||||||
|
<section>
|
||||||
|
<p class="mb10">{{ contentItem.segment.content }}</p>
|
||||||
|
<el-tag
|
||||||
|
type="success"
|
||||||
|
size="small"
|
||||||
|
v-for="(keyword, index) in contentItem.segment.keywords"
|
||||||
|
:key="index"
|
||||||
|
>
|
||||||
|
{{ keyword }}
|
||||||
|
</el-tag>
|
||||||
|
</section>
|
||||||
|
<!-- score -->
|
||||||
|
<span class="score">{{ contentItem.score.toFixed(3) }}</span>
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
</el-card>
|
||||||
<!-- 加载状态 -->
|
<!-- 加载状态 -->
|
||||||
<div v-if="loading" class="loading-message">
|
<div v-if="loading" class="loading-message">
|
||||||
<el-skeleton style="width: 100%" animated>
|
<el-skeleton style="width: 100%" animated>
|
||||||
@@ -205,8 +133,8 @@ export default {
|
|||||||
:class="{ active: paramsConfig.searchMode === 'vector' }"
|
:class="{ active: paramsConfig.searchMode === 'vector' }"
|
||||||
>
|
>
|
||||||
<el-radio v-model="paramsConfig.searchMode" label="vector"
|
<el-radio v-model="paramsConfig.searchMode" label="vector"
|
||||||
>向量检索</el-radio
|
>向量检索
|
||||||
>
|
</el-radio>
|
||||||
<p class="option-desc">
|
<p class="option-desc">
|
||||||
向量检索是一种基于向量相似度的检索方式,适用于知识库中的大数据量场景。
|
向量检索是一种基于向量相似度的检索方式,适用于知识库中的大数据量场景。
|
||||||
</p>
|
</p>
|
||||||
@@ -217,8 +145,8 @@ export default {
|
|||||||
:class="{ active: paramsConfig.searchMode === 'fulltext' }"
|
:class="{ active: paramsConfig.searchMode === 'fulltext' }"
|
||||||
>
|
>
|
||||||
<el-radio v-model="paramsConfig.searchMode" label="fulltext"
|
<el-radio v-model="paramsConfig.searchMode" label="fulltext"
|
||||||
>全文检索</el-radio
|
>全文检索
|
||||||
>
|
</el-radio>
|
||||||
<p class="option-desc">
|
<p class="option-desc">
|
||||||
全文检索是一种基于文本相似度的检索方式,适用于知识库中的小数据量场景。
|
全文检索是一种基于文本相似度的检索方式,适用于知识库中的小数据量场景。
|
||||||
</p>
|
</p>
|
||||||
@@ -229,8 +157,8 @@ export default {
|
|||||||
:class="{ active: paramsConfig.searchMode === 'hybrid' }"
|
:class="{ active: paramsConfig.searchMode === 'hybrid' }"
|
||||||
>
|
>
|
||||||
<el-radio v-model="paramsConfig.searchMode" label="hybrid"
|
<el-radio v-model="paramsConfig.searchMode" label="hybrid"
|
||||||
>混合检索</el-radio
|
>混合检索
|
||||||
>
|
</el-radio>
|
||||||
<p class="option-desc">
|
<p class="option-desc">
|
||||||
混合检索是一种基于向量和文本相似度的检索方式,适用于知识库中的中等数据量场景。
|
混合检索是一种基于向量和文本相似度的检索方式,适用于知识库中的中等数据量场景。
|
||||||
</p>
|
</p>
|
||||||
@@ -245,7 +173,6 @@ export default {
|
|||||||
:precision="3"
|
:precision="3"
|
||||||
:step="0.001"
|
:step="0.001"
|
||||||
:min="0"
|
:min="0"
|
||||||
:max="1"
|
|
||||||
size="small"
|
size="small"
|
||||||
controls-position="right"
|
controls-position="right"
|
||||||
></el-input-number>
|
></el-input-number>
|
||||||
@@ -265,19 +192,23 @@ export default {
|
|||||||
|
|
||||||
<div class="action-buttons">
|
<div class="action-buttons">
|
||||||
<el-button size="small" @click="paramsConfig.visible = false"
|
<el-button size="small" @click="paramsConfig.visible = false"
|
||||||
>取消</el-button
|
>取消
|
||||||
>
|
</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
type="primary"
|
type="primary"
|
||||||
size="small"
|
size="small"
|
||||||
@click="paramsConfig.visible = false"
|
@click="paramsConfig.visible = false"
|
||||||
>确定</el-button
|
>确定
|
||||||
>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<el-button icon="el-icon-setting" size="small" slot="reference"
|
<el-button
|
||||||
>参数设置</el-button
|
icon="el-icon-setting"
|
||||||
>
|
size="small"
|
||||||
|
slot="reference"
|
||||||
|
v-if="false"
|
||||||
|
>参数设置
|
||||||
|
</el-button>
|
||||||
</el-popover>
|
</el-popover>
|
||||||
|
|
||||||
<el-input
|
<el-input
|
||||||
|
|||||||
@@ -46,38 +46,19 @@
|
|||||||
|
|
||||||
<div>
|
<div>
|
||||||
<!-- <el-button type="primary" size="medium" class="normal-button" @click="jumpEditKnowledge">修改知识库</el-button>-->
|
<!-- <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" icon="el-icon-plus" class="primary-button"
|
||||||
|
@click="jumpAddKnowledge">上传知识
|
||||||
|
</el-button>
|
||||||
|
<el-button type="primary" icon="el-icon-s-promotion" size="medium" class="line-button"
|
||||||
|
@click="handleHitTestClick">命中测试
|
||||||
|
</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
type="primary"
|
type="primary" icon="el-icon-edit-outline" size="medium" class="line-button"
|
||||||
size="medium"
|
@click="handleMetaData">元数据
|
||||||
icon="el-icon-edit-outline"
|
</el-button>
|
||||||
class="primary-button"
|
|
||||||
@click="jumpEditKnowledge"
|
|
||||||
>修改知识库</el-button
|
|
||||||
>
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
size="medium"
|
|
||||||
icon="el-icon-plus"
|
|
||||||
class="primary-button"
|
|
||||||
@click="jumpAddKnowledge"
|
|
||||||
>上传知识</el-button
|
|
||||||
>
|
|
||||||
<!-- <el-button-->
|
|
||||||
<!-- type="primary"-->
|
|
||||||
<!-- icon="el-icon-s-promotion"-->
|
|
||||||
<!-- size="medium"-->
|
|
||||||
<!-- class="line-button"-->
|
|
||||||
<!-- @click="handleHitTestClick"-->
|
|
||||||
<!-- >命中测试</el-button-->
|
|
||||||
<!-- >-->
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
icon="el-icon-edit-outline"
|
|
||||||
size="medium"
|
|
||||||
class="line-button"
|
|
||||||
@click="handleMetaData"
|
|
||||||
>元数据</el-button
|
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt20 card-body">
|
<div class="mt20 card-body">
|
||||||
@@ -195,11 +176,7 @@
|
|||||||
</el-drawer>
|
</el-drawer>
|
||||||
|
|
||||||
<!--元数据-->
|
<!--元数据-->
|
||||||
<el-drawer
|
<el-drawer :title="metaDataDrawer.title" :visible.sync="metaDataDrawer.visible" size="30%">
|
||||||
:title="metaDataDrawer.title"
|
|
||||||
:visible.sync="metaDataDrawer.visible"
|
|
||||||
size="30%"
|
|
||||||
>
|
|
||||||
<meta-data ref="metaData" :datasetId="$route.query.datasetId"></meta-data>
|
<meta-data ref="metaData" :datasetId="$route.query.datasetId"></meta-data>
|
||||||
</el-drawer>
|
</el-drawer>
|
||||||
</div>
|
</div>
|
||||||
@@ -212,7 +189,7 @@ import {
|
|||||||
datasetsExPages,
|
datasetsExPages,
|
||||||
datasetUpdate,
|
datasetUpdate,
|
||||||
getDatasetById
|
getDatasetById
|
||||||
} from '@/api/generatedApi/index'
|
} from '@/api/generatedApi'
|
||||||
import { getUserList } from '@/api/generatedApi/system'
|
import { getUserList } from '@/api/generatedApi/system'
|
||||||
import {
|
import {
|
||||||
documentSourceOptions,
|
documentSourceOptions,
|
||||||
|
|||||||
Reference in New Issue
Block a user