feat: refine topic insights and learner experience

This commit is contained in:
2026-08-17 12:42:16 +08:00
parent 77399df060
commit 833763c461
27 changed files with 848 additions and 182 deletions

View File

@@ -22,7 +22,7 @@ defineEmits<{
<template>
<div class="agent-config-grid">
<el-form-item>
<template #label><span class="agent-parameter-label">回答随机性<el-tooltip placement="top" :show-after="200" content="取值 02。数值越小回答越稳定、一致数值越大表达越多样但也更容易发散。答疑场景建议使用较低数值。"><button type="button" class="agent-parameter-help" aria-label="回答随机性说明">?</button></el-tooltip></span></template>
<template #label><span class="agent-parameter-label">回答随机性<el-tooltip placement="top" :show-after="200" content="取值 02。数值越小回答越稳定、一致数值越大表达越多样但也更容易发散。留空表示使用模型供应商默认值;做同题对比时建议设为 0。"><button type="button" class="agent-parameter-help" aria-label="回答随机性说明">?</button></el-tooltip></span></template>
<el-input-number :model-value="temperature" :disabled="disabled" :min="0" :max="2" :step="0.1" @update:model-value="$emit('update:temperature', $event)" />
</el-form-item>
<el-form-item>

View File

@@ -37,6 +37,7 @@ 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 DEFAULT_AGENT_PREVIEW_MESSAGE = "选择模型和知识库后,可以在这里调试 Agent 的真实问答效果。";
const agentPreviewMessages = ref<{
role: "user" | "assistant" | "system";
content: string;
@@ -44,7 +45,7 @@ const agentPreviewMessages = ref<{
showReasoning?: boolean;
streaming?: boolean;
}[]>([
{ role: "assistant", content: "选择模型和知识库后,可以在这里调试 Agent 的真实问答效果。" },
{ role: "assistant", content: DEFAULT_AGENT_PREVIEW_MESSAGE },
]);
const agentForm = reactive({
@@ -132,9 +133,9 @@ async function load() {
?? modelRows[0]?.id;
applyRuntimeConfig(formalConfig);
applyDebugModelDefaults(agentForm.modelId);
agentForm.knowledgeIds = knowledgeRows
.filter((item) => item.status === 1 && item.lifecycleStatus === "active")
.map((item) => item.id);
// 空选择由后端使用和用户端一致的“正式开放知识库”规则。
// 只有管理员显式勾选时,才进入指定知识库的预览模式。
agentForm.knowledgeIds = [];
if (props.previewKnowledgeId) applyPreviewKnowledge(props.previewKnowledgeId);
void searchDebugUsers("");
await loadHistory();
@@ -457,10 +458,15 @@ function scrollAgentPreview() {
});
}
function clearAgentPreview(message = "预览已清空,可以继续发起新的 Agent 调试。") {
agentPreviewMessages.value = [{ role: "assistant", content: message }];
function clearAgentPreview(message?: string) {
const notice = typeof message === "string" && message.trim()
? message
: "预览已清空,可以继续发起新的 Agent 调试。";
agentPreviewMessages.value = [{ role: "assistant", content: notice }];
agentDebugTrace.value = [];
lastDebugRoute.value = null;
agentForm.question = "";
scrollAgentPreview();
}
function changeTypeLabel(value?: string) {
@@ -621,9 +627,18 @@ function errorMessage(error: unknown, fallback: string) {
<el-select v-model="agentForm.knowledgeIds" class="debug-knowledge-select" multiple filterable collapse-tags collapse-tags-tooltip :max-collapse-tags="2" popper-class="debug-knowledge-popper" placeholder="默认使用全部已开放知识库">
<el-option v-for="item in knowledge" :key="item.id" :label="`${item.name}${item.status === 0 ? ' · 已关闭(仅本次预览)' : ''}`" :value="item.id" />
</el-select>
<div class="agent-form-help">不选时与用户端一致只使用已开放已确认且来源正常的正式版本显式选择则是本次预览范围</div>
</el-form-item>
<section class="agent-advanced-settings">
<div class="agent-subsection-title"><h4>高级生成参数</h4><span>仅影响本次后台调试</span></div>
<el-alert
v-if="agentForm.temperature == null"
class="agent-debug-randomness-alert"
title="当前未指定回答随机性,将使用模型供应商默认值;做同题稳定性对比时建议设为 0。"
type="warning"
:closable="false"
show-icon
/>
<AgentGenerationParameters
v-model:temperature="agentForm.temperature"
v-model:top-p="agentForm.topP"
@@ -699,7 +714,7 @@ function errorMessage(error: unknown, fallback: string) {
<aside class="agent-preview-panel">
<div class="agent-preview-head">
<div><h3>调试预览</h3><small>{{ selectedKnowledgeSummary }} · {{ selectedDebugUserLabel }} · {{ selectedDebugTopicLabel }}</small></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 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">
@@ -719,7 +734,10 @@ function errorMessage(error: unknown, fallback: string) {
</article>
</div>
<div class="agent-preview-composer">
<el-input v-model="agentForm.question" type="textarea" :rows="2" resize="none" :disabled="agentDebugging" placeholder="向 Agent 发送测试问题Enter 发送Shift+Enter 换行" @keydown.enter.exact.prevent="debugAgent" />
<div class="agent-preview-input">
<el-input v-model="agentForm.question" type="textarea" :rows="2" resize="none" :disabled="agentDebugging" placeholder="向 Agent 发送测试问题Enter 发送Shift+Enter 换行" @keydown.enter.exact.prevent="debugAgent" />
<small>连续发送会携带上方历史同题对比请先清空并将回答随机性设为 0</small>
</div>
<el-button :type="agentDebugging ? 'danger' : 'primary'" @click="agentDebugging ? stopDebugAgent() : debugAgent()">{{ agentDebugging ? '停止' : '发送' }}</el-button>
</div>
</aside>

View File

@@ -61,14 +61,18 @@ const groupBlueprints: Record<string, SettingGroupBlueprint[]> = {
"AI 问答": [
{
title: "回答体验",
description: "控制会话记忆、引用展示和模型请求的基本行为。",
description: "控制引用展示和模型请求的基本行为。",
keys: [
"ai_timeout_seconds",
"mock_model_enabled",
"chat_context_message_count",
"show_reference_sources",
],
},
{
title: "主题与记忆",
description: "控制会话记忆,以及成功问答达到多少轮后开始自动提炼主题内容。",
keys: ["chat_context_message_count", "topic_auto_settle_successful_rounds"],
},
{
title: "模型分流",
description: "决定正式问答在不同问题类型下如何选择模型。",

View File

@@ -159,6 +159,15 @@ export const systemSettingSections: SystemSettingSection[] = [
max: 100,
description: "当前会话带入模型的最近历史消息条数;更早内容会滚动摘要,设为 0 将关闭会话记忆。修改后下一次提问立即生效。",
},
{
key: "topic_auto_settle_successful_rounds",
label: "开始自动沉淀轮数",
type: "number",
defaultValue: 2,
min: 1,
max: 100,
description: "同一主题达到该数量的成功问答后,自动提炼主题标题和阶段摘要,但不会结束主题或重复扣减额度。",
},
{
key: "show_reference_sources",
label: "用户端展示引用来源",

View File

@@ -1713,6 +1713,22 @@ textarea {
height: 54px;
}
.agent-preview-input {
display: grid;
min-width: 0;
gap: 6px;
}
.agent-preview-input small {
color: #7d8d87;
font-size: 11px;
line-height: 1.5;
}
.agent-debug-randomness-alert {
margin-bottom: 14px;
}
.actions {
margin-top: 12px;
}