目的
- AI時代のプログラム開発を体験してみる。
- 「トレッドミル」状態は避けたいので、適切に制御された開発を目指す。
- 有限要素法のプログラムを対象とする。
環境
- PC
- Ubuntu 22.04 LTS
- Intel Core i9-14900K、メモリ 32GB
- NVIDIA GeForce RTX 4090 (24GB)
- ソフト
- LM Studio 0.4.16
- OpenCode 1.16.2
- Julia 1.12.6
- モデル
- Big Pickle (OpenCode Zen)
- Qwen3.6 35b A3B (qwen/qwen3.6-35b-a3b)
- Qwen3-Coder-Next (unslosh/qwen3-coder-next)
- Gemma 4 31B QAT (google/gemma-4-31b-qat)
- Glm 4.7 Flash 30B (zai-org/glm-4.7-flash)
メモ
最初Ollamaでやろうとしていたのだが、うまくいかなかったので、LM
Studioに変えた。
仕様書作成
Qwen3.6を使用して、仕様書を作成する。ここではJuliaによる2次元トラス解析プログラムの開発を目標とする。
- 仕様駆動開発を前提にして、SPEC.mdの書き方を尋ねた。
- 「要件は書かないよ」
- 要件: 何をなぜ達成するか
- 仕様: どのように実現するか
- 要件はPRD.mdなどに書くらしい。requirementsディレクトリに複数入れることも。
- ざっくり「要件」を渡したら、「粗すぎる」と怒られた。
- PRD.mdの案を書いてもらい、それを参考に書いてみて、添削してもらった。
- PRD.mdの中身を渡してSPEC.mdの案を書いてもらい、SPEC.mdを書いた。
成果物
開発
OpenCodeを使用して開発。
Big Pickle (OpenCode Zen)
/init
- Planモードでタスクリストを作成してもらう。
- Buildモードに戻して、タスクリストをtasklist.mdとして書き出して、それを参照しながら作業を進めるようにAGENTS.mdに追記してもらう。
- タスクリストに従って作業を進めるよう依頼。
- 完了には10分程度かかった。
Qwen3.6
- コンテキスト長を最大の262144に設定。
- 手順はBig
Pickleの場合と同じだが、作業を進めてもらおうとしたらAGENTS.mdをいじってばかりになったので、OpenCodeを再起動して進めた。
- tasklist.mdを更新するよう依頼。
- 完了には1時間半程度かかった。
no thinking
- 途中で進まなくなったので、OpenCodeを再起動。
- 完了には2時間程度かかった。
Qwen3-Coder-Next
- コンテキスト長を最大の262144に設定。
- 手順はBig
Pickleの場合と同じだが、途中で変なループに入って進行しなくなったので、OpenCodeを再起動して、進捗をtasklist.mdに反映してもらって、続きを進めた。
- テストを通すのにだいぶ苦労していて、完了まで3時間半程度かかった。
Gemma 4 31B QAT
- コンテキスト長を16384に設定。最大だとメモリが全然足りなかった。
- 手順はBig
Pickleの場合と同じだが、Planモードでタスクリストを作成してもらおうとすると、考えるだけ考えたあとに「いやRead
Onlyやし」と黙って止まるので、Buildモードで「考えがまとまっていたら書き出してね」とお願いした。作業をお願いしても開始してくれないので、セッションを新しくした。途中でエラーで止まったのでOpenCodeを再起動した。
- 途中で停止していた分も含めて、完了まで3時間程度かかった。
Glm 4.7 Flash
- コンテキスト長を65536に設定。
- 手順はBig
Pickleの場合と同じ。他のモデルよりもタスクリストが細かい。途中で急に止まって進まなくなったので、OpenCodeを再起動した。「タスクはすべて完了している」と主張するので、全テストを再実行させて作業を継続させた。
- 途中で思考のループに入ってしまい、どうしても進まなくなったので断念。
成果物
検証問題
天井から2本のトラスが長辺の長さが2m、天井側のトラスの角度がそれぞれ30度、60度の直角三角形の形でぶら下がっているのを下に引っ張る問題を解く。
解析解
E = 2.0e11
A = 0.0007
P = 10000.0
R1 = [-4330.127018922194, 2500.000000000001]
R2 = [4330.127018922194, 7499.999999999999]
delta = [2.264194986484148e-5, 8.450090727801568e-5]
sigma1 = 7.142857142857145e6
sigma2 = 1.2371791482634837e7
入力
nodes.csv
id,x,y
1,0.0,0.0
2,2.0,0.0
3,1.5,0.8660254037844386
elements.csv
id,n1,n2,E,A
1,1,3,2e11,7e-4
2,2,3,2e11,7e-4
bcs.csv
node_id,ux,uy
1,1,1
2,1,1
loads.csv
node_id,fx,fy
3,0.0,1e4
実行
$ julia --project=. src/main.jl
Big Pickle (OpenCode Zen)
reactions.csv
node_id,rx,ry
1,-4330.127018922194,-2500.0000000000005
2,4330.127018922194,-7500.0
displacement.csv
node_id,ux,uy
1,0.0,0.0
2,0.0,0.0
3,2.2641949864841495e-5,8.450090727801565e-5
stresses.csv
element_id,sigma
1,7.142857142857145e6
2,1.2371791482634837e7
residual.csv
scalar_value
0.0
その他のモデル
Big
Pickleと同様の結果。Qwen3-Coder-Nextは反力の数値が0になっていた。Gemma
4は拘束していない点の反力が0として出力されていた(間違っているわけではないが)。
考察
時間はかかるものの、ローカルモデルで仕様を用いたAIによる自律開発がある程度は可能であることが確認できた。
自律開発をさせるには、テスト駆動である必要がある。どういうテストにパスすれば成果物を受け入れられる(仕様を満たしているとはっきりわかる)か、ということを定義しておけば、テストを実行するだけで受け入れ可否が明確にわかり、LLMはそれに基づいて自律的に作業を回すことが(そして停止することが)できる。
仕様については、何が欲しいかという機能要件だけでなく、何が欲しくないかというスコープの限定(「静的線形弾性」「微小変形」など)、エラー時の振る舞い(同じ節点番号が2つ出てきたらどうするか)など、暗黙的だったり例外的だったりしてすぐには思い浮かばないものをきっちり明確化する必要がある。
実装対象によっては、実装詳細のある程度の明確化が必要になる場合があると考えられる。今回がそうだったかは不明だが(今回はQwen3.6がそのような仕様を提案してきた)、モデルが知らないものは実装しようがないし、知っていてもある程度は設計を指定してやることで成果物が安定するであろう。実装の技術をまったく知らなくても欲しいものが作れるかというと、そうでない場合もあるだろう。
仕様作成にしてもテスト駆動にしても、本来のソフトウェア開発の話であって、AIとは直接関係ないだが、「作りながら考える」タイプの人だと、ちょっとしんどいところがあるかもしれない。ある程度AIに丸投げしても何かしらできるかもしれないが、それだけ時間がかかったり、欲しいものにならなかったり、まったく失敗したりするだろうし、Claudeなどのフロンティアモデルの場合ではとんでもなくお金がかかることになるだろう。
今後はAIコーディングのコストが高騰していくだろうと言われており、そうならないようにコンテキストを限定するように仕様設計・テスト設計を行うこともAIリテラシーのひとつになっていくだろうと考えられる。
感想
「趣味プログラマー」として、これは楽しいか?と言われると微妙である。例えるなら、プラモデル好きが、自動プラモデル組み立て機を手に入れてしまった気分かもしれない。ただ、「自分だけのプラモデルを設計したい」とか、「自分だけのフィギュアとして完成品がほしい」ということだったら、これはありがたいかもしれない。
今回の場合、「トラス解析手法について学びたい」ということだったら自律開発は向かないかもしれないが(出力されたコードを分析するという使い方はありうるが)、「構造設計ツールを作るために自前のトラス解析ツールがほしい」だったら、自律開発は大いに助かると思う。
ただ、そうは言っても、特別な事情がない限り「最初に既存のツールやライブラリを探す」という従来の原則は変わらないと思う。
|