現在、Claude週次制限の危機に陥っている。影響受けるのは5%未満って言ってたのに🥺
まぁProプランではあるのだけれど、別に夜中にバッチ処理しているわけでもなく、普通に開発しているだけなんだが、週次制限の危機になっている。これというのも、最近SDD(Spec-Driven Development, 仕様駆動開発)なるものを、見様見真似で始めたからだ。SDDというのは、まぁそのまんまなんだが、仕様をベースにしてLLMにコーディングさせる手法なのだけれど、まぁなかなかトークン消費量の激しいリッチな開発手法だと思った。
気分は完全にPM。頭はいいが物忘れと思い込みの激しい新人メンバを率いたPM。やっていて脳裏をよぎったのは「人日」という言葉だった。人じゃなかった。AIだった。AI日。AI日と書いてアイニチと読め。
つくったもの:SSDの健康情報モニタリングアプリ
「github/spec-kit: 💫 Toolkit to help you get started with Spec-Driven Development」を使って、見様見真似でやってみた。実はちゃんとドキュメント読まずに始めた😄
specifyとかplanとか一通りのコマンドを舐めた後、こんなん動かさないとわからんやろの精神でとにかくやってみた。やってみた記事。
やるだけやったものの、正直これはSDDと言っていいんだろうか、などと色々疑問に思いつつやっている。
今回作ったやつ
今回作ったのは、SDDの習作ということもあって、単純にSSDのS.M.A.R.T.を定期的に取得しブラウザで表示するだけのアプリだ。

動画はこれ。見たい人はどうぞ。
単純なアプリなのだが、けっこう苦労している(次節から詳述)。
前回ローコードアプリで作ったものとの比較
ちなみに以前ローコードの管理画面作成ツールである、Querierでも同様のものを作ったことがある。なぜ僕は手始めにSSDを監視したがるのか?

そのときの画面は以下。比べてみてどうだろう。


制作時間はローコードアプリのほうが圧倒的に早い。これは確か半日くらいで出来たはず。確かアーキテクチャ(というほどのもんでもないが)はこう。
特徴としては、3区画あることだ。これはインターネット上のサービスであるQuerierから、情報取得ための経由地点としてAWSを置いているから複雑になっている。PC側でサーバ立てていれば、AWSは不要になるのだが、当時は自宅にインターネット向けのクチを作っていなかったので、まぁこうなったんだろうね。
まぁ慣れているから半日で出来たけれど、慣れていないともうちょっとかかるだろう。
今回の開発風景
さて、なぜか先にローコードアプリ開発の話をしたわけだが、それは比較対象としてちょうどよかったからだ。
トークンも時間もめっちゃ使う:所要時間はだいたい3人日、ならぬ3AI日
まずプロトタイプに過ぎない本アプリだが、ここに至るまでだいたい3日かかっている。そんなに?という感じかもしれないが、これは「Claudeの5時間制限」という縛りプレイがあったからだ。これは別途記事にしたいが、正直開発しているときの感覚は完全にPMだった。頭はいいはずだが思い込みと物忘れの激しい愉快なメンバたちを率いる疲れたPMだった。
なので、Anthoropicに100ドル貢げば時間は短縮できただろうが、習作作るために100ドル投資なんて意味不明なので、5時間制限を受け入れてやる。ってかそれくらいがちょうどいい。実際、仕様について考える時間やドキュメントを整備する時間もあるし……ってかこれにばかりつきっきりになっていても仕方が無い。
それにしても、$20/月のうち3日分もってかれたわけだから、このアプリ作るのに2ドルかかっているとも言えるなぁ。300円で売っていても多分買わないアプリではある。
っていうか週次制限の危機に陥っててめっちゃビビってる。影響受けるの5%未満じゃなかったの🥺

まぁProプランにおいては5%未満の使い方、ということになるらしい。。。
コード量は無駄に増える
クソショボアプリであるにも関わらず、実はモノレポになっている。ルートにあるディレクトリとか必要ファイルはこんな感じ。
.
├── CLAUDE.md
├── Makefile
├── bin
├── chart-transformer/
├── config.json
├── config.json.template
├── data/
├── data-reader/
├── graph-server/
├── graph-server-daemon/
├── save-smart-info/
├── schedule-daemon/
├── smartctl-to-csv/
├── specs/
└── specs-draft/
ルートのMakefileは子プロジェクト群のMakefileのラッパーになっている。一括ビルド・インストール・アンインストール・クリーンとかいつものやつを全部実行する。
なんでこんなに、って感じではある。ちなみに specsがLLMが使うやつだが、specifyするたびに連番が増えるのだけれど、今回10までいった。つまり少なくとも10回はimplementしてるわけだね。
アーキテクチャ
なんでたったこれだけのアプリでこんなことになるかと言うと、細かく分解したからだ。
7つのコンポーネントに分かれている。
- config読み込み、データ取得のスケジュール登録デーモン(OS差分の吸収)
- smart情報をcsvに変換する
- 変換したcsvをファイルに保存する
- 保存したcsvを読み込んでGo言語構造体に変換するパッケージ
- Go言語構造体からChart.jsで表示するようにデータ操作・フォーマット変換するパッケージ
- フロントエンド(Go + htmx)
- config読み込み、Webアプリを登録するデーモン(OS差分の吸収)
正直これでいいのかどうかはよくわからない。しかしこうなった。
なぜこうなったかというと、最初は一つの仕様書で作らせようとしたのだが、うまくグラフが表示されず、その原因特定が難しかったからだ。トークンも激しく消費した。……まぁ実際のところは、動作不良の原因についてだいたい察しがついていたので、修正できたと思うんだけれど、これは習作なので、今後のことを考えると、「原因特定できる状態にすること」を再現する必要があると思われた。
で、考えた結果がこのモノレポ構成である。サービスについて、入出力をベースにして責務ごとにコンポーネントを作成し、繋げるようにした感じだ。考え方としては、UNIX的なパイプライン処理だね。
このようにスコープを切り分けることで、以下の効果を期待している。
- トークンの消費量を抑える
- LLMの不確実性を抑える
- 仕様変更時の影響範囲を最小化する
- 人間が動作確認できる、原因を特定できる
直前のコンポーネントまでの動作を常に保証することによって、1つのコンポーネントが動作しなかった場合、明確にそのコンポーネントが悪い、と言えるわけだ。たとえばChart.js用に変換するパッケージでは、デモ用のhtmlを用意し、サンプルデータを表示できる形になっているか、など確認している
所感
人日……AI日が計算できる、つまり時間とコストがわかる
この開発をしてちょっと思ったのは、「これ、時間とコストが見積もれるな」ということだった。
だいたいコンポーネント1つあたりで、5時間制限1.2回分といったところで、これは共通していた。1.2*7=8.4回。これに手戻りとかのオーバーヘッドがだいたい3回分くらいあって、全体で5時間制限12回分、1日4回の5時間制限があってそれを1人日、いや1AI日とするなら、3AI日、である。
そして1AI日100円なので300円くらいかかった、とも言える。
アプリを見るとバカバカしいと感じるかもしれないのだが、今回は学習目的があったためなので、この程度ならば、慣れていてかつ割切った開発をするならかなり短縮できると思う。ただやるだけなら、何も7つにまで分けるこたぁなかろう。
それより重要なことは、見積ができるのではないか、ということ。最初の設計で大まかにコンポーネントを適切に分割できれば、そこからざっくりと必要なAIのリソースが判断できると思われた。
モノレポでいいのかはわからん
正直この開発手法、コンポーネント細かく分割するしかないんと違うかと思ったんだけれど、どうなんだろう。モノがでかいとなんぼイテレートしてもうまくいく気がせん。
しかし、この程度のアプリでこんだけ分割となると、ちょっと大きなアプリになったら凄まじいことになりそうな気もした。いやまぁ、今回は意図的に細かく分割した面はあるんだけれど、しかし実際のところ相当のコンポーネントになってしまいそうな。うーん。どうしたもんかな。
とりあえずGitHubにある理念的なところはけっこう無視してるような感じは正直する。技術的要素は/planだっていうけど、Go言語構造体を作るのが目的のコンポーネントのspecは、もうwhatが技術なんやわ。ってことは、理念的には分割の仕方自体がSDDから外れているのか?とも思うんだけど、現実的に不可分に思える。
まぁ自分的には今回このような形になったのだが、正直なんもわからんまま考えて作った感じだし、粒度についてはもうちょっと色々考えたい。手法自体が新しいので、確立している何かがあるとも思えないし、今回は最初ということで、この手探り姿勢でよかったとは思ってはいるものの、今後どうしよう。他の人がどうしているのかとかは、これはちょくちょくと調べていきたい。
ここに書いてないトラブル多発
書き始めるとそれぞれ記事になりそうだから書いてないんだが、色々トラブった。せっかく作ったパッケージ使わないで独自実装始めるとか、ビルドの統一感がないとか、仕様書駆動開発なのに仕様書に定義したことをやらないとか、仕様の微妙なところで解釈違いとか、勝手に実装を続けて暴走するとか、/specifyからやるすべきか口頭で変更すべきか毎度悩ましいとか、まぁ色々。っていうか、モノレポになったこと自体が、トラブったからだし。
まぁこの構成のせいで、特に繋ぎ込みのところは相当考えさせられたし、実際厄介だった。このへんは別途記事にしていきたい。
当たり前だがローコードより自由だし堅牢
さて、ここまでだとQuerierとかローコードでいんじゃねという結論になりそうなんだが、やはり圧倒的に自由、ということはあげたい。グラフ操作も表示も処理も好きにできる。たとえばQuerierって、時系列データでも問答無用で等間隔とかいう制約があったりしたんだよね(今はどうか知らない)。ローコードって、やってから判明する意外な制約、みたいなのがあって怖いんだけれど、その心配が無い。
何よりローカルで完結するのは素晴らしい。インターネットにデータをあげる必要がない。まぁやりたければインターネット公開も別にできる。
これはネットワークレベルから制御できるということなので、認証とかほしくなったとしても、アプリケーションレベルのたいへんな仕組みを入れなくてもいい。適材適所。
また、責務ごとにコンポーネントを分割することで、今後の変更や、障害対応(このアプリでは考えづらいが)もやりやすいだろう。
まぁ、アプリが明確ならローコードアプリは実際選択肢には入ると思うんだけど、現実的にローコードがぴったりくるには、「運用にめっちゃ寄り添う開発と、めっちゃやる気のある運用」が必要で、それが一番難しいのではないかと……。
アーキテクチャを考えさせられた
今回の試みについては、SDDなるものをやってみた、というより、SDDでうまくいきそうなアーキテクチャをなんとかかんとか考えた、というのが本質的だったかもしれない。正直SDDかといわれると自信はないんだけど、でもAI日みたいなんで見積取れるなぁというのは、個人的には大きな発見だった。
とりあえず機能拡張はもうちょっとやろうかどうしようか。たとえばデータ点数が増えるとちょっと重くなるかもしれないので、Chart.js用に変換するプログラムに改修入れて、データを間引いたり平滑化したりするか、あるいはデシメーションの機能使うか。
自分的にはやりたいことは既にできているので、このままでもいい。あ、Linuxでの動作確認がまだか。どうせだから公開しようと思ったら、もうちょっと汎用的にしようと頑張るかも、くらい。せっかくだしパッケージ化も頑張ってみる?🤔
いずれにせよ、SDD自体は非常にリッチな開発だなぁと思いつつも、一定の保守性と見積が得られるし、入出力パイプライン処理で構築するシステムと相性がよさそうなところで、個人的にちょっとしっくりくる面があったので、これから深掘っていきたい。お金がかかるよ!やったねたえちゃん……。
とりあえずこの動画は見る。
参考書籍


コメント