🤖

ビジュアルプログラミングにLLMを組み込みたい(Blockly × LLM)

2024/11/22に公開

初めまして。そうまめこと得丸創生と申します。
1年ほど前からTypescript / ReactのWebアプリ開発にどハマりして、現在は「TutoriaLLM」というビジュアルプログラミングとAIによる対話、そして、リアルタイムのコード実行の機能などを組み込んだWebアプリケーションを作っています。

https://tutoriallm.com

「TutoriaLLM」は、今年の頭から開発していて、初めてまともに作ったアプリではあるのですが、嬉しいことに未踏ジュニア2024に採択していただいたり、アプリ甲子園2024のAI開発部門で優勝したりしています。

ただ、色々外部のコンテストとかに出してはいるのですが、1つ1つの機能について詳しく説明する機会はあまりなかったので、今日はこのブロックプログラミングを用いたプログラミング教育におけるLLMの組み込みにおいて、色々考えてみようと思います。

多くの人に見てもらいたいので、プログラムの記述などは省きます。詳しいことが気になる場合は私に直接聞くか、GitHubのリポジトリを参照していただけると助かります。(需要があればさらに掘り込んだことも書こうかなと思っています。)
https://github.com/TutoriaLLM/TutoriaLLM

VPLへのLLMの組み込み

VPL(ビジュアルプログラミング言語)はよくプログラミング初学者の教育に用いられることが多いイメージがあるかと思います。そして、最近はLLMの精度も向上してきて、VPLにLLMを組み込もうと考える人もいるのではないかと思います。
https://zenn.dev/yutakobayashi/articles/blockly-openai
たとえば、yutaさんが開発したこのデモでは、Googleが開発したBlocklyというVPLのワークスペース内に直接プログラムを作成することを実現しています。今日ご紹介するTutoriaLLMのVPL×AIの部分のシステムはかなりここからインスパイアされています。

問題点があった

しかし、先述のデモは、一般的な開発者にはかなりウケが良いのです(自分もそのうちの1人です)が、実際にユーザーテストなどを行うと、子供たちが使うとあまり効果がないことがわかりました。GitHub Copilotなどもそうですが、LLMはプログラムを直接作成ということは、人間はプログラムを書くことが少なくなり、特に子供たちはそれに頼りっきりになってしまうため、「自分より良いプログラムが書けるなら、もう全部AIにやって貰えばいいや!」と丸投げになってしまいます。私もCopilotに頼りまくっている人間なので、否定するわけにもいきませんが、ここでは、子供が思考停止してAIに全部タスクを丸投げする事は良くない事として扱います。

ユーザーに手を動かしてもらう

そこで、TutoriaLLMでは、このように、ブロックをハイライトしたり、使うブロックを直接提案するシステムで、ユーザーに実際に手を動かしてもらいながら、AIがそれを補助するというシステムを開発しました。
Image from GyazoAIによるブロックハイライト

Image from GyazoAIによるブロックの提案

まだ大勢に対してテストはできていませんが、これならユーザーは少なくとも自分で手を動かす必要が出てきますよね。実際、私はプログラミング教室で先生をやっていたことがあるのですが、その際も、このようにプログラムの作り方をステップごとに教えていました。LLMは人間の行動、言動を真似することがとても上手なので、このようにステップバイステップで教える際も、ちゃんと動いてくれます。

どうやって実装したのか

このブロックハイライトとブロックの提案は、どちらもBlocklyというビジュアルプログラミングを提供するためのフレームワークに少し手を加えたものを使っています。Blocklyでは、ワークスペースの内容を動的に取得することができます。また、ツールバーの内容なども、ちょっと手を加えれば簡単に取得することができます。

Blocklyワークスペースの内容は、シリアル化することができ、JSONまたはXMLでの保存が可能です。TutoriaLLMでは、このJSONを用いて、処理を行っています。
ハイライト方法に関しては、ワークスペース内にSVGを直接描画することで対応しています。こちらに関しては調べたら出てくると思います。

ツールボックスはBlocklyから用意されている方法で読み取ることができます。折りたたみ可能なツールボックスは、一番下の階層まで全て調べて、一致するカテゴリを発見したらそこまでの経路を全てハイライトすることで処理しました。

そして、これらの技術を使った上で、LLMからの応答を解析し、ブロックのハイライトやブロックの提案などがあれば、フロントエンド側でそれをユーザーが使える形にして応答します。

初期段階

初期段階では、画像のような応答が返ってきていました。1つのメッセージにつき、1つのブロックをAIが指定できます。
Image from Gyazoブロック名をチャット内に書いてしまっているのは良くないですね
これを実現するために、OpenAIのAPIからの構造化出力を用いました。確かこの機能を作っている途中に、JSONモードに代わる新しい構造化出力モードが発表されて、エラーが起きる確率が大幅に減った気がします。
うろ覚えではあるのですが、こんな感じの応答がgptから返ってきていました

{
content: "現在、チュートリアルが..."
block: "ext_example_console_log"
toolbar: null
}

現在の仕様

しかし、この仕様には問題がありました、ブロックが1つしか選べないのです。しかも、文章が長くなりがちなので、小学生程度の子だと、全部読んでくれません。
そこで、若干の確実性と引き換えに、新しいシステムを導入しました。
Image from Gyazo
このシステムは、LLMから出力されたMarkdownを含む文章をフロントエンド側で解析して、ブロック名やワークスペース内のブロックIDが含まれていたら、それを適切なフォーマットに置き換えてレンダリングします。ブロック名やIDが間違っている場合はそのまま文字として表示されてしまうのが現状の問題点ではあるのですが、これのおかげで不要な文字情報を大幅に削減し、よりわかりやすい応答が返せるようになりました。
LLMはただユーザーのワークスペースを文字列として認識し、それを文字列として返していますが、ユーザーはそれが視覚的な情報に変換されて見えるため、結構コスパの良い方法かなと思います。
Image from Gyazo
こんな感じで、インラインで複数のブロック、ワークスペースの指示ができるようになりました。

これなら、先生がいちいち画面を指差して「ここだよ、ほら、ここ!」と言わなくても、AIが全部代わりにやってくれるので、とてもわかりやすいですよね。

音声モード

また、これらを音声で実装するという取り組みも行なっています。
ちょうどこの前出たgpt4o-audio-preview(だったかな?)というモデルでは、これらの入力と出力を音声に置き換えることができます。
巷ではRealtime APIの方が話題になってはいましたが、Realtimeは一度切断するとコンテキストを全て忘れてしまうという致命的な欠点があったのに(今は分かりませんが)加え、voice to voiceしか利用できないため、使いませんでした。
audio-previewは、構造化出力はまだサポートしていないので、たまに壊れたJSONとかを返してしまったりすることはある(ちゃんとしたエラー処理が必要)のですが、ユーザーの指定した通りの方法で対話を行うことができます。たとえば、音声で入力したら、テキストで出力する〜みたいな流れでも全然使えます。
Image from Gyazo音声での入力の場合

Image from Gyazoテキストでの入力の場合

とはいえまだ実用的か?と言われるとそうでもない気もするので、よかったらdemo.tutoriallm.comで試してみてください。

終わりに

ということで
TutoriaLLMは現在開発段階で、毎日のようにクラッシュするレベルで不安定...なのですが、すでにデモ版を公開しています。また、全てオープンソース&絶賛コントリビューター募集中ですので、汚いコードにはなってしまいますが、よければ覗いて行ってみてください。
https://github.com/TutoriaLLM/TutoriaLLM

ご興味ありましたらSNS等フォローもしていただけると嬉しいです!
https://tokumaru.work/ja

Discussion