はじめに
こんにちは、カイポケのリニューアルプロジェクトを担当しているエンジニアの菅原です。2023年12月に入社し、現在はフロントエンドエンジニアとして機能開発を行っています。
最近、Claude CodeやGitHub CopilotなどのAIエージェントが注目されており、弊社でも活発にAIエージェントを活用した開発が行われております。
私が所属しているチームでも、AI活用の取り組みの一環として、フロントエンドの実装自動化に挑戦しました。具体的には、二週間のスプリント期間内で実施するすべてのフロントエンドタスクを、AIエージェントによる自動実装で完成させることを目標とした実験を行いました。
結論から申し上げると、完全な自動化には至らなかったものの、適切な仕組みを整備することで実装プロセスの大幅な効率化を実現することができました。
本記事では、この取り組みを通じて得られた知見と課題、そしてAIエージェントによる実装自動化の現実的な可能性について紹介させていただきます。
取り組みのモチベーション
カイポケのリニューアルプロジェクトでは、開発手法としてLeSS(Large Scale Scrum:大規模スクラム)を取り入れており、隔週でスプリントを回しています。LeSSのイベントである、リファインメントを通じて、複数チームに跨ったPBI(ブロダクトバックログアイテム)の分割や曖昧な要求を詳細化することで、スプリント活動中にチームが担当するPBIの不確実要素が下がった状態を実現できています。
また、スプリント期間中もチーム内でモブプログラミングや実例マッピングといった手法を活用して、チームが担当するPBIの要求をより詳細化していき、SBI(スプリントバックログアイテム)というPBIを完了させるために取り組む必要があるタスクのリストに分割しています。スクラムのプラクティスの1つとして、SBIを1日以内に終わる単位で分割することが推奨されており、開発者が実装するタイミングでは仕様が明確になっているため、スムーズに開発できるケースが多くなっています。
このような状況の中で、私はAIエージェントを活用しつつ日々の開発に取り組んでいましたが、要求が明確なため実装後に期待するアウトプットのイメージが持ちやすく、ある程度はAIエージェントに実装を任せても十分な品質のコードを出力できていると感じていました。
そのため、弊プロジェクトで採用しているLeSSによるPBIの不確実性を下げる取り組みと、AIエージェントによる自動実装には強い親和性があるという仮説を持ちました。そこで思い切って、私が担当する一スプリント内のすべてのタスクをAIエージェントにより実装させることで、実装をどこまで自動化できるかという挑戦を行うことにしました。
LeSS導入時の経緯は過去記事をご参照ください。
自動化の概念図
今回の取り組みでは、スプリント期間中のすべての開発プロセスを自動化するのではなく、初期の実装とPRレビューの指摘事項への修正を対象に自動化することとしました。
自動化対象のイメージは以下の概念図を参照してください。

取り組み内容
1. 設計ドキュメントからAIエージェントがdraft PRを自動作成
まず、AIエージェントによる実装自動化の第一歩として、FigmaのコンポーネントURLと「このコンポーネントを実装して」のような簡潔な指示を出して、AIエージェントに実装を任せてみることから始めました。
しかし、このアプローチでは以下のような問題が発生し、生成されたコードは一見動作するものの、期待値を満たしておらずに大幅な修正が必要になるという結果になりました。
- デザインシステムとの不整合: デザインシステムのコンポーネントやカラー、フォントサイズなどの定義を無視した、独自の実装になってしまう
- インタフェース定義の不備: 他のコンポーネントとの連携に必要なProps定義やGraphQLスキーマの型定義が不適切になってしまう
- 振る舞いの実装ミス: UIの細かな状態変化やユーザー操作に対する振る舞いが期待値と異なる実装になってしまう
これらの問題を解決するため、スプリント活動でアウトプットした設計ドキュメントを基に、実装時に必要な情報を構造化して提供する方針にしました。
MCPを活用してデザインシステムに準拠
デザインシステムとの不整合を解消するため、弊社の内製Figma MCPとデザインシステムMCPを活用したアプローチを採用しました。これにより、AIエージェントは以下のような情報を参照しながら実装を行えるようになりました。
- デザイントークン: カラー、スペーシング、フォントサイズなどの基本的なデザイン要素を参照
- コンポーネント定義: 各UIコンポーネントで定義されたPropsを参照
この仕組みにより、AIエージェントが生成するコンポーネントは、デザイナーが意図した見た目と動作に近い状態で実装できるようになりました。
弊社内製のMCPの実装については以下記事で詳しく解説しているので、併せてご参照ください。
インタフェース定義の標準化
実装するコンポーネントのインタフェース定義やGraphQLスキーマの定義が曖昧な状態では、AIエージェントは柔軟に実装してくれます。しかし、この「柔軟性」が問題となり、毎回異なる結果を出力してしまうことから、実装予定の他のコンポーネントとの連携が取れない実装になってしまうという問題がありました。
この問題を解決するため、スプリント活動の設計フェーズで明確になった仕様を基に、事前にインタフェース定義を固定し、AIエージェントへのインプット情報として明示的に提供するようにしました。
以下はインプットとして提供する情報の例です。
- コンポーネントを実装するディレクトリの例
src/services/careReceivers/tableRow/TableRow.tsx にコンポーネントを実装
- コンポーネントのPropsの例
type Props = { id: string; name: string; };
- 利用するGraphQLスキーマの例
fragment CareReceivers on User { id name }
UIの振る舞いの構造化
AIエージェントが生成したコンポーネントは、見た目は正しく実装されているものの、ユーザーの操作に対する反応や状態変化が仕様と異なることがありました。
この課題に対しては、スプリント活動の実例マッピングで整理したUIの振る舞いを、Given When Then形式で構造化し、AIエージェントにテスト駆動開発で実装させる方針を採用しました。
具体的には、以下のような流れで実装を行います。
- 振る舞いの構造化: 実例マッピングの結果をGiven When Then形式で記述
- テストの実装: AIエージェントがその仕様に基づいてテストコードを実装
- コンポーネントの実装: テストがパスするまでコンポーネントを繰り返し修正
UIの振る舞いの例(Given When Then形式で記述)
- Given: 利用者一覧画面が表示されている状態で
- When: 利用者のチェックボックスをチェックすると
- Then: ヘッダーにチェックした利用者件数が表示されること
このアプローチにより、AIエージェントが生成するコンポーネントは、見た目だけでなく動作も仕様通り実装されるようになりました。
プロジェクト固有のコンテキストの提供
上記の主要な課題への対策に加えて、AIエージェントがプロジェクトの既存実装パターンを理解し、一貫したコードスタイルで実装できるよう、以下も補完情報として加えました。
- リファレンス実装のディレクトリパス
- コーディングガイドラインのファイルパス
これらの構造化されたインプット情報を整備した結果、AIエージェントによる実装品質が安定するようになりました。
2. インラインレビューによるAIエージェントの自動修正
上記のアプローチにより、実装品質が安定したものの、インプットの内容の不備やコンテキストの欠落により、AIエージェントが生成したdraft PRをそのまま商用環境に適用することは厳しいことがわかりました。
そこで、draft PRで不十分な箇所については、人手でのPRレビューにより修正する方針としました。
最初のアプローチとして、AIエージェントがGitHub CLIを活用してPR reviewの内容をチェックして修正するようにしていましたが、以下の課題がありました。
- すでに解決済みのレビューコメントも取得してしまい、フィードバックの回数が増えると適切な修正が行われなくなる
- レビューコメントに対して、AIエージェントが修正した内容をチェックするのに手間取り、指摘内容が適切に修正されているか確認しづらい
そこで、効率的なPRレビューを実現できるようにGitHub GraphQL APIを活用して、以下のツールを持つ簡易的な自作GitHub MCPサーバーを作成し、レビューコメントの修正を行うようにしました。
get_pull_request_review_comments: 未解決かつ参照元のコードが最新のレビューコメントのみを取得するツールreply_to_fixed_commit_in_pull_request_review_thread: レビューコメントに対して修正内容の完了と修正した対象のコミットハッシュを通知するツール
これらのツールを活用することで、AIエージェントが以下のプロセスでインラインレビューの指摘事項を修正することができたため、コードを期待する品質まで改善させることができました。
- レビューコメントの取得:
get_pull_request_review_commentsでPRの未解決コメントを一括取得 - 修正内容の特定: AIエージェントがコメントの内容を解析し、必要な修正を特定
- コードの修正: 指摘事項に基づいてAIエージェントが自動でコードの修正を実行
- 修正完了通知:
reply_to_fixed_commit_in_pull_request_review_threadで修正コミットと修正内容を報告
具体的なMCPツールの実装イメージは以下を参考にしてください。
MCPツールの実装イメージ
1. get_pull_request_review_comments
PRのレビューコメントを構造化されたデータとして取得するツールです。
以下のコードブロックでは、現在の作業ブランチ(draft PRを作成したブランチ)を入力値として渡すと、未解決のレビューコメントのファイルパスとスレッドを返す仕組みを表現しています。
server.registerTool( "get_pull_request_review_comments", { description: "Get comments from pull request review threads", inputSchema: { branchName: z.string().describe("Branch name of the pull request"), }, outputSchema: { filePaths: z.array( z.object({ filePath: z.string().describe("File path of the review thread"), reviews: z .array( z.object({ threadId: z.string().describe("ID of the review thread"), startLine: z .number() .nullable() .describe("Start line of the review thread"), endLine: z .number() .nullable() .describe("End line of the review thread"), comments: z .array(z.string()) .describe("Comments in the review thread"), }), ) .describe("Reviews in filePath"), }), ), }, }, async (params) => { // 未解決のPRレビューコメントを構造化されたデータとして返却する処理 }, );
リクエストの例
- branchName: 現在の作業ブランチ(draft PRを作成したブランチ)
{ "branchName": "feature/current-branch" }
レスポンスの例
- filePath: レビュー対象のファイルパス
- reviews: レビューのスレッドID、コメントの範囲、コメントの内容
{ "filePaths": [ { "filePath": "src/components/UserList.tsx", "reviews": [ { "threadId": "threadId1", "startLine": 15, "endLine": 20, "comments": [ "型定義が不十分です。Propsの型を明確に定義してください。", "ユーザビリティの観点から、エラーハンドリングを追加したほうが良いです。" ] } ] } ] }
2. reply_to_fixed_commit_in_pull_request_review_thread
レビューコメントに対して修正完了の返信を自動で行うツールです。
以下のコードブロックでは、get_pull_request_review_comments で取得したレビューのスレッドIDと修正したコミットハッシュ、修正内容を入力値として、対象のレビュースレッドに対して修正内容を通知する仕組みを表現しています。
server.registerTool( "reply_to_fixed_commit_in_pull_request_review_thread", { description: "Reply to a fixed commit in a pull request review thread", inputSchema: { threadId: z.string().describe("ID of the comment to reply to"), commitHashes: z .array(z.string()) .min(1) .describe("Array of commit hashes of the pull request"), message: z.string().describe("Custom message to include in the reply"), }, outputSchema: { result: z.object({ success: z.boolean().describe("Whether the reply was successful"), body: z.string().describe("Content of the reply"), createdAt: z .string() .describe("Timestamp of when the reply was created"), }), }, }, async (params) => { // レビューのスレッド単位で修正内容を返信する }, );
リクエストの例
- threadId: レビューのスレッドID
- commitHashes: レビューコメントに対して修正したコミットハッシュ
- message: 修正内容
{ "threadId": "threadId1", "commitHashes": ["ea9f557c44b545b93d7f86fcc7cb796c77022367"], "message": "ご指摘いただいた点を修正しました。型定義を追加し、エラーハンドリングも実装しています。" }
レスポンスの例
- threadIdで指定したスレッドに対して、レビューコメントを返す

まとめ
本記事では、LeSSによってPBIの不確実性が低減された状況とAIエージェントによる自動実装に親和性があるという仮説のもと、スプリント期間中のフロントエンド実装自動化に挑戦した取り組みについて紹介させていただきました!
完全な自動化には至らなかったものの、この取り組みを通じて、以下の仕組みによりAIエージェントによる実装の大幅な効率化を実現できました。
- スプリント活動でアウトプットした設計情報を、AIが理解しやすい形式に整理し、設計ドキュメントを構造化
- 独自のGitHub MCPを活用して、PRレビューコメントの自動取得と修正完了通知の仕組みを実装し、自動修正フローを構築
さらに、弊社内製のFigma MCPやデザインシステムMCPとの連携により、デザインシステムに準拠した実装を自動生成する体験も実現しました。
一方で、完全な自動化を実現するには、まだまだ以下のような課題があることもわかりました。
- AIエージェントが安定した出力を行うための設計ドキュメントの構造化が必要
- 複雑なビジネスロジックや例外処理では、人手による詳細な指示やレビューが必要
- AIが解釈しやすい形式でのコーディングガイドライン整備が必要
現状では「完全自動化」よりも「効率的な協働」が現実的であることがわかりました。今後はこれらの課題を解消しつつ、人とAIがより良く協働できる開発体験の実現を目指していきたいと考えています。
