実測記録

AIに家を設計させたら、自分の実装の欠陥が4つ見つかった

直したのは、AIの設計力ではなく、こちらの仕組みでした。 住宅設計のループに「設計する役」「審査する役」「裁定する役」「直す役」を置き、点数は言語モデルではなく法規・構造の決定論エンジンに計算させました。同じ敷地・同じ主題で、断熱レバーを足す前と後を比べると 25.3点 → 82.2点。別の主題では 91.0点(その敷地の到達可能上限は96.2点)。数字が動く一方で、自分のコードの欠陥が4つ出てきました。その記録です。

公開 2026-11-01
対象 bim.house / mu-house
実行 ローカルOllama 14B
外部API料金 0円(ローカル実行)
要点を70秒にまとめた解説動画(ナレーション: 本人の声/字幕付き)
動画の文字起こし(全文)

AIに家を設計させて、実際に何件も回してみました。その途中で、自分の実装の欠陥が4つ見つかりました。設計する役と、審査する役を分けました。審査役には、設計者の意図を見せません。仕様と実測値だけを渡します。採点は言語モデルではなく、法規と構造の決定論エンジンが行います。最初の実走では、どの案も20点台でした。原因は、寒冷地で断熱性能が足りないこと。ところが仕様に断熱の項目が無く、直しようがありませんでした。断熱の段階を追加したら、同じ敷地で82点まで上がりました。2つ目は、敷地の一覧と実行でIDが食い違っていたこと。3つ目は、90点が原理的に届くのか分からなかったこと。全探索を足して96点と分かりました。4つ目は、自動修正が点を最大化してしまい、審査の仕事を奪っていたこと。最終的に、札幌の117平米の敷地で、法規適合のまま91点まで届きました。クラウドのモデルは鍵が無効で、まだ試せていません。

25.3 → 82.2 → 91.0 (札幌117㎡/上限96.2)

先に結論:見つかった欠陥は ①仕様に断熱のレバーが無い ②敷地IDが母集団 n に依存する ③到達可能な天井が未知 ④自動修復が最大化だと敵対ループが空回りする、の4つ。以下、それぞれの症状と直し方です。

なぜ「敵対的」にしたのか

同じモデルに設計させ、同じモデルに褒めさせると、点数は上がるが家は良くならない。

最初にぶつかったのは、ごく普通の失敗でした。言語モデルに設計案を出させ、その案を言語モデル自身に評価させると、もっともらしい点数が返ってくる。ところがその点数は、法規に適合しているかとも、構造が成り立つかとも関係がありません。モデルは文章として筋の通った評価を書くのが得意で、それは「家として成立している」ことの証明にはならないからです。

そこで役割を4つに割りました。

役割やること見せないもの
Proposer(設計)敷地と主題から案を作る—
Adversary(審査)仕様と実測値だけを見て欠陥を指摘する設計意図・作品の物語
Judge(裁定)指摘のうち採用するものを選ぶ指摘の「勢い」
Reviser(修正)採用された指摘だけを反映する—

審査役に設計意図を見せないのが要点です。「自然と共に呼吸する家にしたい」という物語を渡すと、審査役はその物語に引きずられて、都合の良い評価を返します。仕様と実測値だけを渡すと、指摘は具体的な欠陥に寄ります。

裁定(Judge)はLLMですが、自由度はここだけに閉じています。審査役の指摘は「対象軸・深刻度・根拠となる実測値」の形で受け取り、①決定論エンジンの判定と矛盾する指摘は、Judge に渡す前に機械的に捨てる(法規適合なのに「法規NG」と言う指摘など)。②残った指摘から、実測と矛盾するもの・単なる好み・重複を落とし、最大4件まで採用する。点数には一切触れさせません。

そして点数は、言語モデルには一切書かせません。採点は決定論エンジンだけで行います。

同じ仕様を入れれば同じ点が出ます。モデルが「92点です」と言う経路は存在しません。

欠陥1:断熱にレバーが無かった

寒冷地で全案が20点台。原因はAIではなく、仕様の項目不足でした。

最初の実走は散々でした。札幌の117㎡の敷地で「雪国の家」を作ると25.3点、法規は不適合。「継ぐ家」も24.9点。複数まわしても20点台から抜けません。

レポートを読むと、原因ははっきりしていました。寒冷地では断熱性能(UA値)が法規の適合条件に入ります。ところが当時の仕様には断熱の項目そのものが無く、どんな案を出してもUA値を満たせない。つまりAIは「直せない問題」を延々と解こうとしていたわけです。

そこで仕様に断熱の段階(標準/高断熱/超高断熱)を足しました。同じ敷地・同じモデルで、82.2点まで上がりました。点数が上がったのは、AIが賢くなったからではなく、正しいレバーを渡したからです。

ここで分かったこと:エージェントが悪いのではなく、行動空間が閉じていることがある。点数が伸びないときは、まず「伸ばす手段が仕様に存在するか」を疑う。

欠陥2:敷地IDが、母集団サイズ n に依存していた

同じIDでも、n が違うと別の土地になる。ここは「踏みかけた罠」です。

敷地は jp-01-0000 のようなIDで指定します。このIDは、日本の敷地を何件生成するか(母集団サイズ n)によって割り当てが変わります。--list-places で一覧を出すときと --place で実行するときで n が違うと、同じIDが別の土地を指します。

これは実走の数字を比べるときに致命的です。「同じ敷地で25.3点から82.2点に上がった」と言いたいのに、実際には違う土地を見ていた可能性があるからです。duel の実装では、一覧と解決の両方を n=3000 に固定してあります(src/main.rs の --list-places と --place 解決)。実装当初から同じ n を使うように書いていたので、今回の実走で数字が壊れたわけではありません。

それでも書いた理由:この種のIDは、片方だけ別の n で書くと静かに壊れます。エラーも警告も出ず、数字だけがずれる。だから「なぜ n を固定しているか」をコードのコメントと記事の両方に残しました。

欠陥3:90点が原理的に届くのか知らなかった

目標を掲げる前に、天井を測る。

ループの目標は90点にしていました。しかし、その敷地でそもそも90点に届くのかを知りませんでした。届かないなら、何ラウンド回しても無駄です。

そこで --ceiling を足しました。その敷地で取りうる構成を全探索して、到達可能な最高点をLLMなしで計算します。札幌の117㎡では96.2点。所要は約9秒です(time 実測: real 9.106s / user 8.84s)。

これで「目標90、天井96.2、だから届く」と根拠を持って言えるようになりました。逆に、天井が目標を下回る敷地なら、生成器の拡張が必要だと分かります。

欠陥4:自動修正が、審査の仕事を奪っていた

不適合を直す処理が「最大化」だと、敵対ループが空回りする。

言語モデルの案が法規不適合だったとき、決定論的な修復処理で合法化します。このとき、形・階数・素材は保ち、しかけ(features)と断熱だけを変える設計にしました。理由は、スコアを最大化する修復にすると、常に天井の構成に張り付いてしまうからです。

もし修復が最大化を狙うと、どんな案を出しても最終的に同じ最良構成に落ちます。すると審査役が指摘する余地も、修正役が改善する余地も消え、ループはただの往復になります。「合法になる最小の変更」に留めることで、改善の余地を残しました。

最終的な実測

すべてローカルの qwen2.5:14b で実行。クラウドモデルは鍵が無効で未検証です。

段階主題総合法規/構造何を変えたか
初回雪国の家25.3不適合/適合—
断熱の段階を追加雪国の家82.2適合/適合仕様に断熱を追加
全探索で天井を測定(構成の全列挙)96.2適合/適合到達可能上限の確認
ループ実走継ぐ家91.0適合/適合1ラウンドで目標到達

※各条件1回のみの実測です(n=1・分散未測定)。25.3 と 82.2 は同一主題・同一敷地の別実行(断熱レバー追加の前後)で、同一実行内の推移ではありません。91.0 はさらに別主題の値なので、82.2 と 91.0 の差を「改善幅」として読まないでください。

スコア推移(縦軸0〜100) 100 75 50 25 0 天井 96.2 25.3 初回 82.2 断熱を追加 91.0 ループ実走 全探索の上限
札幌 jp-01-0000(117㎡)での実測。縦軸は0〜100点。赤い点線がその敷地の到達可能上限。

91.0点は「継ぐ家」を1ラウンド回して到達した値です(初期案85.3 → 審査役の指摘1件を採用 → 91.0で目標到達、LLM呼出4回)。天井の96.2には届いていないので、まだ改善の余地があるということでもあります。

なお、91.0点の案は延床93.4㎡・概算5,604万円。天井構成は延床98.7㎡・概算7,107万円でした。点数の高い案が常に望ましいわけではなく、面積と費用のトレードオフは別途見る必要があります。

重要な留保:このループが上げるのは設計案の質だけです。法規・構造の判定は決定論エンジンによるスクリーニングであり、建築確認申請の受理・構造安全性・着工可能性を保証するものではありません。実際の建築には建築士の確認と申請が必要です。

未確認のこと

できていないことを、できたことと同じ欄に書かない。

使うなら

同じ構造は、点数を機械で出せる領域ならどこにでも移植できます。

# 敷地の一覧(母集団 n は統一済み)
mu-house duel --list-places --limit 20

# その敷地の到達可能な最高点を先に測る(LLM不要・約9秒)
mu-house duel --place jp-01-0000 --ceiling

# ループを回す
mu-house duel --place jp-01-0000 --theme 継ぐ家 --target 90 \
  --rounds 4 --max-calls 12 --out /tmp/duels   # max-calls = LLM呼び出しの総予算

# 複数主題をまとめて
mu-house duel --place jp-01-0000 --themes "雪国の家,継ぐ家,一人と猫の家" --out /tmp/duels

大事なのは、点数をモデルに書かせないことと、点が伸びないときに仕様側のレバーを疑うことでした。今回見つかった4つの欠陥は、どれもコードを読んでいるだけでは気づけず、実際に回して数字を並べて初めて見えたものです。

この仕組みを自分の敷地で回す

Proposer / Adversary / Judge / Reviser の分離と、決定論スコアラ。手元の Ollama で動きます(クラウドの鍵は不要)。

bim.house で同じ流れを試す

このループの実体は mu-house(Rust製)。bim.house はその設計画面です。

関連: AIに電卓を渡したら、答えを聞き直すのをやめた / 公開ベンチマークと真逆の結論を出した:1回の測定で「最安モデル」と断定した失敗 / 検証器はすでに知っていた

実行環境: macOS / mu-house (Rust) / ローカル Ollama qwen2.5:14b-instruct-q4_K_M / 敷地 jp-01-0000(北海道 札幌周辺 #1・117㎡・第一種中高層住居専用地域)/ 実走日時 2026-11-01 00:11〜02:08 UTC。数値は各レポートの 総合 行から転記。