【実録】ChatGPT と格闘して BizRobo! の拡張機能を作ったが、こういう感じ？

## はじめに

前回 ChatGPT を軽く触ってみた感想を書きましたが、やっぱりもう少し可能性を探ってみようかなと思い今回は実際に利用できそうなサンプルプログラム作成に挑戦します。

https://qiita.com/ParakeetOnTheHead/items/f5ab12a5d72f57145ca0

## 拡張機能？の整理

実際に使えそうなサンプルと言ってもすぐには思い浮かびませんが、先日社内のチャットで偶然目にした「BizRobo!でCSVをExcelに変換するにはどんな方法がある？」というやり取りに着想を得ました。

ということで今回は BizRobo! がCSVファイルををExcelファイルに変換する機能のサンプルを ChatGPT と一緒に作っていきます。

まじめに考えると「●●の場合は？△△の場合は？」など細かにケースを挙げたうえで要件を整理する必要がありますが、今回はシンプルに以下の通りとします。

- CSVファイルをExcelファイルに変換して同名ファイルで出力できること。
- ファイル読み込み時の文字コードを「UTF-8」か「Shift_JIS」で選択できること。
- Webのフロントエンドだけで動作すること。

値が `"` で囲われていてもいなくても、値の中に `"` や `,` や `\n` が混ざっていても今回は特にケアしません。

:::note
BizRobo! の拡張機能といえば `コネクター` が思い浮かびますが、今回はもっと手軽に BizRobo! をパワーアップさせる方法として BizRobo! 内蔵ブラウザエンジン[^1]の機能を使ったWebページ生成を前提とします。
:::

## 完成後のイメージ

下のコードをコピーして使います。テキストエディタに張り付けて保存すれば、一般のブラウザからも試すことができます。

```html:Csv2Excel.html
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>CSV to Excel conversion</title>
  <script src="https://cdn.jsdelivr.net/npm/papaparse@5.2.0/papaparse.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.16.2/xlsx.core.min.js"></script>
</head>
<body>
  <h1>CSV to Excel conversion</h1>
  <form>
    <select id="encoding">
      <option value="utf8">UTF-8</option>
      <option value="shift-jis">Shift_JIS</option>
    </select>
    <input type="file" id="csvfile">
  </form>
  <script>
    document.getElementById('csvfile').addEventListener('change', function(e) {
      var encoding = document.getElementById("encoding").value;
      var csvfile = document.getElementById("csvfile").files[0];

      // CSVファイルをBlob型に変換
      const blob = new Blob([csvfile], { type: 'text/csv' });
      var reader = new FileReader();

      reader.readAsText(blob, encoding);

      reader.onload = function() {
        var data = reader.result;
        var parsedData = Papa.parse(data, {
              encoding: encoding
            });
        var ws = XLSX.utils.aoa_to_sheet(parsedData.data);
        var wb = XLSX.utils.book_new();
        XLSX.utils.book_append_sheet(wb, ws, csvfile.name.split(".")[0]);
        XLSX.writeFile(wb, csvfile.name.split(".")[0] + ".xlsx");
      };
      e.target.value = '';
    });
  </script>
</body>
</html>
```
Design Studio を起動して `ロボット` ファイル内に「参照/ブラウザ」ステップを追加、「アクション」を "ページ生成" に切り替えた後に「コンテンツ」ボックスに上記のコードをコピペします。 
「アプリケーション名」と「ページURL」には任意の文字列を設定してOKです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3090491/535267be-89d5-b38e-7c92-382bb6eeca48.png)
今回作った **”拡張機能”** を使用したロボットのサンプル動画も後段に掲載しておきます。

## 【実録パート】ChatGPT による実装

前稿でも触れたようにChatGPTに期待すべきは `正解の獲得` ではなく `人が考えるための手掛かりや糸口といったざっくりしたアウトライン` だと考えていますが、実験の意図として「頑張ればどこまで正解に近づけるか」を一度試してみたいという気持ちもありました。


### 要件を伝えてコードを生成してもらう

要件はできるだけ具体的に、全体を定義・整理したうえで`リクエスト`として投入します。
ChatGPT を使い始めた当初はワンフレーズで`リクエスト`を送ったり、あいまいな表現で返答を得ようとしましたが、具体的な回答を求めるならば、`リクエスト`自体もなるべく具体的に投げかける必要がありそうです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3090491/04a37d01-8603-56ee-9491-63dfeb7a68e9.png)

:::note
ChatGPTの回答精度を会話によって上げていきたいと思う場合、ベースとなる最初の回答内容がとても重要なので、もしも「あれ？」と思う回答が返ってきた場合には`リクエスト`文言を修正して、再回答を促すことをお勧めします。
:::

### フィードバックをして改善する

#### フィードバック #1
生成されたコードを実行してみたところエラーになりました。
エラー内容をフィードバックし、動作するコードの生成を再度`リクエスト`します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3090491/256a0c55-b196-b20e-7f63-a797cea08de5.png)

:::note
初回`リクエスト`で `Papaparse` とか `SheetJS` など利用するライブラリを指定していますが、その指定がない場合に修正`リクエスト`を送ると別のライブラリを使った全く違うコードを再作成することもあり、`リクエスト`のたびに振り出しに戻ってしまう感があるため要注意です。
ただ最初は「指定するライブラリなどわからん。」と思うので、別口でライブラリ情報をChatGPTに聞いておき、回答されたライブラリについては人が調査し選別しておく。。という前処理が現在のChatGPTに対して必要な人の作業かなぁと思ってます。
:::

#### フィードバック #2
回答の一部を抽出します。今度はもう一つのライブラリでリンクエラーが出ました。
1回目の回答で提供されたリンクは正常に動いていたのに、間違った情報に書き換えてしまったようです。
余計なことしやがって。。。という感じでしょうか。

具体的に修正箇所と内容を指示したいところですが、もう一度問題のみを指摘してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3090491/d80d7b7b-83cc-12c3-be87-e714b50f5d45.png)

#### フィードバック #3
OKです！ライブラリのURLは期待通り指摘した個所だけが修正されました。
ただ、再度実行してみると別のエラーが出ました。
期待を込めて「自分で考えてみろ」的な修正`リクエスト`を投げてみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3090491/a4e1d504-7fcb-7bb9-4394-9bace1225ee2.png)

:::note
「ChatGPTの生成するプログラムコードは文法的に正しいが、実行時のコンテキストによって期待通りには動かない場合もある。（静的には正しく、動的に間違いがある）」とは思わない方がいいでしょう。
今回の例では発生していませんが、平気で存在しない `メソッド` や`関数` を使ったコードを生成することもあります。
:::

#### フィードバック #4
`リクエスト`の仕方をミスりました。
やはり思考範囲を限定した具体的な指示を出さないと的外れな回答になってしまいます。
「画面からプルダウンで文字コードを選択できること」という要件が抜け落ちてしまいました。
やり直し。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3090491/477210cb-6fa6-9ebb-97c9-26cb98f71609.png)

#### フィードバック #5
あれ、また振り出しに戻った。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3090491/6c6f7e03-e316-659e-3c6e-e35ea50ec5cd.png)

#### フィードバック #6
アゲイン。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3090491/7ec591bb-5456-3f35-a85f-93b818b88496.png)

#### フィードバック #7
意味なくAIにキレてみる。の巻
正解がわかっていることについてはこちらが具体的に指示する必要がありますね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3090491/16b4fbe0-9209-c93f-1347-ee46b12f3792.png)

#### フィードバック #8
一歩前進し、また異なるエラーに遭遇。
今後はいきなり修正`リクエスト`を出して回答に「うぉ」とならないように、一旦AIと話し合う。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3090491/80e375b4-5f58-bf74-3cd3-bf8a301087ac.png)

#### フィードバック #9
良い感じなので、提案について具体的に話を進めてみる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3090491/36df1270-dc4a-9f2e-05ad-cfc0663b1678.png)

#### フィードバック #10
しれっと「ブッこんで」来たので、AIの提案に対してダメ出ししてみる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3090491/2297a8d5-5a08-277f-7754-323945cd2caf.png)

#### フィードバック #11
AIを詰める。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3090491/1c1cad79-3b71-d786-b8b0-c1b2063b387e.png)
ただし、AIの謝罪を読んで罪悪感。

#### フィードバック #12
気を取り直してChatCPTの提案を採用。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3090491/0f4c933b-56c7-215b-07a2-71be4b563e73.png)
ただし、これまでの文脈が吹っ飛んでおり全く提案の内容が反映されていない。
驚愕！

### 妥協点を探す
当初は会話を通して徐々にコードが改善され、完成度も上がっていくことを期待していましたが、少なくとも `2023年2月10日` 現在では状況が異なるのかもしれません。

まぁ、もしくは私の 会話スキル（Prompt Engineering Skill）が低いだけなのかもしれませんが。。。
いずれにせよこれ以上ChatGPT側にコードを生成させてもゴールに近づくイメージが持てません。

やりたいことを実現するための要素は一通り出そろったので、あとは人が対応するのがよさそうです。

フレーム問題によるものなのかもしれませんが、具体的な `部品` をChatGPTには作ってもらい、それらの組み合わせは人が行う。という役割分担が妥当な気がします。

https://note.com/sangmin/n/n170bdfd624bc

https://ainow.ai/2021/09/14/258409/

#### コードをマージしてとりあえず動くものを作る
**フィードバック #7** のコードと **フィードバック #11** のコードをマージしたうえで、プラスアルファの微調整
```diff_html
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>CSV to Excel conversion</title>
  <script src="https://cdn.jsdelivr.net/npm/papaparse@5.2.0/papaparse.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.16.2/xlsx.core.min.js"></script>
</head>
<body>
  <h1>CSV to Excel conversion</h1>
  <form>
    <select id="encoding">
      <option value="utf8">UTF-8</option>
-      <option value="shiftjis">Shift_JIS</option>
+      <option value="shift-jis">Shift_JIS</option>
    </select>
    <input type="file" id="csvfile">
  </form>
  <script>
+   document.getElementById('csvfile').addEventListener('change', function(e) {
      var encoding = document.getElementById("encoding").value;
      var csvfile = document.getElementById("csvfile").files[0];

+     // CSVファイルをBlob型に変換
+     const blob = new Blob([csvfile], { type: 'text/csv' });

      var reader = new FileReader();
-     reader.readAsText(csvfile, encoding);
+     reader.readAsText(blob, encoding);
      reader.onload = function() {
        var data = reader.result;
-       var parsedData = Papa.parse(data);
+       var parsedData = Papa.parse(data, {
+             encoding: encoding
+           });
        var ws = XLSX.utils.aoa_to_sheet(parsedData.data);
        var wb = XLSX.utils.book_new();
        XLSX.utils.book_append_sheet(wb, ws, csvfile.name.split(".")[0]);
        XLSX.writeFile(wb, csvfile.name.split(".")[0] + ".xlsx");
      };

+     e.target.value = '';
+   });
  </script>
</body>
</html>
```

### 使ってみる

<iframe width="560" height="430" src="https://www.youtube.com/embed/NLg-0J3dNHQ?controls=0" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

## まとめ

実録として見ていただいた通り、使い方によって ChatGPT といえども非常に手間がかかります。
最新のAIだからと言って何でもできるわけではなく、使う人のレベルにあった結果しか得られないのかもしれません。

AIやRPAの出現によって人の仕事がなくなるという話も依然として聞こえますが、皆さんどうお考えでしょうか。

最後に「AIが作ったコードって、そのまま業務で使っていいんだっけ？」と思い調べてみました。
本稿のコードについてはデモ以外の用途で使うことはないと思いますが、業務で実際に利用するのであれば作り直しますね。

https://note.com/tomotana/n/n4a3799b4ec66


[^1]: Classic（IE8エミュレーション）、WebKit（ES5時代の軽量版エンジン）、Chromium（ES6以降のモダンブラウザエンジン） の3種類のブラウザエンジンを内蔵しており、現在の主流は Chromium です。内蔵エンジン以外のブラウザを操作する場合にはその他のRPA製品と同様にデスクトップ環境を用意していただき、一般のWindowsアプリケーションに対してするように、デスクトップ上でその端末にインストールされているブラウザソフトを操作します。内蔵エンジンによるWeb操作はサーバ側で実行されるため別途実行用の端末を準備する必要はなく、この点が「BizRobo!はバックグラウンド処理」と言われる所以でもあります。