可视化天生适配:Vue 前端直接做集群面板、状态监控、员工管理
流式体验更强:原生 SSE/WebSocket 适配打字机流式回答
# AI 模型请求 + 轻量向量检索npm install openai ai chalk
openai:统一模型请求,兼容所有国产模型(兼容OpenAI格式)
ai:Vercel AI SDK,原生支持流式输出、Agent 调用规范
chalk:服务端日志染色,集群运行状态可视化
// server/config/agent-cluster.ts// 纯TS实现多数字员工集群配置,零Pythonexport type AgentItem = {id: stringname: stringavatar: stringdesc: stringskills: string[]systemPrompt: string}// 数字员工集群池export const agentCluster: AgentItem[] = [{id: 'customer-agent',name: '智能客服员工',avatar: '/avatar/service.png',desc: '负责用户咨询、常见问题解答、售后引导',skills: ['问答咨询', '售后解答', '话术引导'],systemPrompt: '你是专业的企业智能客服,语气亲切、回答简洁,专注解答用户业务咨询问题。'},{id: 'article-agent',name: '文案创作员工',avatar: '/avatar/write.png',desc: '负责文章撰写、公众号文案、内容润色、摘要总结',skills: ['文案创作', '内容润色', '摘要提炼'],systemPrompt: '你是资深文案创作专家,擅长撰写通顺、优质、适合公众号发布的技术与科普文章。'},{id: 'code-agent',name: '研发技术员工',avatar: '/avatar/code.png',desc: '负责代码解答、BUG修复、技术讲解、方案设计',skills: ['代码答疑', '技术科普', '方案输出'],systemPrompt: '你是资深全栈工程师,擅长Nuxt3、Vue、Node开发,回答专业、简洁、可落地。'},{id: 'data-agent',name: '数据整理员工',avatar: '/avatar/data.png',desc: '负责文本总结、数据梳理、内容归类、信息提炼',skills: ['数据总结', '文本提炼', '信息归类'],systemPrompt: '你是专业数据整理助手,擅长提炼核心信息、总结长文本、归纳内容要点。'}]// 根据任务自动匹配最优Agentexport const matchBestAgent = (query: string): AgentItem => {if (/代码|开发|BUG|Nuxt|Vue|前端|后端/.test(query)) {return agentCluster.find(item => item.id === 'code-agent')!}if (/文案|文章|写作|润色|公众号/.test(query)) {return agentCluster.find(item => item.id === 'article-agent')!}if (/数据|总结|提炼|归纳/.test(query)) {return agentCluster.find(item => item.id === 'data-agent')!}// 默认客服员工return agentCluster.find(item => item.id === 'customer-agent')!}
# 兼容 DeepSeek/通义千问/OpenAI 任意模型AI_API_KEY=你的模型密钥AI_API_BASE=https://api.deepseek.com/v1AI_MODEL=deepseek-chat
// 纯TS轻量RAG,无需任何Python依赖// 私有知识库内容,可替换为企业文档、手册、官网内容const KNOWLEDGE_BASE = ['Nuxt3 是基于Vue3的元框架,内置Nitro全栈服务引擎,可纯JS/TS实现AI Agent全栈开发','2026年前端全栈核心趋势:Nuxt3全栈 + AI Agent + 可视化智能集群','数字员工Agent集群可实现多角色分工、自动任务调度、智能问答与自动化工作流','Nuxt3 + Nitro 可以完全抛弃Python,独立完成中小型AI商用系统落地']// 简单相似度匹配(轻量够用,生产可升级精准向量)export const searchKnowledge = (query: string, top = 2) => {return KNOWLEDGE_BASE.filter(item => item.includes(query) || query.includes(item.slice(0, 10))).slice(0, top)}
import { OpenAI } from 'openai'import { searchKnowledge } from '~/server/utils/rag'import { matchBestAgent } from '~/server/config/agent-cluster'export default defineEventHandler(async (event) => {const config = useRuntimeConfig()const body = await readBody(event)const { query } = body// 1. 智能匹配最优数字员工const agent = matchBestAgent(query)// 2. 检索私有知识库const relateDocs = searchKnowledge(query)const context = relateDocs.join('\n')// 3. 初始化模型客户端const openai = new OpenAI({apiKey: config.public.AI_API_KEY,baseURL: config.public.AI_API_BASE})// 4. SSE 流式响应头setResponseHeaders(event, {'Content-Type': 'text/event-stream','Cache-Control': 'no-cache','Connection': 'keep-alive'})// 5. 组装Agent专属Prompt(人设+知识库+用户问题)const stream = await openai.chat.completions.create({model: config.public.AI_MODEL,stream: true,messages: [{ role: 'system', content: `${agent.systemPrompt}\n参考知识库内容:${context}` },{ role: 'user', content: query }]})// 6. 持续推送流式片段for await (const chunk of stream) {const text = chunk.choices[0]?.delta?.content || ''if (text) {await sendStream(event, JSON.stringify({ text, agent: agent.name }))}}// 结束标记await sendStream(event, '[DONE]')})const sendStream = async (event: any, data: string) => {return new Promise(resolve => {event.node.res.write(`data: ${data}\n\n`)resolve(true)})}
import { agentCluster } from '~/server/config/agent-cluster'export default defineEventHandler(() => {// 模拟在线状态,可扩展为真实任务负载监控const list = agentCluster.map(item => ({...item,status: 'online',taskCount: Math.floor(Math.random() * 5)}))return { code: 200, data: list }})
<template><divclass="cluster-container"><h2>🚀 Nuxt3 数字员工 Agent 集群控制台</h2><!-- 集群员工列表 --><divclass="agent-list"><divclass="agent-card"v-for="item in agentList":key="item.id"><h4>{{ item.name }}</h4><p>状态:{{ item.status === 'online' ? '✅ 在线' : '❌ 离线' }}</p><p>当前任务数:{{ item.taskCount }}</p><p>技能:{{ item.skills.join('、') }}</p></div></div><!-- 对话区域 --><divclass="chat-box"><divv-for="(item, idx) in chatList":key="idx"class="chat-item"><pv-if="item.role === 'user'"><strong>你:</strong>{{ item.content }}</p><pv-else><strong>{{ item.agent }}:</strong>{{ item.content }}</p></div></div><textareav-model="question"placeholder="输入任务,自动分配对应数字员工"></textarea><button @click="sendMsg":disabled="loading">{{ loading ? '🧠 员工思考中...' : '发送任务' }}</button></div></template><scriptsetuplang="ts">import { ref } from 'vue'const agentList = ref([])const question = ref('')const loading = ref(false)const chatList = ref([])// 获取集群员工列表const getAgentList = async () => {const res = await $fetch('/api/agent/list')agentList.value = res.data}// SSE 流式请求const sendMsg = async () => {if (!question.value || loading.value) returnloading.value = true// 追加用户提问chatList.value.push({ role: 'user', content: question.value })const nowIndex = chatList.value.lengthchatList.value.push({ role: 'agent', content: '', agent: '' })// 建立流式连接const eventSource = new EventSource('/api/agent/stream', {method: 'POST',headers: { 'Content-Type': 'application/json' },body: JSON.stringify({ query: question.value })})eventSource.onmessage = (e) => {if (e.data === '[DONE]') {eventSource.close()loading.value = falsequestion.value = ''return}const res = JSON.parse(e.data)chatList.value[nowIndex].content += res.textchatList.value[nowIndex].agent = res.agent}eventSource.onerror = () => {eventSource.close()loading.value = false}}onMounted(() => {getAgentList()})</script><stylescoped>.cluster-container { max-width: 1200px; margin: 0 auto; padding: 20px; }.agent-list { display: grid; grid-template-columns: 1fr 1fr 1fr 1fr; gap: 16px; margin-bottom: 30px; }.agent-card { border: 1px solid #eee; padding: 16px; border-radius: 12px; }.chat-box { border: 1px solid #eee; padding: 20px; border-radius: 12px; min-height: 300px; margin-bottom: 16px; }textarea { width: 100%; height: 100px; padding: 12px; border-radius: 8px; border: 1px solid #ddd; }button { margin-top: 12px; padding: 10px 30px; background: #409eff; color: #fff; border: none; border-radius: 6px; cursor: pointer; }button:disabled { background: #999; }</style>
runtimeConfig: {public: {AI_API_KEY: process.env.AI_API_KEY,AI_API_BASE: process.env.AI_API_BASE,AI_MODEL: process.env.AI_MODEL}}
# 打包npm run build# PM2 守护启动pm2 start ecosystem.config.js# 开机自启+日志自动清理pm2 startuppm2 save
维度 | 传统Python Agent方案 | 纯Nuxt3 集群方案 |
|---|---|---|
技术栈 | 前后端割裂、双栈维护 | 统一TS,一套代码全栈闭环 |
部署难度 | Python环境、虚拟环境、依赖冲突 | 零环境依赖、一键部署 |
流式体验 | 需手动封装SSE,体验一般 | Nitro原生支持,极致流畅 |
可视化能力 | 需单独开发前端面板 | 原生Vue可视化,开箱即用集群控制台 |
运维成本 | 高 | 极低,复用Nuxt企业运维体系 |
持久化记忆:接入 Prisma + MySQL 存储对话记录、员工任务日志
精准向量RAG:接入 NuxtHub AI / Cloudflare 向量能力,替代简易检索
任务队列集群:实现多Agent负载均衡、任务排队、并发控制
权限系统:增加登录鉴权、员工管理后台、任务统计
定时Agent任务:Nitro定时任务,自动日报、自动整理数据、自动推送