feat: route fixed information chats by model

This commit is contained in:
2026-07-31 17:42:25 +08:00
parent da313f88ed
commit 85a6da5949
15 changed files with 607 additions and 57 deletions

View File

@@ -310,6 +310,7 @@ function modelSceneLabel(scene: string) {
return ({
background_report: "周期报告",
background_summary: "摘要沉淀",
fixed_info: "固定信息问答",
knowledge_grounded: "知识问答",
general_chat: "通用对话",
} as Record<string, string>)[scene] || scene || "未分类";
@@ -1459,11 +1460,14 @@ function formatRecordDateTime(value: string, boundary: "start" | "end") {
<el-input v-model="modelForm.usageScenarios" placeholder="例如:正式对话、摘要、固定信息、报告批处理" />
</el-form-item>
<el-form-item label="可用能力">
<div class="entitlement-capabilities">
<el-checkbox v-model="modelForm.allowFixedInfo" :true-value="1" :false-value="0">固定信息</el-checkbox>
<el-checkbox v-model="modelForm.allowDeepChat" :true-value="1" :false-value="0">深度对话</el-checkbox>
<el-checkbox v-model="modelForm.allowSummary" :true-value="1" :false-value="0">摘要沉淀</el-checkbox>
<el-checkbox v-model="modelForm.allowReport" :true-value="1" :false-value="0">周期报告</el-checkbox>
<div>
<div class="entitlement-capabilities">
<el-checkbox v-model="modelForm.allowFixedInfo" :true-value="1" :false-value="0">固定信息</el-checkbox>
<el-checkbox v-model="modelForm.allowDeepChat" :true-value="1" :false-value="0">深度对话</el-checkbox>
<el-checkbox v-model="modelForm.allowSummary" :true-value="1" :false-value="0">摘要沉淀</el-checkbox>
<el-checkbox v-model="modelForm.allowReport" :true-value="1" :false-value="0">周期报告</el-checkbox>
</div>
<small class="model-routing-help">默认主模型勾选某项能力时会优先承担该场景如需专用模型接管请取消主模型的对应能力并为专用模型开启该能力</small>
</div>
</el-form-item>
<el-form-item label="备注">

View File

@@ -33,6 +33,7 @@ const historyDetailOpen = ref(false);
const selectedHistory = ref<PromptDetail | null>(null);
const historyDetailLoading = ref(false);
const agentDebugTrace = ref<Record<string, any>[]>([]);
const lastDebugRoute = ref<{ modelName?: string; routeReason?: string } | null>(null);
const agentPreviewMessages = ref<{
role: "user" | "assistant" | "system";
content: string;
@@ -104,7 +105,9 @@ async function load() {
applyPrompt(promptResult);
models.value = modelRows;
knowledge.value = knowledgeRows;
agentForm.modelId = modelRows.find((item) => item.enabled === 1)?.id ?? modelRows[0]?.id;
agentForm.modelId = modelRows.find((item) => item.isDefault === 1)?.id
?? modelRows.find((item) => item.enabled === 1)?.id
?? modelRows[0]?.id;
applyRuntimeConfig(formalConfig);
applyDebugModelDefaults(agentForm.modelId);
agentForm.knowledgeIds = knowledgeRows
@@ -313,6 +316,7 @@ async function debugAgent() {
agentForm.question = "";
agentDebugging.value = true;
agentDebugTrace.value = [];
lastDebugRoute.value = null;
agentDebugAbortController.value = new AbortController();
scrollAgentPreview();
try {
@@ -348,7 +352,8 @@ async function debugAgent() {
},
(result) => {
agentDebugTrace.value = result.retrievalTrace || [];
ElMessage.success(result.message || "Agent 调试完成");
lastDebugRoute.value = { modelName: result.modelName, routeReason: result.routeReason };
ElMessage.success(`${result.message || "Agent 调试完成"} · ${result.modelName || selectedModelName.value}`);
},
agentDebugAbortController.value.signal,
);
@@ -383,6 +388,7 @@ function scrollAgentPreview() {
function clearAgentPreview() {
agentPreviewMessages.value = [{ role: "assistant", content: "预览已清空,可以继续发起新的 Agent 调试。" }];
agentDebugTrace.value = [];
lastDebugRoute.value = null;
}
function changeTypeLabel(value?: string) {
@@ -588,7 +594,7 @@ function errorMessage(error: unknown, fallback: string) {
<aside class="agent-preview-panel">
<div class="agent-preview-head">
<div><h3>调试预览</h3><small>{{ selectedKnowledgeSummary }} · {{ selectedDebugUserLabel }}</small></div>
<div class="agent-preview-head-actions"><span>{{ selectedModelName }}</span><el-button link :disabled="agentDebugging" @click="clearAgentPreview">清空</el-button></div>
<div class="agent-preview-head-actions"><span :title="lastDebugRoute?.routeReason || ''">{{ lastDebugRoute?.modelName || selectedModelName }}</span><el-button link :disabled="agentDebugging" @click="clearAgentPreview">清空</el-button></div>
</div>
<div ref="agentPreviewChat" class="agent-preview-chat">
<article v-for="(message, index) in agentPreviewMessages" :key="`${message.role}-${index}`" class="agent-preview-message-row" :class="message.role">

View File

@@ -159,6 +159,13 @@ export const systemSettingSections: SystemSettingSection[] = [
defaultValue: true,
description: "后台始终记录引用;此项控制用户端是否展示。",
},
{
key: "fixed_info_model_routing_enabled",
label: "固定信息模型分流",
type: "switch",
defaultValue: true,
description: "仅当本轮实际召回内容全部来自固定信息类知识库时使用对应低成本模型;关闭后统一使用默认主模型。",
},
{
key: "chat_max_active_requests",
label: "问答最大并发数",

View File

@@ -534,6 +534,7 @@ textarea {
.storage-grid strong { margin-top: 8px; font-size: 20px; }
.model-capability-tags { display: flex; flex-wrap: wrap; gap: 6px; }
.model-default-tag { margin-left: 6px; }
.model-routing-help { display: block; margin-top: 7px; color: #71827d; line-height: 1.55; }
.cleanup-controls { display: flex; align-items: center; gap: 8px; white-space: nowrap; }
.retention-panel { display: grid; grid-template-columns: minmax(260px, 1fr) 180px auto auto; align-items: center; gap: 12px; padding: 14px 16px; margin-bottom: 14px; border: 1px solid #dfe8e5; border-radius: 8px; background: #fff; }
.retention-panel div span { display: block; margin-top: 4px; color: #667a73; font-size: 12px; }

View File

@@ -243,6 +243,8 @@ export interface AgentDebugResult {
knowledgeIds?: string;
retrievalTrace?: Record<string, unknown>[];
retrievalLogId?: number;
routeReason?: string;
questionType?: string;
}
export interface AgentDebugStreamComplete {
@@ -252,6 +254,8 @@ export interface AgentDebugStreamComplete {
knowledgeIds?: string;
retrievalTrace?: Record<string, unknown>[];
retrievalLogId?: number;
routeReason?: string;
questionType?: string;
}
export interface KnowledgeVersion {