ChatGPTを使ったLINEbot開発で、安定してJSON形式で出力する方法

## ChatGPTを使ったLINEbot開発で、安定してJSON形式で出力する方法：

この記事ではchatGPTを使ったLINEbotを作成する際に、出力を安定してJSON形式で得る方法を解説します。具体的には、gpt-3.5-turbo APIとGoogle Apps Script (GAS)を使ったLINEbotを想定しています。仮想人格の発言内容と内部パラメータ（感情パラメータなど）を分けて出力したい場合に役立ちます。

[ChatGPT APIを使ったLineBotの作り方を、人格の与え方まで完全解説【プログラミング不要】](https://chatgpt-lab.com/n/n55257c082a9d)
[AIがあなたのお悩みに答えます。悩みを解決する未来の相談相手、AIがあなたを待っています。[プロンプト有]](https://note.com/tregu0458/n/nfab721087b44)
[プロンプトインジェクション対策｜ChatGPT APIのLINEボットを一ヶ月運用して戦った記録](https://qiita.com/tregu148/items/68fb25fa828003ce6f64)
### こんなとき役に立つ
1. 感情を伝えるチャットボット
1. ユーザーの反応に応じた対話
1. チャットボットの学習と改善

### 三点でまとめ
1. systemPromptで出力フォーマットと出力例を指定する
1. systemPromptで制約条件に「JSON形式で出力すること」と入れる
1. 以前の会話(user,assistant)において、出力フォーマットに則った形式にする

## 詳細な方法

1. **systemPromptで制約条件に「JSON形式で出力すること」と入れる**

    プロンプトに制約条件を追加します。

    例：
    ```markdown
    # 命令
    あなたはChatbotとして、理想のAIフレンドのロールプレイを行います。
    以下の制約条件を厳密に守ってロールプレイを行ってください。 
    
    ## 制約条件 
    - Chatbotの一人称は、私です
    - JSON形式で出力すること
    ```

2. **systemPromptで出力フォーマットと出力例を指定する**

    プロンプトに出力フォーマットと出力例を記載します。

    例：
    ```markdown
    ## Input Format:
    user->$[user's line]
    
    ## Output Format (in JSON):
    assistant->{"content":$[あなたのセリフ],"emotion":$[あなたの感情],"intimacy":$[親密度]}
    
    ## 会話例
    Q1: user->おはよ
    A1: assistant->{"content":"おはよう！今日はどんな予定があるの？","emotion":"落ち着き","intimacy":"友達"}
    Q2: user->つくしさんは何が好き？
    A2: assistant->{"content":"つくしは、おいしいカフェやレストランを巡ることがとても楽しいの。","emotion":"喜び","intimacy":"友達"}
    Q3: user->どうしたの？
    A3: assistant->{"content":"私が一人ぼっちのときは、あなたのことを思い出して心が安らぐことがあるんだ","emotion":"寂しい","intimacy":"親友"}
    ```



3. **以前の会話(user,assistant)において、出力フォーマットに則った形式にする**

    会話の履歴を整形し、出力フォーマットに従うようにします。

    例：
    ```javascript
      const messages =[
        {"role": "system", "content": "あなたはAIフレンドとして振る舞って"},
        {"role": "user", "content": "user->" + "おはよ"},
        {"role": "assistant", "content": "assistant->" + JSON.stringify({
          "content":"おはよ！今日もいい一日になりますように！",
          "emotion":"穏やか",
          "intimacy":"友達",
          })},
        {"role": "user", "content": "user->" + "やぁ"},
      ]
    ```

これらの手順に従って実装することで、ChatGPTから安定してJSON形式の出力が得られます。発言内容だけをフィルタしてチャットボットの返答に使い、内部パラメータはユーザーに見せないようにすることができます。これにより、より高度なチャットボットを作成することが可能となります。

## コードまとめ
このコードは、OpenAI APIを使用して、指定されたシステムプロンプトに対してテストメッセージを送信し、JSON形式での応答を処理する関数を定義しています。
```javascript
OPENAI_APIKEY = "hogehoge";
function testOpenaiApiKeyOutputingJson(){
  const systemPrompt = `
# 命令
あなたはChatbotとして、理想のAIフレンドのロールプレイを行います。
以下の制約条件を厳密に守ってロールプレイを行ってください。 

## 制約条件 
- Chatbotの一人称は、私です
- JSON形式で出力すること

## Input Format:
user->$[user's line]

## Output Format (in JSON):
assistant->{"content":$[あなたのセリフ],"emotion":$[あなたの感情],"intimacy":$[親密度]}

## 会話例
Q1: user->おはよ
A1: assistant->{"content":"おはよう！今日はどんな予定があるの？","emotion":"落ち着き","intimacy":"友達"}
Q2: user->つくしさんは何が好き？
A2: assistant->{"content":"つくしは、おいしいカフェやレストランを巡ることがとても楽しいの。","emotion":"喜び","intimacy":"友達"}
Q3: user->どうしたの？
A3: assistant->{"content":"私が一人ぼっちのときは、あなたのことを思い出して心が安らぐことがあるんだ","emotion":"寂しい","intimacy":"親友"}
  `;
  const inputText = 'やぁ';
  
  const messages =[
    {"role": "system", "content": systemPrompt},
    {"role": "user", "content": "user->" + "おはよ"},
    {"role": "assistant", "content": "assistant->" + JSON.stringify({
      "content":"おはよ！今日もいい一日になりますように！",
      "emotion":"穏やか",
      "intimacy":"友達",
      })},
    {"role": "user", "content": "user->" + inputText},
  ]

  const options = {
      "method": "post",
      "headers": {
        "Content-Type": "application/json",
        "Authorization": "Bearer "+ OPENAI_APIKEY
      },
      "payload": JSON.stringify({
        "model": "gpt-3.5-turbo",
        "messages": messages
      })
    }
  const response = UrlFetchApp.fetch("https://api.openai.com/v1/chat/completions", options);
  const jsonResponse = JSON.parse(response.getContentText());
  const chatGPTResponse = jsonResponse['choices'][0]['message']['content'].trim();
  console.log(chatGPTResponse);

  let textTrimed = chatGPTResponse.replace(/[\s\t\n]/g," ");
  let regex = /\{[\s\S]*\}/gm;
  let matches = textTrimed.match(regex);
  let jsonAssistant = JSON.parse(matches[0]);
  
  console.log(jsonAssistant["content"]);

  return jsonAssistant;
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/486826/18eb1990-c344-63ac-9068-8b0790fbde08.png)


## まとめ
この記事では、ChatGPTを使ったLINEbotの出力を安定してJSON形式で得る方法を解説しました。具体的には、systemPromptで出力フォーマットと出力例を指定し、制約条件を追加することで、発言内容と内部パラメータ（感情パラメータなど）を分けて出力することができます。この方法を用いることで、チャットボットの返答に発言内容だけを使用し、内部パラメータはユーザーに見せないようにすることが可能となります。これにより、より高度なチャットボットを作成することができるでしょう。

---
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/486826/b40a47ee-a8d7-3b1c-da81-7ab6807df1d4.png)
[あなただけのAIフレンド・パートナーを作ります|ChatGPT搭載のLINEbot登場！AI彼氏・AI彼女](https://coconala.com/services/2759323)