TECH PLAY

Findy/ファインディ

Findy/ファインディ の技術ブログ

210

こんにちは。 CTO室/Platform開発チームでSREを担当している富田( @Cooking_ENG )です。 ファインディでは、サービスがどれほどの負荷に耐えられるかを把握し、性能の問題を表面化・改善することで、ユーザーに安定したサービスを提供できる状態を目指しています。 そこで、Grafana Labsが提供するGrafana Cloud k6を採用し、 負荷試験環境をゼロから構築 しました。今回は、 Findy Conference を対象に負荷試験を実施しています。 Findy Conferenceは、テックカンファレンスに特化したプラットフォームサービスです。 conference.findy-code.io この記事では、負荷試験ツールの選定から、本番トラフィックを再現するシナリオの作成、Grafana Cloud k6とDatadogを組み合わせた負荷試験の実施までの取り組みを、初めて負荷試験を担当するエンジニアの方々や、これから導入を考えているチームに向けて紹介します。 負荷試験環境を作ることになった背景 負荷試験ツールの選定 ファインディで重視した判断軸 候補ツールの比較 負荷シナリオの作成 har-to-k6を使ったスクリプトの作成 負荷のかけ方を調整するOptionsブロックの話 想定する負荷がかけられているかをDatadogを使って確認する方法 作成でつまずいたポイント Options内の値はリテラル必須 認証付きエンドポイントの扱い 負荷試験の実施と結果 負荷規模と必要コンテナ数 Datadogで取ったメトリクス まとめ 負荷試験環境を作ることになった背景 Findy Conferenceでは、セッションの開始や終了のタイミングで、参加者の方々が一斉にアクセスする 瞬間的なスパイク が発生する特徴があります。 過去のBlogにまとめているので、気になる方はぜひ こちらの記事 もご覧ください。 tech.findy.co.jp こうしたスパイクに備えるため、カンファレンス開催前にコンテナ数を増やす運用をしてきました。コンテナ数を決める際の判断はチームの経験値に基づいていたため、本当にその数で十分なのか、過剰になっていないかを根拠を持って判断できない状態でした。 そこで、想定するスパイクに対して 実際の計測値に基づいた最適なコンテナ数を設置できる 状態を目指し、負荷試験環境の整備に取り組むことにしました。 負荷試験ツールの選定 ファインディで重視した判断軸 ツール選定にあたり、ファインディの状況に合わせて次の判断軸を置きました。 インフラ管理が不要であること(環境の構築・運用コストを抑えたい) シナリオ作成の自由度(本番に近いユーザー導線を再現できる) サービスの継続性(SaaSとして長く使えるか) コスト(従量課金で、使わないときに費用が膨らまないこと) 候補ツールの比較 候補として、次のツールを比較しました。 サービス シナリオ記述 提供形態 運営元 特徴・得意領域 Grafana Cloud k6 JavaScript SaaS(OSS版あり) Grafana Labs モダンな開発体験、Grafana統合、専用ダッシュボードが標準。OSS版でローカル実行も可能 BlazeMeter JMeter/GUI SaaS Perforce JMeter資産を活かしやすい。詳細なレポートとGUI操作に強み Gatling Enterprise Scala/Java SaaS Gatling Corp 大規模負荷試験に強み。Javaエコシステムとの親和性が高い Locust Python OSS Locustコミュニティ Pythonでシナリオを柔軟に記述できる。軽量で分散実行にも対応 JMeter GUI/XML OSS Apache Software Foundation 長年の実績と豊富なプラグイン。対応プロトコルが幅広い それぞれのツールには得意な用途があります。今回はファインディの判断軸を基準に評価しました。 評価の結果、Grafana Cloud k6を採用しました。 先に挙げた4つの判断軸それぞれに対する評価は次のとおりです。 判断軸 Grafana Cloud k6での評価 インフラ管理 マネージドサービスのため、負荷試験用の環境を自前で構築・運用する必要がない シナリオ作成の自由度 JavaScriptベースでシナリオを記述するため、フロントエンド/バックエンド双方のエンジニアが読み書きしやすい サービスの継続性 運営元のGrafana Labsが監視・可視化領域のサービスを長く提供している実績があり、長期利用の見通しを立てやすい コスト Proプランの月額が$19、500 VUh/月までは無料枠、超過分も$0.15/VUhの従量課金で、使わないときに費用が膨らまない(2026年6月時点。最新は 公式料金ページ を参照) なお、負荷をかける対象である アプリケーション側のCPUやメモリ といったサーバーリソースは、Grafana Cloud k6では取得せず、すでにアプリケーション側に導入していたDatadogで観測する構成にしました。 Grafana Cloud k6でHTTPメトリクスを、Datadogで負荷をかけられる側のリソースメトリクスを観測する役割分担 です。 負荷シナリオの作成 ここからは、実際に負荷シナリオをどう作っていったかを紹介します。 har-to-k6を使ったスクリプトの作成 本番に近いユーザー導線を再現するには、ユーザーがどのエンドポイントにどの順でアクセスするかをシナリオとして書き起こす必要があります。当初は手作業でシナリオを書こうとしましたが、ステージング環境ではCognitoに加えてファインディ独自の認証基盤「Findy ID」など複数の認証を突破する必要があり、認証の流れをスクリプトで再現するのは簡単ではありませんでした。 そこで、 har-to-k6 を使い、ブラウザの操作ログからk6のシナリオを生成する方法に切り替えました。har-to-k6は、ブラウザの開発者ツールで書き出せる HAR(HTTP Archive)ファイル を入力として、k6用のJavaScriptシナリオを生成してくれる公式ツールです。ブラウザで一度認証を通したあとの操作をHARとして記録すれば、認証後のリクエストをそのまま再現できるため、手作業で書くよりも本番に近いシナリオを効率よく用意できました。 おおまかな流れは次のとおりです。 ブラウザの開発者ツールで、再現したい操作を実行し、HARファイルを書き出す har-to-k6 input.har -o script.js でk6用のJavaScriptに変換する 生成されたスクリプトを、シナリオに不要なリクエストの除去や認証情報の環境変数化などに合わせて整える HARから変換した直後のスクリプトには、画像・CSS・JavaScriptファイルなどの静的アセット取得のリクエストや、HARに含まれていた認証情報(パスワードなど)がそのまま残っています。これらの整理にはClaude CodeなどのAIコーディング支援ツールが便利でした。 ただし、平文のパスワードをそのままAIに渡すのはセキュリティ上避けたいので、先に認証情報を __ENV.TEST_PASSWORD のような形で環境変数化し、それから不要なリクエストの除去をAIに任せました。AIを活用することで、手作業で1つずつ削るよりも短い時間で本番に近いシナリオを用意できました。 負荷のかけ方を調整するOptionsブロックの話 k6のシナリオでは、 options というブロックで負荷のかけ方を細かく制御できます。今回のシナリオでは、 ramping-arrival-rate というexecutorを使って、 スパイクの立ち上がり・ピーク・収束を1本のシナリオで再現する 構造を採用しました。 なお、k6では負荷シナリオの関数が1回実行されることを「イテレーション」と呼びます。今回のシナリオは1イテレーションのなかで複数のHTTPリクエストを送る構成です。 実際のOptionsブロックは次のような形です(数値は記事用のダミー値であり、対象サービスや想定するスパイク規模に応じて調整します)。 export const options = { scenarios: { spike: { executor: 'ramping-arrival-rate', startRate: 0, timeUnit: '1m', preAllocatedVUs: 50, stages: [ { duration: '10s', target: 100 }, { duration: '10s', target: 200 }, { duration: '50s', target: 200 }, { duration: '10s', target: 0 }, ], }, }, cloud: { distribution: { tokyo: { loadZone: 'amazon:jp:tokyo', percent: 100 }, }, }, }; 主な設定項目は次のとおりです。 設定項目 説明 executor 負荷のかけ方のパターン。 ramping-arrival-rate は、各ステージのtargetに向けてイテレーション数をなめらかに増減させ、山型の負荷曲線を表現できる startRate 開始時点のレート。今回は0から立ち上げる timeUnit targetの単位時間。 '1m' にすると目標値を「1分あたりのイテレーション数」で指定できる preAllocatedVUs 目標レートを捌くために事前に確保しておく仮想ユーザー(VU)数 target 各ステージで到達させたい目標イテレーション数/ timeUnit 。 timeUnit: '1m' なら target: 100 は「1分あたり100イテレーション」を意味し、durationをかけてその値までなめらかに増減する timeUnit を '1m' にしているのは、過去のカンファレンスの実測値を「1分あたりのリクエスト数」で把握していたためです。この実測リクエスト数を1イテレーションあたりのリクエスト本数で割ることで、必要なイテレーション数(target)を算出し、シナリオの単位もこれに揃えました。 stagesを4段に分けているのは、本番のスパイクを次のような流れで再現するためです。 1段目(10秒):本番想定の半分まで急速に立ち上げ、アクセス急増の前兆を再現 2段目(10秒):本番想定まで一気に到達させる 3段目(50秒):本番想定の負荷を維持して、システムが安定して捌けるかを観察する 4段目(10秒):目標値を0に戻し、収束させる cloud.distribution では、Grafana Cloud k6上で負荷を発生させるAWSのリージョンを指定しています。今回は実際のユーザーアクセスに近づけるため、東京リージョン( amazon:jp:tokyo )を100%としました。 想定する負荷がかけられているかをDatadogを使って確認する方法 ここがいちばん試行錯誤したところでした。 k6側のレポートで「目標としていたイテレーション数を発行した」と表示されていても、それが アプリケーションのコンテナに実際に届いたリクエスト数 と直接一致するわけではありません。今回のシナリオは1イテレーションで複数のリクエストを送るためです。 そこで、まず「イテレーション数 × 1イテレーションあたりのリクエスト本数」で、アプリケーションに届くはずのリクエスト数(期待リクエスト数)を見積もりました。そのうえで、k6側のtargetを微調整しながら、期待リクエスト数どおりの負荷がかかるように調整していきます。 調整したリクエストが実際に届いているかは、Datadogで確認します。ファインディではもともとDatadogでオブザーバビリティに取り組んでおり、各サービスのダッシュボードを運用しています。負荷試験のメトリクスも普段の監視と同じダッシュボードで確認できるため、状態を把握しやすい環境がすでに整っていました。 ただし、どのメトリクスを見るかで数字の意味が変わります。観測候補をいくつか比較した結果、 ALBのレスポンス数 を見ることにしました。今回はレスポンス数を、アプリケーションが実際に処理した負荷の指標として扱っています。 観測対象 負荷確認の用途として 理由 ALBのレスポンス数 適している アプリケーションが実際に返したレスポンス数。見積もった期待リクエスト数と突き合わせやすい CloudFrontのリクエスト数 向かない CDNキャッシュや静的アセット分が水増しされ、k6の発行数とずれる APMのリクエスト数 やや向かない サンプリングで一部を間引いて記録するため、実際より低めに見えることがある ALBのレスポンス数の推移を見て、見積もった期待リクエスト数どおりの負荷が処理されているかを判断します。値が想定より少ない場合は、CloudFront側で弾かれているリクエストがあるか、シナリオ側で意図しないエンドポイントを叩いていないかを見直すサインになります。 次の図は、ある負荷試験でのALBのレスポンス数の推移です。シナリオで設計したとおり、短時間で立ち上がってピークに達し、収束していく山型になっていることが確認できます。 作成でつまずいたポイント シナリオを書く過程でつまずきがあったので、これから取り組む方向けに共有します。 Options内の値はリテラル必須 Grafana Cloud k6のプレビュー画面では、Optionsブロックの値を静的解析してVUh(仮想ユーザー時間)を試算します。このとき、 Math.round() のような関数呼び出しや、外部の定数を参照する書き方は評価できず、 VUhが正しく計算されません 。 // NG(VUh が計算されない) const MaxTarget = 200; export const options = { scenarios: { spike: { stages: [ { duration: '50s', target: MaxTarget }, // 変数参照は評価されない ], }, }, }; // OK(リテラル数値で書く) export const options = { scenarios: { spike: { stages: [ { duration: '50s', target: 200 }, ], }, }, }; DRYに書きたくなる気持ちはありますが、Optionsブロックに限ってはリテラルで書くことを徹底すると安全です。 認証付きエンドポイントの扱い ステージング環境を本番相当にスケールアップして試験する場合、認証が挟まる導線では CloudFront → Cognito → アプリケーション のようにリダイレクトが連鎖します。最初から本番想定のシナリオを流すと、認証で弾かれてうまく負荷がかからないことがあります。 そこで、まずは /health のような疎通確認用エンドポイントに redirects: 0 を付けてリクエストを送り、想定どおりに200や302が返ってくるかを確認してからシナリオを組み立てるのがおすすめです。 負荷試験の実施と結果 ここまでで作ったシナリオを使い、ステージング環境を本番相当にスケールアップしたうえで負荷試験を実施しました。ここでは、ファインディがどのように 「想定スパイクごとに必要なコンテナ数」を割り出した のかを紹介します。 次の図は、Grafana Cloud k6で負荷試験を実行したときの結果サマリです。設計したとおりに負荷がかかってピークに達し、その間エラーを出さずに処理できていることが確認できます。 ※画像はイメージです。 負荷規模と必要コンテナ数 過去のカンファレンスでの参加者数と実測リクエスト数から、想定する負荷規模(1分あたりのリクエスト数)を複数段階用意し、負荷規模ごとに試験しました。 コンテナ数を判定する指標は、次のように定めました。 項目 内容 判定指標 ecs.fargate.cpu.percent (Datadog) 観測対象 Findy Conferenceのなかで最もリクエストが集中するバックエンドサービス 閾値 50% ボトルネックになりやすいバックエンドサービスのCPU使用率を直接観測することで、コンテナ数の過不足を判断します。 閾値を50%にした背景 オートスケールはより低いCPU使用率で発動するように運用していますが、スパイク時は追いつく前にアクセスが集中してしまいます。 そのため、発動を待つよりも、CPU使用率が50%を超えた時点でコンテナを増やす判断をしたほうが、カンファレンス運営では安全だと考えました。 試験は次のサイクルで進めました。 想定する負荷規模のシナリオをGrafana Cloud k6から実行する DatadogでバックエンドサービスのCPU使用率とSLOに関わるメトリクスを観測する CPU使用率が閾値(50%)を超えた場合はコンテナ数を増やし、同じシナリオを再実行する SLOの範囲内に収まる最小のコンテナ数を、その負荷規模での必要数として記録する この流れを負荷規模ごとに繰り返した結果、想定するカンファレンスの規模ごとに必要なコンテナ数を割り出すことができました。これにより、開催前のコンテナ調整を経験頼みではなく計測値に基づいて行えるようになっています。 Datadogで取ったメトリクス 試験中はCPU使用率のほかにも、次のメトリクスをDatadogで観測しました。 メトリクス 観測する目的 ECSのCPU・メモリ使用率 コンテナのリソースに余裕があるか(コンテナ数判定の主指標) APMのレイテンシ(p95) 遅いリクエストがSLOの範囲に収まっているか DBのコネクション数 データベース側がボトルネックになっていないか エラー発生率 負荷によってエラーが増えていないか また、試験結果の分析にはDatadogのBitsAIも活用しました。試験中のメトリクスからサマリを生成してNotionに集約し、開発チームへの共有や改善提案につなげています。 まとめ 今回は、Grafana Cloud k6とDatadogを組み合わせて、Findy Conferenceの負荷試験環境をゼロから構築した取り組みを紹介しました。コンテナ数の判断を、チームの経験値から計測値に基づくものへ変えられたことが大きな成果です。 ここで整理した手順は他のサービスにも応用できると考えており、今後はファインディで提供している各サービスでも横断的に負荷試験を実施できる体制へ広げていきたいです。 この記事が、これから負荷試験に取り組むエンジニアの方々やチームの参考になれば嬉しいです。最後までお読みいただきありがとうございました! ファインディでは一緒に会社を盛り上げてくれるメンバーを募集中です。興味を持っていただいた方はこちらのページからご応募お願いします。 herp.careers
こんにちは。ファインディ株式会社でテックリードマネージャーをしている戸田です。 2026年6月17日に、Findy AI Meetup in Fukuoka #6を福岡で開催しました。当日参加くださったみなさま、ありがとうございました! findy-inc.connpass.com 今回のテーマは「AI×レビュー AIと共に変わるレビューの形」です。 AIで開発が速くなった一方で、レビューが新たなボトルネックになりつつあります。この記事では、当日のメイン登壇「生成AI時代のレビューを再設計する」を振り返りながら、ファインディが1500以上のPRに適用してきたレビューの仕組みを紹介します。 なお今回の登壇は、先日のAI Engineering Summit Tokyo 2026での登壇内容をベースに、レビューにフォーカスして再構成したものです。 tech.findy.co.jp Findy AI Meetup in Fukuokaについて 生成AI時代のレビューを再設計する AIで速くなったはずなのに、レビューが詰まり始めた 何が起きていたか — 4つの連鎖 AIが出力したコードの責任は「人間」にある コードレビューで「AIに任せる範囲」と「人間が見る範囲」を分ける まとめ Findy AI Meetup in Fukuokaについて Findy AI Meetupは、ファインディのエンジニアが主催する技術系オフラインイベントです。 生成AIやAIエージェントの活用を通じた開発生産性の向上をテーマに、社内での実践事例の紹介やエンジニア同士の交流を目的としています。 福岡での開催は今回で6回目となりました。回を重ねるごとに参加者同士の顔なじみも増え、福岡のエンジニアコミュニティとして根付いてきたことを実感しています。 今回はメイン登壇1本とLT2枠の構成で、定員35名は満席となりました。この記事では、そのうちメイン登壇の内容を振り返ります。 生成AI時代のレビューを再設計する メイン登壇では、ファインディ社内でレビューに何が起きていたのか、そこからどうレビューを設計し直したのかをお話ししました。 AIで速くなったはずなのに、レビューが詰まり始めた 最初に共有したのは、2025年のファインディ社内の開発データです。前年と比べると、次のような変化が起きていました。 指標 変化 補足 稼働人数 1.5倍 メンバー数は増加 1人あたりのPR作成数 横ばい 個人あたりの生産量は伸びず レビューからApproveまでの平均時間 +20分 前年比で延びた レビュー1件あたりの平均コメント数 +30% 指摘量が増えた 数値はいずれも2025年通年の社内データを前年と比較したものです。人数が1.5倍になればチーム全体の開発量は増えるはずなのに、1人あたりのPR作成数は横ばいで、レビューにかかる時間とコメント量はむしろ増えていました。 AIで開発を速くしたはずが、品質の確認とレビューが新しいボトルネックになる。この逆転現象が、社内のあちこちで起き始めていたのです。 何が起きていたか — 4つの連鎖 詰まりの正体を分解すると、次の4段階の連鎖になっていました。 AIでコード生成が高速化し、PRの提出ペースが上がる 書いたコードを十分に理解しないままPRを提出する 「本来は作成者が理解しておくべき部分」までレビュアーが肩代わりする レビュアーに負荷が集中し、人間レビューが詰まりの主因になる つまり、AIで速くなった工数がそのままレビュアー側に流れ込んでいた、ということです。上流の確認が追いつかないまま、その負担を下流のレビューが引き受ける構造になっていました。 AIが出力したコードの責任は「人間」にある ここで整理したのが、工程ごとの担当と責任の所在です。コードを書くのもPRを作るのもAIに任せられますが、品質と最終判断の責任は人間が引き受けます。 工程 担当 責任 コード変更 Pull request作成 セルフレビュー AI コード変更に対する責任 レビュー 人間 作っているものに対する責任 ポイントは、セルフレビューまでを「コード生成」の工程に含めてしまうことです。「AIに書かせて終わり」ではなく「AIに書かせ、AIにセルフレビューさせるところまでが生成」と捉え直すと、人間のレビュアーは初めて見るコードの粗探しから解放され、責任の境界がはっきりします。 コードレビューで「AIに任せる範囲」と「人間が見る範囲」を分ける 責任の境界が決まると、レビューで見るべき観点も自然と整理できます。登壇では、レビューを次のように2つの領域へ切り分けました。 AIに任せる (セルフレビュー) 人間が確認する (レビュー) コード規約・命名 ビジネスロジックが要件をクリアするか 型定義 アーキテクチャ・設計の妥当性 テストコード・テストケース 明確なセキュリティリスク AIに機械的なチェックを任せることで、人間の視点はコードそのものから一段引き上がり、より抽象的な観点に集中できます。レビューが「規約に沿っているか」の確認作業から、「この設計でいいのか」を考える時間へと変わっていく感覚です。 実際にファインディで運用しているレビュー用のSkillなどの解説は、登壇資料や以前の記事でも紹介していますので、是非ご覧になってください。 tech.findy.co.jp tech.findy.co.jp まとめ 生成AIの登場で、レビューには変わったことと変わらないことの両方があります。 変わったのは、AIに任せられる範囲が広がったことです。規約・命名・型・テストといった機械的なチェックはAIに委ね、人間のレビューはビジネスロジックや設計、要件への適合といった、より抽象的な観点へと移りました。 変わらないのは、最終的な品質と判断の責任を人間が引き受けるという点です。AIがどれだけコードを書いても、それを世に出す責任は人間に残ります。 AIに任せる範囲 人間が確認する範囲 コード規約・命名 ビジネスロジック 型定義 アーキテクチャ・設計 テストコード・テストケース セキュリティリスク 機械的なチェック全般 要件への適合 この境界を成り行きに任せず、意図的に設計すること。それが、生成AI時代のレビューだと考えています。 そして早くも次回開催が決定しました!2026年8月5日(水)に開催予定です。 皆さんの熱いご支援のお陰で、Findy AI Meetup in Fukuokaは次回で1周年となっております。そこで次回は「AI × これまでと、これから AI開発の"今まで"と"これから"を語り尽くそう」と題しまして、AIに関して熱く語る会にしたいと思っています。ぜひご参加ください。 findy-inc.connpass.com ファインディでは一緒に会社を盛り上げてくれるメンバーを募集中です。興味を持っていただいた方はこちらのページからご応募お願いします。 herp.careers
こんにちは、Findy AI+のエンジニアをしている山岸です。 エンジニアの毎日は、頭をフル回転させることの連続です。 難しい課題に向き合い、コードと格闘した日ほど、ランチの一皿がじんわり沁みる――。 午後のスイッチを入れ直してくれるそんな一食は、エンジニアにとってちょっとした活力源だと思っています。 前回好評だった天ぷら特集の Part1 に続き、今回は Part2 を執筆しました。 焼肉と唐揚げ、それぞれの「これが私のご褒美ランチ!」をお届けします! 大阪・梅田:精肉卸問屋直営焼肉店 牛次郎 東京・五反田:話食よし おわりに ■ dan / AI+開発 ■ 普段はFindy AI+でバックエンド・フロントエンドの開発をしているdanです。 大阪・梅田:精肉卸問屋直営焼肉店 牛次郎 お店の基本情報 場所 : 大阪府大阪市北区曽根崎2-5-22 日宝パティオ曽根崎 1F 営業時間 : 月〜金 15:30〜27:00 / 土日祝 12:00〜27:00 価格帯 : ¥1,000〜 雰囲気 : 客層は幅広く、ひとりでふらっと入っても、仲間とワイワイ行っても馴染める気取らないお店 梅田ダンジョンに飲み込まれたくない方は、BIGMAN → HEP FIVE → お初天神のルートがおすすめです。 梅田周辺は飲食店が多すぎて、逆にどこに行くか迷いがち。牛次郎はお初天神の通りをまっすぐ進んでいくとたどり着けるので、梅田に慣れていない人でも比較的行きやすい場所にあります。 おすすめはハラミとユッケ。 ランチ写真 ハラミは焼いて食べてみると、脂っこすぎず、でもしっかり肉の旨みがあります。タレでごまかす感じではなく、肉だけでちゃんと美味しい。これ食べたらもう〆に行っていいレベルです。 ユッケは、焼肉屋でよくある細長くカットされたスタイルではなく、薄切りのお肉をお皿に広げ、その上に卵黄と薬味がのった独特のスタイル。薬味は少しスパイシーで、卵黄のまろやかさと合わさってパンチのある味わいです。 食べる前後の楽しみもあります。ミナミの雰囲気はちょっと怖いけど大阪らしさを感じたい、グラングリーン大阪でチルしたいなど、牛次郎の周辺には寄り道したくなるスポットが揃っています。美味しい焼肉と街歩きをセットで楽しめるのも、梅田ならではの魅力です。 ■ 山岸真悠子 / CTO室 AI推進 / AI+開発担当 ■ こんにちは、CTO室のAI推進でFindy AI+の開発を担当している山岸です。 ファインディのオフィスは大崎にあるので、ランチには隣の五反田までよく足を運んでいます。 今回ご紹介するのは、五反田駅前にある創作和食のお店、 話食よし です。ランチの唐揚げ定食がとにかく美味しいので、ぜひ知っていただきたく筆を執りました! 東京・五反田:話食よし お店の基本情報 場所 : 東京都品川区西五反田1-7-1 リビオ五反田プラグマGタワー2F(五反田駅から徒歩1分、大崎広小路駅から徒歩6分) 営業時間 : ランチ 平日11:30〜14:00 / ディナー 17:00〜23:30(不定休) 価格帯 : ランチ ¥1,000〜¥1,999 / ディナー ¥5,000〜¥7,999 雰囲気 : 五反田駅前なのに落ち着いていて、ひとりでもカジュアルに入れる和食店。半個室があるので会食にも使えます 五反田の駅前というと賑やかなイメージがあるかもしれませんが、ここは一歩入ると驚くほど落ち着いた雰囲気です。 気取らずにふらっと入れるのに、ちゃんと美味しい。そんなちょうどいいお店です。 ランチ写真 おすすめは 唐揚げ定食 。 まずは全景から。メインの唐揚げに、ごはんと味噌汁、それに卵焼きやひじき、千切りキャベツ、漬物の小鉢がついた王道の定食スタイルです。 彩りも良く、運ばれてきた瞬間にテンションが上がります。 そして主役の唐揚げ。衣がカリッ、サクッとしていて、おそらく片栗粉で揚げているタイプです。 中はジューシーで、ポン酢と大根おろしでさっぱり、マヨネーズでこってり、と一皿で二度おいしいを楽しめます。 ごはんはツヤツヤ。一粒一粒がしっかり立っていて、これだけでも箸が止まりません! さらに嬉しいことに、 味噌汁はおかわり自由 です。 ちなみに夜に行っても外れなし。鮮魚を使った創作和食が美味しく、半個室があるので少人数の会食やチームの集まりにもぴったりです。 最近五反田ではお気に入りのお店の閉店が続いていて、「もっと通っておけばよかった」と思うことが何度かありました。 美味しいお店との出会いも、結局は通い続けてこそだよなあと。推しのお店には、無理のないペースで足を運んでいきたいですね。 五反田でランチに迷ったら、ぜひ話食よしへ。みなさんもぜひご賞味あれ〜 おわりに 今回は焼肉と唐揚げのお店をご紹介しました。どちらもエンジニアの日々を支えてくれる、元気の源になるランチです。 ファインディには「社内コミュニケーション補助」という制度があり、組織や拠点を超えた交流が促進されています。おすすめのランチを共有し合えるのも、このシリーズの楽しみのひとつです。 また、今回ご紹介したように、ファインディでは全国各地からさまざまなエンジニアが活躍しています。技術にこだわり、より良いものを追求する仲間とともに働いてみませんか? 現在、新しいメンバーを募集しています。興味のある方は、ぜひこちらからチェックしてみてください!
こんにちは。ファインディのPlatform開発チーム(以降、SREチーム)でSREを担当している原( こうじゅん )です。 SREチームでは、AWSのユーザーとGitHubのアカウントの管理をTerraformで運用しています。Slackから申請が来たらTerraformのコードを書き換えてPRを出す、という作業を以前はDevinで自動化していました。 しかしDevinのアカウント利用形態が変わったことをきっかけに、この自動化基盤をClaude Code Actionsへ移行しました。同じようにAIツールでインフラ運用を自動化している方や、Claude Code Actionsの実践的な使い方を探している方に向けて、移行に至った判断理由と、移行後のアーキテクチャについて紹介します。 背景:Devinでアカウント管理を自動化していた 移行を決めた理由 移行後のアーキテクチャ triageジョブ:申請の振り分け routine-prジョブ:ファイル編集とPR作成 escalateジョブ:自動処理できない申請の通知 まとめ 背景:Devinでアカウント管理を自動化していた ファインディでは、GitHub Teamへのメンバー追加やチームの作成・廃止といったアカウント管理を、SREチームがTerraformで運用しています。 エンジニア・ビジネスサイド問わず、メンバーがSlackから申請を出すと、SREがTerraformのコードを手動で書き換えてPRを出し、レビュー・マージ後にapplyされる、という流れでした。毎回決まったパターンのYAML編集とPR作成を手作業でやるのは、典型的なトイルです。 このトイルを減らすために、Devinを使って自動化していました。Slackの申請内容をDevinに渡すと、Terraformリポジトリのコードを編集してPRを作ってくれる仕組みです。この取り組みの詳細は次の記事で紹介しています。 tech.findy.co.jp 移行を決めた理由 きっかけは、 2026年4月1日のDevinのアップデート です。このアップデートでDevinアカウントを持たないユーザーはSlackのDevinスレッドに参加できなくなりました。 アカウントを持たない申請者が@Devinに返信してもDevinが反応せず、「動かない」というSREへの問い合わせが増えました。コンプライアンス上、全メンバーへのアカウント一律払い出しも現実的ではありません。そのため、Devinからの移行に踏み切りました。 移行先の選定にあたっては、次の3つを重視しました。 全メンバーが個人アカウントなしで使えること — Anthropic公式の@Claude(Claude in Slack)も検討しましたが、各ユーザーにClaude Codeのアカウントが必要で同じ問題を抱えて断念しました 申請者の体験を変えないこと — Slack Workflowのフォームはそのまま、バックエンドだけを差し替えます チームのツール統一 — 開発チーム全体がすでにClaude中心の開発体制になっており、自動化基盤もそれに合わせました この選定理由より、今回のアーキテクチャとなりました。 移行後のアーキテクチャ 移行後の全体構成は次のとおりです。 flowchart TD subgraph Slack["Slack (申請者の体験)"] F1["メンバー申請"] F2["チーム申請"] Thread[("申請者スレッド")] end subgraph GHA["GitHub Actions"] Triage["triage\n(Claude Code Action)\n整合性チェック・名前解決"] RoutinePR["routine-pr\n(Claude Code Action)\nファイル編集・PR作成"] Escalate["escalate\n自動処理不可を通知"] end SRE["SRE承認・マージ"] Apply["terraform apply"] F1 -->|workflow_dispatch| Triage F2 -->|workflow_dispatch| Triage Triage -->|routine| RoutinePR Triage -->|escalate| Escalate RoutinePR -->|PR作成| SRE RoutinePR -->|受付通知| Thread Escalate -->|エスカレ通知| Thread SRE -->|マージ| Apply Apply -->|完了通知| Thread classDef unchanged fill:#e6f4ea,stroke:#34a853,stroke-width:2px,color:#1b5e20; class F1,F2,Thread unchanged style Slack fill:#f1f8f4,stroke:#34a853,stroke-width:2px; Slack Workflowからの申請がGitHub Actionsのworkflow_dispatchをトリガーし、正常系ではtriageジョブとroutine-prジョブの2つのClaude Code Actionが順に処理する構成です。 ただし、Slack Workflow Builderから直接workflow_dispatchは呼べません。間にSlack Custom Function(Deno Slack SDK)を挟み、GitHub APIへの認証付き呼び出しを行っています。 api.slack.com sequenceDiagram participant WF as Slack Workflow Builder participant CF as Custom Function<br/>(Deno Slack SDK) participant GH as GitHub API WF->>CF: フォーム入力値を渡す CF->>CF: GitHub App秘密鍵でJWT署名 CF->>GH: JWT → Installation Access Token取得 GH-->>CF: Token返却 CF->>GH: workflow_dispatch(Token認証) GH-->>CF: 202 Accepted 申請者から見ればSlackのフォームに入力するという体験は変わっていませんが、裏側ではCustom FunctionがGitHub Appの認証(JWT署名 → Installation Access Token取得)を行い、workflow_dispatchを呼び出しています。 triageジョブ:申請の振り分け 最初のClaude Code Actionは、申請内容の整合性チェックと振り分けを担当します。 チーム名の名前解決(申請者が入力した表記ブレを、リポジトリ上の実際のディレクトリ名に解決する)、申請内容のバリデーション、そしてroutine(自動処理可能)かescalate(自動処理不可)かの判定を行います。 triageとPR作成を1つのジョブにまとめることもできますが、責務と権限を分離するためにあえて分けました。triageジョブは --max-turns 5 と少ないターン数に制限し、使えるツールも Read と Bash(ls:*) だけに絞っています。判定がおかしければPR作成に進まない安全弁にもなります。 判定結果はJSON Schemaで構造化出力させるので、後続のジョブが確実にパースできます。 claude_args : | --max-turns 5 --allowedTools Read,Bash(ls:*) --json-schema '{"type":"object","properties":{"verdict":{"type":"string","enum":["routine","escalate"]},...}}' routine-prジョブ:ファイル編集とPR作成 triageでroutineと判定された申請は、2つ目のClaude Code Actionが処理します。TerraformリポジトリのYAMLファイルを編集し、ブランチを切ってPRを作成するジョブです。 --max-turns 20 とターン数を多めに確保し、ファイル編集やgit操作、PR作成に必要なツールを許可しています。 claude_args : | --max-turns 20 --allowedTools 'Read,Edit,Write,Bash(git checkout:*),Bash(git add:*),...,Bash(gh pr create:*)' PR作成後はSlackの申請スレッドに受付通知を送り、SREがレビュー・マージすればterraform applyが走って完了通知が届きます。 escalateジョブ:自動処理できない申請の通知 triageが自動処理できないと判断した申請は、Slackの申請スレッドにその旨が通知されます。Claude Code Actionは使わず、シェルスクリプトで通知を送るだけのシンプルなジョブです。 まとめ Devinのアカウント利用形態変更をきっかけに、アカウント管理の自動化基盤をClaude Code Actionsへ移行しました。Claude Code Actionをtriage(振り分け)とroutine-pr(PR作成)の2段階に分け、それぞれの責務と権限を絞った設計にしています。 現在、GitHubアカウント管理の移行は完了し、運用を開始しています。今後はAWSのユーザー管理なども移行を進めていきます。 ファインディでは一緒に会社を盛り上げてくれるメンバーを募集中です。興味を持っていただいた方はこちらのページからご応募お願いします。 herp.careers
ファインディの森( @jiskanulo )と西村( @sontixyou )です。 2026年6月11日に開催されたAnthropic主催のイベント「Code w/ Claude: Extended | Tokyo」に終日参加してきました。 claude.com 本記事はその参加レポートです。私たちがセッションを聴いてどう感じたか、セッションの内容をどう活かすかの感想も書いていきます。 Workshopで気になったセッション How we Claude Code Ship your first Managed Agent ドメインエキスパートがソフトウェアを作る What happens when domain experts can finally build The 1% problem: How domain expertise + Claude let a 2-person team hit #1 on a global classification benchmark まとめ ファインディでは一緒に働く仲間を募集しています Workshopで気になったセッション 西村は主にAnthropicメンバーによるWorkshopへ参加しました。Anthropicが取り入れている設定や仕組みを弊社のプロダクト開発フローに適用できるかを意識して聴きました。 How we Claude Code claude.com Anthropicメンバーが実際に使っているClaude Codeのセットアップ方法を紹介するものです。 今回のイベントでのワークショップで説明された題材は次のリポジトリで公開されています。 github.com このセッションで最も印象に残ったのは「徹底インタビュー」と「HTML先行プロトタイプ」の2つです。 「徹底インタビュー」では、Claude Codeにインタビュアー役を担わせて要件を引き出します。 インタビューでは、つぎのインタビュープロンプトをClaude Codeに渡して、HTMLのプロトタイプを作るための要件を引き出す設計になっていました。 I want to build a bill-splitting app, can you help me brainstorm with me on who the audience is, and then interview me in-depth using the AskUserQuestion tool about what to build, focusing on pulling out any ambiguities to create a spec. 上記のプロンプトを実行し、Claude Codeとのやりとりを通して、要件の曖昧さを潰していき、SPEC.mdを作成する流れが紹介されました。要件の曖昧さを上流で潰すことで、実装のやり直しを減らすという設計思想です。 つぎに「HTML先行プロトタイプ」ではSPEC.mdをもとに、4つの異なるデザインを提案させて、HTMLのプロトタイプを作る流れが紹介されました。 Read ../phase-1-planning for its spec file, then help me figure out the overall design of this app. Explore 4 different designs, and create a set of HTML files with important screens for each. 上記のプロンプトを実行すると、つぎのHTMLのプロトタイプが出力されました。 Markdown形式でデザイン仕様を書き出すのではなく、クリックできるHTMLのプロトタイプを出力することで、見た瞬間に判断できます。 設計するタイミングで、Claude Codeとの認識合わせが視覚的にできることで、実装フェーズでのやり直しが少なくなり、トークン使用量の削減につながります。 また、既に運用しているサービスではデザインシステムといったデザイン基盤があれば、精度よくHTMLを出力できる可能性があります。それによって、新しい機能のデザインをするときの認識合わせがスムーズになりそうだと思いました。 Ship your first Managed Agent claude.com Claude Managed Agents(CMA)の全体像を、インシデントレスポンスのデモを通して整理するワークショップです。 このセッションで印象に残ったスライドが「The brain left the box」でした。 以前のアーキテクチャは、Agent loopとTool executionが同じコンテナの中に同居していました。Managed AgentsではAnthropicが管理する1つのサービスとして動き、ツール実行のSandboxはツールが必要なときだけオンデマンドで起動します。クライアントが切断されていてもループは動き続けるため、ローカルのターミナルを閉じてもセッションが止まりません。 これまで西村の開発環境のClaude Codeの使い方では、ローカルPCでClaude Codeを稼働させているため、プロンプトを入力しないとAIエージェントが動き出せませんでした。また、並列セッション数も最大8が限界でした。 Managed Agentsはこの2点を変えられると感じました。オンデマンドで非同期で動き続ける実行環境があれば、人間の合図を待たずに実装する用途が一気に現実的になります。 試したい用途として思い浮かんだのは、着手できていないイシューの開発・リファクタリング、そして人間が介在せずにPRをマージすることです。 最後の「自律マージ」には前提条件を考えなくてはいけません。最低限必要な前提条件を決めておかなければなりません。 例えば、テストカバレッジが一定基準を超えていること、テストの堅牢性が担保されていることなどです。 これらの前提条件を満たすための仕組みを整えることが、AIエージェントによる自律マージの実現に向けた重要なステップになると感じました。 ドメインエキスパートがソフトウェアを作る 森はFounder stageを中心に話を聞いていました。 いずれのセッションもドメインエキスパートの知識・決定が重要であることを話されていました。 いくつかご紹介します。 What happens when domain experts can finally build claude.com 登壇はクイーンズランド大学のJason Tangen教授。AIネイティブ時代のプロダクトは、汎用的な人材ではなく深いドメイン知識を持つ個人から生まれるという主張です。 「去年までソフトウェアを一行も書いたことがなかった」という彼が、6ヶ月で3つの本番アプリをデプロイしました。 登場したアプリはいずれも学生向けのもので、シラバス生成ツール(classbuild.ai)、法廷証言トレーニング(crosscoach.ai)、学生向け説明ツール、学生の顔と名前を覚えるゲームなど。 専門家の頭の中に眠っていたアイデアが、AIにより作るコストが下がり具現化できるようになりました。 最後に聴衆へ「あなたが何年も密かに欲しいと思っていた小さなツールは何ですか?」「チームの中で、実際にその仕事をやり続けてきた人は誰ですか?」と問いかけられました。 コードを書く能力ではなく、「何を作るべきか」を知っていることが大切なのだと感じました。 The 1% problem: How domain expertise + Claude let a 2-person team hit #1 on a global classification benchmark claude.com 登壇者はGahee Seo氏。分類の誤りが金銭的損失に直結する貿易コンプライアンス領域で、ドメイン知識とClaudeの組み合わせが基盤モデル単体を超える優位を生むことを示します。 韓国からEUへの輸送など、さまざまな規制が複雑に絡み合う貿易の領域では、どんなAIモデルを使うかよりも専門家の判断フローをどう再現するかが優位を決めるとのことです。 最初のプロトタイプはSingle agentで1件の分類に6分かかっており、また、アウトプット精度にも課題があったとのことです。 課題を解決するために分類器を新しく訓練するのではなく、専門家が5段階で判断するワークフローを複製したという設計思想を発表してくれました。 入力が曖昧なまま処理が走らないようinput gateを設けたこと 全規制ルールをsystem promptに詰め込む設計をやめ、必要な文書を検索する Retrieval と出力結果を検証する Verifierという構想に転換 これらの対応をとりあげていました。さらにエージェントを役割ごとに分割することで30秒まで短縮しました。 アウトプットではなくワークフローを教える、という発言もありました。 期待する出力形式を示すのではなく、専門家がどういう順番で何を見て判断するかをシステム化する。職人芸をインフラに変える、という表現が使われていました。 まとめ 西村が午前に参加したAnthropicのワークショップ2つには、共通した問いがありました。 How we Claude CodeのHTMLプロトタイプは、実装前に人間の判断を前の工程に集約する仕組みです。Ship your first Managed Agentの非同期実行は、後工程での人間の介在を手放すための基盤です。 方向は逆に見えますが、根底にある問いは同じだと感じました。「人間はどこで関与すべきか」を先に設計する、という考え方です。その2点を組み合わせることで初めて、AIと人間の役割分担がきちんと設計できると思いました。 森の参加したセッションは「個人開発者・アーリーステージな創設者向け」という性格のものが多かったです。個人が専門知識を武器にプロダクトを作る事例が多く、それ自体は示唆に富んでいました。 どのセッションでも専門家の知識、決定が大事であるという主張を別の角度から語っていました。 一方で、チームでどう使っていくか・チームの中でどう成長していくかという話はありませんでした。 最近個人的に悶々としている「専門家がいない領域でどう専門性を担保するか」「専門家をどう育てるか、時間をかけるしかないのか」という問いには答えが見つからなかったので引き続き考え続けます。 ファインディでは一緒に働く仲間を募集しています ファインディでは一緒に会社を盛り上げてくれるメンバーを募集中です。興味を持っていただいた方はこちらのページからご応募お願いします。 herp.careers
こんにちは。 ファインディ株式会社でテックリードマネージャーをやらせてもらっている戸田です。 生成AIが開発現場に入り込んでから1年あまり。Claude CodeやGitHub Copilotなどのエージェント型ツールも一般的になってきました。 その一方で、「AIを導入したのに、思ったほど速くなっていない」「むしろレビューが大変になった」という声を、社内外でよく聞くようになりました。 そんな中で先日、弊社主催の「AI Engineering Summit Tokyo 2026」にて 「速く作る」から「正しく作る」へ ─ 生成AI時代の開発フロー改革のロードマップと実行 ─ と題して登壇してきました。 ファインディ社内で1年強かけて見えてきた「AI導入の落とし穴」と、そこから組み立てた3段階のロードマップを共有する内容です。 ai-engineering-summit-tokyo.findy-tools.io この記事では登壇内容を振り返りつつ、AI導入の効果が伸び悩んでいる組織に向けて、ファインディがどのような順番で開発フローを作り変えてきたかを紹介します。 それでは見ていきましょう! AIを入れたのに、アウトプットは伸びていなかった 「速く作る」だけでは限界がある AI活用レベル レベル 1:AIエージェントでコード生成 レベル 2:AIエージェントでモノを作る レベル 3:AIで価値を生み出す まとめ AIを入れたのに、アウトプットは伸びていなかった ファインディも同様に生成AIの本格活用を進め、Claude CodeやCodexなどのAIエージェントが日常的な開発フローに入り込んできました。社内の体感としては「1人あたりのPR作成数も増えていそうだし、開発のリードタイムも短くなっているはず」というものでした。 しかし、Findy Team+で1年分の数値を計測してみると、想像とは違う景色が見えてきました。 まずポジティブな変化として、PR作成総数は前年比で伸びていました。ただ、その内訳を見ると、稼働メンバー数が約1.5倍に増えていたことが大きく、1人あたりのPR作成数はほぼ横ばいだったのです。 さらに、レビュー開始からApproveまでの時間は前年比でおよそ20分延び、PR1本あたりの平均コメント数・レビュー数も約30%増えていました。AIによるコード生成が増えた一方で、レビュー側の負荷が確実に積み上がっていたわけです。 シニア層と若手層で傾向を分けて見ると、もう一段深い構造が見えてきました。AIの出力を読んで検証できるシニアメンバーはアウトプットが上がる一方、経験年数が浅いほどAI出力の合否判断に苦戦する傾向があり、結果としてレビュー側に判断の負荷が集中していました。 組織全体として、 AIに使われている 状態に近かったとも言えます。「体感と事実がズレているかもしれない」と疑い、各種数値を可視化していたからこそ、実は「1人あたりのPR作成数は増えておらず、それどころかレビューの負荷が増えており、結果的に開発のリードタイムは長くなっていた」ことに気づくことができたのです。 「速く作る」だけでは限界がある 計測結果から見えてきたのは、「コードを書く速度が上がっても、ボトルネックがレビューに移り変わったために、全体のリードタイムは短くならなかった」、ということでした。 AIでコードを書くスピードは確かに上がります。一方で、内容を十分理解せずに生成するケースが増えると、PRの一貫性や正確性が落ちます。 指摘の量が増えると、リードクラスのレビュー時間が膨らみ、リードタイムが悪化します。最終的に、トータルのアウトプットはAI導入前とほぼ変わらない、という結果に着地します。 AIの成果物に対する確認や検証に時間がかかるようになり、レビューの負荷が増える。これがAI導入の落とし穴の一つです。そのため、AIの成果物の品質を再現性高く担保するための仕組みを整えることが必要になります。 そのために必要になるのが、「正しい作り方と手順」を仕組み化することです。馬を御する馬具(ハーネス)になぞらえ、AIの動きを暴走させず目的の方向へ導くための仕組みを整えることを ハーネスエンジニアリング と呼びます。 このハーネス化を、ファインディは 開発フロー改革 として進めてきました。具体的には、AI活用のレベルを3段階に分け、土台から段階的に積み上げていくロードマップを描いています。 AI活用レベル 開発フローを分解し、AIで何を肩代わりできるかをマッピングすると、3つのレベルが浮かび上がりました。 レベル 1:速く作る :コード変更とPR作成を中心に、AIで代替できる範囲を自動化する レベル 2:正しく作る :タスク分解とIssue作成までAIに任せ、「正しく作る」仕組みを整える レベル 3:必要なものを作る :要件定義やQAという「AIで代替しづらい」とされてきた領域に踏み込む ポイントは、「どれか1つを単独でやる」のではなく、Lv1 → Lv2 → Lv3 と段階的に積み上げて初めて効果が出るという点です。ここから各レベルを順に見ていきます。 レベル 1:AIエージェントでコード生成 レベル 1の目的は、コード変更とPull request作成までをAIエージェントに任せ、人間は本質的なレビューに集中することです。 このフェーズで真っ先に向き合う必要があるのは、「AIが出したコードの責任は誰にあるか」という問いです。 どれだけ自動化されても、AIが出力したコードの責任は人間にあります。品質と判断の最終責任は人間が引き受けることになります。 その前提の上で、レベル 1の工程を整理してみました。 コード変更とPull request作成はAIに全て任せることが出来ます。そしてレビューに関しては、コードの責任という観点から人間が行う必要があると考えていました。しかし、本当にそうなのか疑問に思いました。 自分自身がコードを書いてPull requestを作成していた頃を思い出してみてください。自分でコードを書いて、Pull requestを作成する。レビュー依頼を出す前にやっていたことがありました。セルフレビューです。 そしてセルフレビューで気づく内容と、実際に他のメンバーからもらうレビューの内容は観点や内容が違います。これを今回の開発フロー改革に当てはめました。 レビューをセルフレビューとレビューに分け、レベル 1ではセルフレビューまでをAIに任せることにしました。セルフレビューではコード変更そのものに対するレビュー、レビューでは人間が最終判断しないといけない内容にフォーカスしてレビューというように切り分けることにしました。 ここで重要なのは、AIを入れる前提として「AIと関係なく当たり前のこと」が揃っている必要がある、という点です。 アーキテクチャ・命名規則・型定義といったコード設計、十分なテストカバレッジ、一貫した設計パターン、そしてPRの適切な粒度・レビュー文化・タスク分解の習慣。 これらはAI以前から品質を保つために必須でしたが、AIエージェントが入ると一気に効いてきます。土台が弱いと、AIはその弱さを増幅する方向に働くからです。 ファインディがこの「土台」をどう積み上げてきたかは、次の記事で詳述しています。 tech.findy.co.jp その土台の上に、AIが参照するドキュメントとルールをガードレールとして整備します。 READMEやプロジェクトドキュメントで開発前提・アーキテクチャ・運用ルールを記述し、AGENT.mdやrulesでコード規約・命名規則・テスト方針をAIに自動参照させ、カスタムコマンドやプロンプトテンプレートで依頼タスクを規格化する。 この整備があって初めて、AIは使い物になるコードを出力してくれます。 ファインディではレベル 1を支える仕組みとして、Claude CodeのSkillを複数組み合わせています。代表的なものは次の通りです。 Pull request作成:typecheck/lint/test/buildといった品質チェックの自動実行、ブランチ命名規則の強制、Conventional Commitに沿ったコミット生成、PRテンプレートからのbody自動生成までを1コマンドで実行 Pull request作成前の自動セルフレビュー:セキュリティ/コード品質/規約準拠/Simplify観点/要件検証/チェックリスト照合の6観点で並列分析。信頼度の高い指摘のみを報告してノイズを抑制し、2026年4月時点で1500以上のPRで運用中 AI併用レビュー:Codex CLIを別系統として並行運用し、メインAIのレビューと統合してPRコメントに提示。AIの偏りに依存しない複眼チェックを実現 定期セルフレビュー自動化:平日の朝方にGitHub Actionsで起動し、直近1ヶ月変更されていない技術的負債となりうる既存コードに対して修正Pull requestを自動作成 チェックリスト自動更新:過去レビューコメントをGitHub APIで収集し、LLMで指摘パターンを分類してチェックリストへ反映。レビュアーの暗黙知をSkillに形式知として残す セルフレビュー周りの仕組みについては、それぞれ次の記事でも紹介しています。 tech.findy.co.jp tech.findy.co.jp これらは1リポジトリにSkill/Sub Agent/MCPとしてまとめており、Pluginとして運用することで /plugin install によるワンコマンド配布を実現しています。全員がcontributeできる構造にすることで、改善がそのまま組織全体に反映される回り方になっています。 レベル 2:AIエージェントでモノを作る レベル 1で「速く作る」の足回りが整うと、次にぶつかるのが「要件をどう実現するか」の手順自体がAIフレンドリーではない、という壁です。タスクの粒度や手順を誰も明示的に決めていないため、生成AIに何を渡せば精度よく動くかが属人化していました。 ここで必要になるのが、「作りたいもの(What)」と「作り方の設計図(How)」を分離して扱う発想です。 Whatをタスク分解の形でHowに落とし込み、それをAIに渡せば、AIはそのステップどおりに実装してくれます。そしてレビューでは、出来上がったコードよりも先に「作り方と実現方法が合っているか」を検証し、設計図のほうにフィードバックする。タスク分解の品質が、そのままアウトプットの品質を決める構造です。 このフェーズでは、AIとの関係性が「協働」から「委任」に変わります。 Vibe Codingが「AIは隣で並走するパートナー」だとすると、Agentic Workflowは「AIは自走する実行エージェントで、人間はその指揮者」になります。 任せる粒度も、1行〜1関数のレベルから、タスク/PR/フロー全体へと拡張されます。 Agentic Workflowの定義として4つの自律性を意識しています。 ゴール指向 :「何を」を与え、「どう実現するか」はAIが組み立てる 計画と分解 :大きなタスクをサブタスクに分けて順序付けて実行 ツール使用 :ファイル・Skill・コマンド・検索・MCPを能動的に使う 自己検証ループ :テスト失敗→修正→再実行を自律的に繰り返す 興味深かったのは、AI委任の前提が変わると開発環境そのものが変わったことです。 2026年に入ってから、ファインディではコード生成のメインツールがIDEからターミナルへ変化しました。 1ウインドウで1タスクずつ進めるのではなく、複数ウインドウ・ペインで同時にAIへ委任するスタイルになったため、並列委任しやすい場所として、ターミナル+tmuxのような構成に自然と寄せていく流れになっています。IDEの役割はコードを書く場から、広域に渡るコードリーディングや理解を深める場へとシフトしています。 このレベル 2を支えるのが、要件構造化&Issue自動生成のSkillです。次の6ステップで動きます。 要件理解 ─ インタラクティブな質問で曖昧さを解消 コード探索 ─ 並列の探索Agentが複数観点で同時調査 要件明確化 ─ 不足情報を補完してスコープを定義 設計提案 ─ 実装方針のドラフトを生成 タスク分解 ─ 実装単位に分解(粒度判定Skill連携) Issue作成 ─ Sub Issue/relationshipを含む構造化Issue このSkillで生成したIssueは累計3000以上にのぼり、親Issue(Feature)→子Issue(DB層→API層など)が blocked_by の依存関係付きで自動構成されます。 例えば「ユーザー通知機能の追加」という親Issueに対し、「#1 DB層:通知テーブル追加」「#2 POST API追加」「#3 DELETE API追加」のような子Issueが、依存関係込みで一気に並ぶイメージです。 実装フェーズでは、これを「Issue × Worktree × Agent」の並列モデルで走らせています。Team Lead Agentが blocked_by に従ってLayerごとにWorker Agentを起動・同期し、同じLayer内はworktreeを切ってWorker Agentが完全並列で実装する。Layer 0でDB層が完了したら、Layer 1のPOST/DELETE APIを2つのworktreeで同時に進める、といった動かし方ができます。 この並列モデルの詳細は次の記事で解説しています。 tech.findy.co.jp コードレビューの分担も、レベル 2では明示的に再定義しています。 担当 レビュー領域 AI コード規約・命名、型定義、テストコード・テストケース 人間 ビジネスロジックの要件適合、アーキテクチャや設計、データベース構造、明確なセキュリティリスク 視点はコードそのものから抽象的なところに寄せていきます。 結果として、レベル 2の導入後、1人あたりのPR作成数は前年比で1.5倍を超えました。AIフレンドリーな「設計図(タスク分解+構造化Issue)」を誰でも作れる状態になり、作りたいものを再現性高くアウトプットできるようになった、というのがその答えです。 レベル 3:AIで価値を生み出す レベル 2まで進むと、開発スピードに対する次のボトルネックが見えてきます。「何を作るか」の上流が詰まり、せっかく整えた実装力を活かしきれない状態です。 具体的には、要件の実現可能性を調査できるのがエンジニアだけになっていたり、システムとプロダクトの概念が離れていて、お互いを十分知らないまま施策や検証が進んでしまったりします。 レベル 3の目的は、要件定義(PdM領域)とQA領域というAIで代替しづらいとされてきた領域に、AIで踏み込むことです。 レベル 3の起点になるのが 現状把握 です。現状把握の対象は広い範囲に及びます。コードベース・Google Analytics・プロダクト文書・GitHub Issues/PR・Datadog・各種KPIなど、必要なコンテキストは多岐にわたります。 まず要件定義では、これらを毎回手動で集めるのは現実的ではないため、専門Agentチームが各ソースから必要な分だけ自動収集する仕組みを組みました。 ファインディの要件定義Skillでは、7つの専門Agentが並列で動きます。 目的・成果分析 ─ WHY/WHAT仮説の自律生成 データ・コンテキスト収集 ─ GitHub Issues・Notionから数値収集 プロダクト文書抽出 ─ docs/配下のKPI・ポリシーを抽出 コードベース分析 ─ リポジトリの制約・パターンを分析 スコープ分割 ─ MVPと拡張項目に分割 技術的実現可能性評価 ─ 解決アプローチの実現可能性を評価 アクセス解析データ収集 ─ Google Analyticsから自動収集 これらのAgentがAgentTeamsとして並列で稼働し、お互い会話しながら必要な情報を集めて分析します。 ユーザーは分析結果を修正・補足し、最後にAIが構造化&品質チェックしてGitHub Issueとして出力します。ユーザー操作は入力・レビュー・承認の3回のみで、それ以外はAIが自律的に進める設計です。出力されたWHY/WHAT構造化済みIssueは、そのままレベル 2のIssue自動分解Skillに連携できます。 もう1つの挑戦がQA領域です。ユーザビリティ・アクセシビリティ・UI/UXといった非機能要件のテストはAI単独では難しいため、AIで代替しづらい領域です。ファインディは「代替」ではなく「支援」、つまりAIがQAエンジニアの判断を最大化する形を仮説にしています。 次にQA領域は3つのSkillで一気通貫にしました。仕様ソース(Issue/Figma/Notion)を入力に、次の流れで進みます。 QA観点抽出:観点を自動抽出してQA観点mdを出力 QAテストケース生成:観点→ステップ/期待結果/前提条件に展開してMarkdown+CSV化 QA自動実行:Playwright MCP経由でClaude Codeから直接ブラウザを操作し、Pass/Failとスクリーンショット付きのレポートを出力 QA観点抽出では、仕様分析/画面構造・UX探索/影響範囲判定の3つのAgentが並列で動き、観点設計のたたき台を数分で生成します。 テストケース生成では、観点→具体ケースへの落とし込みにかかる工数が数時間から数分に短縮されました。生成されたQAリストは、認証・認可/入力バリデーション/表示・UI/ファイル操作/外部連携/メール送信の6軸で共通基準と照合し、観点漏れ・粒度のばらつきを検出します。 人間が集中すべきは、ユーザビリティ評価、例外シナリオ、クライアント要件の確認といった「判断が必要な領域」です。反復可能なケースはAIが淡々と実行し、失敗時はスクリーンショット付きレポートで原因特定が速くなりました。 まとめ AI活用のレベルをレベル 1(速く作る)/レベル 2(正しく作る)/レベル 3(必要なものを作る)と分けてきましたが、最大の主張は、これらは「どれか1つ」ではなく段階的に積み上げて初めて成立する、ということです。 そして、ここで強調したいのが 順番を間違えない ことです。土台が弱いと、ガードレールもAI Skillも成果を出せません。ファインディが踏んだ順番は次の4段でした。 裏返すと、AIエージェントを入れる前にやっておくべきことは、AI以前から変わっていません。統一規約、テストコード、PR粒度、レビューなどの開発文化といった 基本の徹底 こそがAI活用における大前提です。 AI時代の本丸は、「速く作る」ではなく、「正しく作る」「必要なものを作る」への段階的越境です。あなたの組織が今どのレベルにいるか、そして次のレベルへ進むためにどの土台が弱いかを確認する目安として、このロードマップが役立てば幸いです。 ファインディでは一緒に会社を盛り上げてくれるメンバーを募集中です。興味を持っていただいた方はこちらのページからご応募お願いします。 herp.careers
はじめに こんにちは。ファインディでデータエンジニアをしている開( @hiracky16 )です。 今回はLookerに搭載されている会話分析機能を使って、ユーザーがより自律的にデータ抽出や分析ができるようにした話をします。セマンティックレイヤー(Explore)を会話分析に使用する設計や開発・テスト・評価までの運用のノウハウを紹介します。 会話分析(Conversational Analytics)は、Lookerに搭載されている機能で、自然言語で質問を投げるとエージェントが裏でクエリを組み立てて実行し、表やグラフを添えて答えてくれます。たとえば「1月から5月までのXXX数をUUベースで集計できますか?」と聞くと、次のように月別の集計結果とグラフが返ってきます。 はじめに 会話分析にセマンティックレイヤーを使う理由 セマンティックレイヤーを会話分析の入口にするメリット 参照先のデータを意味ある単位に限定できる コンテキストの肥大化を避けられる デメリット 運用 エージェント定義をGitで管理する 回答品質の評価 評価ケースを定義する 軸1: 回答テキストの品質をLLMで採点する 軸2: 発行されたクエリを決定論的に検証する フィードバックサイクルを回す 成果 まとめ 会話分析にセマンティックレイヤーを使う理由 以前公開したブログでは、Lookerを導入した背景や、登録ユーザーの7割がダッシュボードの作成・閲覧のために日々訪れていることを紹介しました。 tech.findy.co.jp tech.findy.co.jp これらの記事で触れたとおり、重要な指標や共通のディメンションは、セマンティックレイヤーへの集約を進めてきました。 集約した指標やディメンションを使ってダッシュボードを作り社内に展開していますが、「別の切り口で見たい」「集計ロジックを変えたい」といった要望に都度対応する運用となり、その工数が無視できなくなってきました。 一方で、会話ベースでデータ抽出・集計・分析ができるエージェントが世の中に広がってきました。私たちもGoogle製のADKを使って自作してみましたが、こちらもメンテナンスコストがかかります。さらに、全テーブルを対象にするため、SSoT(Single Source of Truth)が整っていない領域や、コンテキストが薄い領域では精度が出ず実用には届きませんでした。 ここで着目したのが、すでに集約を進めてきたセマンティックレイヤー(LookerのExplore)です。これを会話分析エージェントの入口に据えることで、ダッシュボード運用の工数と、自作エージェントのコンテキスト不足という両方の課題を解決できると考えました。全体像は次のとおりです。 flowchart LR subgraph DWH["データウェアハウス"] direction TB NOTE1[/"会社マスタが複数あり<br/>テーブル単位ではSSoTが曖昧"/] T1[fct_scouts<br/>送信済みスカウト] T2[fct_scout_replies<br/>スカウトへの返信] T3[fct_matches<br/>成立したマッチング] T4[dim_users<br/>ユーザー情報] C1[dim_companies_raw<br/>会社情報(raw)] C2[dim_company_master<br/>会社情報(master)] end subgraph SL["セマンティックレイヤー"] direction TB NOTE2[/"業務単位で集約し<br/>使う会社マスタもExploreで判断"/] E1["スカウトExplore<br/>送信数・返信率を定義"] E2["マッチングExplore<br/>成立件数・成立率を定義"] end T1 & T2 & T4 --> E1 T3 & T4 --> E2 C1 -->|スカウトはrawを使う| E1 C2 -->|マッチングはmasterを使う| E2 E1 --> A1[スカウト分析エージェント] E2 --> A2[マッチング分析エージェント] A1 & A2 --> U([利用者の質問]) 左側のデータウェアハウスには大量のテーブルが並び、どれを使えばよいか、指標をどう計算すればよいかはテーブル単位では自明ではありません。たとえば会社マスタが dim_companies_raw と dim_company_master のように複数存在し、用途によってどちらを使うべきかが曖昧、といったこともあります。これをそのままエージェントに渡しても、うまく答えられないのは当然です。 そこで、Explore側で「スカウト」「マッチング」といった業務の単位にテーブルを集約し、送信数や成立率といった指標の定義まで含めて整えておきます。会社マスタのように複数の候補があるものも、Explore側でどちらを参照すべきかを判断します。たとえばスカウトExploreでは dim_companies_raw を、マッチングExploreでは dim_company_master を使う、といった使い分けをExploreの定義として固定しておくわけです。エージェントは生のテーブルではなくこのExploreだけを見るので、何をどう集計すべきかが定まった状態で質問に答えられます。 セマンティックレイヤーを会話分析の入口にするメリット セマンティックレイヤーを入口に据えると、大きく2つのメリットがあります。 参照先のデータを意味ある単位に限定できる 1つのエージェントは1〜5個のExploreに紐づきます。エージェントが触れられるデータがExploreの範囲に限定されるためエージェントの役割がはっきりします。 また、SSoTが担保できていないテーブルであっても、Lookerから参照する形にすればExplore上でSSoTを表現できます。生のテーブルをそのまま渡すのではなく、Lookerというフィルタを通すことで、エージェントが扱うデータの意味を整えられます。ダッシュボードと会話分析で使用するExploreは同じなので、両者で数値が食い違うという事態も避けられます。 コンテキストの肥大化を避けられる 全テーブルをエージェントに渡そうとすると、コンテキストが膨れ上がり、かえって精度が落ちます。Exploreを入口にすれば、LookMLのdescriptionや指標定義がそのまま「正しい意味」のソースになり、必要な範囲のコンテキストだけを渡せます。 LookerはKnowledge Catalog(旧Dataplex)との連携も進んでおり、メタデータをカタログ側で一元管理できるようになってきています。 docs.cloud.google.com 今はLookMLのdescriptionにコンテキストを持たせていますが、今後はKnowledge Catalog側にも用語や定義を蓄積し、それをエージェントのコンテキストとして活かせるようになることを期待しています。 デメリット 一方で、当然ながら弱点もあります。複数のExploreをまたぐ横断分析やファネル分析は苦手です。たとえば、ファインディが主催するイベントへの参加やメディア閲覧といったイベントを起点に、実際に企業とのマッチングに至るまでの流れを追う、といった分析は守備範囲の外でした。それぞれのイベントが別々のExploreに分かれていると、エージェントはどちらか一方しか見られず、つながりを追えません。 そこで、ユーザーという意味のある単位でフェーズをまたいだデータを1行にまとめた累積ファクトを作り、Exploreとして用意することで対処しました。次のように、1行=1ユーザーで各フェーズの日付を横並びに持たせておきます。 user_key イベント参加日 メディア閲覧日 マッチング日 u_001 2026-04-01 2026-04-03 2026-04-20 u_002 2026-04-05 (なし) (なし) u_003 2026-04-10 2026-04-12 (なし) こうしておけば、1つのExploreの中で「イベント参加からマッチングまで到達した割合は?」といったファネルをたどれます。横断的な問いに答える必要があるものは、あらかじめこの形に整形しておき、エージェントからも参照できるようにしています。 運用 LookMLの開発方法は前述のブログで紹介しているので割愛し、今回はLooker会話分析に使うエージェントの開発・運用について説明します。 エージェント定義をGitで管理する 会話分析のエージェントは、Lookerの画面上からでも作成・編集できます。ただ、画面で直接編集すると、誰がいつ何を変えたのかが追えず、システムプロンプト(instructions)の変更履歴も残りません。 そこで、エージェントに必要な項目をYAMLファイルとして定義し、Gitで管理することにしました。1ファイルにエージェントのID、名前、参照するExplore(sources)、システムプロンプト(instructions)、そして後述する評価ケース(cases)をまとめています。 id : hogefugapiyo # 既存エージェントの更新用。新規作成時は省略 name : マッチング分析エージェント description : 企業と求職者のマッチング状況を分析するエージェントです。 code_interpreter : false # このエージェントが参照するExplore sources : - model : sample_recruiting explore : fct_matchings - model : sample_recruiting explore : fct_daily_snapshot_matchings # システムプロンプト instructions : | あなたはマッチング分析の専門アシスタントです。 LookerのExploreを使って、マッチングの成立件数・成立率・ セグメント別トレンドに関する質問に回答します。 ## 用語集 - マッチング : 企業と求職者の間で選考が始まった状態 - 成立率 : マッチング成立件数 ÷ いいね件数 ... # 評価ケース(評価の章で後述) cases : - prompt : "今月のセグメント別のマッチング成立率は?" reference : "セグメントでグループ化し、成立件数をいいね件数で割った値を回答する" ExploreやYAMLが編集されると、GitHub ActionsでLookerのエージェントに反映されます。 回答品質の評価 エージェントを運用に乗せると、「ちゃんと正しく答えられているか」が気になります。システムプロンプトやExploreを変更するたびに、回答の質が上がったのか下がったのかを判断したくなります。 そこで、エージェント定義に評価ケースを書いておき、CIで自動評価する仕組みを用意しました。 評価ケースを定義する 評価ケースは、前述したエージェント定義のYAMLに質問(prompt)と期待する答え方(reference)の組として書いておきます。たとえば次のように、想定される質問のバリエーションを並べておきます。 cases : - prompt : "今月のマッチング成立件数は?" reference : "当月のマッチング成立件数の合計を回答する" - prompt : "セグメント別のマッチング成立率を高い順に教えて" reference : "セグメントでグループ化し、成立件数をいいね件数で割った成立率を降順で回答する" - prompt : "先月と今月でマッチング成立件数はどう変わった?" reference : "先月と当月の成立件数を比較し、増減と差分を回答する" referenceには「完全一致の正解テキスト」ではなく、答えの作り方の説明を書いています。会話分析の回答は表現に幅があるため、文章の一致ではなく方向性で評価したいからです。 この評価ケースを使って、次の2軸で品質を測ります。 軸1: 回答テキストの品質をLLMで採点する 1つ目は、エージェントが返した回答テキストそのものの質です。これは Agent Platform(Vertex AI)の評価サービス を使い、LLM-as-a-Judge、つまり別のLLMに採点役をやってもらう形で測っています。 採点は4つの観点で行われます。 質問の指示どおりに答えているか(Instruction following) 与えられたコンテキストに基づいているか(Groundedness) 十分な情報量で答えているか(Completeness) 読みやすく整理されているか(Fluent) これらをまとめたスコアを段階評価で受け取り、品質が落ちていないかを確認します。 軸2: 発行されたクエリを決定論的に検証する LLMによる採点は揺れるため、それだけに頼るのは不安が残ります。そこでエージェントが実際に発行したクエリの中身を機械的に検証しています。 会話分析エージェントは、質問を受けると裏でLookerのクエリを組み立てて実行します。このクエリが「どのExploreを使い、どのフィールドを選び、どんなフィルタをかけたか」を期待値と照合して判定します。回答テキストの良し悪しではなく、構造として正しいクエリを組めているかを、ぶれのない形で担保します。 期待値は、評価ケースに assertions として書き足しておきます。 cases : - prompt : "今月のセグメント別のマッチング成立率は?" reference : "セグメントでグループ化し、成立件数をいいね件数で割った成立率を回答する" assertions : explore : fct_matchings # このExploreを使っているか fields_include : # これらのフィールドが含まれているか - segment - matching_rate filters_include : # このフィルタがかかっているか - field : matched_month value : this month これらの評価はGitHub Actionsで自動実行され、結果はPRにコメントされます。QA Qualityの平均スコアやケースごとの内訳、アサーションの判定がひと目で分かるので、変更が品質に与えた影響をレビュー時に確認できます。 フィードバックサイクルを回す 評価ケースは社内メンバーから寄せられるフィードバックをもとに育てています。「この聞き方だと答えてくれない」「この数字が期待とずれている」といった、実際に使う人がぶつかった声ほど価値のあるテストケースになります。 寄せられた声は評価ケースに加えるだけでなく、エージェントに足りないコンテキストの手がかりとして、内容に応じてシステムプロンプト・LookML・BigQueryテーブルのどこに手を入れるかを判断します。こうしてフィードバックを起点にしたサイクルが回っています。 flowchart LR FB([社内メンバーのFB]) --> C[評価ケースに追加] C --> FIX{どこを直す?} FIX -->|答え方| P[システムプロンプト調整] FIX -->|定義不足| D[LookML description補強] FIX -->|データ構造の問題| M[dbtデータモデリング見直し] P & D & M --> EVAL[評価を実行] EVAL --> SCORE[スコアを比較] SCORE -.改善を確認.-> FB 成果 前回のブログで、Lookerの登録ユーザーの7割が週次でログインしていることをお伝えしました。いまではそのうちの半分が、会話分析を通じて自律的にデータ抽出や分析を行っています。 データチームへの影響も大きく、月に十数件あったデータ抽出の依頼はほぼなくなりました。代わりに届くのは、会話分析だけでは解けないより高度な分析を要する相談が中心です。単純な抽出作業から解放されて本来注力すべき仕事に時間を割けるようになりました。 利用者からのフィードバックも増えてきました。「便利になった」という好印象の声もあれば、期待した結果が得られなかったという指摘もあります。後者はチームにとって学びの多い情報で、どこにコンテキストが足りていないのかが明確になります。 このフィードバックサイクルが回り始めたことで、エージェントのinstructionsやLookMLの修正、データモデリングの見直しがこれまで以上に進むようになりました。前述したSSoTについても、Exploreで吸収するだけでなく、テーブルレベルで担保できるよう改善を進めています。 まとめ 本記事では、セマンティックレイヤー(LookerのExplore)を会話分析の入口に据える設計と、Git管理・2軸評価・改善サイクルまでの運用を紹介しました。この設計が効くのは、すでにLookMLで指標やディメンションの定義が進んでいる組織です。土台があるからこそすぐに始められ、成果につなげることができたと思います。 運用で意識しているのは、クイックウィンの積み重ねです。Lookerや生成AIは安価ではないため、小さな成功体験を積み上げ、利用者に定着してもらうことが重要です。そのためにはフィードバックを集める仕組みが重要で、社内勉強会で使い方を共有したり、要望を気軽に投げてもらえるチャンネルを用意したりしています。会話分析を実現させるためには技術的な仕組みと、声が集まる仕組みの両輪が必要だと感じています。 ファインディでは、データ基盤やデータ活用の仕組みづくりに一緒に取り組んでくれる仲間を募集しています。少しでも興味を持っていただけたら、まずはカジュアルにお話ししましょう。 herp.careers
こんにちは。ファインディ株式会社でアプリケーションエンジニアをしている西村です。 ファインディの開発組織ではここ1年ほど、Claude Codeを使った開発プロセスのSkill化を進めてきました。Issue生成やセルフレビュー、タスク分解といった作業をSkillにして、社内のClaude Code Pluginに追加するのが日常になっています。 ただ、便利なSkillを揃えて配っただけでは、それが開発フローの中でどれだけ使われ、成果につながっているかまではわかりません。 そこで今回は、開発組織内で配布したPluginやSkillの利用データをどう集め、どう見て、どう改善に回しているか、その考え方と運用を紹介します。 作成したSkillが使われ続けるかを見る 定着と成果を組み合わせて評価する 利用データから使われ方そのものを変える 定着と成果のデータをFindy AI+で可視化する まとめ 作成したSkillが使われ続けるかを見る 開発プロセスのSkill化については、これまでのテックブログでも何度か紹介してきました。 【Claude】Pluginsで簡単横展開 - 開発手法の標準化 - Findyの爆速開発を支えるAI×チェックリスト型セルフレビュー Findyの爆速開発を支えるAIによるタスク分解の粒度設計 繰り返す作業があればSkillとして作成し、社内のClaude Code Pluginへ追加する流れは今も続いています。 一方で、配ったSkillが日々の開発に定着するかどうかは別の話です。配布した当初は新しい取り組みに前向きなメンバーが使ってくれますが、その後も使い続けるとは限りません。Skillの数と種類は充実しているのに、実際に利用されているのは一部だけ、という状況が生まれます。 「作った」で満足せず、配ったあとも「使われているか」を継続的に見ていく必要があります。 定着と成果を組み合わせて評価する ファインディでは、Claude Codeの活用度や作成したSkillの利用状況を計測して可視化しています。集めたデータから、開発工程のどこでどのSkillが効いているかを見て、改善しつづけています。 データを見てみると、よく使われていても成果につながっていないSkillもあれば、利用回数は少なくても効きどころで使われて大きな効果を出しているSkillもあります。つまり、Skillの利用回数だけを成果とみなすと、この違いを見落とすことがわかりました。 そこで私たちは、Skillが定着しているかを測る指標と、成果への貢献を測る指標を組み合わせて評価することにしました。 定着を測る指標は、一定期間内にSkillがどれくらいの頻度で使われているか、つまり利用頻度です。 成果への貢献を測る指標は、Skillを使い始めた後にPRの作成からマージまでの時間といったリードタイム等が短縮したかです。 利用データから使われ方そのものを変える ファインディでは2026年3月に、セルフレビューSkillを導入しました( 導入の経緯はこちらの記事で紹介しています )。ただ作成するだけでなく、ドッグフーディングして、AgentTeamに対応させたり、テストのカバレッジが十分かを見る観点を加えたりと、Skillの中身を改善してきました。 セルフレビューSkillは、変更したコードのバグを見つけたりテストの網羅性を高めたりする効果があり、組織全体での定着率を上げていきたいSkillです。 ただ、利用データを見て気づいたのは、改善すべきは中身だけではないということでした。導入直後の3月時点で月298回と一定の利用はあったものの、セルフレビューSkillを呼ぶかどうかは各メンバーの判断に委ねていました。そのため、エンジニア全員の開発フローに浸透するほどには使われていませんでした。 2026年3月時点のSkillの利用回数(左:アウトプット上位5名、右:組織全体96名)です。セルフレビューSkillの呼び出しは、アウトプット上位で117回、組織全体でも298回でした。 アウトプット上位 組織全体 そこで、Skillの使われ方そのものを変えました。SlackのPluginリリース告知チャンネルで使い方を周知し、あわせてPR作成Skillの中からセルフレビューSkillを呼び出すようにして、PRを作るときには必ずセルフレビューSkillを使用する環境に変えました。 その結果、セルフレビューSkillの呼び出しは、アウトプット上位で185回、組織全体で479回まで増えました。セルフレビューSkillが組織全体の標準的な動作として定着したことがわかります。 アウトプット上位 組織全体 さらに、導入前後でリードタイムを比べると、コミットからオープンまでの平均時間は22.2時間から16.3時間に縮みました。AIが書いたコードを人間がセルフレビューしていた手間を減らせたことが、短縮の一因だと考えています。 定着と成果のデータをFindy AI+で可視化する これまで紹介してきたSkillの呼び出し回数データは、Findy AI+の分析機能を使っています。Findy AI+ではClaude CodeのMonitoring機能を活用し、Skillやコマンドの実行ログを収集して、「どのSkillがいつ実行されたか」を一元的に追えるようにしています。 集めたログからは、Skillごとの呼び出し回数や、それが一部のメンバーに偏っているか組織全体に広がっているかといった定着の度合いが見えてきます。ここにTeam+のPR作成数やレビューのリードタイムといった成果指標を重ねると、定着と成果のデータが揃い、「どのSkillで、どの指標に効いているのか」を分析できます。 まとめ PluginやSkillは、配って終わりにすると少しずつ使われなくなっていきます。配ったあとも「使われているか」さらに「アウトプットの増加に貢献できているか」まで見て初めて、改善の打ち手が定まります。 もしすでにPluginやSkillを配っている方がいれば、まずは「どのSkillが、誰に、どれだけ使われているか」を1つでも数字で見えるようにするところから始めてみてください。配ったあとのデータがそろうと、次にどこへ手を入れるべきかが自然と見えてきます。 Findy AI+の分析機能については、 Findy AI+の紹介ページ もあわせてご覧ください。 ファインディでは一緒に会社を盛り上げてくれるメンバーを募集中です。興味を持っていただいた方はこちらのページからご応募お願いします。 herp.careers
こんにちは。Findy Freelance開発チームの久木田です。 今回は、社内で運用している支払明細書PDFの生成基盤を、Lambda + Puppeteerから @react-pdf/renderer へ全面的に移行した話を書きます。最終的に処理時間はP50(中央値)で約27倍速くなり、メモリ消費も実測で約1/4まで落とせました。 これまでのPDF生成基盤と課題 対症療法でしのいだ期間 根本対応を決めた3つの背景 技術選定: 戻れる順に試す 移行で押さえておきたい実装ポイント 設計と実装のキモ テンプレート構造 esbuildで橋渡し どう変わったか 学び これまでのPDF生成基盤と課題 現在、システムから発行しているPDFはいくつかありますが、本記事では一例として支払明細書PDFに絞って紹介します。ファインディからフリーランスエンジニアへの支払明細として月次で一括発行しているPDFです。 支払明細書PDFは1件あたり1ページで、支払先、支払者、明細表、特記事項、ファインディの社印を配置した構成です。情報量としては小規模ですが、月次でフリーランスエンジニア全員分を一括発行する必要があり、1回のバッチで数百件規模のPDFを並列生成していました。Rails側からParallelライブラリで並列にLambdaを呼び出す構成です。 このPDFは、AWS Lambda上でPuppeteerを起動し、EJSテンプレートから組み上げたHTMLをヘッドレスのChromiumでレンダリングしてPDF化する構成で動いていました。フロントエンド向けのHTML/CSSをそのまま流用できるため初期実装は速かったのですが、運用が進むにつれ次の課題が顕在化しました。 コールドスタートが重く、Chromiumバイナリの起動だけで5秒前後を消費していた 大量生成で /tmp が枯渇し、一括処理で複数のレンダリングを並走させると、エフェメラルストレージが先に尽きてエラー終了する タイムアウトやエラーが恒常化し、数百件規模の一括出力は途中で停止して再実行が必要になる ボトルネックはChromiumの不安定さでした。Chromium起動のたびにプロファイル・キャッシュ・ソケットファイルが /tmp 配下に生成され、 browser.close() 後もディスク上に残存します。さらに、レンダリング中にChromiumがハングした場合は、一時ファイルを保持したままプロセスが停止します。その間にも新規リクエストでLambdaが起動するため、ウォームスタートで使い回されるインスタンスでは /tmp の残存ファイルが蓄積し、一定量を超えた時点で全体が停止してしまう挙動になっていました。 この蓄積に備えて、メモリと /tmp は常にバッファを含めて多めに割り当てる必要があり、1Lambdaあたり2-3GB相当の確保を継続していました。それでもハングと並列度のピークが重なる局面では詰まるため、設定値を引き上げては別の閾値で詰まるという状態が続いていました。 一括出力は今後数倍に増加する見込みであり、現状の構成のまま継続することは現実的ではありませんでした。 対症療法でしのいだ期間 課題を踏まえ、徐々に対策を施すことにしました。Lambdaのメモリ割り当て増、タイムアウト延長、エフェメラルストレージの拡張、並列度の調整など、設定値で吸収できそうな対策は一通りしました。短期的な改善にはなったものの、根本にあるのはChromiumをサーバーレス環境で動かすこと自体のコストと描画コストが入力規模に比例して伸びる構造です。設定の積み増しではレイテンシーもエラー率も思うように改善しませんでした。 根本対応を決めた3つの背景 根本対応に踏み切る判断は、次の3点が同時に揃った時点で下しました。 現状の課題: レイテンシーが悪化傾向、エラーも日次で観測される 将来の悪化見込み: 一括処理の件数は今後さらに増える計画があり、対症療法の余地がもう残っていない 対症療法の限界: 設定値の調整ではレイテンシーやエラー率の改善が頭打ちで、いずれの打ち手も効果が薄れてきた 課題が大きくなったため、対策を施しました。逆に言えば、どれか1つでも欠けていたら、もう少し対症療法を続けていたと思います。 技術選定: 戻れる順に試す 根本対応の方針として、大きく2案を比較しました。 A案: Lambdaを維持し、 @react-pdf/renderer でProgrammaticにPDFを組み立てる B案: LambdaからECSなど別のランタイムへ移行する A案は、いまのLambda構成を保ったままPDF生成方式だけを差し替える案です。 @react-pdf/renderer はJSXを書く感覚でPDFを組み立てるライブラリで、Chromiumのヘッドレスブラウザは利用しません。 react-pdf.org そもそも @react-pdf/renderer が候補に挙がったのは、ヘッドレスブラウザ以外でPDFを生成する方法を調べていたからです。継続的な利用料金が発生する外部サービスを使う選択肢は外し、OSSのプログラマティック生成ライブラリの中で、Reactと同じJSXで書ける @react-pdf/renderer を選びました。Reactはファインディの他プロダクトでも広く使われており、馴染みがあった点も決め手になりました。 B案はメモリやストレージの制約には強くなりますが、コスト構造が変わり、検証の立ち上げにも工数がかかります。Lambdaのタイムアウトに収まらない処理や、Chromiumの表現力(複雑なCSS・JavaScript描画など)をどうしても残したいケースではB案が候補ですが、今回のPDF生成はそのどちらにも当てはまりませんでした。 そのため、最終的には次の3つの理由からA案を選びました。 戻れる: Lambda構成のままPDF生成方式だけを差し替えるので、問題が出てもPuppeteer版に戻すことが容易 テスト可能: PDF生成ロジックがJSXで書けるため、単体テストや出力差分テストを書きやすい AIで移行コストが現実的になった: EJSテンプレートからJSXへの変換は、生成AIに任せられるレベルまで来ていた B案はA案が失敗した場合の代替案として残し、まずは戻れるA案を試すことにしました。 移行で押さえておきたい実装ポイント EJSからJSXへの書き換え自体は生成AIで一気に進められましたが、 @react-pdf/renderer の実装スタイルに合わせるために事前に押さえておきたい点がいくつかありました。 @react-pdf/renderer v4はESM-onlyで、tscのCommonJS出力からは読み込めないため、esbuildを入れてESMをCJSにバンドルした 日本語フォントは Font.register() で明示的に登録しないと文字化けする Puppeteerの scale: 0.8 相当が無いため、フォントサイズや余白を手で再計算した HTMLの <a> 自動展開は再現されず、URL部分だけ <Link> 化する小さなコンポーネントを自作した HTMLエスケープは自動化されていて、旧実装のエスケープ処理が不要になった(副産物) 特に大変だったのがJSXの空文字列の扱いです。 {stringValue && (...)} と書くと、空文字列がchildとしてそのまま流れ込み、 WARN Invalid '' string child outside <Text> component が大量に出ます。Reactの文法としては正しいのですが、 @react-pdf/renderer の <View> / <Page> 配下では {!!stringValue && (...)} と明示的にboolean化する書き方に揃える必要があります。さまざまなデータでPDFを作成していく過程で警告ログが出ていることに気付き、該当箇所をまとめて修正しました。 設計と実装のキモ ここからは、 @react-pdf/renderer をLambdaに載せていくときに考えた設計面のポイントを2つに分けてまとめます。 テンプレート構造 PDFそのものを1つのReactコンポーネントとして組み立てる構成にしました。リンクの自動展開のように共通で必要な要素は、専用の小さなコンポーネントとして切り出して再利用しています。 EJS時代は部分テンプレートをincludeで組み合わせる作りでしたが、JSXに移ってからはコンポーネントの組み合わせとして自然に再構成できました。 esbuildで橋渡し @react-pdf/renderer v4はESM-onlyですが、Lambda側はCommonJSで動かしています。tscの出力では直接読み込めなかったため、esbuildでESM→CJSのバンドルを作ってLambdaにデプロイする構成にしました。 // esbuild.config.js(抜粋) { entryPoints: ['src/index.ts'], bundle: true, platform: 'node', format: 'cjs', } 設定としてはシンプルですが、ここを通さないと依存関係の解決でつまずくことになるため注意が必要です。 どう変わったか 支払明細書PDFの一括作成処理について、移行前後をCloudWatchメトリクスで比較した実測値が次の通りです。表のP50 / P95 / P99は、実行時間を昇順に並べたときの中央値 / 95パーセンタイル / 99パーセンタイルを表します。 指標 Before After 倍率 実行時間 P50 約3,963 ms 約145 ms 約27倍高速 実行時間 P95 約4,707 ms 約212 ms 約22倍高速 実行時間 P99 約5,249 ms 約458 ms 約11倍高速 平均メモリ 約912 MB 約222 MB 約1/4 最大メモリ 約1,589 MB 約239 MB 約1/7 特に改善幅が大きいのはP50です。旧構成では実行時間そのものの遅さに加え、Puppeteer/Chromium由来のエラー(ブラウザの接続切れやハングなど)が起きると、一括処理の中で個別のPDF生成がLambdaのタイムアウトに到達し、リトライしても最後まで完成せずエラーとして残るケースがありました。表のP99の大きさにそれが現れています。移行後はこれらのエラー、エフェメラルストレージの逼迫、コールドスタートによる遅延がいずれも解消され、Lambda上での実行を意識する必要のない構成になっています。 学び 今回の移行で特に有効だったのは、判断軸として置いた「戻れる順に試す」です。Lambda構成を維持したままPDF生成方式だけを差し替えるA案は、もし行き詰まっても旧版のLambdaに切り戻す選択肢を残せました。ランタイムごと載せ替えるB案を最初に選んでいたら、検証のために抱えるリスクははるかに大きくなっていたはずです。 もうひとつは、生成AIの活用で技術選定の前提条件が変わったことです。A案はEJSテンプレートのJSXへの全件書き換えを伴います。AIなしで工数を見積もると、規模だけでA案は採用候補から外れていました。書き換えだけでなく、旧PDFと新PDFのレイアウト差分の特定と修正案の生成までAIに任せられたため、A案の工数は当初の想定より低く収まりました。 最後に、 @react-pdf/renderer を使った所感をまとめます。 メリットとして大きかったのは、Lambdaの割り当てメモリを大幅に減らせたことと、ヘッドレスブラウザを使っていたころよりテストが格段に書きやすくなったことです。PDFをバッファのまま受け取って中身を検証できるので、ブラウザを起動しない軽量な統合テストをCI上でも組めるようになりました。 一方で、HTML/CSSではなく <View> <Text> といったPDF専用のプリミティブをFlexboxで組み立てる、React Native寄りのコンポーネントモデルです。HTML/CSSしか経験が無い場合は、最初は書き方に戸惑う場面もあると思います。 ファインディでは一緒に会社を盛り上げてくれるメンバーを募集中です。興味を持っていただいた方はこちらのページからご応募お願いします。 herp.careers
こんにちは。Findyでモバイルアプリ開発を担当している加藤と主計です。 Findy初のモバイルアプリ「Findy Events」については、先日 React Native選定の経緯と立ち上げの全体像 を公開しました。 前記事ではUIライブラリ周りには深く踏み込めなかったので、今回はその続編です。UIライブラリの選定と実装パターンに絞ってお届けします。 具体的には、当初採用していたTamaguiからHeroUI Native + react-native-unistylesに乗り換えるまでの判断と、Wrapper Componentを軸にしたUI構築の進め方が中心です。 なお、本記事で題材にしているFindy Eventsは、 App Store と Google Play で公開しています。 Tamagui採用の背景 Tamaguiを使ってみて見えてきた課題 Android実機固有の挙動 Sheet表示直後のタップが効かない Sheet内のScrollViewでスクロールするとSheetが閉じる Expo SDK 54対応のタイミング HeroUI Native + react-native-unistylesに変更を決めた理由 β版採用のリスクとその対策方針 具体的なコード例 HeroUI NativeのWrapper Component react-native-unistylesとWrapper Componentを組み合わせたUI Componentの実装 まとめ Tamagui採用の背景 Findyのモバイルアプリ開発で、当初UIライブラリとして採用していたのは Tamagui 。 選定時の候補は gluestack-ui とTamaguiの2つで、最終的にTamaguiを選びました。 決め手となった理由は大きく3つあります。 1つ目は、ライブラリとしての信頼性と情報量です。 Tamaguiはv0.1.0が2021年3月にリリースされ、5年以上にわたって開発が続いているOSSです。 GitHubのスター数や提供されるComponent数の充実度から、本番プロダクトに採用しても大きく外さないと判断しました。歴史がある分、ネット上の記事も比較的多く、開発時の調査コストを抑えやすい点も後押し材料です。 2つ目は、iOSエンジニアとしての開発経験との親和性です。 iOS開発ではOSSとして提供されたUIをそのまま利用する、あるいは許容範囲で改変するアプローチが一般的で、Tamaguiはこのメンタルモデルに合致していました。 SwiftUIと同じ宣言的UIの思想を持ち、縦方向に並べるSwiftUIの VStack がTamaguiの YStack に対応するように、子要素を軸方向に積み上げてレイアウトを組み立てる考え方が共通している点も馴染みやすいポイントです。 一方のgluestack-uiは、shadcn/uiと同様にCLIでComponentのコードを自分のリポジトリに生成し、必要に応じて編集して使う方式を採っています。Tailwindライクなクラス指定と合わせて、モバイルエンジニア出身の自分にはやや取っ付きにくく感じました。 3つ目は、Propsベースで直感的にスタイリングできることです。 <Stack m="$2" p="$2" backgroundColor="$background"> のように、Componentに対してProps経由でデザイントークンを直接当てられ、感覚としては昔ながらのCSSやSwiftUIのmodifierに近い書き味で扱えます。 デザイントークンによるテーマ管理でライト/ダークテーマの切り替えが容易な点も決め手になりました。 Tamaguiを使ってみて見えてきた課題 Tamaguiを採用してアプリを開発する中で、幾つか見えてきた課題もありました。HeroUI Nativeへの乗り換えを判断した背景でもあるため、ここで率直に共有します。 Android実機固有の挙動 iOSシミュレータやAndroidエミュレータでは問題ないものの、Android実機でのみ起きる挙動に幾つかぶつかりました。ここでは印象に残った2つのケースを、実コードと合わせて紹介します。 Sheet表示直後のタップが効かない メニューや確認ダイアログとして Sheet を表示した直後に、内部のボタンをタップしても反応しないことがありました。 最初はダブルタップが必要なのかと感じましたが、少し時間をおくと反応するため、UIアニメーションの完了までタップが受け付けられていないと推測しました。デフォルトのアニメーションは完了までに時間がかかり、その間タップを取りこぼしていたようです。 そこで Sheet に animation="200ms" のように短い時間のアニメーションを明示的に指定したところ、表示完了までの時間が短くなり、表示直後のタップにもすぐ反応するようになって解消しました。 <Sheet modal open = { open } onOpenChange= { setOpen } snapPoints= {[ 50 ]} animation= "200ms" // 明示しないとAndroid実機で表示直後のタップが効かない > < Sheet . Overlay /> < Sheet . Frame padding = "$4" > < Button onPress = { handleConfirm } > 確定する </ Button > </ Sheet . Frame > </Sheet> Sheet内のScrollViewでスクロールするとSheetが閉じる 選択肢が多い項目を選ばせるUIとして、選択肢一覧を ScrollView で表示した Sheet を出していたのですが、Pixel 10で動作確認していたところ、 Sheet 内をスクロールしようとするとそのまま Sheet ごと閉じてしまう事象が発生しました。 該当箇所はおおよそ次のような構成です。 import { ScrollView } from "react-native" ; import { Sheet } from "tamagui" ; < Sheet modal open = { open } onOpenChange = { setOpen } snapPoints = { [ 80 ] } > < Sheet . Overlay /> < Sheet . Frame > < ScrollView > { options. map (( option ) => ( < Option key = { option. id } option = { option } /> )) } </ ScrollView > </ Sheet . Frame > </ Sheet > Sheet 内の ScrollView でのスクロール操作が、 Sheet を閉じるためのドラッグジェスチャと衝突しているのが原因と推測しています。 暫定対応として Sheet 側に disableDrag を指定したところ、スクロール時に Sheet が閉じる事象は解消されました。 <Sheet modal open = { open } onOpenChange= { setOpen } snapPoints= {[ 80 ]} disableDrag // ドラッグでSheetを閉じる挙動を無効化し、ScrollViewのスクロールと衝突しないようにする > < Sheet . Overlay /> < Sheet . Frame > < ScrollView > { options. map (( option ) => ( < Option key = { option. id } option = { option } /> )) } </ ScrollView > </ Sheet . Frame > </Sheet> ただし disableDrag を指定すると、本来ドラッグで閉じられるはずの Sheet が閉じられなくなり、UX上の妥協が発生してしまいます。 Sheet 周りはAndroid実機での挙動が安定しないケースが続いたこともあり、根本的にはTamaguiの Sheet 自体の利用を見直す必要があると感じはじめ、後にHeroUI Nativeへの乗り換えを検討する一因にもなりました。 Expo SDK 54対応のタイミング ExpoはReact Nativeでクロスプラットフォームのアプリを開発するためのフレームワークで、モバイルアプリの証明書周りを簡単に扱える仕組みや、様々な便利機能をSDKとして提供しています。そのExpo SDK 54は2025年9月11日にリリースされ、TamaguiのGitHub上でも対応に向けたWIP Pull Requestや議論が動いていました。 一方で、Tamagui側の対応版がリリースされたのは2025年11月15日で、対応版リリース日のアナウンスは事前にはなかったと記憶しています。 5年以上の歴史を持つライブラリで、内部に多くの実装を抱えている分、最新Expo SDKへの追従は簡単ではないのだろうと推測しています。OSSライブラリを採用する以上、こうした追従コストとはトレードオフだと改めて感じる出来事でした。 HeroUI Native + react-native-unistylesに変更を決めた理由 ここまで見てきた課題を踏まえ、次のUI基盤としてHeroUI Nativeとreact-native-unistylesを組み合わせる構成を選びました。 HeroUI Nativeを選んだ理由は、Componentの完成度が高く、画面実装のスピードを上げられると考えたためです。デフォルトの見た目が洗練されており、アニメーションやインタラクションも作り込まれているため、細かい調整を加えなくてもそのまま画面を組み立てられます。Findy Eventsはまだ機能を増やしていく段階にあり、必要な画面を素早く形にできることは、UIライブラリに強く求めていた点でした。 スタイリングにreact-native-unistylesを採用したのは、スタイル定義を標準のAPIに寄せたかったためです。HeroUI Native自体は内部のスタイリングにUniwind(Tailwind v4ベースの仕組み)を使っていますが、プロダクト側のスタイルは、React Native標準のStyleSheet APIに近い書き味で扱いたいと考えました。react-native-unistylesなら StyleSheet.create を起点に、色やfontSize、spacing、radiusといったトークンを定義でき、モバイルエンジニアにとっても馴染みやすい書き味になります。 β版採用のリスクとその対策方針 一方で、HeroUI Nativeの採用にはリスクもありました。 検討していた当時のHeroUI Nativeはまだβ版段階のライブラリでした。正式版のv1.0.0は2026年3月19日にリリースされ、Findy Eventsのアプリリリース時点ではv1.0系に到達しています。ただ、採用を判断した時点ではまだ正式版前のライブラリです。β版段階のライブラリを本番プロダクトの土台に据える以上、特に破壊的変更には注意が必要でした。APIがまだ固まりきっておらず、バージョンアップのたびに利用側のコード修正を迫られる可能性があるためです。 そこで、HeroUI NativeのComponentは画面から直接使わず、必ずWrapper Componentを挟んで利用する方針にしました。Wrapper Componentという境界を1枚挟むことで、HeroUI Native側のAPIが変わっても、修正をPrimitive層に閉じ込められます。 この方針は、破壊的変更への備えであると同時に、将来的にHeroUI NativeのComponentを自分たちの独自実装へ切り替えたくなった場合にも効きます。利用側はWrapper Component経由でしかComponentに触れていないため、内側の実装をHeroUI Nativeから独自実装へ差し替えても、画面側のコードに影響を出さずに移行できます。 具体的なコード例 ここでは、HeroUI NativeのComponentをWrapper Componentとして定義し、react-native-unistylesと組み合わせて画面を構築するまでの流れを紹介します。 HeroUI NativeのWrapper Component まず、最もシンプルな例として、 Skeleton のWrapper Componentのコードを見ていきましょう。 // src/components/primitives/skeleton/skeleton.component.tsx import type { SkeletonProps } from "heroui-native" ; import type { PropsWithChildren } from "react" ; import { Skeleton as HeroUISkeleton } from "heroui-native" ; type Props = PropsWithChildren < Pick < SkeletonProps , "isLoading" | "style" > >; export const Skeleton = ( { isLoading = true , style , children } : Props ) => { return ( < HeroUISkeleton isLoading = { isLoading } variant = "shimmer" style = { style } > { children } </ HeroUISkeleton > ); } ; HeroUI NativeのComponentは多くのPropsを持っていますが、アプリ内で実際に使うPropsは限られます。 Wrapper Componentを定義する時に、 Pick<> で必要なPropsだけを公開することで、利用側のインターフェースをシンプルに保つことができます。 また、 variant のようにアプリ全体で固定したい設定値はWrapper Component内で埋め込むことで、利用側が意識する必要がなくなります。 次に、もう少し複雑な例として、 Button のWrapper Componentのコードを見てみましょう。 HeroUI Nativeには Button.Label や Card.Body のように、サブComponentを持つCompound Componentがあります。 ラップした後も Button.Label のような呼び出し方を維持したい場合は、 Object.assign() を使って親ComponentにサブComponentを紐付けます。 // src/components/primitives/button/button.component.tsx import type { PropsWithChildren } from "react" ; import { Button as HeroUIButton } from "heroui-native" ; import type { ButtonLabelProps, ButtonRootProps } from "heroui-native" ; import { StyleSheet } from "react-native-unistyles" ; export type ButtonComponentProps = PropsWithChildren < Pick < ButtonRootProps , "style" | "size" | "onPress" | "isDisabled" | "animation" > >; export type ButtonLabelComponentProps = PropsWithChildren < Pick < ButtonLabelProps , "style" > >; const ButtonRoot = ( { children , style , size , onPress , isDisabled , animation , } : ButtonComponentProps ) => { return ( < HeroUIButton style = { style } size = { size } onPress = { onPress } isDisabled = { isDisabled } animation = { animation } > { children } </ HeroUIButton > ); } ; const ButtonLabel = ( { children , style } : ButtonLabelComponentProps ) => { return ( < HeroUIButton . Label style = { style } > { children } </ HeroUIButton . Label > ); } ; export const Button = Object . assign (ButtonRoot, { Label : ButtonLabel, } ); このように Button.Label の形でアクセスできるため、利用側のコードはHeroUI Nativeの元のAPIと同じ使い心地を維持できます。 react-native-unistylesとWrapper Componentを組み合わせたUI Componentの実装 続いて、定義したWrapper Componentをreact-native-unistylesと組み合わせて、実際の画面で利用するUI Componentを作る例を紹介します。 まず、カラートークンを定義したファイルを用意します。 // src/styles/generated/primitive-colors.ts export const primitiveColors = { black : "#000000" , white : "#ffffff" , ... blue400 : "#377ecd" , blue500 : "#055ec1" , blue600 : "#044b9a" , ... } as const ; export type PrimitiveColors = typeof primitiveColors ; 次に、react-native-unistylesで、テーマに沿ったスタイリングを効率的に行えるように、 StyleSheet.configure でアプリ全体のテーマトークンを定義します。 本アプリでは、色やフォントサイズ、spacing、角丸などをトークンとして管理しており、Componentごとの配色もここに集約しています。 // src/styles/index.ts import { StyleSheet } from "react-native-unistyles" ; import { primitiveColors } from "./generated/primitive-colors" ; const tokens = { colors : primitiveColors, fontSize : { xs : 11 , sm : 12 , md : 14 , lg : 16 , xl : 20 , "2xl" : 22 } , radius : { xs : 2 , sm : 4 , md : 6 , lg : 8 , xl : 12 } , space : { "2xs" : 4 , xs : 8 , sm : 12 , md : 16 , lg : 24 } , } as const ; const lightTheme = { // グローバル定義 background : primitiveColors.white, backgroundPress : primitiveColors.grey50, ... // Componentごとの定義 button : { danger : { background : primitiveColors.red500, color : primitiveColors.white, backgroundPress : primitiveColors.red600, } , } , fontSize : tokens.fontSize, radius : tokens.radius, space : tokens.space, } as const ; const darkTheme = { ... } StyleSheet .configure( { themes : { light : lightTheme, dark : darkTheme } , } ); StyleSheet.create のコールバック関数からこのテーマトークンにアクセスでき、さらにスタイル定義自体を関数にすることで、Propsの値に応じた動的なスタイル切り替えも実現できます。 これを踏まえて、先程のButton Wrapper Componentをカスタマイズした「DangerButton」UI Componentの例を見てみましょう。 // src/components/buttons/danger-button/danger-button.component.tsx import { StyleSheet , useUnistyles } from "react-native-unistyles" ; import { Button } from "@/components/primitives/button" ; import type { ButtonComponentProps, ButtonLabelComponentProps, } from "@/components/primitives/button" ; const DangerButtonRoot = ( { children , style , ... rest } : ButtonComponentProps ) => { const { theme } = useUnistyles(); return ( < Button style = { [ styles.root, style ] } animation = { { highlight: { backgroundColor: { value: theme.button.danger.backgroundPress } , }, }} { ...rest } > { children } </ Button > ); } ; const DangerButtonLabel = ( { children , style } : ButtonLabelComponentProps ) => { return < Button . Label style = { [ styles. label , style ] } > { children } </ Button . Label > ; } ; export const DangerButton = Object . assign (DangerButtonRoot, { Label : DangerButtonLabel, } ); const styles = StyleSheet .create(( theme ) => ( { root : { backgroundColor : theme.button.danger.background, } , label : { color : theme.button.danger.color, } , } )); このように、HeroUI Nativeの className などを隠蔽し、プロダクト固有のスタイル定義をreact-native-unistylesで与えており、HeroUI Nativeとreact-native-unistylesで責務を分割しています。 まとめ 本記事では、Findy Eventsの開発で当初採用していたTamaguiからHeroUI Native + react-native-unistylesへ乗り換えるまでの判断と、Wrapper Componentを軸にしたUI実装パターンを紹介しました。 振り返って改めて感じたのは、UIライブラリの選定は「一度決めて終わり」ではなく、運用しながら継続的に見直す前提で向き合うべきだということです。 Tamaguiは選定時の評価としては妥当な候補で、採用後も多くの場面で十分に機能していました。一方で、Android実機特有の挙動やExpo SDK追従までのタイムラグなど、プロダクトとして長く育てる上で無視できない課題も見えてきます。β版というタイミングを活かしてHeroUI Native + react-native-unistylesに踏み込んだ判断は、開発体験の改善という形で素直に効いています。 実装面では、HeroUI NativeをそのままUI Componentとして使うのではなく、Wrapper Component経由で型・Propsを絞り、スタイル定義はreact-native-unistylesに寄せる責務分離が機能しました。プロダクト固有のテーマや配色をWrapper Component側で受け止めることで、UIライブラリ更新の影響範囲を最小化しつつ、画面側のコードもシンプルに保てています。 Findy初のモバイルアプリということで、技術選定もアーキテクチャも手探りで進めた部分が多くありますが、その都度の判断と振り返りそのものが大きな資産になっていると感じます。本記事の経験談が、同じような選定や設計に向き合っている方の判断材料になれば嬉しいです。 ファインディでは一緒に働くメンバーを募集しています。少しでも興味を持っていただけた方は、ぜひこちらをご覧ください! herp.careers
こんにちは、ファインディでFindy Toolsの開発をしている本田です。 この記事は「 エンジニア達の人生を変えた一冊 」として、ファインディのエンジニアが人生を変えた本を紹介していくシリーズです。 Part7では、本田・加藤・山田の3名でお届けします。アジャイル開発との出会いになった本、iOSアーキテクチャ設計の答え合わせになった本、AI時代に再読して背筋が伸びた本。3冊それぞれ切り口は違いますが、いずれも自分の中の「開発の判断軸」を作り直してくれた一冊です。 それでは、さっそく紹介していきましょう。 RailsによるアジャイルWebアプリケーション開発 第4版 この本を読んだきっかけ 本の内容 この本から影響を受けた点/学んだ点 特に印象に残った部分 このような方におすすめ iOSアプリ設計パターン入門 この本を読んだきっかけ 本の内容 この本から影響を受けた点/学んだ点 特に印象に残った部分 このような方におすすめ 世界一流エンジニアの思考法 この本を読んだきっかけ 本の内容 この本から影響を受けた点/学んだ点 特に印象に残った部分 このような方におすすめ おわりに ■ 本田 / フルスタックエンジニア ■ ファインディでFindy Toolsの開発をしている本田です。 RailsによるアジャイルWebアプリケーション開発 第4版 RailsによるアジャイルWebアプリケーション開発 第4版 作者: Sam Ruby , Dave Thomas , David Heinemeier Hansson オーム社 Amazon 本書は、原著「Agile Web Development with Rails」をもとに、Rails 3.1に対応する形で翻訳された一冊です。著者には、アジャイルソフトウェア開発宣言の起草者の一人であるDave Thomasと、Railsの作者であるDavid Heinemeier Hanssonが名を連ねています。アジャイルの源流とRailsの源流が、ひとつの本のなかに揃っているというのは、今振り返ってみると改めてすごい組み合わせだと感じます。 ちなみに、そのDave Thomasが、2026年6月17日・18日にファインディが主催するオンラインカンファレンス 「エンジニアの役割の変化に向き合うConference 2026」 に登壇予定です。本書の著者本人の話を聞ける機会でもあるので、興味のある方はぜひチェックしてみてください。 この本を読んだきっかけ 業界4年目の頃、私はC#でウォーターフォールの開発をしていました。仕様を固めて設計書を書き、それに沿って実装し、最後にまとめてテストとリリース。それが「開発」というものだと思っていました。 そんなときに、Railsを使った新しいプロジェクトが立ち上がりました。チームメンバーは全員、Railsも本格的なアジャイル開発も未経験で、何から始めればいいのか分からない状態でした。そこで、みんなでこの本を教科書にして、毎日お昼に少しずつ読書会をしながら進めることにしました。各自一章ずつ読んできて集まり、分からないところを話し合い、サンプルを動かしてみる。それを繰り返して、RubyやRailsを少しずつ自分たちのものにしていきました。 本を中心にしたチームの学びの時間は、いまでも当時を思い出すたびに頭に浮かぶ景色になっています。 本の内容 構成のおもしろさは、Depot(デポ)というオンラインショップの架空のプロジェクトを、章を追って少しずつ作り上げていく形式になっているところです。最初は商品一覧の表示だけ、次にカートをつけて、注文できるようにして、メール送信を加えて……というふうに、本一冊を通じて一つのアプリケーションがインクリメンタルに育っていきます。 機能ごとの章タイトルが「タスクA」「タスクB」と続く構成で、まるで開発の現場でユーザーストーリーをこなしていくかのような体験になっています。Railsの機能を学べると同時に、 「動くものを少しずつ広げていく」開発スタイルそのものを擬似体験できる ように設計されていて、書名どおりまさに「Railsによるアジャイル」を体現した本だと感じました。 この本から影響を受けた点/学んだ点 この本を読んで一番大きかったのは、開発の進め方そのものに対する自分の考え方が変わったことです。 それまでの私にとって、「仕様を固める」「設計を作る」「実装する」「テストする」は、それぞれが大きな塊として順番に並んでいるものでした。ところがこの本でDepotを作っていく体験は、まったく違いました。小さく動くものをまず作って、そこに機能を足し、動かしてみて、足りなければ調整して、また次の機能を足していく。短いサイクルで「動くもの」を中心に開発が進んでいく感覚は、当時の自分には完全に新しいものでした。 同じくらい衝撃的だったのは、Rubyという言語とRailsというフレームワークの書き心地そのものです。それまで書いていたコードと比べると、コードの量が圧倒的に少なくて、それでいて表現したいことがすっと書ける。フレームワークが規約として用意してくれている部分にうまく乗ると、書くべきものに集中できる。これも「開発って、こんなに違うものになるのか」という気づきでした。 「Webアプリケーションをアジャイルに作る」というのは、ツールやフレームワークだけの話ではなく、考え方と書き心地と進め方が一体になって初めて成立するものなのだと、サンプルアプリケーションを作りながら肌で理解できた気がします。 特に印象に残った部分 特に印象に残っているのは、Depotを章ごとに育てていく構成そのものです。 本の最初のほうで作ったDepotは、商品一覧を表示するだけのとてもシンプルなものです。それが章を進めるごとに少しずつ機能が増えていき、最後にはちゃんと注文ができてメールが届く、ひとつのアプリケーションになっている。途中で「これで動くようになった」「ここはこういう改善ができるのか」と、小さな達成感が積み重なっていく感覚は、技術書を読みながら得られる体験としてとても新鮮でした。 そして、それをチームで読書会として体験したことも大きかったです。お昼に集まって、一章ずつ進めて、分からないところは議論して、サンプルを動かしてみる。今思えば、これ自体が「短いサイクルで動くものを増やしていく」という本書で学ぼうとしていたスタイルを、学び方そのもののなかで実践していたのだと思います。本を読むという行為が、ただ知識を得る時間ではなく、チームで開発のスタイルそのものを共有する時間になっていました。 このような方におすすめ 日本語版は更新が止まっているため、今からRailsを学び始める人に第一の選択肢として薦める本ではないかもしれません。ただ、原著は今もアップデートが続いていて、最新版ではRailsの新しいバージョンに対応した内容で読むことができます。 pragprog.com 私個人としては、 Railsとアジャイル開発の出会いをひとつの本でまるごと体験した原体験の本 として、今でも特別な位置に置いています。AIで開発の速度や進め方が変わっていく今だからこそ、「小さく動くものを作って、フィードバックを得ながら育てていく」という当時学んだスタイルが、自分のなかでの開発の考え方の土台になっていることをあらためて感じます。 続いては、Tools開発でファインディ初のモバイルアプリ「Findy Events」を担当している加藤さんです。Clean Architectureを採用したプロダクトをリリースした直後に出会った、設計選定の「答え合わせ」になった一冊について語ってもらいました。 ■ 加藤 / モバイルエンジニア ■ ファインディ株式会社でモバイルエンジニアをやっている加藤です。ファインディ初のモバイルアプリ「Findy Events」を開発しています。 iOSアプリ設計パターン入門 peaks.cc ※現在はPEAKSの公式サイトで電子版のみ購入可能です。 私が紹介する「iOSアプリ設計パターン入門」は、iOSアプリのアーキテクチャを網羅的にまとめた書籍です。 この本を読んだきっかけ 当時の私はMVCのみの開発経験しかない中で、業務でClean Architectureに挑むことになりました。 手探りで設計を進め、なんとかリリースまで漕ぎ着けたものの、本当にこれで良かったのか、正しい形は何だったのかという確信は最後まで持てませんでした。 チーム内でClean Architectureに対する共通認識を取り切ることができず、QCDのDを優先して走り切った経緯もありました。そもそもClean Architectureを採用すべきだったのか、別のアーキテクチャの方が適していたのではないかという迷いも残っていました。 そんなタイミングで本書が発売され、自分の中の答え合わせをしたいという気持ちで手に取った一冊です。 本の内容 本書は冒頭で、一般的なアーキテクチャの歴史と構造を整理するところから始まります。 GUIアーキテクチャとシステムアーキテクチャの両面から解説されており、それぞれの位置づけがクリアになる構成です。 その上で、各アーキテクチャをiOSアプリにどう適用するかが具体例とともに示されています。 アーキテクチャの選定に関する考え方にも一定のページが割かれており、サンプルコードがGitHubで配布されているため、手を動かしながら理解を深められるのもありがたいポイントでした。 この本から影響を受けた点/学んだ点 一番大きかったのは、GUIアーキテクチャとシステムアーキテクチャは組み合わせて使うものだという視点を得られたことです。 それ以前の私は、この二つを同じレイヤーのものとして捉えており、MVCとClean Architectureを並べて比較するような考え方をしていました。 本書を読んでから、例えば、「MVPでGUIを構築しつつClean Architectureでシステム全体を整理する」といった組み合わせの発想ができるようになりました。 実際にその後の業務で「MVP + Clean Architecture」という形に取り組み、本書で得た視点を現場に持ち込めたのは大きな収穫でした。 特に印象に残った部分 第2部のまとめ「アーキテクチャの選定基準」に書かれていた次のような問いかけが、強く印象に残っています。 なんとしてでもClean Architectureを採用すべきでしょうか。 どんなアーキテクチャパターンを採用するとしても、そのパターンの経験があったり、パターンに精通していることが望ましいです。 アーキテクチャパターンが目的になっていないか これらは、当時の私の悩みに正面から答えてくれる内容でした。 Clean Architectureを採用したプロダクトをリリースした直後に本書を読んだこともあり、チームでパターンへの精通が揃わないまま走り切ってしまったことを、ページをめくるごとに痛感させられました。 本来であれば設計を選ぶ前に向き合うべきだった問いを、後追いで突きつけられている感覚です。 iOSに限らず、アーキテクチャ選定の場面では常に心に置いておくべき視点だと感じています。 長期的な開発・保守・運用まで見据えて選ぶことの大切さを、自身の反省と重ねて受け取った章でした。 このような方におすすめ これから、あるいは今まさにiOSアプリのアーキテクチャ設計に取り組むエンジニアにおすすめの一冊です。 iOSアプリのアーキテクチャを体系的にまとめた書籍は今でもそう多くないため、最初に手に取る一冊として機能すると思います。 また、iOSに限らずアーキテクチャの歴史や系譜に興味がある方にも価値のある内容です。 発売から7年近くが経つためTCAは扱われていませんが、TCAにつながるFluxの解説があり、現在のiOS開発の文脈でも参考になる部分は多く残っていると感じています。 最後は、事業推進でカンファレンスサービスを開発している山田さんです。山田さんが選んだのは、世界トップクラスのエンジニアの思考プロセスを言語化した一冊。AIコーディングエージェントが日常になった今だからこそ、再読の意味が増した本について語ってもらいました。 ■ 山田 / フルスタックエンジニア ■ ファインディ株式会社でフルスタックエンジニアをやっている山田です。ファインディのカンファレンスサービスを開発しています。 世界一流エンジニアの思考法 世界一流エンジニアの思考法 作者: 牛尾 剛 文藝春秋 Amazon 私が紹介する「世界一流エンジニアの思考法」は、Microsoft Azure Functions開発チームに身を置く著者が、世界トップクラスのエンジニアたちの思考プロセスと働き方を観察して言語化した一冊です。生産性の本質を「基礎理解の深さ」と「試行錯誤の前に思考する姿勢」に求めており、AI時代に再読する価値がむしろ増した本だと感じています。 この本を読んだきっかけ 最初に手に取ったのは、自身やチームの生産性向上を目的に、社内で技術的に優れたアウトプットを圧倒的な量で出し続ける同僚を意識した時期でした。実装スピードも設計の練度もPRの打数も桁が違う。その差分を言語化したくて、世界一流の現場で同種の人々に囲まれて働く著者の本を読みました。 最近になってAIコーディングエージェントが日常の道具となった時期に、自分の中の「思考順序」がAIを挟んで再び崩れ始めている自覚が芽生え、改めて初心に返り本書を再読することになりました。 本の内容 本書は7章構成で、第1章「世界一流エンジニアは何が違うのだろう?」から始まり、マインドセット、情報整理・記憶術、コミュニケーション、チームビルディング、生活習慣を経て、第7章「AI時代をどう生き残るか?」で締められます。 主軸は「生産性は時間ではなく思考の質で決まる」という立場で、具体的には次のような原則が繰り返し強調されます。 Be Lazy: 作業量を減らし、インパクトのある対象に集中する 理解の三要素: 説明可能/いつでも使える/応用可能、を満たして初めて「理解した」と言える 仮説駆動: 試行錯誤を悪とし、事実→仮説→検証の順序を守る シングルタスク/タイムボックス: マルチタスクは生産性が最低なのでやらない AI時代の生存戦略: 自分が学んだものとAIをどう掛け算するか この本から影響を受けた点/学んだ点 初読で強く影響を受けたのは次の二点でした。 基礎理解には時間をかけること。シニアが平気で数日を「読むだけ」に費やす描写から、表面的に動かす速度よりその後の実装と判断の速度を取りに行く姿勢を学びました。 試行錯誤の前に思考すること。手を動かす前に「事実を掴む → 仮説を立てる → 検証する」の順序を必ず通す習慣です。 再読で痛烈に蘇ったのは、AI時代において自分が崩していた順序の自覚でした。具体的には次の3つの兆候です。 AIのアウトプットの質を上げるために、プロンプトを試行錯誤で叩く回数が、自分の思考時間より長くなっていた AIを並列で走らせる並列業務に流され、シングルタスク原則が崩れていた AIが最初に出した "good code" を正にしてしまい、「bestなコードは何か/そこに至る道筋」を自分の頭で検討する工程が薄くなっていた ここから得た結論は、AIの登場は基礎の重要性を消したのではなく、見えにくくしただけということ。基礎力の向上は今も昔も時間がかかり、長い時間、同じ対象に向き合って初めて芽が出ます。AIを係数として効かせるための「自分側の係数」を、地道に上げ続ける意志が問われていると改めて認識しました。 特に印象に残った部分 第3章で示される「理解の三要素:説明可能/いつでも使える/応用可能」は、初読時から自分の判断基準として一番手元に残った概念です。再読時には、この三要素をそのままAI出力のレビュー基準として転用し、「生成されたコードを自分で説明できるか/別文脈で使えるか/応用が効くか」を改めて意識するようになりました。 もう一箇所は、第1章の「マルチタスクは生産性が最低なのでやらない」という言葉です。AIが並列処理を肩代わりしてくれる時代だからこそ、人間側がマルチタスクで思考の解像度を落とすのは本末転倒で、今手をつけている仕事を1つに限定することがAIを使いこなす前提条件だという文脈は再読で初めて腹に落ちたところがありました。 このような方におすすめ 周囲に桁違いのアウトプットを出すエンジニアがいて、その差分を言語化したい方 AIコーディングエージェントを使い始めてから、プロンプトの試行錯誤に時間を溶かしている自覚がある方 AIが出してきた "動くコード" をつい best として採用してしまっていることに違和感を持ち始めた方 並列タスクで日々が埋まり、1つの対象に深く向き合う時間が減っている方 「AI時代に技術力は不要になるのでは」という風潮に、戒めとしての軸を持ち直したい方 おわりに アジャイルを支える開発スタイル、iOSアーキテクチャを選ぶ視点、そしてAI時代に通用する思考法。今回紹介した3冊は扱うテーマこそバラバラですが、いずれも「自分の中の判断軸」を作り直す体験を与えてくれた本でした。 私はRailsとの出会いを通じて「小さく動くものを育てる」スタイルを、加藤さんはアーキテクチャ選定の問いを、山田さんは基礎理解と思考順序の重要性を、それぞれ本から受け取っています。年次を重ねるほど一冊の影響は薄まるのかと思いきや、振り返ってみるとむしろ「あのとき出会えた」一冊が、いまの判断や設計、思考のクセを支え続けている。エンジニアという仕事ならではの面白さだなと感じます。 皆さんにも、そんな一冊との出会いが一つでも増えるきっかけになれば嬉しいです。 ファインディでは一緒に働くメンバーを募集しています。少しでも興味を持っていただけた方は、ぜひこちらをご覧ください。
はじめに こんにちは!ファインディのTeam+開発部でエンジニアをしている澁谷( TENTEN11055 )です。 普段はチームで Findy Context というプロダクトの開発に取り組んでいます。 prtimes.jp 2025年11月、AWS主催のAI-DLC Unicorn Gymに参加し、AI駆動開発の手法であるAI-DLCを実践しました。 学びはとても大きかった一方で、自分たちのチームにそのまま持ち込むには壁もあり、現場の実態に合わせて作り変える必要がありました。 Unicorn Gym参加時の様子はこちら。 tech.findy.co.jp AI-DLCはAIが作業を実行し、人間が監視と判断に集中する開発手法です。 要件・ストーリー・作業単位を整理する Inception 、設計・実装・テストを進める Construction 、IaCやデプロイを担う Operation の3フェーズで構成され、AIが提案する成果物をチーム全員で検証しながら進めます。 チームではそのうち実装に関わるInceptionとConstructionの2フェーズを採用しました。 詳細は次の記事を参照ください。 aws.amazon.com この記事ではAI-DLCをClaude Skill化し、Epic制開発フローの中で要件整理からテストまでを一人のメンバーが一貫して担えるようにした取り組みを紹介します。 はじめに チームが抱える課題 担当領域越境の必要性 AI-DLCをそのまま取り入れる難しさ Epic制開発フローの導入 AI-DLCの2フェーズと付随する作業をClaude Skill化する 1. フォーマットのばらつきが改善 2. 横展開を容易にする 3. ツールを利用してよりシームレスな設計ができる 4. 付随するスキルの精度が上がり、人間の負担を下げる スキル運用後の効果とまとめ チームが抱える課題 これまではPMやデザイナー、QAエンジニアといった専任者と分業する形で開発してきましたが、チーム構成の変化により、エンジニア自身が担当領域を越境していく必要が出てきました。 担当領域越境の必要性 チームのフロントエンド専任者が一人のため、フロントの設計・実装を全て頼るわけにもいきません。 また4月末でQAエンジニアが別プロダクトへ異動となり、実装者のみでのテスト設計、ケース実装を担うことになりました。 さらに専任のPMも他プロダクトを兼務しており割ける時間が限られるため、要件整理など本来PMの領域だった部分にも開発者が踏み込んでいく必要があります。 これらを加味し、エンジニア一人一人が担当領域を広げる必要が出てきました。 AI-DLCをそのまま取り入れる難しさ そこで越境を支援する手段として、これまで個々人で自由に行なっていたAI-DLCをチームの開発フローとして取り入れることを検討しました。 しかしInceptionフェーズは関係者が集まって仕様を決めていくスタイルであり、その実施には一定の同期コストが発生します。 作りたい機能の具体が曖昧であればあるほど全員参加は効果的になりますが、Epicイシューが作成された段階で既に一定の解像度がある場合は、PMも含め全員で擦り合わせをすると、得られる解像度向上に対して投入する時間(チーム全体の同期コスト)の方が目立ってしまいます。 Epic制開発フローの導入 これらの課題を解決する一環としてチームではEpic制を導入しました。 こちらはVPoEの ham さんが Findy Team+ 開発で実施した 個人アサインへのシフト に影響を受けています。 tech.findy.co.jp 各Epicにメンバーをアサインすることで要件整理から開発まで一貫して責任を持つようになり、ボトルネックも発生しづらくなります。 実際の運用としては、大まかに次の流れで開発を進めています。 Epic担当者はAI-DLCスキルを用いてInceptionドキュメントを作成する ワイヤーフレーム作成スキルに1のドキュメントを読み込ませ、HTMLでワイヤーを作成する 1と2を元にデザイナーとPMに確認をとる AI-DLCスキルでConstructionドキュメント、テスト設計、テストケースを実装する デザイン、実装、テスト 受け入れ確認、リリース チーム内ではこれらを用いたフローを AI-E-DLC (AI - Epic - Driven Development Life Cycle) と名付けており、今後も運用と改善を重ねていこうとしています。 ここからはこのフローの1と4で利用するAI-DLCスキルについて掘り下げていきます。 AI-DLCの2フェーズと付随する作業をClaude Skill化する 同じプロンプトを用いてドキュメントを作成しても、AIの成果物にはばらつきが生じる可能性があります。 そのためAI-DLCにおけるInceptionとConstructionのドキュメント生成をそれぞれスキル化し、潜在的な課題をいくつか改善することができました。 1. フォーマットのばらつきが改善 同じAI-DLCのプロンプトを使っても、書き手によって構成・粒度にばらつきが生じたり、必要な情報が抜けたりすることで、実装・テスト設計・レビューなどの工程でAIが読み取りにくいドキュメントが生まれていました。 この課題に対し、スキルで手順と出力フォーマットを固定し、誰が実行しても同じ骨格のドキュメントを出力できるようにしています。 ちなみにこのフォーマットの固定化が多くの改善の起点になっており、これなしでは後述の内容も実現しえませんでした。 2. 横展開を容易にする AI-DLCの手法を各メンバーが再現するには、フェーズ理解・プロンプト設計・観点整理の習熟が必要であり属人化しやすいものですが、スキル化により手順がガイドされるため、未経験者でも気軽に実践できる「型」として提供できます。 またFindy Contextが複数リポジトリで構成されるため、リポジトリ非依存で動くスキルにしています。 今まで各リポジトリに合わせたプロンプトを用意する必要がありましたが、どれにおいても同じスキルを呼べばOKな状態にしています。 汎用性の高いスキルにすることでどこでも誰でもAI-DLCに則ったドキュメントを作成できるようになりました。 3. ツールを利用してよりシームレスな設計ができる AIからの質問事項にはClaude Codeの AskUserQuestion ツールを必ず利用させています。 InceptionではAIから人間への質問フェーズが存在し、ドキュメントに記載された質問に対し人間が回答を書き込むのが基本でした。 これに対し選択 or 自由回答という形式をとり回答候補を提示してもらうことで一から考えることがなくなるため、回答作業だけでなく脳の負担も軽減されました。 他にも一部の難易度の高い作業をAgentに任せるなど、場面に適した設定を共有できるのもスキル化の利点の一つです。 AskUserQuestionを利用した際のサンプル 4. 付随するスキルの精度が上がり、人間の負担を下げる フォーマットのばらつきが改善されたことにより、 専用のテスト設計・ケース実装スキルとドキュメントレビュースキル も作成することができました。 テストをAIで用意する際、何を材料とするかが重要です。 もしコードを材料とした場合、そのコードが仕様に沿っていなければ誤ったテストとなってしまいます。 このテスト設計・作成スキルはInception・Constructionドキュメントを材料とし、エンジニア・PM・デザイナー間で認識が揃った仕様を前提とするため高い精度を出すことができます。 またドキュメントレビューに関してはAI-DLCの中で最も人間の負荷が高い作業です。 AI-DLCスキルで生成されるドキュメントは10ファイルを超え、全部均等にレビューしようとすると破綻します。 そこでレビュースキル側で、生成されたドキュメントを「核となるドキュメント(仕様の中核を担うもの)」と「補助となるドキュメント(核を支える補足)」に分類し、Epicイシューとも照らし合わせて齟齬や抜けがないかをチェックさせています。 これにより人間が熟読すべきドキュメントを明確にし、レビュー負荷を下げることができました。 スキル運用後の効果とまとめ 運用を始めて数日が経ちましたが、想像以上に強力なスキルとフローであると感じています。 チームの課題でもあった「役割の越境」に対して有効なアプローチとなり、これまで専任者(PM・デザイナー・QAエンジニアなど)に頼っていた作業の下地を実装者が担い、専任者はレビュー・判断に集中できるようになりました。 習熟度の壁を下げられたことも大きな成果で、スキル作成後に説明する場を設けなくても気づいた時には他メンバーが使っており、数日後にはスキルの改善PRも上げてくれていました。 レビューにおいてもAI-DLCを始めた頃によくあった「ドキュメントレビューしんどい...」という声は幸いまだ聞こえてきていません。 今回の取り組みはAI-DLCをそのまま導入するのではなく、チームの開発体制や課題に合わせて適応させる試みでした。 まだ運用を始めて間もないため改善の余地はありますが、その部分に誰もが参加できる間口を用意できるのもスキル化の利点かもしれません。 ファインディでは一緒に働くメンバーを募集中です! よかったら覗いてみてください。 herp.careers
こんにちは、ファインディのCTO室でスタッフエンジニアを担当している及川(@rojoudotcom)です。 4月14日(火)〜16日(木)にDevOpsDays Tokyo 2026が開催されました。本記事は、スポンサー登壇者として参加してきたレポートです。 DevOpsDaysは、世界各地で開催されるエンジニア向けの国際カンファレンスです。 開発(Dev)と運用(Ops)の連携、自動化、組織文化、最新の事例やプラクティスを発表しています。日本では DevOpsDays Tokyo として、年に1回開かれています。 本記事では、開発組織の成果を経営層にどう伝えたらいいのかを悩まれている方や、AIを導入したのに成果が見えないと感じる方に向けて書きました。3日間のイベント参加を通じて改めて確信した「可視化は組織が動き出すための前提条件である」というメッセージを、登壇・基調講演・現地での会話の3つの角度から振り返ります。 開発組織は、経営から「見えない」 成果を見やすい形で可視化すれば、見える投資に変わる 経営から「見えない」と言われた開発組織を、仕組み・文化・習慣の3層で診断 組織設計に意図を持つことで組織の活動が見える 成果を見る側に立って翻訳する 仕組みを作り、文化を育て、習慣を変えれば、見えない現場は見える投資に変わる 可視化がない改善は、AIに増幅されない 「可視化されてはじめて、人は動く」 おわりに 開発組織は、経営から「見えない」 DevOpsという言葉についてのおさらいですが、もともと「DevとOpsの壁を壊す」ことから始まりました。コンテナ、CI/CD、SREといった方法論が広まり、Dev-Ops間の景色が変わったと感じる方は多いと思います。 一方で、 Devと経営(Biz)の間の壁は依然として高いままではないでしょうか 。 開発部門が作るソフトウェアは形がなく、損益計算書には給与や販管費などの「費用」としてしか記録されません。経営層の関心は売上向上や費用削減にあるのに対して、開発の関心は製品開発におけるリリース頻度の向上やリードタイム削減にあります。お互いが重要だと思う指標が異なることが、すれ違いを生み続けていると考えています。 成果を見やすい形で可視化すれば、見える投資に変わる 今回の登壇では、ファインディ以前に在籍していた現場の事例を話しました。経営層から状況が見えないと言われていた開発組織を意図を持って再設計し、活動の良し悪しを計測したことで投資の判断ができる状態とした体験談です。 テーマは「Dev-Bizの壁をどう越えるか」。20分のスポンサーセッションで持ち時間は短かったものの、自分の問題意識を言語化する貴重な機会になりました。   経営から「見えない」と言われた開発組織を、仕組み・文化・習慣の3層で診断 私が過去に在籍していたある企業の開発部門の話です。配属された開発部門は発足から20年が経つ自社サービスを担当しており、内製化を進めていたところでした。歴代の担当者は退職済みで、ドキュメントもなく、現場の判断は開発担当者の属人的なナレッジに委ねられていました。 エンジニアリングマネージャとして組織の状況を把握するために現場関係者にヒアリングを始めると、様々なことが見えてきました。 まず、組織のサイロ化が進む仕組みが見えてきました。開発に関わるメンバーはプロジェクトの終了と共に解散するため組織ナレッジが溜まりにくいこと、そして新機能開発チーム(Dev)と運用改善チーム(Ops)は分断されており、特にOpsチームに届けられる改善要求は、その背景が不透明なまま改修が行われていました。 次に、受け身の文化が根付いていました。歴史的に要求は事業部が作成し、開発側は要求を待つ立場だったためです。さらに、上位下達の関係性から、開発側からの提案や意見を出しづらい状況でした。 最後に、経営層からすると、PLやBSの数字以上に開発の状況が見えない状態が続いていて、それ以上踏み込めない状況が習慣化されていました。リソースをどこに集中すべきか、開発予算は適正なのかの判断ができない状況でした。 組織設計に意図を持つことで組織の活動が見える 見えない状態は、組織の設計に「なぜそうしたか」の意図がないことが原因です。最初の取り組みとしてTeam Topologiesで組織体制を再設計しました。すると、顧客の要望がどこからきてどこに流れていくのか(バリューストリーム)を見えるようになり、それぞれの開発チームの責任範囲やチーム間の関係性も明確になりました。 組織の枠組みが整ったところで次はチームの中身(マインドセットや運用ルール)です。アジャイル開発のスクラムフレームワークを導入し、自己管理化を進めていきました。チーム自身が開発案件の優先度や実現方法を話し合うようになりました。さらに、システム的観点から事業部の要望に対する逆提案が生まれるようになりました。 そして、新体制が動き出してきたところでFindy Team+を導入し、開発チームのリードタイムやボトルネックを可視化し、定量的なデータを取り始めました。半年後にはリードタイムが従来比8割短縮、デプロイ頻度も3割増加し、経営層に対しても改善を数字で示せるようになりました。 成果を見る側に立って翻訳する Four Keysによる開発活動の成果や、新機能が完成したときに得られるであろう期待される売上やコスト削減効果は重要な数字ではありますが、経営層が理解するにはもう一歩踏み込む必要があります。 例えば開発生産性が向上したことで稼働可能な人月が増えたと同等の効果と捉えれば、管理会計の項目のどこに増減の影響が生まれるのか。あるいは、リリース回数が増えたことで事業計画がどの程度短縮できるのか。こうした情報は決算書にも書けるような話題で、経営層にとって必要な情報です。 このように、投資判断を行う経営層の立場に立ち、開発の活動を翻訳して伝えることで、ようやく開発部門に対する投資判断の議論ができるようになりました。 仕組みを作り、文化を育て、習慣を変えれば、見えない現場は見える投資に変わる 以上、目の前の問題の直接解決ではなく、問題を生み出す構造(仕組み・文化・習慣)に目を向けて根本解決を促すストーリーでした。 さらに詳しい内容はスライドをご覧いただけるとうれしいです。 見えない開発現場を、見える投資に変える — Speaker Deck 可視化がない改善は、AIに増幅されない 「可視化が大事」とは言われ続けてきました。それでも今このテーマで登壇しようと思ったのは、AI時代に入って、その重要性が以前にも増して大きくなっていると感じていたからです。そして、その直感はカンファレンスの基調講演で裏付けられました。 Google CloudでDORA(DevOps Research and Assessment)プログラムを率いるNathen Harvey氏によれば、 2025年の調査でAI採用率は90%に達した そうです(前年比+14%)。 一方で、コード品質や個人の生産性は上がったものの、 ソフトウェアデリバリーの安定性は悪化していました 。Harvey氏はこの現象を踏まえて、AIの役割を「 増幅器(amplifier) 」と表現していました。 良いシステムには良い結果を、悪いシステムには悪い結果を増幅するもの という意味合いです。 この比喩がしっくり来たのは、増幅されるためにはまず「何が起きているか」が見えていなければならない、という当たり前の前提が浮かび上がるからです。 可視化されていないデータをAIに与えてもノイズを増幅するだけです。可視化されていない開発組織は、AIを入れても何が良くなったのか悪くなったのかすら判断できません。 AI採用は、可視化された土台の上ではじめて成果に結びつく 基調講演から受け取ったメッセージはそこに集約されていました。 そして、もう一つの基調講演でDevOpsムーブメントの礎を築いた一人であるAndrew Clay Shafer氏が残した「 行動を変えるまでは、何も学んでいない 」という一言も、同じことを別の角度から言っていると感じました。見えなければ学ぶことはできないですし、闇雲に行動することになります。それは学んでいないのと同じことです。 ここで触れた2つの基調講演のセッション情報は次のとおりです。 confengine.com confengine.com 「可視化されてはじめて、人は動く」 3日間で一番心に残ったのは、技術的な議論ではなく、夜の懇親会で交わした一つの会話でした。 懇親会で日本酒を参加者に勧めていたとき、たまたまDay1の基調講演スピーカーのNathen Harvey氏が近くにいました。興奮して握手を交わし自己紹介をすると、彼は「 ファインディのプロダクトを見せて欲しい 」とリクエストしてくれました。 その場でブース担当者を呼んで、開発生産性可視化のデモをしました。彼はそれを見終えた後、こう言いました。 可視化することで、ようやく人は動き出すんだよね。 自分の登壇で伝えたかったことも、基調講演で語られていたDORAの研究も、3日間で出会った人たちが共有していた問題意識も、この一文で言い表されていると感じました。 Four Keysのような生産性指標で 内側の現在地 を、DORAのような調査レポートで 外側の方向性 を捉え、両者のギャップを埋めていきます。 可視化はゴールではなく、組織が動き出すための出発点です。 Dev-Bizの壁を越えるにも、AIを増幅器として活かすにも、共通して まず見えていること が要ります。これが3日間を貫いていたメッセージでした。 翌日のスピーカーインタビューのアイスブレイクで「日本に来てどうですか?」と聞かれたHarvey氏が「 ファインディに会えたことが思い出になった 」と答えてくれたのは、嬉しいおまけでした。 おわりに 開発組織を率いるマネジメント層にとって、可視化は「あれば便利な機能」ではなく「動き出すための前提条件」だと、今回の3日間で改めて確信しました。当社は指標を計測するサービスを提供する側だからこそ、組織を歪ませない設計に責任があると、身が引き締まる思いです。 DevOpsDays Tokyoに参加することで、スピーカー同士、運営の方々、そして海外登壇者との繋がりをつくることができ、DevOps文化に貢献したい気持ちも高まりました。来年の開催も楽しみにしています。 ファインディでは一緒に会社を盛り上げてくれるメンバーを募集中です。興味を持っていただいた方はこちらのページからご応募お願いします。 herp.careers
ソフトウェア開発現代史年表Ver2.08 はじめに デリバリーは速ければよいのか 改めて、Four Keysは何を測っているのか 「デプロイ」と「リリース」の混同がFour Keysを遠ざける Dave Farley氏とは 『Continuous Delivery』(2010) は何を変えたか 二つの意味を持つ「リリース」 AI時代に、継続的デリバリーはなぜ重要になるのか AI駆動開発を空回りさせないために 【告知】AI DevEx Conference 2026 - Future of Development Productivity - おわりに はじめに こんにちは。テックブログ編集長の高橋( @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が現在「ソフトウェアデリバリーパフォーマンス」をどう捉えているかを整理しておきましょう。 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(ソフトウェア開発ライフサイクル)上のどこに当てはまるのかを見てみましょう。 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氏は、継続的デリバリーを語るうえで避けて通れない人物です。 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) は何を変えたか Continuous Delivery: Reliable Software Releases through Build, Test, and Deployment Automation (Addison-Wesley Signature Series (Fowler)) 作者: Jez Humble , David Farley Addison-Wesley Professional Amazon 継続的デリバリー 信頼できるソフトウェアリリースのためのビルド・テスト・デプロイメントの自動化 作者: Jez Humble , David Farley KADOKAWA Amazon Jez Humble氏とFarley氏が2010年に出版した『Continuous Delivery: Reliable Software Releases through Build, Test, and Deployment Automation』は、何を変えたのでしょうか。 2010年当時、リリースは重く、失敗が許されないイベントとして扱われていました。本番投入の前には長い調整期間があり、変更はできるだけまとめて出すのが当たり前でした。 『Continuous Delivery』は、この前提を見直す考え方を示しました。 ここでいう「Delivery」は、ソフトウェアをいつでもリリースできる状態に保ち続けることを指します。デプロイ作業そのものや、ユーザー公開としてのリリースとは別の概念です。 主張の柱は、次の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)でも、開発そのものをエンジニアリングとして捉え直し、素早く学ぶことと複雑さを制御することの重要性を説いています。 Modern Software Engineering: Doing What Works to Build Better Software Faster (English Edition) 作者: Farley, David Addison-Wesley Professional Amazon 継続的デリバリーのソフトウェア工学 もっと早く、もっと良いソフトウェアを作るための秘訣 作者: David Farley 日経BP Amazon 変更を小さく保ち、素早く学び、複雑さを制御する姿勢は、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が良い方向に働いているかは判断できません。 技術的発展の階層構造。これらの土台作りが重要。 ここでいう「継続的デリバリーができない」は、単にデプロイ自動化がないことではなく、変更を小さく保ち、デプロイとリリースを切り分け、ユーザーへの影響を制御しながら継続的に届ける仕組みがない状態を指します。 「デプロイ」と「リリース」の混同に、「フィーチャーファクトリー」の罠が重なれば、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社以上が登壇します。 ぜひご参加ください! おわりに ファインディでは一緒に会社を盛り上げてくれるメンバーを募集中です。興味を持っていただいた方はこちらのページからご応募お願いします。
こんにちは!ファインディの大石( @bicstone )、甲斐( @karukan013L23 )、千田( @_c0909 )です。先日、ファインディはベルサール羽田空港で開催された「TSKaigi 2026」に協賛しました。 今回はDevRelメンバーとフロントエンドエンジニア3名で参加し、ブース運営を行いました。本記事ではTSKaigi 2026において印象深かったセッションの紹介や登壇、ブース出展などの活動内容を紹介します。 ブースで実施したユーティリティ型アンケートの集計結果(480票)も後半で公開していますので、ぜひ最後までお読みください。 TSKaigi 2026について 印象深かったセッション 【大石】TS 7: How We Got There 【甲斐】tscからtsgoへ ── DenoのTypeScript基盤はどう変わったか 【千田】Oxlint は ESLint / typescript-eslint を置き換えられるか? 【大石】CfP登壇: TypeScript 6.0での型推論修正を追う ファインディの活動 アンケート結果 さいごに お知らせ 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) のプロジェクトを tsc と tsgo それぞれで実行した際の所要時間と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日間かけて多くの方に投票いただきました。 TSKaigi2026始まりました!入口すぐです! お待ちしております🌟 #TSkaigi2026 #tskaigi pic.twitter.com/ecf1Zzok0V — いわさき@Findy DevRel (@iwasakitchen) 2026年5月22日 x.com アンケートの最終結果はこちらになります。たくさんの投票ありがとうございました。 TSKaigi 2026改めて2日間ご参加いただき、ありがとうございました!よく使うユーティリティの「型」は?の最終結果です!😊🎊 #TSkaigi #TSkaigi2026 pic.twitter.com/0Nt4xun2bQ — いわさき@Findy DevRel (@iwasakitchen) 2026年5月23日 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
はじめに こんにちは、ファインディ株式会社でエンジニアをしている中嶋( @nakayama__bird )です。現在は、新規プロダクトであるFindy Contextの開発に携わっています。 ファインディでは、これまでSREチームが担っていた新規プロダクトのクラウド環境の構築から監視体制の整備までを、プロダクト開発チーム主体で行う体制に切り替えました。 本記事では、私自身がFindy Contextの環境立ち上げを担当した経験を、アプリケーションエンジニアの視点で振り返ります。 経験の浅いエンジニアにとって、0→1のクラウド環境構築は不安の大きい領域です。「自分にできるのか」と思いながら着手した私が前に進めたのは、「SREチームが整えてくれた仕組み」と「自分で進めた学習」、その2つが揃っていたからでした。 それぞれがどう機能したかを、これから体験ベースでお伝えします。 はじめに Findy Contextとは 背景: なぜ開発チーム主体に切り替わったのか これまでの体制 直近の事情の変化 方針転換: 開発チームメインの立ち上げへ 着手前の筆者スペック 委譲のスコープと私が担当した範囲 AWSアカウント発行とインフラ構築基盤整備 インフラリソースの構築 デプロイと運用の整備 監視(Datadog)の整備 個人として取り組んだこと 今後の伸び代 自分側 仕組み側(汎用モジュール・テンプレートへの改善余地) まとめ 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
こんにちは。ファインディでフロントエンドエンジニアをしている大石( @bicstone )です。 2026年5月22日〜23日に開催される TSKaigi 2026 で、 「プロパティの順序で型推論が壊れる!? TS6.0の修正からContext-Sensitivityの仕組みを追う」 というタイトルで登壇します。本記事は10分のトーク内では時間の都合で端折った内容も含めた拡張版としてお届けします。 2026.tskaigi.org TypeScriptでオブジェクトリテラルにメソッドを書いたとき、プロパティの記述順序を入れ替えただけで型推論の結果が変わるとしたら、どう感じるでしょうか。「そんな不思議な挙動があるのか」「気になるけどTypeScript内部のソースコードは難しそうで自分には縁がない」と思った方もいるかもしれません。 この記事では、この不思議な挙動を入り口にしてTypeScriptコンパイラの中で何が起きているのかを1つのPRから追いながら解説します。 背景: プロパティの順序で型が変わる アロー関数なら問題ないのはなぜか Context-Sensitive Functionの考え方 推論の全体像 メソッド構文に隠れている暗黙のthisパラメータ 両方スキップで起こる順序依存の正体 今回の修正を読み解く binder.ts: ContainsThisフラグを立てる utilities.ts: hasContextSensitiveParametersの変更 checker.ts: Generator固有のエッジケース 修正前後の推論を比較する TypeScript 5.9 TypeScript 6.0 TypeScriptのコンパイラを読む最初の一歩 おわりに 参考資料 背景: プロパティの順序で型が変わる 次の test 関数を見てください。型パラメータ T を持ち、2つのプロパティ a と b を受け取ります。 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のジェネリック関数における型推論は、おおまかに次の流れで行われます。 引数を走査し、context-sensitiveな関数を特定する context-sensitiveな関数をスキップする 残りから型パラメータ T を推論する 確定した 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 が先に書かれている場合、推論パイプラインでは次のように処理されます。 a(c) → 暗黙の this → context-sensitive → スキップ b() → 暗黙の this → context-sensitive → スキップ 両方スキップ → T を推論するソースがない フォールバックとして、左 → 右の順番で処理を試みる a(c) を先に処理 → T が未確定 → c: unknown b が先に書かれていた場合はどうなるでしょうか。 同じく両方スキップされる フォールバックとして、左 → 右の順番で b() を先に処理 b() の戻り値 123 から T = number を推論 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.ts の hasContextSensitiveParameters 関数は、関数が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 では、 isContextSensitive の switch に YieldExpression のケースを追加し、 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 a(c) → 暗黙の this → context-sensitive → スキップ b() → 暗黙の this → context-sensitive → スキップ 両方スキップ → T を推論するソースなし フォールバックとして、左→右の順番で処理 a(c) を先に処理 → T が未確定 c: unknown TypeScript 6.0 a(c) → this 不使用 → ContainsThis なし → スキップしない b() → this 不使用 → ContainsThis なし → スキップしない 通常の推論へ b() の戻り値から T = number を推論 a(c) に T = number を適用 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の内部に踏み込むきっかけを持ち帰っていただけたら嬉しいです。 参考資料 Announcing TypeScript 6.0 Beta - TypeScript microsoft/TypeScript - GitHub Improve inference by not considering thisless functions to be context-sensitive by Andarist · Pull Request #62243 · microsoft/TypeScript microsoft/TypeScript-Compiler-Notes - GitHub TypeScript Compiler Internals | TypeScript Deep Dive ファインディでは一緒に会社を盛り上げてくれるメンバーを募集中です。興味を持っていただいた方はこちらのページからご応募お願いします。 herp.careers 本記事の binder.ts / utilities.ts / checker.ts のコードは、 microsoft/TypeScript から引用しており、 Apache License 2.0 のもとで配布されています。
こんにちは。こんばんは。 Findy Team+ 開発のフロントエンドリードをしている @shoota です。 今回はフロントエンドからは少し離れ、AIによるプルリクエストのレビューシステムを作成した話を書きます。 Findy Team+フロントエンドの現状と課題 AIコーディング時代の新たな課題 AIによる自動レビュー(Approve)を作ろう 解決したい課題 レビューは大きく3種類ある 誰が使えるのか 何を判定するのか 判定のキモはTidy First?の分類 実装とポイント GitHub Actions Claude Code Actions ワークフローの変化とプロンプトの改善 実行コスト おわりに 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 に近いのではないか?と考えました。 hustle porn 覚えた https://t.co/y3jpiLDL0x — Takuto Wada (@t_wada) 2026年4月13日 プルリクエストをたくさん書くことは素晴らしいですが、そこに意味のある粒度と価値が伴わなければなりません。 AIによる自動レビュー(Approve)を作ろう このような背景からレビュー負荷を可能な限り低減させ、ただしい 怠惰 を取り戻すために、AIレビューの仕組みを作成することにしました。 まずはやりたいことから全体の構想とコンセプトを決めていき、次のような内容になりました。 解決したい課題 プルリクエストを高速に作り続けることはむしろ歓迎すべき 課題の本質は「レビュープロセスが対ひとでしか機能していない」こと 人の時間をうばう 人のアクションを待つ 両者にメリットが少ない レビューは大きく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本のセッションを参加できなかった方にもイメージが伝わるようにまとめます。 イベント開催の背景 セッション1: ファインディの事業拡大を支える拡張可能なデータ基盤へのリアーキテクチャ セッション2: データモデリングを通して管理会計のオペレーションを再設計 セッション3: 社内で使われるLooker整備の進め方 まとめ イベント開催の背景 ファインディでは、既存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
こんにちは、ファインディでFindy Toolsの開発をしている本田です。 このたび、Findy Toolsの新機能として「アーキテクチャAI」をリリースしました。要件を入力するとAWSのアーキテクチャ図と設計の提案が生成される機能です。 findy.co.jp 今回の開発では、PM・仕様策定・スコープ定義・インフラ・FE/BE開発・テストまで、ほぼ一人で1か月で担当しました。そして、コーディングはほとんどClaude Codeに任せ、私自身はほぼコードを書いていません。 この記事では、そんな開発を進めるなかで分かったこと、難しかったこと、そして改めて実感したエンジニアの仕事について紹介します。 アーキテクチャAIについて 一人開発の全体像 エンジニアが価値とコストを自分で判断する 対話で判断の視野を広げる 動くもので共通認識を作る 自分の仕事は減らず、判断と意思決定の時間が増えた まとめ アーキテクチャAIについて 本題に入る前に、リリースした機能を軽く紹介させてください。 アーキテクチャAIは、Findy Toolsの中で提供している機能の1つで、「作りたいシステムの要件」を入力するとAWSを使った構成案とアーキテクチャ図、そして設計の考え方の解説がまとまった形で得られるものです。 ai-architecture.findy-tools.io アーキテクチャの設計はサービスの土台を決める工程で、経験や周辺知識の広さが問われる領域です。そうした知見を持った人に相談しづらい場面でも、構成の検討を前に進める助けになることを目指しています。 ここから先は、この機能を一人で1か月で作ったなかで気づいたことを中心に書いていきます。 一人開発の全体像 今回は、PMから開発、テスト、リリースまでを一人で担当しました。具体的には次のような範囲です。 プロダクトの方向性・優先順位の決定 仕様策定、スコープ定義 インフラの構築 フロントエンド・バックエンドの実装 テスト、リリース作業 開発のワークフローはシンプルで、だいたいこのサイクルを回していました。 GitHub Issueに「なぜ作るのか」「何を作るのか」を、PRDやユーザーストーリーの形で書く Claude CodeにIssueを渡して実装してもらう 自分は差分をレビューし、必要に応じて指示を出す 別チームのメンバーにレビューしてもらい、PRをマージする 実装の途中でも、作りたい背景やユーザーに届けたい価値に立ち戻って方針を調整することはよくありました。 仕様策定やUIのモック作成も、AIと壁打ちしながら進めていました。結果として、自分でコードを書いた量はごくわずかで、ほとんどの実装はClaude Codeが書いています。 一方で、「自分はほぼコードを書いていない」からといって仕事が少ないわけではありませんでした。むしろコーディング以外にやることが山ほどあるというのが実感です。 何を作るか、何を削るかの判断 仕様の細部に関する意思決定 技術選定 コードレビューと品質の担保 スケジュール管理とリリース計画 ここからは、この進め方で1か月やってみて感じたことを書いていきます。 エンジニアが価値とコストを自分で判断する 最も強く感じたのは、 エンジニア自身がユーザー価値と実装コストのバランスを判断しながら開発に携わることの強み です。 今回は一人で担当していたので、事業やプロダクトの意図、技術的な実現可能性、実装コストが、すべて自分の頭の中に揃っていました。「ユーザー価値として外せない部分はどこか」「コストをかける価値があるのはどこか」を、自分の中でつなげて考えながら開発を進めることができます。 具体的には、開発の途中でアーキテクチャ図の描画ライブラリを切り替える判断をしたり、リリースの2週間前になってからSNSで共有されたときに見栄えの良い画像を生成する機能を追加する判断をしたりと、方針転換を素早く進められました。技術的に成立するかをClaude Codeで素早く検証しつつ、プロダクトとして本当に必要かを自分で判断できたことで、価値とコストの両取りを狙える選択肢を見つけやすくなっていました。 体制を一人にしたことが本質ではないと思っています。大事なのはやはり、作る側のエンジニアがユーザー価値や事業価値を理解したうえで、コストと価値のバランスを判断しながら開発に携われているかだと、今回の開発を通じて改めて感じました。 対話で判断の視野を広げる 意思決定が速いのは良いことですが、速ければ良いわけではありません。一つの視点だけで速く判断を続けていると、気づかないうちに筋の悪い方に流れてしまいます。 ここで効いてきたのが、一人で担当していても孤立はしていないという体制づくりでした。 開発中は、事業部長・PO・デザイナと定期的に相談・共有できる場を持ち、それ以外の場面でもいつでもコミュニケーションを取れるようにしていました。 プロダクトとして何を大事にしているか 事業としてこの機能にどういう期待があるか デザインとして譲れない部分はどこか こうした観点を継続的にすり合わせることで、自分一人では見えていなかったより良い選択肢を見つけやすくしていました。 自分の頭の中だけで判断すると、どうしても視野が狭くなります。そこに他の立場の視点が入ると、「他にもっと良い選び方はないか」という問い直しができます。スピード重視の体制であっても、というよりスピード重視だからこそ、チームとの対話は欠かせないと感じました。 動くもので共通認識を作る もう1つ強く感じたのが、 速く見せられるもの・動くものを使って共通認識を作ることの効果 です。これ自体は昔からよく言われる話ですが、AIの力でぐっとやりやすくなりました。 今回は、実プロダクトの開発を始める前に、別リポジトリでPoCアプリを作り、ステークホルダーやインタビューにご協力いただいた方に、実際に見たり触ったりしてもらう時間を取りました。 PoCアプリの画面。デザインは作り込まず、ユーザーに価値を体験してもらうことを優先した。 文章やスライドだけで議論すると、どうしても抽象的になり、認識のズレに気づきにくくなります。動くものがあると、「これは欲しい」「ここは期待と違う」というフィードバックが具体的に返ってくるだけでなく、「どういう価値が得られそうか」という部分でも共通認識を作りやすくなります。 PoCを見たり触ったりしてもらうなかで見えてきたのは次のようなことです。 ユーザーが本当に価値を感じるのはどの部分か 最初はあると便利そうに見えたが、実際はなくても困らない機能 技術的に見落としていた制約や、逆に想定より軽く実現できそうな部分 PoCで得られたこれらの情報が土台になって、本開発のスコープと方針が定まっていきました。 AIで「仮に動くもの」を高速に作れるようになった強みを活かして、動くものを中心に仮説検証のサイクルを回せたこと が、1か月という限られた期間のなかで特に効いたポイントだと思います。 自分の仕事は減らず、判断と意思決定の時間が増えた ここまで書いてきたことを踏まえて、改めて感じたのは 少なくとも今回の自分の経験では、コーディングをAIに任せても、エンジニアとしてやることは減らなかった ということです。むしろ、本質的な判断に集中する必要が出てきた感覚でした。 今回の開発で自分が時間を使っていたのは、次のような部分です。 この機能を作る意味は何か、誰のどんな課題を解くのか スコープをどこまで広げ、どこで切るか どの技術を選び、どの技術を見送るか 出てきたコードが本当に要件を満たしているか、将来の運用に耐えるか どれも、意思決定と判断の仕事です。コーディングそのものをAIに任せられるからこそ、こうした判断に集中できる時間が増えました。 AIと協業するなかで変わる部分と変わらない部分があり、「コードを書く時間」は確実に減りますが、「エンジニアリングを行う時間」は減らない、むしろ増えている感覚でした。 まとめ ほぼ一人で1か月かけてアーキテクチャAIをリリースしてみて、次のことが学びとして残りました。 エンジニア自身がユーザー価値と実装コストのバランスを判断しながら開発に携われると、価値とコストの両取りを狙える選択肢を見つけやすい 速さだけを追うのではなく、複数の視点を対話で取り込んで選択肢を広げていく AIで仮の動くものを高速に作れるようになった強みを活かせば、短期間でも動くものを軸に仮説検証を回しやすい 少なくとも今回の自分の経験では、コーディングをAIに任せても仕事は減らず、判断と意思決定に集中する時間が増えた AIと一緒に開発する時代になっても、「何を作るか」「どう作るか」「なぜそれを選ぶか」を考え抜くことの大切さは変わらないなと、今回の開発を通じて改めて感じました。 アーキテクチャAIは次のページから触れます(Findy Toolsの会員登録が必要です)。ご興味のある方はぜひ試してみてください。 findy-tools.io ファインディでは一緒に会社を盛り上げてくれるメンバーを募集中です。興味を持っていただいた方はこちらのページからご応募お願いします。 herp.careers