rasa nlu 传递信息及 REST API 替代 rasa nlu
1.4 rasa nlu 传递信息及 REST API 替代 rasa nlu
1.4.1 获取 rasa nlu 传给 rasa core 的响应
开始想在 rasa 内进行拦截,经过测试,难以实现
所以采用接口方式获取
启动 rasa nlu 服务
rasa run --enable-api
请求:

响应:
{
"text": "今天天气怎么样",
"intent": {
"name": "ask_weather",
"confidence": 0.9999315738677979
},
"entities": [],
"text_tokens": [
[
0,
4
],
[
4,
7
]
],
"intent_ranking": [
{
"name": "ask_weather",
"confidence": 0.9999315738677979
},
{
"name": "goodbye",
"confidence": 0.0000572034805372823
},
{
"name": "greet",
"confidence": 0.0000109441825770773
},
{
"name": "inform",
"confidence": 2.0421576607532188e-7
}
]
}
那么我的 node 服务只需要传递这种类型的响应即可
使用命令启动 rasa core,并且打印日志
rasa run --enable-api --cors "*" --port 5006 --debug
经过实测,需要将 text 改为 message
可以以下面这种格式进行传递
{
"sender": "user123",
"message": "今天天气怎么样",
"intent": "ask_weather",
"entities": []
}
会收到以下响应
[
{
"recipient_id": "user123",
"text": "你好!我可以帮你查询天气信息。你想查询哪一天的天气?"
}
]
然而表面上是可行的,实际上依然调用了 rasa nlu,而如何实现只使用 rasa core 呢,请看下文分解
1.4.2 表单初步实现
1.4.2.1 简易版
首先来看一下结果
问:上海明天天气怎么样
再看看流程

首先给 rules.yml 配置
version: "3.1"
rules:
- rule: 激活 form
steps:
- intent: weather
- action: weather_form
- active_loop: weather_form
- rule: 提交 form
condition:
# Condition that from is active.
- active_loop: weather_form
steps:
- action: weather_form
- active_loop: null
- slot_was_set:
- requested_slot: null
# The action we want to run when the form is submitted.
- action: action_weather_form_submit
然后配置 nlu.yml
version: "3.1"
nlu:
- intent: weather
examples: |
- 我想查一下[北京](address)的天气
- 帮我看看[上海](address)[明天](date)的天气怎么样
- 我想知道[广州](address)[后天](date)的天气情况
- intent: affirm
examples: |
- 是的
- 对呀
- 没错
- intent: deny
examples: |
- 不是
- 不对
- 不用了
- intent: goodbye
examples: |
- 拜拜
- 再见
- 下次再聊
再是 config.yml
recipe: default.v1
assistant_id: 20241120-170106-khaki-margarine
language: zh # 改为中文
pipeline:
- name: JiebaTokenizer # 使用支持中文的 Tokenizer
- name: CountVectorsFeaturizer
analyzer: "word" # 基于分词结果生成特征
min_ngram: 1
max_ngram: 2
- name: DIETClassifier
epochs: 100
- name: EntitySynonymMapper
# 配置对话管理
policies:
- name: RulePolicy
domain.yml 也需要配置,这是关键,配置了两个实体,也会在外部动作服务器中用到
目前配置比较简单,其实只用到 weather 这个意图
version: "3.1"
intents:
- weather
- affirm
- deny
- goodbye
entities:
- address
- date
slots:
# address 插槽,用于存储用户提供的地点
address:
type: text
influence_conversation: false
mappings:
- type: from_entity
entity: address
not_intent: ["deny", "goodbye"]
# date 插槽,用于存储用户提供的日期/时间
date:
type: text
influence_conversation: false
mappings:
- type: from_entity
entity: date
not_intent: ["deny", "goodbye"]
forms:
weather_form:
required_slots:
- address
- date
actions:
- weather_form
- action_weather_form_submit
session_config:
session_expiration_time: 60
carry_over_slots_to_new_session: true
在 action_service.js 相比前文主要加了
else if (actionName === 'action_weather_form_submit') {
const requestedAddress = tracker.slots.address || "未知地点";
const requestedDatetime = tracker.slots.date || "未知时间";
const fallbackMessage = `你想查询${requestedDatetime}${requestedAddress}的天气。那天是多云,温度22°C。`;
console.log('Fallback Message:', fallbackMessage);
res.json({
events: [],
responses: [{ text: fallbackMessage }]
});
}
1.4.2.2 加上实体识别版
再通过接口获取 rasa nlu 给 rasa core 传递的信息,这个例子加上了
{
"text": "明天北京天气怎么样",
"intent": {
"name": "weather",
"confidence": 0.9994596838951111
},
"entities": [
{
"entity": "address",
"start": 2,
"end": 4,
"confidence_entity": 0.9538565278053284,
"value": "北京",
"extractor": "DIETClassifier",
"processors": [
"EntitySynonymMapper"
]
}
],
"text_tokens": [
[
0,
2
],
[
2,
4
],
[
4,
6
],
[
6,
9
]
],
"intent_ranking": [
{
"name": "weather",
"confidence": 0.9994596838951111
},
{
"name": "goodbye",
"confidence": 0.0003240504302084446
},
{
"name": "deny",
"confidence": 0.00021139439195394516
},
{
"name": "affirm",
"confidence": 0.000004957571491104318
}
]
}
可以看到使用 nlu 识别的并不是很好,那么现在是时候使用外部接口处理 nlu 了
整个流程是这样的
-
使用 Apipost 发送请求给 Rasa
需要发送一个 POST 请求到 Rasa 的
/model/parse
端点{ "text": "Hello,Hello", "session_id": "user_12345" }
Session ID:这是为了区分不同的用户会话。每个会话可以有独立的上下文和对话状态
我们可以根据需要生成不同的 session_id,比如用用户的 ID 或者生成一个随机字符串
咱们先来看一下接口打通后的样子:
-
配置 NLU 模块调用外部服务
这里需要注意,虽然在 endpoints.yml 中给的是
nlu: url: "http://127.0.0.1:5002/toRasa"
但是在外部服务中接口需要配置
toRasa/model/parse
我在 node 中就需要这样配置
const toRasaModelRouter = require('./routes/toModelRasa'); app.use('/toRasa/model/parse', toRasaModelRouter);
toModelRasa.js 代码如下,目前是写死测试的
const express = require('express'); const axios = require('axios'); const router = express.Router(); require('dotenv').config(); // 路由处理器 router.post('/', async (req, res) => { try { const { text } = req.body; if (!text) { return res.status(400).json({ error: 'Missing "text" in request body.' }); } // 处理意图识别结果 let intent = 'weather'; // 硬编码为 "weather" const intentConfidence = 1.0; // 处理实体识别结果,硬编码两个实体 const entities = [ { entity: 'address', value: '北京', start: text.indexOf('北京'), end: text.indexOf('北京') + '北京'.length }, { entity: 'date', value: '明天', start: text.indexOf('明天'), end: text.indexOf('明天') + '明天'.length } ]; // 构建 Rasa 所需的 JSON 格式 const rasaPayload = { text: text, intent: { name: intent, confidence: intentConfidence }, entities: entities }; console.log("Constructed rasaPayload:", rasaPayload); // 将 Rasa 的响应返回给客户端 res.json(rasaPayload); } catch (error) { console.error('Error in /toRasa:', error.message); res.status(500).json({ error: 'Internal Server Error' }); } }); module.exports = router;
-
Rasa Core 处理
rasa nlu 因为不处理了,所以 config.yml 进行了修改
pipeline: - name: "WhitespaceTokenizer" - name: "RegexFeaturizer" - name: "CountVectorsFeaturizer" - name: "LexicalSyntacticFeaturizer" - name: "ResponseSelector" epochs: 50 - name: "FallbackClassifier" threshold: 0.3 ambiguity_threshold: 0.1
rasa 得到 nlu 的处理结果后,会将这些信息传递给 Rasa Core
在当前例子中就是 RulePolicy 进行处理
-
通过 Apipost 发送请求
使用命令启动 rasa 服务
rasa run -m models --enable-api --cors "*" --debug

成了!全链路打通了,nlu 是 node 处理的,rasa core 主要起到表单的作用,后文也主要涉及多轮对话
END
本文的主要目的是在项目中使用 Node 处理作为 nlu 使用,使用 rasa 自带的 nlu 毕竟控制力会有所减弱,笔者经过尝试终于打通了 nlu 的处理,通过接口传入 rasa,rasa 调用外部 nlu 处理,rasa 处理完成后返回,形成了闭环
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?