简介:这是一套面向高校学生与初学者的Rasa中文聊天机器人完整开发实践资源,适用于毕业设计、课程设计及AI项目入门开发,聚焦自然语言理解(NLU)与对话管理(Core)两大核心能力落地。资源包含24个文件,涵盖7个Markdown开发指南、6个YAML配置文件(含domain、nlu、stories等)、5个Python脚本(含action服务与服务器启动)、3个文本说明及2个Bash部署脚本,整体压缩包仅4.42MB,轻量易用且结构清晰。已有247人学习下载,内容经实测可运行:支持前端调用Rasa服务、集成图灵闲聊与心知天气API,并提供Interactive Learning样本构建、MITIE+supervised_embeddings双管道训练方案及身份查询等典型场景案例。配套文档系统性强,覆盖从环境搭建、NLU优化(同义词/正则/查找表)、Core逻辑设计到1.9.5版本升级排错的全流程,是少有的兼顾原理讲解、代码解析与工程落地的中文Rasa实战资料。
1. Rasa中文聊天机器人不是“调个API就完事”的玩具:它是一套可落地、可调试、可交付的对话系统工程闭环
你手头正赶着毕业设计 deadline,导师说“做个智能客服原型”,你搜到一堆“Python 聊天机器人”——结果点开全是while True: input() + print()的硬编码回声;或者更糟,是套着 Flask 外壳、用 if-elif 堆出 200 行意图分支的“伪 NLU”。这种项目答辩时被问一句“如果用户说‘我昨天订的单怎么还没发货’,你怎么识别‘发货状态查询’这个意图?实体‘昨天’怎么归一化成相对时间?”当场哑火。而这份 Rasa 中文聊天机器人源码包,恰恰卡在真实工程与教学落地的交界点上:它不是 demo,而是跑通了NLU 意图识别 + 实体抽取 + Core 对话管理 + 外部 API 对接 + 交互式样本增强全链路的最小可行系统。所有模块都带中文注释、训练日志截图、train.bash和run_server.bash一键启停脚本,连 Windows 下 TensorFlow 兼容性问题(Rasa 1.9.5 版本锁)都提前踩过坑。适合课程设计快速验证对话逻辑,也经得起毕设答辩追问——比如你能现场rasa interactive进入对话调试模式,实时修正错标样本;也能打开data/nlu.md看到“查天气”意图下混用了“今天北京天气怎么样”“北京明天会不会下雨”“气温多少度”三类表达,并附有同义词表和正则规则。这不是教你怎么写 Python,而是教你怎么构建一个会“听懂人话、记住上下文、调用服务、持续进化”的对话黑匣子。
2. 从零启动:解压即训、训完即跑的 Rasa 中文环境搭建与模型训练实操
2.1 环境依赖与版本锁定:为什么必须用 Rasa 1.9.5 而不是最新版?
项目更新日志明确提到:“将 Rasa 版本升级到 1.9.5,解决 win10 使用 tensorflow 出现的异常”。这不是随意选的旧版本,而是经过实测的兼容性甜点区。Rasa 2.x+ 引入了rasa train core与rasa train nlu分离训练、--enable-api参数变更等 breaking change,而本项目train.bash脚本、config.yml中的 pipeline 配置(如supervised_embeddings)、甚至actions目录下的自定义 action 类结构,全部基于 1.9.5 的 API 设计。若强行升级,你会遇到:
rasa train报错Unknown pipeline component 'RegexFeaturizer'(新版已移除)server.py中rasa.core.agent.load_agent()方法签名变更导致无法加载模型actions模块 import 路径失效(新版要求from rasa_sdk import Action)
因此,环境初始化必须严格锁定:
# 创建独立虚拟环境(强烈建议,避免全局污染) python -m venv rasa_chitchat_env source rasa_chitchat_env/bin/activate # Linux/macOS # rasa_chitchat_env\Scripts\activate.bat # Windows # 安装指定版本(注意:Rasa 1.9.5 依赖 tensorflow<2.3,需避开 TF 2.3+ 的 ABI 不兼容) pip install rasa==1.9.5 tensorflow==2.2.0 numpy==1.19.5 requests==2.25.1 pip install rasa-sdk==1.9.0 # 注意:SDK 版本必须与 Rasa 主版本严格匹配提示:
requirements.txt中未显式声明tensorflow==2.2.0,但train.bash在 Windows 下失败的根本原因就是 TF 2.3+ 与 Rasa 1.9.5 C++ 扩展的 ABI 冲突。这是血泪经验——我曾因 pip 自动升级 TF 到 2.4 而重装系统三次。
2.2 数据结构解析:.md格式不是随便写的,它是 Rasa 1.9.5 的 NLU 训练契约
Rasa 1.9.5 使用 Markdown 格式定义训练数据,其语法有严格约束。本项目data/目录下包含:
nlu.md:意图与样例文本(含实体标注)stories.md:对话流程路径(Core 训练用)domain.yml:意图、实体、槽位、响应模板的全局声明
以nlu.md中“查天气”意图为例:
## intent:chit_chat_weather - 今天[北京](location)天气怎么样? - [上海](location)明天会不会下雨? - [广州](location)气温多少度? - 查一下[深圳](location)的天气预报 - [杭州](location)现在温度是多少关键细节:
## intent:后必须是纯英文标识符(chit_chat_weather),不能含空格或中文,这是模型内部 key;- 实体标注
[北京](location)中,location是 domain.yml 中定义的实体类型,且必须小写; - 每行样例必须独占一行,末尾不能有空格或 Tab;
- 同义词扩展不在
.md文件里,而在data/lookup_tables/location.txt中(每行一个地名),Rasa 会自动加载并用于 fuzzy 匹配。
若你新增样例,必须遵守此格式,否则rasa train会静默跳过该行(不报错但无效),导致意图识别率骤降——这是新手最常翻车的点。
2.3 一键训练:train.bash脚本背后的真实执行逻辑与参数含义
项目提供的train.bash并非简单包装,它封装了 Rasa 1.9.5 的标准训练流程,并预设了关键参数:
#!/bin/bash rasa train \ --config config.yml \ --domain domain.yml \ --data data/ \ --out models/ \ --fixed-model-name chitchat_model_$(date +%Y%m%d_%H%M%S)逐参数说明:
--config config.yml:指定 pipeline 配置。本项目使用supervised_embeddings(而非pretrained_embeddings),它通过监督学习联合优化意图和实体,对中文短句泛化性更好;--domain domain.yml:声明所有可识别的意图、实体、槽位及响应模板。注意其中responses:下的utter_weather_info必须与actions.py中调用的 response 名一致;--data data/:Rasa 会递归扫描该目录下所有.md和.yml文件,不要手动拆分数据到子文件夹,否则部分文件可能被忽略;--out models/:模型输出目录,生成chitchat_model_20200215_143022.tar.gz这样的时间戳命名压缩包;--fixed-model-name:强制指定模型名,避免 Rasa 自动生成随机 hash 名,方便后续run_server.bash精准加载。
执行后,你会看到类似输出:
2020-02-15 14:30:22 INFO rasa.nlu.model - Starting to train NLU component RegexFeaturizer. 2020-02-15 14:30:23 INFO rasa.nlu.model - Starting to train NLU component CountVectorsFeaturizer. ... 2020-02-15 14:32:18 INFO rasa.core.agent - Model directory models/chitchat_model_20200215_143022 created.训练耗时约 2~5 分钟(取决于 CPU),成功标志是models/目录下出现.tar.gz文件,且rasa test nlu能返回 >85% 的 F1 分数(项目实测值为 89.2%)。
2.4 启动服务:run_server.bash与server.py的双轨部署策略
项目提供两种服务启动方式,对应不同调试阶段:
方式一:run_server.bash(推荐用于快速验证)
#!/bin/bash rasa run \ --enable-api \ --cors "*" \ --debug \ --model models/chitchat_model_20200215_143022.tar.gz \ --endpoints endpoints.yml--enable-api:开启 REST API,供前端或 Postman 调用;--cors "*":允许任意域名跨域请求,开发阶段必备(生产环境需替换为具体域名);--debug:输出详细日志,包括每轮对话的 intent confidence、entity extraction 结果;--endpoints.yml:定义外部 action server 地址(本项目指向http://localhost:5055/webhook)。
方式二:server.py(用于深度定制与 debug)
from rasa.core.agent import Agent from rasa.core.interpreter import RasaNLUInterpreter import asyncio async def main(): interpreter = RasaNLUInterpreter("models/chitchat_model_20200215_143022/nlu") agent = Agent( "models/chitchat_model_20200215_143022/core", interpreter=interpreter, action_endpoint="http://localhost:5055/webhook" ) # 启动内置 HTTP server(仅用于测试,非生产) await agent.handle_channels() if __name__ == "__main__": asyncio.run(main())区别在于:rasa run是官方 CLI,稳定但定制性弱;server.py是手动加载模型,便于在 PyCharm 中打断点调试agent.predict_next_action()的决策过程。例如,当用户说“帮我查北京天气”,你可以 step intoagent.handle_message(),观察tracker中slots的变化、latest_event的类型,这才是理解 Rasa Core 工作机制的正道。
3. 对话引擎核心:NLU 意图识别与实体抽取的 pipeline 配置与效果调优
3.1config.yml中的supervised_embeddings管道为何比pretrained_embeddings更适合中文短句?
Rasa 1.9.5 提供多种 NLU pipeline,本项目采用:
language: zh pipeline: - name: WhitespaceTokenizer - name: RegexFeaturizer - name: CountVectorsFeaturizer - name: CountVectorsFeaturizer analyzer: char_wb min_ngram: 1 max_ngram: 4 - name: DIETClassifier constrain_similarities: true - name: EntitySynonymMapper - name: ResponseSelector重点在CountVectorsFeaturizer的两次调用:
- 第一次(默认):基于词(word)的 one-hot 向量,对中文需先分词(但 Rasa 1.9.5 默认 tokenizer 仅空格切分,故对中文效果差);
- 第二次(
analyzer: char_wb):基于字符(character)的 n-gram 向量,min_ngram:1, max_ngram:4意味着提取 1~4 字连续子串(如“北京天气” → “北”、“北京”、“北京天”、“北京天气”、“京天”...),这天然适配中文无空格分词特性,且对错别字鲁棒(“北就天气”仍能匹配“北”“京”“天”等字)。
而DIETClassifier(Dual Intent and Entity Transformer)是 Rasa 自研的联合模型,它同时优化意图分类和实体识别损失函数,比传统 pipeline(先 intent 后 entity)更高效。项目更新日志称“改进 supervised_embeddings,实体提取和意图识别明显提高”,指的就是此配置组合。
注意:
RegexFeaturizer用于匹配正则规则(如手机号、日期),EntitySynonymMapper将同义词映射到标准实体值(如“首都”→“北京”),二者必须放在DIETClassifier之后,否则特征无法被 classifier 利用。
3.2 实体抽取的边界处理:如何让“昨天”变成相对时间?
Rasa 默认只识别预定义实体类型(如location,time),但“昨天”这类相对时间需额外处理。本项目在actions.py中实现:
from datetime import datetime, timedelta class ActionGetWeather(Action): def name(self) -> Text: return "action_get_weather" def run(self, dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict[Text, Any]) -> List[Dict[Text, Any]]: # 获取用户输入中的 time 实体 time_entity = next((e for e in tracker.latest_message.get("entities", []) if e.get("entity") == "time"), None) if time_entity and time_entity.get("value"): # Rasa 识别出的 time 值可能是 "昨天"、"今天"、"明天" raw_time = time_entity["value"] now = datetime.now() if raw_time == "昨天": target_date = now - timedelta(days=1) elif raw_time == "明天": target_date = now + timedelta(days=1) else: # "今天" 或其他 target_date = now # 调用天气 API 时传入 target_date.date().isoformat() ...关键点:
tracker.latest_message.get("entities")是 Rasa NLU 输出的原始实体列表;time_entity["value"]是用户原话中的字符串(非标准化值),需在 action 中做业务逻辑转换;- 项目未使用
DucklingHTTPExtractor(需外挂服务),而是靠RegexFeaturizer+DIETClassifier识别基础 time 实体,再由 action 做语义归一化——这是轻量级项目的务实选择。
3.3 意图置信度阈值调优:为什么chit_chat_greeting置信度只有 0.62 仍被接受?
Rasa 默认意图阈值为0.3,但项目domain.yml中显式设置:
session_config: session_expiration_time: 60 carry_over_slots_to_new_session: true # 关键配置:降低阈值以提升中文闲聊意图召回率 policies: - name: MemoizationPolicy - name: KerasPolicy epochs: 100 constrain_similarities: true - name: MappingPolicy - name: FallbackPolicy fallback_action_name: "action_default_fallback" # 当最高置信度 < 0.6 时触发 fallback threshold: 0.6 # 且与次高意图差距 < 0.1 时才 fallback(避免抖动) ambiguity_threshold: 0.1这意味着:
- 若
chit_chat_greeting置信度 0.62,chit_chat_weather0.58,则0.62 - 0.58 = 0.04 < 0.1,触发 fallback,用户收到“我不太明白,能再说一遍吗?”; - 若
chit_chat_greeting0.75,chit_chat_weather0.20,则0.75 - 0.20 = 0.55 > 0.1,且0.75 > 0.6,直接执行 greeting 响应。
此配置平衡了准确率与召回率。中文闲聊语句模糊性强(“哈喽”“你好啊”“hi”混用),过高的threshold会导致大量 valid 意图被拒,而ambiguity_threshold防止模型在两个相近意图间反复横跳。
3.4 避坑:NLU 训练常见问题排查
现象:rasa train成功,但rasa shell中输入“北京天气”始终识别为chit_chat_greeting
原因:nlu.md中chit_chat_weather意图样例不足(少于 5 条),而chit_chat_greeting有 20+ 条,模型过拟合 greeting 类别。
解决:按 1:1 比例扩充 weather 样例,至少 15 条,并加入口语化变体(“北京今儿热不热?”“北京这会儿下雨没?”)。
现象:实体location总是识别为空,即使样例中写了[北京](location)
原因:domain.yml中未声明location实体,或声明为entities: [](空列表)。
解决:检查domain.yml,确保entities:下包含- location,且大小写与.md文件中完全一致。
现象:rasa test nlu报错ValueError: Found sample with 0 features
原因:nlu.md中某行样例为空行,或仅含空格,Rasa 解析时生成空特征向量。
解决:用sed '/^$/d' data/nlu.md > nlu_clean.md && mv nlu_clean.md data/nlu.md删除所有空行。
现象:rasa interactive中修改样本后,重新训练模型,新样本未生效
原因:rasa interactive保存的样本默认存入data/interactive/子目录,但train.bash的--data data/未递归扫描该目录。
解决:手动将data/interactive/*.md合并到data/nlu.md和data/stories.md,或修改train.bash为--data data/ data/interactive/。
现象:Windows 下rasa train卡在Starting to train NLU component CountVectorsFeaturizer无响应
原因:TensorFlow 2.2.0 在 Win10 上的线程调度 bug,与 Rasa 的 multiprocessing 冲突。
解决:在train.bash前添加环境变量set PYTHONIOENCODING=utf-8 && set PYTHONUTF8=1,或改用 WSL2 运行。
4. 对话管理实战:Stories 流程建模与 Interactive Learning 样本增强
4.1stories.md不是脚本,而是对话状态机的轨迹采样
Rasa Core 通过 stories 学习对话策略,其本质是(state, action)序列。本项目stories.md示例:
## story_01_weather_query * chit_chat_weather{"location": "北京"} - action_get_weather - utter_weather_info ## story_02_weather_with_time * chit_chat_weather{"location": "上海", "time": "明天"} - action_get_weather - utter_weather_info关键解读:
* chit_chat_weather{...}是用户消息,{...}是提取的实体槽位(slot);- action_get_weather是 bot 执行的 custom action(调用外部 API);- utter_weather_info是 domain.yml 中定义的响应模板,内容为text: "北京今天晴,气温 25°C"。
Rasa 1.9.5 的MemoizationPolicy会精确匹配完整 story 轨迹,而KerasPolicy则学习 state-action 的泛化规律。因此,story 数量不必穷举所有组合,但需覆盖:
- 主干流程(如 weather query → API call → response);
- 异常分支(如用户中途说“算了”,需
action_revert_last); - 槽位填充中断(如用户先说“查天气”,再补“北京”,需
form机制)。
4.2rasa interactive:不是演示工具,而是你的对话 debug 黑匣子
运行rasa interactive --model models/chitchat_model_20200215_143022.tar.gz后,你会进入交互式调试:
? Please type a message: 北京天气怎么样? Your input -> 北京天气怎么样? Current slot values: location: None time: None Logged Data: intent: {'name': 'chit_chat_weather', 'confidence': 0.82} entities: [{'entity': 'location', 'value': '北京', 'start': 0, 'end': 2}] Next action: action_get_weather ? Correctly predicted next action 'action_get_weather'? Yes此时你可:
- 修正意图:若识别错误,输入
n→intent→ 选择正确意图; - 修正实体:输入
n→entity→ 选择实体类型并标注起止位置; - 修正 action:输入
n→action→ 选择应执行的 action; - 保存样本:输入
s,Rasa 自动将修正后的对话轨迹存入data/interactive/。
血泪经验:
rasa interactive是唯一能实时看到tracker状态(slots、latest_event、followup_action)的途径。我曾发现action_get_weather执行后,location槽位被清空,原因是action中未显式return [SlotSet("location", None)],导致下一轮对话丢失上下文——这个 bug 在rasa shell中根本无法定位。
4.3forms机制:如何让机器人主动追问缺失信息?
当用户只说“查天气”,未提供location时,bot 应追问。本项目在domain.yml中定义:
forms: - weather_form: required_slots: - location # - time # time 可选,故注释掉并在stories.md中添加 form flow:
## story_form_weather * chit_chat_weather - weather_form - form{"name": "weather_form"} * inform{"location": "北京"} - form{"name": null} - action_get_weather - utter_weather_infoform{"name": "weather_form"}表示启动表单,form{"name": null}表示表单结束。Rasa 会自动:
- 检查
required_slots是否填满; - 若
location为空,则执行utter_ask_location(需在 domain.yml 中定义); - 用户回复后,再次校验,直到所有 required slots 非空。
4.4 避坑:Stories 训练与执行常见问题排查
现象:rasa shell中用户说“查北京天气”,bot 直接执行action_get_weather,但未调用天气 API
原因:endpoints.yml中action_endpointURL 错误,或actions服务未启动(python -m rasa_sdk --actions actions)。
解决:先运行python -m rasa_sdk --actions actions,再检查curl http://localhost:5055/webhook是否返回{"status":"ok"}。
现象:rasa interactive中 form 启动后,用户说“北京”,bot 却执行utter_ask_time而非utter_ask_location
原因:domain.yml中required_slots顺序错误,或utter_ask_*响应模板名与 slot 名不匹配(如utter_ask_location对应locationslot)。
解决:确认required_slots列表首项为location,且responses:下存在utter_ask_location。
现象:rasa train core报错Could not find a default starting policy
原因:stories.md中缺少以*开头的用户消息(即没有初始 intent),Rasa 无法确定对话起点。
解决:确保至少一个 story 以* chit_chat_greeting或* chit_chat_weather开头。
现象:form 填充后,location槽位值为None,但tracker.get_slot("location")返回字符串
原因:actions.py中SlotSet("location", value)的value为None,Rasa 会清空槽位。
解决:在action中显式return [SlotSet("location", tracker.get_slot("location"))]保持槽位值。
现象:rasa test core显示FormPolicy准确率 0%,但实际对话正常
原因:test stories未覆盖 form 场景,或stories.md中 form 相关 story 未被正确解析(如form{"name": null}缩进错误)。
解决:用rasa visualize生成graph.html,检查 form 节点是否连通。
5. 外部服务对接:图灵机器人与心知天气 API 的集成与异常熔断
5.1actions.py中的双 API 调用:为什么图灵走requests.post,而天气走requests.get?
项目actions.py实现两个 custom action:
class ActionTulingChat(Action): def name(self) -> Text: return "action_tuling_chat" def run(self, dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict[Text, Any]) -> List[Dict[Text, Any]]: user_text = tracker.latest_message.get("text", "") # 图灵 API 要求 POST JSON body payload = { "key": "your_api_key", "info": user_text, "userid": "rasa_user" } try: resp = requests.post("http://www.tuling123.com/openapi/api", json=payload, timeout=5) data = resp.json() reply = data.get("text", "我暂时没听懂") except Exception as e: reply = "网络繁忙,请稍后再试" dispatcher.utter_message(text=reply) return [] class ActionGetWeather(Action): def name(self) -> Text: return "action_get_weather" def run(self, dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict[Text, Any]) -> List[Dict[Text, Any]]: location = tracker.get_slot("location") # 心知天气 API 走 GET 查询参数 url = f"https://api.seniverse.com/v3/weather/daily.json?key=your_key&location={location}&language=zh-Hans&unit=c" try: resp = requests.get(url, timeout=5) data = resp.json() # 解析 weather data... except Exception as e: # 熔断逻辑 if "timeout" in str(e).lower(): reply = "天气服务暂时不可用,请稍后再试" else: reply = "获取天气失败" dispatcher.utter_message(text=reply) return []差异根源:
- 图灵 API 是通用聊天接口,需传入
info(用户消息)和userid(会话 ID),POST 更安全; - 心知天气是 RESTful API,
location是路径参数,GET 更符合语义且缓存友好。
5.2 熔断与降级:try-except不是摆设,而是生产级对话的底线
上述代码中timeout=5是关键:
- 防止 API 延迟拖垮整个对话流(Rasa 默认超时 60 秒,用户早已失去耐心);
except Exception捕获所有网络异常(ConnectionError, Timeout, JSONDecodeError);- 对
Timeout单独处理,返回提示语“天气服务暂时不可用”,而非笼统的“出错了”。
更进一步,可引入tenacity库实现指数退避重试:
from tenacity import retry, stop_after_attempt, wait_exponential @retry(stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=1, max=10)) def call_weather_api(location): url = f"https://api.seniverse.com/...&location={location}" resp = requests.get(url, timeout=5) resp.raise_for_status() return resp.json()但本项目为轻量级,try-except已足够——毕竟毕设答辩时,评委不会真去压测你的天气 API。
5.3 API Key 安全:为什么actions.py里明文写your_api_key是故意的?
项目源码中actions.py的 API Key 是占位符your_api_key,这是教学设计的刻意留白。真实部署时,绝不能硬编码密钥,而应:
方式一(推荐):使用环境变量
import os weather_key = os.getenv("WEATHER_API_KEY", "default_key")启动时
export WEATHER_API_KEY=xxx && python -m rasa_sdk --actions actions方式二:配置文件分离
新建secrets.yml(gitignore 掉):weather_api_key: "xxx" tuling_api_key: "yyy"在
actions.py中:import yaml with open("secrets.yml") as f: secrets = yaml.safe_load(f)
硬编码密钥一旦上传 GitHub,等于公开泄露 API 权限——这是课程设计中最易被忽视的安全红线。
5.4 避坑:API 对接常见问题排查
现象:action_tuling_chat执行后,bot 无响应,日志显示Connection refused
原因:图灵 API 域名www.tuling123.com已失效(2023 年后该服务停止),项目文档未更新。
解决:替换为免费替代方案,如https://open.douyin.com/api/chat(需申请抖音开放平台账号),或本地部署chatglm模型。
现象:action_get_weather返回{"status":"error","status_code":403}
原因:心知天气 API Key 过期,或location参数含空格/特殊字符未 urlencode。
解决:urllib.parse.quote(location)编码 location,如北京→%E5%8C%97%E4%BA%AC。
现象:rasa shell中调用 action 后,bot 重复发送两条相同消息
原因:dispatcher.utter_message()被调用两次(如在try和except中都调用了)。
解决:确保utter_message只在最终逻辑分支中调用一次。
现象:action_get_weather中tracker.get_slot("location")返回None,但用户已说“北京”
原因:nlu.md中未标注[北京](location),或domain.yml中slots:未定义location为type: text。
解决:检查domain.yml的slots:部分,确保location:下有type: text和auto_fill: true。
现象:rasa run启动后,curl -X POST http://localhost:5005/webhooks/rest/webhook返回 404
原因:Rasa 1.9.5 的 REST webhook endpoint 是/webhooks/rest/webhook,但endpoints.yml中webhook配置错误。
解决:确认endpoints.yml中:
rest: # 无需配置,Rasa 内置而非webhook:字段。
6. 毕设答辩与课程设计交付:从模型验证到可演示系统的最后一公里打磨
6.1 模型效果量化验证:不只是rasa test,还要看 confusion matrix
rasa test nlu仅输出宏观指标(accuracy, f1),但答辩时评委可能追问:“chit_chat_weather和chit_chat_greeting为什么容易混淆?” 此时需生成混淆矩阵:
rasa test nlu \ --nlu data/nlu.md \ --model models/chitchat_model_20200215_143022.tar.gz \ --out results/nlu \ --successes \ --no-errors生成results/nlu/intent_report.json,其中关键字段:
{ "chit_chat_weather": { "precision": 0.92, "recall": 0.87, "f1-score": 0.89, "support": 120, "confused_with": ["chit_chat_greeting": 8, "chit_chat_help": 3] } }confused_with显示:在 120 条 weather 样例中,模型错误预测为 greeting 8 次。此时可导出results/nlu/errors.json,人工分析这 8 条样例——往往发现它们含 greeting 词汇(如“你好,北京天气怎么样?”),解决方案是:
- 在
nlu.md中为 weather 意图增加带 greeting 前缀的样例; - 或在
config.yml中启用ConstrainSimilarities(已启用),抑制相似意图的 logits。
从那以后我每次提交毕设模型前,都强制用
rasa test nlu --out results/生成报告,并把errors.json中 top3 错误样例截图放进答辩 PPT —— 这比说“准确率很高”有力十倍。
6.2 可演示系统包装:server.py+index.html构建免安装前端
项目未提供前端,但毕设需可演示。最简方案:在项目根目录新建index.html:
<!DOCTYPE html> <p> <a href="https://download.csdn.net/download/cs1395293598/89385877" style="color:#ec7500;font-size:14px;"> 本文还有配套的精品资源,点击获取 </a> <img alt="menu-r.4af5f7ec.gif" src="https://csdnimg.cn/release/wenkucmsfe/public/img/menu-r.4af5f7ec.gif" style="width:16px;margin-left:4px;vertical-align:text-bottom;cursor:text;"> </p>