RASA2.0搭建中文聊天机器人
环境搭建
rasa==2.0.0
rasa-sdk==2.4.1
tensorflow==2.3.2
Flask==1.1.2
开始搭建
- 初始化项目
rasa init
- 初始化后会创建以下文件,介绍几个重要的文件,当然这些文件结构你也可以自己调整文件名作用config.yml配置NLU和Core的文件/data/nlu.ymlNLU的训练语句,意图加包含意图的话术/data/stories.yml对话的故事,可以理解为剧本domain.yml作用域,里面注册你定义的意图,对话模板,自定义action,槽位等endpoints.ymlaction的端口,action对外暴露的接口配置文件/models/xxxx.tar,gz训练的模型
- 我的项目目录结构是这样的,可以作为参考。
[En]
the directory structure of my project is like this, which can be used as a reference.*
.├── actions│ ├── action_kn_test.py│ ├── action_trademark_analy.py│ ├── action_trademark_explain.py│ ├── action_trademark_keyword.py│ ├── action_weather_query.py│ ├── __init__.py│ └── __pycache__│ ├── action_kn_test.cpython-36.pyc│ ├── action_trademark_analy.cpython-36.pyc│ ├── action_trademark_explain.cpython-36.pyc│ ├── action_trademark_keyword.cpython-36.pyc│ ├── action_weather_query.cpython-36.pyc│ └── __init__.cpython-36.pyc├── App│ ├── def_func.py│ ├── def_settings.py│ ├── ext.py│ ├── __init__.py│ ├── models.py│ ├── __pycache__│ │ ├── ext.cpython-36.pyc│ │ ├── __init__.cpython-36.pyc│ │ └── views.cpython-36.pyc│ ├── settings.py│ ├── static│ │ ├── css│ │ │ └── style2.css│ │ ├── images│ │ │ ├── ai.png│ │ └── js│ │ ├── chat.js│ │ └── jquery-3.3.1.min.js│ ├── templates│ │ └── chat.html│ └── views.py├── configs│ ├── config.yml│ ├── credentials.yml│ ├── domain.yml│ ├── endpoints.yml│ ├── zh_jieba_mitie_embeddings_config.yml│ └── zh_jieba_supervised_embeddings_config.yml├── data│ ├── dict│ │ ├── cityname.txt│ │ └── userdict.txt│ ├── nlu│ │ └── nlu.yml│ ├── rules.yml│ ├── stories│ │ ├── stories.yml│ │ └── story1.md│ └── total_word_feature_extractor_zh.dat├── models│ └── 20210420-153935.tar.gz├── __pycache__├── server.py├── shell_diectory│ ├── run_shell│ └── train_shell
开始构建聊天机器人的第一个例子(查天气)
- 定义你的NLU
- intent: query_weather examples: | - 我想查询天气 - 我想查询[广州]{"entity":"address"}的天气 - [明天]{"entity":"datetime"}天气怎么样? - 我想查询[明天]{"entity":"datetime"}[深圳]{"entity":"address"}的天气
- 准备地名词库
- 定义你stories剧本
## query_weather(天气查询)
* query_weather
- weather_form
- active_loop{"name":"weather_form"}
- 在domain.yml 注册,注册你定义的意图,实体,槽位,问话模板,表单,自定义的action等
version: "2.0"
intents:
- greet
- goodbye
- affirm
- deny
- mood_great
- mood_unhappy
- bot_challenge
- query_weather
entities:
- kn_question_num
- datetime
- address
actions:
- action_test
slots:
kn_question_num:
type: text
datetime:
type: text
address:
type: text
requested_slot:
type: unfeaturized
responses:
utter_greet:
- text: "Hey! How are you?"
utter_cheer_up:
- text: "Here is something to cheer you up:"
image: "https://i.imgur.com/nGF1K8f.jpg"
utter_did_that_help:
- text: "Did that help you?"
utter_happy:
- text: "Great, carry on!"
utter_goodbye:
- text: "Bye"
utter_iamabot:
- text: "I am a bot, powered by Rasa."
utter_ask_datetime:
- text: "请问你要查询什么时候的天气?"
utter_ask_address:
- text: "请问你要查询哪里的天气?"
forms:
weather_form: {}
session_config:
session_expiration_time: 60
carry_over_slots_to_new_session: true
- 自定义action.py
'''
@author: 小帆芽芽
date: 2021/04/25
'''
from rasa_sdk.types import DomainDict
from typing import Dict, Text, Any, List, Union
from flask import jsonify
from rasa_sdk import Tracker, Action
from rasa_sdk.events import UserUtteranceReverted, Restarted, SlotSet, EventType
from rasa_sdk.executor import CollectingDispatcher
from rasa_sdk.forms import FormAction
from requests import (
ConnectionError,
HTTPError,
TooManyRedirects,
Timeout
)
from rasa_sdk import ActionExecutionRejection
from rasa_sdk.events import SlotSet, AllSlotsReset
from rasa_sdk.executor import CollectingDispatcher
from rasa_sdk.forms import FormAction, REQUESTED_SLOT
import requests, random, math
import re
import json
import logging
logger = logging.getLogger(__name__)
class QueryWeather(FormAction):
'''
心知天气API
'''
def __init__(self):
super().__init__()
self.KEY = '你的私钥'
self.LOCATION = 'beijing'
self.url = 'https://api.seniverse.com/v3/weather/daily.json'
self.UNIT = 'c'
self.LANGUAGE = 'zh-Hans'
self.data={
'key': self.KEY,
'location': self.LOCATION,
'language': self.LANGUAGE,
'unit': self.UNIT,
'start': 0,
'days': 10
}
self.num = 0
def name(self) -> Text:
return "weather_form"
@staticmethod
def required_slots(tracker):
return ['address','datetime']
def slot_mappings(self) -> Dict[Text, Union[Dict, List[Dict[Text, Any]]]]:
return {'address':[self.from_text()],'datetime':[self.from_text()]}
def validate_address(self,slot_value, dispatcher, tracker, domain):
path = './data/dict/cityname.txt'
d_ = [i.strip() for i in open(path, 'r').readlines()]
if slot_value in d_:
return {"address":slot_value}
else:
dispatcher.utter_message('您输入的不是地名哟')
return {"address":None}
def validate_datetime(self,slot_value, dispatcher, tracker, domain):
d_list = ['今天','明天','后天']
if slot_value in d_list:
return {"datetime":slot_value}
else:
dispatcher.utter_message('暂不支持查询 {} 的天气'.format(slot_value))
return {"datetime":None}
def submit(self,dispatcher, tracker, domain):
date = tracker.get_slot('datetime')
address = tracker.get_slot('address')
self.judge_time(date)
text_day, text_night, high, low, wind_direction, humidity, wind_speed, wind_scale,date_ = self.get_weather(address)
s='{}{}({})的天气情况是:白天{},晚上{}.当天最高温度是{}摄氏度,最低温度是{}摄氏度.风向{},风速{},风力等级为{},空气湿度为{}%'.format(
address,date,date_, text_day,text_night,high,low,wind_direction,wind_speed,wind_scale,humidity
)
dispatcher.utter_message('小娜为您查询到:')
dispatcher.utter_message(s)
return [Restarted()]
def judge_time(self,date):
if date == '今天':
self.num = 0
elif date == '明天':
self.num = 1
elif date == '后天':
self.num = 2
def get_weather(self,address):
self.LOCATION = address
str_ = requests.get(url=self.url,params=self.data,timeout=2).text
dic = json.loads(str_)
print(dic)
text_day = dic['results'][0]['daily'][self.num]['text_day']
text_night = dic['results'][0]['daily'][self.num]['text_night']
high = dic['results'][0]['daily'][self.num]['high']
low = dic['results'][0]['daily'][self.num]['low']
wind_direction = dic['results'][0]['daily'][self.num]['wind_direction']
humidity = dic['results'][0]['daily'][self.num]['humidity']
wind_speed = dic['results'][0]['daily'][self.num]['wind_speed']
wind_scale = dic['results'][0]['daily'][self.num]['wind_scale']
date_ = dic['results'][0]['daily'][self.num]['date']
return text_day,text_night,high,low,wind_direction,humidity,wind_speed,wind_scale,date_
- 采用flask外部调用接口
'''
@author:小帆芽芽
@date:2021/04/25
'''
import json
import re
import requests
from flask import Blueprint, render_template, request
blue = Blueprint('rasa', __name__)
REQUEST_URL = "http://localhost:5005/webhooks/rest/webhook"
HEADERS = {'Content-Type': 'application/json; charset=utf-8'}
def init_route(app):
app.register_blueprint(blue)
@blue.route('/', methods=['GET', 'POST'])
def test():
return render_template('chat.html')
@blue.route('/chat',methods=['GET'])
def chat():
data=request.args.to_dict()
message=data['message']
if message:
answer = rasaresponse('xiaofangyaya',message)
return answer
def rasaresponse(user,msg):
requestDict={'sender':user,'message':msg}
rsp=requests.post(REQUEST_URL, data=json.dumps(requestDict),headers=HEADERS)
if rsp.status_code == 200:
rsp_json=json.loads(rsp.text.encode())
content_text = ''
if len(rsp_json):
for i in range(len(rsp_json)):
txt_=rsp_json[i].get('text')
print('rasa返回内容是---------->{}'.format(txt_))
if txt_:
content_text=content_text+txt_
else:
content_text=content_text + '\n' + rsp_json[i]['image']
return content_text
else:
return '哎呀,这个小娜也不懂呢~~~'
else:
return '返回错误,请重新输入问话。'
- 运行rasa,依次执行以下命令
python -m rasa run --port 5005 -m models/20210420-153935.tar.gz --endpoints configs/endpoints.yml --credentials configs/credentials.yml --debug
python -m rasa run actions --port 5055 --actions actions --debug
python server.py
- 页面测试
- 我的源码地址:
https://gitee.com/menfeng/rasa-weather-edition
希望大家喜欢、关注和支持哦!
[En]
Hope to like, follow and support Oh!
后期还有大波福利发送
Original: https://blog.csdn.net/m0_49501453/article/details/120113135
Author: 小帆芽芽
Title: RASA2.0 搭建中文聊天机器人(附gitee源码)
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/514350/
转载文章受原作者版权保护。转载请注明原作者出处!