こんにちは。
今回はClaude 3.7 sonnetの助けを借りて個人用ミニwebアプリを開発してみました。
普段はサービスデザイナーをしている開発素人の私がClaudeとともにアプリづくりを進めた過程や感想をつづります。
プロンプトやClaudeからの応答を抜粋して載せていますので、初心者のAI駆動な開発プロセスを追体験いただけたら嬉しいです!
プロローグ
「Hey Claude, 俺一人でwebアプリ開発できる確率は?」
『…6%です』
「……ま、そんなところか」
『…あなた一人なら』
「?」
『…あなたは一人ではありません』
「……フッ…。
…そうだったな」「…Hey Claude、"俺"と"お前"でアプリ開発できる確率は?」
『100%です』
「最高だ」
Claude 3.7 sonnetがでた!
2025年2月末、アンソロピック社の最新モデルClaude 3.7 Sonnetが発表されました。
概要はBedrockでお馴染み 我らがみのるんさんの記事をどうぞ。
Claude 3.7 sonnetでは、従来のClaude 3.5からのパワーアップに加えて、コーディングなどで性能が向上する「拡張思考モード」が登場しました。
素人だけど、これで個人開発ってやつをやってみたい
マークダウンすら怪しいほどコーディングができない私。
モノづくりができるエンジニアには常に憧れがあります。デザインだけだと「絵に描いた餅」ですが、リリースできたらユーザーが実際にhappyになるのだから。
そんな憧れに近づくべく、新型Claudeくんを壁打ち相手にして開発してみることにしました。
ちなみに、Claude 3.5 sonnetがリリースされた昨年6月にも挑戦したアプリ開発。
しかしこの時は、サンプルコードの生成まではうまくいったもののデプロイで苦戦。。結局は同僚のつよつよエンジニアに丸投げ 助っ人いただきました。
ということで今回は独力でリリースまでもっていくことを達成目標にしました!
作ったアプリ
地元 鶴見駅のターミナルに山ほどくるバスの発車時刻がぱっと見でわかるスマホ向けwebアプリを作りました。
このアプリを作ろうと思った背景
鶴見駅のターミナルにはとにかくバスが来ます。まじでたくさん来ます。
「珍百景」に登録されたほどです。
https://www.tv-asahi.co.jp/nanikore2017/contents_pre/collection/130814.html
そんな鶴見駅バスですが、乗車待ちの時に毎回悩むのです。
ユーザーの声
「そこそこ離れた4つある乗り場のうち、どこに一番早くバスが来るのかわからない」
「ここかな?と思って並んだ乗り場とは別の乗り場の方が早くバスが来た」
「停車してるバスに向かって歩いてたら乗り場に着く前に発車されちゃった」
もちろん、乗換案内アプリやgoogleマップでも発車時刻は調べられるのですが、イマイチどの路線がどの乗り場かわかりづらいし、そもそも調べるのが手間なのです。
そこで、以下のユーザー要求を実現するアプリを開発することに。
- バスの乗り場ごとに、それぞれ何分後に発車予定か一目でわかる
- スマホからワンタッチで上記が見れる
開発過程のご紹介
開発に使ったのはClaudeとGAS(Google App Script)だけです。あとは雑なスケッチをした紙。
Claudeに質問して、出てきたコードをGASにコピペして、わからないことをまたClaudeに聞いて...という感じです。
要件定義
いきなりClaudeにコードを生成するのではなく、要件定義を手伝ってもらうところから開始しました。
というのも、前回の挑戦時に全く知識のないReactに手を出したらハードルが高くて挫折したからです。
なるべくシンプルな構成になるようにお願いしました。
初手のプロンプト
バスの時刻表が直観的にわかるwebアプリを作りたい。
何をどう検討したらいいのか考えて。
## 今考えていること
* UI:スマホのブラウザで見る前提。手書きのワイヤフレームはあります。
* ユーザーが期待する機能:
* 現在時刻と曜日が見れる
* 現在時刻に対し、各路線のがそれぞれ何分後に発車予定かわかる
* ページを更新できる
* 時刻表データ:PDFもしくはcsvで用意可能
* 構成:
* なるべく簡単な構成にしたい。時刻表データをどう持たせたらいいのかわからない。
どうしたらいいか考えて。フロントエンドだけでもできる??
すると、実装方針を丁寧に提案してくれました。
おーええやん。
特に秘匿する情報もないし、フロントエンドで実装したら良さそう...!
GASはちょっと触ったことあるから抵抗感なくて嬉しい。
また、GASでhtml/css/jsをwebアプリとして公開する具体的手順や、実装ステップもセットで教えてくれたのでそれに従いました。
こんなにstep by stepで教えてくれると安心感が違いすぎる。
実現性検証
前段で決めた方針でとりあえず動くものを作ってみるべく、10秒で手書きしたワイヤーフレームとサンプルとする時刻表を渡してコードを生成してもらいました。
プロンプト
なぜかプロンプトが見えませんが、ワイヤーと時刻表を渡して「一式作ってね」と伝えました。
生成されたindex.htmlの抜粋
私の雑なユーザー要求を紐解いてロジックが出来上がっている...!!
なお、この時点では時刻表はJSONをハードコーディングする力技の実装でした。実現性検証なので。
実装エラーもClaudeに聞いてみる
とりあえずコードはできたものの、コピペで一発!とはいきませんでした。
出てきたエラーをClaudeに入力してデバッグ対応してもらいました。
なるほど。。
ヒントに沿って見直してみるとどうやら公開設定をミスっていたようでした。
その後も、画像IDの設定(コピペ)ミスなどを見つけてもらい、そういった細かい修正を重ねて...
動いたー!
デプロイし、手元のスマホでも動くようになりました!
この時点では4つある乗り場の中で2つだけ、乗り場案内も手書きですが、やりたいことができるとわかりました!
となるとあとは、実用できるように改良していくだけです...!!
本開発
実現性検証を経て、主に開発したのは下記4点です
- 時刻表追加:テスト用の2路線から、本番用に6路線へとデータ増加
- 時刻表の管理方法変更:計算ロジックにハードコーディングするやり方から、JSONファイルをgoogle driveに保存しておいて呼び出す形式に
- 乗り場画像の管理方法変更、本番画像へと差し替え:こちらもgoogle driveに保存しておいて呼び出す形式に
- その他、UIのブラッシュアップ
時刻表追加
公式サイトで配布されているPDF(おそらくexcel方眼紙でできている)をJSONに書き出す作業です。
アプリの信頼性に最も関わる部分のため手が抜けず、意外にもこれが一番大変でした。。
これもClaudeに依頼しました。
たまに始発を1時間間違えたりしていましたが9割以上は正確に書き起こしてくれました。素晴らしい。
時刻表の管理方法変更
だんだん馴れ馴れしくなっていく私。
そして毎回Claudeのコードは正確でした。僕がミスってた。
乗り場画像の修正も同じような感じで進めました
その他、UIなどの修正
イイカンジにしてくれるのでテンションが上がってました。
完成 & リリース!!
そんなこんなで、本記事の頭に載せた形になりアプリ完成!
自分と家族のスマホhome画面にwebアプリのURLをショートカットとして置き、スマホアプリライクに使えるようにしました。
ChromeとSafariで正常に動作したのでこれでリリースとしましょう。
リリースまでの所要時間は?
大体以下の通りでした。合計でざっくり4時間程度でしょうか。
- 構想、ユーザー要求定義:10分
- 要件定義(自身の理解含む):15分
- 実現性検証
- サンプルデータの準備:15分
- サンプルコード生成:5分
- 動くようになるまでtry & error:60分
- 本開発
- 時刻表データの準備:30分
- 機能追加、実装方法の変更:60分
- UIなどの調整:15分
- リリース作業:10分
感触としてはアプリ開発自体はコピペや対話で「すんなり」。
正確な時刻表データをJSONに書き出す作業が一番「めんどくさい」という感じでした。
おまけ:ユーザーテスト
リリース直後に実際にバスに乗る機会があったため家族でユーザーテストしました。
「えーめっちゃ便利!これ、近所のxxさんも欲しがるんじゃない? 他の人も使えるの??」
と、サクラのようなありがたい言葉が自然と得られました。
これはNPSが8点以上とれてるのではないでしょうか。
「NPS」とは「Net Promoter Score」の略で、顧客ロイヤルティ(商品やサービスに対する信頼・愛着)を測る指標。
「商品やサービスを親しい人にどの程度お薦めしますか」の質問から「0-10の11段階」で回答を取得し、値を算出します。
個人開発、さては楽しいな!?
感想
Claude 3.7 Sonnetの安心感
今回使ったClaude 3.7 Sonnetですが、3.5の時にも増して頼れる感じがしました。
特に コードの正確さ がすごい。
実装していて、自分のコピペミスや設定ミスで動かないときはあれど、コード自体がエラーを起こしたりロジックが崩れていたりすることはありませんでした。
また、何でも聞ける 感じが良かったです。
今回は要件定義から相談したりJSONデータを作ってもらったりしましたが、特にGASの使い方をstep by stepで正しく解説してくれるのは素人目線でとても助かりました。
結局、コードが生成できてもデプロイできないと意味ないんですよね。そこの橋渡しも含めて生成されるテキストの精度の高さを感じます。
自然とプログラミングが身に付く
慣れてくるにつれて、コード一式を生成してもらうよりもブロック単位で生成してもらって自分でマージする方が楽に感じてそうしていました。
また終盤は、カードのレイアウトやパディングなどの小さい修正をいちいち自然言語で伝えてコード生成を待つよりも、なんとなくコードを読み解いて書き換える方が楽に感じて自然と手直ししてました。
これってプログラミングが学習できてるということだなと思います。
生成AIをパートナーに据えることで 「具体的なユーザー課題(自分の課題)を解く」という目的ドリブンで前向きに学習できる 良い機会が生まれるのだなと思いました。
リファクタリングしたい気持ちがわかった
今回は極端すぎる例ですが、時刻表データをハードコーディングしていたらうざったすぎて別ファイル管理にしたくなったり、
そもそも計算ロジックをフロントエンドに仕込むのって性能的にどうなん?(今回の要求はミートしてるからいいけど将来的に..)って思ったり。。
色々とメンテしたい部分が出てきました。
リファクタリング/技術負債解消の時間を取ろう!とスクラムのworking agreementに入れてる理由が身をもって実感しました。
MVPを意識した開発
最後にアジャイル、サービスデザインっぽいことに触れてみます。
今回の開発では、(自分の力量の制約から)いかに最小限で、だけど信頼できて使えるプロダクトが作れるかを意識していました。
いわゆるMinimal Viable Product (MVP)です。下図の右側ですね。
(Minimum Viable Product (MVP) and Design - Balancing Risk to Gain Reward)
Functional
ユーザーの要求を満たすことだけにフォーカスしました。
そこで、以下のユーザー要求を実現するアプリを開発することに。
- バスの乗り場ごとに、それぞれ何分後に発車予定か一目でわかる
- スマホからワンタッチで上記が見れる
結果的には、webアプリ開発を超えて「スマホのhome画面にあるアイコンをタップするだけで待ち時間が表示される」ユーザー体験を実現しました。
Reliable
根幹となるバスの時刻表データについて、気が遠くなりそうでしたがしっかり全件チェック。また、残り時間表示の計算ロジックにも目を通して信頼できる結果が得られることを担保しました。
加えて、1sec未満ですが初回アクセス時に処理待ち時間が生じます。
これが正常動作に見えるように「読み込み中表示」を用意することをこだわりました。
Usable
細かい話ですが、発車5分以内のバス(=乗りたいバス)は強調表示するように使い勝手を工夫。
細かい説明用の情報は、想定ユーザーが自分の周りの人物のため極力省き、その代わりにユーザーテストで情報の不足がないか担保してみました。
Emotional designは今回スコープ外!
おわりに
今回は、初めてwebアプリ開発を独力で行い、リリースすることができました。
開発&課題解決の楽しさを味わうことができ、目標達成できて嬉しいです!
生成AIの進化とともにまたアプリ開発にチャレンジしていこうと思います。