- 約5年前からEngineering Managerの役割を担うようになり、本業で直接コードを書く機会は減った
- 業務外でも個人プロジェクトを継続的に進め、プログラミングの感覚を保ちつつ技術力を磨いてきた
- 以前は時間の制約でプロジェクトの進行が遅く、完成前に中断してしまうことが多かった
- しかし2024年には、必要なツールを比較的速いペースで作って公開し、最初のバージョンを「完成」させる習慣が身についた
最近完成させたサイドプロジェクトの例
- jsonplayground.com : JSONフォーマッターであり、ブラウザ内で実行されるJQ機能(WebAssemblyを活用)を提供するため、データを外部に送信しない
- webtomarkdown.com : ファイルをMarkdownに変換したり、Webサイトの一部をMarkdown形式で抽出してLLMにコンテキストとして渡せるようにした
- 航空クラブのページ Evergreen Soaring のデザイン改善案
- Chrome拡張機能を作成し、航空クラブに届くメッセージ対応を自動化した
- fitinterval.com : 運動時のインターバルタイマー機能を提供する
LLMとCursor IDE活用の背景
- LLMがサイドプロジェクトの生産性を大きく高めてくれる
- 特に Cursor IDE を通じて、LLMをコーディング作業に活用する過程が便利だった
- この記事では、新しいプロジェクトを作る全体的な流れを共有し、読者が実際に応用できるようにしたい
- LLMがあらゆる領域で有用というわけではないため、自分で使ってみてどこに適用するか選ぶ必要がある
例示プロジェクト: 習慣トラッキングWebサイト
- 現在使っている習慣トラッキングアプリをWebサイトの形で再現したいと考えた
- すべてのデータはローカル端末に保存され、ユーザーのプライバシーに配慮している
仕様検討の開始
- まずChatGPTに簡単な説明をしたあと、追加の質問を受けながらアプリケーションの仕様を具体化した
- ある程度具体化できたら、「他の人がこの仕様だけを見てアプリ全体を作れる程度」に整理してほしいと依頼した
- TypeScript、React、Tailwind CSSを使う意図を明示し、それらの技術を前提にした仕様を作成した
- 最終仕様は
SPEC.md に保存し、その後の開発工程で参照した
プロジェクトのブートストラップ
- Vite を使ってプロジェクトの骨格を素早く用意した
npm create vite@latest . コマンドで初期設定を行い、SPEC.md をプロジェクトフォルダに置いておいた
- Cursor IDEのComposerでエージェント機能を使い、Tailwindの設定や基本ファイルの修正などを自動化した
- こうすることで、想定するUXレイアウト、localStorageの利用、Markdownエクスポート機能などの初期機能を短時間で実装できた
小さな単位で反復作業
- 一度に多くの機能を要求するより、必要な改善点を分けてLLMに順次アップデートを依頼した
- たとえばUX変更やバグ修正などを小さく分け、ChatまたはComposerモードで指示した
- 画像をChatに添付して望むデザインを説明し、それをコードとして実装するようLLMに依頼した
継続的デプロイの設定
- GitHub Actionsを参考に、mainブランチへコミットが上がると自動ビルド後にGitHub Pagesへデプロイされるよう設定した
- Cursorで別リポジトリの
.yml ファイル例をリンクで渡し、LLMがそれを参照するようにしてデプロイパイプラインを構成した
総合的なヒント
- LLMでプロジェクトの概要や詳細を先に整理し、後で使うコンテキストとして保存しておく
- ツールやオープンソースのテンプレートを使って、プロジェクトのブートストラップと構造設定を行う
- 必須の開発ツールとディレクトリ構造をまとめて用意し、管理しやすいプロジェクトパターンに従う
- Cursor Composer(エージェントモード)などを使ってプロジェクトを素早く開始する
- Claude-3.5-Sonnet と o1(モデル)を組み合わせて使う
- 広範な下書き作業(初回ドラフト)にはo1を活用
- およそ80%はClaude-3.5-Sonnetで具体的な修正・補強作業を進めた
- 適切なモードを選ぶ(Chat、Composer通常、Composerエージェント)
- Chat: 具体的な位置に変更が必要で、修正結果を毎回確認したいときに使う
- Composer(通常): 複数ファイルにまたがる機能追加やマルチファイルの変更が必要な場合
- Composer(エージェント): まだあまり使っていないが、コマンド実行、lint、反復修正などの自動化作業が必要なときに使う(ただし、小さな単位に分けて管理するほうがよい)
- コンテキストを与える際は、具体的なファイル・文書・リンクなども一緒に渡す
- 必要に応じてChatモードでコードベース全体を参照できるように設定し、LLMがコンテキストに合ったコードを検索して提案できるようにする
- プロジェクト関連文書をMarkdown形式(SPEC.md など)で保存しておき、コンテキストとして含められるようにする
- プロジェクトフォルダで
.cursorrules ファイルを活用する
- 特定のライブラリを使わないよう指示したり、Tailwindやshadcnコンポーネントライブラリの使用を強制したりできる
- このようにpromptsに反映したいルールをあらかじめ定義しておくと、ほとんどの依頼で望む方向に結果を導きやすい
- コード全体を理解しながら作業する
- LLMがデバッグできない状況が起きないよう、コード品質と構造を維持する
- 作業を引き続き小さな単位に分け、必要に応じてLLMを活用してリファクタリングやモジュール分割を進める
まとめ
- このようなやり方でプロジェクトを素早く仕上げてデプロイ版を作っておけば、少し休んでも再開がずっと容易になる
- 小さく完成させる習慣が推進力を維持してくれ、小さな成果を素早く確認しながらモチベーションを得られる
3件のコメント
有益な情報をありがとうございます!
みんな試みている様子が似たり寄ったりですね。
最近、上記の内容と似た方法でCursorとLLMを使って小さなプロジェクトを作ってみたのですが、非常に生産性が高かったです。
LLMでSPECやPRDを作成してCursorにコンテキストとして含め、
cursorrulesで使用する技術に関するルールを定めてから、Composerを通じてタスクを一つずつ指示すると、一貫性のあるコードがうまく出力されました。