🤖

AI エージェントを使ってフロントエンド開発を試した所感

2025/03/31に公開

はじめに

こんにちは!ダイニーでソフトウェアエンジニアをしている ta21cos です。

現在ダイニーでは AI エージェントの活用の検証として、Cline(AI エージェント)+ Claude 3.7 Sonnet(LLM) のお試しをしています。ちょうど実装タスクとしてフォームの新規開発案件があり、今回それを題材として Cline に開発を任せてみることにしました。

(Cline は “AI assistant” ですが、日本では「AI エージェント」という呼称が普及しているため、本記事では馴染みのあるそちらの呼び方を使います)

本記事では、その過程で試したことや上手くいかなかった点、気づいたことなどをまとめていきます。今回は、Cline を使って複数ページにまたがるフォームを実装させることを題材としています。

対象読者としては以下のような方を想定しています。

  • AI エージェントに興味がある
  • フロントエンド開発(React / TypeScript)への AI 適用を検討している
  • AI 時代のコーディングについての考え方を知りたい

なお、今回の記録はあくまで一例であり、以下の点をご留意ください。

  • ベストプラクティスに沿っているとは限りません
  • モデルの出力にはランダム性があるため、再現性は保証できません
  • 今回は「どうやって手離れして AI に任せられるか」を主眼としています。AI と並走するやり方では、また違った意見になるかもしれません。

それでは、まずは題材となったフォームの概要について紹介していきます。

題材としてのフォーム実装

今回は、Cline を用いた AI エージェント開発の題材として、複数ページにまたぐマルチステップフォームを実装対象としました。

このフォームを選んだ理由はいくつかあります。

  • 構造がパターン化されている
  • コンポーネントの繰り返しが多く、実装の型が決まっている
  • 既存のコードを参照しながら作れる場面が多い
  • コードの物量が多い

こういった特徴は、AI にとって実装のヒントが得られやすく、比較的指示しやすい領域だと考えました。

フォームの構成

作成したフォームは、全8ステップからなる申し込みフォームです。各ステップは個別のページに分かれており、ユーザーが順に情報を入力していく構成になっています。

  • Step 1: 記入の上での注意事項の表示
  • Step 2: 法人情報の入力
  • Step 8: 送信完了の表示

フォームのデザインは次になります(一部マスクしています)。

求めるコードの技術・制約

既存のコードでは次のようなスタックを用いています。

  • Ant Design
  • Styled Components
  • フォームロジックはカスタムフックに分離
  • 標準コンポーネントをカスタマイズしたものを利用

まずは Cline に既存コードから読み取ってもらえるかを確認すべく、最低限の指示をしてみます。

Cline に実装を依頼してみる

Cline には、Ant Design ベースのマルチステップフォームを実装することをゴールとして設定しました。
各ステップの目的や必要なフィールドに加えて、制約や参考コードの情報も細かく伝えています。
試した印象としては、「丁寧に書くほど精度が上がる」ように感じたため、可能な限り具体的に指示を与えるようにしました。

プロンプトとしては、次を記述しました。

  1. フォームの概要
  2. 各フォームに必要な要素
  3. 実装方針、今回は既存のコードに従うような指示
  4. 禁止事項

以下が、実際に Cline に与えたプロンプトの一部です。公開できないものも含め、長いので大きく省略しています。

I want to create an application form.
This form consists of 8 steps.

// 各ステップの概要を説明する
Each form mock page is located in the folder src/pages/ApplicationForm.
- Step 1: Warning
	- This page is intended to inform users about important notices.
	- It is located in the folder named Top.
- Step 2: Legal Information
	- This page is intended to collect information about legal details.
	- It is located in the folder named LegalInfo.
	...
- Step 8: Completed
	- This page is intended to display the completion status of the form.
	- It is located in the folder named Completed.

// 各フォームに必要なフィールドを列挙する
Here is the content of each page.
- Step 1: Warning
	- This page consists of 3 components:
  - Title
		- 申し込みフォームご記入の前に
  - Description
		- 事前に以下の書類の提出が必要なのでご用意ください。
		...
- Step 2: Legal Information
	- This page contains the following form items:
		- legalName: 会社名
		...
- Step 8: Completed
	- Title: 送信が完了しました
	...

// 既存コードを参照するように伝える
You must follow the existing code structure and implement the form.
You can refer to the 【既存ページ名】 page for implementation.

// 注意事項を伝える
Do not perform the following actions:
- Rename files
- Delete files
- Modify any files except those in the src/pages/ApplicationForm folder.
	- You must implement everything only within the src/pages/ApplicationForm folder.

上記の指示で実装を依頼した結果、次のような画面が出来上がりました(一部マスク済み)。デザイン周りは自分で調整するとして、ある程度できていそうです。コードを細かく見ていくと長くなってしまうので、出力されたコードに関して良かった点、悪かった点をまとめていきます。

上手くいかなかった点

既存コードの模倣は想定通りにはいかない

既存コードを参照させる形で実装を依頼しましたが、いくつかの点で思ったように真似てくれませんでした。発生したケースとコードの実際・理想を示します。

  • Styled Components を一貫して利用しているが、inline style を多用する
// As is
<Form.Item style={{ display: "flex", justifyContent: "flex-end" }}>
  <Button type="primary" htmlType="submit" size="large">
    次へ
  </Button>
	 ...
 </Form.Item>
  
// To be
const StyledFormItem = styled(Form.Item)`
	display: flex;
	justify-content: flex-end
`;
...
<StyledFormItem>
  <Button type="primary" htmlType="submit" size="large">
    次へ
  </Button>
	 ...
 </FormItem>
  • 独自で用意したコンポーネント に気づかず、標準のコンポーネントを利用する
// As is
<Form.Item
  label="氏名"
  name={["owner", index, "nameKana"]}
  initialValue={owner.nameKana}
  ...
/>

// To be

// NOTE: FormItem に型を持たせるために用意したメソッド
export const ApplicationFormItem = createFormItem<ApplicationFormValues>();
...
<ApplicationFormItem
  label="氏名"
  name={["owner", index, "nameKana"]}
  initialValue={owner.nameKana}
/>

しかし、いずれも改めて修正指示を出せばちゃんと適用した実装を出力してくれました。根気強くやる必要はありますが、最初の指示を細かくすれば改善できるかもしれないです。

設計には人間の判断が必要そう

設計には明確な正解がなく、プロジェクトのアーキテクチャやユースケースに応じた判断が必要になります。コンポーネントの粒度、責務の分離、フォルダ構成などは、人間の設計意図が強く影響する領域です。

今回で言えば、AI アシスタントが生成したコードは以下のような構造をしていました。まとめれば各フォームのページごとに Form インスタンスを持つ方法です。

これは動作するという点で間違いはありません。しかし、私としてはコンポーネント間の余計なデータの受け渡しを減らすべく、フォーム全体で一つの Form インスタンスを持つ方針が良いと考えていました。何度か追加で指示を与えた結果が以下です。

ユースケースを与えることで設計も生み出すことも将来的には可能になるかもしれません。しかし今回コンポーネント構造に関してやり取りした限りは、そうなるまではもう少し時間がかかる印象を受けました。

欲しいコードを得るためには時間・お金の両方のコストがかかる

処理が遅いのか負荷が大きいのかわかっていないのですが、レスポンスが遅い場合が結構あります。

また特に「エラーを解消してほしい」というタスクのときには大きなコストがかかる印象があります。エラーを治すときに上手くいかず、試行錯誤し続けることもあり、時間とトークン両方を激しく消費することもあります。Cline は際限なくお金が溶けていくので、コスト感が想定しづらい点が企業目線にはマイナスに働く可能性があると感じました。

少なくとも現時点では、「正確かつ素早く」成果物が欲しい場合には、人間が実装した方が早いと感じました。今後、数年のうちにこの印象が変わる可能性は十分にあると思います。

実際に使ってみて良かったこと

非同期に作業が進む

AI に実装を依頼することは「早くない」かもしれないと書きました。しかし、自分が手を動かしていない間にも実装が進んでいるという点は、大きなメリットでした。会議や別の作業に時間を取られがちなエンジニアでも、それらと並列して実装を進めることができそうです。

一度 AI に教えれば次回以降に期待できそう

今回はゼロから実装を依頼したため上手くいかなかった点が多かったとも言えます。これらを「覚えさせる」ことで2回目以降はよりスムーズなコード生成が期待できます。特に似た構成の画面やパターンが多いシステムでは、「2回目以降の自動化」という観点で、一度時間を欠けて教えることに大きなレバレッジが期待できそうです。

AI エージェントとの開発を通じて考えたこと

ここまでの結果から、AI とコラボレーションした開発環境を考察します。

AI コーディング時代におけるドキュメントの役割

これまでは、ドキュメントや仕様書を詳細に書くことを避けてきた組織も多いのでは思っています(弊社もその一つです)。これは仕様が変化した際のメンテナンスコストの重さが大きいことが理由だと思います。

一方 AI コーディング時代では、詳しく書かれた仕様やコーディングルールは、そのまま AI への指示として使うことができます。メンテナンスコストと天秤にかけたとき、ドキュメントを残す価値の方が高くなるというタイミングが来ているかもしれません。

AI エージェントは新人のように扱う

「既存の実装を参考に新しい機能を実装する」タスクを任せたとき、思ったように真似てくれなかった箇所がたくさんありました。もちろんこれは指示の仕方に改善点があるからなのですが、この様子を見て New Comer の書き方に似ているかも、と思いました。

「見ればわかるでしょ」は通じないので、適切なドキュメントと指示が必要になります。逆に言えば、新人にもわかるような設計・ドキュメントの工夫は、AI に対しても有効なのかもしれません。Devin を導入した組織がそれを「新人」と比喩しているポストを見ましたが、とても的を射た表現だと感じました。

言語の特性について

AI 時代の言語とは、という話を聞いたことがありますが、AI に適している言語というのは存在するのでは、と感じました。重要な観点として「指示しやすい」「出力にブレが少ない」がありそうです。

その意味で言えば、何かを表現するときの選択肢が少ない言語のほうが、AI 生成に適していそうです。具体で言えば「1つの目的に対して複数の手段を持たない」という哲学を持つ Python や、構文や機能の数を減らしている Go 言語あたりになるでしょうか(どちらもちゃんと書いたことがないので、間違っていたらすみません)。

インタフェースについて(Devin と Cline)

Cline の他に、Devin もよく話題に上がります。Cline は VSCode の拡張機能という形で、Devin は Slack をインタフェースとして提供されています。今回「手離れした状態で AI に実装を任せる」という目的からすれば、個人的には Devin のようなインタフェースのほうが適していると思いました。

しかしここは AI の使い方次第なので、どちらが生き残るという話ではなさそうです。今回 Cline を使ってみて、一層 Devin を試してみたくなりました。

おわりに

本記事では、複数ページにまたがるフォーム実装を AI に任せた取り組みについて、試行錯誤や気づきを中心に記述しました。

本記事で紹介した内容はあくまで一例であり、他のタスクやツール、モデルを使えばまた違った結果になるはずです。

それでも、生成 AI を開発に活用するにあたって、実際の現場で何が起こるのかをイメージする材料にはなるかと思います。もし何かの参考になれば幸いです。

We’re hiring!

ダイニーでは、AI も取り入れながら素早くシステムを実装していく仲間を募集しています。

興味がある方は、ぜひ一度お話しましょう!

https://hrmos.co/pages/dinii/jobs/0001

Discussion