ChatGPTでリファクタリングをした時の話

:::note warn
この記事は2024年10月15日に弊社ブログにて公開されたものを移植したものです。
古い情報が含まれている可能性がありますのでご注意ください。
:::

本記事はChatGPTを利用したリファクタリングの内容となっています。備忘録的な内容となっていますが、参考になれば幸いです。

## はじめに
社長より会社の過去資産の利用と、生成AIによるリファクタリングの調査をできないかという提案をいただきました。そこで、PHPとJavaScriptで書かれている生産管理のブラウザアプリケーションをChatGPTでリファクタリングを行いました。ChatGPTでリファクタリングを行ったときに気づいた点や、気を付けなければいけない点をまとめています。

今回 **リファクタリングを行っていた期間が5月～7月頃** となっています。設定や使用モデルが最新のものではない点にご了承ください。何もわからない状態から始めたリファクタリングの備忘録となっていますが、参考になる方がいれば幸いです。

## リファクタリングで何をやったかの話
### 事前準備
リファクタリングを行うにあたり三つの目標を立てていました。
* phpからJavaへ変換すること
* JavaScriptファイルは可能な限りそのまま使用するようにすること
* DockerのJava環境で、Spring bootとThymeleafを利用し、元の機能と同じような動きを目指すこと

Java、Spring boot、Thymeleafを採用した理由は二点あります。
* 社内の別プロジェクトで既に使用されていたため、そこで得た知見を活かせる点
* Spring bootとThymeleafはJavaScriptファイルと互換性があり、これ再利用を容易という点

コスト削減や工数短縮の観点から、JavaScriptファイルはそのまま使用する方針を取りました。

作業手順は下記の流れで行いました。

* リファクタリング先環境を作成
* ChatGPTの準備と対象ファイルの調査
* ChatGPTに対象ファイルを渡してリファクタリング
* リファクタリングしたコードを既定のフォルダに配置
* エラー箇所を修正していく
* 実行

### とりあえず一回行ってみる
事前準備を終えたところで、いよいよリファクタリング作業に取り掛かりました。当時のChatGPTでは「モデル改善」機能をオフにすると、作業中の履歴が残らない状況でした。さらに、今では実装されているメモリ機能もまだ存在していなかったため、セッションを閉じるとすべての作業履歴が消えてしまう状況でした。このため、効率的に進める必要がありました。

ビュー部分からリファクタリングを進め、その後にロジック部分へと着手しました。初めは問題なく進んだものの、作業が進むにつれて、変換された変数や関数、クラス名などの名称に整合性が取れなくなり、混乱が生じました。ChatGPTに修正を依頼しましたが、手作業での修正にも多くの時間がかかり、結果として効率が悪くなってしまいました。

この時自分の進め方に問題があることに気づき、もっと適切な方法があるのではないかと感じました。その後ChatGPTにアップデートが入り、履歴保存機能やメモリ機能が追加されました。これらからリファクタリングを再度行うことを決めました。

### 再度リファクタリングを行う
ビュー部分からリファクタリングを始めたのは良くないと感じたため、まずはロジックから、その後にビューをリファクタリングするようにしました。またメモリ機能が使えるようになったため、「できる限り変数、関数、クラス名を変更しないでリファクタリングする事」と覚えてもらいました。これによって渡したコードやファイルごとに違う変数、関数、クラス名が使われることがかなり少なくなりました。

### リファクタリングしてからエラーの修正作業へ…
一回目よりも良いリファクタリング結果が出ましたが、Java環境で実行するとエラーが出ました。一旦は問題なく変換されているようにみえますが、よく確認すると存在しない関数を呼び出していました。この修正がかなり多く、一番追記したのはゲッターセッターでした。またエラーではありませんが、変換時に生成された関数やライブラリが最新ではない場合もあるので確認が必要です。

### リファクタリングまとめ
* リファクタリング前に **事前準備が必要**
* リファクタリング中は **根気が必要**
* 修正するには両方の **言語知識が必要**

リファクタリングをする前に事前準備を念入りにしておく必要があると感じました。これはリファクタリングの先の環境や、条件、リファクタリング対象確認などです。これらをきちんと決めていないと、手戻りが起こりやすくなってしまいます。また元のコードやファイルをできるだけ生かすのか、それとも元に新規で作成するのかというのもリファクタリング手順に関わってきます。

リファクタリング中は行う順番やコード、ファイルの渡し方など考えながら行わないといけません。また発生したエラーを解消するために、内容を読み修正それら対応し考えていく必要があります。0からコードを書くのとは違い元のコードと見比べながらの作業も必要です。

修正作業時や見比べての作業が発生するので、思った以上に両方の言語知識が必要です。今回Java以外に関して知識が殆ど無く、PHPの理解や、Spring BootやThymeleafの使い方や苦労しました。元の言語とリファクタリング先言語の基本的知識や違い、使用フレームワークやライブラリの知識があるとだいぶ楽になると思います。

## ChatGPTで何やったかの話
リファクタリングにChatGPTを使っていたのですが、期間中にメモリ機能というものが追加されました。使用してみると、いままでより使いやすくなっていました。メモリ機能の使い方やポイント、良かった点を紹介していこうと思います。

### ChatGPTを使う前に
ChatGPTは初期の状態では、会話の内容をモデル学習に使用される設定になっています。学習されたくないという方は、学習されないように設定しましょう。設定の中にデータコントロールがあります。その中の、「すべての人のためにモデルを改善する」という項目をオフにします。これで学習されなくなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3904804/1dd2109e-78d3-9eec-697c-5bedde079bea.png)

### メモリ機能を使う準備
ChatGPTを使う際、返答内容を望んでる形に近づける為会話の最初にルールや条件を入力することがあります。その会話の中ではルールや条件に沿って返答が来ますが、新規の会話を始めるとまたルールや条件を入れなおさないといけません。そこでメモリ機能です。メモリに記憶させた内容は、記憶させた後の会話全てに反映できます。メモリに覚えさせておくことで、会話の最初にルールや条件を入力することなく、会話を始められます。そんなメモリ機能ですが、デフォルトでオフになっています。設定の中のパーソナライズにメモリ項目があるので、オンにしましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3904804/aa9e5436-a3f4-d864-dfa8-8ebf4ac925b1.png)

メモリに記憶させるには、記憶してもらいたい文言をChatGPTに送らなければいけません。その際に覚えてもらいたい文言のほかに、ChatGPTへ記憶するよう指示をした文言も一緒に送らないといけません。例としまして「記憶してください」、「ChatGPTへの要求」という文言をつけると、メモリ更新しましたというメッセージが出ます。これが出たらメモリに記憶されたことを表しています。このメモリ更新しましたという箇所をクリックすると、どのような内容がメモリに記憶されたかを確認できます。内容が気に入らなかったり、間違えている場合は削除し、再度メモリに覚えてもらうようにしましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3904804/e593c261-4d0e-a4f4-9075-00b787378d5e.png)


### メモリ機能の活用例
今回リファクタリングの時にメモリに下記の三つを覚えて貰いました。

* 会話ルール
* リファクタリングルール
* フォルダ構成情報

まず会話ルールです。抽象的な回答ではなく具体的な回答を出すようにお願いしたり、不足している情報がある場合質問や確認をするようにお願いしました。また場合により英語で回答することもあったので、日本語で回答するようにお願いしました。

次にリファクタリングルールです。どのような環境で動かしたいかを伝えたり、渡したコードやファイルを全部変換するように伝えたり、関数やクラス名等をできるだけ変えないように伝えたりしました。これらを伝えておくことで、元コードとの確認が楽になったり、関数やクラス名等の整合性がとりやすくなりました。

最後にフォルダ構成情報です。元の環境とリファクタリング先環境の構成を渡しておくことで、importパスを最初から正しく書いてもらえたり、どこに配置するべきかも出してくれたので、その後の作業が時短されました。これらを覚えさせておくことでリファクタリングもですが、そのあとの修正の時にも改めて情報を渡さずに会話をすることができ非常に楽になりました。

### メモリ機能まとめ
* メモリ機能は **回答の方向性** を決めるのに使える機能
* メモリに記憶があると **回答の精度が上がる**
* 完全には **コントロールはできない** 点に注意

メモリ機能があることで、なかった時に比べて求めた回答を出してもらいやすくなりました。ただメモリ機能があるからと言って絶対その通りに返ってくることもないです。あってない回答の時は再度出してもらうことも必要です。自分の求める回答をしてもらうために細かくメモリに記憶させる内容を調整してみてください。

## 最後に
今回のリファクタリング作業を通じて、事前準備や根気強さ、そして両言語の知識が重要であることを改めて実感しました。特にChatGPTのメモリ機能を活用することで、作業の効率が向上し、リファクタリングやエラー修正の際の整合性を維持でき良かったです。リファクタリングを行う際は、事前の計画と適切なツールを活用しながら、柔軟かつ慎重に進めることが成功の鍵だと感じました。

この備忘録が同じような課題に取り組む方々に少しでも役立つことを願っています。AIの力をうまく活用して、効率的なリファクタリングを行ってください。