CzRger преди 3 месеца
родител
ревизия
3938b75067
променени са 4 файла, в които са добавени 301 реда и са изтрити 71 реда
  1. BIN
      src/assets/images/model-icon-8.png
  2. BIN
      src/assets/images/model-icon-9.png
  3. 1 1
      src/components/SvgIcon/index.vue
  4. 300 70
      src/views/manage/knowledge/model-config.vue

BIN
src/assets/images/model-icon-8.png


BIN
src/assets/images/model-icon-9.png


+ 1 - 1
src/components/SvgIcon/index.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="svg-icon">
-    <svg aria-hidden="true" :style="`width: ${size}px;height: ${size}px;transform: rotate(${rotate}deg); margin-bottom: 1px;`">
+    <svg aria-hidden="true" :style="`width: ${size}px;height: ${size}px;transform: rotate(${rotate}deg);`">
       <use :xlink:href="symbolId" :fill="colorCpt" />
     </svg>
   </div>

+ 300 - 70
src/views/manage/knowledge/model-config.vue

@@ -1,80 +1,261 @@
 <template>
-  <div class="__czr-title_1 mb-[0.5rem]">索引方式</div>
-  <div class="w-full flex gap-[1rem]">
-    <div class="__hover flex-1 h-[8.38rem] rounded-[var(--czr-gap)] px-[1.5rem] py-[1rem] bg-[#ffffff]"
-         style="border: var(--czr-border); border-width: 0.13rem"
-         :class="{'index-method-active': state.indexMethod === 1}"
-         @click="state.indexMethod = 1">
-      <div class="flex items-center">
-        <img src="@/assets/images/model-icon-1.png" class="w-[3.25rem] h-[3.25rem] mr-[var(--czr-gap)]"/>
-        <div class="text-[#2E3238] text-[1.25rem] font-bold">高质量</div>
-        <img src="@/assets/images/model-icon-3.png" class="w-[2.88rem] h-[1.27rem]"/>
+  <template v-if="state.indexMethod.show">
+    <div class="__czr-title_1 mb-[0.5rem]">索引方式</div>
+    <div class="w-full flex gap-[1rem]">
+      <div class="__hover flex-1 h-[8.38rem] rounded-[var(--czr-gap)] px-[1.5rem] py-[1rem] bg-[#ffffff]"
+           style="border: var(--czr-border); border-width: 0.13rem"
+           :class="{'index-method-active': state.indexMethod.value === 1}"
+           @click="state.indexMethod.value = 1">
+        <div class="flex items-center">
+          <img src="@/assets/images/model-icon-1.png" class="w-[3.25rem] h-[3.25rem] mr-[var(--czr-gap)]"/>
+          <div class="text-[#2E3238] text-[1.25rem] font-bold">高质量</div>
+          <img src="@/assets/images/model-icon-3.png" class="w-[2.88rem] h-[1.27rem]"/>
+        </div>
+        <div class="text-[#606266] text-[0.88rem] mt-[0.5rem]" style="line-height: 1.3rem">调用嵌入模型来处理文档以实现更精确的检索,可以帮助大语言模型生成高质量的回答。</div>
       </div>
-      <div class="text-[#606266] text-[0.88rem] mt-[0.5rem]" style="line-height: 1.3rem">调用嵌入模型来处理文档以实现更精确的检索,可以帮助大语言模型生成高质量的回答。</div>
-    </div>
-    <div class="__hover flex-1 h-[8.38rem] rounded-[var(--czr-gap)] px-[1.5rem] py-[1rem] bg-[#ffffff]"
-         style="border: var(--czr-border); border-width: 0.13rem"
-         :class="{'index-method-active': state.indexMethod === 2}"
-         @click="state.indexMethod = 2">
-      <div class="flex items-center">
-        <img src="@/assets/images/model-icon-2.png" class="w-[3.25rem] h-[3.25rem] mr-[var(--czr-gap)]"/>
-        <div class="text-[#2E3238] text-[1.25rem] font-bold">经济</div>
+      <div class="__hover flex-1 h-[8.38rem] rounded-[var(--czr-gap)] px-[1.5rem] py-[1rem] bg-[#ffffff]"
+           style="border: var(--czr-border); border-width: 0.13rem"
+           :class="{'index-method-active': state.indexMethod.value === 2}"
+           @click="state.indexMethod.value = 2">
+        <div class="flex items-center">
+          <img src="@/assets/images/model-icon-2.png" class="w-[3.25rem] h-[3.25rem] mr-[var(--czr-gap)]"/>
+          <div class="text-[#2E3238] text-[1.25rem] font-bold">经济</div>
+        </div>
+        <div class="text-[#606266] text-[0.88rem] mt-[0.5rem]" style="line-height: 1.3rem">每个块使用 10 个关键词进行检索,不消耗 tokens,但会降低检索准确性。</div>
       </div>
-      <div class="text-[#606266] text-[0.88rem] mt-[0.5rem]" style="line-height: 1.3rem">每个块使用 10 个关键词进行检索,不消耗 tokens,但会降低检索准确性。</div>
     </div>
-  </div>
-  <div v-if="state.indexMethod === 1"
-       class="flex items-center gap-[0.5rem] w-full h-[2.5rem] px-[0.75rem] rounded-[0.25rem] text-[#666666] text-[0.8rem] mt-[var(--czr-gap)]"
-       style="border: var(--czr-border); border-color: var(--czr-warning-color); background-color: rgba(var(--czr-warning-color-rgb), 0.1)">
-    <SvgIcon name="czr_tip" color="var(--czr-warning-color)"/>使用高质量模式进行嵌入后,无法切换回经济模式。
-  </div>
-  <div class="__czr-title_1 mb-[0.5rem]">embedding模型</div>
-  <CzrFormColumn
-    :span="24"
-    label="模型类型"
-    v-model:param="state.modelType"
-    link="select"
-    :options="[]"
-    :clearable="false"
-  />
-  <div class="__czr-title_1">检索方式</div>
-  <div class="__hover w-full rounded-[var(--czr-gap)] mt-[1rem] bg-[#ffffff]"
-       style="border: var(--czr-border); border-width: 0.13rem"
-       :class="{'search-method-active': state.searchMethod === 1}"
-       @click="state.searchMethod = 1">
-    <div class="w-full h-full px-[1.5rem] py-[1rem]">
-      <div class="flex items-center">
-        <img src="@/assets/images/model-icon-4.png" class="w-[3.25rem] h-[3.25rem] mr-[var(--czr-gap)]"/>
-        <div class="text-[#2E3238] text-[1.25rem] font-bold">向量检索</div>
+    <div v-if="state.indexMethod.value === 1"
+         class="flex items-center gap-[0.5rem] w-full h-[2.5rem] px-[0.75rem] rounded-[0.25rem] text-[#666666] text-[0.8rem] mt-[var(--czr-gap)]"
+         style="border: var(--czr-border); border-color: var(--czr-warning-color); background-color: rgba(var(--czr-warning-color-rgb), 0.1)">
+      <SvgIcon name="czr_tip" color="var(--czr-warning-color)"/>使用高质量模式进行嵌入后,无法切换回经济模式。
+    </div>
+  </template>
+  <template v-if="state.embedding.show">
+    <div class="__czr-title_1 mb-[0.5rem]">Embedding 模型</div>
+    <CzrFormColumn
+      class="__czr-table-form-column"
+      :span="24"
+      label="模型类型"
+      v-model:param="state.embedding.value"
+      link="select"
+      :options="[]"
+      :clearable="false"
+    />
+  </template>
+  <template v-if="state.searchMethod.show">
+    <div class="__czr-title_1">检索方式</div>
+    <div class="w-full rounded-[var(--czr-gap)] mt-[1rem] bg-[#ffffff] cursor-pointer"
+         style="border: var(--czr-border); border-width: 0.13rem"
+         :class="{'search-method-active': state.searchMethod.value === SearchMethodType.Vector}"
+         @click="state.searchMethod.value = SearchMethodType.Vector">
+      <div class="w-full h-full px-[1.5rem] py-[1rem]">
+        <div class="flex items-center">
+          <img src="@/assets/images/model-icon-4.png" class="w-[3.25rem] h-[3.25rem] mr-[var(--czr-gap)]"/>
+          <div class="text-[#2E3238] text-[1.25rem] font-bold">向量检索</div>
+        </div>
+        <div class="text-[#606266] text-[0.88rem] mt-[0.5rem]" style="line-height: 1.3rem">通过生成查询嵌入并查询与其向量表示最相似的文本分段</div>
+        <template v-if="state.searchMethod.value === SearchMethodType.Vector">
+          <div class="flex flex-col gap-[0.5rem] bg-[#ffffff] rounded-[0.25rem] p-[var(--czr-gap)] text-[#2E3238] text-[1rem] font-bold mt-[1rem]">
+            <div class="flex items-center gap-[0.5rem]">
+              <el-switch size="small" v-model="state.searchMethod[SearchMethodType.Vector].isRerank"/>
+              Rerank 模型
+              <el-tooltip content="重排序模型将根据候选文档列表与用户问题语义匹配度进行重新排序,从而改进语义排序的结果。" placement="top">
+                <SvgIcon name="czr_tip" size="14"/>
+              </el-tooltip>
+            </div>
+            <template v-if="state.searchMethod[SearchMethodType.Vector].isRerank">
+              <CzrFormColumn
+                class="__czr-table-form-column"
+                :span="24"
+                label-width="0px"
+                v-model:param="state.searchMethod[SearchMethodType.Vector].rerank"
+                link="select"
+                :options="[
+                  {label: 'bga-reanskada-v2-sad-m3',value: 1}
+                ]"
+                :clearable="false"
+              />
+            </template>
+            <div class="flex gap-[1rem]">
+              <div class="flex-1">
+                <div class="flex items-center gap-[0.5rem] h-[1rem]">
+                  TOP K
+                  <el-tooltip content="用于筛选与用户问题相似度最高的文本片段。系统同时会根据选用模型上下文窗口大小动态调整分段数量。" placement="top">
+                    <SvgIcon name="czr_tip" size="14"/>
+                  </el-tooltip>
+                </div>
+                <div class="mt-[1rem]">
+                  <el-slider v-model="state.searchMethod[SearchMethodType.Vector].topK" show-input class="re-slider" :min="1" :max="10"/>
+                </div>
+              </div>
+              <div class="flex-1">
+                <div class="flex items-center gap-[0.5rem] h-[1rem]">
+                  <el-switch size="small" v-model="state.searchMethod[SearchMethodType.Vector].isScore"/>
+                  Score 阈值
+                  <el-tooltip content="重排序模型将根据候选文档列表与用户问题语义匹配度进行重新排序,从而改进语义排序的结果。" placement="top">
+                    <SvgIcon name="czr_tip" size="14"/>
+                  </el-tooltip>
+                </div>
+                <div class="mt-[1rem]">
+                  <el-slider v-model="state.searchMethod[SearchMethodType.Vector].score" show-input class="re-slider" :max="1" :min="0" :step="0.1" :disabled="!state.searchMethod[SearchMethodType.Vector].isScore"/>
+                </div>
+              </div>
+            </div>
+          </div>
+        </template>
       </div>
-      <div class="text-[#606266] text-[0.88rem] mt-[0.5rem]" style="line-height: 1.3rem">通过生成查询嵌入并查询与其向量表示最相似的文本分段</div>
     </div>
-  </div>
-  <div class="__hover w-full rounded-[var(--czr-gap)] mt-[1rem] bg-[#ffffff]"
-       style="border: var(--czr-border); border-width: 0.13rem"
-       :class="{'search-method-active': state.searchMethod === 2}"
-       @click="state.searchMethod = 2">
-    <div class="w-full h-full px-[1.5rem] py-[1rem]">
-      <div class="flex items-center">
-        <img src="@/assets/images/model-icon-5.png" class="w-[3.25rem] h-[3.25rem] mr-[var(--czr-gap)]"/>
-        <div class="text-[#2E3238] text-[1.25rem] font-bold">全文检索</div>
+    <div class="w-full rounded-[var(--czr-gap)] mt-[1rem] bg-[#ffffff] cursor-pointer"
+         style="border: var(--czr-border); border-width: 0.13rem"
+         :class="{'search-method-active': state.searchMethod.value === SearchMethodType.Global}"
+         @click="state.searchMethod.value = SearchMethodType.Global">
+      <div class="w-full h-full px-[1.5rem] py-[1rem]">
+        <div class="flex items-center">
+          <img src="@/assets/images/model-icon-5.png" class="w-[3.25rem] h-[3.25rem] mr-[var(--czr-gap)]"/>
+          <div class="text-[#2E3238] text-[1.25rem] font-bold">全文检索</div>
+        </div>
+        <div class="text-[#606266] text-[0.88rem] mt-[0.5rem]" style="line-height: 1.3rem">索引文档中的所有词汇,从而允许用户查询任意词汇,并返回包含这些词汇的文本片段</div>
+        <template v-if="state.searchMethod.value === SearchMethodType.Global">
+          <div class="flex flex-col gap-[0.5rem] bg-[#ffffff] rounded-[0.25rem] p-[var(--czr-gap)] text-[#2E3238] text-[1rem] font-bold mt-[1rem]">
+            <div class="flex items-center gap-[0.5rem]">
+              <el-switch size="small" v-model="state.searchMethod[SearchMethodType.Global].isRerank"/>
+              Rerank 模型
+              <el-tooltip content="用于筛选与用户问题相似度最高的文本片段。系统同时会根据选用模型上下文窗口大小动态调整分段数量。" placement="top">
+                <SvgIcon name="czr_tip" size="14"/>
+              </el-tooltip>
+            </div>
+            <template v-if="state.searchMethod[SearchMethodType.Global].isRerank">
+              <CzrFormColumn
+                class="__czr-table-form-column"
+                :span="24"
+                label-width="0px"
+                v-model:param="state.searchMethod[SearchMethodType.Global].rerank"
+                link="select"
+                :options="[
+                  {label: 'bga-reanskada-v2-sad-m3',value: 1}
+                ]"
+                :clearable="false"
+              />
+            </template>
+            <div class="flex gap-[1rem]">
+              <div class="flex-1">
+                <div class="flex items-center gap-[0.5rem] h-[1rem]">
+                  TOP K
+                  <el-tooltip content="用于筛选与用户问题相似度最高的文本片段。系统同时会根据选用模型上下文窗口大小动态调整分段数量。" placement="top">
+                    <SvgIcon name="czr_tip" size="14"/>
+                  </el-tooltip>
+                </div>
+                <div class="mt-[1rem]">
+                  <el-slider v-model="state.searchMethod[SearchMethodType.Global].topK" show-input class="re-slider" :min="1" :max="10"/>
+                </div>
+              </div>
+              <div class="flex-1" v-if="state.searchMethod[SearchMethodType.Global].isRerank">
+                <div class="flex items-center gap-[0.5rem] h-[1rem]">
+                  <el-switch size="small" v-model="state.searchMethod[SearchMethodType.Global].isScore"/>
+                  Score 阈值
+                  <el-tooltip content="用于设置文本片段筛选的相似度阈值。" placement="top">
+                    <SvgIcon name="czr_tip" size="14"/>
+                  </el-tooltip>
+                </div>
+                <div class="mt-[1rem]">
+                  <el-slider v-model="state.searchMethod[SearchMethodType.Global].score" show-input class="re-slider" :max="1" :min="0" :step="0.1" :disabled="!state.searchMethod[SearchMethodType.Global].isScore"/>
+                </div>
+              </div>
+            </div>
+          </div>
+        </template>
       </div>
-      <div class="text-[#606266] text-[0.88rem] mt-[0.5rem]" style="line-height: 1.3rem">索引文档中的所有词汇,从而允许用户查询任意词汇,并返回包含这些词汇的文本片段</div>
     </div>
-  </div>
-  <div class="__hover w-full rounded-[var(--czr-gap)] mt-[1rem] bg-[#ffffff]"
-       style="border: var(--czr-border); border-width: 0.13rem"
-       :class="{'search-method-active': state.searchMethod === 3}"
-       @click="state.searchMethod = 3">
-    <div class="w-full h-full px-[1.5rem] py-[1rem]">
-      <div class="flex items-center">
-        <img src="@/assets/images/model-icon-6.png" class="w-[3.25rem] h-[3.25rem] mr-[var(--czr-gap)]"/>
-        <div class="text-[#2E3238] text-[1.25rem] font-bold">混合检索</div>
-        <img src="@/assets/images/model-icon-3.png" class="w-[2.88rem] h-[1.27rem]"/>
+    <div class="w-full rounded-[var(--czr-gap)] mt-[1rem] bg-[#ffffff] cursor-pointer"
+         style="border: var(--czr-border); border-width: 0.13rem"
+         :class="{'search-method-active': state.searchMethod.value === SearchMethodType.Mix}"
+         @click="state.searchMethod.value = SearchMethodType.Mix">
+      <div class="w-full h-full px-[1.5rem] py-[1rem]">
+        <div class="flex items-center">
+          <img src="@/assets/images/model-icon-6.png" class="w-[3.25rem] h-[3.25rem] mr-[var(--czr-gap)]"/>
+          <div class="text-[#2E3238] text-[1.25rem] font-bold">混合检索</div>
+          <img src="@/assets/images/model-icon-3.png" class="w-[2.88rem] h-[1.27rem]"/>
+        </div>
+        <div class="text-[#606266] text-[0.88rem] mt-[0.5rem]" style="line-height: 1.3rem">同时执行全文检索和向量检索,并应用重排序步骤,从两类查询结果中选择匹配用户问题的最佳结果,用户可以选择设置权重或配置重新排序模型。</div>
+        <template v-if="state.searchMethod.value === SearchMethodType.Mix">
+          <div class="w-full flex gap-[1rem] mt-[1rem]">
+            <div class="__hover flex-1 h-[8.38rem] rounded-[var(--czr-gap)] px-[1.5rem] py-[1rem] bg-[#ffffff]"
+                 style="border: var(--czr-border); border-width: 0.13rem"
+                 :class="{'index-method-active': state.searchMethod[SearchMethodType.Mix].indexMethod === 1}"
+                 @click="state.searchMethod[SearchMethodType.Mix].indexMethod = 1">
+              <div class="flex items-center">
+                <img src="@/assets/images/model-icon-8.png" class="w-[3.25rem] h-[3.25rem] mr-[var(--czr-gap)]"/>
+                <div class="text-[#2E3238] text-[1.25rem] font-bold">权重设置</div>
+                <img src="@/assets/images/model-icon-3.png" class="w-[2.88rem] h-[1.27rem]"/>
+              </div>
+              <div class="text-[#606266] text-[0.88rem] mt-[0.5rem]" style="line-height: 1.3rem">通过调整分配的权重,重新排序策略确定是优先进行语义匹配还是关键字匹配。</div>
+            </div>
+            <div class="__hover flex-1 h-[8.38rem] rounded-[var(--czr-gap)] px-[1.5rem] py-[1rem] bg-[#ffffff]"
+                 style="border: var(--czr-border); border-width: 0.13rem"
+                 :class="{'index-method-active': state.searchMethod[SearchMethodType.Mix].indexMethod === 2}"
+                 @click="state.searchMethod[SearchMethodType.Mix].indexMethod = 2">
+              <div class="flex items-center">
+                <img src="@/assets/images/model-icon-9.png" class="w-[3.25rem] h-[3.25rem] mr-[var(--czr-gap)]"/>
+                <div class="text-[#2E3238] text-[1.25rem] font-bold">Rerank 模型</div>
+              </div>
+              <div class="text-[#606266] text-[0.88rem] mt-[0.5rem]" style="line-height: 1.3rem">重排序模型将根据候选文档列表与用户问题语义匹配度进行重新排序,从而改进语义排序的结果。</div>
+            </div>
+          </div>
+          <div class="flex flex-col gap-[0.5rem] bg-[#ffffff] rounded-[0.25rem] p-[var(--czr-gap)] text-[#2E3238] text-[1rem] font-bold mt-[1rem]">
+            <template v-if="state.searchMethod[SearchMethodType.Mix].indexMethod === 1">
+              <div>
+                <el-slider v-model="state.searchMethod[SearchMethodType.Mix].weight" :min="0" :max="1" :step="0.1" class="weight-slider"/>
+                <div class="flex justify-between">
+                  <div class="text-[var(--czr-main-color)]">语义 {{ state.searchMethod[SearchMethodType.Mix].weight }}</div>
+                  <div class="text-[var(--czr-success-color)]">{{ (1 - state.searchMethod[SearchMethodType.Mix].weight).toFixed(1) }} 关键词</div>
+                </div>
+              </div>
+            </template>
+            <template v-else-if="state.searchMethod[SearchMethodType.Mix].indexMethod === 2">
+              <CzrFormColumn
+                class="__czr-table-form-column"
+                :span="24"
+                label-width="0px"
+                v-model:param="state.searchMethod[SearchMethodType.Mix].rerank"
+                link="select"
+                :options="[
+                  {label: 'bga-reanskada-v2-sad-m3',value: 1}
+                ]"
+                :clearable="false"
+              />
+            </template>
+          </div>
+          <div class="flex flex-col gap-[0.5rem] bg-[#ffffff] rounded-[0.25rem] p-[var(--czr-gap)] text-[#2E3238] text-[1rem] font-bold mt-[1rem]">
+            <div class="flex gap-[1rem]">
+              <div class="flex-1">
+                <div class="flex items-center gap-[0.5rem] h-[1rem]">
+                  TOP K
+                  <el-tooltip content="用于筛选与用户问题相似度最高的文本片段。系统同时会根据选用模型上下文窗口大小动态调整分段数量。" placement="top">
+                    <SvgIcon name="czr_tip" size="14"/>
+                  </el-tooltip>
+                </div>
+                <div class="mt-[1rem]">
+                  <el-slider v-model="state.searchMethod[SearchMethodType.Mix].topK" show-input class="re-slider" :min="1" :max="10"/>
+                </div>
+              </div>
+              <div class="flex-1">
+                <div class="flex items-center gap-[0.5rem] h-[1rem]">
+                  <el-switch size="small" v-model="state.searchMethod[SearchMethodType.Mix].isScore"/>
+                  Score 阈值
+                  <el-tooltip content="用于设置文本片段筛选的相似度阈值。" placement="top">
+                    <SvgIcon name="czr_tip" size="14"/>
+                  </el-tooltip>
+                </div>
+                <div class="mt-[1rem]">
+                  <el-slider v-model="state.searchMethod[SearchMethodType.Mix].score" show-input class="re-slider" :max="1" :min="0" :step="0.1" :disabled="!state.searchMethod[SearchMethodType.Mix].isScore"/>
+                </div>
+              </div>
+            </div>
+          </div>
+        </template>
       </div>
-      <div class="text-[#606266] text-[0.88rem] mt-[0.5rem]" style="line-height: 1.3rem">同时执行全文检索和向量检索,并应用重排序步骤,从两类查询结果中选择匹配用户问题的最佳结果,用户可以选择设置权重或配置重新排序模型。</div>
     </div>
-  </div>
+  </template>
 </template>
 
 <script setup lang="ts">
@@ -85,10 +266,47 @@ const props = defineProps({
   transfer: <any>{}
 })
 const {proxy}: any = getCurrentInstance()
+enum SearchMethodType {
+  Vector = 'vector',
+  Global = 'global',
+  Mix = 'mix',
+}
 const state: any = reactive({
-  indexMethod: 1,
-  modelType: 1,
-  searchMethod: 1,
+  indexMethod: {
+    show: true,
+    value: 1
+  },
+  embedding: {
+    show: true,
+    value: 1
+  },
+  searchMethod: {
+    show: true,
+    value: SearchMethodType.Vector,
+    vector: {
+      isRerank: true,
+      rerank: '',
+      topK: 5,
+      isScore: true,
+      score: 0.5,
+    },
+    global: {
+      isRerank: true,
+      rerank: '',
+      topK: 5,
+      isScore: true,
+      score: 0.5,
+    },
+    mix: {
+      isRerank: true,
+      indexMethod: 1,
+      weight: 0.7,
+      rerank: '',
+      topK: 5,
+      isScore: true,
+      score: 0.5,
+    },
+  },
 })
 watch(() => props.transfer, (n) => {
   if (n) {
@@ -111,4 +329,16 @@ watch(() => props.transfer, (n) => {
   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>