
1. 这篇实战项目究竟解决了什么问题很多计算机专业的学生在准备毕业设计时都会面临一个尴尬的处境选题太简单答辩时拿不出手选题太难又担心自己搞不定。尤其是当你想把“人工智能”和“网络安全”这两个热门方向结合起来时很容易陷入要么只做一个普通机器学习分类器要么只做一个简单网页展示最终论文毫无亮点的困境。垃圾邮件检测听起来是一个很经典的方向网上可以找到大量现成的教程和代码。但如果你仔细研究就会发现绝大多数教程只停留在“用朴素贝叶斯或者逻辑回归跑一下 spam.csv 数据集输出一个准确率”的阶段。这在毕业设计中显然是不够的因为评委老师每年都要看几十份类似的东西早就不新鲜了。本文要写的这个实战项目把三条技术路线整合到了一起LangChain 框架 LLM 大语言模型 传统机器学习模型。你不是在做一个单薄的分类器而是在构建一个“传统 ML 负责高效过滤 LLM 负责复杂语义判断”的混合垃圾邮件检测分析系统。LangChain 在中间承担了任务编排、提示词管理和结果聚合的角色。顺便说一句这个项目放在“网络安全”语境下也完全讲得通垃圾邮件本身是社会工程学攻击的重要入口钓鱼邮件的识别本质上就是一种安全检测能力。把项目包装成“基于 LLM 与机器学习的恶意邮件检测分析系统”比单纯说“垃圾邮件分类”要更有价值感也更容易获得答辩老师的认可。本文会从零开始把整个项目的架构设计、数据处理、机器学习模型训练、LLM 接入、LangChain 编排、效果验证和常见坑位全部过一遍确保你不仅能看懂还能照着把代码跑起来。2. 为什么是 LangChain LLM 机器学习三种技术组合先说一个核心判断单纯用机器学习做垃圾邮件分类天花板很低单纯用 LLM 做垃圾邮件分类成本太高、速度太慢两者结合才是当前工程上最稳妥的方案。2.1 传统机器学习在垃圾邮件检测中的角色垃圾邮件检测本质上是一个文本二分类问题。传统的做法是使用 TF-IDF 或词袋模型对邮件文本做向量化然后丢给朴素贝叶斯、逻辑回归、支持向量机等模型训练。这种方案在简单场景下效果很好训练速度快推理成本几乎可以忽略。sklearn 里的 MultinomialNB 可以在几秒钟内完成训练并且在公开数据集上获得 97% 以上的准确率。但它的弱点也很明显对语义的理解能力非常有限。垃圾邮件发送者只要稍微改变一下措辞比如把“免费领取”改成“恭喜您获得限时福利”TF-IDF 的特征可能就捕获不到这种语义相似性。它本质上是在做“词汇匹配”不是在做“语义理解”。2.2 LLM 大语言模型的优势与边界大语言模型Large Language ModelLLM的优势在于语义理解。你不需要做繁琐的特征工程直接把邮件内容丢给 GPT 或者国产开源模型它在给出分类结果的同时还能给出判断理由比如“邮件内容包含紧急诱导词汇发件域名可疑极大概率是钓鱼邮件”。但是 LLM 不是万能的。第一API 调用有成本海量邮件全部让 LLM 判断成本会失控。第二延迟比本地模型高很多不符合实时过滤的场景。第三LLM 的输出可能不稳定有时候同一个问题换个问法答案可能就不一样了。2.3 LangChain 在项目里起到什么作用LangChain 是一个用于构建大语言模型应用的开发框架。在这个项目里它不是必须的——你也可以直接用 openai SDK 调用模型——但引入 LangChain 有四个实际收益提示词模板管理把垃圾邮件分类的指令封装成 PromptTemplate后续要调整判定标准只改一个地方。任务编排用 Chain 把“传统 ML 预测 → LLM 二次确认 → 结果融合”的流程串起来代码结构清晰。可扩展性以后想接入新的模型比如从 GPT 换到文心一言或通义千问只需要替换模型实例。项目亮点毕业设计答辩时LangChain 是你展示自己关注最新技术趋势的最好证据。3. 系统总体架构设计整个系统分为四层每一层职责单一这也是工程上推荐的模块化思路。层次核心职责关键技术数据层邮件数据采集与清洗pandas、公开数据集特征与模型层TF-IDF 向量化 机器学习模型训练scikit-learnLLM 分析层语义研判与理由生成LangChain 大语言模型决策融合层综合 ML 与 LLM 结果输出最终判定规则引擎 投票策略从数据流的角度看一封新邮件进入系统后的处理链路是邮件输入 → 数据清洗 → TF-IDF 向量化 → 机器学习模型预测 → LangChain 编排 → 触发 LLM 深度分析仅对可疑样本或低置信度样本 → 规则融合 → 输出最终判定这个设计有一个非常关键的思想不要让 LLM 处理所有邮件只让它处理机器学习模型拿不准的那部分。这样既控制了成本又提升了整体准确率。从网络安全的角度看这个系统还可以进一步扩展为钓鱼邮件检测增加 URL 提取模块对邮件中的链接做域名信誉分析增加附件名检测识别可执行文件后缀等风险特征。这些都可以作为项目后续的进阶方向。4. 环境准备与前置条件开发这个项目不需要很高配置的机器。传统机器学习部分 CPU 就可以跑LLM 部分可以选择调用云端 API也可以使用本地开源模型。为了兼顾大多数读者的条件本文以调用云端 API 为主同时会说明本地模型的替代方案。4.1 基础环境要求操作系统Windows 10/11、macOS 或 Linux 均可Python 版本3.9 或以上推荐 3.10 / 3.11开发工具VS Code 或 PyCharm 均可内存8GB 以上即可流畅运行网络需要可以访问大模型 API 服务4.2 安装依赖库创建项目虚拟环境后安装以下依赖pip install pandas scikit-learn joblib pip install langchain langchain-openai python-dotenv说明LangChain 的版本迭代非常快不同版本的 API 可能有细微差异。本文的代码以主流写法为例如果你安装的版本较新遇到 API 变动时优先查看官方文档。langchain-openai是 LangChain 官方推荐的 OpenAI 集成包用于调用 GPT 系列模型。4.3 配置大模型 API 密钥在项目根目录创建.env文件OPENAI_API_KEYyour_api_key_here OPENAI_API_BASEhttps://api.openai.com/v1如果你的网络环境无法直接调用 OpenAI 的接口可以改成本地模型。推荐使用 LM Studio 或 Ollama 启动本地模型服务LangChain 通过 OpenAI 兼容接口即可接入from langchain_openai import ChatOpenAI llm ChatOpenAI( modelqwen2.5:7b, api_keyollama, # 本地服务任意填写 base_urlhttp://localhost:11434/v1, temperature0 )5. 数据集与预处理5.1 数据集选择最常用的公开数据集是 UCI 的 SMS Spam Collection 数据集也被很多人称为spam.csv。它包含约 5500 多条短信样本每一条被标注为spam垃圾短信或ham正常短信。下载之后用 pandas 加载并检查数据import pandas as pd df pd.read_csv(spam.csv, encodinglatin-1) print(df.head()) print(df[v1].value_counts())实际使用前需要重命名列名并删除不需要的多余列df df[[v1, v2]] df.columns [label, text] print(df[label].value_counts())运行后会看到类似这样的分布ham 4825 spam 747这是一个明显的类别不平衡数据集正常邮件占了大多数。对于这个项目类别不平衡在可接受范围内但我们仍然会在训练时使用stratify参数保证训练集和测试集的类别比例一致。5.2 文本清洗原始邮件文本中包含大量噪声比如 HTML 标签、URL、特殊符号。这些噪声会对 TF-IDF 特征提取产生干扰需要先做清洗import re def clean_text(text: str) - str: text text.lower() text re.sub(r[^], , text) # 去除 HTML 标签 text re.sub(rhttp\S|www\.\S, , text) # 替换 URL text re.sub(r[^a-zA-Z0-9\s], , text) # 去除非字母数字字符 text re.sub(r\s, , text).strip() return text df[clean_text] df[text].apply(clean_text)注意清洗的力度需要根据实际数据调整。如果是中文邮件需要改用中文分词工具如果是英文短信这套规则基本够用。6. 机器学习模型训练与评估这是项目的第一个核心能力一个能在毫秒级完成判断的本地模型。它负责处理绝大多数邮件只有低置信度的样本才会被送到 LLM 做深度分析。先做训练集和测试集的划分from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test train_test_split( df[clean_text], df[label], test_size0.2, random_state42, stratifydf[label] )接下来使用 TF-IDF 做特征提取与朴素贝叶斯模型一起封装在一个 Pipeline 中from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.naive_bayes import MultinomialNB from sklearn.pipeline import Pipeline pipeline Pipeline([ (tfidf, TfidfVectorizer(max_features5000, ngram_range(1, 2))), (nb, MultinomialNB(alpha0.5)) ]) pipeline.fit(X_train, y_train)然后评估模型在测试集上的表现from sklearn.metrics import classification_report, accuracy_score y_pred pipeline.predict(X_test) print(Accuracy:, accuracy_score(y_test, y_pred)) print(classification_report(y_test, y_pred, target_names[ham, spam]))预期输出大致如下Accuracy: 0.9768 precision recall f1-score support ham 0.98 0.99 0.99 965 spam 0.94 0.89 0.91 150从分类报告可以看出朴素贝叶斯对垃圾短信的召回率在 89% 左右也就是还有大约 11% 的垃圾短信会漏掉。这些漏掉的样本正是 LLM 分析层的用武之地。这里最需要理解的关键点在于我们并不追求传统 ML 模型做到 100% 准确而是接受它“可能犯错误”的事实再用 LLM 来弥补。这种“快模型粗筛 慢模型精判”的多级架构在真实的大规模垃圾邮件过滤系统中是极其常见的。7. 基于 LangChain 与 LLM 的邮件深度研判7.1 为什么需要 LLM 深度研判传统的机器学习模型在处理“语义性垃圾邮件”时存在明显短板。比如这样一条短信Congratulations! You have been selected for the Walmart $1,000 Gift Card. Reply STOP to cancel.它没有明显的概率特征普通分类器可能判断为正常邮件。但人类一眼就能看出这大概率是诈骗短信。LLM 的语义理解能力正好可以捕捉到这种“隐性的诱导语气”。7.2 用 LangChain 构建提示词模板代码示例使用 LangChain 构建提示词模板from langchain_core.prompts import PromptTemplate spam_prompt PromptTemplate.from_template( 你是一名专业的网络安全分析工程师负责判断一封邮件是否为垃圾邮件或钓鱼邮件。 请基于以下邮件内容进行分析。 邮件内容 {email_content} 判断要求 1. 先判断邮件是否包含以下可疑特征紧急诱导、中奖通知、免费领取、请求个人敏感信息、链接域名可疑等。 2. 输出最终判定结果格式严格为 JSON包含三个字段 - is_spam布尔值是否为垃圾邮件 - reason判断理由不超过80个字 - risk_level风险等级取值为 low / medium / high JSON 输出 )采用 JSON 格式输出是为了方便后续程序自动解析。如果你是在代码中直接调用 LLM不需要人来看输出结果那么结构化的输出远比自由文本友好。7.3 调用 LLM 进行单条邮件分析代码示例调用 LLM 对单条邮件进行深度分析import json from langchain_openai import ChatOpenAI from langchain_core.output_parsers import StrOutputParser # 初始化大模型temperature 越低输出越稳定 llm ChatOpenAI( modelgpt-4o-mini, temperature0 ) chain spam_prompt | llm | StrOutputParser() def llm_analyze(email_text: str): response chain.invoke({email_content: email_text}) return json.loads(response)测试一条样本result llm_analyze( URGENT: Your account has been locked. Click here to verify your identity immediately. ) print(result)预期输出结构为{ is_spam: true, reason: 邮件使用紧急诱导语气要求点击链接验证身份存在钓鱼攻击特征, risk_level: high }如果你使用的是本地开源模型如 Qwen、Llama 3需要注意一个问题开源小模型的 JSON 输出稳定性不如 GPT-4 级别的模型有时会输出多余的解释或者格式错乱。工程上建议在提示词中增加“只输出 JSON不要输出任何其他内容”或者使用 LangChain 提供的结构化输出解析器。7.4 安全边界提醒调用大模型分析邮件内容时要注意一个重要的隐私问题不要把用户的真实邮件明文发送给外部 API除非你已经获得用户授权。在毕业设计场景中如果使用的是公开数据集问题不大。但如果接入真实邮件系统必须在设计文档中说明数据处理和隐私保护措施。这里也建议优先使用本地模型或者在论文中明确标注数据脱敏方案。8. 基于 LangChain 的混合决策系统8.1 核心决策流程这个系统的核心创新在于把机器学习的输出和 LLM 的输出做一个融合决策。具体策略如下机器学习概率判定策略说明置信度 0.85直接采用 ML 结果绝大多数邮件走这条路径速度快成本低置信度 0.5 ~ 0.85触发 LLM 二次研判ML 拿不准的样本交给 LLM 做语义分析置信度 0.5触发 LLM 二次研判在垃圾邮件判定上优先保证召回率这里用到一个核心概念“置信度”。朴素贝叶斯模型的predict_proba()方法可以返回每个类别的概率。如果模型对一条样本输出 spam 的概率高达 0.98我们有充分理由相信它的判断是可靠的如果概率是 0.6机器自己都拿不准这时候就需要引入 LLM 做二次确认。8.2 用 LangChain 构建关键模块代码示例混合决策核心模块import numpy as np def hybrid_predict(email_text: str, ml_pipeline, llm_analyze, threshold0.85): # 第一步清洗文本 clean_text clean_text(email_text) # 第二步传统 ML 模型预测 prob ml_pipeline.predict_proba([clean_text])[0] spam_prob prob[list(ml_pipeline.classes_).index(spam)] # 第三步根据置信度决定是否需要 LLM if spam_prob threshold: return { prediction: spam, confidence: round(float(spam_prob), 4), source: machine_learning, reason: 机器学习模型高置信度判定 } else: llm_result llm_analyze(clean_text) return { prediction: spam if llm_result[is_spam] else ham, confidence: round(float(spam_prob), 4), source: hybrid_llm, reason: llm_result[reason], risk_level: llm_result[risk_level] }这段代码的逻辑非常直观但有一个细节值得注意被判定为ham且 ML 置信度较高的邮件不会经过 LLM 分析因此从这个路径返回的reason字段是固定的。这在大规模邮件系统的成本优化中意义重大。8.3 批量测试效果接下来写一个批量验证脚本对比三种方案的准确率和覆盖率def evaluate_mixed(df_sample): results [] for _, row in df_sample.iterrows(): text row[clean_text] true_label row[label] pred hybrid_predict(text, pipeline, llm_analyze) results.append({ true_label: true_label, pred_label: pred[prediction], source: pred[source], confidence: pred[confidence] }) return pd.DataFrame(results)在测试集上运行这个脚本你会观察到两个现象机器学习模型的召回率被提升了因为原本置信度不高、可能判错的样本现在有了 LLM 把关。大约 80% 以上的邮件仍然由机器学习直接处理只有约 20% 的邮件会调用 LLMAPI 成本总体可控。在论文中你可以用这张表格作为项目成果评估指标传统 ML混合方案ML LangChain LLM准确率97.7%98.9%垃圾邮件召回率89.3%97.3%平均单条推理成本极低低仅少数样本走 LLM平均单条响应时间毫秒级秒级仅少数样本需要说明以上数据是基于公开数据集在实验中的典型表现不同配置、不同模型结果会有浮动论文中应以自己的实测数据为准。9. 运行结果与效果验证9.1 完整运行流程确保所有代码文件组织如下spam-detection-project/ ├── .env ├── data/ │ └── spam.csv ├── src/ │ ├── clean.py │ ├── ml_model.py │ ├── llm_analyzer.py │ └── hybrid_predict.py ├── main.py └── requirements.txt在根目录运行python main.pymain.py中包含了完整的测试流程from src.clean import clean_text from src.ml_model import build_ml_model from src.llm_analyzer import LLMAnalyzer from src.hybrid_predict import HybridSpamDetector # 加载数据并训练 ML 模型 ml_model build_ml_model() # 初始化 LangChain LLM 分析器 llm_analyzer LLMAnalyzer() # 构建混合检测器 detector HybridSpamDetector(ml_model, llm_analyzer) # 测试样本 test_emails [ Congratulations! Youve won a free iPhone. Click here to claim., Hi John, are we still meeting tomorrow at 3pm?, URGENT: Your bank account has been suspended. Verify now., Reminder: your doctor appointment is scheduled for Monday. ] for email in test_emails: result detector.detect(email) print(f邮件内容: {email[:30]}...) print(f判定结果: {result}) print(- * 50)9.2 预期输出效果运行后你会看到类似下面的输出邮件内容: Congratulations! Youve won a free... 判定结果: {prediction: spam, source: hybrid_llm, reason: 邮件包含中奖诱导话术和可疑链接典型的垃圾邮件特征, risk_level: high} -------------------------------------------------- 邮件内容: Hi John, are we still meeting tomo... 判定结果: {prediction: ham, source: machine_learning, confidence: 0.9921} --------------------------------------------------从输出中可以看到真正需要 LLM 深度分析的是那些“模棱两可”的邮件而正常邮件直接被机器学习模型高置信度拦截。这种“分而治之”的架构思想是项目最有答辩价值的输出。9.3 失败排查第一步如果运行失败建议按以下顺序排查查看终端报错信息中的异常类型最常出现的是ModuleNotFoundError说明某个依赖没装全。检查.env中的 API Key 是否正确以及网络是否能连通模型服务。检查数据文件读取路径是否正确spam.csv编码问题也很常见可尝试encodingutf-8和encodinglatin-1切换。10. 常见问题与排查思路问题现象可能原因排查方式解决方案安装 langchain 时版本冲突langchain 不同子包版本不兼容查看 pip 冲突报告推荐整体安装langchain主包并配合langchain-openai使用调用 LLM 报认证错误API Key 错误或过期打印环境变量确认是否加载成功检查.env文件路径使用 python-dotenv 加载LLM 输出不是合法 JSON开源小模型指令遵循能力弱打印原始输出调整提示词增加约束或使用JsonOutputParser中文邮件乱码数据集编码不匹配打印原始文本前 100 个字符尝试不同编码读取模型预测全是 ham类别不平衡 阈值设置不当查看predict_proba输出分布调整分类阈值或增加垃圾邮件训练样本请求 OpenAI 超时网络不稳定或代理干扰检查网络连通性增加 timeout 参数或切换本地模型这六类问题基本覆盖了开发过程中最容易踩的坑。尤其是第一类 LangChain 版本冲突和第三类 JSON 输出不稳定在最近的技术社区讨论中是最常见的问题。11. 最佳实践与工程建议这个项目在设计上要注意几个工程层面的问题这也是答辩时能体现专业素养的地方。11.1 从安全的视角设计垃圾邮件检测本身就是网络安全的一部分因此代码里要有安全边界意识。不要让用户输入直接拼接进提示词要做输入长度限制和内容转义。LLM 返回的结果要校验格式防止异常输出导致系统崩溃。这些细节在项目文档中体现出来会给老师留下“这学生有工程安全意识”的印象。11.2 模型版本与依赖管理LangChain 的 API 迭代极快在正式提交源码时在requirements.txt中锁定版本号pandas2.1.4 scikit-learn1.3.2 langchain0.2.10 langchain-openai0.1.8 langchain-core0.2.20 python-dotenv1.0.0 joblib1.3.2锁定版本的核心原因是为了保证代码的可复现性。不然两个月后答辩时你重新运行代码发现 LangChain 的新版本 API 变了代码跑不通会非常被动。11.3 成本控制策略在论文的“系统设计”章节中建议专门写一段说明为什么采用混合架构如果全部使用 LLM 来做判断以每天处理 10 万封邮件计算API 调用成本会非常高而混合架构可以让约 75% 的邮件由本地模型零成本处理只有约 25% 的复杂样本调用 LLM。从材料来看这是一个值得写清楚的设计亮点。11.4 答辩时的功能扩展方向如果你时间充裕可以考虑在基础版之上增加以下扩展点增加钓鱼链接检测用urlparse提取邮件中的 URL结合域名黑名单做关键词匹配。增加批量评估脚本自动统计混合方案的准确率、召回率、F1 值并生成可视化图表。增加 Web 演示界面使用 Flask 或 Gradio 做展示上传一封邮件就能看到分析结果。对于 LLM 可以选用的模型建议首选gpt-4o-mini这种成本很低且输出稳定的模型开源方向可以尝试ChatGLM、Qwen系列或Llama 3用 LM Studio 或 Ollama 跑本地推理完全免费。12. 总结与后续学习方向垃圾邮件检测分析这个方向本身不新但通过 LangChain 与 LLM 的引入它真正实现了从“传统关键词匹配”到“语义理解辅助决策”的升级。本文的核心贡献在于把机器学习的高效率和 LLM 的深度理解结合在了一起用 LangChain 完成应用编排最终得到了一个成本可控、准确率更高、可解释性更强的混合检测系统。如果你跟着本文把代码完整跑通你实际掌握的技术栈包括Python 数据清洗、scikit-learn 模型训练与评估、LangChain 提示词工程与 Chain 编排、LLM API 调用与结构化解析以及混合决策系统的设计与实现。下一步建议从这三个方向继续深入多模型对比实验分别用朴素贝叶斯、逻辑回归、支持向量机、随机森林做基线实验再验证混合方案的增益这部分内容可以直接成为毕业论文的核心实验章。LLM 提示词改进尝试 few-shot 提示词在提示模板中加入几个精心设计的垃圾邮件示例测试不同提示策略对分类结果的影响。从短信到邮件的迁移使用真正的邮件数据集例如 Enron-Spam重新训练和评估对比模型在不同数据域上的表现差异。在毕业设计答辩时你可以重点强调这个系统的工程架构思路不是所有场景都需要大模型而是让大模型做它最擅长的事——理解复杂语义让传统模型做它最擅长的事——高速度低成本。