Rasa 多格式 NLU 训练数据示例与转换指南:深入解析 data/examples 中的 Rasa、LUIS、WIT 与 Dialogflow 数据
【免费下载链接】rasa💬 Open source machine learning framework to automate text- and voice-based conversations: NLU, dialogue management, connect to Slack, Facebook, and more - Create chatbots and voice assistants项目地址: https://gitcode.com/GitHub_Trending/ra/rasa
data/README.md指出,仓库的data/examples目录提供了一组餐厅领域(restaurant domain)简单机器人的训练数据示例,覆盖 Rasa 原生格式、LUIS 格式、WIT 格式与 Dialogflow 格式,其设计意图是:当您从这些 NLU 服务导出应用数据时,导出的文件应当与这里的样例保持一致,从而可以被 Rasa 无缝识别、加载并用于训练。本文将围绕这些示例文件展开,结合仓库源码(Reader 实现、格式探测逻辑、CLI 转换命令与测试用例)逐格式讲解数据结构、实体标注规则与相互转换方法,帮助您快速上手 Rasa 的多格式训练数据生态。
一、示例数据目录总览
data/examples目录下按服务商划分了四个子目录:
| 子目录 | 对应 NLU 服务 | 典型文件 | 覆盖领域 |
|---|---|---|---|
data/examples/rasa | Rasa 原生格式 | demo-rasa.yml、demo-rasa.json、demo-rasa-multi-intent.yml、demo-rasa-responses.yml | 餐厅搜索 |
data/examples/luis | LUIS.ai | demo-restaurants_v7.json | 餐厅搜索 |
data/examples/wit | WIT.ai | demo-flights.json | 航班预订 |
data/examples/dialogflow | Dialogflow(API.AI) | agent.json、package.json、intents/、entities/ | 餐厅搜索(英/西双语) |
这些文件都围绕同一个"餐厅领域"示例(WIT 示例为航班领域),共享相近的意图与实体集合:意图包括greet、affirm、goodbye、inform/restaurant_search及检索意图chitchat/ask_name、chitchat/ask_weather;实体包括cuisine(菜系)与location(位置)。
从源码看,这些格式之所以能被统一加载,得益于rasa/shared/nlu/training_data/loading.py中的格式探测与 Reader 工厂机制:load_data会先调用guess_format判断文件格式,再由_reader_factory分派给对应的LuisReader、WitReader、RasaReader、RasaYAMLReader或DialogflowReader(见 loading.py)。
二、Rasa 原生格式:YAML 与 JSON 两种风格
1. YAML 格式(推荐)
data/examples/rasa/demo-rasa.yml是 Rasa 3.x 推荐的 YAML 训练数据示例,文件顶部声明version: "3.1",主体结构如下:
version: "3.1" nlu: - intent: affirm examples: | - yes - yep - yeah - indeed - that's right - ok - great - right, thank you - correct - great choice - sounds really good - intent: restaurant_search examples: | - i'm looking for a place to eat - I want to grab lunch - I am searching for a dinner spot - i'm looking for a place in the north of town - show me chinese restaurants - show me [chines]{"entity": "cuisine", "value": "chinese"} restaurants in the north - show me a mexican place in the centre - i am looking for an indian spot called olaolaolaolaolaola - search for restaurants - anywhere in the west - anywhere near 18328 - I am looking for asian fusion food - I am looking a restaurant in 29432 - I am looking for mexican indian fusion - central indian restaurant该示例集中演示了 Rasa YAML 训练数据中的三类重要标注语法:
- 实体标注(短格式):
实体文本,例如north、chinese; - 实体标注(JSON 扩展格式):
[chines]{"entity": "cuisine", "value": "chinese"},用于把原词chines映射到规范值chinese,与同义词表配合实现实体值归一化; - 多实体同句标注:
central indian restaurant表示一句话内同时出现两个不同实体。
除此之外,示例还演示了synonym(同义词)与regex(正则特征)两种辅助数据:
- synonym: chinese examples: | - chines - Chines - Chinese - synonym: vegetarian examples: | - vegg - veggie - regex: greet examples: | - hey[^\s]* - regex: zipcode examples: | - [0-9]{5}同义词chinese的三个变体chines、Chines、Chinese在训练时都会被归一到规范值chinese;正则特征则用于在特征化阶段向分类器提供模式信号(如[0-9]{5}匹配 5 位邮政编码)。
文件末尾还包含responses区块,演示了检索意图(retrieval intent)的响应定义:
responses: utter_chitchat/ask_name: - image: "https://i.imgur.com/zTvA58i.jpeg" text: Hello, my name is Retrieval Bot. - text: I am called Retrieval Bot! utter_chitchat/ask_weather: - text: Oh, it does look sunny right now in Berlin. image: "https://i.imgur.com/vwv7aHN.png" - text: I am not sure of the whole week but I can see the sun is out today.注意响应键utter_chitchat/ask_name与意图chitchat/ask_name之间的对应关系——这正是 Rasa 检索意图(retrieval intent)"意图 + 响应" 的约定:同一示例既作为意图训练数据,也作为响应选择器的数据源。
2. JSON 格式(旧版)
data/examples/rasa/demo-rasa.json是等价的旧版 Rasa NLU JSON 格式,顶层键为rasa_nlu_data,内部包含regex_features、entity_synonyms与common_examples三个区块:
{ "rasa_nlu_data": { "regex_features": [ { "name": "zipcode", "pattern": "[0-9]{5}" }, { "name": "greet", "pattern": "hey[^\\s]*" } ], "entity_synonyms": [ { "value": "chinese", "synonyms": ["Chinese", "Chines", "chines"] }, { "value": "vegetarian", "synonyms": ["veggie", "vegg"] } ], "common_examples": [ { "text": "i'm looking for a place in the north of town", "intent": "restaurant_search", "entities": [ { "start": 31, "end": 36, "value": "north", "entity": "location" } ] } ] } }与 YAML 的text标注不同,JSON 格式使用字符偏移量start/end定位实体(注意end为开区间,即结束索引需再 +1 才是实际字符位置,与LuisReader中e["endPos"] + 1的处理一致,见 luis.py)。这两种格式在语义上完全等价,仓库测试test_demo_data同时以demo-rasa.json与demo-rasa.yml为输入并断言二者解析出的意图、实体、同义词、正则特征完全一致(见 test_training_data.py)。
3. 多意图示例与独立响应文件
data/examples/rasa/demo-rasa-multi-intent.yml展示了多意图(multi-intent)的写法:意图名用+连接,例如chitchat+ask_name、chitchat+ask_weather,表示"闲聊 + 具体子意图"的组合形式,供支持多意图预测的分类器(如 DIET)使用(tests/nlu/classifiers/test_diet_classifier.py即以该文件为训练数据)。
data/examples/rasa/demo-rasa-responses.yml则把响应独立成文件,只包含responses区块:
responses: utter_chitchat/ask_weather: - text: It's sunny where I live utter_chitchat/ask_name: - text: I am Mr. Bot测试test_demo_data验证了demo-rasa.yml/demo-rasa.json与demo-rasa-responses.yml可以同时加载并合并:合并后共 46 条训练示例、4 条响应示例、2 组响应键(见 test_training_data.py)。这印证了 Rasa 允许把 NLU 数据与响应数据拆分为多个文件,训练时统一合并加载。
三、LUIS 格式示例:demo-restaurants_v7.json
data/examples/luis/demo-restaurants_v7.json是 LUIS.ai 导出的 Schema v7 格式示例。其顶层结构包括:
- 元信息:
luis_schema_version: "7.0.0"、versionId: "0.1"、name: "demo-restaurants"、culture: "en-us"; - 正则实体:
regex_entities数组(LUIS 新版将正则表达式放在此处,旧版regex_features字段也已兼容处理); - 意图:
intents数组,包含affirm、goodbye、greet、inform与None(None 为 LUIS 的空意图); - 实体:
entities数组,定义cuisine与location(其中location带roles: ["to", "from"]); - 训练语句:
utterances数组。
LUIS 的实体标注采用startPos/endPos偏移加entity、role字段,例如:
{ "text": "i'm looking for a place in the north of town", "intent": "inform", "entities": [ { "entity": "location", "role": "to", "startPos": 31, "endPos": 35, "children": [] } ] }LuisReader在解析时会把endPos转换为 Rasa 的开区间end(即endPos + 1),并把role字段映射为实体的角色属性(luis.py)。同时它兼容读取新旧两种正则字段:既遍历regex_features(仅取activated为 true 的项),也遍历regex_entities中的regexPattern(luis.py)。此外,源码对 LUIS Schema 版本做了防御性检查:若主版本号大于 7,会发出警告提示训练可能不正确(luis.py)。
测试test_luis_data验证了解析结果:28 条意图示例、8 条实体示例、1 个正则特征,意图集合为{affirm, goodbye, greet, inform},实体集合为{location, cuisine}(见 test_training_data.py)。
四、WIT 格式示例:demo-flights.json
data/examples/wit/demo-flights.json是 WIT.ai 的导出示例,主题为航班预订(flight_booking意图)。WIT 的 JSON 结构与 LUIS 不同,顶层直接是utterances数组,每条语句包含text、entities、traits和可选的intent字段。
WIT 最显著的特点是实体名内嵌角色,用冒号分隔:location:from、location:to,以及内置系统实体wit$datetime:datetime:
{ "text": "i'm looking for a flight from london to amsterdam next monday", "entities": [ { "entity": "location:from", "start": 30, "end": 36, "body": "london", "entities": [] }, { "entity": "wit$datetime:datetime", "start": 50, "end": 61, "body": "next monday", "entities": [] }, { "entity": "location:to", "start": 40, "end": 49, "body": "amsterdam", "entities": [] } ], "traits": [], "intent": "flight_booking" }WitReader在解析时会将entity字段按最后一个冒号拆分为name与role,并把body作为实体值(wit.py)。另一个值得注意的细节是:没有intent字段的 WIT 语句会被自动标记为USER_INTENT_OUT_OF_SCOPE(即 out_of_scope)意图(wit.py),因此示例中的无意图语句在解析后归属out_of_scope。
测试test_wit_data断言解析后的实体角色为from/to/datetime、实体集合为{location, wit$datetime},意图集合为{flight_booking, out_of_scope}(见 test_training_data.py)。
五、Dialogflow 格式示例:目录结构与多语言实体
data/examples/dialogflow/是一个完整的 Dialogflow 导出包目录(README 中写作examples/api,仓库实际路径为data/examples/dialogflow),结构与 Dialogflow 控制台导出 ZIP 解压后的布局一致:
dialogflow/ ├── agent.json # Agent 级配置(语言、时区、ML 置信度等) ├── package.json # {"version": "1.0.0"} ├── entities/ # 实体定义(含多语言 entries) │ ├── cuisine.json │ ├── cuisine_entries_en.json │ ├── cuisine_entries_es.json │ ├── location.json │ ├── location_entries_en.json │ ├── location_entries_es.json │ └── flightNumber.json / flightNumber_entries_en.json └── intents/ # 意图定义(含多语言 usersays) ├── affirm.json ├── affirm_usersays_en.json / affirm_usersays_es.json ├── goodbye.json / goodbye_usersays_en.json / goodbye_usersays_es.json ├── hi.json / hi_usersays_en.json / hi_usersays_es.json └── inform.json / inform_usersays_en.json / inform_usersays_es.json1. Agent 级文件
agent.json记录 Agent 全局配置:语言"en"、supportedLanguages: ["es"]、默认时区Asia/Hong_Kong、ML 置信度阈值mlMinConfidence: 0.3、webhook 未启用等。package.json仅含{"version": "1.0.0"}。
2. 意图定义与示例文件
每个意图由一对文件组成:<intent>.json(意图定义,含响应文本与参数)与<intent>_usersays_<lang>.json(训练语句)。例如intents/hi_usersays_en.json中的每条示例包含data文本块数组:
[ { "id": "462fb0f5-d97a-4a95-96ab-91f49f289676", "data": [ { "text": "hey", "userDefined": false } ], "isTemplate": false, "count": 0, "lang": "en", "updated": 0 } ]DialogflowReader._read_examples的解析逻辑与目录结构一一对应:对于意图文件,它会按_usersays_<语言>.json后缀寻找配套的训练语句文件;对于实体文件,则按_entries_<语言>.json后缀寻找实体条目(dialogflow.py)。在_join_text_chunks中,多个文本块被拼接为完整语句,同时若某块带meta或alias字段则提取为实体(@sys.ignore类型会被忽略),实体起始位置基于已拼接文本的长度累加计算(dialogflow.py)。
意图定义文件intents/inform.json还展示了 Dialogflow 的参数(slot)定义方式,如location(dataType: "@location",isList: true)与cuisine(dataType: "@cuisine")。
3. 实体定义与多语言同义词
实体定义文件entities/cuisine.json仅声明元信息(isEnum、isRegexp等),真正的同义词表位于带语言后缀的 entries 文件中,例如entities/cuisine_entries_en.json:
[ { "value": "mexican", "synonyms": ["mexican", "mexico"] }, { "value": "chinese", "synonyms": ["chinese", "china"] }, { "value": "indian", "synonyms": ["indian", "india"] } ]DialogflowReader._read_entities会根据实体的isRegexp标志决定生成正则特征还是查找表(lookup table):正则实体 → 把 synonyms 当作正则 pattern 生成regex_features;普通实体 → 把 synonyms 中不含@的元素收集为lookup_tables(dialogflow.py)。test_dialogflow_data断言从该目录可解析出 24 条意图示例、2 个查找表、1 个正则特征,且同义词映射为mexico→mexican、china→chinese、india→indian(见 test_training_data.py)。
六、格式探测与自动识别机制
多种格式共存时,Rasa 依赖rasa/shared/nlu/training_data/loading.py的启发式规则自动判别格式,无需手动指定。核心逻辑是_json_format_heuristics字典(loading.py):
| 格式 | 判定规则(JSON 字段 / 文件名) |
|---|---|
| WIT | 含utterances且不含luis_schema_version |
| LUIS | 含luis_schema_version |
| Rasa JSON | 含rasa_nlu_data |
| Dialogflow Agent | 含supportedLanguages |
| Dialogflow Package | 含version且 JSON 对象仅 1 个键 |
| Dialogflow Intent | 含responses |
| Dialogflow 实体 | 含isEnum |
| Dialogflow 意图示例 | 文件名含_usersays_ |
| Dialogflow 实体条目 | 文件名含_entries_ |
对于目录输入,load_data会递归列出目录下所有文件逐一加载,再通过TrainingData.merge合并为一份完整数据(loading.py)。这就是为什么data/examples/dialogflow/整个目录可以直接作为--data参数传入训练或转换命令。
七、命令行转换:rasa data convert nlu
data/README.md的核心价值之一在于这些示例可直接用于验证格式转换流程。Rasa 提供了rasa data convert nlu子命令(见 cli/data.py),其参数定义在 cli/arguments/data.py:
-f, --format:输出格式,choices=["json", "yaml"],默认yaml;--data:必填,输入的文件或目录(可指向本文介绍的任何格式示例);--out:输出位置,默认converted_data;对json输出指定文件路径,对yaml输出指定已存在的目录;-l, --language:数据语言,默认en(Dialogflow 多语言数据必须正确指定,如en或es)。
实际执行(将 Dialogflow 英文导出转换为 Rasa YAML):
rasa data convert nlu \ --data data/examples/dialogflow \ --out converted_data \ --format yaml \ --language en将 LUIS 导出转换为 Rasa JSON:
rasa data convert nlu \ --data data/examples/luis/demo-restaurants_v7.json \ --out converted_luis.json \ --format json转换的底层实现在rasa/nlu/convert.py:convert_training_data调用load_data完成加载(此时已自动完成格式识别与 Reader 分派),再根据输出格式调用td.nlu_as_json(indent=2)生成 JSON,或调用RasaYAMLWriter().dumps(td)生成 YAML,最后写入目标文件(convert.py)。
仓库测试test_training_data_conversion用参数化方式验证了 5 组"源数据 → 金标准"转换对照:WIT 航班数据、LUIS 餐厅数据、Dialogflow 英/西双语数据、Rasa YAML 数据,分别与data/test/wit_converted_to_rasa.json、data/test/luis_converted_to_rasa.json、data/test/dialogflow_en_converted_to_rasa.json、data/test/dialogflow_es_converted_to_rasa.json、data/test/md_converted_to_json.json逐条比对实体与意图示例(见 test_training_data.py)。这也说明data/test/目录中的*_converted_to_rasa.json文件正是官方转换的"标准答案",可作为自行转换后的对照基准。
八、数据校验与使用建议
1. 校验训练数据
转换或编写训练数据后,可用rasa data validate命令检查数据与 domain、config 的一致性(命令注册见 cli/data.py):
rasa data validate --data data/examples/rasa/demo-rasa.yml该命令会构建TrainingDataImporter加载配置、domain 与训练数据并执行校验,支持--fail-on-warnings(将警告升级为失败)等参数(cli/data.py)。
2. 直接用于训练
上述示例文件本身就是合法的训练数据,可直接配合 config 与 domain 使用。例如demo-rasa.yml同时被 DIET 分类器测试(tests/nlu/classifiers/test_diet_classifier.py使用demo-rasa-multi-intent.yml)、MITIE 意图分类器测试(tests/nlu/classifiers/test_mitie_intent_classifier.py使用demo-rasa.yml)等用作训练输入。若希望分出一部分数据做测试集,可使用rasa data split nlu:
rasa data split nlu \ --nlu data/examples/rasa/demo-rasa.yml \ --training-fraction 0.8 \ --random-seed 42 \ --out train_test_split该命令按--training-fraction(默认 0.8)拆分并输出training_data.yml与test_data.yml(拆分逻辑见 cli/data.py,参数见 cli/arguments/data.py)。
3. 实践建议
- 新项目优先使用 YAML 格式:
demo-rasa.yml是 Rasa 3.x 的主力格式;旧版 JSON(demo-rasa.json)已标记为 deprecated(测试test_data_convert_nlu_json断言转换输出 JSON 时会提示 "NLU data in Rasa JSON format is deprecated",见 tests/cli/test_rasa_data.py)。 - 迁移存量数据时善用转换命令:若您已有 LUIS / WIT / Dialogflow 平台的导出数据,参照本文第二节到第五节讲解的结构确认导出格式,再使用
rasa data convert nlu一次性转为 Rasa 格式,并以data/test/下的金标准文件为参照核验转换结果。 - Dialogflow 多语言数据注意
--language参数:DialogflowReader.read直接依赖kwargs["language"]拼接 usersays/entries 文件名(dialogflow.py),语言参数不匹配将导致找不到配套示例文件。
九、小结
data/examples是理解 Rasa 多格式 NLU 数据生态的最佳入口:demo-rasa.yml展示了意图、实体、同义词、正则与检索意图响应的完整 YAML 写法;demo-rasa.json对应等价的偏移量 JSON 写法;demo-restaurants_v7.json演示了 LUIS Schema v7 的意图/角色/正则实体结构;demo-flights.json演示了 WIT 的"实体名:角色"命名与系统实体;dialogflow/目录则完整复刻了 Dialogflow 导出包的意图-示例、实体-条目双文件与多语言组织方式。配合rasa data convert nlu、rasa data validate、rasa data split nlu三个命令以及rasa/shared/nlu/training_data/loading.py的格式探测机制,您可以快速实现跨平台 NLU 数据的迁移、校验与复用,让 Rasa 无缝接续其他 NLU 服务沉淀的训练语料。
【免费下载链接】rasa💬 Open source machine learning framework to automate text- and voice-based conversations: NLU, dialogue management, connect to Slack, Facebook, and more - Create chatbots and voice assistants项目地址: https://gitcode.com/GitHub_Trending/ra/rasa
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考