尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

本地可调试Python聊天机器人系统搭建指南

本地可调试Python聊天机器人系统搭建指南 简介本资源是一套面向本科毕业设计与Python课程实践的闲聊型AI机器人对话系统完整实现适用于计算机、软件工程等专业学生完成毕设、期末大作业或高分课程设计。系统基于Python构建含清晰代码注释与全流程部署支持兼顾功能完整性与新手友好性可直接运行并二次开发。压缩包共28个文件涵盖10个YAML配置文件用于对话流程、意图识别与凭证管理、3个核心Python脚本主服务与逻辑处理、前端相关JS/HTML/CSS/LESS文件及Webpack构建配置辅以数据库脚本、ReadMe说明、drawio架构图和调试用测试文件整体仅646KB轻量易上手。已有306人学习下载资源提供从环境搭建、模型对接到界面交互的全链路支持目录结构规范模块划分明确如chitchat/data/endpoints.yml体现对话引擎分层设计特别适合希望快速理解AI对话系统工程落地的学生开发者。1. 这不是调用几个 API 的“AI 聊天框”一个真正在本地跑通、可调试、带完整对话状态管理的 Python 闲聊机器人系统你是不是也试过网上搜“Python 聊天机器人源码”下了一堆 zip 包解压后发现只有三行import openaiinput()print()运行起来像在和一个复读机谈恋爱问“今天吃饭了吗”它回“今天吃饭了吗”再问“你叫什么”它回“你叫什么”——根本没状态、没上下文、没意图识别更别说部署成 Web 服务或接入数据库存聊天记录了。这个毕业设计源码包ai_chitchat-main恰恰反其道而行之它不依赖任何外部大模型 API核心对话逻辑基于规则模板轻量级意图匹配domain.ymlactions模块所有代码在本地 Python 环境中可单步调试它自带 Flask 后端、Vue 前端src/public/、SQLite 数据库存储历史会话chitchat/目录下含初始化脚本甚至提供了endpoints.yml配置 WebSocket 连接参数。适合真正想搞懂“对话系统怎么从零搭起”的本科生——不是抄个 demo 交差而是能讲清actions.py里ActionGreetUser怎么触发、views.py如何把用户输入喂给RasaNLUInterpreter本地加载的轻量 NLU 模型、credentials.yml为何要配置socketio而非rest通道。如果你正卡在毕设答辩前“系统跑不通”“老师问‘状态怎么保持’答不上来”“前端发请求后端收不到”这些具体问题上这份源码就是为你写的。2. 从零启动环境搭建、依赖安装与项目结构解剖2.1 环境准备Python 版本、虚拟环境与关键依赖锁定这个项目对 Python 版本有明确要求必须使用 Python 3.8 或 3.9。为什么因为requirements.txt中依赖的rasa2.8.20注意不是最新版 Rasa 3.x与tensorflow2.5.0存在严格的 ABI 兼容性约束。我在 Python 3.10 下执行pip install -r requirements.txt时tensorflow编译失败并报错undefined symbol: _PyThreadState_UncheckedGet这是典型的 CPython ABI 不匹配。解决方案是退回 Python 3.9# 推荐使用 pyenv 管理多版本macOS/Linux pyenv install 3.9.18 pyenv local 3.9.18 python -V # 确认输出 Python 3.9.18 # Windows 用户可用官方安装包勾选 Add Python to PATH # 安装后在 cmd 中验证 python --version提示不要用 conda 创建环境rasa2.8.20的 wheel 包未上传至 conda-forgeconda install 会强制降级numpy到 1.19导致后续scikit-learn加载失败。坚持用venv。创建并激活虚拟环境python -m venv venv_chitchat source venv_chitchat/bin/activate # Linux/macOS # venv_chitchat\Scripts\activate.bat # Windows安装依赖前先升级 pip 和 setuptools避免 wheel 构建失败pip install --upgrade pip setuptools wheel然后安装核心依赖注意顺序rasa必须在tensorflow之后装否则会覆盖兼容版本pip install tensorflow2.5.0 pip install rasa2.8.20 pip install flask2.0.3 pip install python-socketio5.5.0 pip install eventlet0.33.1 pip install -r requirements.txtrequirements.txt中最关键的几项rasa2.8.20: 提供 NLU自然语言理解和 Core对话管理能力本项目用其RasaNLUInterpreter解析用户输入意图用Agent.load()加载训练好的模型。flask2.0.3: 构建后端 REST APIviews.py中的/webhooks/socketio/路由即由此提供。python-socketio5.5.0eventlet0.33.1: 实现 WebSocket 长连接让前端 Vue 页面能实时接收机器人回复而非轮询 HTTP 接口。sqlalchemy1.4.23: ORM 层chitchat/models.py用它定义ChatHistory表结构并通过db.session.add()持久化每轮对话。2.2 项目目录深度解析每个文件夹/文件的真实作用解压后的ai_chitchat-main/目录结构不是随意组织的而是严格遵循 Rasa Flask Vue 的分层架构。下面逐个拆解标出哪些是必须修改、哪些是可删减、哪些是调试时必看路径类型关键作用是否需修改调试关注点chitchat/Python 包核心业务逻辑__init__.py初始化 Flask Appmodels.py定义 SQLite 表database.py封装 DB 连接nlu_interpreter.py加载本地 Rasa NLU 模型✅ 必须检查SQLALCHEMY_DATABASE_URI路径是否指向instance/chitchat.dbmodels.py中ChatHistory的created_at字段是否用datetime.utcnow时区问题易导致记录时间错乱data/文件夹训练数据源nlu.yml意图样本、stories.yml对话流程、domain.yml意图/实体/响应模板✅ 修改nlu.yml新增自定义问候语如 - intent: greetexamples:- 你好呀- 哈喽机器人endpoints.ymlYAML 配置服务通道配置指定action_server地址本项目为http://localhost:5055/webhooksocketio通道参数cors_allowed_origins必须设为[*]否则 Vue 前端跨域✅ 必须将cors_allowed_origins改为[*]或[http://localhost:8080]若 WebSocket 连接失败先检查此处url是否与actions服务启动端口一致actions/Python 包自定义动作实现actions.py中ActionGreetUser类重写run()方法可在此加入数据库查询、天气 API 调用等逻辑✅ 如需扩展功能如查成绩在此新增ActionQueryScore类run()方法中dispatcher.utter_message()的text参数是否被正确拼接中文乱码常源于此处未声明encodingutf-8src/前端源码Vue 3 Composition API 实现的聊天界面App.vue是主组件ChatBox.vue渲染消息流socket.js封装 Socket.IO 客户端✅ 修改socket.js中io(http://localhost:5005)的端口为后端实际端口默认 5005浏览器控制台 Network 标签页查看socket.io/?EIO4...请求是否返回 101 Switching Protocols特别注意config.yml它不是 Rasa 的标准配置而是本项目自定义的 Flask 配置文件其中DEBUG: true决定是否开启 Flask 调试模式开发时必须为true否则 500 错误不显示详细 traceback。2.3 启动三件套后端服务、动作服务器、前端开发服务器这个系统不是单进程应用而是三个独立服务协同工作Flask 后端处理 HTTP/WebSocket、Rasa Action Server执行自定义动作、Vue 开发服务器提供 UI。缺一不可且端口不能冲突。第一步启动 Rasa Action Server必须最先启动进入项目根目录执行cd ai_chitchat-main rasa run actions --enable-api --cors * --debug--enable-api: 允许外部 HTTP 调用动作Flask 后端会向http://localhost:5055/webhook发 POST 请求--cors *: 解决跨域否则 Flask 无法调用动作接口--debug: 输出详细日志看到Action server started即成功注意此命令会占用5055端口。若提示Address already in use用lsof -i :5055macOS/Linux或netstat -ano | findstr :5055Windows查进程并 kill。第二步启动 Flask 后端服务新开终端激活同一虚拟环境执行cd ai_chitchat-main export FLASK_APPchitchat export FLASK_ENVdevelopment flask run --host0.0.0.0 --port5005--host0.0.0.0: 允许局域网内其他设备访问方便手机测试--port5005: 与endpoints.yml中socketio的url端口一致启动后访问http://localhost:5005/health应返回{status:ok}证明后端存活第三步启动 Vue 前端开发服务器再开一个终端进入src/目录cd ai_chitchat-main/src npm install npm run servenpm install: 安装vue,socket.io-client,element-plus等前端依赖npm run serve: 启动开发服务器默认http://localhost:8080此时打开浏览器访问http://localhost:8080即可看到聊天界面验证连通性在前端输入“你好”后端终端应打印Received message: 你好Action Server 终端应出现Executing action: utter_greet数据库instance/chitchat.db中chat_history表应新增一条记录。三者日志全部出现才算真正跑通。3. 对话引擎核心Rasa 2.8 的本地 NLU 模型训练与意图识别原理3.1 为什么不用 ChatGLM 或 Llama轻量级规则模板的工程合理性看到“AI 机器人”就想到大模型这恰恰是本项目最值得深挖的设计选择。ai_chitchat-main没有调用任何 HuggingFace 模型或 OpenAI API而是采用 Rasa 2.8 的传统 pipelineWhitespaceTokenizer→RegexFeaturizer→CountVectorsFeaturizer→DIETClassifier对话意图分类器→EntitySynonymMapper。这套组合在资源受限场景如毕业答辩演示机只有 4GB 内存下优势明显冷启动快rasa train生成的models/下.tar.gz模型文件仅 12MB加载到内存耗时 2s而加载chatglm-6b至少需 12GB 显存和 30s 以上。可控性强domain.yml中明确定义greet,goodbye,ask_weather等意图stories.yml用 YAML 描述“用户问天气 → 机器人查 API → 返回结果”这一确定性流程不存在大模型的幻觉hallucination风险。调试友好rasa shell nlu命令可交互式测试任意句子的意图识别结果比如输入今天北京天气怎么样立即看到intent: ask_weather (confidence: 0.92)而大模型输出不可预测。这种设计不是技术落后而是面向教学场景的精准取舍本科生需要理解“意图识别如何从文本特征映射到标签”而不是调用一个黑匣子 API。data/nlu.yml中的样本就是最好的教材——它告诉你机器学习的第一步永远是高质量标注数据。3.2 训练自己的 NLU 模型从修改 data/ 到生成 models/Rasa 模型训练不是“一键生成”而是分步可验证的过程。以下是标准流程每一步都有检查点① 修改data/nlu.yml新增意图样本例如为支持“查课表”功能在nlu.yml的intent: query_schedule下添加- intent: query_schedule examples: | - 我的课表 - 今天有什么课 - 下节课是什么 - 查一下明天的课注意|符号表示保留换行每行样本必须顶格无缩进否则 Rasa 解析失败报YAML error。② 修改data/domain.yml声明新意图与响应在intents:列表末尾追加- query_schedule并在responses:下添加responses: utter_query_schedule: - text: 请稍等正在查询您的课表...③ 修改data/stories.yml定义对话流程添加一个 story描述用户触发query_schedule后机器人的行为- story: user asks for schedule steps: - intent: query_schedule - action: utter_query_schedule - action: action_query_schedule # 此处调用自定义动作④ 训练模型确保在项目根目录执行rasa train --config config.yml --domain domain.yml --data data/ --out models/--config config.yml: 指定 pipeline 配置本项目config.yml已预设 DIETEntitySynonym--out models/: 模型输出路径生成的.tar.gz文件名含时间戳如20230815-143205.tar.gz⑤ 验证模型效果训练完成后立即用rasa shell nlu测试rasa shell nlu Your input - 今天下午有课吗 { text: 今天下午有课吗, intent: { name: query_schedule, confidence: 0.872 }, entities: [] }如果confidence 0.7说明样本不足需回nlu.yml补充更多变体句式如“下午第一节是什么课”“我第二节上什么”。3.3 自定义动作action_query_schedule的完整实现当stories.yml中的action: action_query_schedule被触发时Rasa Action Server 会调用actions/actions.py中同名类。以下是标准实现模板已适配本项目数据库结构# actions/actions.py from typing import Any, Text, Dict, List from rasa_sdk import Action, Tracker from rasa_sdk.executor import CollectingDispatcher from rasa_sdk.events import SlotSet from chitchat.database import db from chitchat.models import CourseSchedule class ActionQuerySchedule(Action): def name(self) - Text: return action_query_schedule def run( self, dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict[Text, Any], ) - List[Dict[Text, Any]]: # 1. 从 tracker 获取用户 ID假设登录态存在 slot user_id user_id tracker.get_slot(user_id) if not user_id: dispatcher.utter_message(text请先登录以查询课表) return [] # 2. 查询数据库此处简化实际应查 CourseSchedule 表 try: # 示例查今日课程 from datetime import datetime today datetime.now().strftime(%A) # Monday, Tuesday... # 实际 SQL 查询本项目未提供 CourseSchedule 表需自行创建 courses [高等数学, Python 编程] response_text f您今天{today}的课程是{、.join(courses)} except Exception as e: response_text f查询课表时出错{str(e)} # 3. 发送回复 dispatcher.utter_message(textresponse_text) return []关键点说明tracker.get_slot(user_id): 从对话状态中提取用户标识这是实现个性化服务的基础如不同用户看到不同课表。dispatcher.utter_message(): 向用户发送文本必须在此处设置text参数否则前端收不到消息。return []: 返回空事件列表表示不修改对话状态若需设置新 slot如SlotSet(schedule_fetched, True)则需返回该事件。提示actions.py中所有Action类的name()方法返回值必须与stories.yml中action:后的字符串完全一致包括大小写和下划线否则 Rasa 找不到对应动作报错ActionNotFoundException。4. 前后端联调避坑指南WebSocket 连接失败、消息不显示、数据库写入异常的 5 个血泪经验4.1 现象前端页面空白浏览器控制台报Failed to load resource: net::ERR_CONNECTION_REFUSED原因Vue 前端尝试连接http://localhost:5005/socket.io/但 Flask 后端未启动或端口配置错误。解决检查 Flask 终端是否显示* Running on http://127.0.0.1:5005查看src/socket.js第 5 行const socket io(http://localhost:5005);—— 确保端口号与 Flask 启动端口一致若 Flask 启动在0.0.0.0:5005而前端在手机访问则需将localhost改为开发机局域网 IP如192.168.1.100。4.2 现象前端能发消息但机器人不回复Action Server 终端无日志原因endpoints.yml中action_server的url指向错误或 Flask 未正确配置socketio通道。解决检查endpoints.ymlaction_server:下的url必须是http://localhost:5055/webhookAction Server 默认端口检查chitchat/__init__.py确认socketio SocketIO(app, cors_allowed_origins*)已初始化且app是 Flask 实例在 Flask 终端输入curl -X POST http://localhost:5005/webhooks/socketio/webhook -H Content-Type: application/json -d {sender:test,message:hello}若返回{status:success}证明后端接收正常。4.3 现象消息在前端显示但instance/chitchat.db中chat_history表无记录原因chitchat/database.py中SQLALCHEMY_DATABASE_URI路径错误或db.create_all()未执行。解决检查chitchat/database.pyapp.config[SQLALCHEMY_DATABASE_URI] sqlite:///instance/chitchat.db——instance/目录必须存在且chitchat.db文件可写在chitchat/__init__.py的create_app()函数末尾确认有db.create_all(appapp)调用手动创建instance/目录mkdir instance再运行 Flask。4.4 现象中文回复显示为乱码如ä½ å¥½或前端消息气泡错位原因Flask 响应未声明 UTF-8 编码或 Vue 组件未设置meta charsetutf-8。解决在chitchat/views.py的socketio.on(message)处理函数中return jsonify({status: ok, message: reply_text})前添加from flask import make_response response make_response(jsonify({status: ok, message: reply_text})) response.headers[Content-Type] application/json; charsetutf-8 return response检查public/index.htmlhead内必须有meta charsetutf-8。4.5 现象rasa train报错ModuleNotFoundError: No module named sklearn尽管已pip install scikit-learn原因rasa2.8.20依赖scikit-learn0.24.2而新版本scikit-learn1.0API 不兼容。解决pip uninstall scikit-learn -y pip install scikit-learn0.24.2 # 再次运行 rasa train注意此问题在 Python 3.9.18 下高频出现因pip install rasa2.8.20会自动安装scikit-learn0.22但未锁死版本。务必手动降级。5. 高分答辩必备技巧让系统“活”起来的 3 个真实增强方案5.1 方案一接入真实天气 API让utter_ask_weather响应动态数据毕业设计最忌“假大空”一句“正在查询天气”不如直接显示“北京25°C晴”。本项目预留了actions/action_weather.py的扩展入口只需 10 行代码即可接入和风天气免费 API无需申请密钥限次调用# actions/action_weather.py import requests from rasa_sdk import Action from rasa_sdk.events import SlotSet class ActionGetWeather(Action): def name(self) - str: return action_get_weather def run(self, dispatcher, tracker, domain): # 1. 从 tracker 获取城市需先在 domain.yml 中定义 entity location city tracker.get_slot(location) or 北京 # 2. 调用和风天气 API免费版每日 1000 次 url fhttps://devapi.qweather.com/v7/weather/now?location101010100keyyour_key # 注实际使用需注册 https://dev.qweather.com/ 获取 keylocation 参数查城市ID try: res requests.get(url, timeout5) data res.json() temp data[now][temp] text f{city}当前温度 {temp}°C{data[now][textDay]} except Exception as e: text f天气查询失败{str(e)} dispatcher.utter_message(texttext) return [SlotSet(weather_fetched, True)]答辩话术“老师这个天气功能不是静态响应而是实时调用第三方 API。我特意选了和风天气因为它有学生认证通道免费额度足够毕设演示。代码里还加了超时和异常捕获保证系统不会因网络问题卡死。”5.2 方案二用 SQLite 的 FTS5 扩展实现聊天记录全文检索评委常问“历史消息怎么查”本项目chitchat/models.py中ChatHistory表已预留content字段但原生 SQLite LIKE 查询效率低。启用 FTS5全文搜索只需两步① 修改chitchat/database.py在db.create_all()后添加def init_fts(): with app.app_context(): db.session.execute(CREATE VIRTUAL TABLE chat_history_fts USING fts5(content, user_id)) db.session.execute(INSERT INTO chat_history_fts SELECT content, user_id FROM chat_history) db.session.commit() # 在 create_app() 末尾调用 init_fts()② 在chitchat/views.py中新增检索接口app.route(/api/search, methods[GET]) def search_history(): query request.args.get(q, ) if not query: return jsonify([]) # FTS5 全文搜索 results db.session.execute( SELECT content, user_id, created_at FROM chat_history_fts WHERE content MATCH :q ORDER BY rank LIMIT 10, {q: query} ).fetchall() return jsonify([{content: r[0], user_id: r[1], time: r[2]} for r in results])前端 Vue 只需在ChatBox.vue添加搜索框调用/api/search?qPython即可秒级返回含“Python”的历史消息。这比“导出 Excel”高级得多体现数据库优化思维。5.3 方案三用rasa test nlu生成混淆矩阵量化模型效果答辩时被问“准确率多少”别只说“挺高”。用 Rasa 自带工具生成专业报告# 在项目根目录执行 rasa test nlu --nlu data/nlu.yml --out results/nlu --cross-validation --folds 3--cross-validation --folds 3: 三折交叉验证结果更可信输出results/nlu/confusion_matrix.png: 直观展示各意图识别准确率输出results/nlu/report.json: 包含 precision/recall/f1-score将confusion_matrix.png插入答辩 PPT指着“greet”意图的 98% F1-score 说“老师这是在 300 条样本上交叉验证的结果说明我们的问候语识别非常稳定。”从那以后我每次改完nlu.yml都强制走一遍rasa test nlu哪怕只是加了一句话。因为答辩现场被问“你凭什么说这个模型好”一张图胜过十句解释。希望帮到你。本文还有配套的精品资源点击获取
返回列表