【UiPath×OpenAI】開発者向けのプロンプトエンジニアリング③ 後編 テキストの変換と拡張

LLM（Large Language Models）は人々の生活を着実に変えており、開発者にとっては非常に強力なツールです。LLMが提供するAPIを利用することで、開発者は素早く便利なアプリケーションを開発することができます。
OpenAIは、LLMを開発者に提供するためのAPIを提供しており、これを使用することで、開発者は自分のアプリケーションやプロジェクトにLLMの能力を組み込むことができます。

UiPathでOpenAIを使用すると、本来ルールベースのRPAでできなかったこと、例えば、自然言語処理やチャットボットなども可能になり、UiPath開発者として、OpenAIを使用する際のプロンプト文の構成原則やテクニックを把握することで、自動化の範囲が更に広がると思います。

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

https://www.deeplearning.ai/short-courses/chatgpt-prompt-engineering-for-developers/

これが開発者向けのプロンプトエンジニアリングガイドです。Andrew Ng先生の「ChatGPT Prompt Engineering for Developers」コースを基に、**初心者向けのLLM開発者向けに、プロンプトの構築方法とOpenAIのAPIを使用して要約、推論、変換などの一般的な機能を実現する方法をわかりやすく紹介しています。**
記事の最後に、UiPath Studioを使用して、講座でのそれぞれのテーマを実現しました。UiPath×OpenAIの開発において、この情報を活用することで、より高度な自動化ワークフローの開発を期待できます。

本記事では、OpenAIを使用してテキストの変換と拡張を解説し、最後に、UiPath×OpenAIでの応用も説明します。
本記事で作成したJupiter NotebookとUiPath Workflowは以下の通りです。ご参照ください。
- [【OpenAI】開発者向けのプロンプトエンジニアリング③ 後編 テキストの変換と拡張.ipynb](https://drive.google.com/file/d/1iGeZaRKpCapsDwBFOwemmVqI3RnPWJyl/view?usp=drive_link)
- [【UiPath Workflow】開発者向けのプロンプトエンジニアリング③ 後編](https://drive.google.com/drive/folders/1dgyyUvQWE_wx3DzFW1KFP9eYwT3AoC0U?usp=drive_link)

上記Jupiter Notebookの開き方は以下のビデオをご参照ください。

https://www.youtube.com/watch?v=inN8seMm7UI


# 環境設定
この記事では、OpenAIが提供するChatGPT APIを使用しています。したがって、最初にChatGPTのAPIキーを取得する必要があります（または公式ウェブサイトでオンラインテストを実施することもできます）。次に、openaiのライブラリをインストールする必要があります。
openai：
```bash
pip install openai
```
ライブラリのインポートと自分のAPIキーを設定します。
```bash
import openai
import os
openai.api_key='自身のOpenAI キー'
```
これから、OpenAIが提供するChatCompletion APIの使用方法を詳しく確認します。ここでは、それを関数にラップしてみます。内部の仕組みを理解する必要はありません。単に、この関数を呼び出すと、プロンプトに対応するCompletionが提供されることを知っていれば十分です。
```python
# 「Prompt」を受け取り、それに対応する結果を返す関数
# gpt-3.5-turbo
def get_completion(prompt, model="gpt-3.5-turbo"):
    '''
    prompt: 入力となるPrompt
    model: 使用するGPTモデルを指定、デフォルトgpt-3.5-turbo(ChatGPT)
    '''
    messages = [{"role": "user", "content": prompt}]
    response = openai.ChatCompletion.create(
        model=model,
        messages=messages,
        temperature=0, # 生成されたテキストの多様性や予測のランダム性を調整するためのパラメータ
    )
    # OpenAIからの応答からテキストを抽出
    return response.choices[0].message["content"]
```

# テキストの変換

LLMは、入力を異なる形式に変換するのに非常に優れており、典型的な用途には多言語テキストの翻訳、スペルチェックおよび文法修正、トーン調整、形式変換などが含まれます。

この記事では、プログラムを使用してAPIインターフェースを呼び出して「テキスト変換」機能を実現する方法について説明します。

## テキスト翻訳

- 日本語からスペイン語

```python 
prompt = f"""
次の日本語をスペイン語に翻訳しなさい。
```こんにちは、ミキサーを注文したいのですが。```
"""
response = get_completion(prompt)
print(response)
```

出力：`Hola, me gustaría hacer un pedido de una batidora.`

- 言語識別

```python 
prompt = f"""
以下の文章は何語で書かれているか教えてください。
```Combien coûte le lampadaire?```
"""
response = get_completion(prompt)
print(response)
```

出力：`この文章はフランス語で書かれています。`

- 多言語への翻訳

```python
prompt = f"""
以下の文章を中国語、日本語、フランス語、スペイン語に翻訳してください。
```I want to order a basketball.```
"""
response = get_completion(prompt)
print(response)
```

```json 
我想订购一个篮球。(Chinese)

バスケットボールを注文したいです。(Japanese)

Je veux commander un ballon de basket. (French)

Quiero pedir una pelota de baloncesto. (Spanish)
```

## トーンの変換

```python
prompt = f"""
次の文章を、フォーマルな調子とくだけた調子の両方で日本語に訳してください。
```Would you like to order a pillow?```
"""
response = get_completion(prompt)
print(response)
```

出力：

```json
フォーマルな調子：
「枕をご注文いただけますか？」

くだけた調子：
「枕、オーダーする？」
```

## ユニバーサル翻訳機

グローバリゼーションと国境を越えたビジネスの発展に伴い、コミュニケーションの相手はさまざまな国から来る可能性があり、異なる言語を使用することがあります。そのため、私たちは汎用の翻訳器が必要で、各メッセージの言語を認識し、それを目標のユーザーの母国語に翻訳することで、国際的なコミュニケーションをより便利に実現できるようになります。

```python
user_messages = [
  "La performance du système est plus lente que d'habitude.",  # System performance is slower than normal
  "Mi monitor tiene píxeles que no se iluminan.",              # My monitor has pixels that are not lighting
  "Il mio mouse non funziona",                                 # My mouse is not working
  "Mój klawisz Ctrl jest zepsuty",                             # My keyboard has a broken control key
  "我的屏幕在闪烁"                                             # My screen is flashing
]
```

```python
import time
for issue in user_messages:
    time.sleep(20)
    prompt = f"次のテキストが何語で書かれているか教えてください。そして、その言語を直接、例えばフランス語のように、句読点なしで出力してください。: ```{issue}```"
    lang = get_completion(prompt)
    print(f"オリジナルテキスト ({lang}): {issue}\n")

    prompt = f"""
    次のメッセージをそれぞれ日本語と英語に翻訳し、次のように書きなさい。
    日本語訳：xxx
    英語翻訳：yyyy
    のような形式で書きます：
    ```{issue}```
    """
    response = get_completion(prompt)
    print(response, "\n=========================================")
```

出力：

```json
オリジナルテキスト (フランス語): La performance du système est plus lente que d'habitude.

日本語訳：システムのパフォーマンスが通常よりも遅くなっています。
英語翻訳：The system performance is slower than usual. 
=========================================
オリジナルテキスト (このテキストはスペイン語で書かれています。): Mi monitor tiene píxeles que no se iluminan.

日本語訳：私のモニターには光らないピクセルがあります。
英語翻訳：My monitor has pixels that do not light up. 
=========================================
オリジナルテキスト (このテキストはイタリア語で書かれています。): Il mio mouse non funziona

日本語訳：私のマウスが動きません
英語翻訳：My mouse is not working 
=========================================
オリジナルテキスト (このテキストはポーランド語で書かれています。): Mój klawisz Ctrl jest zepsuty

日本語訳：私のCtrlキーが壊れています
英語翻訳：My Ctrl key is broken 
=========================================
オリジナルテキスト (このテキストは中国語で書かれています。): 我的屏幕在闪烁

日本語訳：私の画面が点滅しています
英語翻訳：My screen is flickering 
=========================================
```

## トーンとライティングスタイルの調整

文章のトーンは、読み手によって調整されることが多い。 例えば、仕事のメールではフォーマルな口調で文章を書く必要がありますが、同年代の友人とのLineチャットでは、もっとリラックスした口語調を使うことがあります。

```python 
prompt = f"""
以下のテキストをビジネスメールのフォーマットに変換してください。:
```ちなみに、お兄ちゃん、私は詩佑ですが、前回、私たちの部門が購入する必要があるディスプレイのサイズは何インチだったか覚えていますか？```
"""
response = get_completion(prompt)
print(response)
```

出力：

```json
件名: ディスプレイのサイズについての確認

拝啓 [受信者の名前],

お兄ちゃん、こんにちは。詩佑です。前回の打ち合わせで、私たちの部門が購入する必要があるディスプレイのサイズについて、ご存知でしょうか？

お手数をおかけしますが、前回の会議で確認したディスプレイのサイズ（インチ）を教えていただけますでしょうか？細かな情報が必要となってきたため、再度確認させていただきたいと思います。

ご返信いただければ幸いです。

何卒よろしくお願いいたします。

敬具,
詩佑
```

## ファイル形式の変換

ChatGPTは異なるフォーマット、例えばJSONからHTML、XML、Markdownなどへの変換が得意です。 次の例では、レストランの従業員の名前と電子メールのリストを含むJSONがあり、JSONからHTMLに変換します。

```python 
data_json = { "resturant employees" :[
    {"name":"Shyam", "email":"shyamjaiswal@gmail.com"},
    {"name":"Bob", "email":"bob32@gmail.com"},
    {"name":"Jai", "email":"jai87@gmail.com"}
]}
```

```python 
prompt = f"""
以下のpython辞書をJSONからHTMLに変換してください。 \
カラムヘッダとタイトルを持つテーブル：{data_json}
"""
response = get_completion(prompt)
print(response)

```

```html
以下は、与えられたPython辞書をJSONからHTMLに変換した例です。
<!DOCTYPE html>
<html>
<head>
    <title>Restaurant Employees</title>
</head>
<body>
    <table>
        <tr>
            <th>Name</th>
            <th>Email</th>
        </tr>
        <tr>
            <td>Shyam</td>
            <td>shyamjaiswal@gmail.com</td>
        </tr>
        <tr>
            <td>Bob</td>
            <td>bob32@gmail.com</td>
        </tr>
        <tr>
            <td>Jai</td>
            <td>jai87@gmail.com</td>
        </tr>
    </table>
</body>
</html>

このHTMLコードは、テーブルを作成し、カラムヘッダとタイトルを持つレストランの従業員の情報を表示します。
```

もしテーブル部分だけのHTML文であれば、以下のように修正してください。

```python 
prompt = f"""
以下の辞書をJSONからHTMLのテーブルだけに変換し、テーブルの見出しとカラム名を保持します：{data_json}
このテーブル部分のHTMLだけを出力してください。
"""
response = get_completion(prompt)
print(response)
```

出力：

```html
<table>
  <tr>
    <th>name</th>
    <th>email</th>
  </tr>
  <tr>
    <td>Shyam</td>
    <td>shyamjaiswal@gmail.com</td>
  </tr>
  <tr>
    <td>Bob</td>
    <td>bob32@gmail.com</td>
  </tr>
  <tr>
    <td>Jai</td>
    <td>jai87@gmail.com</td>
  </tr>
</table>
```

以下のPythonコードで上のHTMLコンテンツを表示してみよう！
```python
from IPython.display import display, Markdown, Latex, HTML, JSON
display(HTML(response))
```

## スペルと文法の訂正

スペルと文法のチェックと修正は、非母語話者が特にフォーラムに投稿する場合や英語の論文を発表する場合など、非常に一般的なニーズです。以下の例は、文のリストを提供し、一部の文にスペルや文法の問題がある場合とない場合があります。私たちは各文をループして、モデルにテキストを校正するよう要求し、正しい場合は「エラーが見つかりませんでした」と出力し、間違っている場合は修正後のテキストを出力します。

```python 
text = [
    "先日、領収書の発行がお願いするメールをお送りしたのですが、ご覧いだけておますでしょうか",
    "念のため前回のメールが以下に貼り付けておきます。",
    "領収書は月末の経理処理で必要になます。",
    "この日を過ぎると、お支払いが翌々月末となります。"
]
```

```python 
for t in text:
    prompt = f"""以下の文章を校正・訂正し
    そして訂正したものを書き直してください。もし
    エラーが見つからない場合は、「エラーは見つかりませんでした」。
    本文の周りに句読点は使用しないでください。
    ```{t}```"""
    response = get_completion(prompt)
    print(response)
```

出力：

```json
先日、領収書の発行をお願いするメールをお送りしましたが、ご覧いただけましたでしょうか。
念のため、前回のメールを以下に貼り付けておきます。
領収書は月末の経理処理で必要になります。
この日を過ぎると、お支払いは翌々月末となります。
```

# テキストの拡張

拡張は、短いテキスト（たとえば説明やトピックリストのグループ）を大規模な言語モデルに入力し、モデルがより長いテキスト（例えば特定のトピックに基づく電子メールや論文）を生成するプロセスです。

この記事では、OpenAI APIを使用して、各顧客に対する評価を最適化したカスタマーサポートの電子メールを生成する方法を学びます。また、モデルの別の入力パラメータである「温度」も活用します。このパラメータは、モデルの応答における探索の度合いと多様性を変化させることを可能にします。

## カスタマイズされた顧客メール

当社は、顧客の評価と感情に基づいて、対話型の自動返信メールを作成します。したがって、特定の顧客の評価と感情に基づいて、LLM（言語モデル）を使用してカスタマイズされた電子メールを生成します。

最初に、レビューとそれに対応する感情を含む例を示します。

```python 
# 推論の記事では、コメントを評価してその感情傾向を判断する方法を学ぶことができます。
sentiment = "negative"

# 商品の評価レビュー
review = f"""
彼らは11月の季節セール期間中に、17個のセットを約49ドルで販売し、割引は約半分です。
しかし、何らかの理由（おそらく価格詐欺かもしれません）で、12月の第2週には同じセットの価格が全て70ドルから89ドルに上昇しました。
11個セットの価格も約10ドル上昇しました。
見た目はまだ良いようですが、刃を固定する基座の部分は、数年前の初期バージョンほど良くは見えません。
しかし、私はそれを非常に優しく使うつもりです。例えば、
まず、豆、氷、米などの硬い食材をミキサーで粉砕し、それから必要な量を作ります。
ワイヤーホイップを使用してより細かい粉を作るために切り替え、またはクロスカットブレードを使用してスムージーを作り、次にフラットブレードを使用してより細かく粘りのないものを作ります。
スムージーを作る際の特別な注意点：
フルーツと野菜を刻んで冷凍しておく（ほうれん草を使用する場合、ほんのり茹でてから冷凍し、使用するまで冷凍してください。
ジャムを作る場合は、小～中サイズのフードプロセッサーを使用）、これによりスムージーを作る際に氷を多く追加するのを防ぐことができます。
約1年後、モーターから奇妙なノイズが聞こえ、カスタマーサービスに電話しましたが、保証が切れていたので、新しいものを買うしかありませんでした。
総じて、これらの製品の全体的な品質は低下しており、ブランド認知度と顧客の忠誠心に依存して販売を維持しています。
商品は2日以内に届きます。
"""
```

推論の記事で学んだ方法を使用して、感情を抽出しました。これはミキサーに関する顧客の評価です。今、感情に基づいてカスタマイズされた返信を作成します。

以下はプロンプトの例です：仮想的なカスタマーサービスAIアシスタントとして、あなたの仕事は顧客に感謝のメールを送ることです。顧客の電子メールは三つのバッククォートで区切られています。

```python 
prompt = f"""
あなたは顧客サービスのAIアシスタントです。
あなたの仕事は、重要な顧客にメールの返信を送ることです。
三つのバッククォート(`)で囲まれた評価を基に、評価をお客様に感謝する返信を生成します。
評価の具体的な詳細をモデルに提供してください。
簡潔かつプロフェッショナルな言葉でメールを書いてください。
「AIカスタマーエージェント」として電子メールに署名します。
顧客のコメント：
```{review}```
レビューの感情：{sentiment}
"""
response = get_completion(prompt)
print(response)
```

出力：

```python 
件名：ご意見ありがとうございます

拝啓、お客様

この度は、弊社の製品についてのご意見をお寄せいただき、誠にありがとうございます。お客様の貴重なご意見を真摯に受け止め、改善に努めてまいります。

お客様からいただいたご意見によれば、11月の季節セール期間中にお求めいただいたセットの価格が、12月の第2週に急激に上昇したとのことでした。また、製品の品質についてもご指摘いただきました。このようなご経験をされたことについて、心よりお詫び申し上げます。

お客様のご指摘によれば、製品の品質が以前のバージョンと比べて低下しているとのことでした。私たちはお客様にご満足いただける製品を提供することを最優先に考えており、今回のご意見を真摯に受け止め、品質向上に向けた改善策を検討いたします。

また、お客様からは製品の使い方についてもご指摘いただきました。お客様の貴重なアドバイスを参考にし、より使いやすい製品を開発するために努力いたします。

最後に、お客様が商品を2日以内にお受け取りいただけるよう手配いたします。お手元に届くまで、もうしばらくお待ちいただけますようお願い申し上げます。

お客様のご意見を真摯に受け止め、今後の改善に活かしてまいります。お客様により良い製品とサービスを提供できるよう、努力を重ねてまいります。

お手数をおかけいたしますが、何かご不明な点やご質問がございましたら、お気軽にお知らせください。

AIカスタマーエージェント
```

## 温度パラメータの利用

次に、温度という言語モデルのパラメータを使って、モデル応答の多様性を変化させます。 温度は、モデルの探索度やランダム性と考えることができます。
低い温度値を設定すると、モデルの出力はより確実で予測可能になり、高い温度値を設定すると、モデルの出力はより多様でランダムになります。

例を以下に示します。質問: "太陽は何ですか？"

- 温度 0.2 (低い): 太陽は恒星であり、私たちの太陽系の中心に位置しています。
- 温度 0.7 (中程度): 太陽は私たちの太陽系の中心にある大きな恒星で、地球に光と熱を供給しています。
- 温度 1.0 (高い): 太陽は宇宙のダンスフロアのようなもので、星々が輝きながら回転している中心的存在です！

低い温度では、回答は事実ベースで直接的です。温度が上がるにつれて、回答はより創造的であり、時には意味が不明瞭になることもあります。

一般的に、予測可能な応答を必要とするアプリケーションを構築するときは、温度をゼロに設定することをお勧めします。信頼性が高く、予測可能なシステムを構築しようとしているのであれば、この温度を選ぶべきだと思います。 もしより創造的な方法でモデルを使おうとしていて、より広い範囲の異なる結果を出力する必要があるかもしれないのであれば、より高い温度を使った方がいいかもしれません。

同じメッセージについて、モデルにユーザーのメッセージ内の詳細情報を使用し、温度を設定します。

```python 
prompt = f"""
あなたは重要な顧客へのメール返信のための顧客サービスのAIアシスタントです。
顧客のメールをもとに回答を生成し、お客様の評価に感謝の意を表します。
メール内の具体的な詳細情報を使用し、感情がポジティブまたは中立的な場合は評価に感謝します。
感情がネガティブな場合は、お詫びし、顧客サービスに連絡することを提案します。
簡潔かつプロフェッショナルな言葉でメールを書いてください。
メールの署名には「AIカスタマーエージェント」と記載してください。
顧客レビュー：```{review}```
レビュー感情：{sentiment}
"""
response = get_completion(prompt, temperature=0.7)
print(response)
```

出力：

```python 
拝啓、

お客様、

この度は、弊社製品についてのご意見をいただき、誠にありがとうございます。お客様の貴重なご意見を真摯に受け止め、大変残念な結果となったことをお詫び申し上げます。

お客様がご指摘されたように、11月の季節セール期間中には、弊社製品のセットをお求めやすい価格で提供しておりましたが、12月の第2週には価格が急上昇いたしました。また、初期バージョンのような品質が見受けられない部分もあるとのこと、大変心苦しく思います。

お客様のご要望にお応えするために、弊社では製品の品質向上に向けて努力を重ねております。お客様が望まれるような製品を提供できるよう、スタッフ一同努めてまいります。

お客様のサポートに感謝いたします。弊社では、お客様のご意見を重視し、より良い製品とサービスを提供するために努力しております。

お困りごとがございましたら、いつでもお気軽にお問い合わせください。お手数をおかけいたしますが、弊社のカスタマーサービスまでご連絡いただければと存じます。

お客様のご支持に感謝いたしまして、改めてお詫び申し上げます。

AIカスタマーエージェント
```

温度がゼロの場合、同じプロンプトを実行するたびに、得られる応答は常に同じであるべきです。しかし、温度が0.7の場合、毎回異なる出力を得ることになります。

したがって、以前の電子メールとは異なることがわかります。再度実行すると、再び異なる電子メールが得られます。

したがって、出力がどのように変化するかを確認するために、温度を試してみることをお勧めします。要するに、より高い温度では、モデルの出力がよりランダムになります。それを高い温度で、アシスタントがより散漫になり、また創造的になると考えても良いかもしれません。

# 応用:UiPath Studio×OpenAIでプロンプト文の利用

UiPath StudioでChatGPTと連携して、これらのプロンプト文を使って、ChatGPTからの回答を自分の業務に利用します。

検証サンプル一式はこちらの[【UiPath Workflow】開発者向けのプロンプトエンジニアリング③ 後編](https://drive.google.com/drive/folders/1dgyyUvQWE_wx3DzFW1KFP9eYwT3AoC0U?usp=drive_link)を参照ください。

利用方法は[プロンプト文の原則](https://qiita.com/utanesuke/items/9d8590fbdfa1b2159148#%E3%83%97%E3%83%AD%E3%83%B3%E3%83%97%E3%83%88%E6%96%87%E3%81%AE%E5%8E%9F%E5%89%87-1)と同じです。

# 最後に
UiPath Studioを利用して、Pythonなどのプログラミング言語を知らなくても、簡単にChatGPTを実際の業務に活用できます。
UiPathは最後の一マイルの自動化を実現するための強力なツールです。このツールを使用することで、複数のシステムをシームレスにつなげ、業務プロセスの効率化が可能となります。さらに、OpenAIの自然言語処理技術を組み込むことで、RPAがさらに進化します。