ごく最近まで、チャットボットを作ろうと思えば、「自然言語処理」(NLP)を使ってユーザーが何を求めているかを理解・解釈し、バックエンドのロジックを使ってその要求を満たそうとしていました。DialogflowやMicrosoft Bot frameworkのようなソリューションは、機械学習に基づいた会話AIを提供し、チャットボットを作成する開発者に伝統的に人気があります。
OpenAIとOpenAIのChatGPTは、人工知能を搭載したAIチャットボットをこれまで以上に簡単に作成できるようにします。OpenAIの動力源である大規模言語モデル(LLM)は公開データセットに基づいているため、公開知識ベースに存在すると合理的に予想されるあらゆる情報を提供することで、アプリのユーザーエクスペリエンスを簡単に向上させることができます。
PubNubは、以下のような幅広い業界やユースケースのためのリアルタイム体験を提供します。 カスタマーサポートおよび アプリ内チャットこれらのリアルタイム体験はすべて、ユーザーが読めるメッセージやソリューションに関するメタデータなどのデータによって提供されています。
実際の使用例をいくつか挙げてみましょう:
よくあるカスタマーサポートの質問に対する回答を提供する
既存のデータを追加コンテンツで補強する。例えば、指定された場所の近くで食事ができる場所を提案する。
メッセージ履歴に基づいて会話の要約を提供する。
私たちは 記事その古い記事は今でも正しいが、業界の動きは非常に速く、数ヶ月というのは長い。
この記事では、私たちの PubNubショーケースアプリケーションの中で動いているものと同じような、OpenAIで動くチャットボットの作り方を説明します。
ハイレベルなアーキテクチャ
ChatGPTのようなチャットボットを作成するには、 OpenAIのチャットAPIを使用し、アカウントにサインアップして APIキーを作成する必要があります。 OpenAIのAPIはRESTエンドポイントとしてアクセスできるので、ほとんどのプログラミング言語から呼び出すことができます。
PubNubからデータを抽出し、チャットボットとの会話を開始または継続するための最良の方法は、Functionsを使用することです。 Functionsは、Node.JSで実行されるサーバレスJavaScriptコンテナを提供し、チャットメッセージの受信など、PubNubネットワーク上でイベントが発生するたびにビジネスロジックを実行することができます。 PubNub Functionsは、リアルタイムオンザフライ言語翻訳、冒涜フィルタリング、またはOpenAIのようなサードパーティのサービスを呼び出すために頻繁に使用されます。
この例は次のように動作します:
既存のチャットアプリケーションはPubNubを使ってリアルタイムでメッセージを送受信している。
PubNubファンクションは、特定のチャネルに送信されたメッセージをリッスンします。
単一のメッセージだけではChatGPTにコンテキストを提供しないので、進行中の対話を可能にするために会話履歴の一部もキャッシュされます。
PubNub関数はOpenAI APIを呼び出し、レスポンスを取得します。
レスポンスはチャットボットに関連付けられているPubNubチャンネルに公開されます。
下のシーケンス図を見てください:
50以上のSDKを持つPubNubは、大多数のアプリケーションをサポートすることができ、メッセージはPubNubネットワーク上のチャットボットを表すチャネルに公開されます。
PubNubの関数は、チャネル上でパブリッシュイベントが発生した後に呼び出されるように構成されています。 メッセージを受信すると、チャネルの履歴が取得され、会話にいくつかのコンテキストが提供されます。この履歴は、ユーザー入力といくつかの追加のコンテキストと一緒に、チャット完了APIを介してChatGPTに提供されます。
ChatGPT APIは会話の流れに適したレスポンスを生成します。
PubNub関数内で、ChatGPTから応答が受信され、それが解析されてPubNubネットワークに パブリッシュされます。
PubNubからのメッセージを受信するようにサブスクライブしたアプリケーションは、チャットボットの応答を表示します。
PubNub関数の設定
以下のようにPubNub関数を作成します:
前提条件:PubNubを初めて利用する場合は、ドキュメントに従ってアカウントを設定するか、ツアーに参加してPubNubがどのようなものかを理解してください。
管理ダッシュボードに移動します
左側のメニューから
関数を
選択し、関数を作成したい適切なキーセットを選択します。新規モジュールの
作成を選択します。Module NameとModule Descriptionを入力し、キーセットを選択して
Createを
クリックします。作成したモジュールを選択します。
Create New Functionを
選択します。ファンクションに名前を付け、イベントタイプとして
After PublishまたはFireを
選択します。 このファンクションはメッセージがPubNubに送信された後に呼び出されます。この場合、OpenAIに送信するメッセージのコピーをキャプチャします。関数の種類についての詳細はドキュメントを参照してください。関数のチャンネルは、OpenAI に送信したいメッセージを公開しているチャンネルと一致させる必要があります。 ここではワイルドカードを使うことができるので、例えば
chatgpt.*
は、chatgpt を開始するすべてのチャンネルと一致します。 この関数は同時に複数の人と会話したいので、ワイルドカードを使うことで、アクティブな会話に参加しているユーザを分けることができ、適切なチャンネルで応答できるようになります。複数の人が同時にOpenAIと会話している場合、PubNubはあなたの関数の複数のインスタンスを作成します。 例えば、chatgpt.daveと
chatgpt.simonは
2つの異なるチャンネルですが、どちらもchatgpt.*で
リッスンしているPubNub関数を呼び出します。PubNubがどのようにチャンネルワイルドカードを処理するかはドキュメントで詳しく説明しています。マイシークレットを
選択し、OpenAIAPIキー用の新しいシークレットを作成します。以下のコードでは、このシークレットがOPENAI_API_KEYという
名前であると仮定しています。
以下はOpenAI / ChatGPTを呼び出すPubNub関数の例です。
const pubnub = require('pubnub');
const xhr = require('xhr');
const vault = require('vault');
// Process all messages posted to the private ChatGPT channel
// This will be unique for each user, so chat is 1:1 with ChatGPT
export default request => {
const inboundChannel = request.channels[0];
if (request.message.content.type == "text" && request.message.sender != "OpenAI")
{
// user’s query
let naturalCommand = request.message.content.text;
// Always provide OpenAI with some context of how you want questions answered
let historicalMsgs =
[{"role": "system", "content": "You are a helpful assistant, expert in PubNub"}];
return getOpenaiApiKey().then(apikey => {
// Read the last messages from the conversation to provide conversation context
return pubnub.history({
channel: inboundChannel,
count: 10
}).then((response) => {
response['messages'].forEach((value, index) => {
// The message role will vary depending on whether it was sent or received
if (value.entry.sender && value.entry.sender == "OpenAI")
historicalMsgs.push({"role": "assistant",
"content": value.entry.content.text})
else
historicalMsgs.push({"role": "user",
"content": value.entry.content.text})
});
// Depending on timing, last published message may or may not yet be stored
if (historicalMsgs[historicalMsgs.length - 1].content != naturalCommand)
{
historicalMsgs.push({"role": "user",
"content": naturalCommand});
}
return openAI(naturalCommand, historicalMsgs).then(aiResponse => {
// Respond back by publishing the message to PubNub
pubnub.publish({
channel: inboundChannel, // In the showcase, this is unique per user
message: {
content: {
type: "text",
text: aiResponse
},
sender: "OpenAI",
},
});
return request.ok();
});
})
});
}
return request.ok();
};
// Get API Key for OpenAI
// Key is populated via Vault Secret Manager
let OPENAI_API_KEY = null;
function getOpenaiApiKey() {
// Use cached key
if (OPENAI_API_KEY) {
return new Promise(resolve => resolve(OPENAI_API_KEY));
}
// Fetch key from vault
return vault.get("OPENAI_API_KEY").then(apikey => {
OPENAI_API_KEY = apikey;
return new Promise(resolve => resolve(OPENAI_API_KEY));
});
}
// API Call to OpenAI asking the AI to run functions if it thinks it needs to
function openAI(naturalCommand, msgs) {
// Generate Function Instructions for the AI
const url = 'https://api.openai.com/v1/chat/completions';
const http_options = {
'method': 'POST',
'headers': {
"Content-Type": "application/json",
"Authorization": `Bearer ${OPENAI_API_KEY}`,
},
'body': JSON.stringify({
"model": "gpt-3.5-turbo",
"messages": msgs,
"max_tokens": 300
}),
timeout: 9500, // PubNub functions timeout limit can be raised if needed
retries: 0
};
return xhr.fetch(url, http_options).then((resp) => {
const body = JSON.parse(resp.body);
return body.choices[0].message.content;
})
.catch((err) => {
console.log(err);
return "Timed out. Please try again or ask a simpler question";
});
}
OpenAI APIを呼び出す際の実用的な考慮事項
チャット補完APIのプロパティ
この記事で紹介するコードはOpenAI Chat Completion APIを使用していますが、上記で紹介するよりも多くの設定が可能です。
streamを
trueに指定すると、OpenAIのレスポンスがサーバから送信されたイベントのデータストリームとして返されます。 実用的には、ChatGPTのウェブインタフェースがどのように動作するかに似て、ユーザはより即時のレスポンスを見ることができるので、これは知覚的な待ち時間を減らすことができます。
model
は、応答を生成するために使用される言語モデルを指定します。 API は、異なる機能と価格帯を持つモデルファミリによって提供され、モデルは頻繁にアップグレードされ、新しいモデルが追加されます。
max_tokensは
、APIが出力を生成する際に使用するトークンの数を制限します。 一般的に、トークンの数が少なければ少ないほど、出力は複雑でなくなり、コンテキストの追跡も少なくなりますが、レスポンスはより速く提供されます。
メッセージの役割は
、メッセージの作成者を指定することができます。 この記事の例では、OpenAPIにいくつかの指示を提供するためにsystemを
使用し、エンドユーザーによって送信されたメッセージにはuserを
使用し、OpenAIによって以前に提供された応答にはassistantを
使用しています。
このモデルは、temperature
/top_p
、frequency_penality
、presence_penalty
を指定することで、さらに微調整することができます。 これらの詳細については、 OpenAPI のドキュメントを参照してください。
このAPIでは、モデルの機能を拡張するカスタム関数を定義して指定することもできますが、このブログの範囲外です。 もっと詳しく知りたい場合は、ChatGPTがあなたの代わりにPubNubにパブリッシュする方法を説明した 別の投稿があります。"また、ChatGPTが独自のビジネスAPIを呼び出すことを許可して、例えば、製品情報や注文ステータス情報を顧客に直接提供することもできます。
チャットにコンテキストを提供する
HTTPリクエストはステートレスなので、OpenAIと長く続く会話をするためには、APIにコンテキストを与え、これまでの会話を説明し、その会話の周りのメタデータを提供する方法が必要です。
チャット完了APIは メッセージの
配列を受け付け、AIモデルが曖昧な質問から意味を導き出すことを可能にします。 この例を考えてみましょう:
> ユーザー] 地球の大きさは?
> OpenAI] 地球の直径は約12,742kmです。
> [User]地球の重さは?
> OpenAI] 地球の質量は約5.97x10^24kgです。
明らかに、"How heavy is it "という質問に答えるために、AIは "it "が何であるかを理解する必要があった。
PubNubを利用したチャットボットを構築する際には、どの程度の会話コンテキストを提供すべきかを決定する必要があります。 PubNubの機能を使用している場合、チャネルのメッセージ履歴全体にアクセスすることができ、この例では会話の前の10件のメッセージを提供しています。 もちろん、ニーズに応じて、必要であればもっと多くのメッセージを提供することもできます:
// Read in the last messages from the conversation to provide some context to Chat GPT
pubnub.history({
channel: inboundChannel,
count: 10
}).then((response) => {
response['messages'].forEach((value, index) => {
if (value.entry.sender && value.entry.sender == "ChatGPT")
historicalMsgs.push({"role": "assistant", "content": value.entry.content.text})
else
historicalMsgs.push({"role": "user", "content": value.entry.content.text})
});
PubNub内にチャットのコンテキストをすでに持っていれば、OpenAIにそのコンテキストを提供するのは簡単です。 メッセージがOpenAIに送信されたか、OpenAIから受信されたかによって役割が
異なることに注意してください。
長時間クエリ
ChatGPTのようなチャットボットを開発し、AIモデルによって使用されるパラメータを設定するとき、クエリに対する予想応答時間を考慮してください。 デフォルトでは、PubNub関数は、呼び出しごとに10秒の最大実行時間を提供し、サポートに連絡することによって増加させることができます。 一般的に、ユーザの質問に応答するのに時間がかかりすぎるチャットボットは、ユーザによって否定的に認識されるので、前述のように、応答性と能力の間のバランスを達成するためにモデルのパラメータをダイヤルすることは良いプラクティスです。
OpenAIのユースケースによっては、秒単位ではなく分単位でのレスポンスを期待することができます。 OpenAIをPubNubソリューションに統合していて、レスポンスの時間がデフォルトのFunctionランタイムを超えることが予想される場合は、弊社にご連絡ください。
要約すると
PubNubとOpenAI / ChatGPTの両方を組み合わせることで、あらゆるオンライン体験にAIとチャットを追加する非常に強力なリアルタイムソリューションを迅速に作成することができます。
始める準備ができたら、私たちの管理ダッシュボードにアクセスして、無料のPubNubキーのセットをサインアップしてください。 私たちは、あらゆる業界をカバーする多くのチュートリアルや デモを用意しています。また、PubNubショーケース(Githubでも利用可能)で、OpenAIを利用したチャットボットの例をご覧ください。
目次
ハイレベルなアーキテクチャPubNub関数を設定するPubNub関数を次のように作成します:OpenAI / ChatGPTPを呼び出すPubNub関数の例は次のとおりです:OpenAI APIChatCompletion APIプロパティチャットへのコンテキストの提供長時間実行するクエリまとめ
PubNubはどのようにお役に立てるでしょうか?
この記事はPubNub.comに掲載されたものです。
PubNubのプラットフォームは、開発者がWebアプリ、モバイルアプリ、IoTデバイス向けにリアルタイムのインタラクティブ機能を構築、提供、管理できるように支援します。
私たちのプラットフォームの基盤は、業界最大かつ最もスケーラブルなリアルタイムエッジメッセージングネットワークです。世界15か所以上で8億人の月間アクティブユーザーをサポートし、99.999%の信頼性を誇るため、停電や同時実行数の制限、トラフィックの急増による遅延の問題を心配する必要はありません。
PubNubを体験
ライブツアーをチェックして、5分以内にすべてのPubNub搭載アプリの背後にある本質的な概念を理解する
セットアップ
PubNubアカウントにサインアップすると、PubNubキーに無料ですぐにアクセスできます。
始める
PubNubのドキュメントは、ユースケースやSDKに関係なく、あなたを立ち上げ、実行することができます。
Top comments (0)