💯

自作コーディングエージェントで100日チャレンジ完走した感想

に公開2

はじめに

実はShaftというCLI型コーディングエージェントを作りはじめた7月27日頃から、毎日アプリを作っていました。

https://gitlab.com/tkithrta/shaft

惰性で続けていましたが、どうやら最近100日達成していたみたいなので、完走した感想を書いていきたいと思います。

100日チャレンジとは

https://bookplus.nikkei.com/atcl/catalog/24/12/05/01757/

大塚あみさんが執筆された「#100日チャレンジ 毎日連続100本アプリを作ったら人生が変わった」にインスパイアされて毎日連続100本アプリを作るやつです。

100日チャレンジ自体はイラストや漫画で結構メジャーらしく、100日後に死ぬワニなんかも100日チャレンジの一種としてみてよさそうです。

ただ100日チャレンジを100本のアプリ開発でやるとなるとものすごく大変なわけですから、生成AIやコーディングエージェントによってようやくできる環境が整ってきた感じです。

ChatGPTや有名なコーディングエージェント(CursorやClineなど)でチャレンジしても二番煎じにしかなりませんが、私には自作コーディングエージェントという唯一無二のものがありますし、何より自作コーディングエージェントのドッグフーディングにもなるので試しにやってみた次第です。

https://blog.framinal.life/entry/2025/06/12/143349

https://cline-100-days-challenge.netlify.app/

https://note.com/hashtag/AI100日チャレンジ

やり方

Shaftをインストール(uvのローカルインストール)して対象ファイル、コンテキストファイルをもとにプロンプトを書いていくだけです。

https://gitlab.com/tkithrta/shaft/-/blob/main/src/shaft/docs/ja/getting_started.md

モデルは7割Gemini 2.5 Flash、2割Gemini 2.5 Pro(APIエラーが頻発したのでGemini 2.5 Flashに移行)、1割OpenRouterのステルスモデル(当時のSonoma Dusk Alpha, Sonoma Sky Alphaなど)を使いました。すべて無料APIです。
ちなみにペルソナはほぼ全てProgrammerです。

はじめた当初は普通にテキストファイルで書いたプロンプトをstdinで直接渡していましたが、面倒になってきたので色々スクリプトを書いてプロンプトを渡しやすくするようにしました。
現在のShaftではこれらのスクリプトも公開しています(「Shaft: はじめに」の「スクリプトの例」参照)

現在はTkinter GUIアプリの通知音をあみたろさんの音素材にカスタマイズしたものを使っています。

https://amitaro.net/

一番つらかったこと

何といってもアプリのネタがなくなることです。

ShaftとGeminiの組み合わせが優れているのか分かりませんが、変な実装をして時間がかかったり、アイデアを実現できず諦めたケースはあまりありませんでした。

ただ1日でAffinityのようなアプリを作るのはどう考えても無理ですから、少ないコードで実現可能、かつ実用的なアプリを開発しなければなりません。

例えば複利や単利のような利息計算をするアプリを作るのであれば、ドメイン知識が必要になりますし、調べる時間がかかってしまったり、誤った計算式のアプリを作ってメンテされず放置されてしまう懸念もあります。

とにかく毎日アイデアを考えるのがものすごく大変でした。

アイデアのつくり方

"An idea is nothing more nor less than a new combination of old elements."
— James Webb Young, A Technique for Producing Ideas (1940)

「アイデアとは、既存の要素の新しい組み合わせ以外の何ものでもない。」
— ジェームズ・ウェッブ・ヤング『アイデアのつくり方』(1940年)

さて、少ないコードで実現可能、かつ実用的なアプリのアイデアはどのように考えればいいのでしょうか?

ここでは、ツールやゲームなどのアプリの種類、設定方法、扱うデータの種類などをざっくりまとめて紹介します。
どう紹介したらいいか困りましたが、難しい話は抜きにして、ざっくりと全体を見渡す感じで読んでください。

ツール

特定の作業や目的を効率よくこなすためのプログラムです。
ユーザーや他のプログラムを手助けするような補助的な役割を持っています。

たとえば、テキストを整形したり、ファイルをまとめて処理したりするような小さなプログラムもツールの一種です。

ゲーム

楽しさや挑戦を目的に作られた、インタラクティブなプログラムです。
ルールや報酬を通して、プレイヤーに体験を提供するのが特徴です。

いわゆる「遊べるアプリ」ですね。単純なミニゲームでも、立派なゲームアプリです。

CLIアプリ

コマンドライン上で動くアプリケーションです。
テキストだけで操作できるので、スクリプト化や自動処理にも向いています。

プログラミング言語やOSに依存しにくく、どこでも動かせるのが魅力です。
少ない構成で試せるので、100日チャレンジの題材にもぴったりです。

GUIアプリ

いわゆる「ウィンドウ付き」のアプリです。
ボタンやメニューを使って、直感的に操作できるのが魅力ですね。

PythonならTkinterやPygameで簡単に作れ、見た目も自由に調整できます。
ただし、JavaScriptやGoでは依存関係が増えやすい点に注意が必要です。

Webアプリ

ブラウザで動作するアプリケーションです。
サーバーと通信して、ページの内容を動的に変えられるのが特徴です。

JavaScriptを使う場面が多いですが、FlaskやHonoなどの軽量フレームワークも便利です。
サーバーを動かせば他の端末からも利用でき、応用の幅がとても広いです。

コマンドラインオプション

アプリの動作を切り替えるための設定引数です。
-h--helpのように、ハイフンから始まる形で指定します。

プログラムの挙動を簡単に変更できる便利な仕組みです。

環境変数

システムやアプリの設定を外部に持たせるための仕組みです。
実行時に挙動を簡単に切り替えたいときに便利です。

.envファイルなどで設定しておくと、コードを書き換えずに挙動を変えられます。

設定ファイル

アプリの設定内容をまとめて記述しておくファイルです。
JSONやYAMLなど、扱いやすいフォーマットがよく使われます。

複雑なアプリでは、設定ファイルで細かく挙動をコントロールします。

標準ライブラリ

プログラミング言語に最初から用意されているライブラリです。
ファイル操作やデータ処理など、基本的な機能がひと通り揃っています。

最初のうちは、この標準ライブラリをうまく使いこなすだけでも十分強力です。

依存関係なし

標準ライブラリを使ってたくさん書かないといけない処理は、外部ライブラリをまったく使わずに動作するパッケージを使います。

zero dependenciesやno dependenciesとも呼ばれ、単体で動かせるのがメリットです。
軽量で移植しやすい反面、機能追加には少し制約があります。

最小限の依存関係

Webアプリケーションフレームワーク、CLIフレームワーク、ゲームエンジンを使うときは、必要な外部ライブラリだけに依存したパッケージを使います。

few dependenciesやminimal dependenciesとも呼ばれます。
軽さと拡張性のバランスをとりたいときに向いています。

テキスト

文字だけで構成されたデータです。
人が読める形なので、編集や比較がしやすいのが強みです。

TXTやCSVなどが代表的な形式ですね。

バイナリ

機械が直接扱う2進数のデータです。
人間には読めませんが、処理が速くて容量もコンパクトです。

アプリが扱う画像や動画、実行ファイルなどはほとんどバイナリ形式です。

画像

見た目の情報をピクセル単位で表現したデータです。
JPEGやPNGなど、用途に応じて形式がいろいろあります。

ツール開発では、画像の圧縮・変換・解析などを行うケースも多いです。

PDF

レイアウト込みで文書を保存できるファイル形式です。
テキストや画像をまとめて一枚の紙のように扱えるのが便利です。

レポート出力や帳票作成など、業務系アプリでもよく使われます。

アーカイブ

複数のファイルをひとつにまとめるための形式です。
ZIPやTARのように、圧縮して容量を減らせるものも多いです。

ファイルのバックアップや転送に欠かせない形式ですね。

ハッシュ関数

データから一定の長さの値を作り出す関数です。
データの一致確認やセキュリティ用途によく使われます。

たとえばファイルの整合性チェックに利用されます。

その他気をつけたこと

どのファイルのどのブロックのどの行を編集するか、コーディングエージェントが理解しやすくするのはとても重要です。
コードレビューのベストプラクティス[1]によると、400行未満のコードをレビューするのがよいらしいので、以下のような分類を行いアプリのコード量に問題がないか確認するようにしています。

  • tiny: 5行以上、20行未満
  • small: 20行以上、100行未満
  • medium: 100行以上、400行未満
  • large: 400行以上、2000行未満
  • gigantic: 2000行以上、8000行未満

Shaft自体もそうなのですが、LargeやGiganticに該当するアプリでコーディングエージェントを試した結果、特定のデザインパターンを使用するとクラスなどを使い分割統治してくれるのでよかったです。

  • tool: Facade, Adapter, Builder
  • game: Strategy, State, Decorator

あるいは、ゲームのメッセージをTXTファイルで生成、データをJSONファイルで生成してもらうような拡張子ごとの分割統治も有効でした。

ここらへんはモデルやシステムプロンプトによって変わってくるので一概には言えないかもしれませんが、参考程度に紹介しました。

おわりに

こうして見ていくと、アプリを構成する要素って意外とシンプルです。
「どんな目的で」「どんな形で」「どんなデータを扱うか」を意識するだけで、
少ないコードでも実用的なアプリを作るアイデアがどんどん浮かんできます。

100本のアプリを作るためには、難しく考えすぎず、まずは小さなCLIツールから試してみるのがおすすめです。

たださすがにPC用のアプリばかり作って飽きてきたので、そろそろAndroidアプリにでも挑戦したいですね。

脚注
  1. https://smartbear.com/learn/code-review/best-practices-for-peer-code-review/ ↩︎

Discussion

rakiraki

流し読みしかしてないけども。

とにかく毎日アイデアを考えるのがものすごく大変でした。

アイデアを出すこと自体生成AIに任せて省力化すべきところだし、記事に書いているような条件やカテゴリを指示すれば、それぞれ10個ずつ出させればいい気がする。。。

どちらかと言えばそうやって出力されたアイデアから取捨選択して取り上げた理由や逆に作らなかった理由を書くほうが記事としては面白いのかなって。

黒ヰ樹黒ヰ樹

アイデアのネタがなくなった時にChatGPTやGoogle AI Studioに質問することはありましたが、少ないコードで実現可能、かつ実用的なアプリではなかったので、やらなかったというところに集約されます。

先程試しに100個ほどアイデアを生成してみました。

https://zenn.dev/tkithrta/scraps/f813df9120e88e

すでに作成済み、あるいはランタイムにCLIツールとして既に存在していることが多いです(Pythonのuuidやzipfileなど)
このような現象は50個を超えたあたりから顕著に現れました。
試しに既に作成したアプリのタイトルや概要を追加してリストに含めないように指示しても、なぜか含まれてしまいました。

100日チャレンジ本含め記事で紹介しているような様々な人の100日チャレンジを見ていると、完走できていない、日をまたいでいる、コードの内容を理解できていないみたいなことをが散見されていたので、難しく考えすぎず、まずは自分のレベルで理解可能なCLIツールから試してみれば完走できることを紹介したく今回記事を書きました。

完走できていない、日をまたいでいる、コードの内容を理解できていないといった根本原因を書かなかったのは、単に先駆者に失礼だと思ったからです。