十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

从零搭建AI对话网站:前后端分离架构与Spring Boot+Vue3全栈实践

从零搭建AI对话网站:前后端分离架构与Spring Boot+Vue3全栈实践 简介这是一套开箱即用的AI对话系统网站源码面向人工智能初学者、Web开发者及技术爱好者旨在帮助用户快速搭建具备多模型接入能力的智能对话平台。资源包含完整前后端代码、详细部署教程及配置说明支持对接OpenAI、阿里云、腾讯云等主流大模型API可实现自然语言理解、上下文对话、文案生成、代码编写、翻译等实用功能。压缩包共1612个文件涵盖783个JavaScript交互逻辑、192个HTML页面结构、191个PNG图标资源、120个CSS样式文件、118个Vue组件及39个PHP后端接口脚本整体大小为18.79MB结构清晰、模块解耦便于二次开发与功能扩展。目前已有1904人学习下载配套材料包括数据库SQL初始化脚本、SSL证书配置示例、多主题样式文件如materialdesignicons.min.css、bootstrap.min.css及环境适配说明PHP7.4MySQL5.6显著降低部署门槛与调试成本。1. 项目概述从零构建一个属于自己的AI对话网站最近几年AI对话能力已经从实验室里的尖端科技变成了开发者甚至个人爱好者都能触手可及的工具。你可能用过一些在线AI聊天产品但有没有想过如果能自己搭建一个完全掌控界面、功能甚至对接不同的AI模型会是怎样的体验这个想法听起来很酷但实现路径在哪里今天我就以一个过来人的身份和你详细拆解如何从零开始搭建一个功能完整、前后端分离的AI对话系统网站。这不仅仅是把API接口调通那么简单它涉及到前端交互设计、后端服务编排、模型对接、会话管理、乃至部署上线的一整套工程实践。无论你是想学习全栈开发、为个人项目增加AI能力还是想深入理解现代Web应用与AI服务的整合这篇内容都能给你一份清晰的“施工图”。这个项目的核心价值在于“自主可控”。你不再受限于第三方平台的规则、费用或功能限制。你可以定制对话界面集成自己偏好的模型无论是开源的还是商业API设计独特的对话逻辑并将它无缝嵌入到你自己的产品生态中。整个过程我们将采用目前业界主流的前后端分离架构前端使用Vue 3构建响应式用户界面后端使用Spring Boot提供稳健的API服务通过清晰的职责划分让开发、测试和部署都变得更加高效和灵活。2. 核心架构设计与技术选型考量2.1 为什么选择前后端分离架构在开始敲代码之前我们先要定好房子的“骨架”。对于AI对话这类交互密集型的应用前后端分离Frontend-Backend Separation几乎是必然选择。你可以把它理解为餐厅的前厅和后厨前端Vue是优雅的餐厅前厅负责展示菜单、接收顾客点单用户输入、并呈现精美的菜肴AI回复后端Spring Boot是高效的后厨它处理具体的烹饪逻辑调用AI模型、管理食材库存会话历史、用户数据、并确保每一道菜都能准时、无误地送出。这种架构的优势非常明显开发并行与专业化前端和后端团队可以同时工作只需定义好“点菜单”API接口文档即可互不干扰。前端专注于用户体验和交互动效后端专注于业务逻辑和数据处理。高可维护性与可扩展性前后端解耦后任何一端的升级或替换都不会直接影响另一端。例如未来你想把Vue换成React或者把Spring Boot换成Go只要API契约不变迁移成本会低很多。提升性能与用户体验前端可以独立部署在CDN上实现资源的快速加载。通过异步请求Ajax/Fetch页面无需整体刷新就能获取新的AI回复对话体验如丝般顺滑。更适合现代部署流程可以轻松地结合Docker容器化技术将前端和后端分别打包成镜像实现敏捷的CI/CD持续集成/持续部署。2.2 技术栈的深度解析与选型理由接下来我们为“前厅”和“后厨”挑选具体的工具和材料。前端技术栈Vue 3 TypeScript Pinia Axios Element PlusVue 3选择了Vue 3而非React或Angular主要因其渐进式、易上手的特性以及其组合式APIComposition API对于复杂交互逻辑如流式输出、会话管理的出色组织能力。对于从后端转向全栈的开发者Vue的学习曲线更为平缓。TypeScriptAI对话项目涉及复杂的数据结构消息对象、模型配置、会话列表。TypeScript提供的静态类型检查能在编码阶段就捕获大量潜在错误比如错误的API响应字段访问这对提升大型项目的健壮性至关重要。Pinia作为Vue的官方状态管理库它比Vuex更简洁、对TypeScript支持更好。我们将用它来集中管理全局状态例如当前活跃的会话、用户设置如选择的AI模型、API密钥等。Axios一个强大且易用的HTTP客户端我们将用它来向后端发起请求。它的拦截器Interceptors功能非常实用可以统一处理请求头如添加认证Token、错误响应等。Element Plus基于Vue 3的桌面端组件库。它提供了丰富的、美观的UI组件如按钮、输入框、布局、对话框能极大加速我们的界面开发让我们更专注于业务逻辑而非样式细节。后端技术栈Spring Boot 3 JDK 17 Spring Security JWT MyBatis-Plus RedisSpring Boot 3Java生态中事实上的微服务框架标准。它通过“约定大于配置”的理念极大地简化了Spring应用的初始搭建和开发过程。其强大的自动配置、内嵌Web服务器如Tomcat和丰富的“Starter”依赖让我们能快速构建出生产级可用的RESTful API。JDK 17选择LTS长期支持版本保障了应用的稳定性和长期维护性。JDK 17引入的许多新特性和性能优化也为后端服务提供了更好的基础。Spring Security JWT安全是Web应用的基石。Spring Security提供了全面的认证和授权功能。我们将结合JWTJSON Web Token实现无状态的用户认证。用户登录后后端生成一个加密的Token返回给前端前端在后续请求中携带此Token后端验证Token有效性即可无需在服务器端保存会话非常适合分布式部署。MyBatis-Plus一个强大的MyBatis增强工具。它提供了通用的CRUD操作我们几乎不用写简单的SQL同时保留了MyBatis原生SQL的灵活性。用它来操作数据库管理用户信息、对话记录等效率非常高。Redis一个高性能的内存数据存储。在这个项目中Redis将扮演两个关键角色一是作为缓存缓存一些不常变化但频繁访问的数据如模型列表、系统配置二是作为会话消息临时存储虽然认证是无状态的但用户当前的对话上下文最近N条历史记录需要快速存取内存数据库Redis是最佳选择。AI模型对接层这是项目的灵魂。我们将设计一个可插拔的模型适配器层。核心是定义一个统一的AIModelService接口所有具体的模型实现如OpenAI GPT、国内大模型、开源Llama本地部署都实现这个接口。这样当需要切换或增加模型时只需新增一个实现类核心业务代码几乎不用改动。public interface AIModelService { /** * 发送消息到AI模型 * param request 包含消息列表、模型参数等的请求对象 * return AI的回复 */ CompletableFutureAIResponse chat(AIChatRequest request); /** * 流式发送消息到AI模型 * param request 请求对象 * param emitter 用于发送流式结果的SseEmitter */ void chatStream(AIChatRequest request, SseEmitter emitter); }注意模型API的选择需谨慎。公开的免费API通常有严格的频率和次数限制且稳定性无法保证。用于学习和测试可以但若计划投入实际使用务必考虑使用官方付费API或部署可靠的开源模型。绝对不要尝试寻找非正规渠道或绕过正常使用限制的方法这不仅是技术风险更涉及严重的合规问题。2.3 数据库设计要点我们需要一个关系型数据库如MySQL 8.0或PostgreSQL来持久化核心数据。主要设计以下几张表用户表 (user)存储用户基本信息用户名、加密密码、邮箱等。会话表 (conversation)每个对话会话一条记录关联用户ID包含会话标题、创建时间等。消息表 (message)核心表每条用户消息和AI回复都是一条记录。包含所属会话ID、发送者角色user/assistant、消息内容、模型名称、token消耗如果API返回、创建时间。这里建议使用text或longtext类型存储消息内容。API密钥表 (api_key)如果系统支持用户自带API密钥则需要此表安全地存储密钥务必加密存储。3. 前后端核心功能模块实现详解3.1 后端Spring Boot服务搭建与核心API设计首先使用 Spring Initializr 快速生成项目骨架选择依赖Spring Web, Spring Security, MyBatis Framework, MySQL Driver, Redis, Lombok。3.1.1 用户认证与安全配置在SecurityConfig配置类中我们需要放行登录、注册等公开接口并对其他API进行JWT令牌校验。创建一个JwtAuthenticationFilter过滤器将其添加到Spring Security的过滤器链中用于从请求头中提取并验证JWT Token。3.1.2 核心控制器Controller设计我们的核心API将围绕“会话”和“消息”展开。POST /api/auth/loginPOST /api/auth/register用户登录与注册。GET /api/conversations获取当前用户的会话列表。POST /api/conversations创建一个新的会话。DELETE /api/conversations/{id}删除一个会话。GET /api/conversations/{id}/messages获取某个会话下的所有消息历史。POST /api/chat核心接口发送一条新消息。这里需要处理两种模式普通模式后端同步调用AI API等待完整回复后一次性返回给前端。流式模式推荐使用Spring的SseEmitter实现服务器发送事件。后端接收到请求后立即返回一个SseEmitter对象给前端建立连接然后异步调用AI API如OpenAI的stream参数为true每当收到AI返回的一个数据块chunk就通过emitter.send()推送给前端实现打字机效果。3.1.3 服务层与模型适配器服务层ChatService是业务逻辑的核心。它接收控制器传来的消息处理流程如下验证用户和会话权限。将用户消息持久化到message表。从Redis或数据库中取出该会话的最近上下文例如最近10轮对话组装成AI API要求的格式如OpenAI的messages数组。调用AIModelService接口的具体实现例如OpenAIServiceImpl。收到AI回复后将回复内容持久化到message表。如果是流式输出则在收到每个数据块时即时推送并缓存最后再完整持久化。3.1.4 统一响应与异常处理使用ControllerAdvice创建一个全局异常处理器GlobalExceptionHandler将各种异常如参数校验失败、业务逻辑异常、认证失败、AI服务调用失败封装成统一的JSON响应格式返回给前端包含状态码、消息和可选数据。这能提供良好的API使用体验。3.2 前端Vue 3应用开发与关键交互实现前端项目使用Vite脚手架创建npm create vuelatest按需选择TypeScript, Pinia, Router等。3.2.1 状态管理设计Pinia我们定义一个useChatStore来管理所有与对话相关的状态。// stores/chat.ts export const useChatStore defineStore(chat, { state: () ({ activeConversationId: null as string | null, conversations: [] as Conversation[], // 会话列表 messages: [] as Message[], // 当前活跃会话的消息列表 loading: false, // 是否正在请求中 // ... 其他状态如模型列表、当前模型等 }), actions: { async sendMessage(content: string) { this.loading true; const currentConvId this.activeConversationId; // 1. 乐观更新先将用户消息添加到界面 this.messages.push({role: user, content}); try { // 2. 调用后端流式接口 const response await fetch(/api/chat/stream, { method: POST, headers: { Content-Type: application/json, Authorization: Bearer ${token}}, body: JSON.stringify({conversationId: currentConvId, message: content}) }); const reader response.body?.getReader(); const decoder new TextDecoder(utf-8); let aiMessageContent ; // 3. 创建AI消息占位符 this.messages.push({role: assistant, content: , streaming: true}); const aiMessageIndex this.messages.length - 1; if (reader) { while (true) { const {done, value} await reader.read(); if (done) break; const chunk decoder.decode(value); // 处理SSE格式数据解析出content片段 const lines chunk.split(\n); for (const line of lines) { if (line.startsWith(data: )) { const data line.replace(data: , ); if (data [DONE]) break; const parsed JSON.parse(data); const delta parsed.choices[0]?.delta?.content; if (delta) { aiMessageContent delta; // 4. 实时更新界面上的AI消息内容 this.messages[aiMessageIndex].content aiMessageContent; } } } } } // 5. 流式结束更新状态 this.messages[aiMessageIndex].streaming false; // 可选触发一次会话列表更新以更新会话标题有时用第一条AI回复生成标题 await this.fetchConversations(); } catch (error) { // 错误处理移除乐观更新的消息或显示错误 console.error(发送消息失败:, error); this.messages.pop(); // 移除用户消息 // 显示错误提示 } finally { this.loading false; } } } })3.2.2 核心页面组件Layout.vue整体布局包含头部用户信息、模型切换、侧边栏会话列表和主内容区。ConversationSidebar.vue侧边栏组件展示会话列表提供新建、删除、切换会话的功能。ChatWindow.vue核心聊天窗口。包含消息列表展示区遍历chatStore.messages根据role区分用户和AI渲染气泡。对于流式输出中的AI消息可以添加一个闪烁的光标动画。输入区一个textarea或div支持富文本用于输入一个发送按钮。需要处理文本换行、粘贴、Enter键发送CtrlEnter换行等交互细节。Login.vueRegister.vue登录注册页面。3.2.3 路由与导航守卫使用Vue Router管理路由。配置导航守卫在进入需要认证的页面如/chat前检查本地是否存在有效的JWT Token如果没有则重定向到登录页。3.3 流式对话效果的实现细节这是提升用户体验的关键。前端通过EventSource或fetch读取流式响应。后端流式响应在Spring Boot控制器中方法返回SseEmitter对象。在服务层调用AI API时使用支持回调的HTTP客户端如WebClient或OkHttp每当收到一个SSE数据块就调用emitter.send(data)。最后在完成或出错时调用emitter.complete()或emitter.completeWithError()。前端流式接收如上文sendMessage动作所示使用fetch的response.body.getReader()来读取流。更简单的方式是使用EventSource但它只支持GET请求且头部自定义能力弱。对于POST请求fetch流式读取是更通用的方案。UI渲染优化为了达到流畅的打字机效果每次接收到数据块就立即更新对应的Vue响应式数据。Vue的响应式系统会驱动视图更新。可以为正在接收的AI消息添加一个streaming: true的标志并在样式中为其末尾添加一个闪烁的光标动画。4. 项目部署与运维实战指南开发完成我们需要让它在互联网上跑起来。4.1 后端服务部署推荐使用Docker容器化部署这能保证环境一致性。编写Dockerfile基于openjdk:17-jdk-slim镜像将打包好的Spring Boot Jar包复制进去设置启动命令。编写docker-compose.yml这是关键它定义了多容器应用。我们的应用至少需要三个服务version: 3.8 services: mysql: image: mysql:8.0 container_name: ai-chat-mysql environment: MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD} MYSQL_DATABASE: ai_chat volumes: - mysql_data:/var/lib/mysql ports: - 3306:3306 networks: - ai-network redis: image: redis:7-alpine container_name: ai-chat-redis ports: - 6379:6379 networks: - ai-network backend: build: ./backend # Dockerfile所在目录 container_name: ai-chat-backend depends_on: - mysql - redis environment: SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/ai_chat?useUnicodetruecharacterEncodingutf8useSSLfalse SPRING_DATASOURCE_USERNAME: root SPRING_DATASOURCE_PASSWORD: ${DB_ROOT_PASSWORD} SPRING_REDIS_HOST: redis SPRING_REDIS_PORT: 6379 # 其他环境变量如AI_API_KEY等 ports: - 8080:8080 networks: - ai-network volumes: mysql_data: networks: ai-network: driver: bridge部署将整个项目目录包含docker-compose.yml上传到云服务器。在服务器上安装Docker和Docker Compose然后运行docker-compose up -d所有服务就会按顺序启动并互联。4.2 前端静态资源部署前端项目通过npm run build生成静态文件在dist目录。这些文件可以通过多种方式部署Nginx托管在云服务器上安装Nginx将dist目录下的文件复制到Nginx的HTML目录如/usr/share/nginx/html并配置一个server块将域名指向该目录。同时需要配置反向代理将/api开头的请求转发到后端服务http://localhost:8080。server { listen 80; server_name your-domain.com; # 你的域名 location / { root /usr/share/nginx/html; index index.html; try_files $uri $uri/ /index.html; # 支持Vue Router的history模式 } location /api/ { proxy_pass http://backend:8080/; # 注意这里指向docker-compose中的服务名 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }对象存储 CDN对于更专业的部署可以将dist目录上传至云服务商的对象存储如阿里云OSS、腾讯云COS并开启静态网站托管和CDN加速。这种方式成本低、扩展性强、访问速度快。4.3 域名、HTTPS与安全加固域名解析在域名服务商处将你的域名A记录解析到云服务器的公网IP。HTTPS证书使用Let‘s Encrypt免费申请SSL证书并通过Certbot工具自动配置到Nginx。这是保护用户数据尤其是登录凭证在传输过程中不被窃听的必备步骤。安全加固后端确保Spring Security配置正确防止CSRF、XSS、SQL注入等常见攻击。对用户输入的提示词Prompt进行必要的过滤和长度限制。数据库不要使用默认端口和弱密码。限制数据库服务的公网访问在云服务器安全组或Docker网络层面只允许后端应用访问。API密钥管理后端使用的AI服务API密钥务必通过环境变量注入切勿硬编码在代码中。如果支持用户自带密钥必须在前端加密传输后端加密存储。5. 开发与部署中的常见问题与解决方案在实际搭建过程中你几乎一定会遇到下面这些问题。这里是我踩过坑后总结的经验。5.1 跨域问题CORS在本地开发时前端运行在localhost:5173后端在localhost:8080浏览器会因同源策略阻止请求。解决方案在后端Spring Boot中通过CrossOrigin注解或全局的WebMvcConfigurer配置CORS。生产环境中通常由Nginx反向代理解决因为前后端在同一域名下不同路径不存在跨域。5.2 流式响应中断或连接超时前端长时间没收到数据连接可能会被浏览器或服务器断开。解决方案后端设置SseEmitter的超时时间例如new SseEmitter(60 * 1000L)60秒。在流式传输过程中可以定期发送空注释行: keep-alive\n\n来保持连接活跃。前端做好连接中断的UI提示和重连逻辑。当连接关闭时提示用户“连接已断开”并提供“重新连接”或“重新发送”的按钮。5.3 对话上下文长度管理与Token消耗AI模型通常有上下文窗口限制如4096、8192 tokens。如果无限制地将所有历史消息都发送给API很快就会超出限制导致请求失败或高昂费用。解决方案实现一个智能上下文窗口策略。固定轮数只发送最近N轮对话例如10轮。简单有效但可能丢失早期的重要信息。基于Token计数更精细的策略。从最新的消息开始向前累加历史消息的token数需要估算例如使用tiktoken库或按字符粗略估算直到接近模型的最大限制留出一些空间给本次回复。将筛选出的消息列表发送给AI。总结压缩对于超长的对话可以尝试调用AI本身对早期历史进行总结然后将总结作为一条系统消息放入上下文替代原始的长篇历史。这属于高级优化策略。5.4 生产环境性能与监控项目上线后需要关注其运行状态。数据库连接池确保在application.yml中正确配置了HikariCP等连接池参数如最大连接数、最小空闲连接等避免数据库连接耗尽。Redis缓存策略合理设置会话上下文的缓存过期时间例如30分钟无活动则清除防止内存被无效数据占满。日志记录使用SLF4J Logback记录详细的运行日志特别是AI API的请求和响应注意脱敏API Key、错误信息。将日志收集到ELKElasticsearch, Logstash, Kibana或类似系统中便于排查问题。基础监控使用Spring Boot Actuator暴露健康检查、指标等端点并集成Prometheus和Grafana进行可视化监控关注接口响应时间、错误率、JVM内存使用情况等。5.5 前端构建与部署优化路由模式Vue Router默认使用哈希模式URL带#如果想用更干净的History模式必须在Nginx配置中添加try_files $uri $uri/ /index.html;这条规则否则刷新非首页路由会得到404。公共路径如果前端不是部署在域名根路径下例如https://your-domain.com/chat/需要在vite.config.ts中配置base: /chat/否则静态资源路径会出错。Docker化前端你也可以为前端编写Dockerfile使用Nginx镜像来托管构建产物然后在docker-compose.yml中统一管理前端、后端、数据库服务实现一键部署。整个项目从技术选型到部署上线的链路很长但每一步拆解开来都是扎实的现代Web开发实践。完成这个项目你收获的不仅仅是一个AI对话网站更是一套应对复杂全栈项目的完整方法论。遇到问题多查官方文档、多调试每一个坑爬过去都是宝贵的经验。本文还有配套的精品资源点击获取
返回列表