1
This commit is contained in:
@@ -1,9 +0,0 @@
|
||||
import request from './request.js'
|
||||
|
||||
export function getSettings() {
|
||||
return request.get('/system-config/settings')
|
||||
}
|
||||
|
||||
export function saveSettings(data) {
|
||||
return request.post('/system-config/save-settings', data)
|
||||
}
|
||||
@@ -49,22 +49,22 @@
|
||||
<el-row :gutter="12">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="分块大小">
|
||||
<el-input-number v-model="form.chunk_size" :min="50" :max="5000" :step="50" style="width: 100%" />
|
||||
<div class="ds-tip">每块最大字数。系统自动组合分块策略:优先识别文档结构(条文/章节/编号等)按结构切分,无结构时依次按标题感知、语义、递归切分</div>
|
||||
<el-input-number v-model="form.chunk_size" :min="0" :max="5000" :step="50" style="width: 100%" />
|
||||
<div class="ds-tip">每块最大字数,0=使用 config.yml 全局默认。系统自动组合分块策略:优先识别文档结构(条文/章节/编号等)按结构切分,无结构时依次按标题感知、语义、递归切分</div>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="重叠字数">
|
||||
<el-input-number v-model="form.chunk_overlap" :min="0" :max="500" :step="10" style="width: 100%" />
|
||||
<div class="ds-tip">相邻分块间的重叠字数,用于保持上下文连贯(语义切分路径自动忽略)</div>
|
||||
<el-input-number v-model="form.chunk_overlap" :min="-1" :max="500" :step="10" style="width: 100%" />
|
||||
<div class="ds-tip">相邻分块间的重叠字数,-1=使用 config.yml 全局默认,0=不重叠(语义切分路径自动忽略)</div>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="12">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="智能体轮次">
|
||||
<el-input-number v-model="form.react_rounds" :min="0" :max="10" :step="1" style="width: 100%" />
|
||||
<div class="ds-tip">0=关闭(单次检索问答);1~10=启用 ReAct 智能体模式,模型可自主多次调用检索工具,此为轮次上限</div>
|
||||
<el-input-number v-model="form.react_rounds" :min="-1" :max="10" :step="1" style="width: 100%" />
|
||||
<div class="ds-tip">-1=使用 config.yml 全局默认;0=关闭(单次检索问答);1~10=启用 ReAct 智能体模式,模型可自主多次调用检索工具,此为轮次上限</div>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
@@ -106,7 +106,6 @@ import { onMounted, ref } from 'vue'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { listDatasets, saveDataset, deleteDataset } from '../api/dataset.js'
|
||||
import { listModelConfigs } from '../api/model_config.js'
|
||||
import { getSettings } from '../api/settings.js'
|
||||
|
||||
// 把识别出的结构正则转成可读名称(第[一二三四五六七八九十百千]+条 → 条文)
|
||||
function humanizePattern(p) {
|
||||
@@ -123,25 +122,16 @@ function humanizePattern(p) {
|
||||
|
||||
const datasets = ref([])
|
||||
const embedders = ref([])
|
||||
const defaults = ref({ chunk_size: 800, chunk_overlap: 150, react_rounds: 0, vec_top_k: 0, fts_top_k: 0, rerank_top_k: 0, recall_top_k: 0 })
|
||||
const loading = ref(false)
|
||||
const saving = ref(false)
|
||||
const dialogVisible = ref(false)
|
||||
const editing = ref(false)
|
||||
let editingRowCfgId = 0
|
||||
let editingRowChunk = { chunk_size: 0, chunk_overlap: 0 }
|
||||
const form = ref({ id: 0, name: '', description: '', embedding_cfg_id: 0, chunk_size: 800, chunk_overlap: 150, react_rounds: 0, vec_top_k: 0, fts_top_k: 0, rerank_top_k: 0, recall_top_k: 0 })
|
||||
const form = ref({ id: 0, name: '', description: '', embedding_cfg_id: 0, chunk_size: 0, chunk_overlap: -1, react_rounds: -1, vec_top_k: 0, fts_top_k: 0, rerank_top_k: 0, recall_top_k: 0 })
|
||||
|
||||
onMounted(async () => {
|
||||
await load()
|
||||
try {
|
||||
const s = await getSettings()
|
||||
if (s) {
|
||||
defaults.value.chunk_size = s.chunk_size || 800
|
||||
defaults.value.chunk_overlap = s.chunk_overlap ?? 150
|
||||
defaults.value.react_rounds = s.react_rounds ?? 0
|
||||
}
|
||||
} catch { /* 忽略 */ }
|
||||
try {
|
||||
const m = await listModelConfigs('embedding')
|
||||
if (m && m.list) embedders.value = m.list
|
||||
@@ -167,9 +157,9 @@ function openCreate() {
|
||||
editing.value = false
|
||||
editingRowCfgId = 0
|
||||
editingRowChunk = { chunk_size: 0, chunk_overlap: 0 }
|
||||
// 默认选中默认向量模型,其次第一个;分块大小/重叠/智能体轮次带出全局设置值
|
||||
// 默认选中默认向量模型,其次第一个;分块大小/重叠/智能体轮次传 0/-1 使用 config.yml 全局默认
|
||||
const def = embedders.value.find(x => x.is_default === 1) || embedders.value[0]
|
||||
form.value = { id: 0, name: '', description: '', embedding_cfg_id: def?.id || 0, chunk_size: defaults.value.chunk_size, chunk_overlap: defaults.value.chunk_overlap, react_rounds: defaults.value.react_rounds, vec_top_k: defaults.value.vec_top_k, fts_top_k: defaults.value.fts_top_k, rerank_top_k: defaults.value.rerank_top_k, recall_top_k: defaults.value.recall_top_k }
|
||||
form.value = { id: 0, name: '', description: '', embedding_cfg_id: def?.id || 0, chunk_size: 0, chunk_overlap: -1, react_rounds: -1, vec_top_k: 0, fts_top_k: 0, rerank_top_k: 0, recall_top_k: 0 }
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
|
||||
@@ -1,20 +1,5 @@
|
||||
<template>
|
||||
<div class="settings-page">
|
||||
<div class="block-card">
|
||||
<div class="block-title">分块默认值</div>
|
||||
<div class="block-tip">新建数据集时自动带出,单个数据集仍可在表单中修改</div>
|
||||
<div class="block-row">
|
||||
<span class="field-label">分块大小</span>
|
||||
<el-input-number v-model="chunkForm.chunk_size" :min="50" :max="5000" :step="50" />
|
||||
<span class="field-label">重叠字数</span>
|
||||
<el-input-number v-model="chunkForm.chunk_overlap" :min="0" :max="500" :step="10" />
|
||||
<span class="field-label">智能体轮次</span>
|
||||
<el-input-number v-model="chunkForm.react_rounds" :min="0" :max="10" :step="1" />
|
||||
<el-button type="primary" :loading="chunkSaving" @click="saveChunkDefaults">保存</el-button>
|
||||
</div>
|
||||
<div class="block-tip" style="margin-top: 6px; margin-bottom: 0;">智能体轮次:0=关闭(单次检索问答);1~10=启用 ReAct 智能体模式,模型自主调用检索工具,此为轮次上限。新建数据集时自动带出。</div>
|
||||
</div>
|
||||
|
||||
<div class="section-head">
|
||||
<el-radio-group v-model="modelType" @change="loadModels">
|
||||
<el-radio-button value="chat">对话模型</el-radio-button>
|
||||
@@ -80,33 +65,9 @@
|
||||
import { onMounted, ref } from 'vue'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { listModelConfigs, saveModelConfig, deleteModelConfig, testModelConfig, setDefaultModelConfig } from '../api/model_config.js'
|
||||
import { getSettings, saveSettings } from '../api/settings.js'
|
||||
|
||||
const modelType = ref('chat')
|
||||
|
||||
const chunkForm = ref({ chunk_size: 800, chunk_overlap: 150, react_rounds: 0 })
|
||||
const chunkSaving = ref(false)
|
||||
|
||||
async function loadChunkDefaults() {
|
||||
try {
|
||||
const s = await getSettings()
|
||||
if (s) {
|
||||
chunkForm.value.chunk_size = s.chunk_size || 800
|
||||
chunkForm.value.chunk_overlap = s.chunk_overlap ?? 150
|
||||
chunkForm.value.react_rounds = s.react_rounds ?? 0
|
||||
}
|
||||
} catch { /* 忽略 */ }
|
||||
}
|
||||
|
||||
async function saveChunkDefaults() {
|
||||
chunkSaving.value = true
|
||||
try {
|
||||
await saveSettings(chunkForm.value)
|
||||
ElMessage.success('分块默认值已保存')
|
||||
} finally {
|
||||
chunkSaving.value = false
|
||||
}
|
||||
}
|
||||
const models = ref([])
|
||||
const allModels = ref([])
|
||||
const modelLoading = ref(false)
|
||||
@@ -118,7 +79,6 @@ const modelForm = ref({ id: 0, name: '', model_type: 'chat', model_name: '', end
|
||||
|
||||
onMounted(async () => {
|
||||
await loadModels()
|
||||
await loadChunkDefaults()
|
||||
try { const all = await listModelConfigs(''); if (all && all.list) allModels.value = all.list } catch { /* 忽略 */ }
|
||||
})
|
||||
|
||||
@@ -221,28 +181,4 @@ async function test(row) {
|
||||
align-items: center;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.block-card {
|
||||
border: 1px solid #e4e7ed;
|
||||
border-radius: 6px;
|
||||
padding: 14px 16px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.block-title {
|
||||
font-weight: 600;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.block-tip {
|
||||
font-size: 12px;
|
||||
color: #909399;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.block-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
.field-label {
|
||||
color: #606266;
|
||||
font-size: 14px;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user