RevitアドインをAIで作る(Google NotebookLM編) #008

Google NotebookLMとは

GoogleのAIであるGeminiは名が知れていますが、Google NotebookLMは有名ではありません。これはGoogleの画面を開いたときにブラウザの右上に出る実験フラスコのアイコンから行けます。Search Labsというサービス群です。無料。

Search Labsの中のその他にGoogle NotebookLMがあります。

今すぐ試すを実行します。

では試してみよう

NotebookLMを試すを実行

「ノートブックを新規作成」を実行します。

まずNotebookLMに知識を提供する

NotebookLMは資料をアップロードするとそれをもとにAIが結果を出してくれるものです。もちろん世の中にある情報はプレトレーニングしたAIなのでかなり知識はもっており、それに自分の専門知識をさらに教える的な構造です。つまり、ChatGTPなどのように世の中の幅広い情報からだけ汎用的な結果を出すのではなく、自分の教えたことがベースになり、さらに専門的、特化的なことをさせることができます。上記の画面で提供する情報をPDFなどでアップロードします。私の場合には自分で執筆したRevitアドインの書籍をPDFに変換してアップロードします。ここにアドインの作り方やサンプルコード、解説が書いてあります。これ勉強しておいてという感じです。

お題を出す

NotebookLMはアップロードした資料を読み込んで理解します。概要を提示してくれます。丸に→のボタンの左にはやって欲しいことを書きます。私が書いたのは次の内容です。この本には「モデルから部屋一覧を抽出する」、「1つの部屋を指定したときに天井を作る」という2つのテクニックを説明しています。ここで与えた課題はそれら2つを組み合わせて一段階レベルの高い応用アドインを作って欲しいというタスクです。

「この情報を元にRevit2025を使って次の機能を発揮するアドインプログラムのコードを書いてください。実現したい機能は「現在開いているモデルの中から部屋を全部抽出します。全部の部屋に天井を自動で作成します。天井高さは部屋名に事務室または会議室という言葉が含まれていたら天井高さ2800mm、その他の部屋名の場合には天井高さ2600mmとします。」

回答が出てきた

すぐに次のような回答が返ってきます。NotebookLMはもらった資料のどの部分を参考にして考えたか根拠を示してくれるのでわかりやすいです。

もちろん回答には次のようにコードが書かれています。これをコピーしてエラーなく実行できるのか確かめてみましょう。

コードの説明とポイントもよく書かれています

実行してみよう、動くかな?

Visual Studioを立ち上げてアドインのプロジェクトを作り、NotebookLMが作ってくれたコードを貼り付けます。とりあえず明らかなエラーはありません。(今のところ)

ビルドも問題なくできました。

Visual StudioからRevitを立ち上げてデバッグします。簡単なモデルを作ります。

作ったアドインを実行してみます。

エラー発生!

しかし91行目でエラーが出て停止しました。理由は「BoundarySegmentのListをBoundarySegmentには変換できない」ということです。

ちなみに画面右半分ではGithub Copilotという別のAIにこのエラーの解決手段を提案させましたが、ずいぶんとややこしい提案をしてきたので採用しませんでした。これをやっていくと泥沼に入りこんでしまう場合もあります。

原因究明

NotebookLMが作ってくれたコードの問題の部分周辺は次のとおりです。foreach (BoundarySegment segment in boundaries)が問題個所でその前に宣言されているとおりboundariesはBoundarySegmentのIListのIListなのです。foreach で取り出した項目はBoundarySegmentのIListのはずです。しかしsegmentは1つのBoundarySegmentになっています。それらが不整合だと言っています。

また、if文でboundaries.Count == 0という条件がダブって書かれています。これは無駄です。

// 2. 部屋の境界線を取得し、CurveLoopを作成する
 SpatialElementBoundaryOptions options = new SpatialElementBoundaryOptions();
 IList<IList<BoundarySegment>> boundaries = room.GetBoundarySegments(options); //

 if (boundaries == null || boundaries.Count == 0 || boundaries.Count == 0)
 {
     log.AppendLine($"警告: 部屋 '{roomName}' (ID: {room.Id}) の境界が取得できなかったためスキップします。"); //
     skippedCount++;
     continue;
 }

 CurveLoop curveLoop = new CurveLoop();
 foreach (BoundarySegment segment in boundaries)
 {
     curveLoop.Append(segment.GetCurve());
 }

私の本の該当箇所を確かめてみました。foreach (BoundarySegment segment in boundaries[0])となっていて、NotebookLMが作ったコードは間違っています。boundaries[0]としてIListの最初のBoundarySegment を取り出しているのでエラーにはなりません。

部屋の境界をroom.GetBoundarySegments()メソッドで取り出しますが、部屋の境界は基本的には構成する壁のラインになります。しかし部屋の中に柱があれば柱の周囲も境界セグメント(BoundarySegment )になります。そんなわけでBoundarySegment のリストは複数になるというのが一般解です。私のコードは後側の壁の境界だけを検出して天井を作っています。

この例では、NotebookLMの足りない点は「コード内の整合性のチェックが弱い」「Revit APIをきちんと確認していない」点だと思います。エラーの原因を解明するにも時間がかります。

// 2. 部屋の境界線を取得し、CurveLoopを作成する
 SpatialElementBoundaryOptions options = new SpatialElementBoundaryOptions();
 IList<IList<BoundarySegment>> boundaries = room.GetBoundarySegments(options); //

 if (boundaries == null || boundaries.Count == 0 )
 {
     log.AppendLine($"警告: 部屋 '{roomName}' (ID: {room.Id}) の境界が取得できなかったためスキップします。"); //
     skippedCount++;
     continue;
 }

 CurveLoop curveLoop = new CurveLoop();
 foreach (BoundarySegment segment in boundaries[0])
 {
     curveLoop.Append(segment.GetCurve());
 }

再度実行だ!

エラー原因を修正してから再度実行したところ次のようにアドイン実行完了メッセージが出ました。

モデルを確認します。

もしかして、もっとよく教えるとよくできるようになるのか?

最後に私の本の内容で、部屋境界の説明をさらに書き加えてPDFにして再アップロードしてNotebookLMに同じことを命令しました。つまり、よく教えればエラーは無くなるのか?を確かめたかったのです。

結果は次のとおり、foreach (BoundarySegment segment in boundaries)が間違ったまま、if (boundaries == null || boundaries.Count == 0 || boundaries.Count == 0)と条件がダブったまま。

// Step 4: 部屋の境界線を取得し、天井の輪郭 (CurveLoop) を作成 (9-6章のパターンを参考)
SpatialElementBoundaryOptions options = new SpatialElementBoundaryOptions();
IList<IList<BoundarySegment>> boundaries = room.GetBoundarySegments(options);

if (boundaries == null || boundaries.Count == 0 || boundaries.Count == 0)
{
    // 部屋の境界が取得できない場合、スキップ
    continue;
}

// 部屋の外形 (boundaries) から CurveLoop を作成
CurveLoop curveLoop = new CurveLoop();
foreach (BoundarySegment segment in boundaries)
{
    curveLoop.Append(segment.GetCurve());
}

コードを修正して動くようにして再実行すると次のようになりました。完了メッセージも何故か変わっています。結果として天井は作成されましたが。

これを見ると、同じことを命令しても「全く同じコードを回答するとは限らない」ということです。

まとめと感想

以上の結果から

  • NotebookLMは「完ぺきではない」、しかし95%くらいのレベルにはもっていってくれるので効率は上がる
  • NotebookLMは自分の提供した資料を読み込んで動くので想定内の動きをするので理解しやすい
  • コーディングはAIのほうが速くてうまいので人間の仕事ではなくなるだろう
  • 人間はAIに教えるための資料、知識を高い水準と正確性で記述することが役目
  • 人間のチェック作業の効率化が必要
  • NotebookLMを自分の部下だと考えたときに、頼んだ仕事を何も尋ねずいきなり最後までやってしまうので結果を見ないと〇か×か分からない。大体の場合は×だが。人間なら「先輩、これはこういうやり方でいいですかね」と途中で何度も聞いてから段階的にやるがAIは違う。また、やることがその場限りなので前の経験を積み重ねて、同じ轍を踏まない的な行動ができない。AIは自分のノートをたっていないんだな
  • NotebookLMはポテンシャルはあると思うがもう少し修行する必要があると思う。


コメント

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です