1. くわラジ
  2. #15 LLMに漠然と探させるな——..
#15 LLMに漠然と探させるな——「意味の構造」にフォーカスさせる検査ツール
2026-07-31 41:26

#15 LLMに漠然と探させるな——「意味の構造」にフォーカスさせる検査ツール

LLM(AI)にシーケンス図や設計のレビューを任せたら、なぜ見逃しだらけになるのか?答えは「漠然と探させている」から。ルールベースの検査ツールで怪しい箇所を列挙し、LLMの注意を「意味の構造」にフォーカスさせると、検出精度がほぼ100%まで上がる——そんな検査ツールの作り方を深掘りする回です。


スーパーエンジニアのkuniwakが開発中の、仕様と実装設計を検査するツールの裏側を一般エンジニアのへんてこが根掘り葉掘り聞いていきます。


PlantUMLで書いたシーケンス図の「矢印の連続性」をGo製ツールで解析してLLMにジャッジさせる仕組み、C4モデル(コンテキスト図・コンテナ図)との整合性チェック、そして「誤警告してもいい」というlintツールとの決定的な違いまで。

後半は、LLMに良い設計をさせる鍵としてのテスト駆動開発(TDD)とロードマップ、プライベート関数という抜け道の塞ぎ方、さらにLLMが得意なプログラミング言語と型検査の「税金」の話へと展開します。


AIコーディングエージェントのレビュー精度に悩んでいる人ほど刺さる実践知が詰まっています。


▼この回で話していること

・シーケンス図の落とし穴とは?矢印の連続性に隠れた「暗黙のシステム」

・LLMが図の検査で見逃しを連発する理由——漠然とした探索と計算が苦手

・ルールベースの検査ツール×LLMのジャッジで検出率ほぼ100%にする方法

・C4モデル(C4ダイアグラム)とシーケンス図の整合性チェック

・lintツールとの違い:LLMが最終判断するから誤警告に寛容でいい

・LLMに良い設計をさせる鍵:未来の情報(ロードマップ)とテスト駆動開発(TDD)

・プライベート関数という抜け道をAST解析で塞ぐ、roles.tsvでモジュールの役割を先に定義する

・LLMが得意なプログラミング言語は?動的型付け言語の速さと型検査という「税金」


▼こんな人におすすめ

・Claude CodeなどのAIコーディングエージェントのレビュー精度・設計品質を上げたいエンジニア

・シーケンス図やC4モデルなど設計ドキュメントのチェックをAIに任せたい人

・TDDやlintとLLMをどう組み合わせるべきか、考え方の軸がほしい人


▼関連リンク

・PlantUML 公式サイト: https://plantuml.com/ja/

・C4 model 公式サイト: https://c4model.com/

・DeepWiki: https://deepwiki.com/

・Claude Code: https://www.anthropic.com/claude-code


くわラジ(もっと詳しく教えてくださいラジオ)は、スーパーエンジニアのkuniwakに一般エンジニアのへんてこが「もっと詳しく教えてください」と質問しながら技術を深掘りする、ゆるくてディープな技術雑談番組です。


─────────────

YouTube: https://youtu.be/qK9uNFp9RjY

Web: https://kuwa-raji.henteko07.com/

X: https://x.com/kuwa_raji

感想

まだ感想はありません。最初の1件を書きましょう!

サマリー

本エピソードでは、LLM(大規模言語モデル)を活用してソフトウェア設計の検査精度を劇的に向上させるツールの開発について深掘りします。特に、シーケンス図における「矢印の連続性」の欠如や、C4モデルとの整合性といった、LLMが見逃しやすい曖昧な問題をルールベースの検査ツールで検出し、LLMに「意味の構造」へフォーカスさせることで、ほぼ100%の検出率を達成する方法が紹介されます。 さらに、LLMに良い設計をさせるための鍵として、未来の情報(ロードマップ)の提供とテスト駆動開発(TDD)の重要性が語られます。また、プライベート関数という抜け道をAST解析で塞ぐ方法や、モジュールの役割を事前に定義する`roles.tsv`の活用についても解説。後半では、LLMが得意とするプログラミング言語や、型検査の「税金」とも呼ばれるコンパイル時間の問題、そして言語処理系とリンターの組み合わせによる完全性と健全性の両立について議論が展開されます。

LLMによる設計検査ツールの開発背景とシーケンス図の課題
前回、正当性検証と妥当性検証について 話したんですけど、
その中で語られていた構造を抽出して、 AIに構造に対してフォーカスさせることで、
精度を上げるツールっていうのを作ってるって 話があったかなと思うんですけど、
今回はそのツールについて聞いてみたいな と思ってるんですけど、いいですかね。
はい、いいですよ。 まだ未発表なことが多いんですけど、
具体的には、使用を検査するツールと 実装と設計っていうのかな、
どっちかを検査するツールを開発しています。
具体的にはどういったものなんですかね。
使用というか要求とかを検査するツールは、 シーケンス図の検査ツールとか、
C4ダイアグラムって言われてるものの 検査ツールになっていて、
ちょっとそれぞれ説明していきますね。
シーケンス図って網田九二みたいな図で、 縦棒が人だったりシステムだったりして、
その間で何かコミュニケーションがされると 矢印が発生するというのがあって、
この矢印っていうのが段々と伝わっていって、
例えばアリスとボブがいるシーケンス図だと、
アリスからボブにこんにちはって言ったら、 ボブがこんにちはって返すみたいな、
そんな感じのシーケンス図ですよね。
こういうふうなシーケンス図って、 実はまずいシーケンス図があるんですね。
例えばアリスがボブに対してこんにちはって言って、 もう1回こんにちはって言うときで、
アリスは何を… アリスもう1人いるとちょっとそれが顕著になるんですけど、
アリスボブだともう1人… 何にしよう、名前。チャーリーか。
何だろうな。チャーリー。
で、アリスがボブにこんにちはって言った。
その後にチャーリーがボブにこんにちはって言った。
これ矢印できますよね。
だけどチャーリーはどうしてアリスが こんにちはって言ったことを知ってたんだろうか。
わかりますよね。
なるほど。 アリスからチャーリーには何来連絡が行ってないわけですよ。
だけどなぜかアリスのこんにちはの後に チャーリーはこんにちはができた。
絶対なんかここでコミュニケーションが 隠れてただろうっていう。
その連続性の間に何かあった。
だからこんにちはっていう例だと その場に全員いそうだからちょっと
例として若干適してないかもしれないけど、
何らか情報を渡した時に、
何でお前知ってんねんっていう状態ですよね。 フローズとして。
で、ここは実は仕様としてはすごく重要なポイントで、
もしそこにメッセージが隠れてたとすると、
そこに何らか伝えるためのチャンネルとして、
例えばチャットなのか、それともシステムなのか わかんないですけどが隠れてるんですよね。
このシステムが隠れてることを見逃しちゃうと、
後々進んでみると、あれここ通信しようと思ったら システムないんですけどってなって、
スケジュールが破滅するみたいなことがあるわけですよ。
なので一般的には暗黙的なところって言われるんですかね。
若干抜け落ちているところ。
それとも常識的に考えてここはちょっと書かなくてもいいよねとか、
若干抜けちゃってるところだと。
そういうところですかね。
そう、でもそこにはやっぱりシステムの入る予知っていうのが、
開発しなきゃいけない予知っていうのがあることが多いので、
このシーケンス図がちゃんと矢印がアミダクジのように繋がってるかってことは、
かなり大事なことなんですね。
ちゃんとアミダクジのように繋がってるってことは、
矢印行ったら戻ってきてとかっていうふうに全部繋がってるっていうことですね。
ここがすごく重要な性質になってくるわけです。
これを今時LLMに矢印繋がってるかどうか確かめてよろってしたくなるじゃないですか。
これが。
したくなりますね。
うまくいかないんですよ。
なるほど。
それは渡し方として結構いろいろあるなと思ってて、
画像として渡すのか、それともマーメイドとかが対応してるかどうかちょっと今忘れたんですけど、
そういう文字ベース、マークダウンとか文字ベースで渡すとかですかね。
これはテキストベースで渡しました。
テキストベース。
マーメイドのアシュみたいなものを使ってやっていたんですけど、
もう見逃しがめっちゃ多いんですね。
見逃しがすごく多い理由とかが多いことに気づいたので、
私はちょっとそこでツールを作ったんですよ。
それは矢印が繋がってないところを検証するっていうツールを作りました。
すごいニッチというかそこだけにフォーカスしたものですね。
だからそのプラントMLのシークエンス図を解析して、
矢印が見たくじみたいに繋がってるかなっていうのを見て、
外れてるところはここがどうも外れてますよとかっていうことを指摘するツールを作りました。
実際外れてても問題ないときってあるんですよ。
だからこれは外れてて問題がある可能性がありますよって指摘をするだけのツールなんです。
警告ですね。
警告をするっていう。
これを1111に使わせてみたところ、ほぼ100%見つけてくれるようになりました。
すごい。
しかもちゃんとその後のこれは本当は問題です、本当は問題ないですみたいな判断までほぼ正確でした。
すごい。
だからこれって何を示唆してるかっていうと、
1111に漠然と投げたりとかルールとかを説明して投げると、
やっぱりどうしてもルールの解釈に誤解が入ったりだとか、
あるいはやっぱり苦手なんでしょうね、単純にそういう計算が。
だからツールによってルールベースで補助をしてあげて、
さっき言った繋がってるっていう繋がりの部分、繋がりの破れてる部分にフォーカスさせてあげると、
彼らがちゃんと正しい判断を下すことができるようになるっていうことなんだと思っています。
そのどこが難しかったのかなっていうのを考えると、
なんか人間だったら図を見てそれを絵で判断して、
ここ書いてなくないみたいなそういう判断ができるわけじゃないですか。
ただ1111に渡したテキストベースだとそこが欠落してしまう。
ビジュアルでの判断が欠落してしまうみたいなところが難しかったんですかね。
実はちょうどセッションの途中で、
繋がってますか、いや繋がってますって最初言って、その後にツールを投入してみたっていうセッションが1回だけあって、
見逃してました、それはなぜあなた見逃したんですかって言ったら、繋がってるの意味を誤解してましたって言ってました。
つまり定義の部分が繋がると言っても、
人間と支持者側とAI側でずれてたんですね。
言うて仮に彼が正確な定義を持ってたとしても、見逃したんじゃないかなって気がしてて。
LMって計算が苦手じゃないですか。
だから苦手なもののうちに入ってるんじゃないかなって気はちょっとだけしていますね。
計算が苦手って言っているのはプログラムを介した計算以外が苦手ってことですか。
足し算とかを電卓使わせないでやらせるとすごく間違った答え出してくるんですね。
文字ベースでの足し算がすごい苦手ですよね。
1足す1足すみたいな引っ掛け問題のやつが。
あとは文字の代償比較も苦手ですよね。
あれはどっちかっていうとバージョン文字列に引きずられてる気がするんですけど。
そこら辺がボトルネックというか、落ち度としてあって繋がっているかどうかという判定ができなかったという。
それでツールってどんな感じでサポートしたんですか。
ツールはクロードコードにシーケンス図が繋がってるっていうのはこういうルールで、こういうルールの検査するGoのプログラムを作ってくださいって言って。
私がテスト例をいくつか渡して、これは繋がってる、これは繋がってないでよろって言ったら一撃で作ってくれましたね。
すごい便利。やっぱりあれですね、ここで汲み取れるというかやっぱり言いたいこととしては、決定論的にAIに使わせることの重要性ですよね。
そうですね、その通りです。
プログラムを実行させて、ただのテキストベースでの推論をさせないということですよね、重要なのは。
そうですね、私はそれはどちらかというと意味にフォーカスさせて、意味の構造にフォーカスさせてるっていう風な言い方をしていて、
例えばシーケンス図で言うとシーケンス図の流れまでは多分ね、LNM理解してると思うんですよ。適切な編集ができるんで彼らも。
なんだけど、繋がってないところって言って曖昧、漠然と探すっていうのがやっぱり苦手で、繋がってないところのその局所の構造をフォーカスさせてあげるとやっと気づく。
ルールベースツールとLLMの連携による高精度検査
これ人間も同じですよね、人間も漠然と探せって言われるとうーんってなっちゃうけど、
こことこことここ怪しいよって言われたら、ここダメ、ここダメ、ここはオッケーってすぐ分かるって話なんだと思っていて、
だから一般的に注意力の話なのかなと思っていて、局所にフォーカスさせてあげると注意リソースがちゃんと人間でもLNMでもそこに向くと、
そこが確かに問題があるってことを指摘するってことですね。
いや確かにそうだなと思いましたね。
でそれを使った上でそのシーケンス図、かなり精度高くなったのかなと思うんですけど、なんか実際にこういう効果あったよみたいなのあったり?
いやめっちゃ見逃し、そのシステムとかの隠れてるところを見逃さないで出してくれたんですよ。
元々今回の場合そのパートナーの企業がいて、そのパートナー企業がシーケンス図の叩きみたいなの出してくれたんですよね。
もうめちゃくちゃ指摘されてました。
だからそういったのは直接パートナーに言うとなんか嫌な気持ちになるかなと思ったんで、こっちが適宜ここの部分ってこういうのがあるんじゃないですかみたいな質問集を作るのに使いましたね。
一旦叩きとしてこっちでフィードバック受けた上で、分かりやすいというかもうちょっと優しい形で指摘じゃないですけどね、質問みたいな形で出してあげるっていうのがありました。
あともう一個がさっきちょろって言ったんですけどC4ダイアグラムっていうのがあって、C4ダイアグラムっていうのは4つのレベルのある記法で、
一番上がコンテキストダイアグラムって言って人間と関わるステークホルダーとシステムが一個だけドームみたいな感じの図になっていて、
次のレベル2になるとコンテナ図っていうのになって、サーバーの本当にコンテナがマイクロアーキテクチャだったらマイクロサービスでいっぱいコンテナが分かれてみたいな感じになって、
さらにその下だとコンポーネントとかになって、だんだん詳細化されていく図なんですね。これって実はシーケンス図と対応関係があって、
このシーケンス図でメッセージをやり取りするところは、さっき言ったC4ダイアグラムとコンテキストダイアグラムってところで関係があるってみなされるわけですよね。
だから線で繋がるわけですよ。っていうふうなことをやっていくとシーケンス図とこのC4ダイアグラムが整合してるかってことは当然気になるわけです。
これをAIに整合してるかどうか調べてやろうってやってみたんですよ。まあ見逃しますね。
同じ理由ですよね。
それでプラントユーメルの矢印とシーケンス図の矢印っていうのが整合するかをルールベースでやっぱり同じようにツールを作らせて確認させたら100%の成果になりましたねっていう感じになっていて、
やっぱり彼ら苦手なんですね。そういう漠然と。もちろん整合してるって定義は与えてますよ。
整合してるってのはそれぞれ矢印があるときに矢印がありべきで、矢印がないときには矢印がないべきだみたいなちゃんとそれっぽい定義与えてるんですけど、それでもやっぱり見つけてくれないですね。
やっぱ重要ですね。なんとなく人間だとパッと見めちゃくちゃ複雑なシーケンス図とかだと絶対見逃すと思うんですよね。
なんですけどAIだったら複雑であったとしても絶対繋がってなかったら指摘してくれるってことですよね。
そうですね。
ちなみに栗上さんがパッと見たときにその図で繋がってないと思ったところはあったんですか?先に見たときに、AIに渡す前に。
もちろん指差しながら拡大してこうやってたんで、要するに全部に注意払ってやってたんですよね最初は。
AIに任せきるわけにいかなかったんで。そしたらまあまあ見つかるは見つかるわって感じですね。
じゃあそれありつつもAIにチェックさせてみたらかなり精度高く、てか100%見つけてくれたっていう。
その後ツールを導入したら100%見つけてくれたって感じですね。
なんかそのツール単純に便利そうっていうか、話聞く限りシーケンス図のリントツールなのかなと思ったんですけど。
LLMを活用した設計検査の進展とTDD・ロードマップの重要性
ちょうどその話しようと思ったんですよ。これちょっとリントツールとは少し違うなと思ってるんですね。
違うんですね。
リントツールって誤警告を出さないようにするっていうのがすごく重要なミッションで。
だってそのリントツールCIとかで書けるじゃないですか。
で誤警告多くて、毎回コメントでこうディセーブルするみたいなこと。
まあそれもそうしたのもなくはないんですけど、やっぱりリントってのは誤警告が少なくなるように作ってるんですよね。
割れ間の理論をね、回避するためには。
なんだけど、このLLMの注意を払わせるシステムっていうのは誤警告してもいいんですよ。
だって最終的にLLMがジャッジしてくれるから。
確かに。
っていう意味でLLMとはちょっと違った生き物なんですよね。
より誤警告に寛容なシステムにいったらいいのかな。
なので私はちょっとリントとはかなり心を切り替えて作らないといけないと思っていて。
なるほど。
じゃあそれでいうと、LLMと組み合わせることでリントツールになるのかな?
そういうことですね、その通りです。
CIで実行する際にはそのツールだけじゃなくて、Goで書いたツールだけじゃなくて、
LLMの誤検知したやつを省いてねっていうような形で実行させとけばいい?
私は今回スキルとかで入れてるんで、プレコミットみたいな感じとかでチェックさせるようにしてるんで、
CAにはしてないんですけど、全体そういう感じですね。
じゃあそこまでいったらリントですね。
そうですね。
リントの考え方とちょっと近しいところですね。
じゃあリントのサブセットみたいな感じですよね、サブツールみたいな。
ただやっぱりリントのいいところは高速であることなんですよ。
リントってタイプするごとにかかってほしいって人もいるくらいで、
すごく高速なことが求められるんですよね。
その点でもやっぱりLLMがジャッジするリントってのは異なってて、
遅いんですよ、すごくLLMがジャッジするって。
だからリントっていうよりかはどっちかというとそういう意味ではテストのライフサイクルに近い。
テストですね、確かに。
っていうものですね。
ただテストってやっぱり普通は実装、使用との間で検証するものですけど、
使用じゃなくて、使用と何の間、要求とかの間とか、
使用と使用の間の成功性とかっていうのをチェックするって意味ではリントに近いっていう、
ちょっとなんかこう独特な立ち位置のツールになるわけですね。
相残ってところですね。
そうですね、相残ってところですね。
そうじて。
そこまでの速度ではないけども、かなり精度高く、
しかも頻繁に事故できるものっていう形なの。
ちなみに実行してるのはクロードコード?
クロードコードって実行してますね。
クロードコードのスキル、ルールファイルかな。
ルールファイルでいじった後はこれでチェックしてねって見てるのと、
あとは自動でレンダリングするパイプラインを組んでいって、
例えばプラントMLとかだったらテキストで書かれてて見づらいじゃないですか。
だから自動でそのPNGとかにレンダリングするパイプラインの中に組み込まれています。
の1個のワークフローの中に入ってるってことですね。
入ってる感じですね。
他の人に使ってもらったりするんですか?
他の人にも使ってもらえるように、
シーケースズのレビュースキルとか、
C4ダイグラムのレビュースキルみたいなのがリポートストリームの中に入ってます。
それ使ってねって言ってますね。
じゃあ他の人が書いたとしても、
ちゃんと適宜するフォーマットとしてある程度は出てくるってことですね。
ちゃんと設定されてればってことですね。
すごい良いですね。
それで作ったもの、最終的にできたものっていうのは設計書なんですかね?
今のシーケンスズの話はシーケンスズとC4ダイグラムが出てくるっていう感じですね。
さっき実装設計を検査するツールも作ったって話もしてたんで、
そっちの話をしようかなと思うんですけど、
LLM2の設計ってダメダメなことがすごく多かったと思ってるんですよ。
これは2つ理由があると思っていて、
良い設計っていうのはまず定義をするとダメダメってのはなぜなのかってことが分かるんですけど、
良い設計の定義っていうのは未来に渡って変更する時のコストが最も低い設計っていうのが良い設計なんですよね。
だから例えば2つちょっと良い例と悪い例を挙げてみましょう。
1つは拡張ポイントがめちゃくちゃどこにでもあります。
もう至る所プラグインでできますみたいな。
これは拡張できるってことは未来の変更コストが安いように思えるじゃないですか。
ワードプレスってやつですね。
実際は使わない拡張ポイントの方が多いんですよ。
使わない拡張ポイントって理解の不採になったりだとか、
あるいは実行速度の問題になったりとかっていうふうに不採を残すんですよね。
こういうふうな不採があるってことは結局設計としては良くないんです。
コストがかかるわけだから未来に渡って。
じゃあもう1個何も知らない。
今回聞いた要件だけをやるバリバリの1000行のメイン関数だけのやつを作った。
拡張ポイント全部なくしちゃったぞみたいなやつ。
これもこれでまたひどいということですね。
要件があるごとにそれがすごく書き換えなきゃいけなくなってしまう。
毎回そのために1000行の関数をテストしなきゃいけない。
これはものすごく大変ですね。
なので拡張ポイントっていうのは
未来で使う拡張ポイントだけがちょうどあるって状態が一番良い設計なわけですね。
ということを踏まえた上で
どういうふうにLLMに指示してあげればこの良い設計をしてくれるかといったら
未来の情報は絶対必要だなと思いませんでした?
それはそうですね。
だって未来の情報が1ビットでもないと
こうなるだろうという設計ってできないと思うんで。
だからみんなフレームワークがここで分かれてるからとかっていう理由で
みんなここで分けてるからっていう感じで分けちゃう。
一般的な話になっちゃうんですね。
だからここは違うんだよってなっちゃうわけですよ。
だから人間は未来の情報を与えなきゃいけないっていうのがまず一つ。
つまりあなたはどういうロードマップで何を順々に実装しようとしていて
っていうことがちゃんとロードマップとして管理されてることがすごく重要なわけですね。
これが一つ。
もう一つはテスト駆動開発とかっていうのをちゃんとしてるかっていうのは結構重要で
テスト駆動開発ってすごく設計の良いギプスになるんですよ。
なんでかって言うとテストって製品コードの最初のユーザーなんですよ。
いい表現ですね。
そうですね。これよく私が作ったこともあるんですよ。
メソッドからこう言ってることもあるんですけど。
なのでそのテストを通して使いにくいコンポーネントが作られてしまっている場合
当然製品コードの中ではめちゃくちゃになっていくっていうことになるわけですね。
これの端的な例から。
使いづらいからね。
製品コードの中ではすごく楽に使えるんだけど
切り出してテストしようとすると依存がもうひっちゃかめっちゃかになってて
セットアップがほぼ80%を占めるテストを書かなきゃいけないみたいなことがよくあると思います。
これはぶっちゃけ使いづらいですね。
三つ結合になっちゃってやばいですねっていうのになっていて
これは一般的には良い設計ではない。
その部分を変えようと思ったらその依存部分も全部変えなきゃいけなくなっちゃうっていうパターンが多いからですね。
ってことを考えるとテスト駆動設計で部分的に切り出されてテストできるっていうパーツを積み重ねていくってことができるんですよ。
テストが先に書かれてテストできるものしか書けなくてってなると
自動的に80%のセットアップを占めるコードは生まれなくなるわけですね。
ちゃんとセットアップが1行2行とかで実際実行するのが3行とかあって
アサルトの部分が2行とかになるっていうすごくシンプルなテストになるっていうのがあって
それは使いやすい、一般的には良い設計のコードが生まれやすいっていうのがあって
テスト駆動開発を支持すると結構設計ってよくなるんですよ。
この2つって私はそのLLMの鍵だと思っていて
未来の情報を与える設計のTDDをさせるっていうのがあるんですね。
プライベート関数とモジュール役割定義による設計改善
ただこれでも漏れてくるものがあるんですよ。
っていうのが今回のこの話になるんですね。
で私がその実際このプラクティス未来のことロードマップをちゃんとto doファイルみたいな形で
ちゃんと渡してこういうふうな順序でこういうことを実装していけ
今あなたはこの位置にいるっていうのは伝えた上で
でテスト駆動開発をcloud.mdみたいなので支持させるわけですね。
それでだいぶ設計は良くなるんですよ。
なんだけど抜け道があるんです。
それはプライベート関数でテストしますかって話なんですね。
なんかもういたちごっこの気がしてくるんですけどそこまで来ると
そういうことしてくるんですね。
そういうことしてきますね。
プライベート関数いっぱい作ってくるんですよ。
で至る所に変な所に変なコードが置かれるみたいな
プライベート関数が置かれるみたいな
プライベート関数って例えば5とかだと同じパッケージ内でしか使えないんで
明らかに別の層だろうみたいな感じのコードが
プライベート関数として置かれてしまう。
でテストはそのパッケージのやつだからちょっと
円凸円凸テスト味があるようなテストしか書かれなかったんですよ。
まあ確かにテスト駆動をしている。
だからそれはやったほしいことがないっていうのがあって
これが私のツールを作ろうと思ったやつ。
一番最初のモチベーション。
どうやってやったかというと
まずはcloud.mtとかにプライベート関数をやたらめたら作るなって指示するわけですよ。
これがですね。無視されます。
なんで?
あれは全然効果なかったですね。
本当に効果なかったので私が作ったのは
GoのAST、抽象古文言とかを解析して
関数名を取り出してきて
でプライベート関数を全部列挙させるんですよ。
これは本当にプライベートである必要がありますか?
変身してくださいっていうプロンプトを作る。
事実ベースで詰めるってことですね。
そうですそうです。
っていう風なプロンプトを自動でレビュースキルの時に
インジェクトされるんですよ。
そうすると
すいませんこれはプライベートじゃないべきでしたとかってことに気づいてくれる。
これもやっぱり何をやったかっていうと
プライベート、可視性ですね。
可視性の意味向上に注意を向けさせた。
そうすると
すいませんでしたってちゃんと気づいてくれるっていうのがあって
やっぱり注意力を払わせるってことが
やっぱり大事な例だなと思っていて
そういう風なツールを作っていました。
それで若干思ったのは
テストのプライベート関数がどれだけあるかとか
そういう
一歩引いた数字を
LLMに対して渡して
こんぐらいあるから
これを低くせよみたいな話でも結構聞くのかなと思ったんですけど
そうでもない。
多分聞くと思います。
合ってると思います。
単に実装が楽だったのが
関数抜き出してくるっていうそれだけですね。
なるほど。
理解です。
それであれば本当に
さっきの話で言うと
フォーカスすべきは
その時点でのレビューでフォーカスすべきは
プライベート関数がどれだけ少ないか
本当に意味あるプライベート関数になってるかどうか
をレビューしてくださいというものを入れたということですね。
そうすると
プライベートパブリックにすればいいかって雑なことされるんですよ。
思想
思想
なのでパッケージごとに
role.tsvっていうのを作っていて
あなたこのパッケージではこんなことやりますよ
っていうドキュメントを先に書かせるんです。
なるほど。
それでちゃんとそれに合ってるってことを
ついで確認させるんですよ。
ここのroleはこれ
あなたがパブリックにした関数はこれ
本当にこれ中に入ってるってことをチェックする
これをやっぱりちゃんとフォーカスさせるんですよ。
それを突き合わせると
すいませんこれはここに置くべきでした
って気づいてくる。
私はこの2つをやったら
ほぼレビューでコメントがなくなりました。
やったこととしては
ざっくり言うと
お前の役割はこれなんだ
というのを先に定義した。
モジュールごとに。
分割単位だとは思いますけど
いろんな分割単位で
お前の役割はこれなんだから
これに適してるかどうかを判定せよ
ということをした。
ちなみにそれをゴリゴリやっていくと
めちゃくちゃ分割されそうだな
なんとなく思っちゃったんですけど
そこに関しては
人間がこの役割は
このモジュール
このモジュールみたいな形で
分割単位がちゃんと揃っていれば
大丈夫。
むしろ細かいことは悪いことじゃないんですよね。
大抵ユーティリティってめっちゃ細かくなるんですよ。
ストリングユーティリティがあって
デートユーティリティがあって
それがドメインに散らばっているのが
一番嫌な状態なんですよね。
例えばハズプレフィックスみたいな感じの
よくある関数があって
その関数が至る所ドメインとかで
例えば0文字目から
4ループで比較してるみたいなのがあったりすると
嫌じゃないですか。
それはそうなってるぐらいだったら
ストリングユーティリティみたいなのがあったほうがいい。
それを選択肢がちょっとだけあって
ユーティリティってところにストリングとプールとか
全部まとめるっていう方式と
ストリングユーティリティとかプールユーティリティみたいなのを作るっていう方式があるんですけど
これは私は
ユーティリティってところにまとめると
偉いことになると思っている。
依存関係が
偉いことになる。
広すぎるからってことですよね。
なので細かく分ける方が
よりちゃんと整理されると思っていて
ストリングユーティリティ。
プログラミング言語の特性と型検査の「税金」
そうすると自然的にパッケージって増えちゃうんですよ。
ただそれは悪いことじゃないと思うようにしている。
あれですよね。
モジュールが分割して増えることによって
得るデメリットっていうのが
おそらくインポートと
インポートのオーバーヘッドがかかるとか
そういうことだとは思うんですけど
でもユーティ
そのぐらいだしってことですよね。
そんなにコンパイルのときにも時間かかんないし
むしろコンパイルは
分かれてた方が有利だと思いますね。
なんでかっていうと
モジュールがキャッシュされるからです。
いじられただけで。
細かく分かれてるほどキャッシュヒットする確率が高まるので
むしろ有利だはずですね。
なるほど。
じゃあGoコンパイルがめちゃくちゃ
頭良かったってことですね。
Goコンパイルめちゃくちゃ早いですからね最初から。
型検索とかもそんなに
すごく凝ったことはしないから
すごく高速に
コンパイルされますよねGoって。
結構言語によるかなと思って
例えばSwiftとか
Xcodeかな
IOSプロジェクトとかだと
ちょっとモジュールというか
例えばXstationだったりとか
いろんな分けていくと
ビルドが重かったりだったりとか
遅くなったりというのは
普通にありがちかなと思うんですけど
結構言語によるなとは若干思います。
そうですねSwiftは特に
でもSwiftもインクリメンタルコンパイルが入っているときは
比較的マシかなと思っていて
むしろ
コンパイルが遅いときは
複数モジュールにわたって変更を毎回続けている
って進めるような気がしていて
確かに。
Cシャープも同じようにインクリメンタルコンパイルが働くので
キャッシュされるんですよ。
いじってないところは。
そうなるとやっぱり
そっちも有利なんですよね。
細かく分かれていた方が。
キャッシュされてくれているから
一番の不利はコンパイル時の問題じゃなくて
人間に対する
人間の理解不在ですね。
どっかいのところが。
あのユーティリティどこにあるっけって
ストリングユーティリティ
プールユーティリティとかいっぱいあって
どれじゃんってなるっていう。
でもそこに関しては
AIによって
コードを書くから大体大丈夫でしょってこと?
そうです。さっきのロールがむしろ手がかりになっていて
たぶんここら辺に
このロール未来あるでしょって
絞り込めますから
むしろいいって感じですね。
現代だったらそのぐらいでいいかな
って気がしますね。
人間に対するマッピングに
コードに対するマップは
そこの役割みたいな
ロールっていうところで担保して
AIだったら
コード読むなんて拘束なんでね。
バーって読んでくれるんで
そこの理解認知力は
全然問題ないでしょっていうところですね。
そうですね。実はここに
また比較したものも一個あって
このロール.tsvって
ぶっちゃけDevinとかが作ってるのと
あんま変わんないじゃんっていうのがあって
Devinってあるじゃないですか
DeepLeakとか作ってくれるやつですね。
ソースコードを定期的に
ポーリングっていうのかな
巡回してきて、それで
コードの全体像とか食わせながら
コードはこんなことやってるとか
いろんな幹を自動で
作ってくれるってやつがあって
あいつにロール.tsvみたいなものを
作らせられるのかなと思って検証してみました。
ダメでした。
やっぱりクロードコードとかに
いじった直後に書かせたりとか
パッケージを作らせた直後に書かせる方が
やっぱり精度が良かったですね。
なるほど。差分が大きすぎたりとか
やっぱり
さっきの言葉を借りると
フォーカスしてないってことなんですかね。
そのコンテキストが
ここの役割の
ロールを考えるっていう
形で一個一個やってった方が
それは精度が良いのは確かですよね。
一気に生成させるよりかは。
そうですね。
私はそこでDebianを使うという
目論みを外れ、泣きながら
ロール.tsvを管理するっていう
ような感じになりましたね。
もしかしたら未来
人間が管理するのはそういう
コンテキストなところなんじゃないかなと
若干思いますけどね。
ロール.tsvみたいな形で
何をやる
目的のモジュールなのか
っていうところを管理していて
それをレビューするみたいなね。
人間はレビューし合う
みたいなことがあり得るんじゃないかなと。
ただ私はもう
先ほど言った通り設計でレビューすることが
ほとんどなくなってしまったんですよ。
ほとんどTDDをして
未来の情報を与えてあげて
そしてプライベート関数
っていう逃げ道を塞いで
ロール.tsvを入れる。この4つのことを
してあげたら、もう本当に設計で指摘する
ことはなくなっちゃったんですね。
今私がコードレビューとかでレビューを
しているのは、私が日本語で説明した
ことっていうのがちゃんと彼らがそれを理解して
くれたのかっていうチェックでしかない。
プログラムで書かれていれば
私はその動作をイメージすることができるんで
ここってこんな意味で取られたんだな
とか分かるっていうのがあって
それのチェックをして私がプロンプトで足りなかったことを
チェックしてるっていう感じ
なんですよね。なのでだいぶ
レビューコストは軽くなりました。
さらーって見ておしまい。
だからちゃんと理解して実装しているかどうかの
チェックですよね。
人間においても
同じだなとは若干思いましたけど
AIがなかった頃にタスクを渡して
そのタスクの理解度が
実施者がどれだけ
理解度が高いかどうか改造度が高いか
どうかによって出てくるものが
違うっていうのは当たり前の話じゃないですか。
それと全く一緒ですね。
なんでテストを見て
この入力の時はこれ出力回復
あってるあってる
ほとんど製品コードは
見なくなりましたね。
じゃあもう本当にテストだけ見てっていう
テストさらーって見てOKOK
それが欲しかった
ちょっとここまで来ると
なんとなく今思ったのが
それ専用の言語ってやっぱ開発され売るだろうな
と思ったんですけど
どうなんでしょうね
私はちょっとその分野にあんま詳しくなくて
ただ私がつい最近
見聞きしたのは
2つ情報があって
1つはLLMはどの言語が最も得意なのか
ってことを比較したやつ
記事があって確かに
Rubyの
コミッターの方が
やってたやつだと思うんですけど
結果としてRubyとかPython
とかが
JavaScriptみたいな
型検査がないもの
性的な型検査がない言語が早かった
得意とする
何か同じ要件
ものを作らせようとすると早く作る
ということができて
型検査の重いもの
Haskellとか
は苦手だった
比較的
すごくバラツキ
やっぱ平均値も遅いし
バラツキも大きいみたいな
グラフがあって
これはどちらかというとマイクロベンチマークに近いので
それだけで
全体の傾向が
説明しきれるかというと
微妙だなと思うんですけど
やっぱり
性的型検査があった方が
早く開発できるという神話が
何か崩れる結果だったな
と思ってて
不思議ですよね
意外だなと思ってて
型検査あった方が
LLMとしても
それチェックできるんでいいんじゃないかなと
何となく思う
もしかしたらHaskellに関してだけは
データサンプルが少なかったかもしれないですね
そもそもね
学習が
タイプスクリプトは比較的早かった
ただJavaScriptよりは
遅いんですよ
というのがあって
意外と思ったのを
覚えています
型がなくなった
なんかもうゆるふわ
ゆるふわな言語が
最速になるからそれをみんなAIが使い出すみたいな
どうなんでしょうね
私はちょっと
あまり私が意見を持ってないって言ったな
それで
わかんないんですよ
どれがいいのかって
考えられないですね
さっき聞いてて思ったのは
テストを絶対に書かないといけない
あとはプライベート関数は
むしろ書けない
みたいなそういう
かなり尖った言語が
言語というかなんていうのか
わかんないですけどツールなのかどうなのか
わかんないですけどそういうものが出てくるんじゃないのかな
というのを若干思った
感じですね
テストを書かなければ絶対に何もできない
みたいなことになっていれば
テスト絶対書くじゃないですか
書かないと何も進まないじゃないですか
早いとか遅いとか関係なく
そっちの方がプロダクションに
作るコードとしては
すごく製品としては
品質が高くなっていくのかなというのを
聞いてて思って
これは私は
言語処理系とリントを
かじってるので言えることなんですけど
その言語は
あんま流行らないと思いますね
言語処理系、リンター、完全性の両立と開発サイクルの重要性
なんでかっていうと
その言語は完全性っていうのは
殺しすぎてるっていう言い方をするんですけど
完全性っていうのは
うまく動くんだったら検査に通るはずだよね
です
今の話って
テスト先に書くってことは順序を気にしてるわけですよ
実装順序
だから順序が間違っていても
動くコードってあるわけですよね
たまたま一発で動く
そういうコードをダメってしちゃう
動くのにダメっていうことは
完全性がないって言い方をするんですけど
人間ってこの完全性をすごく重視する生き物で
例えばダックタイピングとか好きなのは
完全性が好きだからなんですよね
だってフィールドあるじゃん
読めるじゃん
ちょっと型検査だけにしようよ
アクセスできるじゃんみたいな
そういう風な
考え方があって
完全性っていうのはすごく大事なんですよね
完全性があると
とりあえずいろいろバグはあるんだけど
ハッピーパスだけ通りゃいいや
そういうケースを救済するんですよね
ちょっとでも間違って操作すれば
クラッシュするんだけど
でも型検査は一応通って
そのハッピーパスだけのプロトタイプを
例えばスプリントレビューとかに持っていける
っていうのがあって
これはすごく価値があることなんですよね
確かに価値ある
そこを制限していくとすごく使いづらい言語になってしまう
っていうのがあって
じゃあどうすればいいかっていうと
多くのリントの人達っていうのは
処理系は完全性が高いように
それぞれが
各々でリントの設定とかを掘って
その完全性を
いらない部分だけ失わせていく
ってことをやることで
後付けでコンパイラーに
ルールを追加するってことだったりですね
なので私は言語としては
むしろ普段の言語
PythonとかRubyとかの言語を使わせて
そこに保証するリントみたいのを
後から付け加えることで
完全性とそのリントの健全性を
両立させるっていうことが
一番いいんじゃないかなって思いますね
いや確かにその通りですね
今聞いてて
そりゃそうだと思いました
プロトタイプを否定することになりますね
そうですね
だからハーネスやりすぎると
さっき言ったように完全性を殺しちゃうんで
そうという風に
ちょっと思ってます
確かにその通りです
だから組み合わせですね
どこをその時に重要視するか
次第で
組み合わせるもの違うし
より堅牢になっていく
プロジェクトの後半だったりとか
本当に壊しちゃいけない
例えば金融の部分だったりだったりとか
健康の命を関わるようなところだったりとか
そういったところをめちゃくちゃガチガチにする
っていうような
判断があったりとかそういうのがありそうですね
確かに
私さっき2つぐらい情報がある
っていう話なんですけど1つ目はさっき言ったとおり
LMの得意な言語
っていう話で
もう1個は最近ハスケルから
Pythonに撤退したっていう人を見かけたんですよ
なんでかって言うと
ハスケルのコンパイルソフトで遅すぎるっていう
話が出ていて
なるほどねそれラストと同じ構造も抱えてるんだろうな
って思ってるんですけど
やっぱりLMとかでもサイクルがすごく大事で
そのサイクルが遅いとやっぱり遅くなるんだって
単純な
単純にそうですよね
CIの実行が遅くなるのもそうだし
自分でローカルで試すっていう時にも
もちろんサイクル
遅くなるし
テストを実行しても遅くなるんで
LMの
ワンゴールが遅くなりますよね
そうそうそう
だからそういう言語が嫌われてるっていうのはあるんだな
っていうのはちょっと思ってて
その人はすごく
ハスケル好きな人だったみたいだから
本当に泣く泣くハスケル辞めた
みたいな感じの記事で
かわいそうに思いながら言ってたんですけど
そう
ここからちょっと私がこうなのかな
って確信があるわけじゃないんですけど
思ったのは型検査って
高速だってことはよく言われるんですけど
ただやっぱりリッチな型ハスケルとか
ラストみたいにリッチな型を持つような言語って
セイフともそうなんですけど
やっぱり遅いんですよね
なんでかっていうと型パズルを解いてるんですよね
中でその型がこの型とこの型は
ちゃんと成功するとかっていう風な
やつをやってて
すごく硬直した
システム例えばゴーグがジェネリックス
入る前とかだとそのほとんど
一瞬で型検査が通るんですよ
なぜかというと試す数が少ないから
っていうのがあるんですけど
ただだんだんリッチな型を入れていこうとすると
試す数が増えてくるんですよね
このジェネリックスのこの形はこの型になるかもしれない
この型になるかもしれない
それを一個一個試すと時間がかかる
その探査空間が
大きくなってくるんですよね
これって
網羅的に検査できるようなテストが
型検査みたいなものなんだけど
それに対する税金がすごく高い
その税金を
毎回毎回払わなきゃいけないんですよね
やっぱり型検査のリッチな言語って
だけど型検査がすごく貧弱なんだけど
まあまあ
なんとかなるかみたいな感じの言語って
その税金がすごく低いんですよね
それは
じゃあその低くなった部分をどうするかっていうと
テストで必要な部分だけ
手厚くかけるっていう風に
投資してるんですよね
こっちのスタイルっていうのもまあありなのかなみたいな
ちょっと思い始めたって感じです
私は型信者だったんで
もともとはその税金を正義とする立場だったんですけど
ただその税金があまりに高すぎるのかもしれないですね
最近は
だから
広く薄く
っていう風にして
広く厚くじゃなくて
広く薄くにして選択的にカバーしたい部分だけ
テストで手厚く書くっていうのが
もしかしたら一番いいのかな
みたいなことを思い始めたりはしました
私も
ハスケルみたいなとか
MLとか書いてるときが一番気持ちいいんで
ハスケルとか
いいなって思うんですけど
現実が
それを許してくれない感が若干あるなって
感じますね
もしかしたらハスケルのコンパイラーが
めちゃくちゃ賢くなって
高速化したら問題なくなる可能性もあるし
そもそも
ローカルで使ってるパソコン
PCのスペックの問題もあるかもしれないですよね
そうですね
計算機械で殴るっていうのは
いつだってできることで
それによって開発されていくものもあるとは思ってます
それ次第ではあるけども
そういったとしても
軽いに越したことはないし
そうですね
早いに
早いは正義ってことですね
現状において
早くて型安全性がある程度あって
埋められない部分においては
リントだったりとかそういうツールで
カバーできれば今のところは
いいんじゃないか
いやその通りだと思いました
ガチガチに
なかなか外せない税金なんで
難しいですよね
全部エニーにすれば高速化されるんでしょうけど
それはどうなん
って感じではあるんで
設計上ダメなんじゃないですか
その極まったスタイルを取るわけにも
なかなかいかずって感じですね
そんなことしたら
どこかで絶対に破綻すると思う
破綻しますよね
ありがとうございます
じゃあ結構いい時間になったので
今回はここまでにしたいかなと思います
もっと詳しく教えてください
ラジオ力士クマラジでは
スーパーエンジニアである国明さんに
一般エンジニアである辺てこが
技術的な質問をしていく番組になってます
今後もいろいろなこと聞いていけたらな
と思ってますのでお聞きのプラットフォームで
高評価やチャンネル登録やフォローの方
お願いします
またこんなことを聞いて欲しいとか
ありましたらコメントいただけると
絶対取り上げたいと思うので
コメントお願いします
Xなどでハッシュタグ
クマラジでつぶえてもらっていると
見つけやすくなるので
ぜひよろしくお願いします
それでは今回もありがとうございました
ありがとうございました
41:26

コメント

スクロール