diff --git a/README.md b/README.md index 76cd157..724a182 100644 --- a/README.md +++ b/README.md @@ -66,6 +66,14 @@ Fay是一个完整的开源项目,包含Fay控制器及数字人模型,可 2、以上每个模块可轻易替换成自家核心产品。 +3、本地nlp(rasa+chatglm)的替换方法: +1、安装启动chatglm(github) +2、安装rasa 包:rasa、rasa-sdk +3、进入test/rasa目录启动actions:rasa run actions +4、启动rasa api server:rasa run --enable-api -p 5006 +5、fay_core.py 引入nlp_rasa.py + + ### **目录结构** ``` @@ -107,6 +115,7 @@ Fay是一个完整的开源项目,包含Fay控制器及数字人模型,可 **2023.04:** + 抖音直播互动数据对接更换成系统代理抓包pd解码的方式(运行直播伴侣即可); ++ 提供本地nlp的对接代码(rasa+chatglm)。 + 修复若干逻辑及说明错误。 diff --git a/test/rasa/actions/__init__.py b/test/rasa/actions/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/test/rasa/actions/actions.py b/test/rasa/actions/actions.py new file mode 100644 index 0000000..3fd5f00 --- /dev/null +++ b/test/rasa/actions/actions.py @@ -0,0 +1,111 @@ +from rasa_sdk import Action,Tracker +from rasa_sdk.executor import CollectingDispatcher +from datetime import datetime +from dateutil.parser import parse +from dateutil.relativedelta import relativedelta +import json +import requests +from rasa_sdk.forms import FormValidationAction + +class ValidateScheduleReminderForm(FormValidationAction): + def name(self) : + return "validate_schedule_reminder_form" + + async def validate_date(self, value, dispatcher: CollectingDispatcher, tracker: Tracker, domain) : + # 在这里添加您的日期验证逻辑 + return {"date": value} + + async def validate_time(self, value, dispatcher: CollectingDispatcher, tracker: Tracker, domain): + # 在这里添加您的时间验证逻辑 + return {"time": value} + + async def validate_event(self, value, dispatcher: CollectingDispatcher, tracker: Tracker, domain): + # 在这里添加您的事件验证逻辑 + return {"event": value} + + +class ActionGPTResponse(Action): + def name(self) -> str: + return "action_gpt_response" + + async def run(self, dispatcher: CollectingDispatcher, tracker, domain): + history = [] + user_messages = [] + bot_messages = [] + + # Separate user messages and bot messages + for event in tracker.events: + if event.get("event") == "user": + user_messages.append(event.get("text")) + elif event.get("event") == "bot": + bot_messages.append(event.get("text")) + + # Combine user and bot messages + for user, bot in zip(user_messages, bot_messages): + history.append([user, bot]) + + print("*******************************") + print(history) + print("*******************************") + + url = "http://127.0.0.1:8000" + req = json.dumps({ + "prompt": "请用20字内回复我。" + tracker.latest_message.get("text"), + "history": history}) + headers = {'content-type': 'application/json'} + r = requests.post(url, headers=headers, data=req) + a = json.loads(r.text).get('response') + history = json.loads(r.text).get('history') + + dispatcher.utter_message(a) + + return [] + + +class ActionAskDate(Action): + def name(self): + return "action_ask_date" + + async def run(self, dispatcher, tracker, domain): + # 获取当前日期 + today = datetime.now().date() + # 获取星期几的信息 + week_day = today.strftime("%A") + # 将星期几的英文名称转换为中文 + week_day_zh = { + "Monday": "星期一", + "Tuesday": "星期二", + "Wednesday": "星期三", + "Thursday": "星期四", + "Friday": "星期五", + "Saturday": "星期六", + "Sunday": "星期日", + }.get(week_day, "未知") + # 将日期格式化为字符串 + date_str = today.strftime("%Y年%m月%d日") + # 将日期和星期信息发送给用户 + dispatcher.utter_message(text=f"今天是 {date_str} {week_day_zh}。") + + +class ActionAskTime(Action): + def name(self): + return "action_ask_time" + + async def run(self, dispatcher, tracker, domain): + # 获取当前时间 + now = datetime.now() + # 将时间格式化为字符串 + time_str = now.strftime("%H:%M") + # 将时间信息发送给用户 + dispatcher.utter_message(text=f"现在是 {time_str}。") + +def parse_datetime(datetime_str): + try: + datetime_obj = parse(datetime_str, fuzzy=True) + if "周" in datetime_str: # 处理相对日期,如 "周五" + today = datetime.now().date() + weekday_diff = (datetime_obj.weekday() - today.weekday()) % 7 + datetime_obj = today + relativedelta(days=weekday_diff) + return datetime_obj + except ValueError: + print("无法解析日期和时间") diff --git a/test/rasa/config.yml b/test/rasa/config.yml new file mode 100644 index 0000000..6f0871d --- /dev/null +++ b/test/rasa/config.yml @@ -0,0 +1,39 @@ +recipe: default.v1 +assistant_id: 20230416-203150-proud-texture +language: zh +pipeline: +# # No configuration for the NLU pipeline was provided. The following default pipeline was used to train your model. +# # If you'd like to customize it, uncomment and adjust the pipeline. +# # See https://rasa.com/docs/rasa/tuning-your-model for more information. + - name: JiebaTokenizer + - name: RegexFeaturizer + - name: LexicalSyntacticFeaturizer + - name: CountVectorsFeaturizer + - name: CountVectorsFeaturizer + analyzer: char_wb + min_ngram: 1 + max_ngram: 4 + - name: DIETClassifier + epochs: 100 + constrain_similarities: true + - name: EntitySynonymMapper + - name: ResponseSelector + epochs: 100 + constrain_similarities: true + - name: FallbackClassifier + threshold: 0.3 + ambiguity_threshold: 0.1 +policies: +# # No configuration for policies was provided. The following default policies were used to train your model. +# # If you'd like to customize them, uncomment and adjust the policies. +# # See https://rasa.com/docs/rasa/policies for more information. + - name: MemoizationPolicy + - name: RulePolicy + - name: UnexpecTEDIntentPolicy + max_history: 5 + epochs: 100 + - name: TEDPolicy + max_history: 5 + epochs: 100 + constrain_similarities: true + diff --git a/test/rasa/credentials.yml b/test/rasa/credentials.yml new file mode 100644 index 0000000..e9f1291 --- /dev/null +++ b/test/rasa/credentials.yml @@ -0,0 +1,33 @@ +# This file contains the credentials for the voice & chat platforms +# which your bot is using. +# https://rasa.com/docs/rasa/messaging-and-voice-channels + +rest: +# # you don't need to provide anything here - this channel doesn't +# # require any credentials + + +#facebook: +# verify: "" +# secret: "" +# page-access-token: "" + +#slack: +# slack_token: "" +# slack_channel: "" +# slack_signing_secret: "" + +#socketio: +# user_message_evt: +# bot_message_evt: +# session_persistence: + +#mattermost: +# url: "https:///api/v4" +# token: "" +# webhook_url: "" + +# This entry is needed if you are using Rasa Enterprise. The entry represents credentials +# for the Rasa Enterprise "channel", i.e. Talk to your bot and Share with guest testers. +rasa: + url: "http://localhost:5002/api" diff --git a/test/rasa/data/nlu.yml b/test/rasa/data/nlu.yml new file mode 100644 index 0000000..fafbea5 --- /dev/null +++ b/test/rasa/data/nlu.yml @@ -0,0 +1,49 @@ +version: "3.1" + +nlu: +- intent: greet + examples: | + - 你好 + - hello + + +- intent: goodbye + examples: | + - 再见 + - 不聊了 + - 回头说 + - 先这样 + +- intent: ask_time + examples: | + - 现在几点钟了? + - 请告诉我现在的时间 + - 你知道现在是几点吗? + +- intent: ask_date + examples: | + - 今天是几号? + - 今天星期几? + +- intent: out_of_scope + examples: | + - 今天天气真好 + - 我想去公园走走 + - 我需要去上玩吗 + - 其实小明也是一个好人 + - 如何计算圆周率呢 + - 1加1等于几 + - 冲咖啡要什么水温 + - 广州有什么地方玩 + - 广州有什么东西吃 + - 荔枝湾在哪里 + - 我现在是不是该睡觉呢 + - 番禺区 + - 广州市 + - 你知道广州吗 + - 还有别的推荐吗 + - 为什么 + - 怎么办 + - 怎么去 + - 还有别的吗 + - 你的速度可以快一点吗 diff --git a/test/rasa/data/rules.yml b/test/rasa/data/rules.yml new file mode 100644 index 0000000..2d2b4bf --- /dev/null +++ b/test/rasa/data/rules.yml @@ -0,0 +1,30 @@ +version: "3.1" + +rules: + +- rule: 闲聊的回应 + steps: + - intent: out_of_scope + - action: action_gpt_response + +- rule: Say goodbye + steps: + - intent: goodbye + - action: utter_goodbye + +- rule: Say hello + steps: + - intent: greet + - action: utter_greet + +- rule: 用户询问日期 + steps: + - intent: ask_date + - action: action_ask_date + +- rule: 用户询问时间 + steps: + - intent: ask_time + - action: action_ask_time + + diff --git a/test/rasa/data/stories.yml b/test/rasa/data/stories.yml new file mode 100644 index 0000000..e69de29 diff --git a/test/rasa/domain.yml b/test/rasa/domain.yml new file mode 100644 index 0000000..0d14b7e --- /dev/null +++ b/test/rasa/domain.yml @@ -0,0 +1,25 @@ +version: "3.1" + +intents: + - greet + - goodbye + - ask_time + - ask_date + - out_of_scope + +responses: + utter_greet: + - text: "你好,有什么帮到你呢?" + + utter_goodbye: + - text: "那我先离开了,一会有事叫我" + - text: "先不打扰你了,你可以随时唤醒我" + +session_config: + session_expiration_time: 60 + carry_over_slots_to_new_session: true + +actions: + - action_ask_time + - action_ask_date + - action_gpt_response diff --git a/test/rasa/endpoints.yml b/test/rasa/endpoints.yml new file mode 100644 index 0000000..86bc425 --- /dev/null +++ b/test/rasa/endpoints.yml @@ -0,0 +1,2 @@ +action_endpoint: + url: "http://localhost:5055/webhook" diff --git a/test/rasa/models/20230423-112023-mild-goldfinch.tar.gz b/test/rasa/models/20230423-112023-mild-goldfinch.tar.gz new file mode 100644 index 0000000..e0dbd8e Binary files /dev/null and b/test/rasa/models/20230423-112023-mild-goldfinch.tar.gz differ diff --git a/test/rasa/nlp_rasa.py b/test/rasa/nlp_rasa.py new file mode 100644 index 0000000..d0cb897 --- /dev/null +++ b/test/rasa/nlp_rasa.py @@ -0,0 +1,10 @@ +import json +import requests + +def question(cont): + url="http://localhost:5005/webhooks/rest/webhook" + req = json.dumps({"sender": "user", "message": cont}) + headers = {'content-type': 'application/json'} + r = requests.post(url, headers=headers, data=req) + a = json.loads(r.text)[0].get('text') + return a diff --git a/test/rasa/readme.txt b/test/rasa/readme.txt new file mode 100644 index 0000000..5a016e5 --- /dev/null +++ b/test/rasa/readme.txt @@ -0,0 +1,5 @@ +1、安装启动chatglm(github) +2、安装rasa 包:rasa、rasa-sdk +3、进入test/rasa目录启动actions:rasa run actions +4、启动rasa api server:rasa run --enable-api -p 5006 +5、fay_core.py 引入nlp_rasa.py diff --git a/test/rasa/tests/test_stories.yml b/test/rasa/tests/test_stories.yml new file mode 100644 index 0000000..d46e39b --- /dev/null +++ b/test/rasa/tests/test_stories.yml @@ -0,0 +1,91 @@ +#### This file contains tests to evaluate that your bot behaves as expected. +#### If you want to learn more, please see the docs: https://rasa.com/docs/rasa/testing-your-assistant + +stories: +- story: happy path 1 + steps: + - user: | + hello there! + intent: greet + - action: utter_greet + - user: | + amazing + intent: mood_great + - action: utter_happy + +- story: happy path 2 + steps: + - user: | + hello there! + intent: greet + - action: utter_greet + - user: | + amazing + intent: mood_great + - action: utter_happy + - user: | + bye-bye! + intent: goodbye + - action: utter_goodbye + +- story: sad path 1 + steps: + - user: | + hello + intent: greet + - action: utter_greet + - user: | + not good + intent: mood_unhappy + - action: utter_cheer_up + - action: utter_did_that_help + - user: | + yes + intent: affirm + - action: utter_happy + +- story: sad path 2 + steps: + - user: | + hello + intent: greet + - action: utter_greet + - user: | + not good + intent: mood_unhappy + - action: utter_cheer_up + - action: utter_did_that_help + - user: | + not really + intent: deny + - action: utter_goodbye + +- story: sad path 3 + steps: + - user: | + hi + intent: greet + - action: utter_greet + - user: | + very terrible + intent: mood_unhappy + - action: utter_cheer_up + - action: utter_did_that_help + - user: | + no + intent: deny + - action: utter_goodbye + +- story: say goodbye + steps: + - user: | + bye-bye! + intent: goodbye + - action: utter_goodbye + +- story: bot challenge + steps: + - user: | + are you a bot? + intent: bot_challenge + - action: utter_iamabot