電通総研 クロスイノベーション本部の山下です。2025年11月-12月にかけて開催されたKiroのHackathonイベントであるKiroweenに参加しましたので、そのレポートをお送りします。
このイベントはKiroを使ってアプリケーションを開発することを目的としたハッカソンイベントです。
作るもののテーマがハロウィンをモチーフにしたイベントになっています。
参加要件など
以下のような参加要件になっていました。
実際の詳細は公式サイトをご覧ください。
基本的にKiroを使ってアプリケーション開発をすればよいのですが、テーマが指定されているのが特徴です。
- Resurrection: お気に入りの技術を復活させる
- Frankenstein: 複数の技術を組み合わせてアプリを作る
- Skeleton Crew: スケルトンを作成し、それから複数のアプリを作る
- Costume Contest: 洗練された不気味なデザインのアプリを作る
といったテーマのようです(日本語訳は筆者による)。
自分はResurrectionを選びました。参加するにあたりテーマ選定にかなり悩んだのですが、知人から自分が普段Common Lispを使っていて、それは十分に古い技術なのではという指摘を受けて、確かにその通りだなということで決めました。
作ったもの
Kabotanというアプリケーションを実装しました。KabotanはCommon Lispを使って作った、HTMXとLLMを組み合わせたアプリケーションです。ハロウィンにちなんだ機能を提供していて、質問に答えたり、ハロウィンに関する文章を生成したりすることができます。
なぜCommon Lispを採用したかというと、古い技術と見なされており、テーマのResurrectionにも合っているためです。一方で自分は普段それなりにCommon Lispを使っているので少しでもCommon Lispの良さを知ってもらえたらと思い選びました。
Kabotanは以下のURLで公開しています。
https://github.com/dentsusoken/kabotan/
Kabotanは以下のようなアーキテクチャになっています。

- フロントエンド: HTMX + Tailwind CSS
- バックエンド: Common Lisp (clack + hunchentoot)
- LLM: llama.cppを利用したローカルモデル(gpt-oss-120bなどを想定)
モダンなアプリケーションではフロントエンドにReactやVue.jsなどのJavaScriptフレームワークを使うことが多いですが、今回はシステムの大部分をCommon Lispで実装したかったため、HTMXを採用しました。
フロントエンドにHTMXを使うことでフロントエンドのJavaScriptコードを最小限に抑え、アプリケーションの大部分をCommon Lispで実装することができました。
実際の画面の例を以下に示します。

特に各コンポーネント間のやり取りではServer Sent Event(SSE)を利用して、LLMからの応答をリアルタイムに受け取れるようにしています。これにより、ユーザはLLMが応答を生成している間も進捗を確認でき、よりインタラクティブな体験が可能となっています。
個人的にはCommon Lispでも現代的なアプリケーションの実装は十分に可能ということを示せたのではないかと思います。
ちなみに、Common Lispを含むLisp系の言語は括弧が多いことで有名です。慣れるとS式は読みやすいのですがなれないと苦労するかもしれません。例えばKabotanのindex.htmlを返す部分は以下のようなコードになっています。
(defun serve-index (env) "Serve the main index.html page. The Lack session middleware automatically handles session cookies, so we don't need to manually set them here." (declare (ignore env)) (let ((html (uiop:read-file-string "public/index.html" :external-format :utf-8))) `(200 (:content-type "text/html; charset=utf-8") (,html))))
Lisp系言語ではこのS式と呼ばれる (関数名 引数1 引数2 ... 引数N) というような記法でプログラム自体を記述します。このデータもプログラム本体も全てこのS式で表現することで、非常に強力なマクロを作れたりするのが特徴となっています。
実装するうえで苦労したところ
Common LispをKiroで利用するにあたって苦労した点、工夫した点がいくつかありました。
Common LispをKiroで利用するための整備
まず、Common LispをKiroが利用できるようにするための整備です。例えば、Common Lispには標準でデバッガが実装されており、エラー発生時などには自動的にデバッガが起動します。Common Lispで広く使われている開発環境のSLIMEではこれを便利に利用することができます。しかし、この機能はKiroなどのAIにとっては対話的な操作が必要になってしまいAIの操作を阻害してしまいます。
また、ASDF(Another System Definition Facility)というCommon Lispのデファクトスタンダードなビルド管理システムがあります。これも事前に定義を行っておきひな形のアプリケーションが動作するような状態まで整備を行いました。その上で、makeを利用して常にデバッガを起動しないオプションを付けて起動するようにし、Kiroからもmake経由で実行するような形にしました。
最終的には以下のようなMakefileのエントリとなりました。--disable-debuggerを実行時に引数で渡し、ASDFを使ってKabotanをビルド、実行する形になっています(ql:quickloadがASDFを内部で呼ぶ仕組みになっています)。
ROS = ros
LISP_IMPL = sbcl
SYSTEM = kabotan
TEST_SYSTEM = kabotan-test
run:
$(ROS) -L $(LISP_IMPL) run -- \
--disable-debugger \
--eval '(ql:quickload :$(SYSTEM))' \
--eval '(uiop:quit (kabotan:main))'
Server Sent Eventへの対応
Kiroでのアプリケーション開発において、Server Sent Event(SSE)に対応させるのに苦労しました。SSEはサーバからクライアントへリアルタイムにデータを送信するための技術であり、LLMの応答をリアルタイムに受け取るために必要でした。
ブラウザ-Kabotan間のSSE対応
Common LispのWebフレームワークであるclackやhunchentootは直接このSSEをサポートしておらず、独自に実装する必要がありました。これはclackのソケットを直接操作する機能を利用して、SSEに対応させることができました。
Kabotan-llama.cpp間のSSE対応
llma.cppのサーバにとってKabotanはSSEのクライアントとして振る舞う必要があります。
これもCommon LispのHTTPクライアントライブラリのdexadorを利用して独自に実装する必要がありました。dexadorは通信に利用しているソケットを扱うことができ、これを操作することでSSEに対応させることができました。
その他苦労した点
HTMX周りはKiroに色々指示を出さないとうまく対応できないことがあり苦労しました。HTMXはフロントエンドのJavaScriptコードを減らすことができる利点がありますが、Kiroにその利点を理解してもらうのが難しい場合があり、何も指示を行わないとフロントエンドのJavaScriptでほとんどの実装を行ってしまい、HTMXの利点がない構成になってしまうことがありました。
またLLMを利用するアプリケーションはテストに時間がかかってしまいます。
そしてKiroはコマンドの応答待ち時間が最大で20分になっていますが、稀にこれを超えてしまうことがありました。こうなってしまうと、Kiroはテストを途中で打ち切ったり問題がないのに問題があると判定して編集作業を行おうとしたり、逆に問題があるのに問題ないと判断してしまったりすることがあり、開発効率が低下することがありました。
Kiroの使い方について
Hackathon全体を通じてどのようにKiroを活用したのかについても紹介します。
Kiroを使ううえで重要だと感じたポイントは以下のとおりです。
- Spec、Steeringの活用
- Hookの活用
- テストの工夫
特に、SpecとSteeringの使い分けは重要だと感じました。
Specという名前を見るとSpec側に詳細な仕様を書くべきだと考えがちですが、実際にはSteering側に詳細な仕様を書く方が効果的でした。例えば、アーキテクチャに関する指示、設計上の選択といったものはSteeringに記載し、実装が進むにつれて状況が変わるたびにSteeringはプロジェクトの実際の状況を表すように更新する必要がありました。
そして、Specは実際の小さな作業を行うために必要な最小限の仕様に留めておく方が効果的でした。基本的な動作の概要を伝えて、Design.mdを作成してもらい、Task.mdを生成してもらうようにしました。つまり、Specはスクラム開発などでいうところの「ユーザーストーリー」に近い役割を果たし、Steeringが「詳細な要件定義書」や「設計書」に近い役割を果たす形です。
これらを前提に置き、詳細な設計などはVibe CodingでKiroと相談しながら進め随時Steeringを更新したり、簡単なバグ修正などは直接修正したりして進めました。一定規模を超える作業になりそうな場合はSpecを作成して対応してもらい、リファクタリングなどの作業もSpecとして作成して随時実施するようにしました。
以下は開発時のKiroの画面の様子です。Agent Steeringに色々設計上を指定しておき、作業ごとにSpecを作り開発していきました。

また、Hookも積極的に活用しました。Hookを使うことで、Kiroが生成したコードに対して自動的に追加の処理を行うことができます。Kabotanではlispファイルが更新されたときに自動的にテストが実行されるようにHookを設定しました。Hookは便利なのですが、TaskとしてKiroが実行してしまうためHookを実行している間新しいタスクの着手が出来ないという欠点もあります。つまり、タスクが完了したとKiroが報告してくるので次のタスクを実行しようとするが、Hookが動作している間は新しいタスクに着手できないということです。しかもKiroは現在実行中のタスクを一望するインタフェースが分かりづらい位置にあるので最初は苦労しました。
以下のUIで実行中のタスクなどが確認できます。クリックして初めて詳細が分かるようになっています。常に表示されていると便利なのですが今後是非改善してほしいですね。

テストの書き方も簡単な単体テストであればKiroに生成してもらうようにして、実際の動作を確認するような総合テストについては細かく指示を出してKiroに生成してもらうようにしました。総合テストでは受け入れのためのテストを作るような指示を出し、それをこまめに実行するような運用を行いました。これは最終的な動作だけはちゃんと確認したいという意図でした。
Kiroが良くなっていた点
Kiroが発表されてから時間が経過しており、その間にKiro自体も改善されていました。今回のHackathonを通じて特に良くなっていたと感じた点は以下のとおりです。
利用できるモデルが増え、特にClaude Sonnet 4.5が利用できるようになりました。これにより、生成されるコードの品質が向上しています。また、利用中にKiroがGA(General Availability)になりQ Developer CLIがKiro CLIになったという変化もありました。これに合わせてアカウント管理などもKiro側で行うことが可能になり、より使いやすくなっていました。特に上限に達した場合にも追加で課金を行うことで利用が可能になるのはとても便利になった点です。Q Developerを試していたころは上限に達すると利用できなくなってしまい、開発が中断されてしまうことがありました。新規アカウントをその都度発行するという手段もあるのですが、会社のアカウントで利用している場合は難しい場合もあるので、追加課金で対応できるのは便利です。
また、プロパティベースのテストが生成できるようになりました。以前は単体テストなどの具体的な値を使ったテストが中心でしたが、今回はプロパティベースのテストを生成するように指示を出すことで、より広範囲な動作確認が可能になります。受入テストなどでは特に有効だと感じました。
まとめ
KiroのHackathonイベントであるKiroweenに参加し、Common Lispを使ったHTMX+LLMアプリケーションであるKabotanを開発しました。Kiroを活用することで、効率的に開発を進めることができ、Common Lispでも近代的なアプリケーションの実装が可能であることを示せたと感じています。
またKiroは言語の限定なく利用できるということが公式ドキュメントで記載されています。Common Lispでも問題なく対応出来ました。採用する機会が少ない言語も含めて色々な言語でアプリケーション開発可能であることも確認できました。
Kiro自体も改善されており、より使いやすくなっていました。今後もKiroを活用して様々なアプリケーション開発に挑戦していきたいと考えています。
以上、Kiroween参加レポートでした。
執筆:@yamashita.tsuyoshi
レビュー:Ishizawa Kento (@kent)
(Shodoで執筆されました)



