对话机器人 Rasa(三十三): 测试 socket.io channel 异步返回多条消息

更新日期: 2024-02-15 阅读次数: 382 字数: 622 分类: AI

测试场景

向 rasa server 发送一条消息,除非一连串的耗时操作,每个操作执行前都返回一条消息。

即,客户端发送一条聊天消息,rasa 机器人间隔返回多条消息回复。

同时作为统一消息格式的测试工具。

客户端模拟

本来打算用 python socket.io client 实现,但是考虑到目前大部分使用场景都是基于浏览器。 所以还是基于 html js 来实现一个客户端更合适。

也顺便把 socket.io 版本的 chatui.io 聊天界面实现。

测试逻辑

  1. 建立 socket.io 连接
  2. 建立连接后,发送消息,触发指定的 rasa custom action
  3. rasa custom action 中,返回消息 utter_a, sleep 3 秒后,返回消息 utter_b

custom action

错误的做法:

class ActionHelloWorld(Action):
    def name(self) -> Text:
        return "action_hello_world"

    async def run(
        self,
        dispatcher: CollectingDispatcher,
        tracker: Tracker,
        domain: Dict[Text, Any],
    ) -> List[Dict[Text, Any]]:
        dispatcher.utter_message(text="Hello World!")
        time.sleep(3)  # sleep 3 seconds
        dispatcher.utter_message(text="Hello World!")
        return []

这个写法,还是会等待第二条消息一并返回。没有达到两条异步返回的效果。

参考:

https://forum.rasa.com/t/delay-in-dispatcher-utter-message/52687/10

似乎是不能在一个 action 中异步返回多个消息,只能拆分成多个 action 来实现这个效果。

实际测试,确实如此,不可以直接在一个 custom action 的 python 代码中通过多个 dispatcher.utter_message 来实现异步返回多条消息。

只能通过拆分为多个不同的 action 来实现。从代码复用,及解耦的角度来看,这样也是合理的。

class ActionHelloWorld(Action):
    def name(self) -> Text:
        return "action_hello_world"

    async def run(
        self,
        dispatcher: CollectingDispatcher,
        tracker: Tracker,
        domain: Dict[Text, Any],
    ) -> List[Dict[Text, Any]]:
        dispatcher.utter_message(text="Hello World!")
        return [
            FollowupAction("action_hello_world2"),
        ]


class ActionHelloWorld2(Action):
    def name(self) -> Text:
        return "action_hello_world2"

    async def run(
        self,
        dispatcher: CollectingDispatcher,
        tracker: Tracker,
        domain: Dict[Text, Any],
    ) -> List[Dict[Text, Any]]:
        time.sleep(3)  # sleep 3 seconds
        dispatcher.utter_message(text="Hello World Again!")
        return []

效果如图

socket.io 多条消息

果然跟预期的一致。

同时,我测试了现有基于 HTTP 的 REST 接口,也确实是等待两条一并返回的。

web 前端 js 代码

user_uttered, 及 bot_uttered 为 rasa socket.io 默认的事件名。

var socket = io.connect("http://localhost:5005", {path: '/my_socket.io'})
socket.on("connect", function () {
  console.log("socketio connected");
  socket.emit("user_uttered", { message: "/hello_world" });
});

socket.on("bot_uttered", function (data) {
  console.log("bot uttered: " + data);
  showMessage(data);
});

function showMessage(data) {
  const messages = document.getElementById("messages");
  const liElement = document.createElement("li");
  liElement.textContent = `text: ${data.text}`;
  messages.appendChild(liElement);
}

查看合集

📖 对话机器人 Rasa 中文系列教程

tags: rasa

关于作者 🌱

我是来自山东烟台的一名开发者,有敢兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊, 查看更多联系方式