使用场景
例如,用 Rasa 实现一个自动聊天机器人,要同时实现多端:
- 网页端
- 微信小程序端
- Android / iOS 原生 App 端
- Windows 端
每一端的回复内容会有些许差异,如:
utter_greet
- 网页端:欢迎使用大象计算器,地球上最不强大的计算器
- 微信小程序端:欢迎使用大象计算器微信小程序,您也可以关注大象工具公众号接收各种骚扰信息
突然想到 Rasa channel 是否可以实现这个功能,于是查了一下官方文档,看起来很挺合适。
不同 channel 返回不同 response
参考:
https://rasa.com/docs/rasa/connectors/custom-connectors
domain.yml 中这样配置:
responses:
utter_greet:
- text: Hi! Welcome to my site.
- text: Hi! Welcome to my Wechat mini app.
channel: wechat
第二条是针对 wechat 这个 channel 的特定返回信息。
Custom Connectors 实现
自定义 Channel 是通过 Custom Connectors 实现的,需实现 name 和 blueprint (蓝图) 方法:
from rasa.core.channels.channel import InputChannel
class Wechat(InputChannel):
def name() -> Text:
"""Name of your custom channel."""
return "wechat"
完整代码参考官方文档:
https://rasa.com/docs/rasa/connectors/custom-connectors
即可。
注意,如果需要使用 metadata, 官方的实现有问题,需要自己实现从 request 中解析 metadata 的逻辑。
sanic blueprint 的用途
https://sanic.dev/en/guide/best-practices/blueprints.html#overview
可以理解为方便添加子目录路由解析。
Blueprints are objects that can be used for sub-routing within an application. Instead of adding routes to the application instance, blueprints define similar methods for adding routes, which are then registered with the application in a flexible and pluggable manner.
例如:
# ./my_blueprint.py
from sanic.response import json
from sanic import Blueprint
bp = Blueprint("my_blueprint")
@bp.route("/")
async def bp_root(request):
return json({"my": "blueprint"})
获取每个端独有的信息
metadata = self.get_metadata(request) # method to get metadata
credentials.yml
假如自定义渠道的代码定义在代码文件 addons/wechat_channel.py。
则对应的配置为:
addons.wechat_channel.Wechat:
默认的配置为:
rest:
# # you don't need to provide anything here - this channel doesn't
# # require any credentials
#facebook:
# verify: "<verify>"
# secret: "<your secret>"
# page-access-token: "<your page access token>"
#slack:
# slack_token: "<your slack token>"
# slack_channel: "<the slack channel>"
# slack_signing_secret: "<your slack signing secret>"
#socketio:
# user_message_evt: <event name for user message>
# bot_message_evt: <event name for bot messages>
# session_persistence: <true/false>
socketio:
user_message_evt: user_uttered
bot_message_evt: bot_uttered
session_persistence: false
客户端发送的数据格式
curl --request POST \
--url http://localhost:5005/webhooks/wechat/webhook \
--header 'Content-Type: application/json' \
--data '{
"sender": "test_user",
"message": "Hi there!",
"metadata": {}
}'
TypeError: name() takes 0 positional arguments but 1 was given
运行
rasa run --enable-api --cors '*'
报错:
TypeError: name() takes 0 positional arguments but 1 was given
def name() -> Text: # 原代码
def name(self) -> Text: # 正确的代码
GraphComponentException
rasa run --enable-api --cors '*'
rasa.engine.exceptions.GraphComponentException: Error running graph component for node run_RegexMessageHandler.
rasa run --enable-api --cors '*' --credentials credentials.yml
不加 credentials 参数也是一样的效果。
参数 message 换成 text,因为代码中用的是 text,需要前后端统一。
> curl --request POST \
--url http://localhost:5005/webhooks/windows/webhook \
--header 'Content-Type: application/json' \
--data '{
"sender": "test_user",
"text": "Hi there!",
"metadata": {}
}'
测试
- http://localhost:5005/webhooks/wechat/webhook
- http://localhost:5005/webhooks/rest/webhook
cors 参数
- 对于新的自定义 channel ,启动 rasa 时,不加 cors 参数,curl 也可以正常访问。
- 但是对于 rest channel,不加 cors 参数,curl 也可以正常访问
坑爹的官方文档
测试了一下,新 channel 和 rest channel 返回的消息是一样的。。。。
原来,需要自定义一个 OutputChannel 替换掉官方文档中的 CollectingOutputChannel
class WechatOutput(CollectingOutputChannel):
@classmethod
def name(cls) -> Text:
return "wechat"
然后就可以了。
眼睛睁不开了,睡觉。
查看合集
微信关注我哦 👍
我是来自山东烟台的一名开发者,有感兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊, 查看更多联系方式