| | |
| | | <script setup lang="ts"> |
| | | import type { AiKnowledgeSegmentApi } from '#/api/ai/knowledge/segment'; |
| | | |
| | | import { onMounted, reactive, ref } from 'vue'; |
| | | import { useRoute, useRouter } from 'vue-router'; |
| | | |
| | |
| | | import { getKnowledge } from '#/api/ai/knowledge/knowledge'; |
| | | import { searchKnowledgeSegment } from '#/api/ai/knowledge/segment'; |
| | | |
| | | type RetrievalSegment = AiKnowledgeSegmentApi.KnowledgeSegment & { |
| | | expanded?: boolean; |
| | | }; |
| | | |
| | | /** 知识库文档召回测试 */ |
| | | defineOptions({ name: 'KnowledgeDocumentRetrieval' }); |
| | | |
| | | const route = useRoute(); |
| | | const router = useRouter(); |
| | | |
| | | const loading = ref(false); // 加载状态 |
| | | const segments = ref<any[]>([]); // 召回结果 |
| | | const queryParams = reactive({ |
| | | const loading = ref(false); |
| | | const segments = ref<RetrievalSegment[]>([]); |
| | | const queryParams = reactive<{ |
| | | id: number | undefined; |
| | | content: string; |
| | | topK: number; |
| | | similarityThreshold: number; |
| | | }>({ |
| | | id: undefined, |
| | | content: '', |
| | | topK: 10, |
| | |
| | | message.warning('请输入查询文本'); |
| | | return; |
| | | } |
| | | if (queryParams.id == null) return; |
| | | |
| | | loading.value = true; |
| | | segments.value = []; |
| | |
| | | topK: queryParams.topK, |
| | | similarityThreshold: queryParams.similarityThreshold, |
| | | }); |
| | | segments.value = data || []; |
| | | segments.value = (data || []) as RetrievalSegment[]; |
| | | } finally { |
| | | loading.value = false; |
| | | } |
| | | } |
| | | |
| | | /** 切换段落展开状态 */ |
| | | function toggleExpand(segment: any) { |
| | | function toggleExpand(segment: RetrievalSegment) { |
| | | segment.expanded = !segment.expanded; |
| | | } |
| | | |
| | | /** 获取相似度分数的样式类名 */ |
| | | function getScoreClass(score: number) { |
| | | if (score > 0.8) return 'bg-green-50 text-green-600'; |
| | | if (score >= 0.6) return 'bg-yellow-50 text-yellow-600'; |
| | | return 'bg-gray-100 text-gray-400'; |
| | | } |
| | | |
| | | /** 获取知识库配置信息 */ |
| | |
| | | queryParams.similarityThreshold = |
| | | knowledge.similarityThreshold || queryParams.similarityThreshold; |
| | | } |
| | | } catch {} |
| | | } catch { |
| | | // 获取知识库配置失败,使用默认值 |
| | | } |
| | | } |
| | | |
| | | /** 初始化 */ |
| | | onMounted(() => { |
| | | // 如果知识库 ID 不存在,显示错误提示并关闭页面 |
| | | if (!route.query.id) { |
| | | message.error('知识库 ID 不存在,无法进行召回测试'); |
| | | router.back(); |
| | | return; |
| | | } |
| | | queryParams.id = route.query.id as any; |
| | | |
| | | // 获取知识库信息并设置默认值 |
| | | getKnowledgeInfo(queryParams.id as any); |
| | | const id = Number(route.query.id); |
| | | queryParams.id = id; |
| | | getKnowledgeInfo(id); |
| | | }); |
| | | </script> |
| | | <template> |
| | | <Page auto-content-height> |
| | | <div class="mb-2"> |
| | | <a-button type="default" @click="router.back()"> |
| | | 返回上一页 |
| | | </a-button> |
| | | </div> |
| | | <div class="flex w-full gap-4"> |
| | | <Card class="w-3/4 flex-1"> |
| | | <div class="mb-15"> |
| | |
| | | placeholder="请输入文本" |
| | | /> |
| | | <div class="absolute bottom-2 right-2 text-sm text-gray-400"> |
| | | {{ queryParams.content?.length }} / 200 |
| | | {{ queryParams.content?.length || 0 }} 字符 |
| | | </div> |
| | | </div> |
| | | <div class="m-2 flex items-center"> |
| | |
| | | {{ segment.tokens }} Token |
| | | </span> |
| | | <span |
| | | class="whitespace-nowrap rounded-full bg-blue-50 px-2 py-1 text-sm text-blue-500" |
| | | class="whitespace-nowrap rounded-full px-2 py-1 text-sm" |
| | | :class="getScoreClass(segment.score ?? 0)" |
| | | > |
| | | score: {{ segment.score }} |
| | | score: {{ segment.score?.toFixed(4) }} |
| | | </span> |
| | | </div> |
| | | <div |