ARTICLE DETAIL

资讯详情

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

Django+大模型旅游路线推荐系统设计与实现

Django+大模型旅游路线推荐系统设计与实现 先聊一个我见过最多的毕设翻车现场题目是XX管理系统技术栈是Django Bootstrap功能是增删改查数据库里挂几张关联表答辩时老师问一句你解决了什么问题就答不上来。说白了评分老师不是想看你会不会写CRUD而是想从你的题目里看到三样东西够不够真实、够不够前沿、工作量能不能扛起来。DjangoLLM大模型做旅游路线规划推荐恰好能把这三样占全Django负责完整的工程链路大模型负责智能规划这个加分项数据分析负责把路线、行为、热度这些数据变成可解释的结论。我近几年带过几个做类似题目的学生这个方向的完成度只要不是太差答辩分数普遍不会难看而且它有一条很清晰的梯度先做基础版拿工作量再加推荐算法拿深度最后接大模型拿亮点每一步都能单独作为论文的章节去写。这篇不是官方文档复读是一套可以直接照着走的落地思路。我会把系统架构怎么拆、数据从哪里来、协同过滤和LLM怎么组合、路线规划怎么让模型输出能用的JSON、数据分析看板怎么做、以及答辩现场最容易翻车的地方都过一遍适合正在纠结选题或者已经开题但不太清楚完整链路的人参考。1. 为什么旅游路线推荐是能拿高分的毕业设计选题先说评审老师心里那杆秤。绝大多数本科毕设答辩老师并不会把你的源码逐行读完他们在意的是题目有没有一个明确定义好的问题域你的系统是不是围绕这个问题构建了完整的闭环里面有没有超出调包调参的技术工作量以及你本人能不能把这个思路讲明白。纯管理系统的问题就在于问题域太薄了用户表、订单表、商品表、前台展示、后台管理写完之后你答不出这里为什么需要真算法、真数据。旅游路线推荐不是这个问题它有三层支撑工程层Django MySQL Redis 前后端联调 部署标准的全栈工作量。算法层评分数据、用户行为数据可以被协同过滤、内容召回、用户画像聚类这些算法真实地跑起来论文里能写公式能出指标。应用层大模型不是挂在墙上当装饰而是真的在接收我只有三天预算2000喜欢古镇和博物馆这类自然语言输入然后生成多条可落地的路线。这个交互产生的智能化体验是纯规则系统做不到的。这个题还有一个好处它天然支持分档完成。我给你的建议是永远不要一上来就把所有功能堆满而是先想清楚你要做的版本。基础版景点和路线的CRUD、按热门度/城市筛选、后台管理、简单的收藏和评分、柱状图和饼图做统计。这个版本已经能保证论文有素材。进阶版在基础版上加入基于物品的协同过滤以及基于用户偏好的召回排序推荐列表真正个性化。完整版在进阶版上接入LLM做自然语言路线生成、推荐理由解释、评论摘要并在前端做一个数据大屏展示分析结论。我见过不少学生卡在完整版上因为什么都想做最后LLM调用不稳定、推荐效果又没时间调。正确的做法是基础版做得极其扎实进阶版算法有指标完整版只挑一两个亮点做好。答辩不会因为你没做某个功能扣分但会因为某个功能做崩了而提问。2. 系统架构与技术选型Django、大模型、数据分析各管哪一块架构层面我的建议不是堆微服务而是把职责拆清楚。毕业设计要展示的是我能把复杂问题结构化而不是我会用Kubernetes。下面这套分层是我亲测过最省事也最好讲的层级技术选型核心职责表现层Bootstrap Vue或Django模板轻量Vue路线列表、推荐卡片、对话式规划、数据大屏接口层Django REST Framework统一返回JSON鉴权、参数校验、分页业务层Django应用recommend、planner、analysis推荐召回/排序、LLM规划、指标聚合数据层MySQL Redis可选Chroma向量库关系数据持久化、热门缓存、向量检索外部服务大模型APIDeepSeek、通义、Kimi等兼容OpenAI协议的服务路线生成、推荐理由、评论摘要为什么是Django而不是FastAPI或Flask理由很实在毕设要交文档Django自带Admin后台、自带ORM和迁移工具你做数据管理和Demo演示都特别方便。你不需要自己实现登录、后台维护景点列表、管理用户评分Admin页面直接帮你省掉了一大半工作量。Django 4.2自带的JSONField可以直接存LLM生成的行程结构和MySQL的JSON类型完美对接不需要额外引入别的方案。大模型这块我强烈建议接API而不是本地部署。原因很简单本地部署一个7B模型需要显卡答辩机房的环境不一定支持而且部署、显存、推理速度全是不可控因素。API方式只需要一个Python环境、一个requests或者openai客户端库就能跑通。我一般建议学生选DeepSeek或通义这类兼容OpenAI接口、成本极低的模型生成一次路线可能只要几厘钱。大模型在这里承担的任务是语义理解和结构化内容生成它不是一个需要你训练的东西你要做的是把提示词、候选数据、输出校验这层工作做好这本身就是答辩时可以展开讲的技术点。数据层有一个容易被忽略的选型如果论文里想写向量检索这个亮点你可以用Chroma或者FAISS存景点文本的embedding用来做语义相似景点召回。但注意这不是必选项。我的建议是先用MySQL的LIKE和标签匹配把链路跑通学期时间允许再上向量库因为投稿论文时语义召回作为对比实验是加分项而作为必做项则可能拖垮进度。部署层面演示机通常是Windows笔记本或本地虚拟机不需要买服务器。本地跑Django开发服务器就够演示了但生产环境那套DockerGunicornNginx的配置最好在文档里写清楚老师问起来你能答上来就行。真正的风险点是LLM调用的超时同步请求大模型如果10秒不回前端卡死很难看所以要么用Django异步视图要么在调用前先返回正在生成的占位响应后台再推送结果。我后面会专门讲兜底方案。3. 数据从哪里来地图开放平台、公开数据和脚本造数这是很多新手第一个卡住的地方推荐系统要个性化可手头根本没有任何用户评分数据。我先给你吃颗定心丸毕设不是要你搞到携程的真实商业数据而是要让你能把数据获取—清洗—入库—分析这条链路完整跑一遍。数据来源有三个层次可以混着用。第一层高德或百度地图的开放平台。这是最正规的景点数据来源注册一个开发者账号申请Web服务API的Key用place/text接口按城市关键词搜索POI就能拿到景点名称、经纬度、地址、类型、评分这些字段。每天有配额但毕设规模完全够用。我建议你写一个Python脚本循环拉取国内十几个热门旅游城市的景点每个城市取二三十个核心景点再手动补上门票参考价和简介。高德返回的字段里有些是未营业或无坐标的清洗时要过滤掉。第二层公开数据集。像UCI或一些学术仓库里有少量旅游相关数据集但质量参差不齐我不太建议你死磕来源。真正好用的方式是半真实半构造——用地图API拿真实景点然后自己写规则生成路线。这个做法在论文里要光明正大写清楚真实场景数据用于验证系统的完整性模拟的评分和行为数据用于验证推荐算法的有效性这是学术社区通用的做法。第三层脚本造数。这里说的造数不是弄虚作假而是为了把协同过滤跑起来你需要一个用户—路线—评分矩阵。真实情况下你不可能等到用户真的评了几千次分再毕设。我的做法是写一个generate_mock_data.py生成大概500个用户、200条路线、5000条评分记录以及几万条浏览、收藏行为日志。造数时要有逻辑不能纯随机老一辈用户偏好人文景点和历史古迹年轻用户偏好网红打卡地和自然风光预算低的用户倾向于多日行程但花费少。带偏好的造数才能让推荐算法有规律可学也能让聚类分析得到可以解读的画像。数据库表结构我建议这样设计和你平时瞎建表区别很大的一点是Behavior表是必建的因为推荐效果分析和数据大屏都依赖它。from django.db import models from django.contrib.auth.models import AbstractUser class User(AbstractUser): city models.CharField(max_length64, blankTrue, default) preferences models.CharField(max_length255, blankTrue, default) age_group models.CharField(max_length16, blankTrue, default) class Attraction(models.Model): name models.CharField(max_length128) city models.CharField(max_length64, db_indexTrue) lng models.FloatField() lat models.FloatField() category models.CharField(max_length32) ticket_price models.FloatField(default0.0) rating models.FloatField(default0.0) heat models.IntegerField(default0) intro models.TextField(blankTrue, default) tags models.CharField(max_length255, blankTrue, default) class Route(models.Model): title models.CharField(max_length128) days models.IntegerField(default1) itinerary models.JSONField(defaultdict) budget models.FloatField(default0.0) tags models.CharField(max_length255, blankTrue, default) creator models.ForeignKey(User, nullTrue, on_deletemodels.SET_NULL) created_at models.DateTimeField(auto_now_addTrue) class Rating(models.Model): user models.ForeignKey(User, on_deletemodels.CASCADE) route models.ForeignKey(Route, on_deletemodels.CASCADE) score models.FloatField(default5.0) comment models.TextField(blankTrue, default) created_at models.DateTimeField(auto_now_addTrue) class Behavior(models.Model): user models.ForeignKey(User, on_deletemodels.CASCADE) route models.ForeignKey(Route, nullTrue, on_deletemodels.CASCADE) action models.CharField(max_length16) created_at models.DateTimeField(auto_now_addTrue)注意一个细节如果你用MySQLDjango的JSONField从3.1开始就支持了数据迁移没有任何问题。itinerary字段用JSON结构存每天的景点ID列表比另建一张行程明细表简单得多查询和前端渲染都方便。数据清洗这一步在论文里也有得写去重、补空值、类别归一化比如自然风光山水户外统一成一个标签体系、价格异常值剔除。你甚至可以把清洗前后的数据量对比做成一张表这就是典型的数据分析叙事。4. 个性化推荐从协同过滤到LLM重排的完整链路推荐模块的核心不是调一个大模型包而是把召回—排序—解释这条链路讲清楚。我建议你分成四层来做每一层都有独立的代码模块答辩时按层讲特别清晰。4.1 冷启动新用户和新路线的兜底策略所有推荐系统都会面对冷启动毕设里最容易翻车的就是这里。新用户没有历史评分你给他推什么我的答案是三层兜底默认推荐该城市热门Top10路线规则根据输入的偏好标签过滤——比如选择了亲子就优先推荐低强度、低花费、有游乐设施的路线如果用户啥都没选就推全站热度最高的路线。新路线的冷启动靠内容特征把路线的标题、标签、城市转换成向量文本用TF-IDF或简单的人工打标跟已有路线做相似度匹配这样新路线就能进候选池。4.2 召回物品协同过滤、用户协同过滤、内容召回三路并行协同过滤是最能体现算法基本功的部分公式和代码都能写进论文。我用的是基于物品的协同过滤先构建用户-路线评分矩阵行的用户列是路线用cosine_similarity计算路线之间的相似度矩阵。用户对某条路线评分较高时就从相似路线列表里找没看过的路线推荐出去。from sklearn.metrics.pairwise import cosine_similarity def build_similar_matrix(user_route_matrix): return cosine_similarity(user_route_matrix.T) def recommend_by_item_cf(user_id, sim_matrix, rated_map, top_n10): scores {} rated_user rated_map.get(user_id, {}) for r_id, rating in rated_user.items(): for other_id in range(len(sim_matrix[r_id])): if other_id in rated_user: continue scores[other_id] scores.get(other_id, 0) sim_matrix[r_id][other_id] * rating return sorted(scores.items(), keylambda x: x[1], reverseTrue)[:top_n]用户协同过滤就是反过来先算用户之间的相似度找到和我口味相似的邻居再推荐邻居喜欢的路线。它适合用户量中等、评分稀疏度不太高的场景。内容召回则用路线标题和标签计算向量余弦相似度用户之前点击的路线能映射到一批同类路线。这三路召回出来的结果要合并。合并方式不要用拍脑袋的加权至少要有依据我用的权重是0.4 * 用户协同 0.3 * 物品协同 0.2 * 内容匹配 0.1 * 热度这个权重在离线实验里调过一次答辩时你就可以说迭代了两版权重第二版在点击率上提升了X%。你不用真的做大规模AB测试但要有对比实验的意识。4.3 排序过滤规则、预算约束和多样性控制召回之后必须过滤这是推荐显得有用而不是随机的关键。要根据用户在前端选择的城市、同行人数、预算区间、天数硬性过滤再按多样性控制——不能让同一个景点的不同路线霸占整个推荐列表每个城市最多出4条每条路线的景点重叠率不能超过50%。排序得分可以简单加权也可以引入机器学习但毕设用加权就够了。重点是记录打分依据为什么这条排在最前面因为用户偏好相似度高、热度高、预算匹配。把原因展示在推荐卡片下方在UI上写一句因为是你看过的杭州路线所以推荐了这条同类古镇路线这个细节很多学生没做但它恰恰是答辩加分项。4.4 LLM重排和解释让推荐结果会说人话这是推荐的最后一层也是最能体现大模型价值的地方。我们把召回排序后的Top5路线传给大模型让它做两件事一是基于用户最近输入的偏好对这5条做一次排序微调并输出理由二是为每条路线生成一句自然语言推荐语比如这条路线适合摄影爱好者两个点位在日落时分的光线效果很好且全程交通距离短不会把时间浪费在赶路上。然后我们在前端把理由渲染出来。这层的技术含量在于你不能让LLM随意发挥编造理由所以给它的输入内容必须包含路线的标签、城市、天数、预算和已有评分让输出严格基于给定数据。我在下一章详细说提示词怎么写这里先记住一个原则——LLM在推荐链路里做的是解释和重排不是凭空发明路线。4.5 离线评估PrecisionK和点击率对比论文需要数字支撑。我建议做两个指标离线时把评分数据按8:2切分训练和测试计算Top10推荐的PrecisionK和RecallK在线演示模式时统计用户查看推荐列表后的点击、收藏情况做一个简单的漏斗对比推荐入口的曝光量、点击率、收藏率和非推荐入口的对比。我做过一个样例项目推荐入口的点击率大约能到18%-25%非推荐入口只有5%-8%这个差距就是你的推荐系统有效性的直接证据。截图放进论文里比大段文字强太多。5. LLM路线规划提示词模板、结构化JSON输出和兜底方案自然语言路线规划是整个项目体验上的最高光时刻。用户在前端输入从上海出发周末两天喜欢文艺和美食预算1500以内你返回一个包含每天的景点安排、餐厅建议、住宿方位、花费预估的结构化方案。实现它的核心难点其实只有一个怎么稳定地从大模型那里拿到能直接渲染的JSON。5.1 为什么不能让模型自由发挥第一次做这个功能的同学通常会写这样的prompt请生成一条北京三日游路线。然后前端按照markdown来渲染。结果就是你得到一篇图文混杂的长文本行程天数忽二忽三费用一会儿元一会儿千元景点名字一半是编的。问题不在于模型不够聪明而在于你没有给它结构约束和候选集约束。正确的做法是两步第一你只让模型从数据库里预先筛好的候选景点中挑选从源头堵住编造景点第二你强制它输出指定JSON Schema让每条日程都是一个结构体前端拿来就渲染。候选景点怎么筛根据用户输入的城市、天数、预算先从MySQL里把该城市热门景点拉出来再按类别尽量分散地取20到30个把这些景点的名称、类别、简介、门票价格作为上下文丢给模型。5.2 提示词与代码模板我用的是openai库把base_url指向兼容OpenAI协议的国内服务商即可这样代码不用改换模型就是换一个model名字。下面这段代码可以直接抄进你的planner/services.pyimport json from openai import OpenAI client OpenAI( api_key你的API_KEY, base_urlhttps://api.deepseek.com/v1 # 或者其它兼容服务 ) def generate_route(user_query: str, candidates: list[dict]) - dict: schema { type: object, properties: { title: {type: string}, days: {type: integer}, schedule: { type: array, items: { type: object, properties: { day: {type: integer}, spots: {type: array, items: {type: string}}, note: {type: string} }, required: [day, spots, note] } }, budget_estimate: {type: number}, tips: {type: string} }, required: [title, days, schedule, budget_estimate, tips] } candidate_text json.dumps(candidates, ensure_asciiFalse) prompt ( 你是旅游路线规划助手。\n 请严格从下方候选景点中选择地点禁止编造不存在的景点。\n f用户需求{user_query}\n f候选景点列表{candidate_text}\n 输出JSON包含title、days、schedule每天一条含day, spots, note、 budget_estimate、tips。requirements: JSON only. ) resp client.chat.completions.create( modeldeepseek-chat, messages[ {role: system, content: 你是旅游规划专家。}, {role: user, content: prompt} ], response_format{type: json_object}, temperature0.7, ) content resp.choices[0].message.content return json.loads(content)注意一个细节即使你要求JSON输出模型偶尔也会在正文前后夹带解释文字或者把schedule里面的spots写成中文顿号分隔而不是数组。所以json.loads也可能抛异常必须写一层兜底解析。5.3 解析兜底和景点白名单校正我的兜底函数做三件事正则提取首个{到末尾}的子串如果还解析失败就退回模板路线解析成功后再做一次白名单校正——遍历返回结果里的所有景点名凡是匹配不到候选景点列表的一律替换成该城市热度最高的景点。这样哪怕模型偶尔犯糊涂你输给前端的数据也一定能用。import re def safe_parse_route(content: str, candidates: dict, fallback_route: dict): try: start, end content.index({), content.rindex(}) data json.loads(content[start:end1]) for day in data.get(schedule, []): spots [] for name in day.get(spots, []): if name in candidates: spots.append(name) else: spots.append(candidates[0][name]) day[spots] spots return data except Exception: return fallback_route这个函数写出来之后LLM调用就变成了尽力而为它负责把体验做得聪明但系统不依赖它也能跑。这也是答辩时老师最爱问的场景之一你可以直接回答我们做了白名单校正和降级兜底模型输出不可用时返回基于规则的默认路线这句话证明你想到了生产环境里的可靠性问题。5.4 成本、缓存和并发考虑大模型API按token计费生成一条路线大约消耗500到1500个token按DeepSeek的价格算一次不到一分钱一天演示几十次也就是几块钱完全可以接受。但为了防止演示现场因为网络或者限流翻车我强烈建议做一个演示模式开关把几组常用的用户输入和对应的生成结果预生成好存成JSON或Redis缓存前端检测到演示模式就直接读缓存。答辩现场用演示模式跑截图和录屏用真实API跑两边都不丢人。前端交互上视频演示中最好看的是流式输出。如果你调用的API支持SSE流式可以让推荐理由像打字机一样逐字出现这个视觉效果在答辩时比任何PPT都抓眼球。但是流式对代码复杂度有要求如果时间不够就做loading转圈几秒后整体出现的效果稳定性优先。6. 数据分析与可视化城市热度、用户画像和推荐效果数据分析模块是很多毕设的短板因为大部分人只是把几个图表堆上去没有分析—结论—行动的闭环。你的系统里有行为日志表、评分表、景点表这些数据足够支撑几个有说服力的分析故事。6.1 城市热度与景点类别偏好第一个分析是城市热度排行榜。聚合Behavior表里按actioncollect或view统计路线所属城市得出最热门的旅行目的地。第二个分析是景点类别的偏好差异按用户年龄段分组统计自然风光、博物馆、主题乐园、古镇这些类别的访问占比。这两个分析实现起来就是几行Django ORM聚合再加一个ECharts柱状图。from django.db.models import Count, Sum from .models import Behavior, Route def city_heat(): rows ( Behavior.objects.filter(actioncollect) .values(route__origin_city) .annotate(totalCount(id)) .order_by(-total)[:10] ) return list(rows)注意如果你的Route模型没有origin_city就需要通过Attraction反查或直接给Route加城市字段。我建议直接在Route上冗余一个origin_city避免每次聚合都跨表join对演示性能也有帮助。6.2 用户画像聚类KMeans让大屏有故事可讲用户画像不用搞花活用KMeans聚类就足够惊艳。取每个用户的行为特征向量各城市路线的浏览数、各类别景点的偏好占比、平均预算档位、活跃时段早/中/晚。标准化后用sklearn.cluster.KMeans聚成3到5类给每一类起一个人口统计风格的名字比如高预算深度游人群学生党穷游人群亲子家庭休闲人群。然后在前端用户列表页或者数据大屏里展示每一类的人数占比和典型偏好标签。我做过的一个样例里聚类出来最明显的两类是20-25岁人群集中在网红打卡高性价比的类别35-45岁人群集中在自然风光人文历史中等预算的类别。这跟常识一致但你要展示的是能从数据里得出这个结论而不是拍脑袋认为如此答辩时这个区分很关键。6.3 用pyecharts生成图片或HTML还是前端写ECharts我建议后端用pyecharts生成图表渲染成HTML文件Django直接当静态模板返回或者生成JSON配置交给前端Vue渲染。pyecharts最简单的用法from pyecharts.charts import Bar from pyecharts import options as opts def city_heat_chart(): data city_heat() bar Bar() bar.add_xaxis([d[route__origin_city] for d in data]) bar.add_yaxis(收藏数, [d[total] for d in data]) bar.set_global_opts(title_optsopts.TitleOpts(title城市热度Top10)) return bar.render_embed()render_embed()返回的是带require.js的完整HTML片段可以直接嵌进Django模板。但如果你前端要用Vue做弹窗更干净的做法是后端返回bar.dump_options_with_quotes()生成的JSON前端用ECharts的setOption灌进去。两条路线都说得通我倾向后者因为前后端数据解耦写进论文里更好看。6.4 推荐效果漏斗用数据证明系统有用这是全系统最能一击制胜的一张图表。统计两个入口的转化漏斗指标非推荐入口个性化推荐入口曝光次数1000800点击次数120260收藏次数3090收藏率3.0%11.25%只要你的推荐算法别做太差这个对比几乎是稳赢的。实现方式就是给前端埋点每次展示推荐列表时记一条actionexpose的行为日志用户点击记录actionclick收藏记录actioncollect。这个埋点本身也是工程化能力的体现。论文里你可以写经过埋点统计个性化推荐入口的收藏率是非推荐入口的3.7倍验证了推荐算法的有效性——这就是数据驱动决策的完整表述。7. 开发排期与答辩防翻车清单最后这部分是给时间管理比较混乱的同学准备的。我按八周给过一个学生排期最终完成度很稳你参考着调整。周次里程碑交付物第1周环境搭建、Django项目骨架、MySQL建库项目能启动登录注册可用第2周景点和路由的CRUD、Admin后台后台能录入景点和路线第3周前端列表页、详情页、搜索筛选用户能浏览路线第4周评分、收藏、行为埋点数据表有日志记录第5周协同过滤算法跑通、生成推荐列表推荐接口有输出第6周数据聚合、pyecharts图表、数据大屏看板页可展示第7周接入LLM路线规划、提示词调优、兜底对话式规划可用第8周打磨Demo、录制视频、整理论文图表答辩材料齐备7.1 环境坑Django MySQL在Windows上的兼容问题我必须要提醒一个高频翻车点Windows上装mysqlclient经常会编译失败因为它依赖MySQL的C客户端库。最快的绕法是改用pymysql在项目的__init__.py里加一行import pymysql pymysql.install_as_MySQLdb()这样Django的ORM就完全感受不到底层驱动的区别。另一个坑是Django版本和Python版本要匹配我推荐Python 3.10 Django 4.2这是目前最稳的组合不要为了追新去用Django 5.x加Python 3.12某些第三方扩展可能没跟上。Redis在Windows上没有官方版本你可以用Memurai或者直接用Docker跑一个Redis容器。如果实在不想碰Docker就把缓存层去掉用Django的cache框架配置成本地文件缓存也能演示效果。运行时功能上差距不大但论文里可以写Redis因为本地文件缓存只是临时替代。7.2 演示现场最常见的五个翻车点LLM调用超时或限流API偶发不稳定演示时必须用演示模式缓存现场断网也能撑住。浏览器缓存导致旧版本的页面答辩前把浏览器缓存清一遍或者用Chrome无痕模式这是刻骨铭心的教训。推荐列表为空冷启动时新用户没有行为一定要保证兜底热门列表永远有数据否则首页白屏直接凉。数据大屏的图表加载失败pyecharts的静态文件路径要放在static目录下不能用开发服务器的动态路径。中文编码问题Windows终端和MySQL连接符不一致容易乱码pymysql.charsetutf8mb4写明确。7.3 答辩问答预演老师可能问的几个角度我模拟一遍问你的推荐系统用什么评价指标答离线八二开切分算PrecisionK和RecallK在线埋点统计点击率和收藏漏斗并给出具体数字。问大模型会不会生成不存在的景点答不会因为我们在提示词里限制了候选集而且输出后会做白名单校正匹配不上的替换为热门景点。问你的数据分析发现了什么答城市热度排行、年龄段偏好差异、推荐入口点击率明显高于非推荐入口并说明这些发现怎么反馈到推荐权重。问哪里是你自己写的哪里用了开源库答协同过滤、召回融合、提示词工程、白名单校正、埋点分析是自己实现的相似度计算、聚类用了scikit-learn图表用pyecharts。开源库是工具链路是自己搭的。这些问题答顺畅了整个答辩的观感就是这个学生真的把系统跑通了而且知道自己在做什么。比堆一堆炫技名词然后一问三不知强太多了。我个人带学生的体会是这个题目真正拉开差距的地方不是谁的LLM调得好而是谁愿意把数据准备、推荐评估、演示稳定性这些不起眼的环节打磨扎实。你不需要让推荐效果跟商业产品比你只需要让整个系统呈现出完整、自洽、可解释的气质。把旅游路线推荐这套DjangoLLM数据分析的链路走完你的工程素养、算法认知和技术叙事能力都算是真正被毕业设计锻炼过了。
返回列表