Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
自GitHub
機(jī)器之心編譯
參與:吳攀、晏奇
Facebook 近日在 GitHub 上開源了一個(gè)可用于在多種開放可用的對(duì)話數(shù)據(jù)集上訓(xùn)練和評(píng)估人工智能模型的框架 ParlAI,機(jī)器之心在本文中對(duì)這一項(xiàng)目的 README.md 內(nèi)容進(jìn)行了編譯介紹。項(xiàng)目地址如下:
官網(wǎng)地址:http://parl.ai
GitHub:https://github.com/facebookresearch/ParlAI
ParlAI(讀音為 par-lay)是一個(gè)用于對(duì)話人工智能研究的框架,是用 Python 實(shí)現(xiàn)的。該框架的目標(biāo)是為研究者提供:
一個(gè)用于訓(xùn)練和測(cè)試對(duì)話模型的統(tǒng)一框架
一次性在許多數(shù)據(jù)集上進(jìn)行多任務(wù)訓(xùn)練
無縫集成 Amazon Mechanical Turk,以便數(shù)據(jù)收集和人工評(píng)估
這第一個(gè)版本支持超過 20 種任務(wù),也囊括了許多流行的數(shù)據(jù)集,比如 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 訓(xùn)練神經(jīng)模型的示例,其包含了在 GPU 上的批訓(xùn)練或在 CPU 上的 hogwild 訓(xùn)練。另外使用 Theano 或 TensorFlow 也是很直接的。
我們的目標(biāo)是讓那些在它們之上訓(xùn)練的任務(wù)和智能體能夠以一種基于社區(qū)的方式成長(zhǎng)。
這個(gè)版本還是早期的 Beta 版,使用過程中可能會(huì)有一些冒險(xiǎn),或遇到一些難題。
目標(biāo)
用于評(píng)估模型的統(tǒng)一框架
可按需下載任務(wù)/數(shù)據(jù)集,且為它們提供了同樣簡(jiǎn)單的接口
統(tǒng)一的數(shù)據(jù)集輸入和評(píng)估框架/標(biāo)準(zhǔn)
agents/ 目錄鼓勵(lì)研究者提交他們的訓(xùn)練代碼,以便在該 repo 中分享
協(xié)助重現(xiàn)
最終目標(biāo)是實(shí)現(xiàn)通用的對(duì)話,包括許多不同的技能
無縫地組合模擬的和真實(shí)的語(yǔ)言任務(wù)
鼓勵(lì)多任務(wù)模型的開發(fā)和評(píng)估
有助于減少模型在特定數(shù)據(jù)集上的過擬合
最終目標(biāo)是實(shí)現(xiàn)與人類的真實(shí)對(duì)話
通過 Mechanical Turk,在與人類的實(shí)時(shí)對(duì)話上訓(xùn)練和評(píng)估
只需簡(jiǎn)單的設(shè)置,就可以連接 Mechanical Turk 上的人類與你的對(duì)話代理
允許比較不同研究組的 Turk 實(shí)驗(yàn)
能夠引導(dǎo)一個(gè)可與人類交互的對(duì)話模型的數(shù)據(jù)集配置
激勵(lì)構(gòu)建將進(jìn)入本 repo 的新數(shù)據(jù)集
特性
所有的數(shù)據(jù)集都像自然對(duì)話:?jiǎn)我桓袷?API
既有固定數(shù)據(jù)集(會(huì)話日志),也有交互式任務(wù)(在線/RL)
既有真實(shí)任務(wù),也有模擬任務(wù)
支持其它媒體,比如 VQA 中的視覺
可以使用 Mechanical Turk 來運(yùn)行/收集數(shù)據(jù)/評(píng)估
Python 框架
PyTorch 的訓(xùn)練示例
可使用 zmq 與其它非 Python 的工具箱對(duì)話,給出了 Lua Torch 的示例
支持模型的 hogwild 訓(xùn)練和批訓(xùn)練
基本示例
從「1k training examples」bAbI 任務(wù)的任務(wù) 1 中展示 10 個(gè)隨機(jī)樣本:
python examples/display_data.py -t babi:task1k:1
同時(shí)在 bAbI 任務(wù)的多任務(wù)與 SQuAD 數(shù)據(jù)集上展示 100 個(gè)隨機(jī)樣本:
python examples/display_data.py -t babi:task1k:1,squad -n 100
在 Movies Subreddit 數(shù)據(jù)集的驗(yàn)證集上評(píng)估 IR 基線模型:
python examples/eval_model.py -m ir_baseline -t "#moviedd-reddit" -dt valid
給出該 IR 基線模型的預(yù)測(cè):
python examples/display_model.py -m ir_baseline -t "#moviedd-reddit" -dt valid
在「10k training examples」bAbI 任務(wù) 1 上訓(xùn)練一個(gè)簡(jiǎn)單的基于 CPU 的記憶網(wǎng)絡(luò),其使用了 Hogwild(需要 zmq 和 Lua Torch),有 8 個(gè)線程(Python 進(jìn)程):
python examples/memnn_luatorch_cpu/full_task_train.py -t babi:task10k:1 -n 8
在 SQuAD 數(shù)據(jù)集上訓(xùn)練一個(gè)「注意 LSTM」模型,其中批大小為 32(PyTorch 和 regex)
python examples/drqa/train.py -t squad -b 32
要求
ParlAI 目前支持 Python3。
核心模組的依賴內(nèi)容參見 requirement.txt。其中部分模型(在 parlai/agents 中)有進(jìn)一步要求,比如需要 PyTorch 或 Lua Torch——所有這些模組的要求都可以參見 requirements_ext.txt 這個(gè)文檔。
安裝 ParlAI
首先,復(fù)制該 repository,然后進(jìn)入復(fù)制的目錄。
鏈接安裝:運(yùn)行 python setup.py develop 來將復(fù)制的目錄鏈接到你的 site-packages。如果你打算根據(jù)你的運(yùn)行修改任何的 parlai 代碼或者提交一個(gè) pull request,特別是如果你想在 repository 上添加另外的任務(wù)的話,那么我們推薦上述安裝過程。所有需要的數(shù)據(jù)都將被下載到 ./data,而且,如果要求任何模型的文件(目前僅是 memnn 模型),它們都將被下載到 ./downloads。
復(fù)制后的安裝內(nèi)容(僅將 parlai 用作一個(gè)依賴項(xiàng)):運(yùn)行 python setup.py install 來將內(nèi)容復(fù)制到你的 site-packages 文件夾。所有數(shù)據(jù)都會(huì)被默認(rèn)下載到 python 的 site-packages 文件夾中(你可以通過命令行來改寫路徑),不過一旦對(duì)代碼作出了任何改動(dòng),你都需要重新運(yùn)行一次安裝。如果你僅想將 parlai 作為一個(gè)依賴項(xiàng)使用(比如用于訪問任務(wù)或核心代碼),那么目前這樣就可以了。但是如果你想要清除下載的數(shù)據(jù),那么刪除 site-packages/parlai 中的 data 和 downloads 文件夾(如果可以的話)。
Worlds, agents 和 teachers
ParlAI 中的主要概念(類):
world——它定義了環(huán)境(它可以非常簡(jiǎn)單,可以僅兩個(gè)代理相互對(duì)話)。
agent——這是世界里的一個(gè)代理,比如一個(gè)學(xué)習(xí)器。(存在很多學(xué)習(xí)器。)
teacher——這是一種可以和學(xué)習(xí)者對(duì)話的代理,它用于實(shí)現(xiàn)前面提到的任務(wù)。
在定義完 ParlAI 中的 world 和 agent 之后,一個(gè)主 loop 可被用來訓(xùn)練、測(cè)試或顯示,它叫做 world.parley() 函數(shù)。我們?cè)谧筮叺拿姘逯薪o出了個(gè)實(shí)例的主要骨架,parley() 函數(shù)真實(shí)的代碼寫在右側(cè)面板。
Actions 和 Observations
所有的 agent(包括 teacher)都以簡(jiǎn)單的格式互相對(duì)話——observation/action 對(duì)象(這是一個(gè) python 字典)。這被用于傳遞 agent 之間的文本、標(biāo)簽和獎(jiǎng)勵(lì)。這和當(dāng)在對(duì)話(行動(dòng))或聽(觀察)時(shí)是同類對(duì)象,但是不同視角(在這些字段中有不同的值)。這些領(lǐng)域如下所述:
盡管'text'(文本)領(lǐng)域?qū)缀蹩赡茉谌拷涣鳎╡xchange)中被使用,但是技術(shù)上來說,基于你的數(shù)據(jù)集,這些領(lǐng)域中的每個(gè)都是可選的。
對(duì)于一個(gè)固定的監(jiān)督式學(xué)習(xí)數(shù)據(jù)集(比如 bAbI)來說,一個(gè)典型的從數(shù)據(jù)集進(jìn)行交流(exchange)例子可以像如下這樣(該測(cè)試集不包含標(biāo)簽):
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
}...
代碼
代碼被設(shè)置進(jìn)了幾個(gè)主要目錄:
core:它包含了框架的首要代碼。
agents:包含了可以憑不同任務(wù)交互的代理(比如:機(jī)器學(xué)習(xí)模型)。
example:包含了不同循環(huán)的一些基本樣例(構(gòu)建詞典、訓(xùn)練/評(píng)價(jià)、顯示數(shù)據(jù))。
tasks:包含了可來自于 ParlAI 的不同任務(wù)的代碼。
mturk:包含了設(shè)置 Mechanical Turk 的代碼和作為樣例的 MTurk 任務(wù)。
下面我們會(huì)更具體地說明每個(gè)目錄,我們根據(jù)依賴項(xiàng)(dependency)來組織行文。
Core 庫(kù)
core 庫(kù)包含了如下文件:
agent.py:這個(gè)文件包含了一些可被你自己模型延展的基本 agent。
Agent:這是所有 agent 的基本類,實(shí)現(xiàn)了 act() 方法,該方法接受一個(gè)觀察表(table)并且返回一個(gè)作為回復(fù)的表。
Teacher:它是 Agent 的子代,也實(shí)現(xiàn)了針對(duì)返回量度(returning metric)的報(bào)告方法。任務(wù)實(shí)現(xiàn)了 Teacher 這個(gè)類。
MultiTaskTeacher:它創(chuàng)造了一個(gè)基于「任務(wù)字符串」的 teacher 集,該集可以傳遞給 Teacher。在其中它創(chuàng)建了多個(gè) teacher 并且在它們之間交替輪換。
create_task_teacher:它從一段給定的任務(wù)字符串中實(shí)例化了一個(gè) teacher(比如「babi:task:1」或「squad」)。
build_data.py:用于設(shè)置任務(wù)數(shù)據(jù)的基本功能。如果你的文件系統(tǒng)需要不同的功能,你可以覆蓋它。
dialog_teacher.py:包含了用于和固定交談(chat)日志進(jìn)行對(duì)話(dialog)的一個(gè)基本 teacher 類,同時(shí)它也包含了一個(gè)用于儲(chǔ)存數(shù)據(jù)的數(shù)據(jù)類(data class)。
dict.py:包含了從觀察中構(gòu)建一般 NLP 風(fēng)格字典的代碼。
DictionaryAgent:在一個(gè)字典中跟蹤索引和詞頻的 agent,可以將一個(gè)句子解析成它字典或 back 中的指數(shù)(indice)。
fbdialog_teacher.py:包含了一個(gè) teacher 類,該類實(shí)現(xiàn)了一個(gè) setup_data 函數(shù),這個(gè)函數(shù)用 Facebook 的 Dialog 數(shù)據(jù)格式來解析數(shù)據(jù)。
metrics.py:計(jì)算對(duì)話的評(píng)價(jià)量度,比如對(duì)排名的量度等。
params.py:用 argparse 來為 ParlAI 解釋命令行 argument。
thread_utils.py:用于 Hogwild 多線程(多重處理)的工具類/函數(shù)。
SharedTable:提供一個(gè)鎖保護(hù)、記憶分享、類字典的用于追蹤度量的的界面。
worlds.py:包含了一套用于內(nèi)部開展任務(wù)的基本 world。
World:所有 world 的基本類,實(shí)現(xiàn)了 parley,shutdown,__enter__,和__exit__。
DialogPartnerWorld:用于雙 agent 回合交流的默認(rèn) world。
MultiAgentDialogWorld:用于兩到多個(gè) agent 的循環(huán)(round-robin)回合 agent 交流。
HogwildWorld:當(dāng)使用多線程(多重處理)時(shí)。這是用于設(shè)置一個(gè)對(duì)每個(gè)線程而言分別獨(dú)立的 world 的默認(rèn) world。
Agents 目錄
agents 目錄包含了已被認(rèn)可進(jìn)入 ParlAI 框架用于分享的 agent。目前有這些可用的目錄:
drqa:這是一個(gè)很周全的 LSTM 模型,它叫「DrQA」(問答博士,論文地址:https://arxiv.org/abs/1704.00051)。它用 PyTorch 框架實(shí)現(xiàn),在 SQuAD 數(shù)據(jù)集上,它得到的結(jié)果相比其它模型更具競(jìng)爭(zhēng)力。
memnn:它是在 Lua Torch 中用于端到端記憶網(wǎng)絡(luò)的代碼。
remote_agent:連接 ZMQ 的任意 agent 的基本類(memnn_luatorch_cpu 就使用這個(gè))。
ir_baseline:簡(jiǎn)單的信息檢索基準(zhǔn)(baseline),它用 TFIDF-權(quán)重匹配為候選者的反饋評(píng)分。
repeat_label:僅重復(fù)(repeating)發(fā)送給它的所有數(shù)據(jù)的基本類(如連接(piping)到一個(gè)文件、調(diào)試)。
實(shí)例
這個(gè)目錄包含了部分基本循環(huán)的具體例子。
base_train.py:一個(gè)非常簡(jiǎn)單的例子,展示了一個(gè)使用默認(rèn) Agent 親本類的訓(xùn)練/驗(yàn)證循環(huán)的輪廓。
display_data.py:使用 agent.repeat_label 來顯示來命令行給出的特定任務(wù)的數(shù)據(jù)。
display_model.py:顯示對(duì)一個(gè)給定模型在命令行給出的特定任務(wù)之上的預(yù)測(cè)。
eval_model.py:使用命名后的 agent 來計(jì)算一個(gè)命令行給出的特定任務(wù)的評(píng)價(jià)量度(evaluation metric)數(shù)據(jù)。
build_dict.py:使用 core.dict.DictionaryAgent 建立一個(gè)來自命令行給出的特定任務(wù)的 dictionary。
memnn_luatorch_cpu:展示了一些在幾個(gè)數(shù)據(jù)集上訓(xùn)練端到端記憶網(wǎng)絡(luò)的例子。
drqa:展示了如何在 SQuAD 訓(xùn)練集上訓(xùn)練一個(gè)周全的 LSTM「DrQA」模型(論文地址:https://arxiv.org/abs/1704.00051)。
任務(wù)
這個(gè)第一版本支持超過 20 種任務(wù),包括 SQuAD、bAbI tasks、MCTest、WikiQA、WebQuestions、SimpleQuestions、WikiMovies、QACNN、QADailyMail、CBT、BookTest、bAbI Dialog tasks、Ubuntu、OpenSubtitles、Cornell Movie 和 VQA-COCO2014 等流行的數(shù)據(jù)集。
我們的第一版包含以下數(shù)據(jù)集,見下圖左欄;獲取它們也非常簡(jiǎn)單,只需在命令行的選項(xiàng)中指定對(duì)應(yīng)任務(wù)的名稱即可,如右欄的數(shù)據(jù)集展示實(shí)用程序所示。查閱當(dāng)前完整任務(wù)列表請(qǐng)?jiān)L問:https://github.com/facebookresearch/ParlAI/blob/master/parlai/tasks/task_list.py
在 ParlAI 中選擇一個(gè)任務(wù)非常簡(jiǎn)單,只需要在命令行中指定它既可,如上圖(右)所示。如果該數(shù)據(jù)集之前沒有被使用過,那 ParlAI 將會(huì)自動(dòng)下載它。因?yàn)樵?ParlAI 中,所有的數(shù)據(jù)集的處理方式都是一樣的(使用單個(gè)對(duì)話 API),所以原則上一個(gè)對(duì)話代理可以在這些數(shù)據(jù)集之間切換訓(xùn)練和測(cè)試。還不止于此,你可以簡(jiǎn)單地通過提供一個(gè)逗號(hào)分隔的列表來一次性指定許多任務(wù)(多任務(wù)),比如命令「-t babi,squad」可以使用這兩個(gè)數(shù)據(jù)集,甚至還可以使用「-t #qa」命令一次性指定所有的 QA 數(shù)據(jù)集或使用「-t #all」一次性指定 ParlAI 中的每一個(gè)任務(wù)。我們的目標(biāo)是使其可以輕松地創(chuàng)建和評(píng)估非常豐富的對(duì)話模型。
每個(gè)任務(wù)文件夾包含:
build.py 文件,用于設(shè)置任務(wù)的數(shù)據(jù)(下載數(shù)據(jù)等,僅在第一次請(qǐng)求時(shí)完成,如果某個(gè)任務(wù)從未被使用,那么就不會(huì)下載它)。
agents.py 文件,包含了默認(rèn)的或特定的教師(teacher)類別,可被 core.create_task 用來從命令行參數(shù)上實(shí)例化這些類別(如有需要)。
worlds.py 文件,是可選的,可用于需要定義新環(huán)境或復(fù)雜環(huán)境的任務(wù)。
要添加你自己的任務(wù):
(可選)實(shí)現(xiàn) build.py 以下載任何所需的數(shù)據(jù)
實(shí)現(xiàn) agents.py,至少包含一個(gè) DefaultTeacher(擴(kuò)展 Teacher 或它的一個(gè)衍生)
如果你的數(shù)據(jù)是 FB Dialog 格式的,那么屬于 FbDialogTeacher 類別
如果不是 FB Dialog 格式:
如果你的數(shù)據(jù)是基于文本的,你可以使用擴(kuò)展的 DialogTeacher,并因此要使用 core.data.TextData,在這種情況下,你僅需要編寫你自己的 setup_data 函數(shù),其可根據(jù)在 core.data 中所描述的格式而在數(shù)據(jù)之上提供一個(gè) iterable.
如果你的數(shù)據(jù)使用了其它字段,那么就要編寫你自己的 act() 方法,其提供了當(dāng)你的任務(wù)每次被調(diào)用時(shí)的觀察。
MTurk
ParlAI 的一個(gè)重要方面是與 Mechanical Turk 的無縫集成,可用于數(shù)據(jù)收集、訓(xùn)練和評(píng)估。在 ParlAI 中,人類 Turker 也被視為代理(agent),因此在一個(gè)標(biāo)準(zhǔn)的框架中可以進(jìn)行人-人、人-bot、多人和多 bot 群聊等形式的對(duì)話,也可以按照需求切換角色,而無需對(duì)代理的代碼進(jìn)行修改。這是因?yàn)?Turker 也可以使用觀察/動(dòng)作(observation/action)詞典中的字段來通過同樣接口的一個(gè)版本進(jìn)行接收和發(fā)送。我們?cè)谶@第一版中提供了兩個(gè)示例——收集數(shù)據(jù)和人類對(duì) bot 的評(píng)估。
mturk 庫(kù)包含以下目錄和文件:
core:該目錄包含了設(shè)置支持 MTurk 聊天接口的 AWS 后端的核心代碼,以及用于 HIT 創(chuàng)建和許可的代碼。
tasks:該目錄包含了兩個(gè)第一版提供的示例 MTurk 任務(wù)。
qa_data_collection:從 Turker 獲取問題和答案,給出了 SQuAD 的一個(gè)隨機(jī)段落
model_evaluator:在 Reddit 電影對(duì)話日志數(shù)據(jù)集上評(píng)估該信息檢索基線模型
run_mturk.py:用于調(diào)用 mturk 核心代碼的文件,包含用戶指定的任務(wù)模塊、對(duì)話日志模型代理、HIT 的數(shù)量和每個(gè) HIT 的回報(bào)。
運(yùn)行示例 MTurk 任務(wù)和代理:
在 run_mturk.py 中,去掉任務(wù)模塊和你想使用的代理類別的注釋
對(duì)于 create_hits 方法,如有需要,改變 num_hits 和 hit_reward。如果你想僅在 MTurk 沙箱中運(yùn)行該樣本,那么就將 is_sandbox 設(shè)置為 True;如果設(shè)置為 False,則就可讓 Turker 來處理這個(gè)工作并得到報(bào)酬。
運(yùn)行 python run_mturk.py
添加你自己的 MTurk 任務(wù)和對(duì)話模型:
在 mturk/tasks 目錄為你自己的任務(wù)創(chuàng)建一個(gè)新的文件夾
部署 task_config.py,至少在 task_config 目錄中包含以下字段:
hit_title:關(guān)于該 HIT 包含的任務(wù)類型的一個(gè)短的描述性標(biāo)題。在 Amazon Mechanical Turk 網(wǎng)站上,該 HIT 標(biāo)題以搜索結(jié)果的形式呈現(xiàn),并且出現(xiàn)在該 HIT 被提及的任何地方。
hit_description:一個(gè) description(描述)包含了該 HIT 所包含的任務(wù)類型的詳細(xì)信息。在 Amazon Mechanical Turk 網(wǎng)站上,該 HIT 描述出現(xiàn)在搜索結(jié)果的擴(kuò)展視圖中,并且也會(huì)出現(xiàn)在該 HIT 和分配(assignment)屏幕上。
hit_keywords:描述該 HIT 的一個(gè)或多個(gè)詞或短語(yǔ),用逗號(hào)隔開。在 Amazon Mechanical Turk 網(wǎng)站上,這些詞被用于搜索 HIT。
worker_agent_id:一個(gè)指示 Turker 在對(duì)話中的作用的短名字
task_description:一個(gè)詳細(xì)的任務(wù)描述,將會(huì)出現(xiàn)在 HIT 任務(wù)預(yù)覽頁(yè)面,并會(huì)顯示在聊天頁(yè)面的左側(cè)。支持 HTML 格式。
實(shí)現(xiàn) agents.py,至少有一個(gè)從 Agent 擴(kuò)展的代理類別。
編寫你自己的 __init__() 方法以打包你的對(duì)話模型代理(具體示例可見 mturk/tasks/model_evaluator/agents.py 文件)。
編寫你自己的 act() 方法,其會(huì)返回你的對(duì)話模型的響應(yīng),以及有助于 Turker 了解接下來應(yīng)該做的事情的幫助文本。
在 run_mturk.py 文件中導(dǎo)入你的任務(wù)模塊和代理類別,然后運(yùn)行 python run_mturk.py
團(tuán)隊(duì)
ParlAI 目前由 Alexander H. Miller、Will Feng 和 Jason Weston 維護(hù)。其他主要貢獻(xiàn)者還包括(不完整列表):Adam Fisch、Jiasen Lu、Antoine Bordes、Devi Parikh 和 Dhruv Batra。
證書
ParlAI 采用 BSD 授權(quán)。我們也提供了額外的專利授權(quán)。
網(wǎng)頁(yè)開發(fā)中,iframe 就像一個(gè)個(gè)嵌套的“小窗口”,為我們展示來自不同源的網(wǎng)頁(yè)內(nèi)容。但如何讓這些“小窗口”與主頁(yè)面進(jìn)行溝通呢?今天,就來揭秘 iframe 父子頁(yè)面通信的技巧,讓你的網(wǎng)頁(yè)交互更上一層樓!
由于瀏覽器的同源策略限制,來自不同源的 iframe 頁(yè)面之間無法直接訪問彼此的數(shù)據(jù)和方法。想要實(shí)現(xiàn)通信,我們需要借助一些技巧來跨越這道“次元壁壘”。
<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'); // 假設(shè)子頁(yè)面地址
};
</script>
子頁(yè)面 (child.html):
<script>
window.addEventListener('message', (event)=> {
if (event.origin !=='http://localhost:8080') return; // 安全校驗(yàn),確保消息來自預(yù)期源
console.log(event.data); // 輸出:{ type: 'greeting', content: 'Hello from parent!' }
});
</script>
postMessage 方法是 HTML5 新增的跨文檔消息傳遞機(jī)制,它允許不同源的窗口之間進(jìn)行安全通信。
iframe 父子頁(yè)面通信是網(wǎng)頁(yè)開發(fā)中的常見需求,掌握 postMessage 、DOM操作 和 window.name 三種方法,能夠幫助你輕松應(yīng)對(duì)各種通信場(chǎng)景,打造更流暢的網(wǎng)頁(yè)交互體驗(yàn)!
在不斷發(fā)展的 Web 開發(fā)環(huán)境中,創(chuàng)建引人入勝的交互式聊天應(yīng)用程序已成為一項(xiàng)流行且具有挑戰(zhàn)性的任務(wù)。利用 ChatGPT、FastAPI 和 ReactJS 等強(qiáng)大工具,開發(fā)人員可以制作動(dòng)態(tài)和智能的對(duì)話界面。本博客將指導(dǎo)您完成在 FastAPI 后端設(shè)置 ChatGPT 并將其與 ReactJS 前端無縫集成以創(chuàng)建功能齊全的聊天應(yīng)用程序的過程。
ChatGPT 由 OpenAI 開發(fā),是一種最先進(jìn)的語(yǔ)言模型,它利用了 GPT(生成式預(yù)訓(xùn)練轉(zhuǎn)換器)架構(gòu)。它可以根據(jù)收到的輸入生成類似人類的文本,使其成為創(chuàng)建對(duì)話界面的理想候選者。
FastAPI 是一個(gè)現(xiàn)代、快速(高性能)的 Web 框架,用于基于標(biāo)準(zhǔn) Python 類型提示使用 Python 3.7+ 構(gòu)建 API。它易于使用,性能高,并自動(dòng)生成 API 文檔。
由 Facebook 開發(fā)的 ReactJS 是一個(gè)用于構(gòu)建用戶界面的 JavaScript 庫(kù)。它允許開發(fā)人員創(chuàng)建可重用的 UI 組件,并在基礎(chǔ)數(shù)據(jù)更改時(shí)有效地更新視圖。React 基于組件的架構(gòu)使其非常適合構(gòu)建交互式和動(dòng)態(tài)應(yīng)用程序。
在深入研究 FastAPI 之前,請(qǐng)確保已安裝 Python 3.7 或更高版本。您可以使用以下命令安裝 FastAPI 和輕量級(jí) ASGI 服務(wù)器 Uvicorn:
JavaScript的
pip install fastapi uvicorn
FastAPI 遵循聲明性語(yǔ)法,允許開發(fā)人員使用 Python 類型提示定義 API。創(chuàng)建一個(gè)新文件,例如,,然后從導(dǎo)入必要的模塊開始:main.py
from fastapi import FastAPI
接下來,初始化 FastAPI 應(yīng)用程序:
app=FastAPI()
這將設(shè)置一個(gè)基本的 FastAPI 應(yīng)用程序。若要測(cè)試它,請(qǐng)運(yùn)行以下命令:
JavaScript的
uvicorn main:app --reload
在瀏覽器中訪問,您應(yīng)該會(huì)看到 FastAPI 文檔。http://127.0.0.1:8000
要集成 ChatGPT,請(qǐng)安裝 OpenAI Python 庫(kù):
JavaScript的
pip install openai
在 OpenAI 平臺(tái)上創(chuàng)建一個(gè)帳戶并獲取 API 密鑰。使用此密鑰對(duì) OpenAI API 的請(qǐng)求進(jìn)行身份驗(yàn)證。在您的文件中,導(dǎo)入模塊并設(shè)置 OpenAI API 密鑰:main.pyopenai
import openaibr
br
openai.api_key="your-api-key"
現(xiàn)在,在 FastAPI 中創(chuàng)建一個(gè)端點(diǎn)來處理聊天請(qǐng)求:
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)
這里是一個(gè)函數(shù),它將用戶的消息發(fā)送到 ChatGPT 并接收模型的響應(yīng)。generate_chat_response
FastAPI 支持 WebSocket 連接進(jìn)行實(shí)時(shí)通信。WebSocket 端點(diǎn)是異步的,允許服務(wù)器和客戶端之間進(jìn)行持續(xù)通信。
在函數(shù)中,啟動(dòng) WebSocket 連接,循環(huán)使用 持續(xù)偵聽傳入消息。chat_endpointawait websocket.accept()data=await websocket.receive_text()
然后,服務(wù)器使用該函數(shù)生成響應(yīng),并使用 將其發(fā)送回客戶端。generate_chat_responseawait websocket.send_text(response)
使用 Create React App 創(chuàng)建一個(gè)新的 ReactJS 項(xiàng)目:
JavaScript的
npx create-react-app chat-appbr
cd chat-app
這將設(shè)置一個(gè)基本的 ReactJS 項(xiàng)目。在首選代碼編輯器中打開項(xiàng)目。
為聊天界面創(chuàng)建一個(gè)新組件,例如 .此組件將處理用戶輸入、顯示消息和管理 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;
此組件在掛載時(shí)初始化 WebSocket 連接,偵聽傳入消息,并相應(yīng)地更新 UI。該函數(shù)將用戶的輸入發(fā)送到服務(wù)器。sendMessage
在組件中,鉤子處理 WebSocket 初始化和消息處理。該函數(shù)將用戶的輸入發(fā)送到服務(wù)器,使用用戶的消息更新本地狀態(tài),并清除輸入字段。Chat.jsuseEffectsendMessage
該組件呈現(xiàn)消息列表和輸入字段,供用戶鍵入。當(dāng)用戶發(fā)送消息時(shí),它會(huì)出現(xiàn)在聊天界面中,從而創(chuàng)建無縫交互。Chat.js
在 中,定義用于發(fā)送和接收消息的 API 端點(diǎn):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)
端點(diǎn)處理 WebSocket 連接,并在服務(wù)器和客戶端之間持續(xù)交換消息。/chat
為了管理 ReactJS 中的狀態(tài),該組件使用鉤子。狀態(tài)數(shù)組保存聊天歷史記錄,而狀態(tài)管理用戶的當(dāng)前輸入。Chat.jsuseStatemessagesinput
FastAPI 和 ReactJS 之間的 WebSocket 通信支持聊天界面的實(shí)時(shí)更新。當(dāng)組件掛載并且傳入消息觸發(fā) UI 更新時(shí),將建立 WebSocket 連接。Chat.js
通過實(shí)施用戶身份驗(yàn)證來保護(hù)聊天應(yīng)用程序。您可以使用令牌或與用戶身份驗(yàn)證系統(tǒng)(如 OAuth)集成。確保只有經(jīng)過身份驗(yàn)證的用戶才能訪問聊天。
定制 ChatGPT 響應(yīng)以增強(qiáng)用戶體驗(yàn)。您可以預(yù)處理用戶消息、添加上下文并設(shè)置響應(yīng)格式,以使對(duì)話更加自然和引人入勝。
請(qǐng)考慮實(shí)現(xiàn)不同的對(duì)話狀態(tài),例如問候語(yǔ)、查詢和告別。根據(jù)檢測(cè)到的狀態(tài),調(diào)整 ChatGPT 的行為以提供更符合上下文的響應(yīng)。
在部署 FastAPI 后端之前,請(qǐng)安裝其他依賴項(xiàng):
JavaScript的
pip install gunicorn uvicorn[standard]
創(chuàng)建包含以下內(nèi)容的文件: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 提供靜態(tài)文件,例如 ReactJS 構(gòu)建文件。
構(gòu)建用于生產(chǎn)的 ReactJS 項(xiàng)目:
JavaScript的
npm run build
這將生成一個(gè)目錄,其中包含優(yōu)化的生產(chǎn)就緒文件。build
要部署前端,您可以使用靜態(tài)文件托管服務(wù),如 Netlify、Vercel 或 GitHub Pages。將目錄的內(nèi)容上傳到托管平臺(tái)。build
更新組件中的 WebSocket URL 以指向生產(chǎn)服務(wù)器。此外,為敏感信息(如 API 密鑰)設(shè)置環(huán)境變量,并確保安全處理它們。Chat.js
當(dāng)您繼續(xù)開發(fā)聊天應(yīng)用程序時(shí),請(qǐng)考慮探索其他功能和增強(qiáng)功能。這可能包括實(shí)現(xiàn)多媒體支持、用戶消息的情緒分析,或與其他 AI 模型集成以豐富對(duì)話。
構(gòu)建具有智能功能的聊天應(yīng)用程序是一項(xiàng)具有挑戰(zhàn)性但有益的工作。繼續(xù)探索 ChatGPT、FastAPI 和 ReactJS 的功能,以創(chuàng)建創(chuàng)新且用戶友好的對(duì)話界面。隨著技術(shù)的進(jìn)步,創(chuàng)建更復(fù)雜、更引人入勝的聊天應(yīng)用程序的可能性也在增加。
祝您編碼愉快!
原文標(biāo)題: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
*請(qǐng)認(rèn)真填寫需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。