当前位置: 首页 > news >正文

BuildingAI 控制台智能体菜单和页面技术架构

1. 文档概述

1.1 文档目的

本文档旨在定义控制台智能体菜单和页面的技术架构,包括系统架构、模块划分、核心功能实现、数据结构与模型、接口设计等,为开发团队提供清晰的技术实现指南。

1.2 适用范围

适用于控制台智能体模块的所有相关页面和功能开发。

1.3 术语定义

  • 智能体:具备特定能力和个性的AI实体,可与用户进行对话并执行任务
  • 智能体广场:展示和分享智能体的公共平台
  • DSL:领域特定语言,用于智能体的配置和导出
  • MCP:模型调用协议,用于智能体与外部服务的交互

2. 技术栈

2.1 前端技术栈

  • 框架:Vue 3 + TypeScript + Nuxt 3
  • UI组件库:@nuxt/ui
  • 状态管理:Pinia
  • 路由:Nuxt Router
  • HTTP客户端:Axios

2.2 后端技术栈

  • 框架:NestJS + TypeScript
  • ORM:TypeORM
  • 数据库:PostgreSQL
  • 权限:基于角色的权限控制(RBAC)

3. 系统架构

3.1 整体架构

┌─────────────────────────┐     ┌─────────────────────────┐     ┌─────────────────────────┐
│      前端页面层         │     │      后端服务层         │     │      数据存储层         │
├─────────────────────────┤     ├─────────────────────────┤     ├─────────────────────────┤
│ 智能体列表页面         │     │ 智能体管理服务         │     │ 智能体实体表          │
│ 智能体创建/编辑页面     │     │ 智能体配置服务         │     │ 智能体配置表          │
│ 智能体详情页面         │     │ 智能体发布服务         │     │ 智能体对话记录表       │
│ 智能体配置页面         │     │ 智能体统计服务         │     │ 智能体发布历史表       │
│ 智能体发布页面         │     │ 智能体标签服务         │     │ 标签表               │
└─────────────────────────┘     └─────────────────────────┘     └─────────────────────────┘

3.2 前后端交互流程

  1. 前端页面通过API调用后端服务
  2. 后端服务处理请求,进行业务逻辑处理
  3. 后端服务与数据库交互,获取或存储数据
  4. 后端服务将处理结果返回给前端页面
  5. 前端页面根据返回结果更新UI

4. 模块划分

4.1 前端模块

4.1.1 页面模块
  • 智能体列表页面:展示所有智能体,支持搜索、过滤和批量操作
  • 智能体创建/编辑页面:用于创建和编辑智能体的基本信息和配置
  • 智能体详情页面:展示智能体的详细信息和配置
  • 智能体配置页面:管理智能体的配置
  • 智能体发布页面:发布智能体和管理发布历史
4.1.2 组件模块
  • 智能体卡片组件:展示智能体的基本信息和操作按钮
  • 智能体模态框组件:用于创建和编辑智能体
  • 智能体DSL导入组件:用于导入智能体的DSL配置
  • 智能体标签组件:用于管理智能体的标签
  • 智能体预览聊天组件:用于预览智能体的聊天功能

4.2 后端模块

4.2.1 控制器模块
  • 控制台控制器:处理控制台端的API请求
  • Web控制器:处理Web端的API请求
4.2.2 服务模块
  • 智能体管理服务:处理智能体的创建、编辑、删除等操作
  • 智能体配置服务:处理智能体的配置管理
  • 智能体发布服务:处理智能体的发布和撤销发布
  • 智能体统计服务:处理智能体的统计信息
  • 智能体标签服务:处理智能体的标签管理
4.2.3 数据访问模块
  • 智能体实体:定义智能体的数据结构
  • 智能体配置实体:定义智能体配置的数据结构
  • 智能体对话记录实体:定义智能体对话记录的数据结构
  • 智能体发布历史实体:定义智能体发布历史的数据结构

5. 核心功能实现

5.1 智能体列表页面

5.1.1 功能说明

展示所有智能体,支持搜索、过滤和批量操作。

5.1.2 技术实现
  • 使用Nuxt 3的页面组件实现
  • 使用@buildingai/service/consoleapi/ai-agent提供的API获取智能体列表
  • 使用BdInfiniteScroll实现无限滚动加载
  • 使用AgentCard组件展示智能体卡片
5.1.3 关键代码
<template><div class="flex w-full flex-col items-center justify-center"><div class="bg-background sticky top-0 z-10 flex w-full flex-wrap justify-between gap-4 pb-2"><div class="flex items-center gap-4"><UInputv-model="searchForm.keyword":placeholder="$t('ai-agent.backend.search.placeholder')"class="w-80"@change="getLists"/><TagSelect v-model="searchForm.tagIds" @change="getLists" /><USelectv-model="searchForm.isPublic":items="[{ label: $t('ai-agent.backend.search.allStatus'), value: undefined },{ label: $t('ai-agent.backend.configuration.public'), value: true },{ label: $t('ai-agent.backend.configuration.private'), value: false },]":placeholder="$t('ai-agent.backend.search.filterByStatus')"label-key="label"value-key="value"class="w-48"@change="getLists"/></div><div><UButtoncolor="primary"variant="ghost"icon="i-lucide-package":label="$t('decorate.openDecorateSettings')"@click.stop="handleAgentDecorate"/></div></div><BdScrollArea class="h-[calc(100vh-9rem)] min-h-0 w-full"><BdInfiniteScroll:loading="loading":has-more="hasMore":threshold="200":loading-text="$t('common.loading')":no-more-text="searchForm.page !== 1 ? $t('common.noMoreData') : ' '"@load-more="loadMore"><div class="grid grid-cols-1 gap-6 pt-2 pb-4 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4"><divclass="group border-default relative cursor-pointer rounded-lg border border-dashed p-4 transition-all duration-200 hover:shadow-lg"@click="handleCreate"><div class="group-hover:text-primary text-foreground mb-3 flex items-center gap-3"><div class="border-default flex size-10 flex-none items-center justify-center rounded-lg border border-dashed"><UIcon name="i-lucide-plus" class="h-6 w-6" /></div><h3 class="truncate text-sm font-medium">{{ $t('ai-agent.backend.create.title') }}</h3></div><div class="text-muted-foreground mb-6 pr-8 text-xs"><p class="line-clamp-2 overflow-hidden">{{ $t('ai-agent.backend.create.desc') }}</p></div><div class="flex items-center gap-2"><UButtoncolor="primary"variant="ghost"class="w-full"icon="i-lucide-package"size="sm":label="$t('ai-agent.backend.create.fromTemplate')"@click.stop="handleCreateFromTemplate"/><UButtoncolor="neutral"variant="ghost"class="w-full"icon="i-lucide-file-up"size="sm":label="$t('ai-agent.backend.dslImport.import')"@click.stop="handleImportAgent"/></div></div><!-- 智能体卡片 --><AgentCardv-for="agent in agents":key="agent.id":agent="agent"@delete="handleDelete"@edit="handleEdit"@export-dsl="handleExportDsl"@update-tags="handleUpdateTags"/></div></BdInfiniteScroll></BdScrollArea></div>
</template>

5.2 智能体创建/编辑页面

5.2.1 功能说明

用于创建和编辑智能体的基本信息和配置。

5.2.2 技术实现
  • 使用Nuxt 3的页面组件实现
  • 使用表单组件收集智能体的基本信息和配置
  • 使用API调用后端服务创建或编辑智能体
  • 支持从模板创建智能体
  • 支持DSL配置导入
5.2.3 关键代码
<script lang="ts" setup>
import type { Agent, QueryAgentParams } from "@buildingai/service/consoleapi/ai-agent";
import { apiAddAgentTags, apiDeleteAgent, apiExportAgentDsl, apiGetAgentList, apiRemoveAgentTags } from "@buildingai/service/consoleapi/ai-agent";// ... 省略部分代码const handleCreateFromTemplate = async () => {const drawer = overlay.create(TemplateDrawer);const instance = drawer.open();const shouldRefresh = await instance.result;if (shouldRefresh) {searchForm.page = 1;searchForm.pageSize = 15;await getLists();}
};const handleImportAgent = async () => {const modal = overlay.create(AgentDslImport);const instance = modal.open();const shouldRefresh = await instance.result;if (shouldRefresh) {searchForm.page = 1;searchForm.pageSize = 15;await getLists();}
};// ... 省略部分代码
</script><template><div class="grid grid-cols-1 gap-6 pt-2 pb-4 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4"><divclass="group border-default relative cursor-pointer rounded-lg border border-dashed p-4 transition-all duration-200 hover:shadow-lg"@click="handleCreate"><div class="group-hover:text-primary text-foreground mb-3 flex items-center gap-3"><div class="border-default flex size-10 flex-none items-center justify-center rounded-lg border border-dashed"><UIcon name="i-lucide-plus" class="h-6 w-6" /></div><h3 class="truncate text-sm font-medium">{{ $t('ai-agent.backend.create.title') }}</h3></div><div class="text-muted-foreground mb-6 pr-8 text-xs"><p class="line-clamp-2 overflow-hidden">{{ $t('ai-agent.backend.create.desc') }}</p></div><div class="flex items-center gap-2"><UButtoncolor="primary"variant="ghost"class="w-full"icon="i-lucide-package"size="sm":label="$t('ai-agent.backend.create.fromTemplate')"@click.stop="handleCreateFromTemplate"/><UButtoncolor="neutral"variant="ghost"class="w-full"icon="i-lucide-file-up"size="sm":label="$t('ai-agent.backend.dslImport.import')"@click.stop="handleImportAgent"/></div></div><!-- 智能体卡片 --><AgentCardv-for="agent in agents":key="agent.id":agent="agent"@delete="handleDelete"@edit="handleEdit"@export-dsl="handleExportDsl"@update-tags="handleUpdateTags"/></div>
</template>

5.3 智能体详情页面

5.3.1 功能说明

展示智能体的详细信息和配置。

5.3.2 技术实现
  • 使用Nuxt 3的页面组件实现
  • 使用嵌套路由展示智能体的不同配置页面
  • 使用导航菜单切换不同的配置页面
5.3.3 关键代码
<script setup lang="ts">
import { apiGetAgentDetail } from "@buildingai/service/consoleapi/ai-agent";
import type { NavigationMenuItem } from "@nuxt/ui";const AgentModal = defineAsyncComponent(() => import("./components/agent-modal.vue"));const route = useRoute();
const router = useRouter();
const { t } = useI18n();
const overlay = useOverlay();
const { hasAccessByCodes } = useAccessControl();
const isMobile = useMediaQuery("(max-width: 1380px)");
const collapsed = shallowRef<boolean>(false);
const agentId = computed(() => (route.params as Record<string, string>).id);const { data: agent, refresh: refreshAgent } = await useAsyncData(`agent-detail-${agentId.value}`,() => apiGetAgentDetail(agentId.value as string),
);provide("agents", agent);const mountAgentModal = async (id: string) => {const modal = overlay.create(AgentModal);const instance = modal.open({ id: id });const shouldRefresh = await instance.result;if (shouldRefresh) refreshAgent();
};const handleEdit = () => {mountAgentModal(agentId.value as string);
};const navigationItems = computed(() => {return [hasAccessByCodes(["ai-agent:detail"]) ? {label: t("ai-agent.backend.menu.arrange"),icon: "i-lucide-radar",to: useRoutePath("ai-agent:detail", {id: agentId.value as string,}),} : null,hasAccessByCodes(["ai-agent:publish"]) ? {label: t("ai-agent.backend.menu.publish"),icon: "i-lucide-radio-tower",to: useRoutePath("ai-agent:publish", {id: agentId.value as string,}),} : null,hasAccessByCodes(["ai-agent-chat-record:list"]) ? {label: t("ai-agent.backend.menu.chatRecord"),icon: "i-lucide-file-text",to: useRoutePath("ai-agent-chat-record:list", {id: agentId.value as string,}),} : null,hasAccessByCodes(["ai-agent:statistics"]) ? {label: t("ai-agent.backend.menu.statistics"),icon: "i-lucide-pie-chart",to: useRoutePath("ai-agent:statistics", {id: agentId.value as string,}),} : null,].filter(Boolean) as NavigationMenuItem[];
});
</script><template><div class="flex h-full min-h-0 w-full"><divclass="bg-muted flex h-full w-50 flex-none flex-col rounded-tr-xl rounded-br-xl p-2":class="{ 'w-18!': collapsed }"><!-- 智能体信息和导航菜单 --><!-- ... 省略部分代码 ... --></div><!-- 内容区域 --><NuxtPage /></div>
</template>

5.4 智能体发布页面

5.4.1 功能说明

发布智能体和管理发布历史。

5.4.2 技术实现
  • 使用Nuxt 3的页面组件实现
  • 使用表单组件收集发布信息
  • 使用API调用后端服务发布智能体
  • 支持版本控制
  • 支持发布范围设置

5.5 后端服务实现

5.5.1 智能体服务

import { BaseService } from "@buildingai/base";
import { InjectRepository } from "@buildingai/db/@nestjs/typeorm";
import { Agent } from "@buildingai/db/entities/ai-agent.entity";
import { AgentChatRecord } from "@buildingai/db/entities/ai-agent-chat-record.entity";
import { AgentChatMessage } from "@buildingai/db/entities/ai-agent-chat-message.entity";
import { AgentAnnotation } from "@buildingai/db/entities/ai-agent-annotation.entity";
import { Tag } from "@buildingai/db/entities/tag.entity";
import { AiModel } from "@buildingai/db/entities/ai-model.entity";
import { AiProvider } from "@buildingai/db/entities/ai-provider.entity";
import { Repository } from "@buildingai/db/typeorm";
import { HttpErrorFactory } from "@buildingai/errors";
import { Injectable } from "@nestjs/common";
import { randomBytes } from "crypto";import { CreateAgentDto, PublishAgentDto, QueryAgentDto, QueryAgentStatisticsDto, UpdateAgentConfigDto } from "../dto/agent";@Injectable()
export class AiAgentService extends BaseService<Agent> {private readonly defaultAvatar = "/static/images/agent.png";constructor(@InjectRepository(Agent) private readonly agentRepository: Repository<Agent>,@InjectRepository(AgentChatRecord) private readonly chatRecordRepository: Repository<AgentChatRecord>,@InjectRepository(AgentChatMessage) private readonly chatMessageRepository: Repository<AgentChatMessage>,@InjectRepository(AgentAnnotation) private readonly annotationRepository: Repository<AgentAnnotation>,@InjectRepository(Tag) private readonly tagRepository: Repository<Tag>,@InjectRepository(AiModel) private readonly aiModelRepository: Repository<AiModel>,@InjectRepository(AiProvider) private readonly aiProviderRepository: Repository<AiProvider>,) {super(agentRepository);}// 创建新智能体async createAgent(dto: CreateAgentDto, user: UserPlayground): Promise<Agent> {const { name, description, avatar, createMode = "direct", thirdPartyIntegration = {}, tagIds } = dto;await this.checkNameUniqueness(name);return this.withErrorHandling(async () => {const agent = await this.create({name,description,avatar: avatar || this.defaultAvatar,showContext: true,createMode,thirdPartyIntegration: thirdPartyIntegration || {},showReference: true,enableFeedback: false,enableWebSearch: false,userCount: 0,isPublic: false,createBy: user.id,});if (tagIds && tagIds.length > 0) {await this.syncAgentTags(agent.id, tagIds);}return agent;});}// 发布智能体async publishAgent(agentId: string, dto: PublishAgentDto): Promise<Agent> {const { version, releaseNotes, publishScope } = dto;return this.withErrorHandling(async () => {const agent = await this.getById(agentId);if (!agent) {throw HttpErrorFactory.createNotFoundError("Agent not found");}const updatedAgent = await this.updateById(agentId, {isPublished: true,publishConfig: { ...agent.publishConfig, version, releaseNotes, publishScope },});// 记录发布历史await this.recordPublishHistory(agentId, version, releaseNotes, publishScope);return updatedAgent;});}// ... 省略其他方法 ...
}

5.6 智能体配置页面

5.6.1 功能说明

配置智能体的模型、数据集、表单字段等参数。

5.6.2 技术实现
  • 使用Nuxt 3的页面组件实现
  • 支持多标签页切换配置不同参数
  • 使用表单组件收集配置信息
  • 使用API调用后端服务保存配置
  • 支持实时预览配置效果
5.6.3 关键代码
<script setup lang="ts">
import { apiGetAgentDetail, apiUpdateAgentConfig } from "@buildingai/service/consoleapi/ai-agent";
import type { Agent, ModelConfig, DatasetConfig } from "@buildingai/service/consoleapi/ai-agent";const route = useRoute();
const { t } = useI18n();
const toast = useToast();const agentId = computed(() => (route.params as Record<string, string>).id);
const { data: agent, refresh: refreshAgent } = await useAsyncData(`agent-detail-${agentId.value}`,() => apiGetAgentDetail(agentId.value as string),
);const modelConfig = ref<ModelConfig | undefined>(agent.value?.modelConfig);
const datasetConfig = ref<DatasetConfig | undefined>(agent.value?.datasetConfig);const updateConfig = async () => {try {await apiUpdateAgentConfig(agentId.value as string, {modelConfig: modelConfig.value,datasetConfig: datasetConfig.value,});toast.add({ title: t("common.saveSuccess"), color: "primary" });await refreshAgent();} catch (error) {toast.add({ title: t("common.saveFailed"), color: "negative" });}
};
</script><template><div class="space-y-6"><div class="flex items-center justify-between"><h3 class="text-lg font-medium">{{ t("ai-agent.backend.menu.configuration") }}</h3><UButton color="primary" size="sm" :label="t('common.save')" @click="updateConfig" /></div><UTabs v-model="activeTab"><UTab title="{{ t('ai-agent.backend.configuration.model') }}"><!-- 模型配置 --><ModelConfigPanel v-model="modelConfig" /></UTab><UTab title="{{ t('ai-agent.backend.configuration.dataset') }}"><!-- 数据集配置 --><DatasetConfigPanel v-model="datasetConfig" /></UTab><UTab title="{{ t('ai-agent.backend.configuration.form') }}"><!-- 表单字段配置 --><FormConfigPanel v-model="formConfig" /></UTab><UTab title="{{ t('ai-agent.backend.configuration.thirdParty') }}"><!-- 第三方集成配置 --><ThirdPartyConfigPanel v-model="thirdPartyConfig" /></UTab></UTabs></div>
</template>

5.7 智能体日志页面

5.7.1 功能说明

查看智能体的运行日志和调试信息。

5.7.2 技术实现
  • 使用Nuxt 3的页面组件实现
  • 支持日志过滤和搜索
  • 支持分页加载日志
  • 支持日志级别筛选
  • 使用WebSocket实现实时日志推送
5.7.3 关键代码
<script setup lang="ts">
import { apiGetAgentLogs, apiClearAgentLogs } from "@buildingai/service/consoleapi/ai-agent";
import type { AgentLog, QueryAgentLogsDto } from "@buildingai/service/consoleapi/ai-agent";const route = useRoute();
const { t } = useI18n();
const toast = useToast();const agentId = computed(() => (route.params as Record<string, string>).id);
const logs = ref<AgentLog[]>([]);
const total = ref(0);
const loading = ref(false);const queryParams = reactive<QueryAgentLogsDto>({page: 1,pageSize: 50,level: "all",keyword: "",
});const getLogs = async () => {loading.value = true;try {const result = await apiGetAgentLogs(agentId.value as string, queryParams);logs.value = result.data;total.value = result.total;} catch (error) {toast.add({ title: t("ai-agent.backend.logs.loadFailed"), color: "negative" });} finally {loading.value = false;}
};const clearLogs = async () => {try {await apiClearAgentLogs(agentId.value as string);toast.add({ title: t("ai-agent.backend.logs.clearSuccess"), color: "primary" });await getLogs();} catch (error) {toast.add({ title: t("ai-agent.backend.logs.clearFailed"), color: "negative" });}
};// WebSocket 实时日志推送
const socket = ref<WebSocket | null>(null);onMounted(() => {socket.value = new WebSocket(`ws://localhost:3000/agent/${agentId.value}/logs`);socket.value.onmessage = (event) => {const log: AgentLog = JSON.parse(event.data);logs.value.unshift(log);if (logs.value.length > 100) logs.value.pop();};await getLogs();
});onUnmounted(() => {if (socket.value) socket.value.close();
});
</script><template><div class="space-y-6"><div class="flex items-center justify-between"><h3 class="text-lg font-medium">{{ t("ai-agent.backend.menu.logs") }}</h3><UButton color="negative" size="sm" :label="t('ai-agent.backend.logs.clear')" @click="clearLogs" /></div><!-- 日志筛选 --><div class="flex flex-wrap gap-4"><USelect v-model="queryParams.level" :options="logLevels" placeholder="{{ t('ai-agent.backend.logs.level') }}" size="sm" /><UInput v-model="queryParams.keyword" placeholder="{{ t('ai-agent.backend.logs.search') }}" size="sm" /><UButton color="primary" size="sm" :label="t('common.search')" @click="getLogs" /></div><!-- 日志列表 --><div class="bg-card rounded-lg border p-4 max-h-[600px] overflow-y-auto"><div v-if="loading" class="flex justify-center py-4">{{ t('common.loading') }}</div><div v-else-if="logs.length === 0" class="text-center py-4 text-muted-foreground">{{ t('ai-agent.backend.logs.empty') }}</div><div v-else><divv-for="log in logs":key="log.id"class="border-l-4 pl-3 py-2 mb-2":class="{'border-red-500': log.level === 'error','border-yellow-500': log.level === 'warn','border-blue-500': log.level === 'info','border-gray-500': log.level === 'debug',}"><div class="text-xs text-muted-foreground flex items-center gap-2"><span>{{ log.timestamp }}</span><span class="font-medium" :class="{'text-red-500': log.level === 'error','text-yellow-500': log.level === 'warn','text-blue-500': log.level === 'info','text-gray-500': log.level === 'debug',}">{{ log.level.toUpperCase() }}</span></div><div class="text-sm whitespace-pre-wrap mt-1">{{ log.message }}</div><div v-if="log.stacktrace" class="text-xs text-red-500 mt-1 whitespace-pre-wrap">{{ log.stacktrace }}</div></div></div></div><!-- 分页 --><div v-if="total > 0" class="flex items-center justify-end"><UPagination v-model="queryParams.page" :total="total" :page-size="queryParams.pageSize" @change="getLogs" /></div></div>
</template>

5.8 智能体统计页面

5.8.1 功能说明

查看智能体的使用统计和性能指标。

5.8.2 技术实现
  • 使用Nuxt 3的页面组件实现
  • 使用ECharts或其他图表库展示统计数据
  • 支持时间范围筛选
  • 支持数据导出
  • 实时更新统计数据
5.8.3 关键代码
<script setup lang="ts">
import { apiGetAgentStatistics, apiExportAgentStatistics } from "@buildingai/service/consoleapi/ai-agent";
import type { AgentStatistics, QueryAgentStatisticsDto } from "@buildingai/service/consoleapi/ai-agent";
import { createChart } from "@buildingai/echarts";const route = useRoute();
const { t } = useI18n();
const toast = useToast();const agentId = computed(() => (route.params as Record<string, string>).id);
const statistics = ref<AgentStatistics | null>(null);
const loading = ref(false);const queryParams = reactive<QueryAgentStatisticsDto>({timeRange: "7d",metrics: ["usage", "responseTime", "successRate"],
});const chartRef = ref<HTMLElement | null>(null);
let chartInstance: any = null;const getStatistics = async () => {loading.value = true;try {const result = await apiGetAgentStatistics(agentId.value as string, queryParams);statistics.value = result;updateChart();} catch (error) {toast.add({ title: t("ai-agent.backend.statistics.loadFailed"), color: "negative" });} finally {loading.value = false;}
};const updateChart = () => {if (!chartRef.value || !statistics.value) return;if (!chartInstance) {chartInstance = createChart(chartRef.value, {xAxis: {type: "category",data: statistics.value.timeSeries,},yAxis: {type: "value",},series: [{name: t("ai-agent.backend.statistics.usage"),type: "line",data: statistics.value.usage,smooth: true,},{name: t("ai-agent.backend.statistics.responseTime"),type: "line",data: statistics.value.responseTime,smooth: true,},{name: t("ai-agent.backend.statistics.successRate"),type: "line",data: statistics.value.successRate,smooth: true,},],});} else {chartInstance.setOption({xAxis: {data: statistics.value.timeSeries,},series: [{data: statistics.value.usage,},{data: statistics.value.responseTime,},{data: statistics.value.successRate,},],});}
};onMounted(() => {getStatistics();
});onUnmounted(() => {if (chartInstance) chartInstance.dispose();
});
</script><template><div class="space-y-6"><div class="flex items-center justify-between"><h3 class="text-lg font-medium">{{ t("ai-agent.backend.menu.statistics") }}</h3><UButton color="primary" size="sm" :label="t('ai-agent.backend.statistics.export')" @click="exportStatistics" /></div><!-- 统计筛选 --><div class="flex flex-wrap gap-4"><USelect v-model="queryParams.timeRange" :options="timeRanges" placeholder="{{ t('ai-agent.backend.statistics.timeRange') }}" size="sm" /><UTagInputv-model="queryParams.metrics":tags="metricsOptions"placeholder="{{ t('ai-agent.backend.statistics.metrics') }}"size="sm"/><UButton color="primary" size="sm" :label="t('common.search')" @click="getStatistics" /></div><!-- 统计图表 --><div v-if="loading" class="flex justify-center py-8">{{ t('common.loading') }}</div><div v-else-if="!statistics" class="text-center py-8 text-muted-foreground">{{ t('ai-agent.backend.statistics.empty') }}</div><div v-else><div ref="chartRef" class="w-full h-[400px] mb-4"></div><!-- 统计卡片 --><div class="grid grid-cols-1 md:grid-cols-3 gap-4"><UCard variant="outlined"><div class="text-sm text-muted-foreground">{{ t('ai-agent.backend.statistics.totalUsage') }}</div><div class="text-2xl font-bold mt-1">{{ statistics.totalUsage }}</div></UCard><UCard variant="outlined"><div class="text-sm text-muted-foreground">{{ t('ai-agent.backend.statistics.averageResponseTime') }}</div><div class="text-2xl font-bold mt-1">{{ statistics.averageResponseTime }}ms</div></UCard><UCard variant="outlined"><div class="text-sm text-muted-foreground">{{ t('ai-agent.backend.statistics.successRate') }}</div><div class="text-2xl font-bold mt-1">{{ (statistics.successRate * 100).toFixed(2) }}%</div></UCard></div></div></div>
</template>

6. 数据结构与模型

6.1 智能体实体

interface Agent {id: string;name: string;description?: string;createMode: string;avatar?: string;chatAvatar?: string;rolePrompt?: string;showContext: boolean;showReference: boolean;enableFeedback: boolean;enableWebSearch: boolean;userCount: number;modelConfig?: ModelConfig;billingConfig?: ModelBillingConfig;datasetIds?: string[];openingStatement?: string;openingQuestions?: string[];quickCommands?: QuickCommandConfig[];autoQuestions?: AutoQuestionsConfig;formFields?: FormFieldConfig[];formFieldsInputs?: Record<string, any>;mcpServerIds?: string[];isPublished: boolean;isPublic: boolean;publishToken?: string;apiKey?: string;createBy: string;publishConfig?: {allowOrigins?: string[];rateLimitPerMinute?: number;showBranding?: boolean;allowDownloadHistory?: boolean;};thirdPartyIntegration?: ThirdPartyIntegrationConfig;tags?: Tag[];
}
### 6.2 智能体日志实体
```typescript
interface AgentLog {id: string;agentId: string;level: "debug" | "info" | "warn" | "error";message: string;stacktrace?: string;context?: Record<string, any>;timestamp: string;createBy: string;
}

6.3 智能体统计实体

interface AgentStatistics {agentId: string;timeSeries: string[];usage: number[];responseTime: number[];successRate: number[];totalUsage: number;averageResponseTime: number;totalRequests: number;successRequests: number;failureRequests: number;
}

7. 性能与安全

7.1 权限体系

  • 基于角色的访问控制(RBAC)
  • 支持资源级别的权限控制
  • 支持数据级别的权限控制
  • 支持动态权限分配

7.2 权限实现

// 权限控制工具函数
export function useAccessControl() {const user = useUser();// 检查用户是否有指定权限码function hasAccessByCodes(codes: string[]): boolean {if (!user.value || !user.value.roles || user.value.roles.length === 0) return false;if (user.value.isSuperAdmin) return true;const userPermissions = new Set<string>();user.value.roles.forEach((role) => {role.permissions.forEach((permission) => {userPermissions.add(permission.code);});});return codes.some((code) => userPermissions.has(code));}// 检查用户是否有指定角色function hasRole(roleCodes: string[]): boolean {if (!user.value || !user.value.roles || user.value.roles.length === 0) return false;if (user.value.isSuperAdmin) return true;const userRoleCodes = user.value.roles.map((role) => role.code);return roleCodes.some((code) => userRoleCodes.includes(code));}return {hasAccessByCodes,hasRole,};
}// 在页面中使用权限控制
<script setup lang="ts">
const { hasAccessByCodes } = useAccessControl();const navigationItems = computed(() => {return [hasAccessByCodes(["ai-agent:detail"]) ? {label: t("ai-agent.backend.menu.arrange"),icon: "i-lucide-radar",to: useRoutePath("ai-agent:detail", {id: agentId.value as string,}),} : null,hasAccessByCodes(["ai-agent:publish"]) ? {label: t("ai-agent.backend.menu.publish"),icon: "i-lucide-radio-tower",to: useRoutePath("ai-agent:publish", {id: agentId.value as string,}),} : null,// ... 其他菜单项].filter(Boolean);
});
</script>

8. RBAC权限控制

8.1 智能体管理接口

8.1.1 获取智能体列表
GET /api/console/ai/agent/list

请求参数:

interface QueryAgentDto {page: number;pageSize: number;keyword?: string;tags?: string[];isPublished?: boolean;isPublic?: boolean;
}

响应参数:

interface AgentListResponse {list: Agent[];total: number;page: number;pageSize: number;
}
8.1.2 创建智能体
POST /api/console/ai/agent

请求参数:

interface CreateAgentDto {name: string;description?: string;createMode: string;avatar?: string;chatAvatar?: string;rolePrompt?: string;showContext: boolean;showReference: boolean;enableFeedback: boolean;enableWebSearch: boolean;datasetIds?: string[];openingStatement?: string;openingQuestions?: string[];formFields?: FormFieldConfig[];tagIds?: string[];
}

响应参数:

interface AgentResponse {agent: Agent;
}
8.1.3 更新智能体配置
PUT /api/console/ai/agent/{id}/config

请求参数:

interface UpdateAgentConfigDto {modelConfig?: ModelConfig;datasetConfig?: DatasetConfig;formConfig?: FormConfig;thirdPartyConfig?: ThirdPartyIntegrationConfig;
}

响应参数:

interface AgentResponse {agent: Agent;
}
8.1.4 发布智能体
POST /api/console/ai/agent/{id}/publish

请求参数:

interface PublishAgentDto {version: string;releaseNotes?: string;publishScope?: "private" | "public";allowOrigins?: string[];rateLimitPerMinute?: number;showBranding?: boolean;
}

响应参数:

interface AgentResponse {agent: Agent;
}

8.2 智能体日志接口

8.2.1 获取智能体日志
GET /api/console/ai/agent/{id}/logs

请求参数:

interface QueryAgentLogsDto {page: number;pageSize: number;level?: "debug" | "info" | "warn" | "error" | "all";keyword?: string;startTime?: string;endTime?: string;
}

响应参数:

interface AgentLogResponse {list: AgentLog[];total: number;page: number;pageSize: number;
}

8.3 智能体统计接口

8.3.1 获取智能体统计
GET /api/console/ai/agent/{id}/statistics

请求参数:

interface QueryAgentStatisticsDto {timeRange: "24h" | "7d" | "30d" | "90d" | "custom";metrics?: ("usage" | "responseTime" | "successRate" | "requestCount")[];startTime?: string;endTime?: string;
}

响应参数:

interface AgentStatisticsResponse {statistics: AgentStatistics;
}

6.2 智能体配置实体

interface AgentConfig {id: string;name: string;type: string;content: any;createdAt: Date;updatedAt: Date;
}

6.3 智能体对话记录实体

interface AgentChatRecord {id: string;agentId: string;userId: string;sessionId: string;messages: AgentChatMessage[];createdAt: Date;updatedAt: Date;
}

10. 部署与维护

7.1 智能体管理接口

接口名称方法路径功能描述
智能体列表GET/api/v1/ai/agent获取智能体列表
创建智能体POST/api/v1/ai/agent创建新智能体
智能体详情GET/api/v1/ai/agent/{id}获取智能体详情
更新智能体PUT/api/v1/ai/agent/{id}更新智能体信息
删除智能体DELETE/api/v1/ai/agent/{id}删除智能体
批量删除智能体POST/api/v1/ai/agent/batch-delete批量删除智能体

7.2 智能体配置接口

接口名称方法路径功能描述
配置列表GET/api/v1/ai/agent/config获取配置列表
创建配置POST/api/v1/ai/agent/config创建新配置
配置详情GET/api/v1/ai/agent/config/{id}获取配置详情
更新配置PUT/api/v1/ai/agent/config/{id}更新配置信息
删除配置DELETE/api/v1/ai/agent/config/{id}删除配置

7.3 智能体发布接口

接口名称方法路径功能描述
发布智能体POST/api/v1/ai/agent/{id}/publish发布智能体
撤销发布POST/api/v1/ai/agent/{id}/unpublish撤销智能体发布
发布历史GET/api/v1/ai/agent/{id}/publish-history获取发布历史

8. 性能与安全

8.1 性能优化

  • 使用无限滚动加载智能体列表,减少初始加载时间
  • 使用缓存机制缓存智能体的配置信息
  • 使用异步加载组件,提高页面加载速度
  • 使用CDN加速静态资源的加载

8.2 安全措施

  • 使用JWT进行身份认证
  • 使用RBAC进行权限控制
  • 使用HTTPS加密数据传输
  • 对敏感数据进行加密存储
  • 对API请求进行限流和防刷

9. API接口文档

9.1 部署方式

  • 使用Docker容器化部署
  • 使用Kubernetes进行容器编排
  • 使用CI/CD工具自动化部署

9.2 维护措施

  • 定期备份数据库
  • 定期更新系统和依赖包
  • 监控系统的性能和可用性
  • 日志记录和分析
  • 故障排查和恢复

10. 总结

本文档详细介绍了控制台智能体菜单和页面的技术架构,包括系统架构、模块划分、核心功能实现、数据结构与模型、接口设计、性能与安全、部署与维护等方面。通过本文档,开发团队可以清晰地了解控制台智能体菜单和页面的技术实现,为后续的开发和维护提供指导。

http://www.dtcms.com/a/611550.html

相关文章:

  • 保定网站制作系统陕西省网站开发
  • 如何在跨部门沟通失误后进行协调与澄清
  • VS2010 C语言编译器使用教程 | 如何高效配置和优化C语言编译环境
  • 常州网站建设要多少钱濮阳免费网站建设
  • 学了lamp做网站就足够了吗无忧中英繁企业网站系统 完整
  • ubuntu:beyond compare 4 This license key has been revoked 解决办法
  • 基于OSip协议栈的GB28181视频平台--jrtp传输过程中作为接收方不发送rtcp包问题处理
  • java加密启动报错
  • SpringAOP、连接点、通知类型、通知顺序、切入点表达式
  • 平面设计师参考网站开发公司总经理竞聘报告
  • 手机可以看的网站如何查看网站是什么语言做的
  • 电源完整性11-电容安装电感的影响因素
  • 手机如何做车载mp3下载网站互联网公司排名深信服
  • 电商网站建设定制北京网站定制价格表
  • 水利网站建设管理汇报广告网站制作多少钱
  • 新建茶叶网站文章内容建设电子商务网站建设工资
  • SAP 如何恢复电子表格EXCEL导出允许选择格式
  • 瓦房店 网站建设二级域名怎么解析
  • 国外做化学申报的网站文化类网站是不是休闲娱乐类网站
  • 最新版LangChain 1.0快速入门介绍
  • 广州开发网站服务设计一个电商网站的首页
  • 单页网站开发网站开发初学
  • 怎样建公司网站有什么网站可以做宣传图片
  • 易缴缴:开启注册资金实缴无忧新时代
  • Java基础——数组1
  • 关于做公司网站成都企业管理培训课程
  • 新开传奇手游发布网站网站首页设计多少钱
  • 设计企业门户网站org是国外的网站吗
  • ACL 2025论文分享|一种同时支持文字、语音、草图、艺术图和低分辨率图等多模态内容检索的新框架Uni-Retrieval
  • 免费在线网站xp系统建设网站