diff --git a/ai_knowledge_base_v2/apps/admin-web/src/App.vue b/ai_knowledge_base_v2/apps/admin-web/src/App.vue index a3b8abe..a7c3b44 100644 --- a/ai_knowledge_base_v2/apps/admin-web/src/App.vue +++ b/ai_knowledge_base_v2/apps/admin-web/src/App.vue @@ -6,6 +6,7 @@ import { api, clearToken, getToken, saveToken } from "./services/api"; import type { AdminProfile, AdminUser, + AgentDebugResult, AiLogRecord, ChatDetail, ChatRecord, @@ -33,6 +34,10 @@ const chatDetail = ref(null); const chatDetailOpen = ref(false); const recordTab = ref("chats"); const editingModelId = ref(null); +const agentDebugging = ref(false); +const agentPreviewMessages = ref<{ role: "user" | "assistant" | "system"; content: string }[]>([ + { role: "assistant", content: "选择模型和知识库后,可以在这里调试 Agent 的真实问答效果。" }, +]); const knowledgeForm = reactive({ name: "", @@ -52,12 +57,12 @@ const modelForm = reactive({ apiKey: "", authType: "bearer", apiVersion: "", - temperature: 0.2 as number | null, + temperature: null as number | null, topP: null as number | null, topK: null as number | null, presencePenalty: null as number | null, frequencyPenalty: null as number | null, - maxToken: 1024, + maxToken: null as number | null, contextWindow: null as number | null, streamEnabled: 1, responseFormat: "", @@ -80,10 +85,10 @@ const quickModelProviders = [ baseUrl: "https://api.deepseek.com", authType: "bearer", apiVersion: "", - temperature: 0.2, + temperature: null, topP: null, - maxToken: 1024, - contextWindow: 128000, + maxToken: null, + contextWindow: null, models: [ { label: "deepseek-v4-pro", value: "deepseek-v4-pro" }, { label: "deepseek-v4-flash", value: "deepseek-v4-flash" }, @@ -98,8 +103,8 @@ const quickModelProviders = [ apiVersion: "", temperature: null, topP: null, - maxToken: 1024, - contextWindow: 1000000, + maxToken: null, + contextWindow: null, models: [ { label: "MiniMax-M3", value: "MiniMax-M3" }, { label: "MiniMax-M2.7", value: "MiniMax-M2.7" }, @@ -161,6 +166,18 @@ const chatFilters = reactive({ dateRange: [] as string[], }); +const agentForm = reactive({ + modelId: undefined as number | undefined, + knowledgeIds: [] as number[], + temperature: 0.2 as number | null, + topP: null as number | null, + topK: null as number | null, + presencePenalty: null as number | null, + frequencyPenalty: null as number | null, + maxToken: 1024 as number | null, + question: "", +}); + onMounted(async () => { if (!getToken()) return; try { @@ -201,7 +218,15 @@ async function loadCurrentMenu() { if (activeMenu.value === "dashboard") stats.value = await api.dashboard(); if (activeMenu.value === "users") users.value = await api.users(userKeyword.value); if (activeMenu.value === "knowledge") knowledge.value = await api.knowledge(); - if (activeMenu.value === "prompt") promptContent.value = (await api.prompt()).promptContent; + if (activeMenu.value === "prompt") { + const [prompt, modelRows, knowledgeRows] = await Promise.all([api.prompt(), api.models(), api.knowledge()]); + promptContent.value = prompt.promptContent; + models.value = modelRows; + knowledge.value = knowledgeRows; + if (!agentForm.modelId && modelRows.length) { + agentForm.modelId = modelRows.find((model) => model.enabled === 1)?.id ?? modelRows[0].id; + } + } if (activeMenu.value === "models") models.value = await api.models(); if (activeMenu.value === "configs") configs.value = await api.configs(); if (activeMenu.value === "records") { @@ -260,6 +285,18 @@ function buildModelPayload() { payload[field] = null; } }); + Object.assign(payload, { + temperature: null, + topP: null, + topK: null, + presencePenalty: null, + frequencyPenalty: null, + maxToken: null, + contextWindow: null, + streamEnabled: 1, + responseFormat: null, + extraParams: null, + }); return payload; } @@ -281,13 +318,13 @@ async function quickAddModel() { apiKey: quickModelForm.apiKey, authType: provider.authType, apiVersion: provider.apiVersion, - temperature: provider.temperature, - topP: provider.topP, + temperature: null, + topP: null, topK: null, presencePenalty: null, frequencyPenalty: null, - maxToken: provider.maxToken, - contextWindow: provider.contextWindow, + maxToken: null, + contextWindow: null, streamEnabled: 1, responseFormat: null, extraParams: null, @@ -332,7 +369,7 @@ function applyModelPreset(label: string) { { apiVersion: "", authType: "bearer", - temperature: 0.2, + temperature: null, topP: null, topK: null, presencePenalty: null, @@ -356,13 +393,13 @@ function editModel(row: ModelItem) { apiKey: "", authType: row.authType, apiVersion: row.apiVersion ?? "", - temperature: row.temperature ?? null, - topP: row.topP ?? null, - topK: row.topK ?? null, - presencePenalty: row.presencePenalty ?? null, - frequencyPenalty: row.frequencyPenalty ?? null, - maxToken: row.maxToken ?? 1024, - contextWindow: row.contextWindow ?? null, + temperature: null, + topP: null, + topK: null, + presencePenalty: null, + frequencyPenalty: null, + maxToken: null, + contextWindow: null, streamEnabled: row.streamEnabled, responseFormat: row.responseFormat ?? "", extraParams: row.extraParams ?? "", @@ -383,12 +420,12 @@ function resetModelForm() { apiKey: "", authType: "bearer", apiVersion: "", - temperature: 0.2, + temperature: null, topP: null, topK: null, presencePenalty: null, frequencyPenalty: null, - maxToken: 1024, + maxToken: null, contextWindow: null, streamEnabled: 1, responseFormat: "", @@ -427,6 +464,52 @@ async function saveConfig() { await loadCurrentMenu(); } +async function debugAgent() { + if (!agentForm.modelId) { + ElMessage.error("请选择调试模型"); + return; + } + if (!agentForm.question.trim()) { + ElMessage.error("请输入调试问题"); + return; + } + agentPreviewMessages.value.push({ role: "user", content: agentForm.question.trim() }); + agentDebugging.value = true; + try { + const result: AgentDebugResult = await api.debugAgent({ + promptContent: promptContent.value, + modelId: agentForm.modelId, + knowledgeIds: agentForm.knowledgeIds, + question: agentForm.question.trim(), + temperature: agentForm.temperature, + topP: agentForm.topP, + topK: agentForm.topK, + presencePenalty: agentForm.presencePenalty, + frequencyPenalty: agentForm.frequencyPenalty, + maxToken: agentForm.maxToken, + }); + if (!result.ok) { + ElMessage.error(result.message); + agentPreviewMessages.value.push({ role: "assistant", content: result.message }); + return; + } + agentPreviewMessages.value.push({ role: "assistant", content: result.answer }); + ElMessage.success(result.message); + } catch (error) { + const message = error instanceof Error ? error.message : "Agent 调试失败"; + ElMessage.error(message); + agentPreviewMessages.value.push({ role: "assistant", content: message }); + } finally { + agentDebugging.value = false; + } +} + +function clearAgentPreview() { + agentPreviewMessages.value = [ + { role: "assistant", content: "预览已清空,可以继续发起新的 Agent 调试。" }, + ]; +} + async function searchChats() { chats.value = await api.chats(buildChatQuery()); } @@ -461,7 +544,7 @@ function buildChatQuery() {