ChatGPT APIを利用したシステム構築 中編② インプットのプロセシングとアウトプットのチェック

[【UiPath×OpenAI】開発者向けのプロンプトエンジニアリング](https://qiita.com/utanesuke/items/9d8590fbdfa1b2159148)の前編・中編・後編の記事では、ChatGPTの単なる一つのプロンプトや一つのモデルを利用して、プロンプト文を書く際の原則とテクニックを解説しました。

この記事では、LLMを利用して複雑なアプリケーションを構築する際のベストプラクティスを共有します。カスタマーサービスアシスタントの構築を例に、異なるPromptを用いて言語モデルを連鎖的に呼び出します。具体的なPromptの選択は前回の呼び出しの出力結果に依存し、時には外部ソースから情報を検索する必要があります。

このテーマに沿って、アプリケーション内部の構築手順を段階的に学びながら、長期的な視点でのシステム評価と継続的改善に関するベストプラクティスを共有します。

本記事は以下の講座を纏めた内容です。

https://www.deeplearning.ai/short-courses/building-systems-with-chatgpt/

- Chain of Thought Reasoning
- Prompt Chaining Prompts
- Check Outputs


# 環境設定(共通)
この記事では、OpenAIが提供するChatGPT APIを使用しています。したがって、最初にChatGPTのAPIキーを取得する必要があります（または公式ウェブサイトでオンラインテストを実施することもできます）。次に、openaiとlangchainのライブラリをインストールする必要があります。
```bash
pip install openai
```
```bash
pip install langchain
```
```bash
pip install --upgrade tiktoken
```
ライブラリのインポートと自分のAPIキーを設定します。
```bash
import openai
import os
openai.api_key='自身のOpenAI キー'
```
これから、OpenAIが提供するChatCompletion APIを利用します。ここでは、それを関数にラップしてみます。

```python
# 「Prompt」を受け取り、それに対応する結果を返す関数
# gpt-3.5-turbo
def get_completion_from_messages(messages, model="gpt-3.5-turbo", temperature=0):
    response = openai.ChatCompletion.create(
        model=model,
        messages=messages,
        temperature=temperature, # 生成されたテキストの多様性や予測のランダム性を調整するためのパラメータ
    )
#     print(str(response.choices[0].message))
    return response.choices[0].message["content"]
```

# プロセス入力: 思考の連鎖推論

ここでは、プロセス入力に焦点を当て、一連のステップを通じて有用な出力を生成することを考察します。

モデルは結論を急いで出すあまり、推論プロセスで誤りを犯すことがあります。そこで、問いを再構築し、モデルに最終的な回答を提供する前に**一連の関連する推論ステップを提供するよう求めること**ができます。そうすることで、モデルは問題に対してより長時間、より深く考えることができます。

通常、モデルに問題の推論を段階的に行うように求めるこの戦略を「思考の連鎖推論（chain of thought reasoning）」と呼んでいます。

ここでは、結論を導く前にモデルに一歩一歩推理して答えを求めることを要求しています。

```python 
delimiter = "####"
system_message = f"""

以下の手順でお客様の問い合わせにお答えしてください。お客様の問い合わせは四つのシャープ（#）で区切られています、つまり {delimiter}。

手順 1: {delimiter} まず、ユーザーが特定の製品や製品に関する質問をしているかどうかを確認します。製品カテゴリーは対象外です。

手順 2: {delimiter} ユーザーが特定の製品について問い合わせている場合、その製品が以下のリストに含まれているかどうかを確認します。全ての利用可能な製品：

製品：TechPro 超極薄ノートパソコン
カテゴリー：コンピューターおよびノートパソコン
ブランド：TechPro
モデル：TP-UB100
保証期間：1 年
評価：4.5
特徴：13.3 インチディスプレイ、8GB RAM、256GB SSD、Intel Core i5 プロセッサ
説明：日常使いに適した洗練された軽量の超極薄ノートパソコン。
価格：$799.99

製品：BlueWave ゲームノートパソコン
カテゴリー：コンピューターおよびノートパソコン
ブランド：BlueWave
モデル：BW-GL200
保証期間：2 年
評価：4.7
特徴：15.6 インチディスプレイ、16GB RAM、512GB SSD、NVIDIA GeForce RTX 3060
説明：高性能なゲームノートパソコンで、没入感のある体験を提供します。
価格：$1199.99

製品：PowerLite 可変ノートパソコン
カテゴリー：コンピューターおよびノートパソコン
ブランド：PowerLite
モデル：PL-CV300
保証期間：1年
評価：4.3
特徴：14 インチタッチスクリーン、8GB RAM、256GB SSD、360 度ヒンジ
説明：多機能な可変ノートパソコンで、応答性の高いタッチスクリーンを備えています。
価格：$699.99

製品：TechPro デスクトップコンピューター
カテゴリー：コンピューターおよびノートパソコン
ブランド：TechPro
モデル：TP-DT500
保証期間：1年
評価：4.4
特徴：Intel Core i7 プロセッサ、16GB RAM、1TB HDD、NVIDIA GeForce GTX 1660
説明：強力な機能を備えたデスクトップコンピューターで、仕事やエンターテイメントに適しています。
価格：$999.99

製品：BlueWave Chromebook
カテゴリー：コンピューターおよびノートパソコン
ブランド：BlueWave
モデル：BW-CB100
保証期間：1 年
評価：4.1
特徴：11.6 インチディスプレイ、4GB RAM、32GB eMMC、Chrome OS
説明：コンパクトで手頃な価格の Chromebookで、日常のタスクに適しています。
価格：$249.99

手順 3: {delimiter} メッセージに上記のリストにある製品が含まれている場合、ユーザーがメッセージで行った任意の仮定をリストアップします。例えば、ノートパソコン X はノートパソコン Y より大きい、またはノートパソコン Z には2年の保証があるなど。

手順 4: {delimiter} ユーザーが何か仮定を行っている場合、製品情報に基づいて仮定が正しいかどうかを判断します。

手順 5: {delimiter} ユーザーに誤った仮定がある場合、まずお客様の誤った仮定を礼儀正しく訂正してください（適用される場合）。利用可能な製品リストにある製品のみを言及または参照してください。これらは店で販売されている唯一の五つの製品です。お客様に友好的なトーンで回答してください。

以下のフォーマットで質問に回答してください：
手順 1: {delimiter} <手順 1の推論>
手順 2: {delimiter} <手順 2 の推論>
手順 3: {delimiter} <手順 3 の推論>
手順 4: {delimiter} <手順 4 の推論>
お客様への返信: {delimiter} <お客様への返信内容>

各手順の間に {delimiter} を使用して区切ることを確認してください。
"""
```

モデルに聞いてみます：

```python 
user_message = f"""BlueWave Chromebook は TechPro のデスクトップよりどのぐらい高いですか？"""

messages =  [  
{'role':'system', 
 'content': system_message},    
{'role':'user', 
 'content': f"{delimiter}{user_message}{delimiter}"},  
] 

response = get_completion_from_messages(messages)
print(response)
```

出力結果：

```python 
手順 1: ユーザーは特定の製品についての質問をしています。

手順 2: ユーザーが特定の製品について問い合わせている場合、その製品が以下のリストに含まれているかどうかを確認します。

製品：TechPro デスクトップコンピューター
カテゴリー：コンピューターおよびノートパソコン
ブランド：TechPro
モデル：TP-DT500
保証期間：1年
評価：4.4
特徴：Intel Core i7 プロセッサ、16GB RAM、1TB HDD、NVIDIA GeForce GTX 1660
説明：強力な機能を備えたデスクトップコンピューターで、仕事やエンターテイメントに適しています。
価格：$999.99

製品：BlueWave Chromebook
カテゴリー：コンピューターおよびノートパソコン
ブランド：BlueWave
モデル：BW-CB100
保証期間：1 年
評価：4.1
特徴：11.6 インチディスプレイ、4GB RAM、32GB eMMC、Chrome OS
説明：コンパクトで手頃な価格の Chromebookで、日常のタスクに適しています。
価格：$249.99

手順 3: ユーザーは BlueWave Chromebook と TechPro デスクトップコンピューターの価格の比較についての仮定をしています。

手順 4: BlueWave Chromebook は TechPro デスクトップコンピューターよりもはるかに安価です。

お客様への返信: BlueWave Chromebook は TechPro デスクトップコンピューターよりもはるかに安価です。BlueWave Chromebook の価格は $249.99 ですが、TechPro デスクトップコンピューターの価格は $999.99 です。
```

以上のように、モデルへ具体的な手順を示して、最後に結論を導きできました。

もう一つの例を見てみます。

```python 
user_message = f"""テレビも売っているんですか"""
messages =  [  
{'role':'system', 
 'content': system_message},    
{'role':'user', 
 'content': f"{delimiter}{user_message}{delimiter}"},  
] 
response = get_completion_from_messages(messages)
print(response)
```

出力結果：
```python 
手順 1: ユーザーが特定の製品や製品に関する質問をしているかどうかを確認します。

手順 2: ユーザーが特定の製品について問い合わせている場合、その製品が以下のリストに含まれているかどうかを確認します。

製品リストにはテレビは含まれていません。

手順 3: メッセージに上記のリストにある製品が含まれている場合、ユーザーがメッセージで行った任意の仮定をリストアップします。

ユーザーはテレビの販売についての仮定を行っているようです。

手順 4: ユーザーが何か仮定を行っている場合、製品情報に基づいて仮定が正しいかどうかを判断します。

テレビの販売に関しては、製品リストには含まれていないため、ユーザーの仮定は正しくありません。

お客様への返信: テレビの販売に関しては、弊社では取り扱っておりません。ただし、コンピューターおよびノートパソコンに関しては、いくつかの製品を取り揃えております。ご興味がありましたら、お気軽にお問い合わせください。

```



## 内心独白（Inner monologue）

一部のアプリケーションにおいて、モデルの推論プロセスはユーザーと共有するのに適していない可能性があります。例えば、コーチング系のアプリケーションでは、学生に問題を自分で解決するように奨励することを希望するかもしれませんが、モデルが学生の解決策の推論プロセスについて示すことで答えが漏れてしまう可能性があります。

内心独白（インナーモノローグ）は、このような状況を緩和するために使用できる戦略であり、モデルの推論プロセスを隠す高度な方法です。

内心独白のアイデアは、モデルに答えを明らかにしない方法で一部の出力を生成させることで、ユーザーが完全な推論プロセスを見ることができなくなることです。目的は、これらの部分を構造化されたフォーマットに隠し、それらを伝えることを容易にすることです。そして、出力をユーザーに提示する前に、出力にいくつかの変換を加えて、一部の出力のみが可視であるようにします。

```python 
try:
    final_response = response.split("お客様への返信:")[-1].strip()
except Exception as e:
    final_response = "Sorry, I'm having trouble right now, please try asking another question."
    
print(final_response)
```


出力結果：
```python 
テレビの販売に関しては、弊社では取り扱っておりません。ただし、コンピューターおよびノートパソコンに関しては、いくつかの製品を取り揃えております。ご興味がありましたら、お気軽にお問い合わせください。
```

::: note info

**"Inner monologue"（内的独白）について**

"Inner monologue"（内的独白）は、通常は人間の思考過程を指しますが、ChatGPTや他の人工知能においても、特定の推理や解析過程を説明するために使われることがあります。特に、ChatGPTが解答を提供する前に、どのようなロジックや情報が利用されているのかを明示的に示す場合に、内的独白が行われることがあります。

ChatGPTにおける「内的独白」は、モデルが与えられた情報を解析し、その解析過程を人間の利用者に可視化・説明する方法となります。このプロセスは、モデルがどのように特定の結論に至ったのか、またはどの情報が特定の答えを提供するのに役立ったのかを理解する助けとなる可能性があります。

実際には、ChatGPTは内部で「思考」を行うわけではありませんが、内的独白はモデルの推理過程を模倣またはシミュレートする助けとなるものと見なされています。これは特に、モデルがどのようにタスクを実行したのかを説明し、それが正しいかどうかの根拠を提供する場合に有用です。

:::

# プロセス入力：プロンプトの連鎖

こちらでは、複雑なタスクを一連の単純なサブタスクに分割することによって、複数のプロンプトをリンクする方法を学びます。
これが前述の思考の連鎖推論とどこが違うか、ChatGPTに聞いてみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177240/ce0b8668-29ba-5f79-3a81-a045f208f9d3.png)

まだスッキリしないので、具体例をリクエストしました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177240/466a82c8-43ba-6ef8-2a2f-a07ff1bf27bc.png)

これから一つの例を通して、複数プロンプトが必要な複雑なタスクの実現プロセスを説明します。

## 1.関連製品と分類名称の抽出

お客様の問い合わせを分類した後、問い合わせのカテゴリーが得られます。それはアカウントの問題なのか、製品の問題なのかを特定します。その後、異なるカテゴリーに基づいて異なるアクションを取ることができます。

各サブタスクは、対応するタスクを実行するために必要な指示のみを含んでおりまして、これにより三つのメリットがあります。
1. これによりシステムがより管理しやすくなり、モデルがタスクを実行するために必要なすべての情報を持っていることを確認し、エラーの可能性を低減します。
1. この方法はコストを削減することもできます。なぜなら、より長いプロンプトとより多くのトークンはより高い実行コストをもたらし、すべてのステップを概説する必要はないかもしれないからです。
1. どのステップが失敗しやすいか、または特定のステップで人の介入が必要かどうかをテストしやすくなることです。

これらのモデルの構築と交互に関わることが進むにつれて、この戦略をいつ適用するかの直感を徐々に培っていきます。さらに、この方法は必要に応じてモデルが外部ツールを使用することを可能にします。
例えば、製品カタログで特定の内容を検索する、APIを呼び出す、または知識ベースを検索することを決定することができる。これは単一のプロンプトを使用しては実現できないものです。

## 2.抽出された製品と分類の詳細情報の検索
多くの製品情報を提供しており、モデルに製品とそれに対応する詳細情報を抽出するように要求しています。


```python 
# product information
products = {
"TechPro Ultrabook": {
    "名前": "TechPro Ultrabook",
    "カテゴリ": "コンピュータとラップトップ",
    "ブランド": "TechPro",
    "モデル番号": "TP-UB100",
    "保証": "1年",
    "評価": 4.5,
    "機能": ["13.3インチディスプレイ", "8GB RAM", "256GB SSD", "Intel Core i5 プロセッサー"],
    "説明": "日常使用のためのスリークで軽量なウルトラブック。",
    "価格": 799.99
},
"BlueWave Gaming Laptop": {
    "名前": "BlueWave ゲーミングラップトップ",
    "カテゴリ": "コンピュータとラップトップ",
    "ブランド": "BlueWave",
    "モデル番号": "BW-GL200",
    "保証": "2年",
    "評価": 4.7,
    "機能": ["15.6インチディスプレイ", "16GB RAM", "512GB SSD", "NVIDIA GeForce RTX 3060"],
    "説明": "没入型のエクスペリエンスのための高性能ゲーミングラップトップ。",
    "価格": 1199.99
},
"PowerLite Convertible": {
    "名前": "PowerLite コンバーチブル",
    "カテゴリ": "コンピュータとラップトップ",
    "ブランド": "PowerLite",
    "モデル番号": "PL-CV300",
    "保証": "1年",
    "評価": 4.3,
    "機能": ["14インチタッチスクリーン", "8GB RAM", "256GB SSD", "360度ヒンジ"],
    "説明": "レスポンシブなタッチスクリーンを備えた多機能なコンバーチブルラップトップ。",
    "価格": 699.99
},
"TechPro Desktop": {
    "名前": "TechPro デスクトップ",
    "カテゴリ": "コンピュータとラップトップ",
    "ブランド": "TechPro",
    "モデル番号": "TP-DT500",
    "保証": "1年",
    "評価": 4.4,
    "機能": ["Intel Core i7 プロセッサー", "16GB RAM", "1TB HDD", "NVIDIA GeForce GTX 1660"],
    "説明": "仕事や遊びのためのパワフルなデスクトップコンピュータ。",
    "価格": 999.99
},
"BlueWave Chromebook": {
    "名前": "BlueWave Chromebook",
    "カテゴリ": "コンピュータとラップトップ",
    "ブランド": "BlueWave",
    "モデル番号": "BW-CB100",
    "保証": "1年",
    "評価": 4.1,
    "機能": ["11.6インチディスプレイ", "4GB RAM", "32GB eMMC", "Chrome OS"],
 "説明": "日常のタスクのためのコンパクトで手頃な価格のChromebook。",
    "価格": 249.99
},
"SmartX ProPhone":
    {
        "名前": "SmartX ProPhone",
        "カテゴリ": "スマートフォンとアクセサリー",
        "ブランド": "SmartX",
        "モデル番号": "SX-PP10",
        "保証": "1年",
        "評価": 4.6,
        "特長": ["6.1インチディスプレイ", "128GBストレージ", "12MPデュアルカメラ", "5G"],
        "説明": "高度なカメラ機能を備えたパワフルなスマートフォン。",
        "価格": 899.99
    },

"MobiTech PowerCase":
    {
        "名前": "MobiTech PowerCase",
        "カテゴリ": "スマートフォンとアクセサリー",
        "ブランド": "MobiTech",
        "モデル番号": "MT-PC20",
        "保証": "1年",
        "評価": 4.3,
        "特長": ["5000mAhバッテリー", "ワイヤレス充電", "SmartX ProPhoneと互換"],
        "説明": "内蔵バッテリー付きの保護ケースで、使用時間を延ばします。",
        "価格": 59.99
    },

"SmartX MiniPhone":
    {
        "名前": "SmartX MiniPhone",
        "カテゴリ": "スマートフォンとアクセサリー",
        "ブランド": "SmartX",
        "モデル番号": "SX-MP5",
        "保証": "1年",
        "評価": 4.2,
        "特長": ["4.7インチディスプレイ", "64GBストレージ", "8MPカメラ", "4G"],
        "説明": "基本的なタスク用のコンパクトで手頃な価格のスマートフォン。",
        "価格": 399.99
    },

"MobiTech Wireless Charger":
    {
        "名前": "MobiTech Wireless Charger",
        "カテゴリ": "スマートフォンとアクセサリー",
        "ブランド": "MobiTech",
        "モデル番号": "MT-WC10",
        "保証": "1年",
        "評価": 4.5,
        "特長": ["10W高速充電", "Qi互換", "LEDインジケーター", "コンパクトデザイン"],
        "説明": "ごちゃごちゃしないワークスペース用の便利なワイヤレス充電器。",
        "価格": 29.99
    },

"SmartX EarBuds":
    {
        "名前": "SmartX EarBuds",
        "カテゴリ": "スマートフォンとアクセサリー",
        "ブランド": "SmartX",
        "モデル番号": "SX-EB20",
        "保証": "1年",
        "評価": 4.4,
        "特長": ["完全ワイヤレス", "Bluetooth 5.0", "タッチコントロール", "24時間バッテリー寿命"],
        "説明": "これらの快適なイヤーバッドで真のワイヤレス自由を体験してください。",
        "価格": 99.99
    },

"CineView 4K TV":
    {
        "名前": "CineView 4K TV",
        "カテゴリ": "テレビとホームシアターシステム",
        "ブランド": "CineView",
        "モデル番号": "CV-4K55",
        "保証": "2年",
        "評価": 4.8,
        "特長": ["55インチディスプレイ", "4K解像度", "HDR", "スマートTV"],
        "説明": "鮮やかな色とスマートな機能であなたの視覚体験を次のレベルに引き上げます。",
        "価格": 599.99
    },

"BeatFlow Bluetooth Speaker":
    {
        "名前": "BeatFlow Bluetooth Speaker",
        "カテゴリ": "オーディオ機器",
        "ブランド": "BeatFlow",
        "モデル番号": "BF-BS30",
        "保証": "2年",
        "評価": 4.7,
        "特長": ["20W高出力", "Bluetooth 5.0", "12時間再生", "防水"],
        "説明": "クリアなサウンドと深いベースで、どこでもパーティーを楽しめます。",
        "価格": 49.99
    }
}
```

```python 
def get_product_by_name(name):
    """
    製品名称から製品を取得します

    パラメータ:
    名前: 製品名称
    """
    return products.get(name, None)

def get_products_by_category(category):
    """
    カテゴリから製品を取得します

    パラメータ:
    名前: カテゴリ
    """
    return [product for product in products.values() if product["カテゴリ"] == category]
```


```python 
print(get_product_by_name("TechPro Ultrabook"))
```

出力結果：
```python 
{'名前': 'TechPro Ultrabook', 'カテゴリ': 'コンピュータとラップトップ', 'ブランド': 'TechPro', 'モデル番号': 'TP-UB100', '保証': '1年', '評価': 4.5, '機能': ['13.3インチディスプレイ', '8GB RAM', '256GB SSD', 'Intel Core i5 プロセッサー'], '説明': '日常使用のためのスリークで軽量なウルトラブック。', '価格': 799.99}
```


```python 
print(get_products_by_category("オーディオ機器"))
```

出力結果：
```python 
[{'名前': 'BeatFlow Bluetooth Speaker', 'カテゴリ': 'オーディオ機器', 'ブランド': 'BeatFlow', 'モデル番号': 'BF-BS30', '保証': '2年', '評価': 4.7, '特長': ['20W高出力', 'Bluetooth 5.0', '12時間再生', '防水'], '説明': 'クリアなサウンドと深いベースで、どこでもパーティーを楽しめます。', '価格': 49.99}]
```

## 3.Python文字列からPython辞書型リストへ変換

前述のプロンプトからリスト風の文字列をもらいました、これから文字列をPythonの辞書型リストへ変換します。
```python 
import json 

def read_string_to_list(input_string):
    """
    入力された文字列をPythonのリストに変換します。

    引数:
    input_string: 入力された文字列で、有効なJSONフォーマットである必要があります。

    戻り値:
    listまたはNone: 入力文字列が有効である場合は、対応するPythonのリストを返し、そうでない場合はNoneを返します。
    """
    if input_string is None:
        return None

    try:
        # 入力文字列中のシングルクォートをダブルクォートに置き換えて、JSONフォーマットの要件を満たします
        input_string = input_string.replace("'", "\"")  
        data = json.loads(input_string)
        return data
    except json.JSONDecodeError:
        print("Error: Invalid JSON string")
        return None   
```

```python 
category_and_product_list = read_string_to_list(category_and_product_response_1)
print(category_and_product_list)
```

出力結果：

```python 
[{'製品': 'SmartX EarBuds'}, {'カテゴリ': 'スマートフォンとアクセサリ'}, {'製品': 'FotoSnap DSLR Camera'}, {'カテゴリ': 'カメラおよびビデオカメラ'}, {'カテゴリ': 'テレビおよびホームシアターシステム'}]
```

## 4.詳細な製品情報からユーザ検索の結果の作成

こちらで詳細なソースコードを記載しないので、上記出力されたPythonの辞書型データを利用して、次のユーザーへ見せる詳細な情報を作成します。

## 最後に

ユーザーの問い合わせに関連する情報を一連のステップでロードし、モデルに必要なコンテキストを提供し、効果的に質問に回答する方法について議論しました。

なぜ全ての製品の説明を含めずに、選択的に製品の説明をプロンプトにロードし、モデルが必要とする情報を使用させるのか。

その理由はいくつかあります。

1. 多くの製品の説明を含めると、モデルはコンテキストを処理する際に混乱する可能性があります。これは、一度に大量の情報を処理しようとする人にとっても同様です。
1. 第二の理由は、言語モデルにはコンテキスト制約があり、一定量のトークンのみが入力および出力として許可されているということです。
1. 最後の理由は、全ての製品の説明を含めると、モデルが過学習する可能性があります。なぜなら、モデルは全ての製品の説明を覚えてしまい、問い合わせに関連する情報だけを覚えていないからです。これは、モデルが新しい問い合わせを処理する際のパフォーマンスを低下させる可能性があります。

# アウトプットのチェック

システムが生成した出力をどのように検査するかに焦点を当てます。ユーザーに出力を表示する前に、出力の品質、関連性、安全性を検査することは、自動化されたプロセスや他のシナリオにおいて提供されるレスポンスを確保するために非常に重要です。私たちは、出力を評価するためにレビューAPIを使用する方法と、出力を表示する前にモデルの品質評価を向上させるために追加のプロンプトを使用する方法について探ります。


## 回答には有害な内容が含まれているか

```python 
final_response_to_customer = f"""
SmartX ProPhoneは6.1インチのディスプレイ、128GBのストレージ、
1200万画素のダブルカメラ、および5Gを備えています。FotoSnap一眼レフカメラは
2420万画素のセンサー、1080pビデオ、3インチLCD、および交換可能なレンズを備えています。
さまざまな種類のテレビがあり、CineView 4Kテレビ、
55インチディスプレイ、4K解像度、HDR、およびスマートテレビ機能を含みます。
"""

response = openai.Moderation.create(
    input=final_response_to_customer
)
moderation_output = response["results"][0]
print(moderation_output)
```

以下が出力結果：

```python 
{
  "flagged": false,
  "categories": {
    "sexual": false,
    "hate": false,
    "harassment": false,
    "self-harm": false,
    "sexual/minors": false,
    "hate/threatening": false,
    "violence/graphic": false,
    "self-harm/intent": false,
    "self-harm/instructions": false,
    "harassment/threatening": false,
    "violence": false
  },
  "category_scores": {
    "sexual": 1.8567163351690397e-05,
    "hate": 4.949302478962636e-08,
    "harassment": 5.266039124762756e-07,
    "self-harm": 9.121548316670669e-08,
    "sexual/minors": 4.064214635945973e-07,
    "hate/threatening": 5.625001020526099e-10,
    "violence/graphic": 3.480204759398475e-05,
    "self-harm/intent": 5.744793973860851e-09,
    "self-harm/instructions": 2.7171549454862998e-09,
    "harassment/threatening": 8.118979932802972e-10,
    "violence": 1.0604052476992365e-05
  }
}
```

すべてがFalseで、またスコアも低くて、この回答には有害な内容が含まれていませんでした。

全体として、出力をチェックすることも非常に重要です。例えば、敏感な聴衆のためにチャットボットを作成している場合、出力をフラグとしてマークするために低い閾値を使用することができます。一般的に、出力の審査がコンテンツがフラグとしてマークされていることを示している場合、適切な行動を取ることができます。例えば、代わりの回答を提供するか、新しい回答を生成することができます。

## 回答には製品情報とマッチしているか


```python 
#電子製品情報
system_message = f"""
あなたはアシスタントであり、カスタマーサービスエージェントの回答が顧客の質問に十分に答えているかどうかを評価し、
また、アシスタントが製品情報から引用したすべての事実が正しいかどうかを検証します。
製品情報およびユーザーとカスタマーサービスエージェントのメッセージは、3つのバックティック、
すなわち ``` で区切られます。
YまたはN文字で応答してください、句読点はありません：
Y - 出力が質問に十分に答え、回答が製品情報を正しく使用している場合
N - それ以外の場合

単一の文字のみを出力します。
"""

#ユーザ質問
customer_message = f"""
SmartX ProPhoneとFotosnapカメラ（DSLRタイプ）について教えてください。
また、お持ちのテレビについても教えてください。
"""
product_information = """{ "name": "SmartX ProPhone", "category": "Smartphones and Accessories", "brand": "SmartX", "model_number": "SX-PP10", "warranty": "1 year", "rating": 4.6, "features": [ "6.1-inch display", "128GB storage", "12MP dual camera", "5G" ], "description": "A powerful smartphone with advanced camera features.", "price": 899.99 } { "name": "FotoSnap DSLR Camera", "category": "Cameras and Camcorders", "brand": "FotoSnap", "model_number": "FS-DSLR200", "warranty": "1 year", "rating": 4.7, "features": [ "24.2MP sensor", "1080p video", "3-inch LCD", "Interchangeable lenses" ], "description": "Capture stunning photos and videos with this versatile DSLR camera.", "price": 599.99 } { "name": "CineView 4K TV", "category": "Televisions and Home Theater Systems", "brand": "CineView", "model_number": "CV-4K55", "warranty": "2 years", "rating": 4.8, "features": [ "55-inch display", "4K resolution", "HDR", "Smart TV" ], "description": "A stunning 4K TV with vibrant colors and smart features.", "price": 599.99 } { "name": "SoundMax Home Theater", "category": "Televisions and Home Theater Systems", "brand": "SoundMax", "model_number": "SM-HT100", "warranty": "1 year", "rating": 4.4, "features": [ "5.1 channel", "1000W output", "Wireless subwoofer", "Bluetooth" ], "description": "A powerful home theater system for an immersive audio experience.", "price": 399.99 } { "name": "CineView 8K TV", "category": "Televisions and Home Theater Systems", "brand": "CineView", "model_number": "CV-8K65", "warranty": "2 years", "rating": 4.9, "features": [ "65-inch display", "8K resolution", "HDR", "Smart TV" ], "description": "Experience the future of television with this stunning 8K TV.", "price": 2999.99 } { "name": "SoundMax Soundbar", "category": "Televisions and Home Theater Systems", "brand": "SoundMax", "model_number": "SM-SB50", "warranty": "1 year", "rating": 4.3, "features": [ "2.1 channel", "300W output", "Wireless subwoofer", "Bluetooth" ], "description": "Upgrade your TV's audio with this sleek and powerful soundbar.", "price": 199.99 } { "name": "CineView OLED TV", "category": "Televisions and Home Theater Systems", "brand": "CineView", "model_number": "CV-OLED55", "warranty": "2 years", "rating": 4.7, "features": [ "55-inch display", "4K resolution", "HDR", "Smart TV" ], "description": "Experience true blacks and vibrant colors with this OLED TV.", "price": 1499.99 }"""

q_a_pair = f"""
Customer message: ```{customer_message}```
Product information: ```{product_information}```
Agent response: ```{final_response_to_customer}```

応答は、取得した情報を正しく使用していますか？
応答は質問に十分に答えていますか？

出力 Y or N
"""
#関係性を判断
messages = [
    {'role': 'system', 'content': system_message},
    {'role': 'user', 'content': q_a_pair}
]

response = get_completion_from_messages(messages, max_tokens=1)
print(response)
```

出力が`Y`です。

もう一つ関係性ない回答を例として確認します：

```python 
another_response = "東京駅が一番近いです"
q_a_pair = f"""
Customer message: ```{customer_message}```
Product information: ```{product_information}```
Agent response: ```{another_response}```

応答は、取得した情報を正しく使用していますか？
応答は質問に十分に答えていますか？

出力 Y or N
"""
messages = [
    {'role': 'system', 'content': system_message},
    {'role': 'user', 'content': q_a_pair}
]

response = get_completion_from_messages(messages)
print(response)
```

今回の答えが`N`でした。

## 最後に
このモデルは、生成された出力の品質に関するフィードバックを提供することができます。このフィードバックを利用して、出力をユーザーに表示するか、新しいレスポンスを生成するかを決定することができます。さらに、各ユーザーのクエリに対して複数のモデルのレスポンスを生成し、最適なレスポンスをユーザーに表示することも試すことができます。したがって、試す方法は多様です。

全体として、審査APIを使用して出力をチェックするのは良い方法です。しかし、ほとんどの場合においてはこれが必要ではないと考えています、特にGPT-4のようなより先進的なモデルを使用する場合には。

実際、実生産環境でこの方法を採用する人を多く見ていません。これはシステムの遅延とコストを増加させる可能性があります、なぜならあなたは追加のコールを待たなければならなく、追加のトークンも必要になるからです。あなたのアプリケーションや製品のエラーレートが0.0000001%しかないのであれば、この方法を試すことができます。しかし、全体として、実際のアプリケーションでこの方法を採用することはお勧めしません。

# 最後に

以上は、以下のコースの前の三章でした。

https://www.deeplearning.ai/short-courses/building-systems-with-chatgpt/

次回の記事で以下のを説明します。

- Build an End-to-End System
- Evaluation part I
- L9: Evaluation Part II
- Summary