整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

FB开源人工智能框架ParlAI:可轻松训练评估对话

FB开源人工智能框架ParlAI:可轻松训练评估对话模型

自GitHub

机器之心编译

参与:吴攀、晏奇

Facebook 近日在 GitHub 上开源了一个可用于在多种开放可用的对话数据集上训练和评估人工智能模型的框架 ParlAI,机器之心在本文中对这一项目的 README.md 内容进行了编译介绍。项目地址如下:

  • 官网地址:http://parl.ai

  • GitHub:https://github.com/facebookresearch/ParlAI

ParlAI(读音为 par-lay)是一个用于对话人工智能研究的框架,是用 Python 实现的。该框架的目标是为研究者提供:

  • 一个用于训练和测试对话模型的统一框架

  • 一次性在许多数据集上进行多任务训练

  • 无缝集成 Amazon Mechanical Turk,以便数据收集和人工评估

这第一个版本支持超过 20 种任务,也囊括了许多流行的数据集,比如 SQuAD、bAbI tasks、MCTest、WikiQA、WebQuestions、SimpleQuestions、WikiMovies、QACNN & QADailyMail、CBT、BookTest、bAbI Dialog tasks、Ubuntu Dialog、OpenSubtitles、Cornell Movie 和 VQA-COCO2014。

还包括使用 PyTorch 和 Lua Torch 训练神经模型的示例,其包含了在 GPU 上的批训练或在 CPU 上的 hogwild 训练。另外使用 Theano 或 TensorFlow 也是很直接的。

我们的目标是让那些在它们之上训练的任务和智能体能够以一种基于社区的方式成长。

这个版本还是早期的 Beta 版,使用过程中可能会有一些冒险,或遇到一些难题。

目标

用于评估模型的统一框架

  • 可按需下载任务/数据集,且为它们提供了同样简单的接口

  • 统一的数据集输入和评估框架/标准

  • agents/ 目录鼓励研究者提交他们的训练代码,以便在该 repo 中分享

  • 协助重现

最终目标是实现通用的对话,包括许多不同的技能

  • 无缝地组合模拟的和真实的语言任务

  • 鼓励多任务模型的开发和评估

  • 有助于减少模型在特定数据集上的过拟合

最终目标是实现与人类的真实对话

  • 通过 Mechanical Turk,在与人类的实时对话上训练和评估

  • 只需简单的设置,就可以连接 Mechanical Turk 上的人类与你的对话代理

  • 允许比较不同研究组的 Turk 实验

能够引导一个可与人类交互的对话模型的数据集配置

  • 激励构建将进入本 repo 的新数据集

特性

  • 所有的数据集都像自然对话:单一格式/API

  • 既有固定数据集(会话日志),也有交互式任务(在线/RL)

  • 既有真实任务,也有模拟任务

  • 支持其它媒体,比如 VQA 中的视觉

  • 可以使用 Mechanical Turk 来运行/收集数据/评估

  • Python 框架

  • PyTorch 的训练示例

  • 可使用 zmq 与其它非 Python 的工具箱对话,给出了 Lua Torch 的示例

  • 支持模型的 hogwild 训练和批训练

基本示例

从「1k training examples」bAbI 任务的任务 1 中展示 10 个随机样本:

python examples/display_data.py -t babi:task1k:1

同时在 bAbI 任务的多任务与 SQuAD 数据集上展示 100 个随机样本:

python examples/display_data.py -t babi:task1k:1,squad -n 100

在 Movies Subreddit 数据集的验证集上评估 IR 基线模型:

python examples/eval_model.py -m ir_baseline -t "#moviedd-reddit" -dt valid

给出该 IR 基线模型的预测:

python examples/display_model.py -m ir_baseline -t "#moviedd-reddit" -dt valid

在「10k training examples」bAbI 任务 1 上训练一个简单的基于 CPU 的记忆网络,其使用了 Hogwild(需要 zmq 和 Lua Torch),有 8 个线程(Python 进程):

python examples/memnn_luatorch_cpu/full_task_train.py -t babi:task10k:1 -n 8

在 SQuAD 数据集上训练一个「注意 LSTM」模型,其中批大小为 32(PyTorch 和 regex)

python examples/drqa/train.py -t squad -b 32

要求

ParlAI 目前支持 Python3。

核心模组的依赖内容参见 requirement.txt。其中部分模型(在 parlai/agents 中)有进一步要求,比如需要 PyTorch 或 Lua Torch——所有这些模组的要求都可以参见 requirements_ext.txt 这个文档。

安装 ParlAI

首先,复制该 repository,然后进入复制的目录。

链接安装:运行 python setup.py develop 来将复制的目录链接到你的 site-packages。如果你打算根据你的运行修改任何的 parlai 代码或者提交一个 pull request,特别是如果你想在 repository 上添加另外的任务的话,那么我们推荐上述安装过程。所有需要的数据都将被下载到 ./data,而且,如果要求任何模型的文件(目前仅是 memnn 模型),它们都将被下载到 ./downloads。

复制后的安装内容(仅将 parlai 用作一个依赖项):运行 python setup.py install 来将内容复制到你的 site-packages 文件夹。所有数据都会被默认下载到 python 的 site-packages 文件夹中(你可以通过命令行来改写路径),不过一旦对代码作出了任何改动,你都需要重新运行一次安装。如果你仅想将 parlai 作为一个依赖项使用(比如用于访问任务或核心代码),那么目前这样就可以了。但是如果你想要清除下载的数据,那么删除 site-packages/parlai 中的 data 和 downloads 文件夹(如果可以的话)。

Worlds, agents 和 teachers

ParlAI 中的主要概念(类):

  • world——它定义了环境(它可以非常简单,可以仅两个代理相互对话)。

  • agent——这是世界里的一个代理,比如一个学习器。(存在很多学习器。)

  • teacher——这是一种可以和学习者对话的代理,它用于实现前面提到的任务。

在定义完 ParlAI 中的 world 和 agent 之后,一个主 loop 可被用来训练、测试或显示,它叫做 world.parley() 函数。我们在左边的面板中给出了个实例的主要骨架,parley() 函数真实的代码写在右侧面板。

Actions 和 Observations

所有的 agent(包括 teacher)都以简单的格式互相对话——observation/action 对象(这是一个 python 字典)。这被用于传递 agent 之间的文本、标签和奖励。这和当在对话(行动)或听(观察)时是同类对象,但是不同视角(在这些字段中有不同的值)。这些领域如下所述:

尽管'text'(文本)领域将几乎可能在全部交流(exchange)中被使用,但是技术上来说,基于你的数据集,这些领域中的每个都是可选的。

对于一个固定的监督式学习数据集(比如 bAbI)来说,一个典型的从数据集进行交流(exchange)例子可以像如下这样(该测试集不包含标签):

Teacher: {

'text': 'Sam went to the kitchen\nPat gave Sam the milk\nWhere is the milk?',

'labels': ['kitchen'],

'label_candidates': ['hallway', 'kitchen', 'bathroom'],

'episode_done': False

}

Student: {

'text': 'hallway'

}

Teacher: {

'text': 'Sam went to the hallway\nPat went to the bathroom\nWhere is the milk?',

'labels': ['hallway'],

'label_candidates': ['hallway', 'kitchen', 'bathroom'],

'episode_done': True

}

Student: {

'text': 'hallway'

}

Teacher: {

... # starts next episode

}...

代码

代码被设置进了几个主要目录:

  • core:它包含了框架的首要代码。

  • agents:包含了可以凭不同任务交互的代理(比如:机器学习模型)。

  • example:包含了不同循环的一些基本样例(构建词典、训练/评价、显示数据)。

  • tasks:包含了可来自于 ParlAI 的不同任务的代码。

  • mturk:包含了设置 Mechanical Turk 的代码和作为样例的 MTurk 任务。

下面我们会更具体地说明每个目录,我们根据依赖项(dependency)来组织行文。

Core 库

core 库包含了如下文件:

  • agent.py:这个文件包含了一些可被你自己模型延展的基本 agent。

  • Agent:这是所有 agent 的基本类,实现了 act() 方法,该方法接受一个观察表(table)并且返回一个作为回复的表。

  • Teacher:它是 Agent 的子代,也实现了针对返回量度(returning metric)的报告方法。任务实现了 Teacher 这个类。

  • MultiTaskTeacher:它创造了一个基于「任务字符串」的 teacher 集,该集可以传递给 Teacher。在其中它创建了多个 teacher 并且在它们之间交替轮换。

  • create_task_teacher:它从一段给定的任务字符串中实例化了一个 teacher(比如「babi:task:1」或「squad」)。

  • build_data.py:用于设置任务数据的基本功能。如果你的文件系统需要不同的功能,你可以覆盖它。

  • dialog_teacher.py:包含了用于和固定交谈(chat)日志进行对话(dialog)的一个基本 teacher 类,同时它也包含了一个用于储存数据的数据类(data class)。

  • dict.py:包含了从观察中构建一般 NLP 风格字典的代码。

  • DictionaryAgent:在一个字典中跟踪索引和词频的 agent,可以将一个句子解析成它字典或 back 中的指数(indice)。

  • fbdialog_teacher.py:包含了一个 teacher 类,该类实现了一个 setup_data 函数,这个函数用 Facebook 的 Dialog 数据格式来解析数据。

  • metrics.py:计算对话的评价量度,比如对排名的量度等。

  • params.py:用 argparse 来为 ParlAI 解释命令行 argument。

  • thread_utils.py:用于 Hogwild 多线程(多重处理)的工具类/函数。

  • SharedTable:提供一个锁保护、记忆分享、类字典的用于追踪度量的的界面。

  • worlds.py:包含了一套用于内部开展任务的基本 world。

  • World:所有 world 的基本类,实现了 parley,shutdown,__enter__,和__exit__。

  • DialogPartnerWorld:用于双 agent 回合交流的默认 world。

  • MultiAgentDialogWorld:用于两到多个 agent 的循环(round-robin)回合 agent 交流。

  • HogwildWorld:当使用多线程(多重处理)时。这是用于设置一个对每个线程而言分别独立的 world 的默认 world。

Agents 目录

agents 目录包含了已被认可进入 ParlAI 框架用于分享的 agent。目前有这些可用的目录:

  • drqa:这是一个很周全的 LSTM 模型,它叫「DrQA」(问答博士,论文地址:https://arxiv.org/abs/1704.00051)。它用 PyTorch 框架实现,在 SQuAD 数据集上,它得到的结果相比其它模型更具竞争力。

  • memnn:它是在 Lua Torch 中用于端到端记忆网络的代码。

  • remote_agent:连接 ZMQ 的任意 agent 的基本类(memnn_luatorch_cpu 就使用这个)。

  • ir_baseline:简单的信息检索基准(baseline),它用 TFIDF-权重匹配为候选者的反馈评分。

  • repeat_label:仅重复(repeating)发送给它的所有数据的基本类(如连接(piping)到一个文件、调试)。

实例

这个目录包含了部分基本循环的具体例子。

  • base_train.py:一个非常简单的例子,展示了一个使用默认 Agent 亲本类的训练/验证循环的轮廓。

  • display_data.py:使用 agent.repeat_label 来显示来命令行给出的特定任务的数据。

  • display_model.py:显示对一个给定模型在命令行给出的特定任务之上的预测。

  • eval_model.py:使用命名后的 agent 来计算一个命令行给出的特定任务的评价量度(evaluation metric)数据。

  • build_dict.py:使用 core.dict.DictionaryAgent 建立一个来自命令行给出的特定任务的 dictionary。

  • memnn_luatorch_cpu:展示了一些在几个数据集上训练端到端记忆网络的例子。

  • drqa:展示了如何在 SQuAD 训练集上训练一个周全的 LSTM「DrQA」模型(论文地址:https://arxiv.org/abs/1704.00051)。

任务

这个第一版本支持超过 20 种任务,包括 SQuAD、bAbI tasks、MCTest、WikiQA、WebQuestions、SimpleQuestions、WikiMovies、QACNN、QADailyMail、CBT、BookTest、bAbI Dialog tasks、Ubuntu、OpenSubtitles、Cornell Movie 和 VQA-COCO2014 等流行的数据集。

我们的第一版包含以下数据集,见下图左栏;获取它们也非常简单,只需在命令行的选项中指定对应任务的名称即可,如右栏的数据集展示实用程序所示。查阅当前完整任务列表请访问:https://github.com/facebookresearch/ParlAI/blob/master/parlai/tasks/task_list.py

在 ParlAI 中选择一个任务非常简单,只需要在命令行中指定它既可,如上图(右)所示。如果该数据集之前没有被使用过,那 ParlAI 将会自动下载它。因为在 ParlAI 中,所有的数据集的处理方式都是一样的(使用单个对话 API),所以原则上一个对话代理可以在这些数据集之间切换训练和测试。还不止于此,你可以简单地通过提供一个逗号分隔的列表来一次性指定许多任务(多任务),比如命令「-t babi,squad」可以使用这两个数据集,甚至还可以使用「-t #qa」命令一次性指定所有的 QA 数据集或使用「-t #all」一次性指定 ParlAI 中的每一个任务。我们的目标是使其可以轻松地创建和评估非常丰富的对话模型。

每个任务文件夹包含:

  • build.py 文件,用于设置任务的数据(下载数据等,仅在第一次请求时完成,如果某个任务从未被使用,那么就不会下载它)。

  • agents.py 文件,包含了默认的或特定的教师(teacher)类别,可被 core.create_task 用来从命令行参数上实例化这些类别(如有需要)。

  • worlds.py 文件,是可选的,可用于需要定义新环境或复杂环境的任务。

要添加你自己的任务:

  • (可选)实现 build.py 以下载任何所需的数据

  • 实现 agents.py,至少包含一个 DefaultTeacher(扩展 Teacher 或它的一个衍生)

  • 如果你的数据是 FB Dialog 格式的,那么属于 FbDialogTeacher 类别

  • 如果不是 FB Dialog 格式:

  • 如果你的数据是基于文本的,你可以使用扩展的 DialogTeacher,并因此要使用 core.data.TextData,在这种情况下,你仅需要编写你自己的 setup_data 函数,其可根据在 core.data 中所描述的格式而在数据之上提供一个 iterable.

  • 如果你的数据使用了其它字段,那么就要编写你自己的 act() 方法,其提供了当你的任务每次被调用时的观察。

MTurk

ParlAI 的一个重要方面是与 Mechanical Turk 的无缝集成,可用于数据收集、训练和评估。在 ParlAI 中,人类 Turker 也被视为代理(agent),因此在一个标准的框架中可以进行人-人、人-bot、多人和多 bot 群聊等形式的对话,也可以按照需求切换角色,而无需对代理的代码进行修改。这是因为 Turker 也可以使用观察/动作(observation/action)词典中的字段来通过同样接口的一个版本进行接收和发送。我们在这第一版中提供了两个示例——收集数据和人类对 bot 的评估。

mturk 库包含以下目录和文件:

  • core:该目录包含了设置支持 MTurk 聊天接口的 AWS 后端的核心代码,以及用于 HIT 创建和许可的代码。

  • tasks:该目录包含了两个第一版提供的示例 MTurk 任务。

  • qa_data_collection:从 Turker 获取问题和答案,给出了 SQuAD 的一个随机段落

  • model_evaluator:在 Reddit 电影对话日志数据集上评估该信息检索基线模型

  • run_mturk.py:用于调用 mturk 核心代码的文件,包含用户指定的任务模块、对话日志模型代理、HIT 的数量和每个 HIT 的回报。

运行示例 MTurk 任务和代理:

  • 在 run_mturk.py 中,去掉任务模块和你想使用的代理类别的注释

  • 对于 create_hits 方法,如有需要,改变 num_hits 和 hit_reward。如果你想仅在 MTurk 沙箱中运行该样本,那么就将 is_sandbox 设置为 True;如果设置为 False,则就可让 Turker 来处理这个工作并得到报酬。

  • 运行 python run_mturk.py

添加你自己的 MTurk 任务和对话模型:

  • 在 mturk/tasks 目录为你自己的任务创建一个新的文件夹

  • 部署 task_config.py,至少在 task_config 目录中包含以下字段:

  • hit_title:关于该 HIT 包含的任务类型的一个短的描述性标题。在 Amazon Mechanical Turk 网站上,该 HIT 标题以搜索结果的形式呈现,并且出现在该 HIT 被提及的任何地方。

  • hit_description:一个 description(描述)包含了该 HIT 所包含的任务类型的详细信息。在 Amazon Mechanical Turk 网站上,该 HIT 描述出现在搜索结果的扩展视图中,并且也会出现在该 HIT 和分配(assignment)屏幕上。

  • hit_keywords:描述该 HIT 的一个或多个词或短语,用逗号隔开。在 Amazon Mechanical Turk 网站上,这些词被用于搜索 HIT。

  • worker_agent_id:一个指示 Turker 在对话中的作用的短名字

  • task_description:一个详细的任务描述,将会出现在 HIT 任务预览页面,并会显示在聊天页面的左侧。支持 HTML 格式。

  • 实现 agents.py,至少有一个从 Agent 扩展的代理类别。

  • 编写你自己的 __init__() 方法以打包你的对话模型代理(具体示例可见 mturk/tasks/model_evaluator/agents.py 文件)。

  • 编写你自己的 act() 方法,其会返回你的对话模型的响应,以及有助于 Turker 了解接下来应该做的事情的帮助文本。

  • 在 run_mturk.py 文件中导入你的任务模块和代理类别,然后运行 python run_mturk.py

团队

ParlAI 目前由 Alexander H. Miller、Will Feng 和 Jason Weston 维护。其他主要贡献者还包括(不完整列表):Adam Fisch、Jiasen Lu、Antoine Bordes、Devi Parikh 和 Dhruv Batra。

证书

ParlAI 采用 BSD 授权。我们也提供了额外的专利授权。

网页开发中,iframe 就像一个个嵌套的“小窗口”,为我们展示来自不同源的网页内容。但如何让这些“小窗口”与主页面进行沟通呢?今天,就来揭秘 iframe 父子页面通信的技巧,让你的网页交互更上一层楼!

跨越“次元壁垒”:iframe 通信挑战

由于浏览器的同源策略限制,来自不同源的 iframe 页面之间无法直接访问彼此的数据和方法。想要实现通信,我们需要借助一些技巧来跨越这道“次元壁垒”。

实战演练:三种常用通信方法

1.postMessage大法:跨域通信的利器

  • parent.postMessage(message, targetOrigin) :父页面发送消息。message : 要发送的消息内容。targetOrigin : 接收消息的窗口的源,用于安全校验。
  • window.addEventListener('message', handler) :子页面监听消息。
  • 父页面 (index.html):
   <iframe src="child.html" id="myIframe"></iframe>
   <script>
       const iframe=document.getElementById('myIframe');
       const message={ type: 'greeting', content: 'Hello from parent!' };

       iframe.onload=()=> {
           iframe.contentWindow.postMessage(message, 'http://localhost:5173'); // 假设子页面地址
       };
   </script>

子页面 (child.html):

   <script>
       window.addEventListener('message', (event)=> {
           if (event.origin !=='http://localhost:8080') return; //  安全校验,确保消息来自预期源
           console.log(event.data); //  输出:{ type: 'greeting', content: 'Hello from parent!' }
       });
   </script>

2. 操作 iframe DOM:简单直接,但有限制

  • 父页面访问子页面DOM: iframe.contentWindow.document
  • 子页面访问父页面DOM: window.parent.document
  • 限制: 仅适用于同源页面。

3.window.name:古老但有效

  • 利用 iframe 的 name 属性传递消息。
  • 优点: 简单,可跨域。
  • 缺点: 传递信息量有限。

源码解析:postMessage 背后的秘密

postMessage 方法是 HTML5 新增的跨文档消息传递机制,它允许不同源的窗口之间进行安全通信。

  • 当父页面调用 postMessage 发送消息时,浏览器会将消息包装成一个 MessageEvent 对象,发送给子页面。
  • 子页面通过监听 message 事件,可以接收到该消息。
  • MessageEvent 对象包含以下属性:data : 消息内容。origin :发送消息的窗口的源。source :发送消息的窗口对象。

总结

iframe 父子页面通信是网页开发中的常见需求,掌握 postMessage 、DOM操作 和 window.name 三种方法,能够帮助你轻松应对各种通信场景,打造更流畅的网页交互体验!

博客将指导您完成在 FastAPI 后端设置 ChatGPT 并将其与 ReactJS 前端无缝集成的过程。

在不断发展的 Web 开发环境中,创建引人入胜的交互式聊天应用程序已成为一项流行且具有挑战性的任务。利用 ChatGPT、FastAPI 和 ReactJS 等强大工具,开发人员可以制作动态和智能的对话界面。本博客将指导您完成在 FastAPI 后端设置 ChatGPT 并将其与 ReactJS 前端无缝集成以创建功能齐全的聊天应用程序的过程。

了解技术

ChatGPT:概述

ChatGPT 由 OpenAI 开发,是一种最先进的语言模型,它利用了 GPT(生成式预训练转换器)架构。它可以根据收到的输入生成类似人类的文本,使其成为创建对话界面的理想候选者。

FastAPI:基于 Python 的 Web 框架

FastAPI 是一个现代、快速(高性能)的 Web 框架,用于基于标准 Python 类型提示使用 Python 3.7+ 构建 API。它易于使用,性能高,并自动生成 API 文档。

ReactJS:用于用户界面的强大 JavaScript 库

由 Facebook 开发的 ReactJS 是一个用于构建用户界面的 JavaScript 库。它允许开发人员创建可重用的 UI 组件,并在基础数据更改时有效地更新视图。React 基于组件的架构使其非常适合构建交互式和动态应用程序。

使用 FastAPI 设置后端

安装 FastAPI 和 Uvicorn

在深入研究 FastAPI 之前,请确保已安装 Python 3.7 或更高版本。您可以使用以下命令安装 FastAPI 和轻量级 ASGI 服务器 Uvicorn:

JavaScript的

pip install fastapi uvicorn

创建 FastAPI 应用程序

FastAPI 遵循声明性语法,允许开发人员使用 Python 类型提示定义 API。创建一个新文件,例如,,然后从导入必要的模块开始:main.py

from fastapi import FastAPI

接下来,初始化 FastAPI 应用程序:

app=FastAPI()

这将设置一个基本的 FastAPI 应用程序。若要测试它,请运行以下命令:

JavaScript的

uvicorn main:app --reload

在浏览器中访问,您应该会看到 FastAPI 文档。http://127.0.0.1:8000

将 ChatGPT 与 FastAPI 集成

要集成 ChatGPT,请安装 OpenAI Python 库:

JavaScript的

pip install openai

在 OpenAI 平台上创建一个帐户并获取 API 密钥。使用此密钥对 OpenAI API 的请求进行身份验证。在您的文件中,导入模块并设置 OpenAI API 密钥:main.pyopenai

import openaibr
br
openai.api_key="your-api-key"

现在,在 FastAPI 中创建一个端点来处理聊天请求:

from fastapi import WebSocketbr
br
@app.websocket("/chat")br
async def chat_endpoint(websocket: WebSocket):br
    await websocket.accept()br
    while True:br
        data=await websocket.receive_text()br
        response=generate_chat_response(data)br
        await websocket.send_text(response)

这里是一个函数,它将用户的消息发送到 ChatGPT 并接收模型的响应。generate_chat_response

处理用于实时通信的 WebSocket 连接

FastAPI 支持 WebSocket 连接进行实时通信。WebSocket 端点是异步的,允许服务器和客户端之间进行持续通信。

在函数中,启动 WebSocket 连接,循环使用 持续侦听传入消息。chat_endpointawait websocket.accept()data=await websocket.receive_text()

然后,服务器使用该函数生成响应,并使用 将其发送回客户端。generate_chat_responseawait websocket.send_text(response)

使用 ReactJS 开发前端

设置 ReactJS 项目

使用 Create React App 创建一个新的 ReactJS 项目:

JavaScript的

npx create-react-app chat-appbr
cd chat-app

这将设置一个基本的 ReactJS 项目。在首选代码编辑器中打开项目。

构建聊天界面

为聊天界面创建一个新组件,例如 .此组件将处理用户输入、显示消息和管理 WebSocket 连接。Chat.js

JavaScript的

import React, { useState, useEffect } from 'react';br
br
const Chat=()=> {br
  const [messages, setMessages]=useState([]);br
  const [input, setInput]=useState('');br
  const [socket, setSocket]=useState(null);br
br
  useEffect(()=> {br
    // Initialize WebSocket connectionbr
    const newSocket=new WebSocket('ws://localhost:8000/chat');br
br
    newSocket.onopen=()=> {br
      console.log('WebSocket connection opened');br
    };br
br
    newSocket.onmessage=(event)=> {br
      // Handle incoming messagesbr
      const newMessages=[...messages, event.data];br
      setMessages(newMessages);br
    };br
br
    setSocket(newSocket);br
br
    // Clean up WebSocket connection on component unmountbr
    return ()=> {br
      newSocket.close();br
    };br
  }, [messages]);br
br
  const sendMessage=()=> {br
    // Send user message to the serverbr
    socket.send(input);br
br
    // Update local state with user messagebr
    const newMessages=[...messages, input];br
    setMessages(newMessages);br
br
    // Clear input fieldbr
    setInput('');br
  };br
br
  return (br
    <div>br
      <div>br
        {messages.map((message, index)=> (br
          <div key={index}>{message}</div>br
        ))}br
      </div>br
      <inputbr
        type="text"br
        value={input}br
        onChange={(e)=> setInput(e.target.value)}br
      />br
      <button onClick={sendMessage}>Send</button>br
    </div>br
  );br
};br
br
export default Chat;

此组件在挂载时初始化 WebSocket 连接,侦听传入消息,并相应地更新 UI。该函数将用户的输入发送到服务器。sendMessage

实现 WebSocket 通信

在组件中,钩子处理 WebSocket 初始化和消息处理。该函数将用户的输入发送到服务器,使用用户的消息更新本地状态,并清除输入字段。Chat.jsuseEffectsendMessage

处理用户输入和显示消息

该组件呈现消息列表和输入字段,供用户键入。当用户发送消息时,它会出现在聊天界面中,从而创建无缝交互。Chat.js

在 FastAPI 和 ReactJS 之间建立通信

定义用于发送和接收消息的 API 端点

在 中,定义用于发送和接收消息的 API 端点:main.py

from fastapi import WebSocketbr
br
@app.websocket("/chat")br
async def chat_endpoint(websocket: WebSocket):br
    await websocket.accept()br
    while True:br
        data=await websocket.receive_text()br
        response=generate_chat_response(data)br
        await websocket.send_text(response)

端点处理 WebSocket 连接,并在服务器和客户端之间持续交换消息。/chat

在 ReactJS 中管理状态

为了管理 ReactJS 中的状态,该组件使用钩子。状态数组保存聊天历史记录,而状态管理用户的当前输入。Chat.jsuseStatemessagesinput

利用WebSocket实现实时通信

FastAPI 和 ReactJS 之间的 WebSocket 通信支持聊天界面的实时更新。当组件挂载并且传入消息触发 UI 更新时,将建立 WebSocket 连接。Chat.js

使用 ChatGPT 增强用户体验

实现用户身份验证

通过实施用户身份验证来保护聊天应用程序。您可以使用令牌或与用户身份验证系统(如 OAuth)集成。确保只有经过身份验证的用户才能访问聊天。

自定义 ChatGPT 响应

定制 ChatGPT 响应以增强用户体验。您可以预处理用户消息、添加上下文并设置响应格式,以使对话更加自然和引人入胜。

处理不同的对话状态

请考虑实现不同的对话状态,例如问候语、查询和告别。根据检测到的状态,调整 ChatGPT 的行为以提供更符合上下文的响应。

部署应用程序

准备 FastAPI 后端以进行部署

在部署 FastAPI 后端之前,请安装其他依赖项:

JavaScript的

pip install gunicorn uvicorn[standard]

创建包含以下内容的文件:main.py

from fastapi import FastAPIbr
from fastapi.staticfiles import StaticFiles br
app=FastAPI() br
app.mount("/static", StaticFiles(directory="static"), name="static") br
# ... (rest of the FastAPI code)

此配置允许 FastAPI 提供静态文件,例如 ReactJS 构建文件。

构建和部署 ReactJS 前端

构建用于生产的 ReactJS 项目:

JavaScript的

npm run build

这将生成一个目录,其中包含优化的生产就绪文件。build

要部署前端,您可以使用静态文件托管服务,如 Netlify、Vercel 或 GitHub Pages。将目录的内容上传到托管平台。build

为生产环境配置环境变量

更新组件中的 WebSocket URL 以指向生产服务器。此外,为敏感信息(如 API 密钥)设置环境变量,并确保安全处理它们。Chat.js

测试和调试

  • 对 FastAPI 后端进行单元测试:为 FastAPI 后端编写单元测试,以确保 API 端点按预期工作。使用诸如自动化测试过程之类的工具。测试不同的方案,包括 WebSocket 连接和消息处理。pytest
  • 测试 ReactJS 组件:利用 Jest 和 React 测试库等测试库来测试 ReactJS 组件。为用户交互、状态更改和 WebSocket 通信编写测试。确保组件正确呈现并优雅地处理不同的场景。
  • 调试实时应用程序中的常见问题:实时应用程序,尤其是使用 WebSocket 的应用程序,可能会遇到连接中断或消息延迟等问题。使用浏览器开发人员工具调试 WebSocket 连接并监视网络活动。在服务器端记录消息以识别潜在问题。

安全注意事项

  • 保护 WebSocket 连接:使用 (WebSocket Secure) 协议实现安全的 WebSocket 连接。这确保了服务器和客户端之间传输的数据是加密的,防止窃听和中间人攻击。wss
  • 安全处理用户身份验证:如果实施用户身份验证,请遵循最佳实践来安全地处理用户凭据。使用 HTTPS 在传输过程中加密数据、哈希和加盐密码,并在服务器端验证用户令牌。
  • 实现 HTTPS 以实现安全数据传输:为 FastAPI 后端和 ReactJS 前端启用 HTTPS 以保护数据传输。从受信任的证书颁发机构获取 SSL 证书,并相应地配置 Web 服务器。

扩展应用程序

  • 负载均衡策略:为了处理增加的流量,请考虑实施负载均衡策略。将传入请求分布在多个服务器上,以防止单个服务器上过载并确保最佳性能。
  • 缓存响应以提高性能:实施缓存机制来存储和检索经常请求的数据。这可以通过减少为重复请求生成响应的需要来显著提高性能。
  • 扩展 ChatGPT 以处理并发请求:如果 ChatGPT for IT 操作遇到高并发请求,请考虑部署模型的多个实例或使用负载均衡来分发请求。优化模型的性能和资源利用率。

结论

当您继续开发聊天应用程序时,请考虑探索其他功能和增强功能。这可能包括实现多媒体支持、用户消息的情绪分析,或与其他 AI 模型集成以丰富对话。

构建具有智能功能的聊天应用程序是一项具有挑战性但有益的工作。继续探索 ChatGPT、FastAPI 和 ReactJS 的功能,以创建创新且用户友好的对话界面。随着技术的进步,创建更复杂、更引人入胜的聊天应用程序的可能性也在增加。

祝您编码愉快!


原文标题:Building a Dynamic Chat Application: Setting Up ChatGPT in FastAPI and Displaying Conversations in ReactJS

原文链接:https://dzone.com/articles/building-a-dynamic-chat-application-setting-up-cha

作者:Atul Naithani

编译:LCR