概要
Devin・Cursor・WindsurfといったAIエージェントを用いて開発を進める中で、ツールごとの特性や得意・不得意、そして運用の工夫によって体験が大きく変わることを実感しました。本記事では、各エージェントの使用体験と課題、それに対する実践的な対処法を紹介しながら、効率的で現実的なAI駆動開発の進め方を考察します。
目次
- 概要
- 目次
- 目的
- 対象読者
- PR
- 本文
- 自律的に動くAIエージェントとの開発体験
- CursorとWindsurfで試したこと、起きたこと
- 失敗から生まれたRules整備と学び
- Rulesの適用に関して感じたこと
- DevinによるAI駆動開発
- AIエージェントの記憶喪失に備えるベストプラクティス
- コードベースの整備があっても見落とされる現象
- うまくいった対処法と考察
- AIに文脈を届けるためのドキュメント運用戦略
- 人間が効率的に介入する開発構成のすすめ
- DRY原則の観点
- AIとどう付き合っていくか
- 参考リンク
- PR
目的
AIエージェントを用いた開発体験から得られた知見を共有し、効率的かつ現実的なAI活用の方法論を明らかにすること。特に、開発コスト・エラー対応・作業分担における工夫について提案します。
対象読者
- リードエンジニア
- 現場でAI支援開発を検討・導入している開発者
PR
UZUMAKIではアジャイル開発で新規事業の開発から、大規模Webアプリケーションのアーキテクチャ更新などの開発をしています。
お問い合わせはUZUMAKIのHPのお問合せフォームから
本文
自律的に動くAIエージェントとの開発体験
GitHub Copilotや一般的な補完型ツールと異なり、Devinや、Cursor・WindsurfのAgent機能/Write機能などは、タスクを自律的にこなすことを目指しています(注:GitHub Copilotでもエージェントモードが最近発表されました)。本稿ではRailsベースのSNS型Webアプリを題材に検証を行いました。以下では、それぞれを使ってみた中で印象的だった点を整理します。
CursorとWindsurfで試したこと、起きたこと
私はCursorから使い始めました。CursorではClaudeやGemini、GPTなどのサードパーティモデルを使用することができます。また、Rulesという、AIエージェントが開発する際の規則を設定することができます。最初は特別な設定を追加せずにプレーンな状態で使ったので、AIエージェントとのやり取りに慣れることができました。プロンプトの出し方、出力の受け取り方、話しかけ方など、基本的な付き合い方を学ぶ上で適しており、Rules設定の重要性に気づくことができました。
ただし、Cursorには課題もありました。
- コード全体に対する過剰な修正
- セッションの焦点ぼやけ問題
目的の変更だけでなく、関係ない箇所まで書き換えられることがあり、意図しない差分が多発しました。これは、コード全体を常に最適化しようとする傾向が強いためだと感じています。
会話が長引くと、話題が本筋から逸れてしまい、指示が曖昧になる場面が増えました。特に複数ステップにわたるタスクでは、初期の目的が忘れられがちです。
Windsurfに移ってからは、そうした余計な修正が少なく、応答の軽快さや安定性が非常に快適でした。Windsurfでは、Cursorでも使用したサードパーティモデルの他に、専用のモデルを使用することも可能で、私は専用のモデルを使っていました。そのためか、Cursorよりも指示の意図を正確に汲んでくれる場面が多く、期待通りの出力が得られやすかったです。
ただし、Windsurfにも特有の課題があります。たとえば、提示してきた解決策を自ら実行せず、「あなたがやって」と明示的に促さないと動かないケースがありました。提案と実行が自然につながることを期待していた分、そのギャップに少し戸惑うこともありました。それでも、個人的な感触として、Cursorよりも実務的に安心して使える印象です。
WindsurfもCursorと同様に、長い対話の中で本題を見失う傾向はありました。途中でマイルストーンから逸れて、違う話を始めてしまうということも珍しくありません。
この点でDevinは一歩先を行っており、明示的に目的を伝えておくことで、それを保持したまま実装と記録を進めてくれる体験はとても良好でした。
失敗から生まれたRules整備と学び
また、CursorやWindsurfでは、git操作やPR作成といったタスクに対して不安定な挙動を見せることもありました。たとえば、PRのタイトルが曖昧だったり、意図と違うブランチを選んでしまうことも。
こうしたミスに対応する中で、私はRulesを整備するようになりました。 具体的には、まず、開発ブログなどで公開されているRulesをベースにして開発を行います。AIが失敗したときにその原因を振り返り、ChatGPTに相談して指示例やプロンプトのテンプレートを練り直し、共通ルールとしてまとめておくという流れです。
- AIが失敗する
- → 私が失敗の原因を分析
- → ChatGPTに修正文案やルール案を相談
- → Rulesに追記
- → AIが同じ失敗をしなくなる
という改善サイクルを繰り返すことで、AIとのやりとりが次第にスムーズになっていきました。
Rulesの適用に関して感じたこと
CursorやWindsurfを使用する中で、あらかじめ設定したRulesの適用について、以下のような傾向が見られました。
- Cursorでは、設定したRulesが比較的忠実に適用される印象がありました。
- Windsurfでは、Rulesが適用されないケースがCursorに比べて多かったように感じました。
- また、両者に共通していたのは、「Aを行ったら必ずBを行う」や「Cの状態になったら必ずDを行う」といった複雑なルールは反映されにくい点です。
たとえば、commitメッセージの形式やPRの作成ルールなど、事前に設定しておいたルールに従った出力が多く、修正の手間が少なく済みました。
たとえば、「コミットする前に、現在のブランチ名がルールに沿っているかを確認する」といったルールは、Windsurfでは反映されず、そのままコミットが実行されることがありました。
たとえば、「1PRあたりの差分は10ファイル以内に抑える」といったルールは、無視されるケースがありました。これは、CursorやWindsurfのRulesの役割として想定されているのが「常に適用されるような単純なルール」であって、ワークフロー的に手順を示したり、状態を見て動作を分岐する目的で適用されることは想定されていないためと考えられます。WindsurfならWorkflow機能があるようなので、こちらを試してみるとうまくいった可能性があります。
このように、あらかじめ設定したRulesだけでは思うように機能しない場面もあり、ツールごとの仕組みに合わせて人がうまく補完しながら使う工夫が求められると感じています。
DevinによるAI駆動開発
- Devinの良かったところ
Felix Pappe Design First, Code Later: The AI Era Mantra
Adron Composite Thrashing Code Adron's success in misadventures of thrashing coding and calamity! Writing Swift Like a Pro: Clean Code, Separation of Concerns, and AI-Assisted Development
- タスク駆動型で、対話形式で設計・実装・修正が進む
- 一定レベルのプロジェクト構造を持ったコードベースならスムーズに動ける
- ロジックが複雑になってくると、自動的にServiceクラスを作って分離しようとする工夫が見られた
- 最初のプロンプトで「対象はマイルストーンの○○だよ」と明示すると、最後まで意図を保持し、DEVELOPMENT_JOURNAL を更新しながら進めてくれた
- Devinで困ったところ
- クレジット消費が大きい($40を6時間ほどで使い切った)
- 小さな修正や微調整は手動のほうが速いことが多い
- テストや動作確認を自動で行わず、明示的に指示する必要がある
- 依存関係の不整合など、上位環境でのエラーには対処しきれない
- git stash を使って差分を退避しつつ調査するような柔軟な動きはできない
Railsにおける典型的なアンチパターンの一つに「Fat View/Controller」があります。AI駆動型開発では、AIエージェントが初心者と同様の構造上の誤りを犯しやすく、結果としてViewやControllerの肥大化を招くのではないか──そんな声も一部では見られます(※ただし、明確な根拠や事例は確認できていません)。
しかし、Devinで基本的なSNS型Webアプリの開発を進める限り、その傾向は見られませんでした。Serviceクラスが適切に定義され、Viewクラスの条件分岐もそれほど深くならず、Controllerもスッキリと保たれていました。
AIエージェントの記憶喪失に備えるベストプラクティス
AIエージェントを使って開発を行う中で、セッションをまたぐと記憶がリセットされてしまうこと(いわゆるコンテキスト・リセット問題)が共通の課題として存在します。この件をCursorに相談したところ、以下の対策を講じてくれました:
- セッションごとに目的を再確認する仕組みを用意
- コードベースに docs フォルダを作成し、ADR や DEVELOPMENT_JOURNAL、milestones を整備することで、AIエージェントとコンテキスト共有しやすいプロジェクト構成を構築
- 作業の経過や判断をエージェントに記録させ、次回以降の参照を可能に
これにより、どのエージェントであっても文脈を取り戻すための資料が整っていれば、記憶喪失の影響を最小限に抑えることができるようになりました。この取り組みをさらに拡張する方法として、以下のような工夫もあります。 最近ではMCP(Model Context Protocol)の登場により、エージェントが外部情報にアクセスしやすくなっており、Notionやesaといった外部ドキュメントを読み込む構成も現実的になってきました。これにより、コードベースだけでなく、プロジェクト外部に蓄積された知識も参照可能となり、より柔軟な文脈共有が可能になります。
コードベースの整備があっても見落とされる現象
実際に、私は docs/development/milestones/*
以下にマイルストーンドキュメントを整備し、AIエージェントに「docs 以下を全部読んで」と指示することで文脈を補おうと試みました。しかし現場では、フォルダ階層が少しでも深くなると、それだけで無視されることが多いという問題に直面しました。
たとえば、docs/milestones.md
のようなトップレベルのドキュメントは比較的読まれましたが、docs/development/milestones/ENV-001.md
のようなファイルは読み飛ばされるケースが頻発。AIが「深い階層にあるドキュメントの読み込みを積極的に行わない」か、あるいは「パス指定のない包括的な指示をうまく処理できない」といった仕様上の限界が背景にあると考えています。
このような状況では、「整備すれば参照してくれるはず」という前提が崩れるため、次のような対処が効果的でした。
うまくいった対処法と考察
- 重要ドキュメントはトップレベルにハードリンク/転記する
- 明示的にファイルパスを列挙して渡す
- プロジェクト全体の目次的ドキュメントを作成する
- 読み込むべき資料をセッション開始時に一覧で提示
docs/milestones/summary.md
など、階層の深いドキュメントの内容を、docs/README.md
や DEVELOPMENT_JOURNAL.md
に要約しておくと、参照されやすくなりました。
「docs/development/milestones/ENV-001.md
を読んで」と具体的に指定することで、読み飛ばしが減りました。特にWindsurfやCursorでは、暗黙的なパス解釈に限界があるため、明示的に渡すことが有効です。
docs/index.md
や docs/_toc.md
のような案内役となるファイルを作っておくと、そこに書かれているリンクを優先して読む傾向が観察されました。AIにとって、リンクを追いやすい構造のほうが認識されやすいのかもしれません。
セッションごとに、今回の開発で参照すべき資料を一覧で提示しておくと、記憶喪失後の文脈復元がうまくいくケースが増えました。
AIに文脈を届けるためのドキュメント運用戦略
AIエージェントの文脈保持を支援するためにドキュメントを整備することは有効ですが、階層が深いと参照されにくいという制約があるため、構造と提示方法にも工夫が必要です。
特に、エージェントに包括的な読み込みを期待するのではなく、人間が意図を持って見せたい情報を明示的に渡す設計が、現時点での最適解だと考えています。
人間が効率的に介入する開発構成のすすめ
Devin のような大型エージェントは、ターミナル操作や複数ファイルにまたがる提案も可能で、とても頼もしい存在です。 一方で、1回のセッションで消費されるクレジットが大きく、頻繁に呼び出すとコストがかさみがちです。特に、粒度の大きいタスクをそのまま渡した場合、依存関係の不整合や実行環境の違いによってエラーが発生しやすく、その復旧にさらにクレジットを費やしてしまうこともあります。
自律性の高さゆえに、意図とずれた方向に突き進んでしまった場合、修正にも多くのコストがかかります。
そのため、Devin には主に設計フェーズまでを担当させ、分解したタスクの実装や確認は Windsurf のような軽量エージェントに任せる運用が効果的でした。 この構成であれば、仮にエラーが発生しても、小さな単位で早期に検出でき、影響も限定的です。
- 設計・構造の検討(重めの思考) Devin や Roo Code に詳細設計を任せ、タスクを細かく分解してもらう。その上で、Windsurf などの軽量エージェントに分割タスクを実行させると効率的。
- 軽量な実装・修正 Windsurf や Cursor を用いて、変更や検証を高速に進める。
こうした役割分担によって、高速なフィードバックと低コストなループを維持しながら、効率的なvive coding(対話型コーディング)を実現できました。
DRY原則の観点
なお、今回の検証ではDRY(Don't Repeat Yourself)原則を維持できるかどうかという観点については十分に観察できませんでした。
というのも、今回扱ったのはWebアプリ開発の初期フェーズが中心で、コードベースがまだそれほど複雑でなく、コア機能の新規実装が主だったためです。既存のメソッドや構造を再利用する必要自体があまりなく、重複コードの発生や回避といったDRY観点での評価には至りませんでした。
今後、機能追加やリファクタリングのフェーズに入った際には、AIがどの程度DRY原則を意識した提案を行えるか、複数ファイルにまたがる処理の一貫性をどう保つかといった点を検証したいと考えています。
AIとどう付き合っていくか
AIエージェントは着実に進化していますが、現時点では万能な開発者ではありません。むしろ、提案・実行を得意とするAIと、判断・構造化を担う人間との役割分担を明確にすることが、うまく付き合っていくための鍵だと感じています。
今回試したDevin、Cursor、Windsurfはいずれも魅力があり、それぞれに得意・不得意があります。だからこそ、どのフェーズでどのツールを使うか、どんな情報をAIに渡すべきかといった観点からの戦略的な使い方が重要になってきます。
これからもAIと人間のコラボレーションの最適解を探りつつ、開発体験そのものをアップデートしていきたいと思います。
参考リンク
PR
XではUZUMAKIの新しい働き方や日常の様子を紹介!ぜひフォローをお願いします!
noteではUZUMAKIのメンバー・クライアントインタビュー、福利厚生を紹介!
UZUMAKIではRailsエンジニアを絶賛募集中です。
↓の記事を読んでご興味を持っていただいた方は、ぜひ応募よろしくお願いします!
是非応募宜しくおねがいします!