【ソフトウェア開発現代史】継続的デリバリーができない組織でAIは増幅器(amplifier)として空回りを生む 〜Dave Farley氏の来日に寄せて〜

https://cdn-ak.f.st-hatena.com/images/fotolife/T/Taka_bow/20250502/20250502174921_original.png

ソフトウェア開発現代史年表Ver2.08

はじめに

こんにちは。テックブログ編集長の高橋(@Taka-bow)です。

冒頭に掲載した「ソフトウェア開発現代史年表Ver2.08」は、ソフトウェア開発の考え方がどのように変化してきたのかを、できるだけ一枚で見渡せるように整理したものです。

この年表の中に、2010年の『Continuous Delivery』があります(赤枠)。

Jez Humble(ジェズ・ハンブル)氏とDave Farley(デイビッド・ファーリー)氏によるこの本は、CI/CDやFour Keysを考えるうえで、出発点にあたる一冊です。

本記事では、この『Continuous Delivery』を起点とする流れを取り上げます。

生成AIによって、コードを書く速度は大きく上がりました。AI駆動開発という言葉も広がり、実装からデプロイまでの時間はますます短くなりました。

しかし、ソフトウェアを速く作れることと、価値あるものを継続的に届けられることは、同じではありません。

そこで今回は、Dave Farley氏の初来日に寄せて、AI駆動開発を機能させる土台としての継続的デリバリーに焦点を当てます。

Dave Farley氏が築いてきた継続的デリバリーとは何か、それがDORA Metricsとどうつながっているのか、そしてAI時代にこの思想がなぜいっそう重要になるのかを整理します。

デリバリーは速ければよいのか

むかし、その場しのぎの言い訳や曖昧な返答を「蕎麦屋の出前じゃないんだから」とたしなめる言い回しがありました。そんな比喩が通じるほど、かつての出前(デリバリー)は「遅くて当てにならないもの」と見られていたのでしょう。

いまは違います。Uber Eatsやmenu、出前館のような専門サービスが増え、マクドナルドのように飲食店自身が届けてくれることも当たり前になりました。

「ピザのデリバリーは30分以内」。そんなイメージを持っている人も多いのではないでしょうか。速く届くこと自体が、ひとつの価値になっています。

しかし、30分で届いたピザでも、冷めきっていたり、注文と違うものが届いたりしたらどうでしょう。速く届いたかと、価値あるものが届いたかは、別の問いです。

ソフトウェアの「デリバリー」も同じです。

私たちエンジニアにとってのデリバリーといえば、CI/CDの「CD」、すなわちContinuous Delivery=継続的デリバリーです。文字どおり、「ソフトウェアの価値」を「継続的」に「届ける」ことを指します。

近年は生成AIの登場によって、実装からデプロイまでの流れが目に見えて速くなっています。ソフトウェアの「デリバリー時間」が短くなっていることは、多くの現場で体感されているはずです。

ただし、速さはソフトウェアのデリバリーパフォーマンスの一面にとどまります。フードデリバリーと同じく、速く届くことと、価値あるものが届くことは別の話です。

この前提に立つと、Four Keysの見え方も少し変わってきます。

改めて、Four Keysは何を測っているのか

ソフトウェア開発のデリバリーパフォーマンスを測る指標として、Four Keys、および現在のDORA Metricsが広く知られています。

これは、継続的デリバリー(Continuous Delivery)が重視してきたソフトウェアデリバリーの能力を、計測可能な指標として捉えようとするものです。DORA Metricsを理解することは、継続的デリバリーが目指すものを理解することに直結します。

一方で、お客様と話しているとこんな声をよく耳にします。

「我々にはFour Keysのような計測手法はしっくり来ません。なぜなら、アジャイルみたいに何度もリリースしたりしないんです」

この疑問を考える前に、まずDORAが現在「ソフトウェアデリバリーパフォーマンス」をどう捉えているかを整理しておきましょう。

https://cdn-ak.f.st-hatena.com/images/fotolife/T/Taka_bow/20260525/20260525124147_original.png

DORAにおけるソフトウェアデリバリーパフォーマンスの構造

DORAは近年のレポートで、「ソフトウェアデリバリーパフォーマンス」を2つの軸に整理しています。

ひとつは「ソフトウェアデリバリースループット(software delivery throughput)」、つまり、スピードと効率性の軸です。次の3つで測ります。

  • 変更リードタイム(change lead time)
  • デプロイ頻度(deployment frequency)
  • デプロイ失敗時の復旧までの時間(failed deployment recovery time)

もうひとつは「ソフトウェアデリバリーの不安定性(software delivery instability)」、これは、品質と信頼性の逆指標(低いほど良い)です。次の2つで測ります。

  • 変更時の障害率(change failure rate)
  • やり直し率(rework rate)

旧来の「Four Keys」(2018年頃)はデプロイ頻度・変更リードタイム・変更時の障害率・サービス復旧時間の4指標でしたが、現在のDORAでは5指標を「スループット」と「不安定性」の2軸に整理し直しています。

この再整理は、DORAがソフトウェアデリバリーを単なる速さではなく、速さと不安定性の両面から捉えようとしていることを示しています。AI駆動開発によってコードの生成量や品質の傾向が大きく動くいま、この見方はますます重要になっています。

次に、これらの指標がSDLC(ソフトウェア開発ライフサイクル)上のどこに当てはまるのかを見てみましょう。

https://cdn-ak.f.st-hatena.com/images/fotolife/T/Taka_bow/20260524/20260524203053_original.png

DORA MetricsがSDLC上のどこに当てはまるかを示した図

この図でまず見てほしいのは、デプロイとリリースの位置関係です。デプロイはSDLC上のひとつのフェーズであり、リリース(図中の▼)はそのあとに位置します。

DORA Metricsのうち、頻度として測るのはリリース回数ではなくデプロイ頻度です。ここを取り違えると、「リリース回数が少ない自分たちにはFour Keysは合わない」という違和感が生まれます。

実際、デプロイとリリースをひとまとまりのイベントとして扱う現場も少なくなく、歴史の長い組織ほど、その傾向が根強い印象です。

しかし、DORA Metricsが見ているのは「ユーザーに何回公開したか」ではなく、「変更をどれだけ継続的に本番へ届けられているか」です。図の中でリリースが何度も登場している理由は、後の章「二つの意味を持つ『リリース』」で詳しく扱います。(ここではまず、DORA Metricsは「リリース回数」ではなく、変更をどれだけ速く、安定して届けられているかを捉える指標だと押さえてください。)

また、最近はAI駆動開発が広まるにつれて、こんな声も聞くようになりました。

「AI時代にFour Keysは合わないですよね」

この見方も、少し立ち止まって考える必要があります。

生成AIは、とりわけ実装・テストのフェーズを大きく速くします。さきほどの図で見たとおり、実装・テストはデプロイの手前にあります。ここが速くなれば、その変化は下流のデプロイや、DORA Metricsの「変更リードタイム」にも表れます。

もちろん、速くなるのは良い面だけではありません。

生成AIが出力したコードを鵜呑みにすれば、欠陥を見逃すリスクも高まります。その影響は、DORAがいう「ソフトウェアデリバリーの不安定性(software delivery instability)」(やり直し率や変更時の障害率)にも現れます。

つまり、生成AIはDORA Metricsを不要にするどころか、数値を大きく動かします。

だからこそ、DORA Metricsが何を測っていて、何を測っていないのかを理解する必要があります。その理解の出発点が、「デプロイ」と「リリース」の違いです。

次章では、Four Keysへの違和感を生みやすいこの混同を、もう少し丁寧にほどいていきます。

「デプロイ」と「リリース」の混同がFour Keysを遠ざける

Four Keysへの戸惑いは、AIが現れるよりも前からあります。

その大きな理由のひとつが、「デプロイ」と「リリース」という二語の混同だと思っています。まずは、この二つを分けておきましょう。

デプロイ(Deployment) リリース(Release)
意味 コードや設定を本番環境に反映する作業 機能をユーザーが実際に使える状態にする判断
性質 機械的・技術的(自動化が可能) ビジネス判断(公開タイミングをコントロール)
頻度 高頻度(日次・時間単位もありうる) 機能ごと・公開戦略次第

ところが、多くの現場ではこの二つが切り離されず、ひとつの大きなイベントとして扱われています。デプロイもリリースも「めったに行わない重い作業」になっていれば、Four Keysが自分たちとは無縁に見えてしまうのも当然の感覚です。

たとえば、ゲートキーパー型のQAを置き、「リリース判定会議」を経て本番に出す流れです。この場合、現場の感覚としては「リリース判定会議 → デプロイ」の順序に見えます。

昔のリリース候補マイルストンも、何ヶ月もかけて次の段階へ進めていく形でした。

flowchart LR
    A["プレアルファ版<br/>(pre-α)"] --> B["アルファ版<br/>(α)"] --> C["ベータ版<br/>(β)"] --> D["リリース候補版<br/>(RC)"] --> E["ゴールドリリース版<br/>ゴールデンマスター版<br/>(GM)"]

これは、ソフトウェアが物理パッケージで出荷されていた時代の名残でもあります。CD-ROMを焼き(書き込み)、紙のマニュアルを同梱して箱に詰める。バグが見つかればディスクの焼き直し、マニュアルにミスがあれば製本のやり直し⋯⋯手戻りは、時間とコストの両面で致命的なダメージでした。

しかし、時代は変わりました。高速なネットワーク、パワフルなPC、ストレージの大容量化、紙媒体の電子化⋯⋯やり方を過去のままにしておく理由は、もうありません。

それでもこの流れを前提にしていると、リリースとデプロイの適切なタイミング、順序、そして頻度の感覚は分からないままです。

この混同をほどき、「リリース」の二つの意味を分離する考え方を体系化したのが、Jez Humble氏とDave Farley氏です。

Humble氏はその後、DORAの設立メンバーとして、DORA Metricsの礎を築いていきました。今回は、もう一人の著者であるDave Farley氏にスポットを当てます。

Dave Farley氏とは

Dave Farley氏は、継続的デリバリーを語るうえで避けて通れない人物です。

https://www.infoq.com/images/profiles/d3g3wtOZD786r9wNCVgnorqQ8kZeZkz6.jpg?t=1734050734108
David(Dave) Farley(Image source: InfoQ.com)

Jez Humble氏との共著『Continuous Delivery』(2010、Jolt Award受賞)は、CI/CD、デプロイメントパイプライン、デプロイとリリースの分離といった考え方を広め、現代のソフトウェアデリバリーの前提をつくった一冊です。単著『Modern Software Engineering』(2021)でも、ソフトウェア開発をエンジニアリングとして捉え直す考え方を示しています。

DORA Metricsも、この継続的デリバリーの思想と地続きにあります。つまりFarley氏は、「継続的デリバリーの本を書いた人」にとどまらず、現在のソフトウェアデリバリーの議論そのものに影響を与えてきた人物です。

Farley氏の言葉に重みがあるのは、実践の現場でも大きな仕事を残してきたからです。

低レイテンシシステムの分野では、Duke Awardを受賞したオープンソースプロジェクト「LMAX Disruptor」に貢献しています。並行処理や高スループットの設計を語る場面で、いまも参照され続ける仕事の一つです。

さらに、応答性や回復性、弾力性を重視する「リアクティブシステム」の考え方を示したReactive Manifestoの共同執筆者でもあります。

近年はYouTubeチャンネル「Modern Software Engineering」(旧名Continuous Delivery)の主宰者として、世界中のエンジニアに継続的デリバリーやモダン・ソフトウェアエンジニアリングの考え方を発信し続けてきました。チャンネル登録者数は26万人を超えています。

www.youtube.com

英語圏のエンジニアにとっては、継続的デリバリーの代表的な書籍を世に出した人でありながら、いまもYouTubeを通じて最新のソフトウェアエンジニアリングを語り続ける存在です。

www.youtube.com

Farley氏は近年、DORA(DevOps Research and Assessment)の年次レポートにも参加しています。2022年は10人の著者の一人として、2023年は「継続的デリバリーの効用(Benefits of continuous delivery)」の章の執筆者および分野アドバイザーとして、2024年は分野の専門家として報告書に名を連ねています。

『Continuous Delivery』(2010) は何を変えたか

Jez Humble氏とFarley氏が2010年に出版した『Continuous Delivery: Reliable Software Releases through Build, Test, and Deployment Automation』は、何を変えたのでしょうか。

2010年当時、リリースは重く、失敗が許されないイベントとして扱われていました。本番投入の前には長い調整期間があり、変更はできるだけまとめて出すのが当たり前でした。

『Continuous Delivery』は、この前提を見直す考え方を示しました。

ここでいう「Delivery」は、ソフトウェアをいつでもリリースできる状態に保ち続けることを指します。デプロイ作業そのものや、ユーザー公開としてのリリースとは別の概念です。

主張の柱は、次の3つです。

  1. デプロイメントパイプラインという概念の提唱
  2. 「ソフトウェアを常にリリース可能な状態に保つ」という考え方
  3. 自動化の範囲を「統合(CI)」から「デプロイメント」まで広げたこと

これらは自動化の対象範囲を広げるとともに、ソフトウェア開発の文化にも影響を与えました。変更をまとめて重く出す形から、頻繁に小さく出して安定性を高める形へと、考え方が変わりました。

リリースは一大イベントではなくなり、デイリーないし時間単位の活動になりました。

こうした変化のなかで、「デプロイ」と「リリース」を分けて考える発想が広がりました。次章ではこの分離について詳しく見ていきます。

二つの意味を持つ「リリース」

「リリース」という言葉がややこしいのは、継続的デリバリーに取り組んでいるかどうかで、指しているものが変わるからです。

旧来のリリース管理では、「リリース」は本番投入に向けた承認・計画・調整を含む、大きなマネジメント上の区切りでした。リリース判定会議を経て、デプロイし、ユーザーに公開する。これら全体をまとめて「リリース」と呼んでいたのです。

flowchart LR
    A["リリース判定会議"] -- "判定OK" --> B
    subgraph Release["リリース"]
        direction LR
        B["デプロイ<br/>(手動)"] --> C["ユーザー公開"]
    end

一方、継続的デリバリーでは、このまとまりを分解します。デプロイは自動化された反映作業として高頻度に行い、ユーザー公開としてのリリースとは切り分けて考えます。

この文脈での「リリース」は、ユーザーが新機能を実際に使えるようになる瞬間です。つまり、先にデプロイしておき、後で公開判断によってリリースする、という順序になります。

flowchart LR
    A["デプロイ<br/>(自動)"] --> B["本番環境<br/>(まだ非公開)"]
    B -- "公開判断" --> C["リリース<br/>(ユーザー公開)"]

だから、「リリース → デプロイ」も「デプロイ → リリース」も、現場ではどちらも正しい言い方になりえます。問題は順序そのものではなく、それぞれの「リリース」が別の意味を指していることです。

この違いは、コンビニにたとえると分かりやすくなります。

  • デプロイ = 商品をバックヤードに搬入する作業
  • リリース = その商品を陳列棚に並べて、顧客が買えるようにする判断
flowchart LR
    Code["新商品<br/>(コード)"] --> Deploy(("デプロイ<br/>(機械的・高頻度)"))
    Deploy --> Backyard["バックヤード<br/>(本番環境)"]
    Backyard --> Release(("リリース<br/>(ビジネス判断)<br/>※Feature Flag"))
    Release --> Shelf["陳列棚<br/>(ユーザーに公開)"]
    Shelf --> Buy(("商品を選んで<br/>購入"))
    Buy --> Customer["顧客<br/>(ユーザー)"]

バックヤードに搬入すること(デプロイ)と、陳列棚に並べる判断(リリース)は、本来別々のものです。Jez Humble氏とFarley氏は『Continuous Delivery』で、この二つを意図的に分離する発想を提示しました。

  • デプロイは機械的な反映作業として、できる限り自動化し、高頻度に行う
  • リリースはビジネス判断として、機能の公開タイミングをコントロールする

この分離を支える代表的な仕組みが、フィーチャーフラグ(Feature Flag)、カナリアリリース、ブルーグリーンデプロイメントです。たとえばフィーチャーフラグを使えば、コードは本番環境に置いたまま、機能の有効/無効や公開対象を切り替えられます。

ただし、これらの仕組みにも限界はあります。データベースのスキーマ変更や外部サービスへの副作用を伴う処理では、設計や運用ルールも含めた備えが必要です。

具体的な運用例は、Findy Tech Blogの過去記事でも紹介しています。

tech.findy.co.jp

AI時代に、継続的デリバリーはなぜ重要になるのか

ここまで見てきたように、継続的デリバリーは単なる自動化の話ではありません。

変更を小さく保ち、素早くフィードバックを得て、いつでも安全にリリースできる状態を維持するための規律です。

Farley氏は『Modern Software Engineering』(2021)でも、開発そのものをエンジニアリングとして捉え直し、素早く学ぶことと複雑さを制御することの重要性を説いています。

変更を小さく保ち、素早く学び、複雑さを制御する姿勢は、AI時代にこそ重要になります。なぜなら、生成AIは変更を生み出す速度を上げる一方で、その変更が安全で価値あるものかどうかまでは保証しないからです。

生成AIは、速さの面でも品質の面でも、DORA Metricsの数値を動かします。その意味で、DORA Metricsは今も計測の出発点です。

一方で、動いた数値をこれまでと同じように読み解き、開発の良し悪しを判断することは難しくなりました。

DORA Metricsだけでは、「速く届いた先で、ユーザーにどんな価値が生まれたのか」までは見えないからです。

2025年のDORAレポートはAIを「増幅器(amplifier)」と呼び、その効果を引き出す組織側の条件を「AI Capabilities Model」として整理しています。

%%{init: {'flowchart': {'curve': 'linear'}}}%%
flowchart LR
    AI("AIの導入")
    MUL("×")
    subgraph CAP["7つのケイパビリティ"]
        direction TB
        C1("ユーザー<br/>中心の視点")
        C2("優れたバージョン管理<br/>プラクティス")
        C3("AIでアクセス可能な<br/>内部データ")
        C4("小さいバッチ<br/>単位の作業")
        C5("明確で周知された<br/>AIのスタンス")
        C6("質の高い内部<br/>プラットフォーム")
        C7("健全なデータ<br/>エコシステム")
    end
    subgraph OUT["アウトカム"]
        direction TB
        O1("チーム<br/>パフォーマンス")
        O2("コードの品質")
        O3("個人の有効性")
        O4("プロダクト<br/>パフォーマンス")
        O5("摩擦の低減")
        O6("スループット")
        O7("組織<br/>パフォーマンス")
    end
    AI ~~~ MUL
    MUL ~~~ C4
    C1 --> O1
    C2 --> O1
    C2 --> O3
    C3 --> O2
    C3 --> O3
    C3 --> O4
    C4 --> O3
    C4 --> O4
    C4 --> O5
    C5 --> O3
    C5 --> O4
    C5 --> O5
    C5 --> O6
    C5 --> O7
    C6 --> O5
    C6 --> O7
    C7 --> O7
DORAの「AI Capabilities Model」をもとに作成

冒頭のピザのデリバリー話に戻しましょう。

「速く届いた」ことと、「価値あるものが届いた」というアウトカムは、必ずしも一致しません。

DORA Metricsはあくまで「届けるまでの速さと安定性」を示すものです。ピザでいえば、配達時間だけでなく、配送中に崩れずに届いたか、問題が起きたときに素早く立て直せるかまで含めた指標に近いでしょう。大事な指標ですが、それだけでは「届いたあと、ユーザーや事業にとって何が起きたか」までは見えません。

DORAは2025年のレポートで、まさにこの「ユーザー側に何が届いたか」を主役に据えました。

AI Capabilities Modelの7つのケイパビリティ(上の図)のひとつに「ユーザー中心の視点(User-centric focus)」を掲げ、AIを「正しい方向」に効かせるための北極星(North Star)と位置づけています。

チームがアウトプット(出荷した機能の数や速度)を追うばかりで、ユーザーに届いたアウトカムを見失うと、AIは「フィーチャーファクトリー(機能量産工場)」を加速させます。

活動量は多くてもインパクトの出ない状態に陥る、とレポートは警告しています。

DORAの調査では、ユーザー中心の視点が欠けたチームではAIを導入するとチームパフォーマンスにマイナスの影響さえ及ぼす、と報告されています。一方、ユーザー中心の視点を持つチームでは、AIがプラスの影響を大きく増幅すると報告されています。

生成AIでデリバリーがさらに速くなる時代だからこそ、速さの先にあるユーザー側のアウトカムを見失わないことが、これまで以上に重要です。

AI駆動開発を空回りさせないために

「デプロイ」と「リリース」の混同は、用語の取り違えにとどまりません。AI駆動開発を進める組織にとっては、そのままリスクの増幅につながります。

日本のソフトウェア開発現場でも、「リリース=大イベント」「デプロイ=リリース当日にやる作業」という理解が、いまだに根強く残っています。

『Continuous Delivery』の日本語訳は2012年に出版されました。

それから14年が経ったいまも、継続的デリバリーの重要な概念的貢献である「デプロイとリリースの分離」は、少なくとも日本の多くの現場で十分に共有されているとは言えません。

継続的デリバリーを実践している組織では当たり前に使われる "Deployment ≠ Release" という整理が、日本の現場ではいまも「同じこと」として語られがちです。

Farley氏は2021年の『Modern Software Engineering』で、誤った考えが根強く残る理由をこう書いています。

間違った考え方をなかなか捨てられない理由のひとつは、ソフトウェア開発のパフォーマンス(能力、業績)を効果的に計測できていないことにあります。

Farley, D.(2022), 長尾高弘 (訳). 継続的デリバリーのソフトウェア工学: もっと早く、もっと良いソフトウェアを作るための秘訣 (Nagao, T., Trans.). 日経BP社. (Original work published 2021) p.70

デプロイとリリースを分離できれば、デプロイの頻度を上げながら、機能の公開タイミングは別途コントロールできます。

逆に、分離できなければ、リリース=デプロイ=大イベントの連鎖から抜け出せません。

いまも日本の多くの現場は、「動いているコードには触れるな」という考え方の延長線上にあります。

Farley氏は同書で、こうも指摘しています。

私の印象では、ソフトウェア産業は学ぶことも進化することもなかなかできないで苦闘しているように見えます。この相対的な停滞は、コードを実行するハードウェアのとてつもない進化によって見えなくされているのです。

Farley, D.(2022), 長尾高弘 (訳). 継続的デリバリーのソフトウェア工学: もっと早く、もっと良いソフトウェアを作るための秘訣 (Nagao, T., Trans.). 日経BP社. (Original work published 2021) p.69

2021年のこの指摘は、いまの生成AIにもそのまま当てはまります。生成AIは、変更を大量に、しかも高速に生み出します。

だからこそ、問われているのは「AIでどれだけ速く作れるか」だけではなく、作られた変更を、小さく、安全に、継続的に届けられるか、つまり「開発資本」を組織として持てているかです。

デプロイとリリースを切り分ける土台がなければ、AIは変更の速度だけでなく、リスクも増幅します。DORA Metricsの数値が動いても、それだけではAIが良い方向に働いているかは判断できません。

https://cdn-ak.f.st-hatena.com/images/fotolife/T/Taka_bow/20260524/20260524225256_original.png

技術的発展の階層構造。これらの土台作りが重要。

ここでいう「継続的デリバリーができない」は、単にデプロイ自動化がないことではなく、変更を小さく保ち、デプロイとリリースを切り分け、ユーザーへの影響を制御しながら継続的に届ける仕組みがない状態を指します。

「デプロイ」と「リリース」の混同に、「フィーチャーファクトリー」の罠が重なれば、AI駆動開発はいくら進めても成果に届きません。継続的デリバリーができない組織で、AIは増幅器(amplifier)として空回りを生むのです。

まずは、自チームで「デプロイ」と「リリース」をいまどう区別しているのかを言語化してみてください。境界がぼやけているなら、それ自体が改善の第一歩になります。

【告知】AI DevEx Conference 2026 - Future of Development Productivity -

継続的デリバリーとAI時代のソフトウェア開発について、Farley氏本人の言葉で聞ける機会があります。

AI DevEx Conference 2026で、Farley氏が初めて日本に登壇します。

開催概要は以下のとおりです。

項目 内容
開催日時 2026年7月22日(水)・23日(木)9:30〜18:40
開催形式 オフライン・オンライン配信(要事前登録)
チケット 現地参加チケット(アーリーバード第2弾) ¥3,000(税抜)※締切日:5月27日(水)
現地参加チケット ¥5,000(税抜)
オンライン(無料)
開催場所 JPタワーホール&カンファレンス(東京・丸の内)
申込URL https://dev-productivity-con.findy-code.io/aidevex2026
主催 ファインディ株式会社
対象者 DevExやソフトウェア開発の改善に関心があるエンジニアやマネージャー、経営者など

Farley氏は、初日の7月22日に次のテーマで登壇します。

「AIと共存する世界のソフトウェアエンジニアリング ─不変の本質とプログラミングの未来」

AIと共存する時代に、より良いソフトウェアをより速く作るためには何が必要なのか。この記事で扱ってきた継続的デリバリーやエンジニアリングの話とも、まっすぐつながるテーマです。

このほか、t_wadaさんこと和田卓人氏や、「DevEx」の第一人者であるEirini Kalliamvakou氏も登壇予定です。DeNA、Uber、Citibank、LinkedInなど、国内外50社以上が登壇します。

ぜひご参加ください!

おわりに

ファインディでは一緒に会社を盛り上げてくれるメンバーを募集中です。興味を持っていただいた方はこちらのページからご応募お願いします。

TSKaigi 2026に協賛・参加しました 〜TypeScriptエコシステムのNative化を感じた注目セッション〜

こんにちは!ファインディの大石(@bicstone)、甲斐(@karukan013L23)、千田(@_c0909)です。先日、ファインディはベルサール羽田空港で開催された「TSKaigi 2026」に協賛しました。

今回はDevRelメンバーとフロントエンドエンジニア3名で参加し、ブース運営を行いました。本記事ではTSKaigi 2026において印象深かったセッションの紹介や登壇、ブース出展などの活動内容を紹介します。

ブースで実施したユーティリティ型アンケートの集計結果(480票)も後半で公開していますので、ぜひ最後までお読みください。

TSKaigi 2026について

TSKaigiは日本最大級のTypeScriptをテーマとした技術カンファレンスです。東京都大田区のベルサール羽田空港にて、2026年5月22日(金)〜23日(土)に開催されました。

2026.tskaigi.org

印象深かったセッション

興味深いセッションが多くありましたが、その中でも3名それぞれが印象に残ったセッションを紹介します。

【大石】TS 7: How We Got There

2026.tskaigi.org

TypeScriptチームのJake Baileyさんによる、TypeScript 7をGo言語へ移植した経緯と成果についての基調講演です。

特に印象的だったのは、Goを採用した理由を体系的に知ることができた点です。

JavaScriptではスレッド間でオブジェクトを共有できず、async/awaitが関数全体に伝播してしまうため、並列化が困難でした。

Goのgoroutineを活かすことで、Parse・Bind・Emitの各フェーズを並列化し、Checkerも複数並べることで高速化を実現しています。

VS Code (Electron) のプロジェクトをtsctsgoそれぞれで実行した際の所要時間とCPU使用率の差を見せていただいたデモでは、マルチスレッドの活用やCPU使用率の変化が一目で分かり、なぜ大幅な高速化を実現できたのか直感的に理解できました。

発表のなかで繰り返し強く呼びかけられていたのが、コミュニティからのフィードバックでした。「ぜひbetaやnightlyを試してほしい」「VS CodeのNative Preview拡張を入れてほしい」「クラッシュやコンパイル挙動の変化、特にAPIへの意見を送ってほしい」と呼びかけていました。

過去1年でコミュニティから1141件のIssueと1487件のマージ済みPRが寄せられ、テレメトリ経由のクラッシュ情報も含め、利用者からの報告が開発の方向性を支えていることが伝わってきました。

私たちのチームでは、すでにコミット時のフックでtsgoを試験的に採用しています。今後は開発フロー全体への導入を進めながら、検知した問題は積極的にフィードバックを送っていきたいです。

ファインディでも従来からOSSへのIssue起票やPull Requestの作成、メディア企画を通じた寄付などの形で支援を続けてきましたが、TypeScriptのように多くの利用者を抱えるプロジェクトでは、利用者一人ひとりの報告こそが大きな貢献になることを再認識しました。

これまで断片的にしか追えていなかったTypeScript 7について体系的に理解でき、とても学びの多い発表でした。社内にもぜひ共有していきたいと思います。

【甲斐】tscからtsgoへ ── DenoのTypeScript基盤はどう変わったか

2026.tskaigi.org

Denoのmaguroさんによる、DenoのTypeScript基盤をtscからtsgoへ移行する取り組みについてのセッションです。

元々DenoはTypeScriptをフォークしたパッケージを使用し、Deno Rust側と必要な情報をやり取りし、Deno固有の概念をtscが解釈できるよう、tscにパッチを当てたものをDeno binaryの中に埋め込んでいました。

tsgoへの移行の最初のアプローチはtsgoをフォークし、Deno固有の概念をtsgoに渡せるようにするアプローチでした。

tsgoはDeno固有の概念をそのまま解決できないため、Deno Rust側で処理できるよう対応しています。LSP対応のコスト、フォークしたパッケージのメンテナンスコストが高く、現在はフォーク版ではなく公式のTypeScriptパッケージを利用するアプローチが試みられています。

TypeScript向けにDenoの依存と型をローカル生成することで、パッチを当てずにDeno固有の概念を解釈できる構成にしています。

特に印象的だったのは、DenoのWeb標準の哲学を少し曲げてでもTypeScriptで扱える形に寄せていった点です。Deno binaryの中→Deno binaryの外→Deno projectの外へTypeScriptパッケージが押し出されており、フォークによる運用コストの増加を避けつつ実行可能なアプローチをとっています。

型チェックを使用したい他のライブラリも同様にフォーク以外の選択肢を模索しており、方向性は同じだがそれぞれ異なるアプローチになっていることが興味深かったです。

普段Denoは使用していませんでしたが、現在の形に辿り着くまでにどのような意思決定があったかを見ていくことで、ここに至るまでの課題や意思決定ごとのトレードオフを学ぶことができ、現在の思想を理解する助けとなりました。

今後もツールチェーンやライブラリの意思決定の背景を学ぶ機会を定期的に設けていきたいなと思います。

【千田】Oxlint は ESLint / typescript-eslint を置き換えられるか?

2026.tskaigi.org

株式会社うるるの藤田翔雅さんによる、OxlintがESLint / typescript-eslintをどこまで置き換えられるのかを整理したセッションです。

特に印象的だったのは、Type-Aware Linting(型情報を使ったLint)の有無でパフォーマンスが大きく変わる点をベンチマークで示していたことです。

型情報を使わない比較ではESLintの8.213秒に対しOxlintは0.304秒と約27倍速く、型情報を使うルールを有効にしてもESLintの16.121秒に対しOxlintは0.807秒と約20倍速いという結果でした。

型情報を使わないLintが構文解析だけで完結するのに対し、型情報を使うLintはプロジェクト全体の型グラフ構築(tsc/tsgo)を必要とするためボトルネックになる、という構造的な解説も理解の助けになりました。

導入判断についても踏み込んでおり、型情報を使わないLintであればOxlintは主要ルールを十分カバーしており移行は現実的である一方、oxlint-tsgolintによるType-Aware Lintingはまだ非安定版であること、カスタムルールを抱えるプロジェクトでは移行コストが上がることなど、現場目線のトレードオフが具体的に語られていました。

結論として、非Type-Aware LintingであればOxlintへの移行を推奨するというメッセージが明快でした。

私たちのチームでもESLint + Prettierを利用しており、CIの実行時間は継続的な課題です。すでにOxc系(Oxlint + Oxfmt)への移行を計画しており、既存のプロダクトはType-Aware Lintingに依存しない構成となっています。

本セッションの「非Type-Aware LintingならOxlint移行を推奨」という結論は私たちの状況に当てはまり、実際の移行計画に重ねて考える良い機会になりました。

【大石】CfP登壇: TypeScript 6.0での型推論修正を追う

当日のCfP枠では、大石が「プロパティの順序で型推論が壊れる!? TypeScript 6.0の修正からContext-Sensitivityの仕組みを追う」というタイトルで登壇しました。

プロパティの記述順序を入れ替えるだけで型推論が壊れる挙動を入口に、TypeScript 6.0でマージされたPRの中身まで踏み込んだ内容です。詳細は別記事にまとめていますので、あわせてご覧ください。

tech.findy.co.jp

speakerdeck.com

ファインディの活動

ファインディはGoldスポンサーとして協賛し、ブース出展という形で支援しました。

ブースでは「よく使うユーティリティ型」をテーマにしたアンケート企画を実施しました。普段の開発でよく使うユーティリティ型を選んでいただく内容で、2日間かけて多くの方に投票いただきました。

x.com

アンケートの最終結果はこちらになります。たくさんの投票ありがとうございました。

x.com

アンケート結果

総数:480票

順位 ユーティリティ型 割合 票数
1位 Record<Keys, Type> 33.3% 160票
2位 Pick<T, Keys> 17.7% 85票
3位 Readonly<T> 14.6% 70票
4位 Partial<T> 9.4% 45票
5位 ReturnType<T> 8.8% 42票
6位 Exclude<T, U> 4.2% 20票
7位 Extract<T, U> 2.5% 12票
8位 NonNullable<T> 2.5% 12票
9位 Awaited<T> 1.0% 5票
- その他 6.0% 29票

その他内訳

ユーティリティ型 票数
その他・使っていない 22票
Omit<T, Keys> 5票
Beautify<T> 1票
&| 1票

加えて、マーケティング担当のメンバーがAIを活用して自ら開発したルーレットアプリと、ファインディオリジナルのノベルティをご用意し、立ち寄っていただいた方に楽しんでいただきました。

さいごに

セッションは多岐にわたるなかで、私たちが特に注目したのはGoによるコンパイラの再実装(コンパイラ本体のネイティブ化)、tscからtsgoへの基盤刷新(他ランタイムによる採用)、Rust製Linterの可能性(周辺ツールへの波及)でした。

3つを通して、TypeScriptエコシステムがNative実装へと動いている流れを実感する2日間となりました。TSKaigiはとても温かい素敵なコミュニティで、いち参加者としても多くの学びと交流の機会を得ることができました。

カンファレンスの開催にあたりご尽力いただいた、運営スタッフの皆様、関係者の皆様、登壇者の皆様に感謝申し上げます。

お知らせ

同日参加したファインディのDevRelメンバーによるレポート記事も公開されています。あわせてご覧ください。

note.com

TSKaigi 2026のアフターイベント「TSKaigi Night talks 〜after conference〜」をスポンサー企業9社で共催します。当日のCfP枠で採択されなかった知見もコミュニティへ還元することを目的としたイベントです。

ファインディからは千田が「OSSのUIライブラリでESLintのカスタムルールを作っている話」、甲斐が「Temporal - TypeScript 6.0で始める新しい日時API」というテーマで登壇予定です。

2026年6月10日(水)19:00から、ファインディのイベントスペースにて開催します。TSKaigi 2026に参加された方も、参加できなかった方も、ぜひお越しください。

findy.connpass.com

ファインディでは一緒に働くメンバーを募集しています!

興味がある方はこちらから ↓ herp.careers

経験1年のエンジニアでも、新規プロダクトのEmbedded SREに初挑戦できた理由 — 仕組みと個人の学習で踏み出す

はじめに

こんにちは、ファインディ株式会社でエンジニアをしている中嶋(@nakayama__bird)です。現在は、新規プロダクトであるFindy Contextの開発に携わっています。

ファインディでは、これまでSREチームが担っていた新規プロダクトのクラウド環境の構築から監視体制の整備までを、プロダクト開発チーム主体で行う体制に切り替えました。 本記事では、私自身がFindy Contextの環境立ち上げを担当した経験を、アプリケーションエンジニアの視点で振り返ります。

経験の浅いエンジニアにとって、0→1のクラウド環境構築は不安の大きい領域です。「自分にできるのか」と思いながら着手した私が前に進めたのは、「SREチームが整えてくれた仕組み」と「自分で進めた学習」、その2つが揃っていたからでした。 それぞれがどう機能したかを、これから体験ベースでお伝えします。

Findy Contextとは

Findy Contextは、ファインディが2026年4月にリリースしたAI駆動開発支援プロダクトです。 プロダクト開発で日々生まれる文脈(過去のPR、関連議論、意思決定の経緯)をAIが資産化し、開発の調整コストを削減することを目指しています。

Findy Contextが目指すのは、特定の個人に依存せず、少人数でも高い開発能力を維持できる組織運営です。 あちこちに散らばっていた判断のプロセスを蓄積していくことで、組織の経験を資産として再活用できる土台を作っていきます。

findy.co.jp

このFindy Contextの本番運用基盤を、なぜSREチームではなく開発チームが主体で構築することになったのか。その背景から振り返ります。

背景: なぜ開発チーム主体に切り替わったのか

これまでの体制

ファインディにはSREチームが存在し、共通インフラやプラットフォームの運用、汎用モジュール・テンプレートの整備、セキュリティ・コスト最適化など、全社横断の取り組みを担っています。 インフラはTerraformでコード管理されており、SREチームが提供する汎用モジュールやテンプレートもTerraformで書かれています。オブザーバビリティの基盤としてはDatadogを採用しています。

また、既存プロダクトでは、プロダクトの一部メンバーがEmbedded SREとして、次のような役割を担っています。

  • アプリケーション開発に必要なインフラの整備・管理
  • モニタリングの整備
  • SLOの振り返り

一方、新規プロダクトの立ち上げに関しては運用が異なっていました。 SREチームが環境を構築し、ある程度の運用準備を整えてからプロダクト開発チームに引き渡す形が基本でした。

直近の事情の変化

ここ1〜2年で、事業成長や生成AIの追い風もあり新規プロダクトの立ち上げ件数が大きく増えたことで、これまでの体制で支えられる範囲を超えつつありました。 一方で、SREチームの人員を急に増やすことは難しく、既存プロダクトの運用や全社横断の取り組みも並行して走り続けています。新規プロダクトすべての環境構築をSREチームが担う体制は、現実的に維持できなくなりつつありました。

方針転換: 開発チームメインの立ち上げへ

そこで、新規プロダクトの立ち上げ〜運用フェーズを、プロダクト開発チームが主体となり、SREチームがイネーブリングを担う体制へと切り替わりました。

これは、「開発側にオーナーシップを置く」というEmbedded SREの発想を、新規プロダクトの立ち上げフェーズにも広げた形と言えます。 SREチームが整備した汎用モジュール・テンプレート・イネーブリング体制を活用して、開発チームが自分たちの責任で立ち上げる。Findy Contextの立ち上げは、この新方針の第一弾として位置付けられたプロジェクトでした。

着手前の筆者スペック

未経験からファインディに入社し、当時は経験1年のエンジニアでした。業務の中でAWSの一部サービスを使うことはあっても、新規プロダクトの基盤として複数のサービスを組み合わせて構築した経験はありませんでした。0→1のクラウド環境構築は今回が初めてです。

そんな中、Findy ContextのEmbedded SREとして配置されることになりました。 開発チーム主体で環境構築を進める新方針のもと、その構築をメインの担当者として進めてほしいと依頼されました。 着手当初はそもそも「何から手をつければいいのか」が分からない状態でした。設計の手順も、優先順位も、判断基準が自分の中にありませんでした。

委譲のスコープと私が担当した範囲

まず、SREチームと開発チームの担当範囲を整理しておきます。

領域 SREチームが担当 開発チームが担当
AWSアカウント Organizations管理 アカウントの発行、発行後の初期設定
インフラリソース(ネットワーク・アプリケーション基盤) 共通方針、汎用モジュール・TerraformのCI/CDテンプレートの整備 汎用モジュールを使ったリソース構築(足りないものは個別作成)、CI/CD設定
監視(Datadog) Datadogの管理 ダッシュボード・モニター作成、運用

開発チームが引き受けた範囲は、SREチームが整備してくれた仕組みを使って自分たちで構築する、という形でした。

今回のFindy Contextの環境構築は、約2ヶ月をかけて、主にSREチームが事前に分解してくれた作業を順に消化する流れで進めました。ここからは、その流れを4つのフェーズに分けて振り返ります。

AWSアカウント発行とインフラ構築基盤整備

最初のフェーズは、Findy Context用のAWSアカウントを作り、Terraformで管理する基盤を整える作業でした。次のようなタスクです。

  • 新規AWSアカウントの作成
  • HCP TerraformへのProject作成
  • Terraform用のGitHub Actionsワークフロー作成

ファインディには、SREチームが整備した初期セットアップ用のテンプレートがあり、Terraform用リポジトリの初期化はこのテンプレートで一気に進められました。 CI/CD・Docker・Trivy・TFLintなど、新規プロダクトに必要な基盤が一式揃った状態でスタートできます。

それでも詰まったのは、GitHub ActionsからAWSへのOIDC認証の設定でした。 Identity ProviderやIAM Roleの信頼ポリシーといった、IAM周りのポリシー理解が必要になります。IAMポリシーの仕組みをこれまで触る機会がなく、何をどう書けば期待通りの認証が通るのかが最初は全く分かりませんでした。

乗り越え方は、既存プロダクトのTerraformリポジトリを参考に、動いている設定を「型」として読み解くことでした。 特に初期は、SREチームの方と毎日ペアで作業する時間を持ち、レクチャーを受けたり質問を重ねたりしながら、自分の中に手順のイメージを作っていきました。

インフラリソースの構築

ここからが、Findy Contextのインフラを実際に組み立てるフェーズです。約1ヶ月かけて、次のようなリソースを順に構築していきました。

  • ドメイン / DNS Zone / 証明書(ACM)
  • ネットワーク(VPC・サブネット等)
  • コンテナ関連(ECSなど)
  • データベース関連(RDSなど)
  • 認証(Cognito)
  • 配信(CloudFront)

ここで強く助けられたのが、SREチームが整備した汎用モジュールです。汎用モジュールの整備については、別の記事で詳しく紹介されています。

tech.findy.co.jp

ネットワーク・コンテナ・データベースなど、アプリケーション開発で標準的に必要なリソースは汎用モジュールが用意されており、変数を指定するだけで適切な構成が組み上がります。 「ベストプラクティスを毎回ゼロから調べる」必要がない状態でスタートできることは、学習コストを大きく下げる効果がありました。

それでも詰まったポイントが2つありました。

1つ目は、汎用モジュールにないリソースの作り込みやレビューです。Findy Contextでは、まだ汎用モジュール化されていないリソースを複数扱う必要がありました。 作成だけでなくレビューも、構成のイメージが頭の中にないと判断が難しく苦労した部分でした。AWS公式ドキュメントに加え、Claudeを活用して疑問に思った箇所を一つずつ理解していくアプローチで進めました。

2つ目は、リポジトリ構成とリモートステートの設計です。新規のリソースを作成する際、AWSのサービスごとに細かくstateを分割しようとしていたところ、SREチームから「リモートステートを多用しすぎない設計」をお勧めされました。 stateを分けるほど依存関係が複雑化し、apply順や terraform_remote_state の管理コストが増えるためです。アプリケーションエンジニア側のみで進めていたら気付けなかった視点で、SREチームのレビューを受けながら進められた価値を強く感じました。

デプロイと運用の整備

インフラリソースが揃ったら、次はアプリケーションをデプロイし、運用できる状態にするフェーズです。デプロイ用ワークフローの作成、Operationコンテナ環境の整備、Cognitoとアプリケーションの繋ぎこみなどを進めました。

ここで助けになったのは、既存の他プロダクトでしっかり整備されていたCI/CDフローでした。

tech.findy.co.jp

デプロイの流れもOperationコンテナの構成も、基本的に「ゼロから設計する」のではなく「動いているフローを参考にする」アプローチで進められたのです。

SREチームと既存プロダクトを担当するエンジニアの両方に相談しながら、Findy Contextの構成に合わせた設計を組み立てていきました。

監視(Datadog)の整備

環境構築のクローズ後、別途取り組んだのが監視体制の整備です。Datadogでのダッシュボード作成、モニター(アラート)設定、ログ・メトリクスの収集設計、エラー検知の整備などを進めました。

SREチームが整備したDatadog基盤のおかげで、「Datadog自体をどう使うか」は迷わずに進められました。

このフェーズで一番大きな気付きは、監視や可視化はインフラ側だけでは完結しないということです。 例えばログ・エラー検知の領域です。エラーを正しく追跡できるようにするには、アプリケーション側で例外ハンドリングの設定を見直す、ログの出し方を整える、といった作業が必要でした。 「Datadogでエラーが見えない」という現象の根本原因が、Datadogの設定ではなくアプリケーションコード側にあるケースがありました。

詰まったポイントは2つです。

1つ目は、アラートの閾値とチューニングです。「何を、どの値を超えたらアラートを出すべきか」は、各サービスや時期に応じて判断が必要で、最初は誤検知が頻発したり、逆に本来検知すべき異常を見逃したりしながら調整を重ねました。

2つ目は、ダッシュボード設計とアプリ側のログ整備です。「何を載せるか、載せないか」「どんなログをどう出せば後で追跡できるか」は、メトリクスやログの選定だけでなく、アプリケーションの実装と表裏一体でした。 SREチームや既存プロダクトを参考にしつつ、Findy Contextのコードにも並行して手を入れていきました。

監視整備は、「インフラだけ知っていればよい」という認識を一番大きく崩した経験でもありました。可視化の基盤として、アプリケーション側の知識が必要だと、身をもって学んだフェーズです。

個人として取り組んだこと

ここまで「仕組みが整っていた」という話を中心にしてきましたが、それだけで踏み出せたかというと、そうではありません。仕組みを活かすには、自分側でも一定の準備が必要でした。

私が並行して取り組んだのは、AWS認定ソリューションアーキテクト アソシエイト(SAA)の取得でした。 試験勉強の中ではAWS公式の「AWS Hands-on for Beginners」も活用し、書籍だけでは身につきにくい「実際にコンソールを触ってリソースを作る」感覚も合わせて身につけました。

SAAを通して、実際の業務で使うサービスだけでなく、AWSの主要サービスとアーキテクチャパターンを体系的に学べたことで、知識の幅が広がりました。 例えばコスト最適化のように、業務で直接深掘りしていない領域でも、「ここはもう一歩改善できそう」という気付きを得られる引き出しが増えた感覚があります。

「環境が整っていれば誰でも自走できる」わけではなく、整った環境を活かすための準備として、自分の側に基礎知識のストックを作ることが、踏み出す上で大きな支えになりました。

今後の伸び代

今回の構築で見えてきた、自分側と仕組み側の伸びしろを書いておきます。

自分側

複数リポジトリにまたがるサービスならではのオブザーバビリティ設計です。 Findy Contextは複数リポジトリで構成されており、1リクエストが複数サービスを跨ぐ場合の追跡や、ログ・メトリクスの相関付けには、まだ改善の余地があります。 Datadog APMなどを活用しながら、どう設計していくかは今後の課題です。

仕組み側(汎用モジュール・テンプレートへの改善余地)

ここまで書いてきたとおり、SREチームが整備してくれた汎用モジュールやテンプレートには、非常に大きな価値を感じています。その上で、実際に使ってみて感じた「もう一歩テンプレート化されると嬉しい」領域も挙げておきます。

初期セットアップ(AWSアカウントの発行 → OIDC認証 → Terraform / GitHub Actionsの初期構成)の部分は、想像以上に時間がかかった領域でした。 中核のリソース構築は汎用モジュールのおかげで早く進められた一方で、初期のアカウント・認証まわりは、まだ個別対応の比率が高めだと感じました。

ここがもう一段テンプレート化されると、次に立ち上げる新規プロダクトの初動はさらにスムーズになりそうです。

まとめ

Findy Contextのクラウド環境立ち上げを通して、最も強く感じたのは、「仕組み」と「個人の学習」の両方が揃って初めて、経験1年のエンジニアでも0→1に踏み出せるということでした。

仕組み側(SREチーム)が整備してくれた汎用モジュール、テンプレート、既存プロダクトの参考実装、相談しやすいサポート体制など、これらがなければ「何から手をつけるか」の段階で長く立ち止まっていたはずです。 一方で、SAAを通した体系的な学習や、ハンズオンでの実機感覚がなければ、整った環境を活かしきれなかったとも感じます。

仕組み側の整備は、開発者の「やってもらう」マインドを「自分たちでやる」オーナーシップへと自然に切り替えてくれる装置でもあります。 SREの開発チームへの委譲は、人手不足への対応策にとどまらず、開発組織全体のスキルと当事者意識を底上げする取り組みになりうると感じました。

自社で似た取り組みを検討している方や、キャリアの早い段階で挑戦を考えているエンジニアの方の参考になれば嬉しいです。


ファインディでは一緒に会社を盛り上げてくれるメンバーを募集中です。興味を持っていただいた方はこちらのページからご応募お願いします。

herp.careers

プロパティの順序で型推論が壊れる!? TypeScript6.0の修正からContext-Sensitivityの仕組みを追う

こんにちは。ファインディでフロントエンドエンジニアをしている大石(@bicstone)です。

2026年5月22日〜23日に開催されるTSKaigi 2026で、「プロパティの順序で型推論が壊れる!? TS6.0の修正からContext-Sensitivityの仕組みを追う」というタイトルで登壇します。本記事は10分のトーク内では時間の都合で端折った内容も含めた拡張版としてお届けします。

2026.tskaigi.org

TypeScriptでオブジェクトリテラルにメソッドを書いたとき、プロパティの記述順序を入れ替えただけで型推論の結果が変わるとしたら、どう感じるでしょうか。「そんな不思議な挙動があるのか」「気になるけどTypeScript内部のソースコードは難しそうで自分には縁がない」と思った方もいるかもしれません。

この記事では、この不思議な挙動を入り口にしてTypeScriptコンパイラの中で何が起きているのかを1つのPRから追いながら解説します。

背景: プロパティの順序で型が変わる

次のtest関数を見てください。型パラメータTを持ち、2つのプロパティabを受け取ります。

function test<T>(options: {
  a: (c: T) => void;
  b: () => T;
}) {}

次の2つの呼び出しは、プロパティの記述順序が違うだけです。しかし、TypeScript 5.9以前では、この2つの結果は異なります。

test({ b() { return 123 }, a(c) { return c } });  // c: number
test({ a(c) { return c }, b() { return 123 } });  // c: unknown

プロパティの順序を入れ替えただけでcの型がnumberからunknownに変わります。

手元で挙動を確認したい場合は、TypeScript Playgroundを開いてみてください。cをホバーするとunknownが表示されるはずです。

アロー関数なら問題ないのはなぜか

一方、同じコードをアロー関数で書き換えると、順序に関係なく推論が通ります。

// アロー関数は、どちらの順序でもc: number
test({ a: (c) => { c }, b: () => 123 });  // c: number
test({ b: () => 123, a: (c) => { c } });  // c: number

メソッド構文では順序に依存するのに、アロー関数では依存しない。この差はどこから来るのでしょうか。

答えはTypeScriptの型推論パイプラインにおけるContext-Sensitive Functionという考え方にあります。

Context-Sensitive Functionの考え方

Context-Sensitive Functionとは、型注釈のないパラメータを持つ関数のことです。パラメータの型を決めるために、外部のコンテキストが必要になります。

// context-sensitive:
(c) => c          // cの型がわからない → 外部に依存

// context-sensitiveでない:
(c: number) => c  // cの型が明示されている
() => 123         // パラメータがない

TypeScriptの型推論において、context-sensitiveな関数は特別扱いされます。推論の過程で「後回し」にされるのです。

なぜ後回しにする必要があるのでしょうか。次のコードで考えてみます。

function callFunc<T>(callback: (x: T) => void, value: T) {}

callFunc(x => x.toFixed(), 123);
//       ^                 ^^^
// xの型を知りたい        Tの情報源

callbackの引数xの型を決めるにはTが必要です。しかしTを推論するためにはcallbackの情報も必要です。鶏と卵の問題が発生します。

TypeScriptはこれを解決するために、context-sensitiveな関数(ここではcallback)をいったんスキップし、他の引数(ここでは123)から先にT = numberを推論します。その後、callbackに戻ってx: numberを確定させます。

推論の全体像

TypeScriptのジェネリック関数における型推論は、おおまかに次の流れで行われます。

  1. 引数を走査し、context-sensitiveな関数を特定する
  2. context-sensitiveな関数をスキップする
  3. 残りから型パラメータTを推論する
  4. 確定したTで後回しの関数のパラメータを型付けする

ステップ2で全ての関数がスキップされてしまうとTを推論するソースがなくなります。その場合、TypeScriptはフォールバック処理に入り、左から右の順番で処理を試みます。

メソッド構文に隠れている暗黙のthisパラメータ

メソッド構文で書かれた関数は、暗黙のthisパラメータを持ちます。

// メソッド構文
{ a(c) { return c } }
// ↓ TypeScriptの内部的な解釈
{ a(this: ???, c: ???) { return c } }
//  ^^^^ 暗黙のthis → 型注釈なし → context-sensitive

thisパラメータには型注釈がないため、TypeScriptはこの関数をcontext-sensitiveと判定します。thisを実際には使っていなくても、存在するだけでcontext-sensitiveになってしまいます。

一方、アロー関数はthisパラメータを持ちません。

// アロー関数
{ a: (c) => c }
// → thisパラメータなし
// → cだけが未注釈のパラメータ

この差が、メソッド構文とアロー関数で推論の挙動が異なる根本的な原因です。

両方スキップで起こる順序依存の正体

冒頭の例に戻りましょう。

test({ a(c) { return c }, b() { return 123 } });

aが先に書かれている場合、推論パイプラインでは次のように処理されます。

  1. a(c) → 暗黙のthis → context-sensitive → スキップ
  2. b() → 暗黙のthis → context-sensitive → スキップ
  3. 両方スキップ → Tを推論するソースがない
  4. フォールバックとして、左 → 右の順番で処理を試みる
  5. a(c)を先に処理 → Tが未確定 → c: unknown

bが先に書かれていた場合はどうなるでしょうか。

  1. 同じく両方スキップされる
  2. フォールバックとして、左 → 右の順番でb()を先に処理
  3. b()の戻り値123からT = numberを推論
  4. a(c)T = numberを適用 → c: number

これがプロパティの順序で型が変わる原因です。フォールバック処理が左 → 右の順番で行われるため、どちらのプロパティが先に書かれているかが推論結果を左右していました。

今回の修正を読み解く

この問題を修正するTypeScriptのPR #62243はAndarist氏によって実装され、2025年12月にマージされました。

github.com

thisを実際に使っていない関数は、context-sensitiveと見なさない、という修正が実施されました。

この変更は3つのファイルにまたがっています。

ファイル 役割 変更内容
binder.ts フラグを立てる 関数内のthis使用を追跡し、ContainsThisフラグを設定する
utilities.ts 判定を変える ContainsThisがなければ、暗黙のthisパラメータを無視する
checker.ts 補完する Generator固有のエッジケースに対応する

それぞれの変更箇所を見ていきます。

なお、以降に掲載するコードは、解説の都合上、各ファイルから該当箇所のみを抜粋し、// ... 中略 ...などで省略しています。実装の正確な差分はPR #62243のFiles changedをあわせて参照してください。

binder.ts: ContainsThisフラグを立てる

TypeScriptのbinder.tsは、AST(抽象構文木)を走査してシンボルテーブルを構築します。今回は、関数ノードのバインド時にthisキーワードの使用を追跡する処理が追加されました。

まず、AST走査中にthisキーワードを見つけたら、seenThisKeywordフラグを立てます。

case SyntaxKind.ThisKeyword:
    if (node.kind === SyntaxKind.ThisKeyword) {
        seenThisKeyword = true;  // 追加
    }
    // ... 既存処理 ...

次に、関数のコンテナをバインドするbindContainerで、関数本体のバインド前後でseenThisKeywordを退避・初期化し、本体内でthisが出現していればNodeFlags.ContainsThisを立てる処理が追加されました。

const saveSeenThisKeyword = seenThisKeyword;  // 退避(追加)
// ... 他ステートの退避 ...

seenThisKeyword = false;                      // 初期化(追加)
bindChildren(node);
// 増分コンパイル向けのリセット対象にContainsThisを追加
node.flags &= ~(NodeFlags.ReachabilityAndEmitFlags | NodeFlags.ContainsThis);

// ... 中略 ...

if (seenThisKeyword) {                        // フラグを立てる(追加)
    node.flags |= NodeFlags.ContainsThis;
}

// ... 中略 ...

// 復元(アロー関数は内部のthis使用を外側に伝播)
seenThisKeyword = node.kind === SyntaxKind.ArrowFunction
    ? saveSeenThisKeyword || seenThisKeyword
    : saveSeenThisKeyword;

seenThisKeywordはバインド中にローカルに管理されるフラグで、関数本体内でthisキーワードが出現したかどうかを追跡します。関数のバインドが完了した時点でthisが使われていれば、NodeFlags.ContainsThisフラグがノードに設定されます。

末尾の復元処理がアロー関数とそれ以外で分岐しているのは、アロー関数自身はthisバインディングを持たず、内部のthisはコード上で自分を囲っている外側の関数のthisをそのまま参照するためです。アロー関数の内部でthisが使われていれば、外側のメソッドのContainsThisを立てる必要があります。

つまり、thisを使っている関数だけにContainsThisフラグが立ち、使っていない関数にはフラグが立ちません。

utilities.ts: hasContextSensitiveParametersの変更

utilities.tshasContextSensitiveParameters関数は、関数がcontext-sensitiveかどうかを判定するための関数です。

export function hasContextSensitiveParameters(node: FunctionLikeDeclaration): boolean {
    // Functions with type parameters are not context sensitive.
    if (!node.typeParameters) {
        // Functions with any parameters that lack type annotations are context sensitive.
        if (some(node.parameters, p => !getEffectiveTypeAnnotationNode(p))) {
            return true;
        }
        if (node.kind !== SyntaxKind.ArrowFunction) {
            // If the first parameter is not an explicit 'this' parameter, then the function has
            // an implicit 'this' parameter which is subject to contextual typing.
            const parameter = firstOrUndefined(node.parameters);
            if (!(parameter && parameterIsThisKeyword(parameter))) {
                return !!(node.flags & NodeFlags.ContainsThis);  // 変更箇所
            }
        }
    }
    return false;
}

実際の変更点は最後のreturnの1行のみです。

-                return true;
+                return !!(node.flags & NodeFlags.ContainsThis);

この行が発火するのは「型パラメータがない」「アロー関数ではない」「最初のパラメータが明示的なthisパラメータではない」という3条件を満たす場合、つまり暗黙のthisを持つメソッド構文の関数です。

変更前は、この条件に合致するメソッドを無条件にcontext-sensitiveとして扱っていました。変更後は、ContainsThisフラグが立っている(=本体でthisを実際に使っている)ときだけcontext-sensitiveとして扱うようになりました。

checker.ts: Generator固有のエッジケース

Generator関数はアロー関数として書くことができません(function*構文のみ)。そのため、thisを使わないGeneratorでも常にメソッド構文(=thisあり)で書かれることになります。

thisなしの関数がcontext-sensitiveでなくなると、Generator関数も一律にcontext-sensitiveでなくなってしまいます。しかし、Generator内のyield式自体がcontext-sensitiveである場合があります。

declare function pipe<T>(
  gen: () => Generator<(arg: T) => string, void, void>,
  initial: T,
): void;

pipe(function* () {
  yield (arg) => arg.toFixed(2);  // yield式がcontext-sensitive
}, 42);

このyield (arg) => arg.toFixed(2)は、Tの型が確定しないとargの型が決まりません。つまり、このGenerator全体はcontext-sensitiveとして扱う必要があります。

checker.tsでは、isContextSensitiveswitchYieldExpressionのケースを追加し、isContextSensitiveFunctionLikeDeclarationに新規関数hasContextSensitiveYieldExpressionを呼ぶ分岐が追加されました。

case SyntaxKind.JsxExpression:
case SyntaxKind.YieldExpression: {                             // 追加
    const { expression } = node as JsxExpression | YieldExpression;
    return !!expression && isContextSensitive(expression);
}
function isContextSensitiveFunctionLikeDeclaration(node: FunctionLikeDeclaration): boolean {
    return hasContextSensitiveParameters(node)
        || hasContextSensitiveReturnExpression(node)
        || hasContextSensitiveYieldExpression(node);             // 追加
}

function hasContextSensitiveYieldExpression(node: FunctionLikeDeclaration): boolean {  // 追加
    return !!(
        getFunctionFlags(node) & FunctionFlags.Generator
        && node.body
        && forEachYieldExpression(node.body as Block, isContextSensitive)
    );
}

これにより、yield式がcontext-sensitiveな場合はGenerator全体をcontext-sensitiveとして扱えるようになります。

修正前後の推論を比較する

冒頭のコードで、修正前後の推論を比較してみましょう。

test({ a(c) { return c }, b() { return 123 } });

TypeScript 5.9

  1. a(c) → 暗黙のthis → context-sensitive → スキップ
  2. b() → 暗黙のthis → context-sensitive → スキップ
  3. 両方スキップ → Tを推論するソースなし
  4. フォールバックとして、左→右の順番で処理
  5. a(c)を先に処理 → Tが未確定
  6. c: unknown

TypeScript 6.0

  1. a(c)this不使用 → ContainsThisなし → スキップしない
  2. b()this不使用 → ContainsThisなし → スキップしない
  3. 通常の推論へ
  4. b()の戻り値からT = numberを推論
  5. a(c)T = numberを適用
  6. c: number

thisを使っていないメソッド構文の関数がcontext-sensitiveと判定されなくなったことで、アロー関数と同じ推論に入るようになりました。プロパティの記述順序に依存しなくなります。

TypeScriptのコンパイラを読む最初の一歩

TypeScriptコンパイラのchecker.tsは5万行を超える巨大なファイルです。kkk4oruさんがTSKaigi 2025で登壇された「checker.tsに対して真剣に向き合う」も印象に残っている方が多いのではないでしょうか。

2025.tskaigi.org

5万行に圧倒されますが、一つの機能を追うのであれば全部読む必要はありません。

OSSのPRを読むときは、次の観点で読み進めると迷子になりにくくなります。

  • リンクされているIssueを先に読み、課題や何を解決しようとしているのかを理解
  • 先に修正されたテストを読むことで、何を直したのかを理解
  • PRの説明やレビューコメントを読むことで、修正の意図を理解
  • NodeFlags/TypeFlagsが増えていれば、それを追うことで変更の意図を理解

これらは今回の自分の読解で実際に役に立った観点です。

おわりに

1つのPRからTypeScriptの型推論の仕組みを追うことで、Context-Sensitivityという概念と、TypeScriptの内部に踏み込むきっかけを持ち帰っていただけたら嬉しいです。

参考資料


ファインディでは一緒に会社を盛り上げてくれるメンバーを募集中です。興味を持っていただいた方はこちらのページからご応募お願いします。

herp.careers


本記事のbinder.ts / utilities.ts / checker.tsのコードは、microsoft/TypeScriptから引用しており、Apache License 2.0のもとで配布されています。

不要なレビューをAIにまかせてAIコーディングの環境改善を加速した

こんにちは。こんばんは。 Findy Team+ 開発のフロントエンドリードをしている @shoota です。 今回はフロントエンドからは少し離れ、AIによるプルリクエストのレビューシステムを作成した話を書きます。

Findy Team+フロントエンドの現状と課題

過去のブログでも触れていますが、Findy Team+のフロントエンドは、非常に大きなモノレポで構成されています。

tech.findy.co.jp

このため、CIの最適化・チューニングはもちろんのこと、コードベース全体の秩序の品質を維持するためにさまざまな工夫や制約をもって運用してきました。 AIコーディングが主流になってからは更にこれらを強化し、制約やルールの策定、ESLintやユニットテストなどのガードレール整備や強化をおよそ1年をかけて進めてきました。 (この内容については別で発表したいと思います)

これらの投資とAIモデルの進化により、これまでバックエンドを中心に活動しているメンバーのフロントエンドの参入障壁を大きく下げることに成功しています。 現在では、AIが生成するコードの質は1年前から大きく向上していると体感しています。

AIコーディング時代の新たな課題

しかしここで新たな課題が生まれました。それは、「AIが真似すべきでないコードの修正や、それらを防ぐルールの導入のためのレビューコストが異常に高い」ということです。

  • AIの活用のためにコードを直し続ける活動は巨大なコードベースではかなりコストがある
  • 技術的な障壁よりも単純な物量がつらく、対抗する手段がない
    • ESLintのルールを1つ変更するだけでプルリクエストが大量に必要になる
      • 特定のルールのちょっとした厳格化で25件のプルリクエストを作成
      • あたらしいルールを追加したときは150件のプルリクエストが必要になった
    • 軽微な変更でも意味のある粒度で修正しなくてはレビューできないため、ひたすらに数を重ねる

このような事象が定常的に発生しており、次のFindy Team+でのグラフでも確認できます。

大量のプルリクエストが発生する様子

Vitestの一部のassertionがdeprecatedになったことに対して、私が一人でClaude Codeを回し、1日に72件、2日で100件以上のプルリクエストを作成しました。 レビュー待ちが多く発生する割に、内容は関数の置き換えなのでレビュー価値が低いプルリクエストが大量に必要になったのです。

このような 「AIを利用して品質を維持するための整備が人間を苦しめている」 という状況は、近頃話題になっていたHustle Pornに近いのではないか?と考えました。

プルリクエストをたくさん書くことは素晴らしいですが、そこに意味のある粒度と価値が伴わなければなりません。

AIによる自動レビュー(Approve)を作ろう

このような背景からレビュー負荷を可能な限り低減させ、ただしい怠惰を取り戻すために、AIレビューの仕組みを作成することにしました。 まずはやりたいことから全体の構想とコンセプトを決めていき、次のような内容になりました。

解決したい課題

  • プルリクエストを高速に作り続けることはむしろ歓迎すべき
  • 課題の本質は「レビュープロセスが対ひとでしか機能していない」こと
    • 人の時間をうばう
    • 人のアクションを待つ
    • 両者にメリットが少ない

レビューは大きく3種類ある

  1. レビューする価値がないことを確認するレビュー。レビューというワークフローを実施しているだけであり、本質的なレビューはしていない。レビューワークフローに相乗りしている儀式のひとつ。
  2. 品質、プログラム観点としてのコードレビュー。いわゆる本質的なコードレビュー。
  3. レビュー結果が反映されていることのレビュー。論点が絞られており、コードの内容がレビュー指摘に即して修正されているかを「確認する」だけの作業的な儀式。

今回は1. の「レビューする価値がないことを他者が保証する儀式」をAIにやらせることをゴールとします。

誰が使えるのか

初手はフロントエンドのレビュワーチームのみに絞る

  • 最大リスクは、誤判定や手順のハックによるレビューのザル化
  • フロントレビュワーチームはセルフレビューで一定の品質担保ができている前提で考える
  • 条件的に一般解放は想定するが、判定の成功率データがたまるまではリスクのほうが大きい

何を判定するのか

  • 要はプルリクエストの分類器をつくる
  • Claude CodeのReview (~$25) は必要がない
  • 変更内容から人間がレビューする必要があるかどうか?を判定する
    • 振る舞いが変わらない構造的なリファクタリング
    • code generatorなどの既存の機械的なワークフローの結果も不要と判断する

判定のキモはTidy First?の分類

レビューの必要性を測る判定処理に、構造的なリファクタリングという概念を持ち込みました。 これは昨年の弊社のイベントでキーノートを務めていただいたKent Beck氏の書籍Tidy First?から引用した言葉です。 この書ではリファクタリングの分類が紹介されており、リファクタリングを効率的に進めるための作業を指します。 和訳では「整頓」と表現されています。

  • 振る舞いの変化を伴わない、「コードの移動・分割」、「名前の変更」、「配置の変更」
  • プログラム(群)の凝集度に対するリファクタリングアプローチ
  • これらの修正は人間が目で追うのは意外と面倒で、レビューコストが割に合わない

例)ファイル移動や統合、変数・関数のリネームor削除、関数統合・分離

www.oreilly.co.jp

Tidy First?に関する考察は非常に多く議論されているので、Claude Codeに調査させながら「人間のレビューが不要」の定義を確定し、プロンプトに起こしていきました。 次に示すのがそのパターンの概要です。詳しい内容はぜひ書籍を確認していただけるとよいかと思います。

  • 対象パターン(T1〜T14)

    • T1: ファイル移動・リネーム
    • T2: import整理・barrel export
    • T3: 型定義の移動・分離
    • T4: コンポーネント・関数の分割・統合・抽出
    • T5: 変数・関数・propsのリネーム(テスト/モックへの機械的波及含む)
    • T6: ESLint/Prettier修正
    • T7: 不要コード・ファイル削除
    • T8: 非推奨APIの機械的移行(1:1対応)
    • T9: GraphQL codegen実行結果
    • T10: Nx generator実行結果
    • T11: ガード節への変換
    • T12: 説明変数・定数の導入
    • T13: Feature Flag名の追加
    • T14: コメントの追加・修正・削除
  • NGパターン(NG1〜NG7)

    • 新条件分岐、新ビジネスロジック、API変更、状態管理変更、テスト追加、UI変更、設定値変更

実装とポイント

全体の要件が決まったのでここからは実装です。

GitHub Actions

GitHub Actionsをランナーとし、プロンプトファイルを読み込んだうえでClaude Code Actionsに渡して実行、結果をパースしてレポートする非常にシンプルなフローです。 またFindy Team+はCI結果を送ってCIの実行分析ができるので、これも組み込んであります。

GitHub Actionsのフロー

Claude Code Actions

Claude Code Actionsの呼び出しのポイントは--max-turnsです。 これはClaude Codeが処理を何手まで行うかを制限するもので、変更ファイル数やそれらのファイルの関連性によって前後します。

      - name: Classify PR changes
        id: claude
        uses: anthropics/claude-code-action@5d5c10a4f389689f992ea10bb14dcb6fcc83146d # v1.0.102
        with:
          anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
          claude_args: '--max-turns 20'
          prompt: ${{ steps.prompt.outputs.content }}

何パターンかの構造的なリファクタリングのプルリクエストで試したところ〜15 turnsにおさまるようでしたが、余裕を見て20を設定しています。 これを設定しておくことでプロンプトの誤認や想定しない大きな差分で実行された場合でも「判定不能」で安全に終了するようにしています。

ワークフローの変化とプロンプトの改善

何度か試していくうちに、ひとつの気づきがありました。

これまでプルリクエストは 「人間が認知できる変更量」にサイジングするようにすべき でしたが、AIは機械的にこれを分析できるので「同じ作業なら差分が大きくても1つのプルリクエストにまとめる」ことができる、ということです。 そのため大きな差分でもApproveができるような負荷耐性をもたせる必要があります。

そこで変更ファイルが多い場合は変更そのものを見るのではなく、いくつかをサンプリングし、「diffのパターンが同一であるか?」をClaudeが確認するようにしています。

<!-- 追加したプロンプトの抜粋 -->
## 大規模 PR のフォールバック

- **変更ファイル数が 30 ファイルを超える場合**: 同一パターンの変更が繰り返されるファイル群はサンプリング(代表的な数ファイルの確認)で判定してよい。サンプリングした旨と確認したファイルを注意事項に記載する
- **サンプリング時は副作用の取り逃しに注意する**: ある T パターンを特定したら、**その波及先ファイル群(スナップショット、spec、モック、`index.ts` の re-export、import 更新 等)も必ず1件以上サンプリングに含め、元の T パターンとの対応を確認する**。波及先のファイルだけを単独で見ると NG に誤分類しやすい(例: T5 リネームのインラインスナップショット更新を NG5 と誤認)。波及元・波及先を**セットで**サンプリングすること
(以下略)

実行コスト

Claude CodeのReviewは 最大$25の費用が必要ですが、今回はプルリクエストの分類器なのでそこまでのコストがかかりません。 CIから実行したログからみると、1 runあたり、$0.20〜0.50で分類ができていました。

{
  "type": "result",
  "subtype": "success",
  "is_error": false,
  "duration_ms": 62472,
  "num_turns": 10, // Claude Codeの手数の実績値。最大20で絞ってある。
  "total_cost_usd": 0.24731475000000003, // 約$0.25を消費
  "permission_denials_count": 0
}

おわりに

プルリクエストの分類器をGitHub Actions + Claude Code Actionsで作成することで、人がレビューしなくて済むプルリクエストは作成者が単独でマージできるようになりました。

この仕組みの導入は想定以上に開発者体験がよく、また機能開発の合間でリファクタリングするモチベーションも高めてくれます。 まさにTidy First?のなかでの「先に整頓、あとに整頓」を仕組みで支えることができたと感じています。

Claude Code Actionsはチャット形式に似たJSONレスポンスを返すため、AIチャットの実装経験もCIのデバッグに役立ちました。

今後はさらに対象を拡大させつつ、組織的に利用するAIワークフローを充実させていきたいと思います。


ファインディでは一緒に会社を盛り上げてくれるメンバーを募集中です。興味を持っていただいた方はこちらのページからご応募お願いします。

herp.careers

イベント「事業成長に効かせるファインディ流データエンジニアリングの実践」開催レポート

こんにちは。ファインディ株式会社でデータエンジニアをしているです。

2026年4月28日(火)に、データソリューションチーム主催の採用イベント「事業成長に効かせるファインディ流データエンジニアリングの実践」を開催しました。

findy-inc.connpass.com

この記事では、イベントを企画した背景と当日の3本のセッションを参加できなかった方にもイメージが伝わるようにまとめます。

イベント開催の背景

ファインディでは、既存4プロダクトに加えて、新たに4つのプロダクトをリリースし、エンジニアの皆さまへサービスを多角的に展開しています。会社規模の拡大とともに、扱うデータの量と種類は急速に広がってきました。

prtimes.jp

変化の激しい事業環境のなかで客観的な意思決定を支えるには、社内の情報流通をより活性化させる仕組みが欠かせません。私たちは、その土台を担うのがデータエンジニアリングだと考えています。

データソリューションチームは少数精鋭で推進してきましたが、事業成長のスピードに合わせてデータ基盤をさらにスケールさせるには、共に挑戦してくれる仲間の存在が不可欠です。今回のイベントは、ファインディがどのような課題に向き合い、どのような技術と組織で解いているかを直接お話しする機会としました。

セッションは3本立てで、データ基盤・データモデリング・BIの3つの観点からファインディのデータエンジニアリングをお話ししました。

セッション1: ファインディの事業拡大を支える拡張可能なデータ基盤へのリアーキテクチャ

登壇者: 開

speakerdeck.com

事業拡大に合わせてデータ基盤をどうリアーキテクチャしているかを紹介しました。直近1年でデータソースは10倍、Google Cloudプロジェクトは6倍に増える一方、データエンジニアは3名のままで、認知コストと運用負荷が膨らんでいました。

これまでは事業=ドメインとしたデータメッシュ的な構成で、技術選定も各チームに委ねていました。アジリティは出る一方で、ドメイン間の連携不足や技術のばらつき、作業重複が課題になっていました。

そこで、データメッシュの利点は残しつつ実装を見直し、Google Cloudプロジェクトの統合、IAMのデータセット単位での管理、dbt Platformへのオーケストレーション集約やマネージドサービスの活用を進めています。これによりマネージドサービスのAPIやMCPを用いてAIエージェントに運用を一部移譲することができています。作成したスキルやサブエージェントは以前テックブログで紹介したプラグインとしてチーム全体で使えるようにしています。

tech.findy.co.jp

DataOpsの省力化が進む一方、コスト透明性の低下といった新しい課題も見え、FinOps体制の構築や、浮いた時間をデータ活用者との会話やイネーブリングに使っていくことを次のテーマにしています。

セッション2: データモデリングを通して管理会計のオペレーションを再設計

登壇者: 田頭さん

speakerdeck.com

経営判断に直結する管理会計という業務領域に対して、データモデリングの観点からオペレーションを再設計した取り組みを紹介しました。

ファインディの管理会計は、長らくスプレッドシートを中心に回っていました。月次のたびに関数とピボットを手作業で組み直し、IMPORTRANGEやVLOOKUPで絡み合ったスプレッドシートのリネージは50件を超え、どこか1枚崩れると全体が連鎖して壊れる脆さを抱えていました。同じKPIが部署ごとに別ロジックで計算されて数字が合わない、月次締めに2〜3日かかって意思決定が後追いになる、といった状態も常態化していました。

再設計の起点に置いたのは、技術選定ではなく業務担当者へのヒアリングです。「計上組織」「補助科目」「配賦」「予算番号」といった専門用語が飛び交うなか、勘定元帳やマクロを眺めるだけでは掴めない集計粒度や分析軸を、経営管理部の担当者と何度もMTGを重ねて引き出していきました。書籍『アジャイルデータモデリング 組織にデータ分析を広めるためのテーブル設計ガイド』のBEAM✲を参考に、誰が・何を・いつ・どこで集計したいのかを対話から輪郭化し、総勘定元帳を起点に売上・費用・原価を月次粒度のファクトとして整理しています。

実装は、会計データソースをGoogle DriveにアップロードしてTROCCOで取り込み、dbtで集計してLookerやスプレッドシートから参照する構成に落としています。これにより、ワンボタンで月次の実績値が揃い、想定外の科目も自動で検出できるようになりました。「どの数字が正しいか」を議論する場面はなくなり、月次締めの所要時間と数字の信頼性が同時に改善しています。

今後は、実績ファクトと同じ粒度で予算・見通しを取り込んだ予実分析の自動化や、整備済みのファクトを起点にAIエージェントが自然言語で会計分析を行える基盤への展開を進めています。

セッション3: 社内で使われるLooker整備の進め方

登壇者: 出相さん

speakerdeck.com

社内で実際に使われるBIにするためにLookerをどのように整備してきたかを紹介しました。「ダッシュボードを作った瞬間がピークになって使われなくなる」「事業部からはデータ活用の入口が見えない」「スプレッドシート運用が属人化して限界が見えている」といった、よくある課題を出発点にしています。

ファインディでは、Lookerを意思決定にひも付くダッシュボードを定常的に見る場としてだけでなく、Exploreや会話分析でデータそのものを探索する場にすることを目指しています。ただし、最初はLookerを見に行く習慣もExploreの操作にも慣れていないため、進め方の工夫が欠かせません。

そこで、ヒアリングで課題を引き出す → 最低限の機能に絞って最初のダッシュボードを素早く提供する → 共有MTGで一緒に触りながら改善ループを回す → 利用が定着してからディメンショナルモデルやメタデータを整える、という4ステップで価値を積み上げてきました。完璧な設計よりも早い体験提供を優先し、苦労していたことから先に解消していくことを大切にしています。詳しい進め方は以前のテックブログでも紹介しています。

tech.findy.co.jp

その結果、MAUは2026年1月から4月途中で約1.5倍、WAUは1月中旬から4月中旬で約2.6倍に成長しました。経営管理部からも「BigQueryやLookerを駆使したモニタリングが事業拡大に不可欠」というコメントが届くなど、Lookerが信頼できるデータソースとして社内に定着してきています。

まとめ

今回のイベントを通じて、ファインディがデータエンジニアリングをどのように事業に効かせようとしているかを、3つの異なる切り口でお伝えできたと思います。データ基盤・データモデリング・BIのいずれも、技術そのものよりも「事業や業務にどう接続するか」を軸に進めてきた取り組みです。

参加してくださった皆さん、ありがとうございました!

ファインディでは、データエンジニアリングの力で事業成長を支える仲間を募集しています。今回のイベント内容に少しでも興味を持っていただけた方は、ぜひお気軽にカジュアル面談などでお話しできるとうれしいです。

herp.careers

コーディングをAIに任せても、エンジニアの仕事は減らなかった ― ほぼ一人で1か月、AI機能をリリースしてみて

こんにちは、ファインディでFindy Toolsの開発をしている本田です。

このたび、Findy Toolsの新機能として「アーキテクチャAI」をリリースしました。要件を入力するとAWSのアーキテクチャ図と設計の提案が生成される機能です。

findy.co.jp

今回の開発では、PM・仕様策定・スコープ定義・インフラ・FE/BE開発・テストまで、ほぼ一人で1か月で担当しました。そして、コーディングはほとんどClaude Codeに任せ、私自身はほぼコードを書いていません。

この記事では、そんな開発を進めるなかで分かったこと、難しかったこと、そして改めて実感したエンジニアの仕事について紹介します。

アーキテクチャAIについて

本題に入る前に、リリースした機能を軽く紹介させてください。

アーキテクチャAIは、Findy Toolsの中で提供している機能の1つで、「作りたいシステムの要件」を入力するとAWSを使った構成案とアーキテクチャ図、そして設計の考え方の解説がまとまった形で得られるものです。

ai-architecture.findy-tools.io

アーキテクチャの設計はサービスの土台を決める工程で、経験や周辺知識の広さが問われる領域です。そうした知見を持った人に相談しづらい場面でも、構成の検討を前に進める助けになることを目指しています。

ここから先は、この機能を一人で1か月で作ったなかで気づいたことを中心に書いていきます。

一人開発の全体像

今回は、PMから開発、テスト、リリースまでを一人で担当しました。具体的には次のような範囲です。

  • プロダクトの方向性・優先順位の決定
  • 仕様策定、スコープ定義
  • インフラの構築
  • フロントエンド・バックエンドの実装
  • テスト、リリース作業

開発のワークフローはシンプルで、だいたいこのサイクルを回していました。

  1. GitHub Issueに「なぜ作るのか」「何を作るのか」を、PRDやユーザーストーリーの形で書く
  2. Claude CodeにIssueを渡して実装してもらう
  3. 自分は差分をレビューし、必要に応じて指示を出す
  4. 別チームのメンバーにレビューしてもらい、PRをマージする

実装の途中でも、作りたい背景やユーザーに届けたい価値に立ち戻って方針を調整することはよくありました。

仕様策定やUIのモック作成も、AIと壁打ちしながら進めていました。結果として、自分でコードを書いた量はごくわずかで、ほとんどの実装はClaude Codeが書いています。

一方で、「自分はほぼコードを書いていない」からといって仕事が少ないわけではありませんでした。むしろコーディング以外にやることが山ほどあるというのが実感です。

  • 何を作るか、何を削るかの判断
  • 仕様の細部に関する意思決定
  • 技術選定
  • コードレビューと品質の担保
  • スケジュール管理とリリース計画

ここからは、この進め方で1か月やってみて感じたことを書いていきます。

エンジニアが価値とコストを自分で判断する

最も強く感じたのは、エンジニア自身がユーザー価値と実装コストのバランスを判断しながら開発に携わることの強みです。

今回は一人で担当していたので、事業やプロダクトの意図、技術的な実現可能性、実装コストが、すべて自分の頭の中に揃っていました。「ユーザー価値として外せない部分はどこか」「コストをかける価値があるのはどこか」を、自分の中でつなげて考えながら開発を進めることができます。

具体的には、開発の途中でアーキテクチャ図の描画ライブラリを切り替える判断をしたり、リリースの2週間前になってからSNSで共有されたときに見栄えの良い画像を生成する機能を追加する判断をしたりと、方針転換を素早く進められました。技術的に成立するかをClaude Codeで素早く検証しつつ、プロダクトとして本当に必要かを自分で判断できたことで、価値とコストの両取りを狙える選択肢を見つけやすくなっていました。

体制を一人にしたことが本質ではないと思っています。大事なのはやはり、作る側のエンジニアがユーザー価値や事業価値を理解したうえで、コストと価値のバランスを判断しながら開発に携われているかだと、今回の開発を通じて改めて感じました。

対話で判断の視野を広げる

意思決定が速いのは良いことですが、速ければ良いわけではありません。一つの視点だけで速く判断を続けていると、気づかないうちに筋の悪い方に流れてしまいます。

ここで効いてきたのが、一人で担当していても孤立はしていないという体制づくりでした。

開発中は、事業部長・PO・デザイナと定期的に相談・共有できる場を持ち、それ以外の場面でもいつでもコミュニケーションを取れるようにしていました。

  • プロダクトとして何を大事にしているか
  • 事業としてこの機能にどういう期待があるか
  • デザインとして譲れない部分はどこか

こうした観点を継続的にすり合わせることで、自分一人では見えていなかったより良い選択肢を見つけやすくしていました。

自分の頭の中だけで判断すると、どうしても視野が狭くなります。そこに他の立場の視点が入ると、「他にもっと良い選び方はないか」という問い直しができます。スピード重視の体制であっても、というよりスピード重視だからこそ、チームとの対話は欠かせないと感じました。

動くもので共通認識を作る

もう1つ強く感じたのが、速く見せられるもの・動くものを使って共通認識を作ることの効果です。これ自体は昔からよく言われる話ですが、AIの力でぐっとやりやすくなりました。

今回は、実プロダクトの開発を始める前に、別リポジトリでPoCアプリを作り、ステークホルダーやインタビューにご協力いただいた方に、実際に見たり触ったりしてもらう時間を取りました。

PoCアプリの画面
PoCアプリの画面。デザインは作り込まず、ユーザーに価値を体験してもらうことを優先した。

文章やスライドだけで議論すると、どうしても抽象的になり、認識のズレに気づきにくくなります。動くものがあると、「これは欲しい」「ここは期待と違う」というフィードバックが具体的に返ってくるだけでなく、「どういう価値が得られそうか」という部分でも共通認識を作りやすくなります。

PoCを見たり触ったりしてもらうなかで見えてきたのは次のようなことです。

  • ユーザーが本当に価値を感じるのはどの部分か
  • 最初はあると便利そうに見えたが、実際はなくても困らない機能
  • 技術的に見落としていた制約や、逆に想定より軽く実現できそうな部分

PoCで得られたこれらの情報が土台になって、本開発のスコープと方針が定まっていきました。AIで「仮に動くもの」を高速に作れるようになった強みを活かして、動くものを中心に仮説検証のサイクルを回せたことが、1か月という限られた期間のなかで特に効いたポイントだと思います。

自分の仕事は減らず、判断と意思決定の時間が増えた

ここまで書いてきたことを踏まえて、改めて感じたのは少なくとも今回の自分の経験では、コーディングをAIに任せても、エンジニアとしてやることは減らなかったということです。むしろ、本質的な判断に集中する必要が出てきた感覚でした。

今回の開発で自分が時間を使っていたのは、次のような部分です。

  • この機能を作る意味は何か、誰のどんな課題を解くのか
  • スコープをどこまで広げ、どこで切るか
  • どの技術を選び、どの技術を見送るか
  • 出てきたコードが本当に要件を満たしているか、将来の運用に耐えるか

どれも、意思決定と判断の仕事です。コーディングそのものをAIに任せられるからこそ、こうした判断に集中できる時間が増えました。

AIと協業するなかで変わる部分と変わらない部分があり、「コードを書く時間」は確実に減りますが、「エンジニアリングを行う時間」は減らない、むしろ増えている感覚でした。

まとめ

ほぼ一人で1か月かけてアーキテクチャAIをリリースしてみて、次のことが学びとして残りました。

  • エンジニア自身がユーザー価値と実装コストのバランスを判断しながら開発に携われると、価値とコストの両取りを狙える選択肢を見つけやすい
  • 速さだけを追うのではなく、複数の視点を対話で取り込んで選択肢を広げていく
  • AIで仮の動くものを高速に作れるようになった強みを活かせば、短期間でも動くものを軸に仮説検証を回しやすい
  • 少なくとも今回の自分の経験では、コーディングをAIに任せても仕事は減らず、判断と意思決定に集中する時間が増えた

AIと一緒に開発する時代になっても、「何を作るか」「どう作るか」「なぜそれを選ぶか」を考え抜くことの大切さは変わらないなと、今回の開発を通じて改めて感じました。

アーキテクチャAIは次のページから触れます(Findy Toolsの会員登録が必要です)。ご興味のある方はぜひ試してみてください。

findy-tools.io

ファインディでは一緒に会社を盛り上げてくれるメンバーを募集中です。興味を持っていただいた方はこちらのページからご応募お願いします。

herp.careers