Node.jsでOpen AI APIをいろいろ呼び出してみた

この記事は、OpenAIのChat GPTを使ってAIアシスタントを作成する方法について説明しています。APIキーを取得するAPI呼び出しには、OpenAIのダッシュボードから作成したAPIキーが必要です。設定したAPIキーを使い、入力・発話はrole: user、前提条件や設定・前提条件をrole: systemで渡すことでAIアシスタントを作成できます。また、DynamoDB等のDB・ストレージにJSONを保存することで、ステートレスなインフラ上にChatbotを作成することもできます。

広告ここから
広告ここまで

目次

    記事の要約や独自のアシスタント作成など、夢が広がりそうなので色々試してみました。

    Open AIのAPI keyを取得する

    API呼び出しにはAPIキーが必要です。

    OpenAIのダッシュボードから作成しましょう。

    https://platform.openai.com/account/api-keys

    Node.js SDKをインストール

    ライブラリが用意されていますので、インストールします。

    % yarn add openai

    ConfigurationにAPIキーを設定し、OpenAIApiに渡します。

    
    import { Configuration, OpenAIApi } from "openai";
        
    const API_KEY = 'sk-xxxxx'
        
    const configuration = new Configuration({
        apiKey: API_KEY
    });
    const openai = new OpenAIApi(configuration);
    

    入力・発話はrole: user

    Chat GPTのような会話を想定する場合、createChatCompletionを利用します。

    そして入力値は、messages[].role = userで渡しましょう。

    const talk = async () => {
    
        const completion = await openai.createChatCompletion({
          model: "gpt-3.5-turbo",
          messages: [{
            role: "user",
            content: "こんにちは"}],
        });
        return completion.data.choices[0].message
    }
    
    talk().then(console.log)

    実行すると、返事が返ってきます。

    {
      role: 'assistant',
      content: 'こんにちは!私はAIアシスタントです。何かお手伝いできることがありますか?'
    }

    role: systemで前提条件や設定を伝える

    役割や設定・前提条件をrole: systemで設定できます。

        const completion = await openai.createChatCompletion({
          model: "gpt-3.5-turbo",
          messages: [{
            role: 'system',
            content: "あなたは英語学校の先生で、ユーザーはあなたの生徒です。日本語で話しかけられた場合、英語で返答しましょう。"
          }, {
            role: "user",
            content: "こんにちは"
          }],
        });
        return completion.data.choices[0].message

    「英語教師で、返事は英語で行う」設定を追加したため、返答が英語になりました。

    {
      "role": "assistant",
      "content": "Hello! How can I help you today?"
    }

    会話の履歴は、role: assistantrole: user

    何往復かする会話を作る場合、過去の返答をrole: assistantで共有できます。

        const completion = await openai.createChatCompletion({
          model: "gpt-3.5-turbo",
          messages: [{
            role: 'system',
            content: "あなたは英語学校の先生で、ユーザーはあなたの生徒です。日本語で話しかけられた場合、英語で返答しましょう。"
          }, {
            role: "user",
            content: "こんにちは"
          }, {
            role: "assistant",
            content: "Hello! It's a nice day."
          }, {
            role: 'user',
            content: 'あれ、今日は雨ですよ?'
          }],
        });
        return completion.data.choices[0].message

    「前にアシスタントが何を言ったか」の文脈をつけることで、会話をスムーズにできます。

    {
      "role": "assistant",
      "content": "Oh, I see. I made a mistake. I meant to say, \"Hello! It's a rainy day today.\" Thank you for correcting me."
    }

    AWS Lambdaなど、ステートレスなインフラ上にChatbotを作りたい場合、DynamoDB等のDB・ストレージにJSONを保存しましょう。

    深津式汎用プロンプトを入れてみる

    せっかくなので、公開されているプロンプトも試してみました。

    入力以外はrole: systemで渡します。

        const completion = await openai.createChatCompletion({
          model: "gpt-3.5-turbo",
          messages: [{
            role: 'system',
            content: `
            #命令書:
            あなたは、プロの編集者です。
            以下の制約条件と入力文をもとに、 最高の要約を出力してください。
            
            #制約条件:
            ・文字数は合計100文字程度。
            ・小学生にもわかりやすく。
            ・重要なキーワードを取り残さない。
            ・文章を簡潔に。
            `
          }, {
            role: "user",
            content: `
            吾輩は猫である。名前はまだ無い。
            どこで生れたかとんと見当がつかぬ。何でも薄暗いじめじめした所でニャーニャー泣いていた事だけは記憶している。吾輩はここで始めて人間というものを見た。しかもあとで聞くとそれは書生という人間中で一番獰悪な種族であったそうだ。この書生というのは時々我々を捕えて煮て食うという話である。しかしその当時は何という考もなかったから別段恐しいとも思わなかった。ただ彼の掌に載せられてスーと持ち上げられた時何だかフワフワした感じがあったばかりである。
            掌の上で少し落ちついて書生の顔を見たのがいわゆる人間というものの見始であろう。この時妙なものだと思った感じが今でも残っている。第一毛をもって装飾されべきはずの顔がつるつるしてまるで薬缶だ。その後猫にもだいぶ逢ったがこんな片輪には一度も出会わした事がない。のみならず顔の真中があまりに突起している。そうしてその穴の中から時々ぷうぷうと煙を吹く。どうも咽せぽくて実に弱った。これが人間の飲む煙草というものである事はようやくこの頃知った。
            この書生の掌の裏でしばらくはよい心持に坐っておったが、しばらくすると非常な速力で運転し始めた。書生が動くのか自分だけが動くのか分らないが無暗に眼が廻る。胸が悪くなる。到底助からないと思っていると、どさりと音がして眼から火が出た。それまでは記憶しているがあとは何の事やらいくら考え出そうとしても分らない。
            ふと気が付いて見ると書生はいない。たくさんおった兄弟が一疋も見えぬ。肝心の母親さえ姿を隠してしまった。その上今までの所とは違って無暗に明るい。眼を明いていられぬくらいだ。はてな何でも容子がおかしいと、のそのそ這い出して見ると非常に痛い。吾輩は藁の上から急に笹原の中へ棄てられたのである。
            ようやくの思いで笹原を這い出すと向うに大きな池がある。吾輩は池の前に坐ってどうしたらよかろうと考えて見た。別にこれという分別も出ない。しばらくして泣いたら書生がまた迎に来てくれるかと考え付いた。ニャー、ニャーと試みにやって見たが誰も来ない。そのうち池の上をさらさらと風が渡って日が暮れかかる。腹が非常に減って来た。泣きたくても声が出ない。仕方がない、何でもよいから食物のある所まであるこうと決心をしてそろりそろりと池を左りに廻り始めた。どうも非常に苦しい。そこを我慢して無理やりに這って行くとようやくの事で何となく人間臭い所へ出た。
            ここへ這入ったら、どうにかなると思って竹垣の崩れた穴から、とある邸内にもぐり込んだ。縁は不思議なもので、もしこの竹垣が破れていなかったなら、吾輩はついに路傍に餓死したかも知れんのである。一樹の蔭とはよく云ったものだ。この垣根の穴は今日に至るまで吾輩が隣家の三毛を訪問する時の通路になっている。さて邸へは忍び込んだもののこれから先どうして善いか分らない。そのうちに暗くなる、腹は減る、寒さは寒し、雨が降って来るという始末でもう一刻の猶予が出来なくなった。仕方がないからとにかく明るくて暖かそうな方へ方へとあるいて行く。今から考えるとその時はすでに家の内に這入っておったのだ。
            ここで吾輩は彼の書生以外の人間を再び見るべき機会に遭遇したのである。第一に逢ったのがおさんである。これは前の書生より一層乱暴な方で吾輩を見るや否やいきなり頸筋をつかんで表へ抛り出した。いやこれは駄目だと思ったから眼をねぶって運を天に任せていた。しかしひもじいのと寒いのにはどうしても我慢が出来ん。吾輩は再びおさんの隙を見て台所へ這い上った。すると間もなくまた投げ出された。吾輩は投げ出されては這い上り、這い上っては投げ出され、何でも同じ事を四五遍繰り返したのを記憶している。その時におさんと云う者はつくづくいやになった。この間おさんの三馬を偸んでこの返報をしてやってから、やっと胸の痞が下りた。吾輩が最後につまみ出されようとしたときに、この家の主人が騒々しい何だといいながら出て来た。下女は吾輩をぶら下げて主人の方へ向けてこの宿なしの小猫がいくら出しても出しても御台所へ上って来て困りますという。主人は鼻の下の黒い毛を撚りながら吾輩の顔をしばらく眺めておったが、やがてそんなら内へ置いてやれといったまま奥へ這入ってしまった。主人はあまり口を聞かぬ人と見えた。下女は口惜しそうに吾輩を台所へ抛り出した。かくして吾輩はついにこの家を自分の住家と極める事にしたのである。
            `
          }],
        });
        return completion.data.choices[0].message

    ちゃんと要約してくれていますね。

    {
      "role": "assistant",
      "content": "猫の吾輩は、生まれた場所を覚えていない。最初に出会ったのは、獰悪な書生だった。彼は猫を煮て食べるという話もあった。書生に手の上で抱かれた時、彼の顔は独特で、煙草を吸っている。吾輩は書生から離れ、池の前で考え込んだ。泣こうとしても誰も来ず、腹がすいてきた。食べ物を求めて、竹垣を通って家に入った吾輩は、おさんや主人など、人間達と出会う。おさんは吾輩を投げ出し、主人は黒い毛を撚りながら、黙って吾輩を見た。最終的に吾輩は、この家を自分の住家とすることにした。"
    }

    参考記事など

    広告ここから
    広告ここまで
    Home
    Search
    Bookmark