00:00
いや、くにわけさん、ちょっと聞いて欲しいんですけど、普段コードを書いていて、プルリクとか出したときに、
Lintが原因でCIがエラーで落ちてます、みたいな感じのことが結構あって、またLintか、みたいなことが結構あるんですけど、
実はですね、Lintが何者でなんであんなに細かく起こってくるのかっていうのが、正直よくわかってないんですよね。
で、Lintに指摘された項目、もちろん直していくんですけど、これをやり方としては脳死で修正していくみたいな感じになってて、
これ本当に生産的なことなんかなとか思ったりとかして、Lintって本当に意味あるんですかね?何の意味があるんですかね?
とてもよくわかりますね。とてもよくわかるんだけど、そうですね、私から言えるとしたら、実はLintってメンタルに効くんですよ。
メンタルに効く。全然思いもよらなかったような角度からの回答なんですけど、どういうことですかね?
私が日々いろんな開発者を見ていて思うのは、みんなちょっと自信がないんですよね。自分の設計だったりだとか、コードとかにいつでもちょっと自信がなくて、
だから何か自信を与えてくれるものを常に探している。例えばテストだったり、あるいはLintだったりのような。
で、それを入れることで自分が一定以上の品質のコードを強制されている、かけているんだっていうふうなことがわかるようになって、
それが、まあ何て言うでしょう、メンタルに効くということなんですよね。
じゃあどちらかというと、チームのためというよりかは、自分のための方が大きいんじゃないかということか、Lintを使うの。
導入の動機は間違いなくそれだと思います。例えば実際に誰かがその技術を導入するという時に、チームのためっていうふうに入れる人ももちろんいると思うんですけど、
やっぱり最初っていうのは、自分がちょっと便利になりそうだからっていう時の人が多いと思うんですよ。
そういうふうに入った時には、やっぱり一定以上の品質のものを書きたいっていう願いっていうのかな、何て言うんだ、願望があって、
それをやっぱり一定解消してくれるっていうのがLintなんだろうと思っています。
なるほど。じゃあ、やっぱり自分が使いたいから、自分の生産性を上げるためにLintっていうのをチームで導入していって、
その中で良いコードというか、Lintによって矯正されたコードが、これであれば最低品質は保たれているであろうというお墨付きをもらいたいから使ってるっていうところがまずあると。
本当にその通りだと思います。それはいくつものことから見て取れて、例えばESLintとかって呼ばれてるJavaScriptのLintには膨大な量のルールがあるわけですね。
で、ひとつひとつをちゃんと選んでいくと、チームに合った形でのコードっていうのを矯正することができるんだけれども、実は皆さん一個一個ルールを有効化してたりしないですよね。
皆さんだいたいAirbnbとかのプリセットを使っている。使って何故じゃあそのプリセットを使うのか、一個一個カスタマイズした方がチームに合ってるものを作れるっていうのは当然のことなわけですよ。
だけどそのプリセットを使うってこと自身が私は自信の無さの現れだと思っています。なぜかというと、他の人に決めてほしいんですよ。
03:06
そっちの方が楽だから。
楽だから。自分でそこを考えなくていいと一定の品質が担保されると思うっていうところから、私は人々はLintっていうのをメンタルのために結構使ってるんだろうと思っているところですね。
なるほど。ちなみにESLintだったらルールの数どんぐらいあるかって知ってます?
いやもうとんでもない数がありますね。スタイルのLintもあるし、いろんなLintもあるので、あとはプラグインとかも含めたら本当にとんでもない量のLintがあるはずですね。
じゃあ100とか200とかで聞かずにもう1000ぐらいあるぐらいですか?
1000はないんじゃないかな、でもわかんない。こういう時はちょっと本当にわかんない。ノラル量とかも含めれば1000とかはあってもおかしくないかもしれないですね。
だいたいじゃあ国明さんが今までの見ていくプロジェクトでいろんなLintとか見てきてくるかなと思うんですけど、その中でルールがイネーブルされてる?ルールがどのぐらいありました?なんとなくの裸でいいですか?
他の人がメンテしてるところだとやっぱり20とか30とかイネーブルされてるものが多かったですね。ゲームのグランツとかもそんな感じだったかな、Cシャープのゲームとかだと。
じゃあやはり全てを有効化しておくというよりかは、本当に重要な部分だけ有効化しているLintのルールでやっていってる?
本当はそれが一番いいんですけど、でもやっぱり何の目的で使うかっていうことによってその設定の目的って変わってくると思っていて、メンタルに効かせたいんだったら標準的なもの、長いものに巻かれろっていうのはすごく効くと思います。
なるほど。
ただ例えば、Lintの中にはセキュリティ警告を出すようなLintも結構あって、例えばパールのLint、パールクリティックっていうLintがあって、
こいつは危ないタイプでセキュリティの脆弱性を作り込んじゃうような関数の呼び出し方とかっていうのを指摘してくる機能があったりします。
これとかっていうのを例えばコードレビューとかでいちいちチェックしなきゃいけないのがめんどくさいから、だから自動化しちゃおうとかっていうふうな使い方とかあるかって言っています。
なるほど。ただ文法だけじゃなくてセキュリティ維持になりそうだよという、いわゆる経験則的なコードの匂いみたいな、バグの匂いみたいないうところまでLintはサポートしている範囲としてある。
その通りです。ここからちょっと少しLintの定義というか、成り立ちとかの話に少し近づいてくるんですけど、Lintっていう名前、そもそもこのLintって名前不思議だと思いませんか?
Lintって何?
Lintっていうのはもともと糸くずっていう意味で、本当は糸くずだから取りたい、糸くずを取るためのツールのことをLintと呼んでいた。
なるほど。細かいゴミということ。
細かいゴミをくじるために。もともとはC言語で1978年頃に登場したのがこのLintっていうものになっていて。
すごい昔だ。
大昔なんだけれども、このLintの役割っていうのは当時からやっぱりスタイルのチェックだとか、そういうところとかやってて、
06:05
ここに私はちょっと名前の妙があると思っていて、すっごく重大な問題をめちゃくちゃ頑張って発見するっていうツールじゃないんですよ。
Lintって糸くずってそんな重大なものじゃなくて、なんかちょっとうざったいな、取りたいなみたいな、そのレベルのもの、それを取るっていうのがLintっていう名前になっていて。
なので今、大昔の1978年のLintから今に至るまで、Lintって呼ばれているものはほとんどそういうふうな結構軽量に検出できるものっていうものを主に扱っているっていう感じですね。
基本的には機械的に簡単にバッと見れるところがルールが主だよね。
主です。PHPスターみたいな化け物みたいなものもあれば、もっと簡単なものもいっぱいあって。
なのでLintがそのスタイルだけを調整するものかっていうとそうじゃなくて、セキュリティ警告もそうだし、あとはこれはほぼバグるよみたいなものを指摘してきますね。
例えば未宣言変数の参照とか、これがほぼ確定的にバグるってやつで、これがなんかも指摘してくるので、バグの気配だったり、セキュリティの問題だったり、
あとはスタイルの問題だったり、いろいろ軽く見つけられるものすべてを大体見つけるっていうのがLintの定義と言えると思います。
Lintの基本はそういった軽いところで、その応用編としてLintで一緒に実行してしまってるんだから、
セキュリティの一周とかも一緒に警告出そうよねみたいないうのが応用的な使い方として発展していったっていうのが現代のLintっていう成り立ち。
確かにそう見ると納得感がありますね。
じゃあ本当にLintがなかった頃というか、別に現代でもLintを使ってないプロジェクトっていっぱいあるかなと思ってて、現実的には。
そういったところでも別に問題になるというよりかは、やはりそういうゴミみたいな、本当に糸くずみたいなところを取ってきれいにしていくっていうところがLintの役割としてあるっていうのがありそうなんですね。
ここに私はちょっと面白い経験則があると思っていて、Lintを全く入れてないプロジェクト、結構言語によって偏りがあると思います。
例えば、JavaScriptはES-Lintみたいなのを入れる人がほとんどでしょうね。
パルもパルクリティックみたいなLintを入れる人が結構多いんじゃないかなと思います。
なんですけど、例えばラストにLintを入れますかとか。
なるほど。
そういうのがあって、ここに私はちょっと思うところが結構あります。
っていうのは、コンパイラーもこのコード確実に壊れてますみたいなときにエラー出しますよね。
出す。
Lintも出しますよね。
出す。
同じこと言ってる。
そう、かぶってて。なのでコンパイラーとかが、インタープリッターが優秀であれば優秀であるほどLintがしょぼくなるんですよ。
そう、なんかさっきの話聞いてて、コードも確実にバグりますよみたいなところだったり、
09:01
あとはこういう書き方だとちょっとおかしいよねみたいないうのって、そもそも言語仕様としてやってしまった方が良くないと思ってて、
取り入れちゃった方が良くない、そんなところみたいなことを思ってて、それがまさにエンが言ってもらったコンパイラーだったりとか、
実際に実行するときの警告文みたいなところが賢くなってたらLintはちょっとしょぼくなっていくみたいなところがある。
そう、アルトリソン通りです。
例えばわかりやすいのは、Pythonってインデントが意味を持っている言語になっていて、
インデントがちゃんとしてないと動かないんですよ、あの言語。
そう、っていうことは、これはインデントをチェックするようなLintがないってことなんですね。
逆に言えば。
Python側がインタープリンターがチェックしてくれてるから。
で、Haskellとかもこういうふうなオフサイドルールって言われてるようなインデントのルールっていうのが結構備わっていて、
なのでこういうものはコンパイラー側が伝えるまで口を出してくるっていう。
なるほど、確かにじゃあ言語によってかなり違うんですね。
言語によってかなり違う。JavaScriptはすっごく自由だから、本当にいろいろみんながガチガチで、
こうしたコミュニティのルールも分裂してたりするぐらいいろいろあって。
セミコロンつけるつけないとか。
確かに。
そう、JavaScriptでよくLintのルールで揉めますけど。
なんかJavaScriptとかの場合はLintとかでオートフィックスというか、勝手に書き換えるやつとかあるかなと思うんですけど、
そういったところが若干言語仕様のところまで踏み込んでるかなみたいな感じなんですかね、Lintからはみ出て。
オートフィックスは基本的にこうあるべきだろうっていうものへの差分を計算できるときとしかオートフィックスできないんですよ。
こうあるべきっていうのが姿が一つに定まるべきじゃなくて、姿が定まってなくてもできるのが今のAIとか、
生成AIとか使ってるタイプのやつとかで、あれはなんとなくいい感じに埋めてくれるわけだけれども、その代わり重くなっちゃうんですよね。
だから今のLintっていうのは軽く、特に毎回保存時とか、あるいはちょっと書き換えたときに毎回毎回実行されても遅くならないぐらい、
高速なことしかしないっていうふうに割り切りがあるので、そういうふうな分担というか役割分けがある感じですね。
じゃあ今AIみたいな、LLMとかを使ってそういうコードフォーマット、ないしは勝手に書き換えるみたいなことをやってるのは、
本質的にはもしかしたらLintという呼ばれるものではなさそう。
そう、あんまりLintと呼ばれるものではないですね。
なるほど。じゃあ逆にこれからのLintってどうなってくるんですかね。
それはとてもいい質問で、私がLintですごく予測していたのは、歴史からだんだん話していこうかなと思います。
まず最初に登場したLintっていうのは、検査ルールと検査対象のデータを巡回していくっていうプログラムが一緒くたになっている、
12:00
統合型みたいな感じのっていう名前でいいのかな、統合型みたいなLintになっていて、
これは作るのは結構最初の頃は簡単で手早く作れるんだけども、だんだんとルールが増えてきたりだとか、
ある人がこのルールを作ってくれたので取り込みたいとかっていう時に、
いちいちコードのメインラインに入れていくっていうのはめんどくさいっていうのがあって、
プラグインケースみたいなのをやりたいっていう時にすごく不便なんですよね。
なのでルールを一つ一つのコンポーネントとしてプラガブルにするっていう概念が誕生して、
これが分離型のLintっていうのが出てきたんですね。
この分離型のLintが出てきたのはおそらく2001年頃になっていて、
Javaのスタイルチェックか、あるいはPythonのPyLint、この辺りがルール分離型の初めてのLintになってくると思います。
この辺りになってくると、ルールをいろいろコミュニティが足していくっていうふうなことができるようになってくる。
これは実は一つの可能性を生んでいて、Lintって言語ごとに大抵用意されていたんですけど、
みんな言語の上にフレームワークとか使ったりしますよね。
そうするとフレームワークのルールを入れたくなってくる。
リアクトのコンポーネントのルール。
リアクトのコンポーネントのこれ使うなみたいなとか。
これをリアクト使ってない人に強制するのは変な話だから、ルールを切り替えられるようにしたいっていう。
そうすると一つのLintにいろいろなものが入れられると、こういうフレームワークのLintっていうのが可能になってくるわけですよ。
今はそんなに数が多くないんだけど、フレームワークのLintっていうのはやっぱりあります。
こういうのがだんだん増えてきて、だんだん今って生産力が爆上がりしてるから、
このフレームワークはこういうふうな使い方をしないでほしいっていうベストプラクティスみたいなのが、
今までドキュメントで配布されていたのがどんどんどんどんLintに変わってくると思います。
そういうふうなのがまず短期的にフレームワークとか言語よりももうちょっと細かい単位で入れたり外したりしたくなるようなものっていうのが増えてくるだろうと予測しています。
それで言うと、どんどんLintっていうのが本当に細かいところまで、本当の意味での糸くずみたいなところまで手が届くようになっていくという感じの予測だったんですけど、
逆にLintがいらなくなっていくみたいな世界線もあったりするんですかね。
今言った、さっき言った言語の仕様に取り込まれていく方向性、開発がどんどん高速化していくと、だんだん言語仕様の方も高速化してくると思うんですよね、言語の開発も。
っていう世界線もあったりするんですかね。
これは私はおそらくそうはならないだろうと思っていて、正確に言うと、なる分野もあればならない分野もある、2つに分かれるだろうという予測をしています。
なぜですかというと、まず分かれない分野っていうのは、Pythonが例えばインデントに口を出し始めたようにガッチガチに縛っちゃって、
1つのある処理の意味に対して1つのコードしか許さないみたいな、そういうふうな1つのやり方、1つの書き方だけみたいな、
そういうふうな考え方の言語コミュニティっていうのができた場合は、これはLintはほぼなくなるだろうと思います。
15:00
結構語言語とかがそれに近い雰囲気を感じますね。
一方で、いろんな書き方、1つのやりたいこと、いろんな書き方っていう言語もまたあります。
例えばRubyとかがそれに代表されるもので、こういうものたちっていうのは、そこに芸術性っていうのかなとかいろんなものを感じていて、
言語がそこを縛ろうっていう思想を持っていないんですよね。
だけどこの上に例えば何か大きな巨大な城みたいなものを例えようとすると、ある程度はやっぱり秩序が必要で、そういう時にLintを扱いたくなってくるっていうのがあって、
やっぱり言語側に吸収されていく、インタープリター、コンパイラーに吸収されていくものと、そうじゃなくてコミュニティが自分たちがあくまで自由なところの上に、
自分たちの城を建てたいみたいな時に補助的に使うLintを使う世界って、この2つに分かれていくだろうという予測をしている。
なるほど。じゃあどっちかというとLint単体というよりかもしかしたらフレームワーク単位でLintが作成される可能性もなくにしもあらず。
はい、その通りだと思っていますね。
じゃあレイルズのLintだったり。
そう、レイルズのLint。今はRuboCopの中にレイルズっぽいものとかいろいろ入れたりできるんで、そういうことは今はRuboCopが受け止めてますけど、
ただ例えばそうですね、わかりやすい話だと、例えばJavaScriptってJavaScriptにコンパイルされる言語たち、トランスパイルされる言語たちっていうのがあって、
そういう言語たちって元々のESLintとかって検査しても大抵何もわからないわけですよ。
そういうものたちっていうのはある意味フレームワークのLintに近いような形になっていて、トランスパイル言語のLintですね。
そういうものとかっていうのは結構出てくるんじゃないかなって思う。
まあしたりにもなってくるんじゃないかなって思う。
なるほど。
そうしています。
TypeScriptとかの場合はTypeScriptコンパイル、TSCとかが若干Lintを見ているか、そこでやってるのかなというのが若干ありそうですけどね。
そうですね。TypeScriptはTSLintっていう有名なLintあるんですけど、あいつあんまりルールないんですよね。
それなんでかっていうTypeScriptコンパイラーが大体やってくれるかっていう。
なるほど。じゃあやっぱり言語仕様というか、そういうところにLintは目指してるっていうことがありそうですね。
ちなみにそういうLintって今までの話だったらプログラミング言語だけだったかなと思うんですけど、
ここからはもうちょっと広がってLintって先ほど言ったみたいな感じで糸くずを取っていくみたいなツールだったんですけど、
自然言語だったりとか、あとは仕様書みたいなところまでLintの適用範囲ってどんどん広がっていくんですかね、プログラミング言語以外のところでも。
それはとってもその通りだと思っていて、まず一番最初にLintは自然言語に行く前に設定ファイルとかのLintにまず行きましたね。
なるほど。
例えばテラフォームみたいなのとか言ったらあれはプログラムというよりかどっちかというと設定ファイルに近いものだと思うんですけど、テラフォームにはLintはあります。
あれはその設定ファイルに対してこういう書き方を表製するってまさしくコードの延長線上でやっているっていうものなわけですよね。
こういうものたちがまず結構すでにいっぱい使われているっていうのがあると思ってます。
あとちょっと面白いものと代わりだけだとGitに対するLintみたいなのがやっぱりあって、コミットメッセージに対するLintみたいな感じですね。
18:03
そんなのもあるんだ。
っていうのもあって、こうやって言語に近づくようになってくるんだけど、Gitにはコンベンショナルコミットっていうやり方があって、
頭にこれはこういうタイプの変更台をみたいなことをくっつけるみたいなことがあって、
それが許可されてないものとかだと起こるみたいな感じのLintとかっていうのを作りたかった人がいるみたいですね。
そういうものとかがあったりします。
なるほど。
あとは先ほど仕様書って話があったんで、仕様書に関するLintは実は私が前職で作っていて、DNA時代に作っていて、
画面仕様書ってIOSのアプリとかAndroidのアプリがあって、そのアプリの仕様書に対する簡易的なLintみたいなのを作ってました。
これはAIを使ってなくて、例えばなんですけど、アプリの画面に画像を表示するとします。
ここに画像を表示してくださいってなったときに、画像が固定の画像だったら特に何も考えなくていいんだけれども、
お客様の上げた画像とかだったりする場合って、縦横の比率とかって決まってないですよね。
そうなった時に、画面上でどういうふうに拡大縮小するか、アスペクト比を保つべきなのかっていうふうな指定が必要になってきます。
この指定を忘れると仕様が漏れてるということになるので、こういうふうなのを画像をここにはめるんだとしたら、
少なくとも拡大縮小とかアスペクト比を保ってとかっていうような文言が入ってなきゃダメだよねっていうLintを作ります。
なるほど。じゃあ本当にルールベースですね。
ルールベースです。
完全なる、こういう文言を入れるべきであるみたいなルールがそこに定義されていて、
実行するとそれで起こってくれるみたいな。
その通りです。
じゃあどちらかというとあれですか、デザイナーの指定漏れを検出して、
エンジニアチームに渡す前に検出できるようにするみたいな使い方。
おっしゃる通りです。
結構それワークしました。
使用バグは結構、例えば私の担当分からはかなりのバグを見つけてくれたんですよね。
本当に書かなきゃいけなかったのに書いてなかったところを見つけてくれたんですけど、一方で運用は続きませんでした。
なぜかというと、エンジニアが使用書を書いていた時代があって、その時はうまく回ってたんです。
エンジニアその使い方とかもよくわかっているから。
なんですけど、だんだんエンジニアはちゃんとコード書く役割にシフトしていこうと。
使用が出来上がったんだからコード書いていこうという風になって、今まで使用書いてたエンジニアじゃない人たちが
それを触れるようになってきた時に、リントを気にしないでやっぱりやっちゃう。
なるほど。
当時リントをやっている対象はコンフルエンス上にあったので、
コンフルエンスってコミットする時にリントが必ずかかるみたいな設定は絶対できないですから、
そうなっちゃうとやっぱり無法置いたりになってしまう。
なるほど。
実行が毎度されなくなったから境外化してしまったと。
その通り。
難しいですね、その問題はとても。
あれですよね、だからそういう使用書をGitHubとかで管理していたら、
毎回リントが実行されて確認できていた。
21:02
けども、ビジネス職の方とかが触るからGitHubとかは結構難しいよね、
みたいな背景もあったって感じですか?
あったと思いますね。
それめちゃくちゃ難しくてどう解決すればいいのかって感じですね。
そこに実は私は最近やっぱりLLMが効くんじゃないかなと思っていて、
そのルールをオートフィックスしてくれればいいわけですよ、ルールに沿うように。
なのでLLMがオートフィックス勝手にしてくれるみたいな世界線はある意味運用が続く方法も一つだろうとは思ってしまう。
あれですよね、だから一回投げ込んでHuman in the loopみたいな感じで、
例えば画面の比率とかだったら絶対こんな感じですかみたいなタッチでAIが聞いてくれて、
ディレクターとかがそれですみたいな感じで承認していくみたいな。
そういうワークフローがちゃんと組めたらいいだろうというか、
ちゃんとLintを通すワークフローとしてワークするだろうみたいな形ですね。
なんかもう本当にLintから、Lintって言えばLintだけども、何て言うんですかね、
もうワークフローの話ですよねもう完全に。
ここはワークフローの話です。
仕事の進め方というかやり方みたいな、もうちょっとでかい話な気がしますね。
なんかLintの是非というよりかは、どうチームで進めるか。
でもそういう風な手段の中、例えば単体テストとかいろんなテストとかそういう風な問題を見つけるための手段がたくさんあって、
その中でもLintっていうのは比較的あんまりワークフローに影響を与えない方ではあります。
なぜかというと、単体テストとかっていうのは先にテスト書くかとか、
ちゃんとテスト対象はテスト用意になってないといけないねとかいろいろ考えなきゃいけないことがあるんだけれど、
Lintっていうのは大抵そうではないですよね。
確かに。
っていうのがあって、インストールするだけでまあまあ大体動くっていうのがLintの良いところで、
場合によってはLint入れたら4000個くらいのケースでI'm withみたいなケースになることももちろんあるんだけど、
そうじゃない限りは基本的にはインストールするだけで動くっていうのは良いところですね。
健全なことを維持するっていうのがなかなか難しいってことですよね、普通に。
それは多分普通のプログラミング言語にLintを入れて後から入れたパターンですね、プロジェクトに。
でめちゃくちゃ警告があるから、まあこれいいよねみたいな感じでみんなでするするみたいなのとかなり似てる、構造上。
いや、なかなかすごいですね。やっぱそういう、でもLintの進化先としてはやっぱりそういう人間の、
まあもうちょっと広いところのところにそういうLintという考え方を適用していくっていうのは、
次の時代というかAI時代にとってかなり重要そうですよね、より。
ちなみにLintって、どんな感じで実装とかってしていくんですかね。
例えば、さっき例で挙げてくれた、その仕様のLintだったりとかって、どんな感じで実装してたんですか。
24:07
Lintっていうのは基本的に大体2ステップから3ステップぐらいで実装されていて、
まずLintの対象となるものっていうのはコードっていうと文字列だけですね。
仕様書も文字列だし、コードも文字列。
ただ文字列のままだとすごく扱いづらいんですよ。
正規表現でいちいち見つけるかって言われたら大抵の問題に使えられないので、
なのでまずは分析しやすい構造に変換するっていうことをやります。
仕様書であれば例えば表があるんだったら表を抜き出してきて、
その二次元の配列みたいなものを入れてあげるとか。
あとは例えばコードだと代表的なのが2つあって、
1つはトークン列って呼ばれてるものですね。
例えば、JavaScriptとかで言うと、function、ほげとかって書いたりするじゃないですか。
そうするとまずはfunctionっていうその1つの並びがあって、その後にスペースがきて、
そこから次にほげっていうのがきて、次に括弧がきてっていう風に、
こういう風にちょっとした単位に分割していくことができますね。
これをトークンという風な言い方をして、このトークンっていうのを列、
ファンクションっていうのは次に空白がきて、次に関数2名がきて、
次に開き括弧がきてみたいな、これを検査していくっていうものがあります。
これがトークン列をベースにするもの。
もう1つは抽象構文理っていうものをベースにするものがあって、
例えばさっきのファンクションっていうのだと、
一旦そのファンクション全部が1つのオブジェクトになって、
このファンクションってところには名前と、あとはその引数列と、
あとはその中身、処理の中身っていうのが、この3つが古文としているわけですよね。
その小要素として持っていくと、
例えばその処理の中にはさらに関数を増やすことができるわけですから、
最遽的にこうな構造になって、要するに木構造になってるんですよね。
こういう風な抽象構文理っていうそのプログラムをデータ構造として木として
ご覧したものっていうの、この2つのいずれかに変換してから検査するものがほとんどです。
なるほど。じゃあ扱いやすくするっていうのが手前にあるって言います。
大前提あるって。
大前提です。
そこに対してルールを適用していって。
ルールの適用に関しては単純な異風文みたいな感じなんですかね。
基本的にはトークン列の場合は簡単で、セルトから順に見ていくだけです。
順に見ていって、要するに4-1ですね。4-1でやっていくっていう形になる。
関数型言語だと4-1っていうかリリースの方がわかりやすいかな。
で、抽象構文理も実はほぼトークン列みたいなもので、なぜかというと、
大抵深さ優先探索するからなんですね。
深さ優先探索は、要するに木があったらまずはどんどんどんどんここまで行って、
これ以上ここがいないよってなったら今日だって。いなかったら上に戻ってみたいなことをやっていくっていう風な
処理方法ですけど、この深さ優先探索にしているんで、結局木を一列に並べてるんですよ。
一列に並べて、それで検査していくっていう風なことをやっていく。
これはリントの世界だとよくトラバースっていう風な関数。
トラバース。
トラバースっていう風な言い方をしていて、大体どのリントにもこのトラバースっていうものが入ってます。
27:01
抽象構文理を一列に並べて、一個ずつ順番で見ていくっていう感じの処理をします。
さっき言ってた仕様書の実装はどうしてたんですか。
正規表現的な感じになっちゃうのかなってなんとなくは思うんですけど。
仕様書の場合はコンフレンスからデータを引っ張ってくると、JSONみたいな構造になってて、
表は表になってるし、見出しは見出しになってるし、その本文は本文になってるっていう風に、
この時点でデータ構造になってくれてるので、あそこで表を見つけてきて、
それで松のJSONの中から表を見つけてきて、そこだけを検査するみたいな、そんなようなイメージです。
なるほど。じゃあ仕様書の書き方自体もある一定のルールが存在している。
そもそもです。
それに倣ってプラスの忘れがちなところのルールを追加している、みたいなところが。
なるほど。
結構やっぱりリントって聞けば聞くほど応用範囲が広い。
リントというかリントの考え方みたいなお話かもしれないですけど、
高速に確認できる、そういうターランドタイムをできるだけ小さくして確認して、
良いもの、成果物を、品質を担保する、みたいないう考え方自体は本当にいろんなところで適用可能ですよね。
その通りです。
なんかちなみに次こういうところに応用してみたいなって、ぐにゃぐにゃきさんあったりするんですか。
やっぱりちょっと遅くなるってことは前置きした上で、生成AIによるリントっていうのはやってみたいなと思って、
実際今は生成AIによるリントをちょっと作っていて、今回の検査対象はテストケースでした。
テストケースっていうのは実際皆さんがソフトウェアを作っているときにバグが入っちゃってるかもしれないわけですよね。
それを検証フェーズに入るとテスターの人たちがこの入力を試してバグがあるかなってことを確かめて、
バグが見つかればまずいってことがわかるし、バグがなければその範囲では大丈夫そうだってことがわかるっていう活動ですよね。
このテストケースっていうのにはやっぱり良し悪しがあるんですよ。
テストケースっていうのは入力と出力のペアになっていて、こういうふうなことをするとこういうことが起こるっていうのが書いてある。
例えば、フィズバズ関数のテストケースだと言うと、1の時にはモジュレット1が返ってきて、3の時にはフィズが返ってきて、
5の時はバズが返ってきてみたいな、そういうふうなのがテストケースになっているわけですよね。
そういうテストケースが、例えば悪いテストケースだと、Aボタンを押すと正しい表示がされるとか書いてある。
正しい表示とは?ってなるわけですよね。
ありがちですよね。
ありがち。
テストケースが本当は正しさのサンプルなので、あなたが正しいって言ったら使うと循環したんですよって話になる。
ダメなんですよね。
正しいって言葉を正気表現で抜き出してきて落とすってことは確かにできるんだけれども、
それをすり抜ける、同じようなことをいっぱい書けるわけですよね。
例えば期待通りであるとか、観点表に書いてあるとかできちゃうわけですよ。
それは非常に良くないので、これをやっぱり生成AIとかに加わせてみて、ちょっと高速じゃないんだけど、
30:03
要するにリントからちょっと外れてきてはしまうんだけれども、テストケースの問題を見つけたいっていうことはやっていましたね。
それは現時点でやってる?
結構いくつか成果があって、こういうふうなAIに静的検索器、リントみたいなのを作ると、問題が2つあって、
1つは遅い、これは周囲に1回回すとかっていうのでだいぶ軽減できるんですけど、もう1つは擬容性が多いことなんですね。
嘘をついてくる。
嘘の警告。嘘をついてくるっていうのは2つの意味になっちゃうから、どっちかというと誤警告が出てくる。
つまり警告なんだけど本当は実は警告じゃん、問題起こってないみたいな、そういうことです。
なんでもかんでも口うるさく言ってくるんですよ、おかんリントみたいに。
これ実際に私の手元でやったやつだと、ある時は3分の2が誤警告でしたね。
かなり多いですね、それは。
っていうのがあって、またあるケースでは100%が誤警告でした。
なるほど、使い物にならない。
使い物にならない、そう。っていうのがあって、この誤警告をいかに減らすかってことがAIベースのリントのポイントになってくるっていう感じですね。
完全に世の中がやってるハルシネーションを抑えるみたいなところがそこ。
そう、なってきます。今回やった方法は3つあります。
1つはネガティブプロンプトを入れる。
例えばこういうものは、これはお客様にとってこれがOKかOKじゃないかってことは重要じゃなかったら、それは問題じゃなくていいよっていうネガティブプロンプトを入れたりとかするっていうのがあります。
これ入れるとだいたい100%だったら誤警告率が60%ぐらいまで確か落ちてくれるんですね。
だいぶ落ちてくれる。その代わり、義人性って言って、本当は指摘しなきゃいけないんだけど指摘を忘れちゃったみたいなのが増えます。
難しい。
難しい、そう。
で、もう一つの方法が敷地制御ってやつで、AIに深刻度を何段階から評価させるんですよ。
深刻度、これ以上のものだけは対応して、それ以下は対応しないであったらバッサできるっていうのがあって、
実際そのAIの判定した深刻度と人間の判断した深刻度と比べてみると、大雑把に言うと相関がちゃんとあるっていう感じ。
なんだけど、やっぱり何でもかんでも深刻と言いがちではあるんだけれども、AIが深刻じゃないって言ったものは、やっぱり人間は全部深刻じゃないって評価してるものだけしかなかったので、
そのAIが深刻って言った、最も深刻って言ったものだけを見ればいいってやると警告を15%減らせるんですね。
これもまた結構効くっていう感じのものです。
これが2つ目の敷地制御。で、3つ目が、これがちょっと結構ユニークかなと思っていて、形式化シンキングっていう方法を使いました。
形式化シンキングっていうのは、これ私が普段やってることをちょっとAIにやらせてみたっていうやつの話なんですけど、
何か曖昧に書かれてるものっていうのが本当はどういうデータ構造を持っているべきで、そのデータ構造に直した後にこういうふうな違反があるよってルールを検査させるんですよ。
33:01
ってことをやらせてみたらどうなるかっていうのが形式化シンキングってやつです。
今回の場合のテストケースっていうのはちょっと難しい理論を使って、テストケースはこういうデータ構造になるはずだよっていうことを伝えた上で、それに一旦セセアに変換させるんですよ。
変換させて、それにこのデータ構造はこういうものが違反だよ、まずいものだよっていうのを与えてあげて、そこでチェックさせるってことをやらせました。
で、そのチェックして出てきたものがデータ構造に言及する形になっちゃってるからちょっとわかりにくいので、最後に紙砕いて説明してねっていう。
人間にはわかりやすいから説明するっていうので、結局人間はテストケースを入れて問題を受け取るって形に変わりはないんだけれども、内側の質を変えるってことをやりました。
これをやったら、擬音成立が6割から3割まで落ちたんですよ。
おーでかい。
でかい。そして、擬音成立はその3割だったものが0%になった。
おーすごい。
っていうのがあって、この結構形式化シンキングが効くんじゃないかっていう、ちょっと弱い証拠、サンプル数が少ないんで、弱い証拠が得られたっていうことをやってました。
ちなみにそういういろんなやり方でハルシネーションを抑えていくみたいなやり方もある一方で、そもそものコンテキストとしてそのプロダクトがどういったもので何を重要視しているかみたいな大前提のコンテキストを入れておくことも結構重要だったりするんですかね。
えっとそれは何を調べたいのかによるっていう感じですね。これもちょっとLintの考え方に少し似ていて、Lintっていろんなことをチェックすればするほどリッチにできる。その代わり遅くなってくるんですよね。
そりゃそうですよな。
AIも全く同じで、コンテキストに追加してあげればあげるほど見られる問題は増えてくる。
例えばこれはあなたのテストケースはプロダクトのやりたいことを実現できてないみたいなことをやるためにコンテキストにビジネス要件とか呼ばれるものとかみたいなそういうものを入れたからあげないといけないですよ。
KPIとかお客様のペルソナーコーデみたいな。それをやっていくと遅くなるしお金もかかる。
なるほど。
ここがトレードオフになっているってことですね。
だからこそそこでちょっと線引きというかここまでは確実に検知できるからというところがLint味があるところなんですね。
Lint味があるところです。
だからやりたいこととしては100%これによって品質が100%のテストケースが担保されるよではなくてあくまでも最低品質が担保されているがやりたいことなんですかね。
確かにそれだったら一般的なテストケースだったらこういう感じになってるよねみたいな確かに聞きそうな感じがします。
すごい未来というかやっぱそういうところがあると本当に仕事とかでQAとかやるんですけどテストケースとか作るわけじゃないですかもちろん。
テストケースを作る専門家でもないわけですよ自分は。
このテストケースが合ってるかどうかは分からないけどこのテストケースを流すことによって何か一定の安心感を得るからやるみたいな感じになってて。
36:06
まあでもそもそも大前提このテストケースが間違ってるとあれなんだけどもねみたいな感じに結構なりがちかなと思ってて。
そういった意味でも本当に全く最初の結論と一緒でそれはもうメンタルに効くんですね。
そうメンタルに効くんですよ。
その最低保証がこのツールによってされてますよというのはかなりの安心度がありますね。
そうやっぱり私は開発する時に自信ってすごく大事だと思うんですよ。自信がないものを開発すると速度落ちるしやっぱり負の影響すごいんですよね。
だからなるべくなら自信を高めた状態で開発する方がやっぱりいい成果を生むと思っているのでその意味で私はLintがすごく役に立つと思っているって感じですね。
なんかいい感じでちょっとまとまったところでちょっと今回は時間があるのでここらまでにしたいなと思います。
なんかLintについてくねけさん最後にあります言いたいこと?
そうですね言いたいことはねやっぱりLintはねいいですよ。ぜひLintを学んでいきましょう。
Lintはいいぞというところで。ありがとうございます。
ということで今回はここまでにしたいと思います。
ちょっとぬるっと始まったんですけどもっと詳しく教えてくださいラジオという番組です。
この番組ではですね略してクワラジって言ってるんですけどスーパーエンジニアであるくねけさんに一般エンジニアであるへんてこが技術的な質問をしていく番組になっています。
今後もですねいろいろなことを聞いていきたいなと思ってますので大きなプラットフォームで高評価やフォローの方お願いします。
またですねこんなことをくねけさんに聞いてほしいちょっと深掘って聞いてみたいみたいなことありましたらコメントいただけると取り上げたいなと思ってますのでよろしくお願いします。
Xなどでハッシュタグクワラジ、クワはひらがな、ラジはカタカナでつぶやいてもらっても大丈夫ですのでよろしくお願いします。
感想もぜひお願いします。
それでは今回ありがとうございました。
ありがとうございました。