事件代理¶
事件代理允许将正在运行的对话机器人连接到处理来自对话的数据的其他服务。事件代理将消息发送到消息流服务(也称为消息代理),来将 Rasa 事件从 Rasa 服务器转发到其他服务。
格式¶
每次追踪器更新其状态时,所有事件都会作为序列化字典流式传输到代理。default
追踪器发出的示例事件如下所示:
{
"sender_id": "default",
"timestamp": 1528402837.617099,
"event": "bot",
"text": "what your bot said",
"data": "some data about e.g. attachments"
"metadata" {
"a key": "a value",
}
}
event
字段采用事件的 type_name
(有关事件类型的更多信息,请参见事件文档)。
Kafka 事件代理¶
建议所有对话机器人都使用 Kafka。将事件流式传输到 Rasa Pro Services 或 Rasa Studio 时,Kafka 是必需的。
Rasa 使用 confluent-kafka 库,这是一个用 Python 编写的 Kafka 客户端。
配置¶
可以通过将 event_broker
部分添加到 endpoints.yml
来指示 Rasa 将所有事件流式传输到 Kafka 事件代理。
要使用 Kafka 设置 Rasa,需要执行以下步骤:
-
将所需配置添加到
endpoints.yml
。endpoints.ymlevent_broker: type: kafka partition_by_sender: True security_protocol: PLAINTEXT topic: topic url: localhost client_id: kafka-python-rasa
使用
SASL_PLAINTEXT
协议,端点文件必须具有如下项:event_broker: type: kafka security_protocol: SASL_PLAINTEXT topic: topic url: localhost partition_by_sender: True sasl_username: username sasl_password: password sasl_mechanism: PLAIN
使用
PLAINTEXT
协议,端点文件必须具有如下项:event_broker: type: kafka security_protocol: PLAINTEXT topic: topic url: localhost client_id: kafka-python-rasa
如果使用
SSL
协议,端点文件应如下所示:event_broker: type: kafka security_protocol: SSL topic: topic url: localhost ssl_cafile: CARoot.pem ssl_certfile: certificate.pem ssl_keyfile: key.pem ssl_check_hostname: True
如果使用
SASL_SSL
协议,端点文件应如下所示: -
要使用 Kafka 后端启动 Rasa 服务器,请添加
--endpoints
标志,例如:
配置参数¶
分区键¶
Rasa 的 Kafka 生产者可以选择配置为按对话 ID 对消息进行分区。可以通过将 endpoints.yml
文件中的 partition_by_sender
设置为 True
来配置。默认情况下,该参数设置为 False
,生产者会为每条消息随机分配一个分区。
event_broker:
type: kafka
partition_by_sender: True
security_protocol: PLAINTEXT
topic: topic
url: localhost
client_id: kafka-python-rasa
身份验证和授权¶
Rasa 的 Kafka 生产者接受以下类型的安全协议:SASL_PLAINTEXT
、SSL
、PLAINTEXT
和 SASL_SSL
。
对于开发环境,或者如果代理服务器和客户端位于同一台机器中,可以使用 SASL_PLAINTEXT
或 PLAINTEXT
的简单身份验证。通过使用此协议,客户端和服务器之间交换的凭据和信息将以明文形式发送。因此,这不是最安全的方法,但由于它易于配置,对于简单的集群配置很有用。SASL_PLAINTEXT
协议需要设置先前在代理服务器中配置的用户名和密码。
如果 Kafka 集群中的客户端或代理位于不同的机器上,则使用 SSL
或 SASL_SSL
协议来确保数据加密和客户端身份验证则非常重要。在为代理和客户端生成有效证书后,必须提供证书路径和为生产者生成的密钥,以及 CA 的根证书。
使用 SASL_PLAINTEXT
和 SASL_SSL
协议时,可选配置 sasl_mechanism
,默认设置为 PLAIN
。sasl_mechanism
的有效值为:PLAIN
、GSSAPI
、OAUTHBEARER
、SCRAM-SHA-256
和 SCRAM-SHA-512
。
如果 GSSAPI
用于 sasl_mechanism
,则需要额外安装 python-gssapi 和必要的 C 库 Kerberos 依赖。
如果启用了 ssl_check_hostname
参数,客户端将验证代理的主机名是否与证书匹配。它用于客户端连接和代理间的连接,以防止中间人攻击。
将事件发送到多个队列¶
Kafka 不允许你配置多个主题。
但是,多个消费者可以从同一个队列读取,只要它们属于不同的消费者组。每个消费者组将独立处理所有事件(从某种意义上说,每个组都有自己对已处理的最后一个事件的引用)。Kafka:权威指南。
Pika 事件代理¶
如下展示的示例实现了使用 RabbitMQ 的 Python 客户端库 Pika。
使用端点配置添加 Pika 事件代理¶
要使用 Pika for RabbitMQ 设置 Rasa,需要执行以下步骤:
-
将所需配置添加到
endpoints.yml
。 -
要使用 Redis 后端启动 Rasa 服务器,请添加
--endpoints 标志
,例如:
配置参数¶
可以在参考文档中找到在 endpoints.yml
文件中自定义的所有参数的完整列表。当重新启动 Rasa 服务时,Rasa 将自动启动流式传输事件。
向 Pika 事件代理添加 SSL 选项¶
可以通过设置如下必需的环境变量来创建 RabbitMQ SSL 选项:
RABBITMQ_SSL_CLIENT_CERTIFICATE
:SSL 客户端证书的路径。RABBITMQ_SSL_CLIENT_KEY
:SSL 客户端密钥的路径。
请注意,不再支持通过环境变量指定 RABBITMQ_SSL_CA_FILE
,以及指定 RABBITMQ_SSL_KEY_PASSWORD
,请改用未加密的密钥文件。
在 Python 中添加 Pika 事件代理¶
如下是使用 Python 代码添加它的方法:
import asyncio
from rasa.core.brokers.pika import PikaEventBroker
from rasa.core.tracker_store import InMemoryTrackerStore
pika_broker = PikaEventBroker('localhost',
'username',
'password',
queues=['rasa_events'],
event_loop=event_loop
)
asyncio.run(pika_broker.connect())
tracker_store = InMemoryTrackerStore(domain=domain, event_broker=pika_broker)
实现 Pika 事件消费者¶
需要运行一个 RabbitMQ 服务器,以及另一个使用事件的应用。消费者需要使用 callback
操作来实现 Pika 的 start_consuming()
方法。示例如下:
import json
import pika
def _callback(ch, method, properties, body):
# Do something useful with your incoming message body here, e.g.
# saving it to a database
print("Received event {}".format(json.loads(body)))
if __name__ == "__main__":
# RabbitMQ credentials with username and password
credentials = pika.PlainCredentials("username", "password")
# Pika connection to the RabbitMQ host - typically 'rabbit' in a
# docker environment, or 'localhost' in a local environment
connection = pika.BlockingConnection(
pika.ConnectionParameters("rabbit", credentials=credentials)
)
# start consumption of channel
channel = connection.channel()
channel.basic_consume(queue="rasa_events", on_message_callback=_callback, auto_ack=True)
channel.start_consuming()
将事件发送到多个队列¶
你可以指定多个事件队列来发布事件。这适用于 Pika 支持的所有事件代理(例如 RabbitMQ)。
SQL 事件代理¶
可以将 SQL 数据库用作事件代理。使用 SQLAlchemy 建立与数据库的连接,SQLAlchemy 是一个可以与多种不同类型的 SQL 数据库(例如:SQLite、PostgreSQL 等)进行交互的 Python 库。默认的 Rasa 安装允许连接到 SQLite 和 PostgreSQL 数据库。其他选项请参见 SQLAlchemy 文档的 SQL 方言。
要使用 SQL 事件代理设置 Rasa,需要执行以下步骤:
-
将所需配置添加到
endpoints.yml
。使用 SQLite 时:
也可以使用 PostgreSQL 数据库:
-
要使用 Redis 后端启动 Rasa 服务器,请添加
--endpoints 标志
,例如:
文件事件代理¶
可以将 FileEventBroker
用作事件代理。此实现会将事件记录到 JSON 格式文件中。
如果希望覆盖默认文件名 rasa_event.log
,可以在 endpoints.yml
文件中提供路径键。
自定义事件代理¶
如果你需要一个无法开箱即用的事件代理,可以实现一个自定义的。通过扩展基类 EventBroker
可以完成。
自定义事件代理类必须实现如下基类方法:
from_endpoint_config
:从端点配置创建一个EventBroker
对象。(源代码)publish
:将 JSON 格式的 Rasa 事件发布到事件队列中。(源代码)is_ready
:判断事件代理是否准备好。(源代码)close
:关闭与事件代理的连接。(源代码)
配置¶
要使用自定义事件代理设置 Rasa,需要执行以下步骤:
-
将所需配置添加到你的
endpoints.yml
。 -
要使用 Redis 后端启动 Rasa 服务器,请添加
--endpoints 标志
,例如: