每年到毕业设计选题季实验室里讨论最多的不是“做什么题目”而是“做什么题目能既撑得起工作量又不会被答辩老师一句话问倒”。古诗词方向以前听着冷门但一旦把Django、DeepSeek大模型、知识图谱、情感分析、推荐系统和可视化组合到一起它就不再是那种只写几个增删改查页面的管理系统而是一个工程与算法结合、有大模型应用场景、还能做出漂亮展示页的综合型项目。我最近就把这套系统完整地做了一遍。整套系统说白了就是让计算机“读懂”中国古代诗歌对每首诗做情感判断根据情感、意象、诗人之间的关系给用户推荐诗再把诗与诗之间复杂的语义关联用知识图谱和图表呈现出来。标题里那一长串关键词并不是随便拼凑的它们各自对应真实的技术环节。这篇文章我会把项目的技术拆解、数据层设计、算法实现、实操过程和踩坑经验全部过一遍。如果你是正在准备毕业设计的学生或者想找一个“大模型知识图谱”入门实战项目的开发者这篇文章应该能给你一条明确的技术路线。1. 毕业设计做古诗词分析为什么这届学生都盯上了它1.1 这个系统到底解决了什么问题先说说选题背景。最近几年的毕业设计里纯管理系统类题目已经很难做出区分度“用户管理、订单管理、分类管理”三板斧做完工作量一眼就能被看穿。纯算法类题目又往往缺少工程载体算法模型跑了半天没有一个能演示的界面答辩时用户也看不出价值。古诗词情感分析这个方向恰好站在两者中间。这个系统解决的实际问题有三个。第一传统情感分析手段对古文效果很差。普通的文本情感分析模型大多是基于现代汉语训练的遇到“举头望明月低头思故乡”这种表面写景、实际写情的诗句经常识别成中性或者错误情绪。第二古诗词之间的关系不是用普通数据库就能优雅表达的。诗人与诗人之间有唱和诗歌与意象之间有引用意象与情感之间有象征这些关系如果用关系型数据库反复join查询逻辑会非常难写。第三新上线的推荐系统普遍有冷启动问题没有足够的用户行为数据协同过滤根本跑不起来需要有基于内容或基于知识图谱的推荐策略来兜底。所以整套系统解决的就是这三个层面的问题用大模型的情感理解能力替代传统情感词典用知识图谱承载诗词间的语义网络用混合推荐策略解决冷启动。通过这三个能力最后把古诗词数据变成一个人人可浏览、可交互、可探索的智能化平台。1.2 技术选型Django、DeepSeek、知识图谱的组合逻辑后端框架我选了Django而不是FastAPI理由很实际。第一Django自带Admin后台诗词数据管理页面几乎是免费的这对于毕设来说性价比极高。第二Django的ORM对初学者非常友好模型写好之后迁移、建表、增删改查都是现成的。第三答辩时老师问“你用了什么成熟的企业级技术”Django是一个从简历到工业界都说得过去的答案。FastAPI更轻量但很多组件需要自己拼装在有限时间内不太划算。大模型选型方面DeepSeek在这类题目里优势很突出。首先是中文古文理解能力在同类开源模型里属于第一梯队其次API风格和常用的OpenAI协议接近对接成本很低另外它的调用成本也便宜业余项目完全可以承受。这里要强调一下本地没有GPU的学生完全不需要自己部署模型用云端API就可以完成整个项目的载体工作。知识图谱的存储层可以分成两条路线。一条是认真上Neo4j图数据库支持多跳路径查询可视化和推理能力都很强另一条是用MySQL存三元组前端再用ECharts画关系图。两种方式都叫“知识图谱项目”但是含金量完全不同。我的做法是MySQL和Neo4j并行MySQL保存业务数据和诗词原始信息Neo4j保存图谱关系两边通过同步脚本保持数据一致。这样答辩时你既可以说清业务数据流又能在知识图谱页面上展示真正的图结构查询。2. 系统架构与数据层设计从数据采集到图谱建模2.1 整体架构与数据流设计整套系统的数据流可以概括成一条链数据采集 → 清洗入库 → 情感分析 → 图谱构建 → 推荐计算 → API输出 → 前端可视化。最开始的输入是公开的古诗词数据集一般以JSON或CSV的格式存在里面包含朝代、作者、标题、正文、注解和译文。拿到之后先做清洗把重复记录、繁体字、缺字段的数据处理干净再写入MySQL。这一步完成之后会启动一个批量分析任务逐首调用DeepSeek的情感分析接口把返回的情感标签、情感分数和推理原因回填到诗词表里。接下来从诗词正文中抽取出“月、花、酒、孤舟”这类意象名词再把诗人、朝代、情感、意象这些实体和关系导入Neo4j。用户在前端完成收藏、评分、浏览后推荐模块结合用户行为和知识图谱路径为每一首诗生成推荐候选集。最后通过REST API统一输出前端用ECharts完成可视化展示。我建议在Django里按模块拆分app而不是把代码全部堆在同一个地方。我当时是拆成了poem、user、kg、recommend、stats这五个核心app分别处理诗词管理、用户体系、知识图谱、推荐逻辑和统计可视化。这样代码维护起来非常轻松后期写论文时也可以直接拿app的划分来说明系统模块设计。2.2 数据库设计MySQL表结构和Neo4j图谱模型MySQL这边主要是业务数据。核心表包括朝代表、诗人表、诗词表、用户表、收藏表和评分表。其中最关键的是poem表它除了保存诗文的原文、译文和注释之外还会冗余存储情感标签和情感分数。这里做适度冗余是有意的因为毕设场景里绝大多数查询是只读的减少join次数可以显著降低写SQL的复杂度。表名主要字段作用dynastyid, name, start_year, end_year朝代信息poetid, name, dynasty_id, alias, intro诗人信息poemid, title, content, author_id, dynasty_id, translation, notes, emotion_label, emotion_score诗词原文与情感分析结果userid, username, password_hash, created_at用户账户favoriteid, user_id, poem_id, created_at用户收藏关系ratingid, user_id, poem_id, score, created_at用户评分行为Neo4j这边的图模型比MySQL更复杂一些。我定义了四类主要节点Poem诗、Poet诗人、Emotion情感、Image意象外加Dynasty朝代节点。关系上诗人节点用WROTE关系指向诗歌诗歌节点用BELONGS_TO指向朝代用EXPRESSES关系指向情感用CONTAINS关系指向意象。最重要的语义设计是“ImageSYMBOLIZESEmotion”也就是“意象象征情感”。比如“月”常常象征思乡“柳”常常象征送别“酒”有时候象征豪放有时候象征愁绪。这样建模的好处是推荐系统可以通过“诗包含意象意象象征情感情感关联更多诗”这样的路径做推理而不是只做文本相似度那种机械匹配。这个“意象情感”双层结构是整个项目里最适合写进论文创新点的设计。2.3 数据处理管线清洗、分词、情感标注数据质量直接决定图谱和推荐系统做出来的效果。很多同学一上来就直接把数据集读入数据库结果页面上全是空字段图谱里全是孤立节点观感很差。我当时花了大概一周的课余时间专门处理数据事实证明非常值。清洗阶段主要做五件事。第一以“标题正文作者”作为唯一键去重避免同一个版本的数据重复入库。第二用OpenCC把繁体中文转简体统一文本格式。第三去除全角空格和遗留的注释标记。第四删除那些缺少朝代、缺少正文的脏数据对于“佚名”作者则统一标记为“无名氏”而不是直接删除否则图谱里会少一大片节点。第五对词牌名和曲牌名做单独字段保存这个信息在后续知识图谱里可以作为标签使用比如“同词牌名的作品可以在推荐时作为相似性特征”。情感标注是整个数据管线的核心步骤。因为古诗词语料规模通常只有几千到几万首在这个量级上微调一个大模型性价比很低而且很多同学没有GPU资源。所以我的做法是用DeepSeek做批量离线标注输出“情感标签情感分数分析原因”的JSON结果然后把结果保存成标注文件。为了让后面写论文时有可信的评估数据我还额外抽了200首诗人工复核了一遍统计模型标注和人工标注的一致率这部分内容在系统测试章节里非常加分。3. 核心算法与模型实现情感分析、推荐算法、知识图谱推理3.1 基于DeepSeek大模型的古诗词情感分析实现情感分析模块是整个系统的技术重点核心实现思路是提示词工程加结果解析。我没有采用传统微调模型路线原因是古诗词语料规模太小几万条文本微调一个大模型效果不一定比精心设计的Prompt更好而且本地没有GPU基本上跑不动。改用大模型接口做zero-shot分类反而能得到更符合语义的判断结果。情感标签体系设计要合理。标签太少比如只有“积极/消极”两类论文里没有细节标签太多模型输出会不稳定人工复核也累。我采用的是八分类标签集合喜悦、愤怒、悲伤、忧思、闲适、豪迈、思念、愁苦。因为情感本身存在交叉允许一首诗输出1到3个标签既可以体现情感的复杂性又不会让结果发散。下面给一个简化版的调用示例实际项目里还需要把这段逻辑封装成独立的服务文件。import requests import json def analyze_emotion(content: str, labels: list[str]) - dict: api_key your_api_key url https://api.deepseek.com/chat/completions prompt f 你是一位精通中国古典诗词的文学研究者。请分析下面这首古诗表达的情感。 可选情感标签{labels} 要求 1. 只输出JSON不要任何多余解释。 2. JSON格式{{emotions: [思念], score: 0.9, reason: 诗句通过描写 ... 表达 ...}} 古诗内容 {content} resp requests.post( url, headers{ Authorization: fBearer {api_key}, Content-Type: application/json, }, json{ model: deepseek-chat, messages: [ {role: system, content: 你是一个严谨的中文古诗词研究者。}, {role: user, content: prompt}, ], temperature: 0.2, max_tokens: 300, }, timeout30, ) data resp.json() raw data[choices][0][message][content] return parse_json_safe(raw)大模型输出结果不完全稳定偶尔会带Markdown代码块或者夹带解释性文本所以解析函数必须写得足够健壮。import re import json def parse_json_safe(raw: str) - dict: raw raw.strip() if raw.startswith(): raw re.sub(r^(?:json)?, , raw).strip() raw re.sub(r$, , raw).strip() try: return json.loads(raw) except json.JSONDecodeError: match re.search(r\{.*\}, raw, re.S) if match: return json.loads(match.group()) raise ValueError(模型输出无法解析为JSON)调用参数方面我对temperature设置得很低一般是0.2。因为情感分类是一个确定性强、主观性弱的任务输出越稳定越好。max_tokens控制在300以内每首诗的分析结果量级很小不需要模型长篇大论。批量分析时还要注意限流问题两次请求之间加随机延迟并且做好失败重试。情感分析结果最终要回写到MySQL的poem表中再同步到Neo4j。我还在诗表里加了一个audit_status字段标注这条情感结果是否已经人工审核这样后期可以随时修正模型的误差也让整个系统的可信度更高。3.2 融合知识图谱的推荐系统设计推荐模块我采用了一种混合策略而不是依赖单一的协同过滤。表面原因是项目早期没有用户数据协同过滤冷启动。深层原因是古诗词推荐非常适合做“可解释推荐”告诉用户“推荐这首诗因为你喜欢的诗和它都表达了思念并且都使用了明月这个意象”比冷冰冰的算法结果有说服力得多。第一种策略是基于内容的相似推荐。把每首诗的分词结果转换成TF-IDF向量用余弦相似度计算最相近的Top-K首诗。实现简单运行稳定适合做兜底候选池。第二种策略是知识图谱路径推荐。这是项目的亮点。给定当前诗P在图谱中先找到它关联的情感节点、意象节点和诗人节点再通过这些节点向外扩展找到与P共享情感、共享意象或者属于同一位诗人的其他作品。路径越短关联越紧密。比如当前诗包含“月”并表达“思念”那么另一个也包含“月”并表达“思念”的诗就会获得很高的路径分数。第三种策略才用到协同过滤。当用户行为数据积累到一定量之后可以根据“收藏了这首诗的人也收藏了哪些诗”来做物品协同过滤。在论文的系统测试部分我会说明协同过滤在数据稀疏时效果不佳所以它只作为候选池的补充来源。三种策略各有特点用一张表能看得更清楚推荐策略数据依赖优点缺点基于内容相似诗词文本冷启动友好实现简单容易同质化知识图谱路径图谱三元组可解释性强推荐结果有语义图谱不完善时路径稀少协同过滤用户行为个性化程度高冷启动问题明显最终候选集的排序分数采用加权融合final_score w1 乘以文本相似度 w2 乘以图谱路径分 w3 乘以情感偏好分。三个权重可以根据演示效果手动调整论文中也可以多设几组对比实验来说明权重选择的合理性。3.3 可视化模块从ECharts词云到图谱动态渲染可视化部分直接决定答辩时的第一印象。我当时把整个页面按“数据总览、内容检索、图谱探索、情感分析”四个维度来设计其中最有视觉冲击力的就是知识图谱关系图。为了让ECharts能展示Neo4j里的图数据后端需要先把Cypher查询结果转成前端要求的nodes和links格式。我统计情感分布、高频意象、朝代分布等指标时也统一通过REST API返回聚合JSON不在前端做复杂计算。一个基础的知识图谱接口响应长这样{ nodes: [ {id: p1, name: 某首古诗, category: poem}, {id: e1, name: 思念, category: emotion}, {id: i1, name: 月, category: image} ], links: [ {source: p1, target: e1, relation: 表达}, {source: p1, target: i1, relation: 包含} ] }前端用ECharts的graph类型渲染设置force布局节点大小代表这首诗被收藏的次数或者情感节点关联的诗数颜色按poet、poem、emotion、image四类区分。这样做出来之后页面不仅好看而且交互性很强点击任意一个意象节点就能看到所有包含这个意象的诗点击情感节点就能看到持有该情感的作品集合。除了知识图谱还有三个必做的图表情感分布玫瑰图、高频意象词云、朝代诗作量柱状图。这三个图表的数据量不大渲染很快放在首页可以做数据总览。如果想让情感分析更有深度还可以在诗词详情页放一个单诗雷达图把模型返回的1到3个情感标签扩展成多维度强度分布视觉上很出效果。4. 实操落地从环境搭建到发布上线的完整流程4.1 环境准备与项目初始化动手开发之前环境准备环节值得认真对待。我建议使用Python 3.10以上版本用虚拟环境管理依赖避免系统Python环境被搞乱。依赖安装的核心清单是django、djangorestframework、jieba、opencc、requests、pandas、neo4j、gunicorn、mysqlclient或pymysql。MySQL我用的是8.0Neo4j用的是Community 5.x。Neo4j我强烈建议用Docker部署一条命令就能把服务和可视化控制台一起带起来省去手动配置的环境坑。初始化Django项目的步骤如下django-admin startproject创建项目根目录python manage.py startapp分别创建poem、user、kg、recommend、stats五个应用。然后在settings.py里配置MySQL连接、时区、静态文件目录和REST Framework配置。全部配置完成后执行makemigrations和migrate数据库表就生成了。这里插一句不要为了图省事用SQLite。毕设系统最终要演示收藏、推荐、图谱等业务数据量大一点SQLite就会响应变慢而且答辩老师看到SQLite会默认你的系统很初级。MySQL是成本很低但专业度很高的选择。4.2 Django后端核心代码实现后端模型是整个系统的地基。我在这里给出核心模型的设计示例实际开发时可以直接参考from django.db import models class Dynasty(models.Model): name models.CharField(max_length32) start_year models.IntegerField(nullTrue, blankTrue) end_year models.IntegerField(nullTrue, blankTrue) class Poet(models.Model): name models.CharField(max_length64) dynasty models.ForeignKey(Dynasty, on_deletemodels.SET_NULL, nullTrue) alias models.CharField(max_length255, blankTrue) intro models.TextField(blankTrue) class Poem(models.Model): title models.CharField(max_length128) content models.TextField() author models.ForeignKey(Poet, on_deletemodels.SET_NULL, nullTrue) dynasty models.ForeignKey(Dynasty, on_deletemodels.SET_NULL, nullTrue) translation models.TextField(blankTrue) notes models.TextField(blankTrue) emotion_label models.CharField(max_length128, blankTrue) emotion_score models.FloatField(default0.0) is_audited models.BooleanField(defaultFalse)这里有一个设计细节值得注意外键都用SET_NULL而不是CASCADE。因为古诗文数据是珍贵的语料不能因为误删一个诗人就连带把所有诗作删掉这是数据安全意识答辩时可以主动提出来。API层我统一用Django REST Framework实现不直接在视图函数里拼JSON字符串。主要接口包括诗词列表分页接口、诗词详情接口、相似推荐接口、收藏接口、评分接口、情感分布统计接口、知识图谱图数据接口。每个接口对应一个viewset或APIView代码结构非常清晰。DeepSeek调用逻辑建议放在services/deepseek.py这个独立服务模块里视图和模型都不要直接引用requests包。这样后期如果换模型或者调整Prompt只需要改一个文件。4.3 前端页面与ECharts可视化接入前端页面我采用传统Django模板加Bootstrap的方案图表部分用ECharts。页面规划为五个核心页面首页、诗词列表、诗词详情、知识图谱、个人中心。首页最重要的部分是统计图。打开页面时前端会并发请求情感分布接口、朝代统计接口和高频意象接口拿到数据后分别渲染玫瑰图、柱状图和词云。ECharts对中文支持很好但要注意后端返回的JSON编码必须是UTF-8否则会出现中文乱码。知识图谱页是演示的重点。页面做成半透明仪表盘风格左侧是节点类型筛选器右侧是ECharts的graph实例点击节点时拉取详情面板。ECharts的graph类型提供force布局、拖拽、缩放等交互能力基本能满足演示需求。这里给一个最小可用的前端示例div idkgChart stylewidth:100%; height:600px;/div script srcecharts.min.js/script script fetch(/api/kg/graph) .then((r) r.json()) .then((data) { const chart echarts.init(document.getElementById(kgChart)); chart.setOption({ tooltip: {}, series: [ { type: graph, layout: force, data: data.nodes, links: data.links, roam: true, force: { repulsion: 300, edgeLength: 100 }, categories: data.categories, }, ], }); }); /script演示时强烈建议在页面里做“点击节点显示关联诗”的交互而不只是静态展示。因为答辩老师十有八九会想上手点一点交互越流畅系统越显得成熟。4.4 系统部署与演示技巧开发阶段用runserver跑很舒服但到了答辩前建议还是用Gunicorn加Nginx部署成正式服务好处有三个答辨现场访问更稳定避免runserver在并发访问下崩掉静态文件加载更快页面美观度上一个台阶简历上写“部署于Linux环境”也更有说服力。部署的简要流程是先执行collectstatic收集静态文件然后用Gunicorn启动Django应用监听8000端口最后用Nginx反向代理80端口到8000端口并把静态文件目录交给Nginx处理。数据库口令和密钥不要写死在settings.py里最好通过环境变量注入细节虽小但写到论文里很体现工程素养。演示技巧方面最重要的一条是不要高估现场网络的可靠性。大模型API在公网环境下可能有延迟如果答辩现场网络不好实时调用DeepSeek会很尴尬。我给系统的建议是将情感分析做成离线批量的方式所有情感结果都预先入库前端只读缓存结果线上预测只作为后台管理功能来演示。这样整个演示流程完全不依赖外部API稳定性大大提升。5. 踩坑实录与答辩要点开发中的真实问题与解决方案5.1 大模型调用不稳定怎么兜底在实际开发过程中大模型接口带来的问题是最多的主要集中在四个方面。第一个问题是限流。批量分析几千首诗时连续请求很容易触发限流。解决办法是每次请求之间加随机延迟设置指数退避重试同时把算好的结果永久缓存到本地避免同一首诗被反复请求。缓存可以放在数据库里也可以放在Redis里对毕设来说数据库缓存就足够了。第二个问题是返回格式不稳定。模型偶尔会在JSON前后加解释文字偶尔会输出Markdown格式的代码块。我写的parse_json_safe函数专门处理这类情况先剥掉代码块再尝试正则取花括号内容基本能兜住绝大多数异常情况。第三个问题是标签不落在预设集合里。比如模型返回“思念故乡”而标准标签是“思念”如果不做映射就会导致统计图表里出现一堆杂乱的标签。解决方法是建立一个同义词映射表把“思乡”“怀人”“思念故乡”等都映射到“思念”。个映射表本身也可以作为论文里“标签体系构建”的一部分来写。第四个问题是离线环境保障。答辩现场断网的情况并非罕见所以一定要避免“页面打开时才实时请求大模型”这种设计。最稳妥的方案是全部情感分析结果提前入库前端和推荐模块只做本地数据读取模型的实时调用作为后台管控功能单独封存。5.2 知识图谱可视化性能优化Neo4j里存几千个节点、几万条关系时数据库查询本身没有压力真正的压力在前端渲染。ECharts force布局在节点数超过几百个时就会开始卡顿尤其是同时开启缩放、拖拽和动画的时候。我的优化方案有三个方向。第一后端接口限制返回节点数量默认只返回100个核心节点而不是把全图数据一次性发给前端。第二对展示内容做子图划分比如首页图谱只展示“诗意象情感”关系用户点开诗人节点后再展示诗人的关联子图。第三过滤低频意象只保留出现频率Top 50的意象进入图谱这样图谱既不会稀疏到没内容也不会密到看不清关系。还有一个细节是查询语句的优化。比如只查必要字段、在Cypher中使用LOI限制条数这些工作虽然简单但能让接口响应时间从几百毫秒降到几十毫秒。答辩时如果老师问到性能问题你可以直接说出这套方案会显得思考非常完整。5.3 论文写作与答辩演示的心得这个题目写论文的素材非常充足。需求分析阶段可以写传统情感分析方法在文言古诗中的不足关键技术阶段可以写大模型提示词设计和知识图谱路径推荐系统实现阶段可以写MySQL与Neo4j的双库架构系统测试阶段可以写情感标注一致率评估和推荐TopN准确率统计。整套论文的逻辑闭环非常清晰。创新点的提炼建议放在“引入”和“融合”这两个关键词上。比如“将大模型语义理解能力引入古诗词情感识别缓解传统方法在隐喻表达下的理解偏差”“设计意象到情感的图谱关系层提升推荐结果的可解释性”。这里要注意措辞不要写“首创”这种过于绝对的表达否则答辩时容易被追问。答辩老师最常问的问题我提前模拟过一轮。问为什么用大模型而不用微调小模型时可以从数据规模、成本、古诗词语料特点三个角度回答。问知识图谱数据来源时要说明是公开数据集清洗加模型抽取、人工复核。问推荐效果如何评价时可以承认目前以离线统计和演示体验为主并补充说模拟用户行为数据进行过TopN准确率测试。回答既要自信也要实事求是不要夸大系统能力。演示流程我建议按照“首页图表 → 搜索一首诗 → 查看情感分析 → 点击知识图谱 → 体验相似推荐 → 收藏后刷新推荐”的顺序走一遍每一步都能自然衔接到下一步。每个页面的停留时间控制在半分钟左右把系统的核心亮点快速展示完。最后再分享一个我实际操作中的体会这类项目的第一优先级永远是数据。我在数据清洗和情感标注上花的时间比写前端页面多出好几倍但效果也正正都体现在最终演示里。如果你正在为这个题目做准备先花几天时间把“一条诗从清洗、分析、入库、推荐到可视化”的完整链路跑通再回来写页面做优化。骨架通了后面加什么功能都顺理成章。