QuickThinkerをリリースしました!
QuickThinkerは約70%(コード割合)がLLM(ChatGPT,Claude)で作られています。本日はQTを実装するにあたり、LLMを用いたプロダクト開発の感動と苦労を語っていきたいと思います。
下記からインストールできます(Google Chromeのみ対応)
Chrome拡張の基本機能が一瞬でできた
QuickThinkerは、現在見ているwebページを要約/質疑応答できる拡張機能です。QuickThinkerのような、copilot的なものは世の中たくさんありますが、そのwebページ以外の情報を組み合わせて情報を深く理解できるツールがなかったため、自分で作ることにしました。私自身はエンジニア(機械学習/AI)であるものの、Chrome拡張を作ったこともなければフロントエンドもちょっと大学の講義で触ってみた程度の経験しかありませんでした。
(今回リリースしたQuickThinker)
そんな中、LLMを使って遊びで作ってみたところ、ものの2時間ちょっとでwebページの要約/質疑応答ができるChrome拡張機能ができてしまいました。
(できたもののイメージ)
デザインを整える
一瞬でベース機能はでき、MVP(Minimam value product)としては十分動くものができたものの、デザインはイマイチ(今もイマイチというツッコミは置いておいて)でした。上記の画像のように、かなりシンプル近い状態でした。(素のHTML状態といえばエンジニアには伝わると思います)
そこで、私は運良くtailwindを知っていたので、「tailwind風にして」とLLMに指示したところ、今のデザインになりました。たった一言で、デザインが見違える程変わりました。
また、UIに関しては、LLMは人間の感覚とズレている感じたところもあります。チャット欄の境目を右にドラッグしたら右に動き、左にドラッグしたら左に動くのが人間的な動きですが、LLMは逆の実装で出力してきました。(たしかに明示していませんが。)
雑務的な部分はLLMへアウトソース
さて、基本的な機能は全てできたのですが、プロダクトとしてリリースするには十分ではありません。
ロゴを作成する
設定ファイルを書く
デプロイする
LPを作る
決済まわりを実装する
特商法に関する取引やプライバシーポリシーを作成する
Chrome拡張の審査
など、いろいろやることがあります。
そんな雑務的な部分も、全てLLMにやってもらいました。今回のQuickThinkerのロゴも生成AIで作成していますし、LPのデザイン〜実装も全てLLMにしてもらっています。(基本的には80点のところまでLLMに作ってもらい、残りは人間が行うようにしました)
(LLMが作ったロゴ)
LPのデザイン、ページ遷移の設計、プライバシーポリシーの作成全てを8割方作ってもらっています。LLMがなかった時代と比べて、20倍くらいのスピード感で色々進んでいきました。エンジニア以外の職種の方も、LLMを使わないのはありえないと思いました。
ハルシネーションで悩まされた1週間
ハルシネーション(幻覚)とは、平たく言えばLLMが嘘をつくことです。chatGPTリリース当初と比べるとハルシネーションはかなり減ったと思いますが、それでも現状起こってします。今回のプロダクト実装およびリリースで一番苦労したのが、この「ハルシネーション」です。
1例を出すと、「このコードをEdgeで動くようにして」と指示すると、LLMは実際に動かないコードをあたかも動くものように出力してきます。当時のコードではEdge対応はできないのですが、「できない!」とはっきり言わず、動かないコードを永遠と出力してきました。存在しないメソッドを使ったり、動作しないメソッドを出力したり。
ハルシネーションに苦しんだ原因の1つに私の知識不足の部分もありました。webアプリエンジニアの方ならコードを読んで気づけたかもしれませんが、私には全くわかりませんでした。
結局なぜ気づいたかというと、Perplexityで外部検索をしながら原因解明を進めていき発見にいたりました。「できない」といってくれれば違うアプローチをとれたのに、「できる」と言われ続けたのがかなり時間を無駄にしました。
実装でのハルシネーション地獄に陥る3つの条件
1つ仮説なのですが、このようなハルシネーション地獄に陥る条件が3つあるかと思っています。
1. あまり多くの人がやったことないことをやろうとする(学習データにない)
2. LLMに入力する前提が省略されている
3. 入力が長い
1に関しては、LLMの特性とかpre-trainを考えると納得すると思うのですが、学習してないことには対応できないが、何かしらは出力してしまうという特性からきていると考えています。2に関しては、暗黙の前提を作り出す問題からきています。3は、入力が長くなると、前提を忘れたり自分で話したことを覚えてなかったりします。つまり、これらの3条件を満たすと、私のようにハルシネーション地獄に陥る可能性が非常に高いということです。
企業戦略とシステムの不一致
今回学んだことなのですが、LLMは長期の視点での最適実装を提示するとは限りません。最適実装というのは、企業戦略/リソースに即した実装を指します。
今回の具体例でいうと、Chrome拡張機能だけど、Microsoft Edgeに対応できるよう実装をしてほしかったができていませんでした。最初実装する前に、Edge対応できるかどうかLLMに聞き、「できる」との回答で進めたのですが、いざLLMに実装をさせ、リリース間近にEdgeでテストしたら動きません。後からLLMに聞くなり自分で調べるなりしてわかったことなのですが、EdgeとChromeの互換性がないメソッドを使ってLLMが実装を進めていました。
このミスはリリース間近だったので当初の計画はかなり狂いました。これに加えて、後述するハルシネーション問題も複合し、かなりのリソースが喰われました。このようにLLMは短期的な実装は良い時が多いのですが、長期的な戦略を踏まえたプロダクト開発はまだまだできないと思いました。
なぜ企業戦略とLLMの実装がズレるのか
これは私の分析なのですが、使う側とLLM側に問題があると思います。
1. LLMに十分な情報を与えていない(使う側)
2. 不足情報を聞いて来ないし、暗黙の前提を勝手に作る(LLM側)
3. ハルシネーション(LLM側)
人間で考えるとわかりやすいのですが、実装者に十分な情報を与えておらず実装させた場合に手戻りが発生することは多々あると思います。実装者が人間なら、LLMに与えるような指示だけでは実装できません。仕様書を確認する、指示者に質問をする等、不足している情報を補う行動をすることで、意図した通りに実装できるのです。しかしながらLLMはこの「不足している情報を補う」行動ができないので、このような事態が起こってしまうのです。
例えば仕事で、「素数判定のAPIを書いといて」と言われた時、あなたはどう動きますか?どんな言語で、どういった仕様かを確認すると思います。不足情報を聞きますよね。一方LLMは、この指示だけでpythonでコードを書き始めます。幸いLLMの出力は一瞬なので、その場で指摘してすぐに書き直してもらえます。ですが、それは指示する側が意図とは別のことをしているのが判明している場合のみです。複雑なコードや、ステップ数が多くなってくると、この不足情報を勝手に妄想で作られることが後になって大きなダメージとなって返ってきます。
今回のQuickThinkerの実装では、いつのまにか暗黙の了解がChromeでのみ動くコードということになっており、将来的に高いコストを払わなくてはならなくなりました。(Edge対応は別途実装する予定です。エンジニアの方ならわかると思うのですが、似たような機能の二重管理は技術的負債となり、時間が経つにつれ開発速度の鈍化や高いコストを払わなければならなくなります。)
最後に
LLMの弱点や文句をかなり言いましたが、それでも今回のリリースはLLMがなかったら確実に成せてなかったと思います。「自分が今までできなかったことを、LLMを使ってできるようになった」ことが何より未来を感じさせてくれました。LLMでビジネスが変わる系の話は色々なところに情報があるので割愛しますが、私もそう思います。また、LLMは日進月歩で進化しているので、今まで述べたことが近い未来改善される可能性が高いです。今後もLLMの進化を期待するとともに、正しい付き合い方をしていきたいと思います。
おまけ:プロダクト開発を通してわかった、LLMとうまく付き合える人
今回の経験から、LLMとうまく付き合える人は2種類いるんじゃないかと考えています。1種類目は、IT戦略を考慮しながらLLMの出力に責任を持てるようなスペシャリストです。LLMが出力したコードの意図を理解しながら、意図にそぐわない部分は書き直しを指示できる人です。
もう1種類は浅く広く知っており、重要な意思決定に関わるゼネラリストだと思っています。浅く広く知っているのも何よりも重要だなとつくづく思いました。上記でも例を出しましたが、「tailwind」という単語と何をする時に便利なのかを知っていれば、実装したことなくても生成AIが勝手に作ってくれます。「浅く広く」の「浅く」が、生成AIによってブーストされ「深く」なるんじゃないかと思いました。
おまけ:LLMとのやりとり
おまけでQuickThinkerを作った時のプロンプトを一部お見せします。
Comments