feat: refine topic insights and learner experience
This commit is contained in:
@@ -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="取值 0–2。数值越小,回答越稳定、一致;数值越大,表达越多样,但也更容易发散。答疑场景建议使用较低数值。"><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="取值 0–2。数值越小,回答越稳定、一致;数值越大,表达越多样,但也更容易发散。留空表示使用模型供应商默认值;做同题对比时建议设为 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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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: "决定正式问答在不同问题类型下如何选择模型。",
|
||||
|
||||
@@ -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: "用户端展示引用来源",
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user