はじめに
みらい翻訳のプラットフォーム開発部のtoshと申します。
弊社では複数のAIツールを採用しており、その中で個人的にはClaude Codeを使って開発しています。開発をしている中で、コードを書くスピードは確実に上がったのですが、一方でいくつか課題も見えてきました。
そんな中で、設計ファースト(Spec-First)とClaude Codeのスラッシュコマンドを組み合わせたアプローチを試してみているので紹介します。
課題と解決のアプローチ
AI時代に顕在化した問題
AIを使い始めて、コードを書くスピード自体は確実に上がりました。ただ、その分新たな課題に直面しています。
まず、セルフレビューと手直しに使う時間が増えてしまった点です。AIが生成したコードは一見動くように見えますが、想定していた挙動とずれることがあります。また、よく見ると命名等の実装方針が統一されていなかったり、プロンプトに入力していなかった箇所を勝手に補完して時に間違った実装をする、といった問題があります。それを見つけて直す作業に思いのほか時間を取られるようになりました。
次に、PRのレビュー時に大量に指摘されることがありました。自分では見落としていた問題をレビュアーに指摘されることが増え、レトロで「レビューが面倒になってきた」とフィードバックをもらってしまいました。これは正直、反省しています。
そして何より、指摘の多さに伴う品質への漠然とした不安が出てきました。AIが書いたコードは本当に大丈夫なのか、見えないところで問題を抱えていないか、という不安です。
まとめると、実装は速いのですが、その後の検証や修正に時間がかかり、結果として生産性が上がっているのか微妙な状況になっていました。
なぜSpec-Firstなのか
この課題に対して、設計ファースト(Spec-First)のアプローチが有効だと考えています。
ポイントは「AIが読む前提を整える」ことです。AIが生成したコードが想定していた挙動とずれるのは、そもそも「想定していた挙動」が明確に定義されていないからです。また、プロンプトに入力していなかった情報をAIが勝手に補完してしまうのなら、先に必要な情報を整理してから実装に入れば良いわけです。
具体的な取り組み
とはいえ、最初から完璧な設計ドキュメントを揃えるのは現実的ではありません。実際に私が取り組んだのは、以下のような小さな工夫です。
まず、コーディング規約の扱いを見直すことから始めました。規約自体は以前からあったものの、AIがうまく読み込んでくれないことが多発していました。そこで、明確に規約ファイルを読み込むことをプロンプトに含めるようにしたところ、生成されるコードの品質が安定するようになりました。
次に、先に実装の詳細設計とテストケースをplanとしてテキストファイルで出力してもらうようにしました。Claude Codeのplanモード(Shift + Tabでモード切り替え)を使うと、実装前に設計を詰めることができます。このplanの段階で要件の曖昧さに気づけるのが大きなメリットです。
テキストファイルで出力する理由は、会話履歴だと流れてしまい実装時に漏れが出やすいからです。ファイルとして残しておけば、実装中に見直せますし、後から修正もできます。また、そのままドキュメントとしても機能するため、実装前の設計段階でフィードバックをもらえるのも利点です。
さらに、planの時点である程度コードを出力してもらって、最終的な実装前にざっくり確認するようにしました。いきなり全実装に入るのではなく、サンプルコードレベルで方向性を確かめることで、大きな手戻りを防げます。
これらは小さな取り組みですが、「仕様→設計→実装」の順序を意識するだけでも、AIの生成の揺れ幅が縮まり、レビュー時の指摘が減ることを実感しています。
テストファーストの実践
TDDコマンドとサブエージェント
設計ファーストの考え方を実践する手段として、Claude CodeでTDDコマンドを作成して試しています。
TDDコマンドは、.claude/commands/tdd.md にプロンプトを配置するだけで使えるスラッシュコマンドです。これを実行すると、Claude CodeがRed → Green → Refactorのサイクルに従って開発を進めてくれます。
実際の使い方としては、まずplanモードで計画を作成してから、TDDコマンドを実行しています。
# 1. planモードで計画を作成(Shift + Tabでモード切り替え) ユーザー認証機能を実装したい # やり取りしながらプランを仕上げてもらう # 2. 計画ができたらTDDコマンドで実装 /tdd 計画通りに実装
コマンドを実行すると、以下のサイクルが回ります。
- 🔴 RED:失敗するテストを先に書く → 失敗を確認
- 🟢 GREEN:テストを通す最小限のコードを実装 → 成功を確認
- 🔧 REFACTOR:コード品質を改善 → テストが通ることを再確認
1サイクル完了後にユーザー確認を挟むので、方向性がズレていないかをチェックできます。
さらに、サブエージェントという仕組みも併用しています。サブエージェントは特定の役割に特化した独立したAIアシスタントで、今回はjava-code-reviewerというJavaコードのレビュー専門のエージェントを使っています。
TDDコマンドのプロンプト内で「REFACTORフェーズではjava-code-reviewerエージェントを起動」と指示しているので、自動的にレビューが走ります。
なぜこの組み合わせなのか
この仕組みの狙いは、仕様→テスト→実装の順序を強制することです。
従来の開発では「実装→テスト」の順序になりがちで、テストが実装の後追いになり、仕様の抜け漏れに気づきにくくなります。仕様からテストを起こして、そのテストを通すコードを書くという順序にすれば、仕様がテストとして明文化されるので、実装が仕様に沿っているかを機械的に検証できるわけです。
なお、TDDコマンドという名前ですが、厳密なTDDを実践しているわけではありません。本来のTDDはRed→Green→Refactorの短いサイクルを繰り返しながら段階的に設計を改善していくのが本質ですが、今回のアプローチはむしろ「テストファースト開発」+「フェーズ分割による品質チェック」と言った方が正確です。
それでも、和田卓人氏が指摘しているように、テストを先に書くアプローチは「AIの暴走を防ぐガードレール」として機能します。先にテストを書いておけば、AIが生成したコードが仕様を満たしているかをすぐに確認できます。
結果として、以下の二重チェック体制になっています。
- TDDコマンド:仕様→テスト→実装の順序を強制し、テストで仕様との整合性を検証
- サブエージェント:コード品質や潜在バグを専門エージェントがレビュー
やってみてわかったこと
期待通りだった点
まず、テストケースを先に考えることで、仕様の曖昧さや抜け漏れに早期に気づけるようになりました。planの段階で実際のコードを確認するため、欲しかったコードとの乖離が減りました。さらに、実コードを書く前のサンプル実装の時点でブラッシュアップできるため、コード品質も向上しました。
また、PRのレビュー前にサブエージェントでレビューすることにより、あくまで体感ですが事前に用意していた観点での指摘が正確になったように思えます。
結果として、コード品質が上がったのは確かです。セルフレビューでの手直しや、レビュー時の指摘が減ったことで、以前よりも自信を持ってPRを出せるようになりました。
想定と違った点
一方で、TDDを実践している感覚はないのが正直なところです。全フェーズをAI任せにしているため、自分でテストを書いて実装を考えるという一般的なTDDの手触りはありません。どちらかというと「AIがテストファーストプロセスに従って開発してくれるのを見守る」スタイルです。
また、テストケースの見直しが必要なこともあります。AIがテストを大量に作ることがあるので、作りすぎや重複のチェックは別途行う必要があります。
コストとトレードオフ
このアプローチには明確なコストがあります。フェーズ分割とレビューを挟む分、開発時間は増えますし、コンテキスト消費も多くなります。
向いているのは、複雑なビジネスロジックの実装や、長期メンテナンスが必要なコードです。反対に、プロトタイピングや使い捨てコードは向いていないように思います。
まとめ
AIを使った開発で、実装速度は上がったものの品質面での不安があったため、設計ファースト(Spec-First)とClaude Codeのスラッシュコマンドを組み合わせたテストファーストのアプローチを試してみました。
具体的には、コーディング規約の扱いの見直し、planモードでの事前設計、サンプル実装での確認といった小さな工夫から始めています。そして、TDDコマンドで仕様→テスト→実装の順序を強制し、サブエージェントで二重チェックを行う体制にしました。
結果として、コード品質が向上し、レビュー時の指摘が減ったのは確かです。一方で、開発時間の増加というコストもあるため、使いどころを見極める必要があります。
完璧に実践できているわけではありませんが、AI時代だからこそ、上流の設計を丁寧にする価値があると実感しています。今後も少しずつ改善を続けていければと思います。
We are hiring!
みらい翻訳では、私たちと一緒に翻訳・AIエージェントプロダクトの開発を進めていただけるエンジニアを募集しています!ご興味のある方は、ぜひ下記リンクよりご応募・お問い合わせをお待ちしております。