
WinActorでAmbientに登録されたデータを集計してみた②
はい、かーでぃです。
今回は、2024/2/9に開催予定のRPACommunityのLTのために作ったWinActorシナリオの紹介と説明です。
が、こちら、LT会では登場しません!(笑)
LT会のタイトルを「LINE x ChatGPT」としたため、OpenAI APIを使うのは違うかな、と思いまして…
折角作ったので、note記事にします。
長くなるため、Ambientからデータを取得する①と、取得したデータを集計する②に記事を分けたいと思います。
※本記事は②になります。①はこちら。
1.イベント情報
RPACommunityのYoutubeチャネル登録者数1万人突破記念イベントです。
お祝いしたくての登壇です。決して、アマギフ1万円に目がくらんだわけではありません!
2.登壇資料
時間の関係上割愛した宣伝コーナーが後ろに数ページあったりしますw
さて本記事では、OpenAI APIにプロンプトを投げ、その結果で返ってきたJSONを解析し、エクセルに転記するところまで一気にやりたいと思います。
3.OpenAI API処理
全体の流れは以下のようになります。
まず、OpenAI APIに投げるヘッダ情報を設定します。次に、プロンプトを作成して、OpenAI APIを叩きます。
得られた結果を踏まえてJSON解析を行い、欲しい情報だけを取り出します。

ヘッダ情報
ここは、ただの変数値設定のノードになります。APIキーは、変数APIKeyに持たせてあります。

プロンプト作成
プロンプトは外部のテキストファイルに持たせてありますので、テキストファイル読込ライブラリ(13_ファイル関連 - 01_テキストファイル読込)を使います。
プロンプトファイルをメモ帳で作成する場合は、保存時にエンコードをANSIに、WinActor側ではファイルフォーマットをAscii形式にしてください。

これで、読み込んだ結果がstrPromptに入ります。
ちなみに、プロンプトはこんな感じです。
次の単語を「ジョジョの奇妙な物語」の用語かそうではないかを判定し、JSONで返してください。
単語=$keyword$
制約事項
・JSON配列形式で回答すること。
・回答に単位は含めない。
・回答の数値項目は、数値のみとする。
JSON配列の形式
・配列のキーは付与しない。
・メンバーは、以下の2つとする
・origin : 入力された単語
・jojo : 判定結果(ジョジョの奇妙な物語用語の時1、そうではないとき0)
「$keyword$」のところを、Ambientから取得した値で置換します。
また、出力をJSON配列形式で取得するように指示しています。こうすることで、ChatGPTからの返答が安定しますし、JSONで返ってくるためシナリオ内でのデータの扱いが非常に楽になります。


下の「promptの置換」は、OpenAI APIに渡すプロンプトに決まったルールがあるためです。
jsonMessageは、シナリオの冒頭の初期設定として下記のようにしてあります。変数値設定ノードを用いて、jsonMessageには、下記のような文字列(JSON)を設定しています。この中の$prompt$を、実際に問合せしたいプロンプトに置き換えているのが、上記の処理です。

続いて、OpenAI APIを叩きます。
①では、HTTP(詳細)を使いましたが、ここではHTTPライブラリを使います。理由は…
「プロンプトに改行コードが含まれていると、正しく処理されなかった」からです。自分のやり方が間違っていたのかもしれませんが、プロンプトに改行コードが含まれない場合は、ちゃんと返ってくるのですが、含まれている場合はエラーが返ってきてしまいました。
そのため、ここではHTTPライブラリを使用しています。
※OpenAI APIの叩き方については、こちらも参考にしてください。

基本設定は、Ambientの場合とあまり変化はありませんね。
メソッド:POST
URL:テキスト生成の場合のURLはこちらになります。
要求タブ(ヘッダ)
OpenAI APIを叩く時のお約束ですので、このまま設定して頂いて大丈夫です。1つだけ、Authenticationに設定する%APIKey%だけは、自身のAPIキーを変数指定しておいてください。
要求タブ(ボディ)
ここも、OpenAI APIを叩く際のお約束になります。
temperatureは、0~2の間で指定でき、0になるほど回答にブレがなくなり、2に近づくほど回答がブレるようです。
応答タブ(ボディ)
こちらは、取得したJSON値からchoices要素を取り出す指定になります。
{
"id": "chatcmpl-8XrmVLjGwqeQbtJs02OKYgrViJP8i",
"object": "chat.completion",
"created": 1703082251,
"model": "gpt-3.5-turbo-0613",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "{\"Prefecture\": \"石川県\", \"Population\": 10, \"AverageTemperature\": 14, \"TouristAttractions\": \"金沢城、兼六園、21世紀美術館\"}"
},
"logprobs": null,
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 186,
"completion_tokens": 55,
"total_tokens": 241
},
"system_fingerprint": null
}
今回の例ではありませんが、OpenAI APIに問合せると、正しく処理された場合は上記のようにchoices[0].message.contentに回答が格納されて返ってきます。
HTTP(詳細)ライブラリだと、上記のようにフルパス指定で一発で取得できるのですが、HTTPライブラリはフラットなJSON配列しか取り扱えないため、一旦、choicesを抜き出すこととしています。
※以前の記事では、一旦ファイルに落とすようにしていましたが、今回はあえて変数に格納するようにしてみました。
JSON解析①
得られたJSON配列からフラットな状態にするため、まずはインデックス0の値を、strAnsJsonに格納します。

次に、messageの中身をstrMessageJsonに取得します。

最後にcontentで抜き取ることで、本来欲しかった結果がstrContentに格納されます。

[
{"origin": "ジョジョ", "jojo": 1},
{"origin": "お疲れ様", "jojo": 0},
{"origin": "ChatGPT様〜", "jojo": 0},
{"origin": "スライドに送る方法", "jojo": 0},
{"origin": "スライドに送る方法", "jojo": 0},
{"origin": "これ、おもしろい!", "jojo": 0},
{"origin": "Ambient", "jojo": 0},
{"origin": "いぇい", "jojo": 0},
{"origin": "いっぱい送りたくなる", "jojo": 0},
{"origin": "10文字バリデむずい", "jojo": 0},
{"origin": "これすごい", "jojo": 0},
{"origin": "えええええ!?!?", "jojo": 0},
{"origin": "楽しみ!!おきなか", "jojo": 0},
{"origin": "ぼざろ", "jojo": 0},
{"origin": "登壇ありがとうござい", "jojo": 0},
{"origin": "がんばれ!", "jojo": 0},
{"origin": "かーでぃさんお話めち", "jojo": 0},
{"origin": "#LINEDC", "jojo": 0},
{"origin": "#LINEDC", "jojo": 0},
{"origin": "#LINEDC", "jojo": 0}
]
JSON解析②&エクセル転記
最後の処理ですね。
この繰り返しの中で上記JSONを1レコードずつ取得し、エクセルに転記していきます。

02_JSON - JSONオブジェクト 配列指定 値の取得ライブラリを用いて、上記JSONを1レコードずつ取得し、strRecordに格納します。

02_JSON - JSONオブジェクト 値の取得ライブラリを使って、origin項目を取り出してstrOriginに格納します。

同様に、jojo項目の値をstrJojoFlgに格納します。
これでOpenAI APIから得られたJSONより、指定された行(ix)のorigin / jojoの値が取り出せました。
次は、この値をエクセルに転記していきましょう
エクセル操作 値の設定2ライブラリを使って、strOriginの値をA列に、strJojoFlgの値をB列に書き込んでいきます。


処理として以上になります。
これで、Ambientから値を取得し、OpenAI APIに投げ、その結果をエクセルに出力することができました。
4.最後に
APIを叩くためにはHTTP/HTTP(詳細)と2つのライブラリがあります。HTTP(詳細)ライブラリの方が、より細かな指定ができるのですが、動作の安定性としてHTTPライブラリの方が(現時点では)安定してるっぽい気がします(先ほども書きましたが、プロンプトに改行があるとエラーになるなど)。
一方で、JSONライブラリは01系と02系があり、02系の方が新しいライブラリのようですが、現状では01系も使いつつ、という感じがします。
恐らくですが、HTTP(詳細)の動きが安定してくると、目的の値(choices[0].messages.content)をHTTP(詳細)で直接指定が出来るようになります。そうなれば、そこにあるJSONは、02系だけで処理ができるんじゃないかと。
ただ現状、HTTP(詳細)の動作が安定していないため、HTTPライブラリも併用する必要があり、結果、JSONライブラリも01系と02系を併用することになっているんじゃないかと思うのですが…ATさん、どうでしょ??
API連携できると、他のソリューションとのデータのやり取りが非常に安定しますので、この辺りの情報整備はしていきたいですね(ATさんからも公式情報を是非ー)。
いいなと思ったら応援しよう!
