带毕业设计这件事,很多同学一上来就问“这个系统怎么做”,但真正劝退人的往往不是代码,而是前期需求压根没想清楚。拿“基于AI+Spring Boot+微信小程序的数字博物馆系统”这个题目来说,它把当下最热的两条线都占了:一条是AI落地,另一条是前后端分离的完整工程化开发。如果你正在为这个选题发愁,或者已经折腾了一两周还卡在架构上,这篇文章就是按实战辅导的思路来写的——从需求拆分、技术选型逻辑、后端接口设计、小程序端实现,到论文结构和答辩话术,一次性讲透。
先说结论:这个课题并不算特别难,但它是一个典型的“看起来高级、做起来考验基本功”的综合项目。它真正考察的不是单个技术有多深,而是你能不能把AI能力、业务表结构、移动端交互、权限控制这些串成一条完整的链路。只要链路通了,代码量其实不多,论文也有得写,答辩也有得讲。
1. 项目全景与目标拆解
1.1 这个系统到底是做什么的
数字博物馆系统,本质上就是把线下博物馆的藏品、展厅、讲解员、活动公告搬到线上,再叠加数字化互动能力。传统的管理系统只做“信息展示+后台增删改查”,而这个项目多出来的东西是“AI”,也就是让用户能够用自然语言提问,比如“这件青铜器的年代是什么”“馆里有哪些和丝绸相关的展品”,系统能基于藏品知识库给出回答,甚至可以结合知识图谱推荐关联展品。
这样一来,系统的核心角色就变成了三类:游客用户、后台管理员、AI服务模块。用户端在小程序里完成浏览、搜索、收藏、在线提问;后台在管理端完成藏品录入、展厅管理、用户管理、AI知识库维护;AI模块则负责处理用户的自然语言请求、返回流式或非流式的回答,并把问答记录落库,方便论文里做数据分析。
很多同学容易忽略的一点是:AI不一定要做得“很重”。毕业设计里,最稳妥的AI实现方式并不是从零训练模型,而是接入一个大模型API,把藏品信息加工成知识库或提示词上下文,再封装一层对话服务。这个思路成本低、效果稳定,而且能讲清楚技术链路,比硬造一个所谓的“AI模型”靠谱得多。
1.2 为什么选这个组合:技术选型背后的逻辑
先拆技术组合:AI + Spring Boot + 微信小程序。这三样东西分别对应算法能力、后端服务能力、前端触达能力,可以说覆盖了企业级项目中最常见的技术栈组合,也刚好是毕业生简历上最常出现的三个方向。
Spring Boot在毕设中的优势不是性能最强,而是生态成熟。它内置了Tomcat,把配置简化到了极致,配合Redis做缓存、MyBatis-Plus做ORM、JWT做登录态,基本上一个人也能轻松维护。更重要的是,市面上能找到的参考代码、技术博客、报错解决方案几乎是全网的,这对毕设阶段来说是最宝贵的资源。
微信小程序选得也很聪明。小程序不用开发两个端的App,一套代码跑在微信生态里,用户用完即走,天然适合博物馆这种低频但刚需的场景。对开发者来说,小程序从注册、开发、真机调试到上线发布,每一步都有官方文档,而且审核流程比App Store简单很多,时间上完全可控。
至于AI,放在这个项目里其实是两种能力的融合:一是AI导览对话,二是AI辅助管理。前者面向用户,后者可以在后台做藏品标签自动提取、文物断代辅助判断、敏感信息过滤等增强功能。哪怕只把第一种做好了,也足以撑起论文的算法设计章节。
1.3 这个选题适合谁,能锻炼什么能力
如果你Java基础一般,但能看懂Spring Boot的自动配置,那这个题完全能做。它不像单纯的中间件研究那么烧脑,也不像纯粹的算法项目那样对数学有高要求。它更看重的是工程整合能力,说直白一点就是:你能不能把模块拼起来,并且让它们稳定地跑起来。
做这个项目的过程中,你会被迫去覆盖以下能力点:数据库设计、RESTful API开发、JWT身份认证、HTTP请求跨域处理、小程序页面生命周期、组件通信、大模型API接入、前后端联调、服务器部署等。这任何一个单点拿出来都能写进简历,而且面试官听到你做了这个组合,第一反应会是“这人至少不是只会做增删改查”。
还有个隐藏价值:这个项目的演示效果好。小程序里和AI助手对话,能实时展示一轮完整的自然语言交互,这在答辩现场比你PPT里写一堆技术名词要有说服力得多。做技术的人都知道,项目演示能跑通,就已经赢了一半。
2. 从需求到架构:先把地基夯实
2.1 功能需求梳理:用户端、管理端、AI能力面
做需求梳理的时候,别一上来就写代码。先用一张功能清单把范围圈死,再决定哪些做、哪些砍。我建议按照“必要、重要、可选”三个层级来划分。
用户端必要功能包括:微信登录或账号登录、藏品分类浏览、藏品详情展示、关键词搜索、收藏功能、个人中心。重要功能包括:展厅导览、语音讲解、AI问答助手、浏览历史记录。可选功能包括:扫码看展、线上活动报名、分享海报、积分签到。
管理端必要功能包括:藏品管理(增删改查、图片上传)、展厅/分类管理、用户管理、AI对话记录查看。重要功能包括:藏品标签自动提取、首页轮播图配置。可选功能包括:数据统计报表、管理员操作日志。
AI能力面是重点。至少要做两类:第一类是RAG式导览问答,也就是先根据用户问题检索相关藏品,再把检索结果拼进提示词,交给大模型生成回答;第二类是实体抽取或标签推荐,例如对藏品描述文本进行自动摘要、提取器型、年代、材质等信息,辅助管理员录入。第一类是必做项,第二类有余力再做。
2.2 系统架构与数据流设计
架构上保持“小程序端 + 后端服务 + 数据库 + AI服务”的经典四层结构。前端不直接访问数据库,也不直接调大模型API,所有请求走后端网关。这样做有两个直接好处:一是密钥统一保存在后端,不会把大模型的API Key暴露到小程序端;二是可以在后端做统一的鉴权、限流、日志记录,也方便后期加缓存和消息队列。
数据流上,核心链路有三条:
- 浏览链路:用户打开小程序 -> 请求藏品列表 -> 后端从Redis读缓存,未命中则查数据库 -> 返回JSON -> 小程序渲染。
- 登录链路:用户微信授权 -> 后端调用微信接口获取openid -> 签发JWT -> 小程序保存token -> 后续请求携带token。
- AI问答链路:用户输入问题 -> 后端先调用检索服务从藏品库召回相关文本 -> 组装提示词 -> 调用大模型API -> 返回答案 -> 同步记录到问答历史表。
设计的时候想清楚这三条链路,后面写代码就不会乱。值得提醒的是,AI问答一定要加一个“先检索、后生成”的环节,不要直接把用户问题丢给大模型让它自由发挥。否则模型很容易答非所问,或者说出一堆和馆藏无关的百科内容,看起来很像那么回事,但实际上没用到博物馆数据,论文里也不好写。
2.3 数据库核心表设计思路
数据库不需要设计得太复杂,但表之间的关系必须清晰。我用的表结构大致是这样:
| 数据表 | 核心字段 | 说明 |
|---|---|---|
| user | id, openid, nickname, avatar, phone | 用户表,openid唯一 |
| collection | id, name, dynasty, category_id, description, image_url, audio_url, status | 藏品表,存文字介绍和多媒体资源 |
| category | id, name, sort | 分类表,对应陶瓷、书画、青铜等 |
| exhibit | id, title, cover, start_time, end_time, description | 展厅/展览表 |
| favorite | id, user_id, collection_id, create_time | 收藏表,做唯一索引 |
| chat_record | id, user_id, question, answer, model_name, create_time | AI问答记录表 |
| admin_user | id, username, password, role | 后台登录账号 |
从毕设论文的角度,表数量在6到8张之间最合适,太少显得没工作量,太多又容易把自己绕进去。关键在关联合理:user和favorite是一对多,collection和category是多对一,chat_record记录用户openid但不做强外键也行,因为历史记录即使用户删了也不影响业务。
一个实战细节:数据库的时间字段建议统一用datetime类型,Java实体类用LocalDateTime,避免用Date导致的时区问题。MySQL的时区设置也检查一下,有些同学部署到云服务器后,差8小时,就是时区和连接参数没配对造成的。
3. 后端 Spring Boot 开发的关键环节
3.1 项目初始化与分层结构
Spring Boot项目我建议直接用Spring Initializr生成,依赖选Spring Web、Validation、MySQL驱动、Redis。ORM层用MyBatis-Plus,它能减少大量重复的CRUD代码,对毕设来说非常友好。项目结构上,按包名分层,但不要过度设计,建议:
com.example.museum ├── common // 统一返回、异常处理、常量 ├── config // 配置类,跨域、拦截器、Redis ├── controller // 接口层 ├── service // 业务层 ├── mapper // 数据访问层 ├── entity // 数据库实体 ├── dto/vo // 入参出参对象 └── ai // AI相关服务分层的目的只有一个:让答辩的时候能说清楚“每一层职责是什么”。如果你把业务逻辑全写在Controller里,代码能跑,但论文和答辩都会很被动。哪怕多写几个类文件,也比后期重构强。
pom.xml里几个关键依赖如下,版本以实际稳定版为准,这里给的是一个可参考的组合:
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.3</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-api</artifactId> <version>0.11.5</version> </dependency> </dependencies>3.2 鉴权设计与接口规范
用户端登录,最省事的是微信小程序“一键登录”配合JWT。流程是:小程序调用wx.login拿到code,后端拿code去微信接口换openid,然后查表:如果是新用户就自动注册,最后生成JWT返回前端。这个方案不需要用户输手机号,用户体验也好。
JWT工具类里主要有三个方法:生成token、解析token、校验token。拦截器继承HandlerInterceptorAdapter,在preHandle里取出请求头的Authorization,校验token是否有效,并把用户信息放到ThreadLocal或请求上下文中,方便后续业务使用。
接口设计上,统一返回结构很重要。不要有的接口返回Map,有的返回String,到了前端联调时再各自解析,会非常痛苦。我一般用一个Result类:
public class Result<T> { private Integer code; private String message; private T data; public static <T> Result<T> ok(T data) { Result<T> r = new Result<>(); r.code = 200; r.message = "success"; r.data = data; return r; } public static <T> Result<T> error(String msg) { Result<T> r = new Result<>(); r.code = 500; r.message = msg; return r; } }再有就是跨域问题。小程序开发工具里开启“不校验合法域名”后,请求本机局域网IP的Spring Boot服务通常不会跨域,但如果你做了Web管理后台,或者用了网站端的调试页面,就必须要处理CORS。最简单的方式是在配置类里注册CorsFilter,或者实现WebMvcConfigurer的addCorsMappings方法,允许所有来源、所有请求头,避免联调阶段被跨域卡住。
3.3 AI能力的接入:提示词与检索策略
这是整个项目最亮眼的部分,也是同学们最容易翻车的地方。先说思路:把藏品数据转成文本片段,每件藏品对应一段描述。用户提问后,先在藏品库做一次相关性匹配,召回TopK藏品,然后把这些藏品的描述拼接到提示词里。提示词结构大概是:
你是一名数字博物馆导览助手。请根据以下馆藏资料回答用户问题。 馆藏资料: 1. 藏品名称:XXX 年代:XXX 描述:XXX 2. 藏品名称:YYY ... 用户问题:XXX后端调用大模型的代码,本质就是一个HTTP请求。Spring Boot里用RestTemplate或者WebClient都能做。考虑到毕设场景,RestTemplate就够用。这里给一个最小可用代码:
@Service public class ChatAiService { @Value("${ai.api-url}") private String apiUrl; @Value("${ai.api-key}") private String apiKey; private final RestTemplate restTemplate; public ChatAiService(RestTemplate restTemplate) { this.restTemplate = restTemplate; } public String chat(String question, List<String> contextList) { String context = String.join("\n", contextList); Map<String, Object> requestBody = new HashMap<>(); requestBody.put("model", "your-model"); requestBody.put("messages", List.of( Map.of("role", "system", "content", "你是一名数字博物馆导览助手,请基于提供的馆藏资料回答问题。"), Map.of("role", "user", "content", "馆藏资料:\n" + context + "\n\n问题:" + question) )); requestBody.put("temperature", 0.3); HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); headers.setBearerAuth(apiKey); HttpEntity<Map<String, Object>> entity = new HttpEntity<>(requestBody, headers); ResponseEntity<Map> response = restTemplate.postForEntity(apiUrl, entity, Map.class); // 根据返回结构解析,通常返回 choices[0].message.content Map data = response.getBody(); if (data != null && data.containsKey("choices")) { List<Map> choices = (List<Map>) data.get("choices"); Map message = (Map) choices.get(0).get("message"); return message.get("content").toString(); } return "抱歉,我暂时无法回答这个问题。"; } }搜索匹配这一步,最简单的是数据库模糊查询:SELECT * FROM collection WHERE description LIKE %问题关键词% 。但效果只能说勉强够用。如果想做得更“专业”,可以把藏品文本做分词,再算TF-IDF或向量相似度。毕设阶段用关键词匹配+标签匹配已经能满足演示需求,但如果论文里想加一章“基于向量的检索增强生成”,也可以引入文本向量化,把藏品描述预先转为向量存储,提问时再算余弦相似度,效果会明显好于模糊查询。
这里有一个经验要提前告诉各位:大模型生成的答案一定要加“兜底逻辑”。如果检索召回结果为空,就不要调用模型,直接返回“未找到相关馆藏信息”。否则模型没有上下文,会开始胡编,答辩时台下老师一问“这个答案是从哪来的”,场面会很尴尬。
4. 微信小程序端实现要点
4.1 小程序项目结构与页面划分
小程序端建议用原生框架,不要引入uni-app或Taro。原因很简单:原生框架调试方便,资料多,模板代码少,而且不会出现“原生坑没踩过又踩框架坑”的情况。项目目录一般分为pages、components、utils、api四块:
miniprogram ├── pages │ ├── index // 首页,轮播图+热门藏品 │ ├── list // 藏品列表,分类切换 │ ├── detail // 藏品详情 │ ├── chat // AI导览对话 │ ├── favorite // 收藏列表 │ └── mine // 个人中心 ├── components │ ├── collection-card │ └── empty-view ├── utils │ ├── request.js // 封装wx.request │ └── auth.js // token存储 └── app.jsonindex首页不需要做复杂功能,放一个swiper轮播、一组分类入口、一个“热门推荐”列表就够。重点是list和detail页面,这两个是用户使用频率最高的。detail页面除了展示图片、年代、描述之外,一定要放一个“切换到AI讲解”的入口按钮,跳转到chat页面并带上藏品ID,这样AI对话就不只是冷冰冰的通用问答,而是能结合具体藏品展开。这个交互设计答辩时拿出来讲,非常加分。
4.2 登录态处理与请求封装
小程序请求后端,最忌讳在每个页面里直接写wx.request,因为重复代码太多,而且token过期、错误提示这些逻辑会在每个页面复制一遍。正确的做法是先在utils/request.js里封装一层公共函数:
const request = (url, method, data) => { return new Promise((resolve, reject) => { wx.request({ url: getApp().globalData.baseUrl + url, method: method, data: data, header: { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + wx.getStorageSync('token') }, success: (res) => { if (res.data.code === 200) { resolve(res.data.data); } else if (res.data.code === 401) { // token过期,重新登录后再请求 wx.removeStorageSync('token'); wx.navigateTo({ url: '/pages/login/login' }); } else { wx.showToast({ title: res.data.message, icon: 'none' }); reject(res.data); } }, fail: (err) => reject(err) }); }); }; module.exports = { request };登录流程需要写一个专门的auth工具。用户第一次进入小程序,先检查本地有没有token,没有就自动执行wx.login,把code发给后端换token。这里有个细节:不要频繁调用wx.login,它是有有效期的,后端返回的token一般也能用一段时间,所以只要本地有token且没有抛出401,就不要重新登录,否则用户在页面间跳转时会反复白屏。
4.3 列表渲染、加载状态与性能优化
藏品列表是数据量比较大的页面,需要处理三件事:加载中状态、下拉刷新、触底加载更多。加载中状态用wx.showLoading,触底加载用一个布尔量isLoading防止重复请求。分页参数传给后端,后端用pageNum和pageSize控制,小程序端每次返回后把新数据追加到原有数组中。
性能上,最容易被忽略的是图片优化。藏品图片如果是高清大图,直接放到小程序的image组件里,会导致页面加载很慢。建议后端图片接口支持裁剪参数,或者在上传图片时统一压成宽750px左右的图。另外,列表页的图片用懒加载属性lazy-load,给image组件加上,实测加载速度提升非常明显。
还有一件事你必须知道:小程序上线时,所有请求域名必须是HTTPS且在小程序管理后台配置到“服务器域名白名单”里。在开发阶段可以用“详情 -> 本地设置 -> 不校验合法域名”来绕过,但答辩前如果想让评委扫体验版二维码,也必须先把后端接口部署到有HTTPS证书的服务器上。很多同学项目做完,输在这一步——不是代码不行,是域名没备案或证书没配好。
5. 实战过程与时间规划
5.1 分阶段推进,八周完成全流程
毕业设计最怕的不是题难,是前面拖太久、最后两周熬夜赶工。按我辅导学生的经验,八周是比较合理的节奏:
| 阶段 | 时间 | 核心任务 |
|---|---|---|
| 需求梳理与方案设计 | 第1周 | 功能清单、用例图、数据库表设计 |
| 后端基础框架 | 第2周 | 项目初始化、登录鉴权、统一返回 |
| 藏品/展厅/收藏模块 | 第3-4周 | 后端CRUD、图片上传 |
| AI模块 | 第5周 | 检索逻辑、大模型API接入 |
| 小程序端 | 第6-7周 | 首页、列表、详情、AI对话页面 |
| 部署联调与测试 | 第8周 | 云服务器部署、真机调试、修Bug |
这八周不是平均用力。前期方案设计决定了后面所有环节是否顺畅,所以我建议第一周哪怕不写代码,也要把表结构和接口清单列出来。接口清单可以简单到就是一个Excel表格,写明URL、请求方式、参数、返回结果。后端按这个清单写,小程序按这个清单调,两边不会互相等。
5.2 开发顺序:先打通最小闭环,再补细节
很多同学喜欢从后台管理页面开始做,先把所有CRUD写完再做小程序。我推荐反过来:先做最小的端到端链路,也就是“小程序查看藏品列表 -> 点进详情 -> 收藏”。这条链路打通之后,项目其实已经“活”了,后面再往里面加AI、加后台、加分类,都只是增量。
最小闭环具体怎么串?后端先只写collection的表、mapper、service、controller,然后写一个小程序页面,直接请求后端列表接口。这个过程中你会提前遇到一堆问题:接口地址怎么配、请求头怎么带、返回结构怎么解析、图片路径怎么拼。这些是后面开发会反复遇到的问题,越早踩坑越有利。
等最小闭环通了,再做AI对话。AI对话的最小闭环是:页面输入框 -> 调后端chat接口 -> 后端检索 -> 调大模型 -> 返回答案 -> 页面渲染。这个闭环也建议一天内打通,哪怕答案质量一般,先不要优化提示词,先确保链路通。之后再根据演示效果打磨提示词、增加上下文记忆、加入流式输出。
5.3 部署与演示环境搭建
部署这块,我强烈建议用一台云服务器,系统选Ubuntu 22.04,装好JDK 17、MySQL 8.0、Redis、Nginx。后端用Spring Boot打jar包,然后用Nginx做反向代理,把/api路径转发到后端端口。小程序访问的HTTPS域名,则通过Nginx配置SSL证书实现。
部署时容易踩的坑有三个:一是MySQL连接串里要加serverTimezone=Asia/Shanghai,否则时间乱;二是jar包的端口不能和Nginx冲突,建议后端用8081,Nginx监听443或80;三是静态图片要单独建一个目录,不要放在数据库里存base64,要有独立的图片访问路径。
答辩演示的时候,最稳妥的组合是:笔记本上开着后端服务和小程序开发者工具,手机上装体验版,演示流程固定为“首页 -> 列表 -> 详情 -> AI问答 -> 收藏”,控制在5分钟以内。不要在现场临时演示部署过程,也不要演示复杂的数据库操作,稳定性比炫技重要。
6. 常见问题与排错实录
6.1 接口请求失败、报错404或500
这类问题占毕设调试期的80%。404基本是路径写错或者Controller没扫描到,检查Controller类的包路径是否在启动类所在包的子包下面,以及@RequestMapping路径是否和你浏览器请求的路径一致。500则多半是空指针、数据库字段映射错误,打开后端日志看异常堆栈是最快的方式。
小程序端如果请求一直失败,先别急着查后端,先在浏览器里访问一下接口。浏览器能通、小程序不通,那基本是小程序域名校验的问题。浏览器不通,就抓后端日志。注意一个细节:Spring Boot的默认错误页不会返回给你具体的堆栈,如果没配全局异常处理器,建议先加一个@RestControllerAdvice,把异常信息打印出来,调试会舒服很多。
6.2 真机预览白屏或网络异常
开发工具里一切正常,但用手机扫码预览就白屏,十有八九是后端地址写成了localhost。手机访问的开发机局域网IP时,要保证手机和电脑在同一个WiFi下,而且电脑防火墙要放行对应端口。更建议的做法是直接把后端部署到云服务器,小程序统一用HTTPS域名访问,这样真机调试就不受局域网限制了。
小程序发布体验版之后,如果还是网络异常,要去小程序管理后台把request合法域名配好,而且必须是HTTPS协议的域名,不能是IP。这里我再强调一次:域名备案和SSL证书要提前准备,至少预留一周时间,不要卡在答辩前一晚。
6.3 大模型响应慢、答案质量差
AI接口响应时间如果超过5秒,用户体验就会明显下降。这个问题通常有两个原因:一是检索返回的上下文太长,把无关藏品也塞进提示词了;二是API请求参数里把max_tokens设得太大。解决办法是:每次只召回3到5个相关藏品,每个藏品的描述截断到200字以内,同时把temperature调低,让回答更稳定不发挥。
答案质量差的另一个原因是提示词不够具体。不要只说“你是一个助手”,要给模型明确约束:必须依据馆藏资料回答、如果资料中没有相关信息要说明不知道、回答控制在200字以内、语气亲切专业。模型是吃提示词长大的,你把规范写清楚,输出质量马上就提升。也可以在收到回答后做一次简单后处理,比如把“根据馆藏资料显示”这样的冗长开头去掉,让回复更自然。
最后提醒一个安全细节:用户传入的文本不要直接拼进提示词,要做长度限制和敏感词过滤。大模型API的调用最好在后端统一做,不要开放给前端自由传系统提示词。这一方面是防止突破上下文限制刷接口,另一方面也避免用户在演示时输入奇怪内容造成尴尬。
7. 论文写作与答辩辅导
7.1 论文结构怎么搭最稳
论文结构建议按“绪论 -> 相关技术 -> 需求分析 -> 系统设计 -> 系统实现 -> 系统测试 -> 总结”来写。很多同学一上来就想写系统实现,但本科毕设论文真正难写的是需求分析和系统设计这两章。需求分析里要说清楚业务流程、用例分析、功能需求和非功能需求;系统设计里要画出架构图、功能模块图、数据库ER图、接口设计表。
这里有个反常识的经验:不要先写论文再补图,而是先画图再写文字。先画架构图、ER图、用例图,然后对着图写文字,思路会清晰很多。画图工具建议用通用的绘图软件,画完导出矢量图,插到论文里不会糊。论文中所有图都要有编号和图名,表格也要有编号和表名,这虽然是格式问题,但答辩时老师第一眼就会看规范。
7.2 答辩PPT与现场演示的关键准备
答辩PPT控制在10到12页就够了。第1页题目和基本信息,第2页背景与意义,第3页技术选型,第4页需求分析,第5页系统架构,第6页数据库设计,第7页核心功能实现(重点放AI模块和小程序端截图),第8页系统测试,第9页难点与解决方法,第10页总结与展望。演示环节不要用PPT里的截图替代系统,一定要现场跑真机或小程序开发工具。
现场演示时,AI对话这个环节建议预演三遍以上。因为AI响应有延迟,如果当场等太久,场面会冷下来。你可以先准备好一段经典问题,比如“介绍一下馆内的代表性藏品”,让评委看到答案明显来自你们自建的馆藏数据,而不是模型的通用知识。再准备一个稍微刁钻的问题,让AI坦率回答“资料中没有相关信息”,这样反而能体现你们做了检索控制。
答辩可能被追问的细节也要提前过一遍:为什么选JWT而不是Session、MySQL索引在收藏表上怎么建、Redis缓存了哪些数据、大模型API调用失败了怎么办、你的检索是怎么实现的。强记答案没有用,要把代码和自己的设计思路串起来。哪怕被问到没准备的问题,也先复述一遍问题,再结合代码和数据流来说,不要直接说“我不知道”。
最后聊聊我辅导这个项目的体会
带过好几个学生做类似的数字博物馆项目,我发现最后得分高的,不一定是代码写得最花哨的,而是能把“为什么这么做”讲清楚的人。比如同样接大模型,有人写“我用提示词把藏品资料放进去”,有人会说“我考虑了提示词长度限制和检索召回数量的平衡,避免超出模型上下文窗口,也控制了响应延迟”。这两种表述的差距,就是良和优的差距。
所以我的建议是:代码可以抄思路,但设计决策一定要自己消化。每完成一个模块,就写一段笔记,记录你当时遇到了什么问题、为什么这样解决。这一小段文字放到论文里就是现成的“难点与解决方案”,放到答辩上就是你最自然的回答。技术更新很快,但把一件完整的事情从需求做到部署,再总结成别人能听懂的语言,这种能力是任何技术都替代不了的。祝你的毕设项目顺利收尾。