【Revit×ChatGPT】ChatGPTにRevitを操作させる

AMDlab河野です。

皆さんChatGPT使ってますか?私は使ってます。
Revitの面倒な作業や操作をChatGPTがやってくれると楽ですよね。
今日はChatGPTにRevitを操作させる「Revit Copilot」の実装例の紹介です。
シンプルかつ大胆な作戦は以下のとおりです。

  1. Revit上でプロンプトを書けるUIを作成する
  2. ChatGPTにソースコード(RevitAPI)(C#)を書かせる
  3. ソースコードをリアルタイムにコンパイルして実行する
  4. つくったプログラムをRevitアドインにする

本当に実現できるのか?やってみましょう。
コードは以下にアップしています。
https://github.com/AMDlab/RevitCopilot
その前に、Revitアドインの最初の一歩は以下の記事をご参照くださいね。

Revitアドイン入門① – 環境構築+Revit起動時にメッセージ

Revit上でプロンプトを書けるUIを作成する

DockablePaneを利用します。
DockablePaneはRevitAPIが提供しているUIで、xamlを用いて記述でき、モーダレスに動作します。
また、その名の通りですがお馴染みのプロパティブラウザやプロジェクトブラウザにドッキングさせることができます。
モーダレスということでRevitのドキュメントを変更することは出来ませんが、今後の課題とし、今回は動くところまでいきます。
※ソースコードは以下のページを参考にしています。
https://thebuildingcoder.typepad.com/blog/2013/05/a-simpler-dockable-panel-sample.html

View(xaml+コードビハインド)とViewModelを示します。
ちなみに、xamlはChatGPTに書いてもらいました。大雑把ですが、動くものであれば良いでしょう。

xamlの以下の記述により、ViewModelの Prompt 、 CsMethod とバインドしています。
Text="{Binding Path=Prompt, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Text="{Binding Path=CsMethod, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
これにより、UIでの変更がプログラムに反映されます。
深く知りたい場合はMVVMパターンで検索してみてください。

なお、 Prompt 、 CsMethod に初期値を入れているのはデバッグで起動しなおす度に入力するのが大変なためです。

RevitCopilotManagerCompileManager に関してはロジック部分なので後述します。

ChatGPTにソースコード(RevitAPI)(C#)を書かせる

C#(.NET)からChatGPTにリクエストを送るライブラリはいくつかありますが、

This is the only .net Framework ChatGPT API You Can use

の文言に誘われてChatGPT.API.Frameworkを使います。
以下、 RevitCopilotManager の実装です。

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx はご自身のAPIKeyに置き換えてください。
重要なのは以下の部分です。

cgc.CreateCompletions(“hoge”,
“あなたはRevitアドインの開発者です。” +
“ユーザーの問い合わせに返答するためのC#クラスとメソッドを作成してください。” +
“以下のルールを必ず守ってください。” +
“・クラスは1つのみ作成する” +
“・メソッドは、クラスメソッドとして1つのみ作成する” +
“・メソッドの引数は(Autodesk.Revit.DB.Document document)とする” +
“・static修飾子は使用しない”
);

ここの第2引数はChatGPTに投げるSystemMesssageであり、ChatGPTの振る舞いを決定づけます。
この後、ChatGPTが書いたソースコードをコンパイルするので、極力コンパイルが通るようなソースコードを書いてくれるプロンプトを研究しましょう。
今回は、クラス1つメソッド1つを書かせ、メソッドの引数を Autodesk.Revit.DB.Document document とするように入力してみました。
なお、ChatGPTの返答にはソースコード以外に枕詞等の文言が入っているため、 GetCsMethodFromResponse メソッドでソースコード部分のみを抜き出しています。

ソースコードをリアルタイムにコンパイルして実行する

次に、ChatGPTが書いたソースコードをリアルタイムにコンパイルする CompileManager の実装を示します。

SystemMesssageで指定しているので、クラスが1つ、メソッドが1つ、メソッドの引数が Autodesk.Revit.DB.Document documentであることを前提としたコードとなっています。
上記条件で決め打ちでコーディングしているので、ChatGPTの書いたプログラムが指定通りになっていないと例外となります。
ChatGPTの書いたC#メソッドを呼び出しているのは method.Invoke(instance, new object[] { RevitDocuments.Doc }); 部分で、引数にRevitドキュメントを渡していることが分かるかと思います。

また、意外と重要なのが GetDllFileNames() です。
ソースコードをコンパイルするためには、利用するライブラリのdllが必要になります。
今回は使いたいライブラリをRevitCopilot.dllと同じディレクトリに格納しておき、 GetDllFileNames()で探しにいく作戦です。
この辺も、プログラムが上手く動作してから詰めていけば良いと思います。

 

つくったプログラムをRevitアドインにする

これまで作ったプログラムがRevitアドインとして動作するようにします。
今回はボタンが一つしかないため、”アドイン”(英語版”Add-in”)タブにボタンが作られるようにします。
なお、ボタンの動作はDockablePaneの表示/非表示を切り替えるものです。

 

.addinファイルの作成と設置も忘れないようにしましょう。

 

余談になりますが、 Autodesk.Revit.DB.Document などを静的クラスにまとめておくと便利なのでよくやります。
DocumentChanged イベントでドキュメントが変更されるたびに設定しなおす仕組みです。

 

完成

Revitを起動して確認してみましょう。

・アドインタブに「Switch Display」ボタンはありますか?
・ChatGPTに問い合わせることができましたか?
・ソースコード部分を抜き出すことができましたか?
・ソースコードをコンパイルして実行することが出来ましたか?

 

プロンプトを
「「「構造柱カテゴリと梁カテゴリのインスタンスの数を数えてタスクダイアログで表示してください。」」」
に変更して「Query ChatGPT」→「Execute C# Method」を試してみました。

モデルはご覧の通りですが、絶対に間違えていますね・・・。
とはいえ、ChatGPTの返答からソースコードを抜き出してコンパイルして実行する一連の流れが動作するだけでも御の字ではないでしょうか。
精度に関しては今後の課題とし、プロンプトを研究するか、LLM・GPTの更なる進化に期待しましょう。

Revit Copilot、皆さんもぜひ動かしてみてください。

ARTICLES