AI時代の『作り方』を設計する【AI駆動開発エンジニア勉強会/イベントレポート】

 

※この記事は、2025年10月に開催されたイベントでの発表内容をレポートしたものです。

登壇者はこの方

*

Sohei Takeno

株式会社SANU
テクノロジー本部長

Wantedlyで全社アーキテクトを務めた後、SANUに参画。ノーコードで構築された大規模システムをTypeScript・GraphQLで再設計し、技術とチームを内製化。ソフトウェア領域全般を管掌。

 

 

Takeno:SANUという会社に2023年から勤務しています。
ソフトウェアエンジニアとして参画し、ソフトウェア領域の技術および組織の内製化を推進してきました。今はソフトウェア組織全般を見ています。

SANU 2nd Home について

SANUについて聞いたことがない方もいらっしゃるかと思いますが、SANU 2nd Homeというサービスを提供しています。

SANU 2nd Homeは、軽やかに都市と自然を行き来するライフスタイルを提案する、シェア別荘サービスです。現在、日本全国に33拠点を運営しており、2028年には国内外100拠点以上を目指しています。純粋にソフトウェアだけでなく、現地の滞在体験もあるサービスです。

実は私もユーザーで、ワーケーションがしやすいところにたまに行って仕事をすることもあります。

このサービスは多くのオペレーションと拠点がありますが、基本的に無人でアプリのみで使えるようになっており、そこにソフトウェアを活用しています。

内製化:AI時代を見据えたフルスクラッチ

SANUというサービスは、2023年までノーコードで構築されていました。私が入社した時に、これをフルスクラッチですべて作り直すという、ゼロベースで作り直す機会がありました。

製化を始めたタイミングがLLM、ChatGPT-4が登場した時期でした。3.5から4への進化は短期間で大きく、ここからAI駆動になっていくという流れは間違いないだろうという見通しが立ち始めていたタイミングでしたので、AI駆動になることを見据えて設計を行いました。

それもあり、DevinやCursor、Claude Codeなど様々なツールを使ってきましたが、比較的どのツールを使っても安定して機能しており、そのような経緯から、今回AI時代のための作り方を設計するという話をさせていただこうと思います。

AI時代の『作り方』を設計する

作り方を設計する際、AIと協業する際に、そもそも自分たちがどのようにソフトウェアを作っているのか、その作り方自体=プログラマーの頭の中にあるものを見つめ直すことが重要だと考えています。それを踏まえて意志を持って、それをフレームワークとして設計することが大事だと考えてきました。

今回はそのような中で、どのようなことに気をつけて、ポイントとして選んできたかをお話しします。

作り方を見つめる

作り方を見つめる際、LLMに代表される昨今のAIは、知能があるとか意味を扱えるといった、ふわっとしたものを扱えるところがあり、それがコーディングに役立つわけですが、ある種確率分布のようなものであるため、非決定性があります。

つまり同じ入力をしても結果が変わったり、入力を少し変えるだけで違う結果になったりします。

ただこのAIの非決定性という前に、プログラマーがソフトウェアを作る場合にも、意思決定には非決定性があると考えています。プログラムで命名するとか、設計で何か選択をする際に、10回考えて10回同じ命名になるかというと、そうではないと思います。

ただ、ソフトウェアエンジニアリングを行う中で、あまりにも非決定性が大きく、あらゆることがランダムにソフトウェアの設計やコーディングが選択されていくと、さすがに安定しないため、様々な工夫をしていくことが、ソフトウェアエンジニアリングの一つの営みだと考えています。

その工夫は主に非決定性を制約していくことであると、ここでは考えます。

分類:決定性のある制約と、非決定性のある制約

この制約は日々の営みの中に様々入っていますが、非決定性のある制約と決定性のある制約があるというところをポイントとして挙げておきます。

分かりやすい例でいうと、型のようなものは、ある種のランタイムエラーをなくせるような型検査が行えるため、常にその種類のプログラムを排除できるという決定性のある制約が導入できます。Linterでも同じで、あるプログラムが必ず存在しないようにすることができます。

一方で、それだけでソフトウェアエンジニアリングを行っているわけではなく、日々命名をしたり、アーキテクチャを設計したり、ADRを残したりする中で、様々な意味や理解を形作ることで、ある種のソフトウェアの方向性も制約していると感じています。

このように、非決定性のある制約から、ある種非決定性がゼロで完全に同じ結果になる決定性のある制約までをソフトウェアの中では使っており、これを今回AIを使う際にも同じように織り込んでいくことが有効であると考えました。

実践と設計事例

ここからは、どのようなことを行ってきたかをいくつか紹介していきます。

プログラミング言語

まず分かりやすいところでは、プログラミング言語としてTypeScriptを採用しました。

TypeScriptであることが重要というよりは、AI活用の観点からどのようなことを重視したのかという点でいうと、一つは型検査があることです。これは先ほども述べたように、ある種のランタイムエラーが出ないことを保証できるため、非決定性を大きく抑えることができます。AIが様々なコードを書く際にも、そのようなプログラムをすべて排除することができるというのはメリットだと考えました。

ただこれだけではなく、型によってある程度設計ができることも重視しています。ここに書いたようなプログラムはTypeScriptで書けますが、ユーザーIDはStringであるといった、型の付け方、命名もできます。

動作上は全く変わりませんが、この型がStringであるというよりは、この型はユーザーIDであると宣言することで、意味をよりソフトウェアの中に込めていくことができ、非決定性の中でもより縛っていくことができます。このような部分も含めてできる型システムを持つプログラミング言語の一つとしてTypeScriptを採用しました。

スキーマ定義言語(インターフェイス定義言語)

もう少し大きなレベルでいうと、よくあるように三層アーキテクチャという形で、フロントエンド、バックエンド、データベースというふうに分けて構築しています。そうすると、この間の部分をどうするのかという通信のポイントが二つ発生します。

フロントエンドはバックエンドを叩きますとなると、バックエンドのAPI、インターフェースはどうなっているのか、バックエンドとデータベースでやり取りするデータベースのスキーマはどうなっているのか、という問題があります。

このような部分に対して、スキーマ定義言語、あるいはインターフェース定義言語とも言いますが、それぞれ導入しています。

GraphQLのスキーマを具体的に示すと、このような形で書けます。あるエリアというようなデータがあり、このようなフィールドがあるということを書いていけます。

これを使って全てのバックエンドのインターフェースを記述します。

同じようにデータベースに関してもPrismaという技術を使って、スキーマによってデータベースのインターフェースを記述しています。

これらがどのような価値を持つかというと、これも2つあります。スキーマはスキーマですが、そこからコードと型を自動生成することができます。

フロントエンドとバックエンド、あるいはバックエンドとデータベースの間の通信エラーを、ある種のエラーをゼロにすることを保証できます。LLMでコード生成することはもちろんありますが、その前に通常のいわゆるロジカルなコード生成によって、かなり安定する形でソフトウェアのアーキテクチャ全体を作ることができるため、このような決定性のある制約を最初に導入するのが一つです。

もう一つの意味は、スキーマを定義することで、言葉を定義し、AIに意味と文脈を与えることが非常に重要だと考えています。

ここに示したGraphQLスキーマの例を見ていただきたいのですが、スキーマ定義言語は、意味やソフトウェアのインターフェースを簡潔に伝えることに特化して設計されています。

このような情報を見るだけで、エリアはこのような情報を持っており、サイトはこのような情報を持っている、エリアとサイトはこのような関係にある、ということが簡単にわかります。つまり、これを見るだけで、AIも人間もバックエンドの持っている機能やデータが全てわかるということです。

このような部分でAIに意味と文脈を与えることができます。

これだけでも価値があるのですが、SANUで工夫している部分として、このすべてのデータ型とプロパティに対して日本語でもコメントを書くということをしています。

プロダクト開発をしていると、プログラム上は「サイト」と書かれていても、プロダクト開発の中では「拠点」と言ったりすることがあると思います。そのような時に「拠点の名前をページタイトルに表示して」というような指示を出すだけで、このスキーマを読みに行き、拠点はサイトのことだと理解し、プログラムと繋がっていきます。これは人間がやっても同じような意味がありますが、AIもこれによって、ユビキタス言語とプログラムをつなぐことができ、この点が非常によく機能しています。

作業範囲を制約する

さらに作業範囲を制約することもしています。インターフェース駆動開発といって、先にインターフェースを書きましょうということを設計しています。

フロントエンドとバックエンド、両方開発するという観点でいっても、GraphQLスキーマを最初に設計することや、先ほど書いたような、そのシンプルなファイルの中で、どのようなデータを入れるか、どのようなデータのリードあるいはライトのAPIを生やすかということが、かなり簡潔に狭いスコープで作業ができるため、これをまず作業します。

1. GraphQLスキーマを確定させる
  • Claude Codeなど AI に伴走してもらいながら設計する

このようなフェーズは、そもそもソフトウェアはどのようなものを持つか、どのような操作ができるかというかなり定義の段階になるため、このようなフェーズでは、命名などはClaude Codeなどにも伴走してもらいながら設計するという伴走型の設計ができます。

2. バックエンドを実装する
  • Claude CodeやCursorに伴走してもらう or 自走してもらう

この真ん中のフロントエンドとバックエンドのスキーマを設計しておくと、バックエンドのAPIもそれを実装することになりますが、このくらいのフェーズになってくると結構簡単なDB取得であれば、そのまま実装してもらって、完全にこのAPIを実装してくださいということで、場合によっては勝手に実装ができるという状態になったり、あるいはドメインロジックが複雑な部分に関しては伴走型でまた行ったりという形で実装できます。

3. フロントエンドを実装する
  • Claude CodeやCursorに伴走してもらう or 自走してもらう

これは最初にスキーマを定義しているため、その定義する作業によって、かなりフロントエンドとバックエンドの実装の定義を大きく制約することができ、そこから徐々に人が手放していくような形で、設計から実装へと移行することがものによって使い分けられるというのが、このアーキテクチャのAI非決定性をコントロールしている部分になっています。

実装でも「作り方」を制約する

もう少し細かい部分についてもお話しすると、実際の実装もあります。実際の部分に関しても段階的に制約していくことが重要だと考えています。

まず技術選定をします。

一歩目としての「技術選定」
  • フロントエンド:Tailwind, React, Next.js, GraphQL Codegen Client Preset
  • バックエンド:GraphQL Yoga, GraphQL Codegen Server Preset, Prisma

技術選定をしてどのような技術が使えるかという状態が決まっても、例えばJavaScriptでいうと、日付や時刻を扱う際に、DateとTemporalという2つがあります。このどちらを使うかという、より詳細部分を決めていきます。

二歩目としての「技術の使い方」
  • 例:日付や時刻を扱う際にはDateではなくTemporalを使います

さらに複数の技術をどう組み合わせて使うかという部分もあります。GraphQLのデータをReactに流し込みましょうという際に、様々なReactコンポーネントの流し込み方があると思いますが、そこに対してFragment Colocationというパターンをやっていきますというようなことを作っていくことを段階的に行っていきました。

三歩目としての「複数の技術をどう組み立てるか」
  • 例:GraphQLのデータをReactに流し込む際にはFragment Colocationをします

さらに:「作り方」をまとめた1ページのドキュメントを運用

このようなことを行って、作り方に関して工夫していることとして、一つのページのドキュメントに、ただ技術やコードを見るだけでは分からないような作り方を全部まとめることをしており、これを運用しています。

作り方がアップデートされれば、これをどんどん更新していきます。これはもちろん新しく入ってきたエンジニアが読むというのもありますが、AIも読むように作っており、これによって、そもそもこのコードベースでどのような作り方をしているのかという話の最初の入り口の部分が分かるということとして使っています。これをClaude Code、Devin、Cursorなど、全部のナレッジを入れる場所に使っています。

ただ、ここの注意点として、このような部分でプログラム全部を制御するのは結構難しいと考えています。

指示文があまりにも多くなってしまうと、AIもアテンションが偏ってしまうという部分があるため、あくまでここまで述べたような様々な制約を組んだ上で、最後の補助として、このようなポリシーのような部分をナレッジとして与えるのが良いバランスで、このようなドキュメントだけで全部解決しようとしないということも同時に重要だと考えています。

まとめ

AI時代の作り方を設計するというタイトルでお話しさせていただきましたが、そもそもその作り方、自分たちがソフトウェアをどう作っているのかという話を見つめつつ、フレームワークとして昇華していくことが重要だと考えています。

AI時代の『作り方』を設計する

フレームワークとして設計する際に、様々なレベルがあり、非決定性のあるものから決定性のあるものまで組み合わせてソフトウェア全体を織り込んでいきます。それによって様々AIツールの進化がありますが、ある程度はツールや課題によらずAIに駆動されるエンジニアリングが実現できるのではないかというところが今回のお話でお伝えしたかったところです。

 

▼▼ ぜひ他登壇者の発表レポートもご覧ください!

 

 

Community Members

さまざまなテーマで事例や知見を学ぶ
IT・テクノロジー人材のための勉強会コミュニティ

①上記ボタンをクリックするとTECH PLAY(外部サイト)へ遷移します。

②TECH PLAYへ遷移後、アカウントをお持ちでない方は、新規会員登録をお願いいたします。

③TECH PlAY会員登録後、TECH Streetページよりグループフォローをしてください。

今後のイベント参加・メンバー登録に関する重要なお知らせはこちら