AI-Oriented Development

Yayavara
14 min readDec 13, 2024

--

2024年のAIプログラミング体験と考察

この記事は MOSH Advent Calendar 2024 の14日目の記事です。
https://adventar.org/calendars/9989

はじめに

こんにちは! MOSH EXチームのAndyです。
今年Moshの会員サイトの動画コンテンツ要約、目次生成など話題なAI機能をリリースしまして、最近もAIマーケット周りの機能を開発中です。何でもできそうなAIはエンジニアをリプレースできますか?実際今年AIにコーディングしてもらいました体験をシェアしたいと思います。

AI活用の軌跡

ChatGPT 3.5の登場以降、各種大規模言語モデルの性能は著しく向上し、AIを活用したコーディングが注目を集めています。当時はGitHub Copilotなども存在していましたが、そんなに使わないとだめな気持ちはなかった。

人類の進歩は「怠惰」から生まれるという格言通り、2024年初頭、私もAIを活用したコーディングを本格的に試み始めました。印象的な経験の一つは、Google Apps ScriptsからAWS API Gatewayを呼び出す認証処理の実装でした。フロントエンドプロジェクトであれば、aws-amplifyライブラリが自動的にRESTful APIリクエストへの署名を処理してくれますが、Google Apps Scriptsにはそのような便利なライブラリがなく、手動での実装が必要でした。自力での実装は諦めていたところ、GPT-4との対話を通じて、エラー情報をフィードバックしながら5回ほどの改善を重ねることで、わずか1時間足らずで動作する実装が完成しました。

フロントエンド開発に関するもう一つの経験は、Angularプロジェクトでのtooltipコンポーネントの開発です。既存のコンポーネントを使用せず、スキル向上も兼ねて自作することにしました。これが初めて設計図をAIにアップロードして開発を依頼した事例となりました。AIは要件説明を受けた後、UIの見た目は約80%の類似度で再現できましたが、細部の実装では課題が残りました。例えば、tooltipの吹き出しの矢印は、ホスト要素の上下左右の位置に応じて配置を変更する必要がありましたが、AIが生成したコードはこの要件を理解しているものの、なぜか実装では逆の動作をしてしまいました。また、対話を重ねるごとにコードの質が低下する傾向があり、時にはAIが人間の意見に過度に同調し、コードが中途半端な状態になってしまうことがありました。

この経験から、以下の重要な教訓を得ました:

開発タスクを「解決策が明確な問題」と「オープンエンドな問題」に分類することが重要です。この違いは、開発者自身が解決策を明確に把握しているかどうかにあります。オープンエンドな問題の場合、まず一つのAIと技術選定やアーキテクチャを検討し、その後、別のAIに具体的な実装を依頼する方法が効果的です。これは、AIが小規模で具体的な問題により強みを発揮するためです。また、頻繁にコンテキストを更新し、コードの提出を細かく行うことで、単純なコピー&ペーストによる品質低下を防ぐことができます。ただし、Webインターフェースでの作業は依然として煩雑で、大量のファイル内容のコピー&ペーストやコンテキストの説明が必要でした。

2024年後半、CursorエディタがX(旧Twitter)の中国語圏で注目を集め、特にClaude AIの強化されたコーディング能力と組み合わせることで、迅速な開発を実現する事例が多く報告されました。8月にCursorを導入して試用したところ、その予測機能が非常に優れていることがわかりました。同名の変数を修正する際、次に変更が必要な箇所を自動的に予測し、Tabキーを押すだけで変更できる機能は特に便利でした。この予測能力はコピー&ペースト操作時にも発揮されます。

Cursorの革新的な点は、エディタ内にAI対話機能が組み込まれており、コンテキストの説明やコードのコピー&ペーストの手間が大幅に削減されることです。ただし、念のため参照コードの説明をテキストボックスに記述することもあります。最近では、コード内にコメントを追加してファイルの役割や階層構造を説明したり、MDファイルを作成してモジュールやコンポーネントの機能を説明したりする方法などSNSで議論されていました。これは、将来的にコードが人間だけでなく、AIにも理解しやすい形式で記述される必要性もある傾向性になるでしょう。

AIを活用したコーディングには課題もあります。多くの開発者が懸念するバグの問題について、私の最近の経験を共有させていただきます。Angularのルーティングは通常routing moduleに定義されますが、特定の条件下でこのrouting moduleの内容を動的に変更する要件がありました。以前の経験を活かし、AIと技術選定について検討を行い、router.resetConfigを使用する方法と使用しない方法の提案を受けました。さらに、router.resetConfigを使用する場合の実行タイミングと呼び出し方法についても複数の選択肢が提示されました。私はルートガードでの実装を選択し、既に方針が決まっていたため、コーディング自体は順調に進みました。しかし、リリース後に特定の条件下でrouter.resetConfigが実行されないというバグが発生しました。これは、設計者である私の要件定義に基づいて正しく動作した結果であり、AIの問題というよりも、アーキテクチャの設計ミスでした。

この教訓を活かし、現在は自然言語でより詳細な要件を記述し、実装前に十分な検討を行うようにしています。AIは人間の能力を増幅すると同時に、ミスも増幅する可能性があります。以下は、現在使用しているプロンプトの例です:

我々はバックエンド開発タスクを実施し、データベースイベントのハンドラーを開発する必要があります。
まず、データベースイベントとコード間のモデル層には変換ステップが存在し、
@ファイルAを参照してください。
このイベントの定義は@ファイルBにあり、本質的にはクラスインスタンスです。
ハンドラーのサンプルコードは@ファイルCを参照してください。

我々はファイルBのイベントに基づく新しいハンドラーを開発する必要があります。
ビジネスロジックは以下の通りです:

ファイルBのイベントを受信した後、テーブルCをクエリする必要があります。テーブルCの定義は@ファイルCにあり、データベース操作コードは@ファイルDにあります。
現在の@ファイルDは要件を満たしていないため、以下の要件に従って修正が必要です。

修正後、ハンドラーの開始時に@ファイルDのクエリメソッドを使用してクエリを実行します。
クエリ結果を以下の要件に従ってフィルタリングします。
次の条件を満たす場合、実行を中止します。
最後に@ファイルEのデータを構築し、データベースに書き込みます。
ハンドラーの開発完了後、宣言的なファイルを補完する必要があります。
XXXフレームワークを使用しているため、@ファイルxを参照し、このハンドラーの定義を追加してください。

このプロンプトをCursorのcomposer機能に入力すると、即座にコードが生成されます。コミット前の修正は、主に命名規則とリンター関連の調整のみでした。

以上が私のAI活用開発の経験です。ここからQ&A形式で追加の考察を共有させていただきます:

Q&A

様々な大規模言語モデルの印象について
Claudeはコーディング能力が優れているというのが開発者コミュニティの共通認識です。現在、私も主にClaudeを使用しています。GPT-4はアーキテクチャ設計が得意と言われていますが、私自身は未検証です。昨日までの情報では、最新のGemini 2 Flashが急速に追い上げているようですが、こちらも未使用です。

AIのコード生成における特筆すべき強みについて
AIの得意分野は確かにフロントエンド開発だけではありません。特に注目すべきは、既存コードやAPIドキュメントなどの参照情報が与えられた場合の能力です。その中でも印象的な2つの領域について詳しく見ていきましょう。 テストコード生成の卓越性について、私が特に感銘を受けたのは、AIがソースコードの文脈を理解し、適切なテストケースを導き出せる点です。例えば、境界値テストやエッジケースの考慮、モックオブジェクトの適切な使用など、テスト設計の基本原則に則したコードを生成できます。これは単なるコードの模倣ではなく、テストの目的と意図を理解した上での知的な生成と言えます。 もう一つ特筆すべきは、OpenAPI仕様のYAMLファイル生成能力です。APIの設計図とも言えるこの仕様書の作成は、多くの開発者にとって煩雑な作業でしたが、AIはAPI設計のベストプラクティスを踏まえながら、整合性の取れた仕様を生成できます。特に、エンドポイントの詳細な定義やレスポンス例の生成、さらにはセキュリティ定義まで、包括的なドキュメントを作成できる点は驚くべき進歩です。 これらの能力は、既存の開発プロセスを大きく効率化する可能性を秘めています。しかし、重要なのは、AIがこれらのタスクを完全に自動化するのではなく、開発者の思考プロセスを補完し、より創造的な作業に時間を割けるようサポートしている点です。

他のAIエディタやIDEについて
Cursor以外にもWindsurfbolt.newもあります。Windsurfは噂によるとCursorよりも優れた体験を提供するとのことですが、現在は様子見の状態です。bolt.newは新規プロジェクトの迅速な展開に特化しているように見えますが、こちらも未使用です。

AI優先のドキュメントについての見解
これは確実にトレンドの一つです。AIにコードを理解させやすくする観点からも重要です。現時点では、コメントを充実させる方法やコンポーネント・モジュール専用のドキュメントを作成する方法など、様々なアプローチが試みられています。最近注目されているllms.txtもこの流れに関連していると考えられます。

中国語圏でのAI関連トピック
吴恩达(Andrew Ng)の翻訳手法李継刚のプロンプト (URLの文章はchrome翻訳で見てください)が特に注目されています。吴恩达の翻訳手法は、CozeやDifyなどのローコードAIエージェントプラットフォームで構築された翻訳エージェントが優れた成果を上げていることから人気を集めていますが、私自身は実践経験がありません。李継刚のプロンプトについては、プロンプトの新しい書き方を学ばせていただきました。この手法は実践済みで、後ほど詳しく共有させていただきます。また、以前会社でAI診断プロジェクトを実装しましたが、半年から数ヶ月前同様の原理を用いたプロジェクトがオンラインで話題となりました。なんか羨ましいです。
https://36kr.com/p/2899651963083652 (chrome翻訳で見てください)
twitter MBTI receipt (中国の方が開発してたtwitterでMBTI診断のツールです)

推奨AIツール
今後はV0の使用を検討しています。特にコンポーネントレベルのデザイン能力が優れているためです。また、ideogramを使用してデザインを試みたいと考えていますが、これらの設計図はFigmaにインポートできない可能性があります。一方、Galileo AIはFigmaへのインポートが可能です。また、DribbbleのデザインとV0を組み合わせることで良好な結果が得られるとの報告もあります。

現在のAIの改善点
大規模言語モデルのトレーニングデータ収集の特性上、AIはフロントエンドコードの生成に特に長けており、デフォルトでReact、TypeScript、shadcnの使用を前提としています。これにより、Webサイトの同質化が進む可能性があります。また、Pythonのコード生成は比較的良好ですが、Rustなどの言語では課題が残るとされており、この面での改善が期待されます。

AIとエンジニアの未来について
最近、Devin.aiのような高度なAIプログラミングアシスタントの登場により、「AIはエンジニアをリプレースするのか」という議論が活発になっています。(Moshでもこのような製品の導入は興味深い可能性を秘めています)。しかし、私の考えでは、この議論の本質は「リプレース」ではありません。むしろ、エンジニアとAIの協働はすでに現実のものとなっており、重要なのは未来のITエンジニアの定義や役割がどのように進化していくかということです。

プロンプト

最後に、李継刚のプロンプトについて共有させていただきます。彼のプロンプトはLisp言語を使用して論理的な関係を表現し、SVG形式で出力する特徴があります。これは私に新しい視点を提供してくれました。以前AI診断機能を開発した際、画像生成機能の追加を検討しましたが、応答時間の遅延が課題でした。李継刚のSVG生成アプローチは非常に斬新でした。SVGはテキストでありながら、実質的に画像としても機能します。AIによる直接の画像生成は応答時間の問題がありますが、SVGならその問題を回避できます。実は以前からAIを使用してMermaid.jsのフローチャートを生成していましたが、これも一種のテキストから画像への変換と考えることができます。また、AIによるBase64テキストの生成と、それを解析して動画を生成する可能性についても興味深い提案があります。私はまだ試していませんが、皆様もぜひ試してみてください。

以下は、中国語のプロンプでも日本語を出力できるように最適化した李継刚のプロンプトです。これは日本語の語彙を図解付きで説明するためのプロンプトです。プロンプトという名称ですが、実際にはプログラムとして扱うことができ、ぜひLLMのチャットで試してください。

;; 作者: 李继刚 
;; 版本: 0.3
;; 模型: Claude Sonnet
;; 用途: 将一个日本語語彙进行全新角度的解释
;; 设定如下内容为你的 System Prompt
(defun 新日本語老师 () "你是年轻人,批判现实,思考深刻,语言风趣, 使用日语表达" (风格 . ("Oscar Wilde" "魯迅" "夏目漱石")) (擅长 . 一针见血) (表达 . 隐喻) (批判 . 讽刺幽默))

(defun 日本語新解 (用户输入) "你会用一个特殊视角来解释一个词汇" (let (解释 (精练表达 (隐喻 (一针见血 (辛辣讽刺 (抓住本质 用户输入)))))) (few-shots (委婉 . "刺向他人时, 决定在剑刃上撒上止痛药。")) (SVG-Card 解释)))

(defun SVG-Card (解释) "输出SVG 卡片" (setq design-rule "合理使用负空间,整体排版要有呼吸感" design-principles '(干净 简洁 典雅)) (设置画布 '(宽度 400 高度 600 边距 20)) (标题字体 '毛笔楷体) (自动缩放 '(最小字号 16)) (配色风格 '((背景色 (蒙德里安风格 设计感))) (主要文字 (汇文明朝体 粉笔灰)) (装饰图案 随机几何图)) (卡片元素 ((居中标题 "日本語新解") 分隔线 (排版输出 用户输入 英文 日本語) 日本語解釈 (线条图 (批判内核 解释)) (极简总结 线条图))))

(defun start () "启动时运行" (let (system-role 新日本語老师) (print "言ってみよ、まだどの言葉で騙されたの?")))

;; 运行规则
;; 1. 启动时必须运行 (start) 函数
;; 2. 之后调用主函数 (日本語新解 用户输入)

--

--

Yayavara
Yayavara

No responses yet