目次 はじめに Partial Prefetchingは何を解決するのか すべてを先読みする方法と、何も先読みしない方法の中間を作る OISHYでPartial Prefetchingを試す 検証条件 計測方法 実験1:クリック前の取得を減らすと、通信と遷移はどう変わるか 実験2:URL固有のデータを待つ間に何が見えるか 補足:適用範囲によって先読みの形が異なった まとめ 参考文献 はじめに こんにちは、開発本部の 黒髙 です。最近はアメリカ向けレシピサービスである OISHY の開発に関わっています。 Next.js 16.3 では、ページ遷移の応答性を改善する仕組みとして Instant Navigations が追加されました。クリック前に再利用できるUIやデータを準備し、クリック後に必要な部分を取得することで、遷移直後から次のページを描画しやすくする仕組みです。 Instant Navigationsを構成する機能のうち、今回取り上げるのは Partial Prefetching です。本記事では、Partial Prefetchingを紹介したうえで、OISHYの既存ページでは通信と画面遷移にどのように現れるのかを検証します。 Partial Prefetchingは何を解決するのか すべてを先読みする方法と、何も先読みしない方法の中間を作る Next.jsの <Link> によるprefetch(先読み) では、リンクが画面内に入ると、ユーザーがクリックする前に遷移先のデータを取得します。クリック時にデータが揃っていれば、遷移先をすぐに表示できます。 一方、リンクが多い画面では、実際にはクリックされないリンクのデータも取得します。先読みを無効にすれば事前通信はなくなりますが、その場合はクリックしてから遷移先のデータを取得することになります。 Next.js 16.3のPartial Prefetchingは、この二つの中間を作る機能です。Cache Componentsを使うページへの既定の <Link> では、URLごとの完成形をすべて先読みする代わりに、同じ種類のページで再利用できるApp Shellを先読みします。クリックされたURLに固有のデータは、必要になった時点で取得します。 App Shell とは、URL固有のデータを待たずに表示できるページの共通部分です。サイト共通のレイアウトや、データの読み込み中に表示するUIなどが含まれます。 レシピ詳細ページを例にすると、レシピ名や材料はURLごとに変わりますが、それらを待っている間の枠組みは複数のレシピで共有できます。 同じルートを指す複数のリンクで一つのApp Shellを再利用できる ため、リンクごとに同じ共通部分を取得し直す必要もありません。 この仕組みは、次のようなページで効果が現れやすいと考えられます。 商品、記事、レシピなど、同じ種類の詳細ページへのリンクが多数並ぶ 表示されたリンクのうち、実際にクリックされるのは一部だけである 詳細ページに、共通レイアウトやデータ取得中の表示など、URLをまたいで再利用できる部分がある OISHYのトップページにも、同じ /recipes/[id] へ遷移するレシピリンクが多数並びます。そこで今回は、レシピ詳細ページをPartial Prefetchingへ切り替えたとき、クリック前の通信とクリック後の表示がどう変わるかを確かめました。 OISHYでPartial Prefetchingを試す OISHYでは、すでに Cache Components を有効にしています。まず、レシピ詳細ページへの遷移にPartial Prefetchingを適用するため、次の設定を追加しました。 // app/recipes/[id]/page.tsx export const prefetch = 'partial' ; 公式リファレンスでは、 prefetch = 'partial' はリンクではなく遷移先に設定する ものと説明されています。この設定により、レシピ詳細ページをPartial Prefetchingへ段階的に切り替えます。 検証条件 主な検証では、次の3条件を比較しました。 条件 Next.js Partial Prefetchingを適用する場所 データ取得中の表示 条件A 16.2.11 適用しない なし 条件B 16.3.1 レシピ詳細ページ なし 条件C 16.3.1 レシピ詳細ページ スケルトン表示 実験1では条件Aと条件Bを比較し、クリック前の取得を減らしたときに通信と画面遷移がどう変わるかを確認しました。実験2では条件Bと条件Cを比較し、URL固有のデータを待つ間にApp Shellが画面にどう現れるかを確認しました。 以下で扱う条件B・Cと補足検証の先読み通信は、Next.js 16.3.1で観測したものです。内部的な通信の形は、今後のバージョンで変わる可能性があります。 OISHYの既存構成では、Next.jsの standalone server をECSで動かし、その前段にCloudFrontとALBを置いています。今回の計測もこの配信経路で行いました。 計測方法 対象 :同じ10件のレシピを、それぞれ3回ずつ計測 操作 :トップページを新しいタブで開き、対象リンクが画面内に入る位置までスクロール。5秒待ってからクリックし、クリック前の先読み通信とレシピタイトルが表示されるまでの通信・時間を記録 ブラウザ条件 :画面サイズは1280×900、回線速度の制限はなし。ブラウザ側のHTTPキャッシュは計測のたびに無効化し、スクロール位置とクリックまでの待ち時間を統一 集計 :各レシピの3回の中央値を求めたあと、10件の中央値を代表値として使用。通信量にはChrome DevTools Protocolの Network.loadingFinished.encodedDataLength を使い、ブラウザが受信したデータ量に近い値を比較 実験1:クリック前の取得を減らすと、通信と遷移はどう変わるか 最初に、Next.js 16.2.11の条件Aと、16.3.1へ更新してレシピ詳細ページをPartial Prefetchingへ切り替えた条件Bを比較しました。この比較にはNext.js自体の更新も含まれるため、Partial Prefetchingだけの効果ではなく、OISHYで16.3.1への更新と機能導入を行った前後差として扱います。 ここでいう RSC(React Server Components)データ は、Next.jsがクライアント側の画面を更新するために送るデータです。 指標(中央値) 条件A(変更前) 条件B(レシピ詳細ページに適用) クリック前のRSCリクエスト 75 6 クリック前の転送量 約319KB 約20KB クリック後のRSCリクエスト 0 1 クリック後の転送量 0KB 約20KB クリック前後の合計リクエスト 75 7 クリック前後の合計転送量 約319KB 約38KB クリック前のリクエスト数は約92%、転送量は約94%減りました。クリック後には、選択したレシピのRSCリクエストが1件発生しています。それを含めた合計転送量も約88%減っており、クリック前の通信がそのまますべてクリック後へ移ったわけではありませんでした。 変更前は、画面内に並ぶ多数のレシピについてURL固有のRSCデータを取得していました。変更後は、共通部分を先読みし、選択したレシピのデータをクリック後に取得しています。今回の画面では、クリックされなかったレシピへの先読みが減ったことが、通信量の差として大きく現れました。 次の画像は1回の計測例で、表の数値は反復計測から求めた代表値です。 条件Bでのクリック前のNetwork記録の例 一方、クリックからレシピタイトルが表示されるまでの代表値は、変更前が約44ms、変更後が約82msで、どちらも100ms未満でした。URL固有のデータをクリック後に取得するようになったことと整合しますが、今回の条件では目視できるほど長い待ち時間にはなりませんでした。大きく変わったのは、完成画面が出るまでの見た目よりも、クリック前に取得するデータの量でした。 なお、この結果は回線速度を制限しない環境でのものです。Partial Prefetchingは、クリック前の転送量を減らす代わりに、URL固有データの取得をクリック後へ移す仕組みです。低速な回線では、クリック後の待ち時間が今回より長くなる可能性がある一方、クリックされないリンクへの先読みを抑える効果は大きくなるため、有効に働くかどうかは通信環境によってトレードオフになり得ます。 実験2:URL固有のデータを待つ間に何が見えるか Partial Prefetchingでは、URL固有のデータがクリック時点で揃っていなければ、クリック後にデータの取得を待つ時間が生じます。その間にApp Shellがどのように現れるかを見るため、条件Cではレシピデータの取得中に表示するスケルトンを loading.tsx として定義しました。 loading.tsx 自体はNext.js 16.3の新機能ではありません。同じルート階層のページを Suspense 境界で囲み、定義したUIをデータの準備中に表示する仕組みです。Partial Prefetchingでは、 この代替表示を含むApp Shellが先読みの対象になります 。 // app/recipes/[id]/loading.tsx export default function RecipeDetailLoading () { return < RecipeDetailSkeleton /> ; } スケルトンとは、完成後のレイアウトに近い枠を先に表示し、データを待っている場所を示すUIです。今回のレシピ詳細ページでは、次のスケルトンがApp Shellとして先に表示される部分になります。 レシピ詳細ページのスケルトン表示例 30回中25回はスケルトンを経由せず、完成したレシピ詳細が直接表示されました。スケルトンが先に現れたのは5回で、クリックから14〜22msで表示され、レシピタイトルより約68〜856ms先行しました。 この結果から、スケルトンは毎回挟まる中間画面ではなく、レシピ固有のデータがクリックまでに揃わなかった場合だけ、遷移先の枠組みとして先に表示されることが分かりました。 また、条件Cの通信を追加で確認すると、条件Bとは異なる挙動が見つかりました。条件Bではレシピ固有のデータをクリック後に取得していた一方、条件Cの補完計測では、10回中4回で複数のレシピ固有データをクリック前に取得するRSC通信が並びました。 条件Cでクリック前に観測したレシピ固有データの先読み この違いがPartial Prefetchingの適用範囲と関係するのかを確認するため、追加計測しました。 補足:適用範囲によって先読みの形が異なった 条件Cでは、レシピ詳細ページだけに prefetch = 'partial' を設定していました。 prefetch = 'partial' は、設定したページより上位のルート階層まで同じ設定にするものではありません。 Next.js 16.3.1の実装 では、それぞれのルート階層が、その階層で指定された設定かアプリ全体の既定値を参照します。 この挙動を調べる中で、 段階導入時の先読みを扱うNext.js 16.3.1の公式テスト を見つけました。このテストにも、動的なページだけをPartialにし、未設定の上位階層を従来の方法で扱う構成で、リンク先固有のデータまで先読みする例があります。 そこで、条件Cの loading.tsx とページ側の設定を残したまま、 アプリ全体の既定値をPartialにする partialPrefetching: true だけを追加しました。 // next.config.ts const nextConfig = { cacheComponents : true , partialPrefetching : true , } ; 同じ導線を10回計測した結果は次のとおりです。 Partial Prefetchingの適用範囲 URL固有データの先読み 共有部分の先読み レシピ詳細ページのみ 10回中4回で観測 あり アプリ全体 10回中0回 あり 同じ loading.tsx を残したまま適用範囲を変えると、今回の導線ではURL固有データの先読みが10回中4回から0回になりました。一方、App Shellを構成する共有部分の先読みは続いていました。Next.js 16.3.1の実装と公式テストを合わせると、今回観測した通信にはPartial Prefetchingの適用範囲が関係していたと考えられます。 まとめ Partial PrefetchingをOISHYのレシピ一覧で試したところ、16.3.1への更新と機能導入後、クリック前のRSC転送量が約94%減り、クリック後を含む合計でも約88%減りました。 一方、変更前からレシピタイトルまでの表示は約44msと十分に速く、回線速度を制限しない今回の環境では、通信量ほど大きな見た目の差はありませんでした。スケルトンを含むApp Shellは、URL固有のデータがクリックまでに揃わなかった場合だけ、完成したページより先に表示されました。 また、レシピ詳細ページだけに適用した場合と、アプリ全体に適用した場合では、クリック前の先読みも異なりました。ページ単位で試せる機能ではありますが、今回の検証では適用範囲も実際の通信に関係していました。 Partial Prefetchingは、商品・記事・レシピの一覧のように、同じ種類の詳細ページへのリンクが多く、その一部だけがクリックされる画面を想定しています。クリックされないURL固有データの先読みを抑えながら、データが間に合わない場合にはApp Shellを先に表示する仕組みです。今回のOISHYでは、先読み通信量には大きな差が出た一方、見た目の差は小さいという結果でした。 参考文献 Next.js 16.3 Next.js 16.3: Instant Navigations Instant Navigationガイド Adopting Partial Prefetching <Link> のprefetch(先読み) Cache Components Server and Client Components output: 'standalone' prefetch のルート設定(Next.js 16.3.1) 同じルートでApp Shellを再利用する説明(Next.js 16.3.1) partialPrefetching の全体設定(Next.js 16.3.1) loading.tsx とSuspense境界(Next.js 16.3.1) loading.tsx の代替表示を先読みする説明(Next.js 16.3.1) ルート階層ごとの先読み設定を扱う実装(Next.js 16.3.1) 段階導入時の先読みを確認する公式テスト(Next.js 16.3.1) Chrome DevTools Protocol: Network.loadingFinished
title はじめに こんにちは、株式会社エブリーでデリッシュキッチンのiOSアプリの開発をしている成田です。 現在は、プレミアムユーザーの登録数の向上やプレミアムユーザーの体験をより良くすることを目的としたチームで開発をしています。 サブスクリプションの解約は、これまで開発者にとってブラックボックスでした。ユーザーが App Store の管理画面で「サブスクリプションをキャンセルする」を押すとき、アプリ側にできることは何もありません。引き止めのメッセージも、オファーの提示も、そもそも解約されようとしていることを知ることさえ、その瞬間にはできませんでした。 WWDC26 で発表された Retention Messaging は、ここに初めて介入手段を与える機能です( セッション309 )。解約確認画面に、アプリからのメッセージやオファーを差し込めるようになります。 Appleによれば、この機能を導入したサブスクリプションでは、解約を取りやめて利用を継続するユーザーの割合が改善されているとのことです。解約抑止にも取り組む立場としては、無視できない機能です。 まだ一般提供はされていませんが、具体的に何ができるのか、どう始めればよいのか、現時点で分かっていることを整理します。 何ができるのか ユーザーが App Store のサブスクリプション管理から解約しようとすると、確認画面が出ます。Retention Messaging を設定しておくと、この画面にアプリからのコンテンツが表示されます。 表示できる形式は3つです。 形式 内容 メッセージのみ ローカライズ済みの引き止め文言 メッセージ + 画像 テキストメッセージに Asset Library 等から設定した画像を添えて訴求 メッセージ + オファー 割引や無料期間付きなどのオファーを提示する ユーザーがオファーの対象である場合、オファーの表示が画像を置き換えます。「解約する前に、3ヶ月無料で続けられるオファーがあります」のような画面を、Apple の解約フローの中に出せるわけです。この画面は App Store 側が描画するもので、公式ドキュメントによれば iOS 15.1 以上で利用できます。アプリの最低対応バージョンと関係なく届くのは、地味に嬉しいところです。 オファーが引き換えられたかどうかはサーバー側で確認できます。署名付きトランザクションに新しいオファー種別が入ります。 { " offerType ": 5 , " offerIdentifier ": " Yoga_2026_cancel_free_3m ", " offerDiscountType ": " FREE_TRIAL ", " offerPeriod ": " P3M " } offerType はトランザクションに「どの種類のオファーが絡んだか」を刻むフィールドで、これまで4種類あったものに追加で Retention Offer が加わった形です。 offerType 種類 1 お試し 2 プロモーション 3 オファーコード 4 再獲得 5 Retention Offer メッセージを用意する方法は2つある ここまでが主に「解約確認画面に何が出るか」の話です。次は、その表示をアプリ側がどう用意するかです。 方法は2つあって、手軽さが大きく違います。App Store Connect で設定するだけの方法と、自前のサーバーを立てて顧客ごとにリアルタイムで出し分ける方法です。順に見ていきます。 方法1: App Store Connect 側での設定 App Store Connect 上でメッセージ・画像・オファーを設定し、対象のサブスクリプションにマッピングするだけです。自前のサーバー実装は不要で、Apple 側が表示を担います。 流れはこうです。 ローカライズ済みのメッセージ文言を作る 任意で Asset Library の画像、Retention Offer を添える 1つ以上のサブスクリプションにマップする Sandbox 環境でテストして公開 方法2: リアルタイム API 型(ユーザーごとの出し分け) 方法1の弱点は、全員に同じものしか出せないことです。 新しく発表された Retention Messaging API を使うと、「誰に・何を出すか」を自社のデータで決められるようになります。 誤解しやすい点を先に書いておくと、 解約の理由そのものが Apple から届くわけではありません 。リクエストに入っているのは「誰の契約か( originalTransactionId )」までです。ただ、この ID で自社のユーザーデータを引けば、手持ちの情報が使えます。例えば、購読してからどれぐらいか、最後にアプリを開いたのはいつか、月額プランか年額プランか、過去にオファーで引き止めたことがあるかなどがあるでしょう。 理由そのものは分からなくても、こうしたデータから仮説は立てられます。 出し分けのロジックが自前のサーバーにあることで A/B テストでの検証も可能になるはずなので、その仮説を検証することもできそうです。 次に、仕組みを見ていきます。 Retention Messaging API を使うと、解約操作が起きたまさにその瞬間に、App Store から自前のサーバーへ問い合わせが来ます。 // App Store からのリクエスト { " originalTransactionId ": " 123456789 ", " appAppleId ": 6745974591 , " productId ": " Yoga_summer_2026 ", " userLocale ": " en-US ", " requestIdentifier ": " c03248af-dd76-4e9b-9c1e-4489cd19a768 ", " environment ": " Production ", " signedDate ": 1780920000000 } これに対して、 このユーザーに何を出すか を返します。返せる応答は3種類です。 ① メッセージ { " message ": { " messageIdentifier ": " 551ee7c0-... " } } ② プラン切替の提案(alternateProduct) { " alternateProduct ": { " messageIdentifier ": " ed7f25fc-... ", " productId ": " Yoga_summer_2026_annual " } } 同じサブスクリプショングループ内の別プランへの乗り換えを提案できます。「月額×12ヶ月コミット」の新プランタイプとも連動していて、たとえば年額プランを解約しかけた人に「月額の12ヶ月コミットなら続けやすいですよ」という導線が作れたりしそうです。 ③ プロモーショナルオファー { " promotionalOffer ": { " messageIdentifier ": " 80135e2b-... ", " promotionalOfferSignatureV2 ": " eyJhbGciOiJFUzI… " } } プロモーショナルオファーは、開発者が特定のユーザーだけに提供できる限定オファーです。 対象ユーザー以外には利用されないように、開発者のサーバーが秘密鍵を使って「このユーザーに、このオファーを適用してよい」という署名を発行します。アプリはこの署名を使って、オファーが正しく発行されたものかを確認します。 promotionalOfferSignatureV2 は、このデジタルな許可証を標準的な形式である JWS(JSON Web Signature) で表現する新しい仕様です。 ところで、ここまでの応答例が messageIdentifier という ID しか返していないことに気づいたでしょうか。メッセージの文言や画像の実体は、あらかじめ Apple に登録しておく設計になっています。解約フローの真っ最中に文言ごと送るのではなく、実体は事前登録しておいて、その場では「どれを出すか」を ID で選ぶだけです。 この事前登録を担うのが、管理用のエンドポイント群です。メッセージや画像の登録のほか、リアルタイム問い合わせの受け口 URL の設定、性能テストの実行もここで行います。 POST /messages // メッセージ登録 GET /messages // 登録済み一覧 DELETE /messages/{messageId} // 削除 POST /images // 画像登録 GET /images DELETE /images/{imageId} POST /defaultMessages // デフォルトメッセージ設定 GET /defaultMessages/{productId}/{locale} DELETE /defaultMessages/{productId}/{locale} POST /realtimeUrl // 受け口URLの設定 GET /realtimeUrl DELETE /realtimeUrl POST /performanceTests // 性能テスト GET /performanceTests/{testId} フォールバックは段階的 リアルタイム応答が使えない・不正な場合は App Store Connect で設定されたものに、それも無ければ API で設定したデフォルトメッセージにフォールバックされます。 また、Sandbox には自社サーバーの応答性能を測るためのテスト用エンドポイントが用意されています。解約フローの中で同期的に呼ばれる API なので、応答が遅ければ体験を壊します。本番前にここで確認しておく、という建て付けだと理解しています。 まとめ Retention Messaging は、解約確認画面という最後の接点に初めて介入できる機能 用意する方法は2つ。サーバー不要の App Store Connect 設定型と、ユーザーごとに出し分けるリアルタイム API。フォールバックも整理されている 返せるのはメッセージ、プラン切替提案、プロモオファーの3種 メッセージや画像の実体は事前登録しておき、リアルタイム応答では ID で選ぶだけ。Sandbox には応答性能のテスト用エンドポイントも用意されている 解約はこれまで、起きてから初めて知るものでしたが、今回からは解約を思いとどまってもらうための施策を、解約のタイミングに合わせて出せるようになります。サブスクリプションを運営しているチームは、サービス提供が始まる前に、どんなメッセージを出すか、どんなオファーを用意するかを検討しておくとよさそうです。
Cloudflare Walletsが使う決済プロトコル x402 を理解する 目次 はじめに x402が対象とする課題 プロトコルフロー ② 402 Payment Required と PaymentRequirements scheme が取る値 — exact と upto ③ authorization への署名 ④ PaymentPayload の送信 ⑤ verify / settle と facilitator 決済の確定と不可逆性 HTTPを利用する構成のメリット 支払ってよいかの判断は仕様の範囲外 まとめ 参考 はじめに こんにちは、開発本部開発1部の 赤川 です。食事管理アプリ ヘルシカ の開発をしています。 ダイエット・食事管理・体重管理・カロリー計算 - ヘルシカ every, Inc. ヘルスケア/フィットネス 無料 2026年8月4日、Cloudflareが Cloudflare Wallets を発表しました。これは、Web上でサービスの購入や入金を行うためのウォレットで、Cloudflareのアカウントに紐づきます。現時点ではウォレットの識別子の予約のみが提供されており、僕もとりあえず予約してみました。 Cloudflare Wallet Tagを予約した Cloudflare Walletsでは、アカウントが持つWalletから、エージェントが使うVirtual Walletに支出権限を委任できます。エージェントはVirtual Walletを使って、API、MCPツール、コンテンツなどを購入できます。 この購入のやり取りには、 x402 という決済プロトコルが使われています。x402は、HTTPのリクエストとレスポンスの中だけで完結し、支払いが必要であることを示すのに、HTTPステータスコードの 402 Payment Required 1 を使っています。 本記事ではこの x402 について、ドキュメントをあたりながらまとめてみました。 x402が対象とする課題 例えば有料APIを利用しようと思ったら、我々は一般に次の手順を踏みます。 サービスにサインアップする クレジットカードなどの決済手段を登録する APIキーを発行する そのキーをリクエストに付けて呼ぶ 月末にまとめて請求される 認証と課金がフローとして完全に分離しており、いずれも事前のサインアップを前提としています。 人間が利用する分には何の問題もないですが、クライアントがAIエージェントである場合、この前提が制約になります。手順1〜3のうち、サインアップページは人間向けのUIとして作られており、決済手段の登録も人間の承認が必要です。エージェントは事前登録された識別子も支払い手段も持たないため、この3手順の実行には人間の介在が必要になります。 x402は、事前の登録手続きなしに支払いを成立させる方式を定義しています。 プロトコルフロー プロトコルのフローは次のとおりです。この章の図や記述は、 x402 Specification v2 と Cloudflare の x402 ドキュメント に基づいており、執筆時点で最新のv2について書いています。 x402のプロトコルフロー このフローには、アカウントやセッション、事前に共有したAPIキーなどは含まれません。ClientとServerはこのリクエストで初めて通信し、支払いが成立します。 ※ 実際の支払いは、ブロックチェーン上でトークンを送ることで成立します。USDCなどのステーブルコイン(米ドルなどの法定通貨に価値を連動させたトークン)が使われます。 ② 402 Payment Required と PaymentRequirements ①のリクエストに対して、Serverは②で 402 Payment Required を返します。支払いの条件は PAYMENT-REQUIRED ヘッダに、Base64エンコードされたJSONとして載ります。 このJSONの accepts フィールドに、支払いの条件が配列で入ります。要素1つが「この条件で払ってくれれば、このリソースを渡すよ」という1件分の提示にあたり、これを PaymentRequirements と呼びます。配列なのでServerは条件の異なる複数の選択肢を並べられ、Clientはその中から1つを選びます。 PaymentRequirements は次のフィールドから構成されます。 フィールド 内容 scheme 支払いスキーム( exact / upto ) network 対象ブロックチェーン(Base、Ethereum、Solana など) amount 金額 asset トークン種別(USDC など) payTo 支払いの宛先アドレス maxTimeoutSeconds タイムアウト scheme が取る値 — exact と upto scheme フィールドは支払い方式を指定します。 Cloudflare のドキュメント に記載されているのは次の2つです。 exact : 固定額の送金です。EVM(Ethereum Virtual Machine) 2 上では USDC を payTo のアドレスに送金します。②の時点で金額が確定しているケースに対応します。 upto : 上限額を先に承認し、実際の課金額を決済時に確定します。LLMの推論APIのように、実行するまでトークン数が確定せず、金額が事後に決まるケースに対応します。 ③ authorization への署名 Clientは、 accepts の中から採用する PaymentRequirements を1つ選び、その内容を authorization オブジェクトに反映して署名します。authorization の形は、 scheme とチェーンの種類の組み合わせで決まり、EVM上で exact を使う場合は次のフィールドを持ちます。 フィールド 内容 from 送金元アドレス to 宛先アドレス value 金額 validAfter / validBefore 有効期間 nonce 一度きりの値 署名は自身の秘密鍵で行います。署名が保証するのは、その鍵の保有者にしか生成できないこと、署名対象が1バイトでも変われば検証に失敗すること、の2点です。 nonce は一度きりの値であり、 validBefore で有効期間が区切られるため、同じ署名を他の支払いに再利用することはできません。 ④ PaymentPayload の送信 署名と authorization は PaymentPayload にまとめられ、 PAYMENT-SIGNATURE ヘッダに載って、同じURLに再送されます。 PaymentPayload は次の構造です。 { " x402Version ": 2 , " resource ": { ... } , " accepted ": { /* ②の accepts から選んだ PaymentRequirements */ } , " payload ": { " signature ": " ... ", " authorization ": { " from ": " ... ", " to ": " ... ", " value ": " ... ", " nonce ": " ... " } } } ⑤ verify / settle と facilitator ⑤でServerが行う検証と決済は、facilitator に委譲できます。facilitator は、支払いの検証とブロックチェーンへの送信を担うサービスで、次の2つのエンドポイントを提供します。 POST /verify : 支払いペイロードが有効かを、ブロックチェーン上で送金を実行せずに検証する POST /settle : 検証済みの支払いをブロックチェーンに送信し、送金を確定させる facilitator の利用は必須ではありませんが、ブロックチェーンとのやり取りを抽象化できるため、Cloudflareのドキュメントでは推奨されています。 Clientは facilitator と直接通信せず、ServerとHTTPで通信します。⑤の内側を展開すると、次のようになります。 facilitator を含む⑤の内側 決済が確定すると、Serverは⑥でリソースを返します。決済の確認は PAYMENT-RESPONSE ヘッダに載ります。 決済の確定と不可逆性 x402の決済は、1回の送金で確定します。カード決済のように、支払いを承認する段階と実際に資金が動く段階が分かれることはありません。これにより、リソース1件ごとのような少額の支払いでも短時間で決済できますが、同時に次の制約が生じます。 決済を取り消せない プロトコルとして返金手段を定義していない 誤送金や詐取による送金があった場合、プロトコルの範囲では資金は戻りません。返金や救済を実装する場合は、アプリケーション層で別途定義することになります。 HTTPを利用する構成のメリット x402は決済専用のプロトコルを新設せず、支払いのやり取りをHTTPのリクエスト/レスポンスサイクルの中で表現します。そのためクライアントを選びません。エージェント、curl、サーバ間通信のいずれも対象になり、SDKも必須ではありません。 402応答は特定のURLに対する支払い要求なので、値付けの単位もURLになります。エンドポイントごと、MCPツールごとに価格を返せます。 支払ってよいかの判断は仕様の範囲外 x402の仕様が定義しているのは、3つのHTTPヘッダ、 PaymentRequirements と PaymentPayload の構造、facilitator の verify / settle の手順、および scheme です。「どのような条件で支払いを承認するか」は定義されていません。仕様上、正しく署名されたペイロードは正当な支払いとして処理されます。 Cloudflare Walletsは、この判断をウォレット側で縛る仕組みを持っています。エージェントに渡すVirtual Walletには、使ってよい金額の枠(allowance)、支払い先の許可リスト(allow list)、1回あたりの上限額(maximum transaction size)を設定できます。 これらはウォレット側の設定なので、エージェントが何をしようとしても、枠を超える送金や、許可リストにない相手への送金は成立しません。x402が定義していない「支払ってよいか」の判断を、エージェント任せにせず、ウォレットの設定として持たせている構成です。 まとめ x402の仕様を整理すると、次のようになります。 決済専用のプロトコルを新設せず、HTTPのリクエスト/レスポンスサイクルで支払いを表現する 事前のアカウントもAPIキーも使わず、402応答とその再送だけで支払いが成立する scheme として exact (固定額)と upto (上限額の事前承認)を定義する 検証と決済は facilitator に委譲できる。利用は必須ではない 決済はブロックチェーン上で確定し、プロトコルとして取り消し手段を持たない 支払ってよいかの判断は仕様の範囲外で、クライアント側に委ねられる 最後までお読みいただきありがとうございました。 参考 Announcing Cloudflare Wallets: The programmable wallet for the agentic Internet - The Cloudflare Blog (2026年8月4日) x402 - Cloudflare Agents docs x402 Specification v2 - coinbase/x402 RFC 9110: HTTP Semantics - 15.5.3. 402 Payment Required 現行のHTTP仕様である RFC 9110 では "The 402 (Payment Required) status code is reserved for future use." と記述されています。402が標準として用途を定義されてこなかったことを、僕は今回の記事を書くまで知りませんでした。 ↩ Ethereum が採用しているブロックチェーンの実行環境です。これを採用するチェーンは多く、Cloudflareのドキュメントも EVM に対応するチェーンとして Base、Ethereum、Polygon などを挙げています。 ↩
はじめに こんにちは、株式会社エブリーのデリッシュキッチンにて7月から約1か月間エンジニアとしてインターンシップに参加していました、亀井と申します。 この記事では、インターン中に取り組んだことの中心である「Databricks LakebaseへのOAuth M2M認証の導入」と、その先でデータを読むための「GoのPostgreSQL向けライブラリ選定」の2つについて、どう実装・検証・調査したのかを書きたいと思います。 インターンで取り組んだこと インターンでは、Go言語で書かれたデリッシュキッチンのAPIサーバーを主な対象として、次の4つに取り組みました。 デリッシュAIの表示順ソートのロジックの実装 Databricks LakebaseへのOAuth M2M認証の実装 GoのPostgreSQL向けデータアクセスライブラリ(ORM)の比較調査 M2M認証を動かすための環境変数・ECSタスク定義の追加 この記事では主に2と3について書きます。 開発の背景 デリッシュキッチンのサーバーから、Databricks上の新しいリソースに接続したいという需要が生まれていました。接続先はLakebase Autoscaling PostgresというDatabricksが提供するフルマネージドなPostgreSQLで、projects → branches → endpointsの3階層でリソースを管理する新世代のサービスです。 Databricks本体は分析寄りで、アプリが求める個別レコードを低レイテンシで引く用途には向きません。そこで、Databricksでテーブルを一元管理するカタログ機能であるUnity Catalog側のテーブルをsourceとしてLakebaseのPostgresに自動同期し(synced table)、アプリからは読み取り専用のPostgresテーブルとして高速に読む、という構成を取ります。 問題は認証です。既存のDatabricks接続はPAT(Personal Access Token)という長命トークンで認証していました。しかしPATは失効管理が手動で、そもそもLakebaseのPostgres認証(OAuth role)は「発行から60分で失効するトークン」を前提としており、PATでは接続できません。静的なパスワードで認証するroleも作れますが、DatabricksのID管理に紐づかない長命の静的クレデンシャルになるため、漏洩時のリスクを考えると避けたいところです。 Databricksはサービスプリンシパルの認可にはOAuth 2.0を推奨しており、ここではOAuth M2M認証、すなわちサービスプリンシパルとclient credentialsフローの組み合わせを実装しました。用語を整理すると: サービスプリンシパル(SP): 人間ではなくアプリ自身に与えるIDアカウント。人に紐づけると退職や異動等で処理が止まり、権限も広くなりがちなので、機械用のアカウントを別に立てます client credentialsフロー: ユーザーの同意画面を介さず、アプリがClient IDとClient Secretを認可サーバーに提示してアクセストークンを得るOAuth 2.0のフロー つまり、サーバーが自分自身のIDとシークレットでトークンをもらい、そのトークンでAPIを呼ぶ仕組みです。 M2M認証の実装と検証 設計方針 設計方針の要点は次の3つです。 環境分離はbranchで行う:Lakebaseのbranchはコピーオンライト(CoW)でデータを分岐でき、 production (親)と development (子)で本番と開発を分離します。SPは環境別に2本立て、dev用SPのOAuth roleを production branchに作らないことが、dev環境から本番データへの到達を防ぐ唯一の境界になります。roleの状態はbranch間で独立している、というのが公式の仕様です。 認証専用のパッケージは作らない:トークンの発行・キャッシュ・更新はすべてSDK内部の責務で、自前コードに共通化すべきロジックが発生しないためです。 環境変数はSDKの標準名( DATABRICKS_HOST / DATABRICKS_CLIENT_ID / DATABRICKS_CLIENT_SECRET )を使う:databricks-sdk-goの統一認証チェーンは、これらの環境変数があればSPとしてM2M認証し、なければ開発者個人のCLIプロファイルに自動でフォールバックします。本番はSP・ローカルは個人認証という切り替えが分岐コードゼロで手に入り、SPのシークレットを開発者の端末に配らずに済みます。 この設計方針の下で実装を進めてきました。 実装 実装は公式ドキュメントのGoサンプルをほぼそのまま踏襲する形式になりました。核になるのは、GoのPostgreSQL接続ライブラリpgxが提供する接続プールの BeforeConnect フックです。 BeforeConnect は、プールが新しい接続を張る直前に毎回呼ばれる関数で、ここで接続に使う設定を書き換えられます。 w, err := databricks.NewWorkspaceClient(&databricks.Config{}) // 空のConfigでSDKの統一認証チェーンに委ねる: // DATABRICKS_*環境変数(本番ECS)→ CLIプロファイル(ローカル) // Lakebaseは全接続にSSL/TLSを必須とするため、sslmodeはコード側で固定する poolCfg, err := pgxpool.ParseConfig( "sslmode=require" ) // credentialは発行から60分で失効する。BeforeConnectは新規接続にしか // 効かないため、失効前に接続自体を作り直させる(公式サンプル準拠)。 // Jitterで寿命をばらつかせ、一斉失効による再接続の集中を防ぐ poolCfg.MaxConnLifetime = 45 * time.Minute poolCfg.MaxConnLifetimeJitter = 5 * time.Minute poolCfg.BeforeConnect = func (ctx context.Context, connCfg *pgx.ConnConfig) error { cred, err := w.Postgres.GenerateDatabaseCredential(ctx, postgres.GenerateDatabaseCredentialRequest{ Endpoint: endpointName, // projects/{project}/branches/{branch}/endpoints/{endpoint} }) if err != nil { return err } connCfg.Password = cred.Token // 接続確立ごとに新鮮なトークン return nil } ポイントは3つあります。 Database Credentialはキャッシュしない:60分で失効するトークンをキャッシュすると、失効間際のトークンを掴む事故が起きます。毎回発行するとAPIコールが増えそうに見えますが、発行が走るのは接続プールが新規接続を作るときだけなので、実際の頻度は低く抑えられます。 接続寿命をトークンのTTL(有効期間)未満に制限する: BeforeConnect が効くのは新規接続だけで、確立済みの接続にあとから新しいトークンを渡す手段はありません。接続を作りっぱなしにすると、認証に使ったトークンが失効した接続がプールに残り続けます。そこで公式サンプルと同じく MaxConnLifetime = 45 * time.Minute で、失効前に接続自体を作り直させます。さらに、プールの接続はデプロイ直後などにまとまって作られるため、寿命が同じだと作り直しのタイミングも一点に集中します。これをずらすのが、寿命に上乗せするランダムな幅であるジッターです。ジッターを足しても接続寿命は最長50分で、TTLの60分を確実に下回ります。 接続先のdatabaseはコードで切り替えられるようにする:これはレビュー指摘で直した点です。当初は接続先のdatabase名を環境変数 PGDATABASE 任せにしており、接続先が1つに固定されていました。しかし今後は複数のdatabaseを読む可能性があります。そこでdatabase名を型として定義し、database単位に接続プールを分けて、接続文字列の dbname で明示指定する形に改めました。pgxでは接続文字列の設定が環境変数より優先されるためです。endpointと認証credentialはdatabaseを問わず共通なので、 BeforeConnect の仕組みは全プールでそのまま共有できます。 環境変数とタスク定義 このコードを本番で動かすには、AWSのコンテナ実行サービスであるECSのタスク定義への環境変数の追加が必要です。 DATABRICKS_* の3変数に加えてPostgres接続用の PG* 変数を、dev / prdそれぞれのタスク定義に追加しました。ひとつ注意が要るのは PGUSER で、本番ではSPのclient ID、ローカルでは開発者個人のIDと、環境で値の種類そのものが違うため、ハードコードせず環境ごとに注入します。 検証 作った接続コードが「本当に意図通り動くのか」を示すために、疎通確認用のCLIをリポジトリ内に用意しました。確認したいことが3層に分かれているので、CLIも段階を選べるようにしてあります。 --auth-only : Postgresには触らず、ワークスペースAPIへの認証だけを確認します フラグなし: credentialを発行してPostgresにログインし、 SELECT 1 を実行します --count 2 --interval 65m : 接続寿命を跨いで再接続できるかを確認します なぜ分けるかというと、1と2は通信経路も認可の仕組みも別物だからです。段階1はワークスペースのAPIに届くかの確認で、認可は、ワークスペースの機能を使う権利であるエンタイトルメントが担います。段階2は発行されたcredentialでPostgresにログインする確認で、認可はbranch単位のOAuth roleが担います。一気に確認すると、失敗したときにどの層が原因か切り分けられません。 データを読むライブラリをどう選ぶか 認証が通ったら、次はその接続でデータを読む実装です。ここで「GoからPostgreSQLを扱うのに何を使うか」というライブラリの比較を行いました。 結論から書くと、第一候補はBob、第二候補はsqlcです。理由は、クエリの書きやすさ、型の安全性、そして上で作った既存の *pgxpool.Pool をそのまま使えることです。 選定の前提は次の3つで、それぞれが結論の理由に対応しています。 対象はsynced tableです。スキーマはUnity Catalog側が所有し、アプリからは ALTER を発行しません:主キーのないテーブルを扱えること、スキーマ変更に気付けることが効いてきます 接続は、 BeforeConnect による認証をバイパスしないよう既存の *pgxpool.Pool を使います:プールを直接扱えるライブラリが有利です 読み取るテーブルは今後増えていきます:1テーブルなら手書きでも書けますが、増えるほど書きやすさと型安全性が効いてきます 選定の理由 選定の過程では生成AIを用いてORMを列挙させ、上記の観点から7つのライブラリを選出しました。利点と欠点で比較をし、参考程度にDocker上のPostgreSQLで実測を行いました。その後議論を行い、以下のORMを選定しました。 Bob: 既存の *pgxpool.Pool を公式に直接扱えます。ビルダでクエリを書きやすく、コード生成で型安全性を足せます。主キーのないテーブルでも生成が通り、読み取り専用のモデルになるためsynced tableの性質と噛み合います。 sqlc: SQLを書いてコードを生成する型で、列名や型の誤りを生成時に検出できます。スキーマをUnity Catalog側が所有する今回の状況では、上流のスキーマ変更を再生成時のコンパイルエラーとして捕まえられる固有の強みがあります。 他の候補を見送った理由も簡単に説明します。GORMはフルORMの利点が今回の要件では効きません。entはジェネレータが主キー id を必須とするため、主キーのないsynced tableへの全件取得が失敗します。scanyは短く書けますが開発が止まっています。手書きのpgxは型が go build 時点で固定される書き方ですが、テーブルが増えるほど手書きの Scan が積み上がります。 まとめ インターンを通して、実際にユーザーに使われているデリッシュキッチンのサーバーに触れられたのは、とても貴重な経験でした。チームの設計方針や、既存のコードを読み解きながら実装を行う経験は開発現場だからこそ得られるものだと思います。インターンシップで学んだことも活かしつつ、今後もさまざまな技術に触れながら、エンジニアとして成長していきます。 最後に、1か月間サポートしてくださったデリッシュキッチンの皆様、本当にありがとうございました。 参考 Connect external app to Lakebase using SDK OAuth machine-to-machine (M2M) authentication Branching Manage Postgres roles Connection security databricks-sdk-go Bob: pgx driver — NewPool ent: Fields — ID
はじめに こんにちは。リテールハブ小売アプリ開発チームの池です。 小売アプリチームでは、昨年から CodeRabbit を利用して PR レビューを行っています。日々活用してはいるものの、アップデートの内容を追いきれていませんでした。そこで本記事では、2026 年にアップデートされた内容を整理し、気になった機能をピックアップして紹介します。 なお、本記事の内容は 2026 年 8 月 12 日時点の情報をもとにしています。CodeRabbit はアップデートの頻度が高いため、機能の挙動やプラン要件は変わっている可能性があります。最新の情報は公式ドキュメントをご確認ください。 また、私たちのチームでは Pro プランを利用しているため、Pro プランで利用できる範囲を中心に、Pro+ プラン限定の機能はその旨を明記しながら紹介します。 2026 年アップデートの全体像 CodeRabbit の Changelog および 公式ドキュメント をもとにアップデートの全体像を整理します。2026 年 1〜8 月の changelog は約 100 件あり、主なアップデート内容を独自に抜粋して整理すると次のようになります。 カテゴライズ 主なアップデート(月) 概要 レビューUX ・Multi-Repo Analysis(2 月、6 月拡充) ・Review auto-pause(2 月) ・Slop PR 検出(3 月) ・Quiet プロファイル(7 月) マルチリポ分析の登場とレビューノイズの削減 Finishing Touches ・Autofix(2 月) ・Simplify(3 月) ・Resolve Merge Conflicts(3 月) ・Custom Recipes(3 月) ・Fix CI(7 月) レビュー後の修正作業をエージェントに委譲 CLI・コーディングエージェント連携 ・Claude Code Plugin(2 月) ・CodeRabbit Skills(2 月) ・CLI --agent モード(3 月) ・Codex plugin(4 月) Claude Code などのコーディングエージェントにレビューを統合 静的解析ツールの追加 ・Trivy / TFLint(2 月) ・zizmor(5 月) ・oasdiff(6 月) ・ast-grep の Dart 対応(6 月) ・e18e(7 月) 対応言語・領域の拡大(今年だけで 10 種超) Analytics・ダッシュボード ・Learnings ダッシュボード(2 月) ・ダッシュボード再編(3 月) ・利用メトリクス(6 月) ・レートリミット可視化(7 月) 運用状況の可視化が大幅に強化 外部ツール連携・CodeRabbit Agent ・Slack 向け Agent(4 月) ・メッセージトリガー自動化(4 月) ・Post-Merge Actions(7 月) ・Agent Skills(7 月) Slack を入口にした汎用エージェントと SaaS 接続の拡大 Plan ・Issue Planner(2 月) ・VS Code での Plan(6 月) Issue からの実装計画生成 セキュリティ ・Betterleaks(3 月) ・Security Agent(7 月) ・Secrets 検証ステータス(7 月) ・Git 履歴スキャン(7 月) PR レビューからコードベース全体のスキャンへ ナレッジ・Learnings ・承認フロー(6 月) ・Learnings API(6 月) ・Code Guidelines 管理 UI(6 月) 学習内容の可視化と統制 組織管理・ガバナンス ・Custom Roles(2 月) ・Audit Logs(3 月) ・Pro+ プラン導入(4 月) ・Global Overrides(4 月) エンタープライズ向け統制と料金体系の再編 Change Stack ・semantic diff / Code Peek(5 月) ・Change Stack 各プラットフォーム展開(5〜7 月) ・アプリ内レビュー会話(7 月) 意味的に構造化された PR レビュー専用UI と各プラットフォーム展開 ここからは、この中から気になった 5 つのテーマをピックアップして紹介します。 ① レビューUX 2 月: Multi-Repo Analysis が登場 3 月: Pro プランでリンク可能リポジトリ数が 1→2 に増加 6 月: レビュー対象 ref の固定(Multi-Repo Ref Selection)、自動リポジトリリンクとその管理 UI(Pro+ プラン) Multi-Repo Analysis は、PR のレビュー時に関連リポジトリのコードも合わせて参照して分析する機能です。単一リポジトリの diff だけでは見つけられない、リポジトリをまたぐ問題(API の破壊的変更、型の不一致、依存のドリフトなど)を検出できます。たとえばモバイルアプリと API サーバーが別リポジトリに分かれている場合、サーバー側の API 変更に対して「アプリ側の呼び出しが壊れないか」という観点をレビューに加えられます。 Pro プランでは自動リンク機能が使えないので、管理画面から手動で関連するリポジトリを設定しないと本機能は適用されないようです。設定方法を見ていきます。 設定方法 リンク設定は、管理画面の Review > Repositories > Settings > Knowledge base にあります。手動でのリンクと自動リンクの 2 通りがあります。なお、リンクできるリポジトリ数について、changelog には 3 月に Pro プランで 1→2 に増加したと記載がありますが、執筆時点の管理画面では 1 リポジトリまででした。 手動でリンクする リポジトリ設定はデフォルトで Organization 設定を継承しており、この状態ではリポジトリ単位のカスタマイズができません。Review > Repositories > Settings > General にある「Use Organization Settings」のトグルを一度クリックすると、設定の継承は on のまま、リポジトリ単位で編集できるようになります。 Linked repositories でリンクするリポジトリを選択し、Instruction にリポジトリ間の関係を記述できます。 保存すると Linked repositories の一覧に表示され、リンク設定は完了です。 自動リンク(Automatic repository linking) Automatic repository linking を有効にすると、Organization 内の関連するリポジトリが自動的に検出されリンクされます。なお、自動リンクは Pro+ プラン以上の機能です。 Multi-Repo Analysis のレビューでの見え方 Multi-Repo Analysis の結果は、PR Walkthrough の Review details > Additional context used に、リンクされたリポジトリ名ごとにグループ化されて表示されます。自動リンクされたリポジトリが含まれる場合は、Review info セクションに CodeRabbit が参照したリポジトリの一覧が表示され、それぞれに手動リンクか自動検出かのラベルが付きます。また、関連がある場合はインラインのレビューコメントやコメント返信にも指摘として現れます。 なお、Review details セクションを表示するには、 .coderabbit.yaml で review_details を有効にしておく必要があります。 # .coderabbit.yaml reviews : review_details : true ② Finishing Touches Finishing Touches は、レビュー後の仕上げ作業(指摘の修正、docstring や単体テストの作成など)を、PR コメントや PR Walkthrough のチェックボックスから CodeRabbit のエージェントに任せられる機能群です。 2 月: Autofix(未解決の指摘への修正を自動適用)、Chat code editing(Early Access) 3 月: Simplify、Resolve Merge Conflicts、Custom Recipes 7 月: Fix CI(CI 失敗の調査から修正・PR 作成までを行う) Finishing Touches の一覧 執筆時点で利用できる Finishing Touches は以下の 7 種類です。一部は Pro+ プラン限定となっています。 Autofix(指摘の自動修正) Docstrings(docstring の生成) Fix CI(CI 失敗の修正、Pro+ プラン) Resolve Merge Conflicts(コンフリクトの解決、Pro+ プラン) Unit Tests(単体テストの生成、Pro+ プラン) Simplify(コードの簡素化、Pro+ プラン) Custom Recipes(カスタム定義による修正、Pro+ プラン) トリガー方法は 2 種類あります。 PR コメント: @coderabbitai generate docstrings のようなコメントを投稿する チェックボックス: PR Walkthrough のコメント上のチェックボックスにチェックを入れる Autofix Autofix は、PR に残っている未解決のレビュー指摘を対象に、サンドボックス内で修正を作成する機能です。修正の反映先は、現在のブランチへの直接コミットか、stacked PR かを選べます。 以下のようにコメントすることで利用できます。 @coderabbitai autofix # 修正を現在のブランチにコミット @coderabbitai autofix stacked pr # 修正を stacked PR として作成 Autofix 機能はデフォルトで有効になっています。リポジトリ単位で無効にしたい場合は、 .coderabbit.yaml で設定します。 # .coderabbit.yaml reviews : finishing_touches : autofix : enabled : false # Autofix を無効化 実際に試したところ、人間のレビュアーのコメントに対して @coderabbitai autofix stacked pr を実行しても、以下のようにスキップされました。 Autofix の対象は、CodeRabbit 自身が投稿した修正手順つきの未解決レビューコメントのみで、人によるレビューコメントの修正は任せられないようです。 次に、CodeRabbit の修正手順つき未解決コメントが残っている PR で実行したところ、今回は受け付けられました。特定の 1 件の指摘スレッドへの返信として実行しましたが、PR 上の未解決指摘 17 件すべてが修正対象になりました。コメントを投稿した場所に関係なく、PR 単位で一括適用される挙動のようです。 実行から約 6 分半で、12 ファイルの修正を含む stacked PR が作成されました。 ③ CLI・コーディングエージェント連携 CodeRabbit CLI は、ターミナルから手元のコード変更に対して CodeRabbit のレビューを実行できるツールです。PR を作成する前に、ローカルで指摘の検出と修正を済ませられます。2026 年は、この CLI を土台にした Claude Code などのコーディングエージェントとの統合が進みました。 2 月: Claude Code Plugin 対応、CodeRabbit Skills(open agent skills 標準) 3 月: CLI --agent モード(構造化 JSON 出力)、CLI 用 Usage-based アドオン(従量課金オプション) 4 月: CLI ブラウザ完結のサインイン、Codex plugin 対応 5〜8 月: coderabbit doctor 、 --light モード、レビュー信頼性の改善 CLI は無料プランでも利用できます(基本的な静的解析、1 時間あたり 3 回まで)。Pro プランにすることで、組織の Learnings を活用した強化レビューになり、レートリミットは 1 時間あたり 5 回に引き上げられます。 コーディングエージェントに CLI を統合するメリット CodeRabbit は、Claude Code などのコーディングエージェントと CLI を組み合わせる意義を、次のような役割分担として説明しています。 専門家による問題検出 : 一般的なリンターでは見逃しやすい競合状態・メモリリーク・論理エラーを CodeRabbit が検出する AI を活用した修正 : Claude Code が CodeRabbit の分析結果に基づいて修正を実装する コンテキストの保持 : 問題の発生場所・深刻度・推奨される対処法が簡潔に Claude Code へ渡される 継続的なワークフロー : ツールを切り替えることなく、レビュー → 修正 → 反復のループを開発の流れの中で回せる Claude Code への導入方法 導入は「CLI のインストール・認証」と「Claude Code へのプラグイン追加」の 2 段階です。 まず CodeRabbit CLI をインストールします。 curl -fsSL https://cli.coderabbit.ai/install.sh | sh # または brew install coderabbit 次に認証を行います。4 月の CLI v0.4.0 からサインインはブラウザで完結するようになりました。 coderabbit auth login Claude Code 側では、公式プラグインマーケットプレイスに CodeRabbit が用意されているので、選択するだけで使えるようになります。 プラグインの内容 導入すると、Claude Code 内で coderabbit-review コマンドと、code-review・autofix の 2 つのスキルが利用できるようになります。 /coderabbit:coderabbit-review : 手元の変更に対して CodeRabbit のレビューを 1 回実行し、結果を表示するコマンド /coderabbit:code-review : CodeRabbit のレビューをワークフローとして扱うスキル。エージェントがレビューを必要と判断した場面でも自動起動する /coderabbit:autofix : GitHub PR のレビュースレッドにある CodeRabbit の指摘を、変更ごとに承認を挟みながら安全に適用する また、プラグインとは別に、open agent skills 標準に対応した CodeRabbit Skills も提供されています。Claude Code の場合はプラグインの導入でスキルも一緒に入るため追加の作業は不要ですが、Cursor / Codex / Gemini CLI など他のエージェントでも使いたい場合は、以下のコマンドで各エージェントのスキルディレクトリに導入できます。 coderabbit skills code-review と autofix の 2 つのスキルの実体は、ワークフローを記述した Markdown ファイル(SKILL.md)です。それぞれ次の内容がワークフローとして明記されています。 code-review : 「実装 → レビュー → Critical/Warning の修正 → 再レビュー → クリーンになるまで繰り返す」という自律ループ autofix : エージェント自身が指摘の妥当性をローカルコードで検証し、1 件ずつユーザーの承認を取りながら修正を適用する手順 ループが前提として設計されている点、必要な箇所で人の承認を挟んでいる点から、AI を使った開発ワークフローに CodeRabbit を自然に組み込める仕組みだと感じました。 ④ 静的解析ツールの追加 静的解析ツールの追加は活発に行われており、1〜8 月だけで 10 種を超えるツールが追加・更新されています。対応しているツールの一覧は 公式ドキュメントの Tools 一覧 を参照してください。 2 月: Trivy(IaC のセキュリティスキャン)、TFLint(Terraform)、Stylelint(スタイルシート)、TruffleHog(シークレットスキャン)、OpenGrep(Semgrep 互換の静的解析エンジン)など 9 種 3 月: Betterleaks(シークレットスキャナを Gitleaks から Betterleaks へ置き換え。既存の gitleaks 設定キーがそのまま使える) 5 月: zizmor(GitHub Actions ワークフローのセキュリティ解析) 6 月: Infer(C / C++ / Java の null 参照・リソースリーク・並行処理バグ検出)、oasdiff(OpenAPI の破壊的変更検出)、React Doctor(React のセキュリティ・パフォーマンス・アクセシビリティの問題を検出)、ast-grep の対応ファイルタイプ拡大(Dart、TOML、Markdown など) 7 月: e18e ESLint plugin(モダンな代替がある依存や、メンテナンスされていないパッケージを指摘) これらの静的解析ツールは CodeRabbit ではほぼすべてデフォルトで有効になっており、該当するファイルタイプの変更を検出すると自動で実行されます。 ルールの詳細を制御したい場合は、各ツールの設定ファイルを使います。リポジトリに .eslintrc.js や pyproject.toml があれば CodeRabbit はそれを尊重するため、既存の設定をそのまま生かせます。 また、対象領域は、シークレット・IaC・CI 設定といったアプリケーションコードの周辺へと拡大しています。PR レビューの対象が、コードそのものからリポジトリ全体の安全性へ広がっていると感じました。 複数のリポジトリを運用していると、リポジトリごとに静的解析ツールを選定して管理していくのはそれなりのコストになります。ツールの追加・実行・アップデートを CodeRabbit 側が担ってくれることで、この導入・運用コストを下げられるのはメリットの一つだと思いました。 ⑤ Analytics Analytics は、CodeRabbit の管理画面で組織のレビュー活動を可視化するダッシュボード機能です。レビューされた PR の数や指摘への対応状況、レビューにかかった時間、Learnings などナレッジの活用状況といったメトリクスを、リポジトリ・ユーザー・期間で絞り込みながら確認できます。 2 月: Learnings ダッシュボード(KPI カード、利用回数・最終利用日などのメタデータ) 3 月: ダッシュボード再編(Git プラットフォームレビューと IDE/CLI レビューの分離、Knowledge Base / Pre-merge Checks / Reporting などの新ページ) 6 月: Path 指示・Finishing Touches の利用メトリクス 7 月: レートリミット影響の可視化(Usage Rate-Limit Insights)、Explore ページのレコメンデーション 3 月の再編により、Analytics は大きく「PR reviews」と「IDE/CLI reviews」の 2 つに分かれています。それぞれ見ていきます。 PR レビューのメトリクス PR レビュー側は Summary / Quality Metrics / Time Metrics / Knowledge Base / Organization Trends / Pre-merge Checks / Reporting / Data Metrics のページで構成されており、すべては書ききれないほど多くのメトリクスがあります。以下は Summary ページの画面です。 ここでは代表的な項目を挙げます。 レビュー成果 : レビュー済みでマージされた PR 数、投稿コメント数、Acceptance Rate(開発者が指摘に対応した割合)、Reviewer Time Saved(AI 推定のレビュー工数削減時間) 時間系 : レビュー可能になってから「マージ」「最初の人間レビュー」などまでの時間(平均・中央値・P75・P90)と週次トレンド ナレッジ系 : Learnings の作成数・適用率、Path-based Instructions の利用率、MCP サーバー別の PR カバレッジ 運用系 : Pre-merge Checks や Finishing Touches の実行数と結果、レートリミットの影響 これらのメトリクスは、開発プロセスの改善、効果の定量的な説明、CodeRabbit 自体のチューニングなど、幅広く活用できそうです。 IDE/CLI レビューのメトリクス IDE / CLI がチームでどれだけ使われているかを示すメトリクスです。 アクティブユーザー数・レビュー数・レビューコメント数を、IDE 拡張 / CLI の種別ごとに集計 Learnings や Path-based Instructions がローカルレビューに適用された割合 SAST・リンターによるツール検出の内訳(ツール別・重要度別) ユーザー別の明細(拡張の種別、導入日、最終利用日時、レビュー数) 従来見えづらかった PR に到達する前の品質活動を追えるのは、開発フローの改善を測るうえで示唆がありそうです。 おわりに 本記事では、CodeRabbit の 2026 年 1〜8 月のアップデートを整理し、気になった 5 つのテーマをピックアップして紹介しました。 アップデートの内容を追うと、CodeRabbit が PR レビューのツールにとどまらず、開発ライフサイクル全体を支えるエージェントプラットフォームへと広がっていると感じました。 AI によりコードの生成量が増大する中で、いかに効率良く品質を担保するかは、AI 活用における課題の一つだと思います。CodeRabbit を適切に活用することは、この課題を解決する方法の一つになると感じています。 私たちのチームでも、今回整理したアップデート内容を実際の開発フローに組み込みながら、活用を広げていければと思います。 本記事が少しでも参考になれば幸いです。最後まで読んでいただきありがとうございました。
はじめに こんにちは、開発1部でデリッシュキッチンの開発をしている蜜澤です。 現在データ基盤はDatabricksを使用しており、データはUnity Catalog(以下UC)のテーブルです。 UCのテーブルをプロダクトのAPIから配信したいという状況が直近の1年で増えてきました。 例えば、「レコメンド結果をアプリの画面に出したい」「集計したアプリのログデータを分析できる社外向けのダッシュボードツールを作成したい」といった要望があります。 これをアプリ側から読めるようにするには、UCのテーブルのデータをAPIが参照できるDBに複製する必要があります。DatabricksのLakebase(マネージドPostgreSQL)を使えば、これを実現できそうです(Lakebaseは 2026年6月30日に東京リージョンで利用可能になりました )。 ただ、複製の方法はLakebase以外にもあります。本記事では、従来の方法と比較しながらLakebaseで実現するのが良いのかどうかを考えてみます。複製先のDBは、既存のアプリのDB(MySQL互換のRDS)かLakebaseのどちらかになります。 比較する際に考慮したのは以下の4点です。 ダウンタイム(DBのデータが空や一部欠けた状態で読まれる時間)が発生するかどうか アトミック性(一連の更新がすべて反映されるか、まったく反映されないかのどちらかになる) 実装コスト(初期整備や、配信テーブルを増やすたびに必要な実装の量) 金銭的コスト(追加で発生するインフラ費用) 紹介するのは以下の3種類の方法です。 DatabricksからRDSに直接書き込む バックエンドのバッチで取り込む Lakebaseのsynced tableを使用する DatabricksからRDSに直接書き込む 概要 DatabricksからJDBC接続で、アプリのRDSに直接書き込みます(Sparkの df.write.format("jdbc") )。 UC (Delta) --[Spark JDBC writer]--> アプリの RDS --> API アプリ側から見れば、普通のDBのテーブルが1つ増えるだけになります。 メリット 実装コストが小さいです。 バックエンド側の実装はテーブル定義のマイグレーションのみで、Databricks側の実装は書き込み処理を書くだけであり、最小限の実装で済みます。 ただし、これはあくまでアプリケーションコードの話で、DatabricksからRDSにネットワーク的に到達できるようにする設定(VPCピアリングなど)は別途必要です。 デメリット mode("overwrite") で書き込みを行うと、ダウンタイムが発生してしまいます。 mode("overwrite") はテーブルを空にしてから書き直しますが、Sparkはパーティションごとに独立したトランザクションでコミットするため、この一連の処理を1つのトランザクションで囲む方法がありません。結果として、テーブルが空の状態や一部しか入っていない状態が、そのままAPIから読めてしまいます。つまり書き込みが終わるまでの間、データが欠損した状態で配信されるダウンタイムが発生します。 この問題は mode("append") を使えば解決できます。 append は既存行を消さないため、テーブルが空の状態や一部しか入っていない状態が読まれることはありません。 ただし append は追記しかしないため、全件を更新したい場合は使えません。ダウンタイムを発生させずに全件更新したい場合は、本番とは別のテーブルに全件を書き込んでおき、 RENAME TABLE で本番のテーブルと入れ替えることで実現できます。 RENAME TABLE は1つの文に渡した複数テーブルの付け替えをアトミックに実行するため、読み手からは入れ替えの前か後のどちらかの状態しか見えず、空や一部欠けた状態が読まれることはありません。 なお、厳密には入れ替え時にメタデータロックの取得待ちが発生し得ます。長時間のクエリや未コミットのトランザクションが同じテーブルに触れていると、 RENAME TABLE が待たされるだけでなく後続の読み取りクエリもその後ろで待たされるため、入れ替えは長時間のクエリと重ならないタイミングで実行するのが安全です。 この構成では「アプリのDBに対するテーブルの入れ替え(DDL)をDatabricks側から実行する」ことになります。アプリ側がマイグレーションで管理しているスキーマをETLが作り替える形になるため、動きはするものの設計としてはあまり綺麗ではない印象です。 また、外部キー制約がある子テーブルを書き込もうとすると、キーの管理が煩雑になります。参照先の親テーブルがアプリのDBにしか存在しない場合、そのidを確認するためにアプリのDBを見る必要があります。子テーブルのデータを作るには、アプリのDBからidを取得してきて、それと整合するようにDatabricks側で外部キーを振る必要があり、idの管理をDatabricks側で抱え込むことになります。 用途 向いている 検証段階で、まず動くものを最短で作りたい場合 データの全件更新が不要で増分更新のみでよい場合 全件更新時の短時間のダウンタイムを許容できる場合 ダウンタイムを許容できない場合でも、 RENAME TABLE による入れ替えを許容できる場合 向いていない ダウンタイムなしの全件更新が必要で、 RENAME TABLE による入れ替えを許容できない場合 外部キー制約で既存のテーブルと繋がる子テーブルを作成したい場合 バックエンドのバッチで取り込む 概要 DatabricksからUCのテーブルのデータをCSVファイルとしてS3に出力し、それをアプリのバックエンドに実装した取り込みバッチで読み込んでRDSに書き込みます。 Databricks側はS3にファイルを置くところまでを責務とし、そこから先の取り込みはアプリ側が担います。 UC (Delta) --> S3(CSV) --> [アプリ側の取り込みバッチ] --> アプリのRDS --> API メリット 全件更新したい場合でもアトミックな切り替えが可能になります。アプリの通常のコードなので、単一プロセスから単一トランザクションで書けます。実際にはアプリのコードでS3のCSVを読み込んでバルクINSERTを繰り返す形になりますが、構造としては以下の通りです。 BEGIN ; DELETE FROM xxx; INSERT INTO xxx ... ; COMMIT ; DELETE はトランザクショナルなので、確定は COMMIT の1回だけです。読み手は切り替わりの前か後しか見ません。 取り込み時に加工・検証ができます。参照先マスタの実在チェック、正規化、既存データとの整合確認をアプリのドメインロジックで書けます。外部キー制約も張れるので、参照先が消えたときの挙動をDBに任せられます。 デメリット 実装コストが大きくなりがちです。Databricksから直接書き込む方法ではDatabricks側に書き込み処理を数行書くだけで済みますが、この方法では数百行程度とはいえ取り込み処理を追加で実装する必要があります。さらに、以下のような定期実行の仕組みがバックエンド側に整っていない場合は、それらも合わせて実装する必要があります。 スケジューリング : バッチを動かす実行環境の定義と、デプロイパイプラインへの組み込み 資格情報 : S3の読み取り権限とDBの書き込み権限、それぞれのIAMとシークレットの管理 監視とアラート : 取り込みの失敗に気づくための通知の仕組み 冪等性と再実行 : 途中で失敗しても安全にやり直せる作り データ受け渡しのルール : ファイル形式・置き場所・命名の取り決めや、書き込み途中のファイルを読まないための完了通知 ここを整えないと、取り込み処理自体はできているのに手動実行の運用が残ってしまう、ということになりがちです。 また、S3上のファイルとDBの両方にデータのコピーが存在することになるため、ETLからS3へファイルを置く処理が失敗した場合、ETL側の再実行だけでは復旧できず、バックエンドの取り込みバッチも合わせて再実行する必要が出てきます。 用途 向いている 取り込み時に加工・検証・既存マスタとの整合が必要なとき 外部キーでDBの他テーブルと繋がるような場合 向いていない アプリ側に実行基盤が整っておらず、整備する工数を取れない場合 Lakebaseのsynced tableを使用する 概要 DatabricksのLakebase(マネージドPostgreSQL)を使い、UCのテーブルをPostgresのテーブルとして同期します。 UC (Delta) --[synced table]--> Lakebase (Postgres) --> API 同期モードは3つあり、同期のされ方が異なります。 Snapshot : 実行のたびに同期元の全量を取得し、テーブルを丸ごと置き換える。手動・API・スケジュールで起動する Triggered : 初回に全量を取得し、以降は前回実行からの差分だけを適用する。起動方法はSnapshotと同じ Continuous : 初回に全量を取得し、以降はパイプラインが常時実行され、変更をほぼリアルタイムで適用し続ける 参考: Databricksの公式ガイド メリット 全件更新をアトミックに行えます。Snapshotモードの同期は、全量をコピーしたうえでテーブルをアトミックに置き換えるため、空の状態や一部だけ入れ替わった状態が読まれることはありません。Databricksから直接書き込む方法では RENAME TABLE を使って自前で実装する必要があった入れ替えを、プラットフォームの機能として提供してくれています。 また、アプリ側に取り込みバッチを実装する必要がありません。バックエンドのバッチで取り込む方法で課題になった定期実行の仕組みの整備が不要で、スケジューリングも監視もETL側の仕組みに閉じます。 読み取りは通常のPostgresと同じなので、配信のレイテンシもミリ秒オーダーです。配信するテーブルを増やしたい場合もsynced tableを1つ追加するだけでよく、アプリ側は接続の仕組みを共有できます。 デメリット 他の方法と比べて金銭的なコストが大きくなります。ここまでの2つの方法は既存のRDSにデータを入れるため追加のインフラコストがほとんどかかりませんが、この方法ではRDSとは別にLakebaseを新しく持つことになるため、その分の料金が追加で発生します。Autoscalingプランは従量課金で、Computeの料金は1 CU-hourあたり$0.111程度(2026年8月12日時点の 公開価格 )、これに加えてストレージなどの料金がかかります。使っていない時間にコンピュートを落とすscale-to-zeroという機能もありますが、常時リクエストが来るAPI配信ではそもそも落ちる時間がなく、むしろコールドスタートを避けるために最小キャパシティを確保しておく必要があります。 また、接続まわりの作り込みが必要です。認証はOAuthトークンかネイティブPostgresロールパスワード認証(Autoscalingプロジェクトではデフォルト無効)の2方式で、OAuthの場合はトークンの有効期限が1時間のため、新規接続のたびにトークンを取得し直す仕組みをアプリ側に組み込む必要があります。認証方式の詳細は 公式ドキュメント を参照してください。 synced tableは読み取り専用として扱う必要があります。データのソースはUC側であり、Postgres側で直接更新すると同期元との整合が壊れてしまうため、読み取りのみにすることが推奨されています。なお、Lakebase自体は通常のPostgresなので、synced tableとは別に書き込み可能なテーブルを作ること自体は可能です。ただし、アプリのDB(RDS)とは別のデータストアであることに変わりはないため、アプリのマスタテーブルとの外部キー制約は張れません。参照先のマスタが消えた場合の整合性は、ETL側で担保するか配信時のフィルタで守ることになります。 外部依存が増えるため、Lakebaseに障害があったときにアプリの機能全体を落とさないような設計も必要になります。 用途 向いている 分析基盤が作ったデータをそのままAPIから配信したいとき アプリ側に取り込みの仕組みを作らず、ETL側で完結させたいとき 向いていない 接続まわりの初期実装に工数をかけられない場合 配信データを既存のアプリのDBと同じDBで管理したいとき(別のデータストアになるため不可) Lakebaseの予算を捻出できない場合 まとめ 今回紹介した3つの方法をまとめると以下になります。 Databricksから直接書き込む バックエンドのバッチで取り込む Lakebaseのsynced table ダウンタイムなしの全件更新の実現方法 別テーブルに書き込み、 RENAME TABLE で入れ替え(自前で実装) 単一トランザクションでの書き込み Snapshotモードの同期 初回のみ必要な整備 VPCピアリングなどの経路設定 定期実行の仕組みの整備 Lakebaseの作成 + トークン管理など接続まわりの作り込み テーブルごとに必要な作業 書き込み処理の実装 取り込み処理の実装 synced tableの追加 追加のインフラコスト ほぼなし ほぼなし あり(Lakebaseの従量課金) データの加工・検証を行う場所 Databricks側(書き込み前) アプリ側(取り込みバッチ内) Databricks側(同期元テーブルの生成時) 既存テーブルとの外部キー制約 張れる(id管理が煩雑) 張れる 張れない ETLが失敗したときの再実行範囲 ETLのみ ETL + 取り込みバッチ ETL + 同期 従来の方法とLakebaseを使用する方法を比較しましたが、LakebaseはUCのデータをアプリに届ける選択肢になり得ると感じました。ダウンタイムなしの全件更新がプラットフォームの機能として手に入り、アプリ側に取り込みの仕組みを作らずETL側で完結できるのは、従来の2つの方法にはない強みです。 ただし、Lakebaseを新しく持つことによる金銭的コストと接続まわりの初期実装が必要で、既存のテーブルと外部キーで繋ぐこともできないため、どんな場合でもLakebaseが最適というわけではありません。 どの方法も一長一短ではあるので、使用する状況に合わせて選定するのが良いと思います。個人的には、次のフローチャートに沿って判断するのが良いかなと思っています。 最後まで読んでいただきありがとうございました! この記事がいつか誰かの参考になれば嬉しいです!
はじめに こんにちは!デリッシュキッチンで主にバックエンドの開発を担当している秋山です。 AIツールの導入などで、ツール費用が増えている方も多いのではないでしょうか。 有料ツールを導入すると当然支出は増えますが、予算が無限にあるわけでもありません。 私も先日、有料ツールを導入したいと考えたときにコストの壁にぶつかりました。 そこで「先に既存のムダを削って、浮いた分の範囲内でまずは導入/検証する」という進め方を取ることにしました。 その中でコストとどう向き合うか考えるきっかけになったので、その時のことを紹介していきます。 どうやってコスト削減に取り組んだか コスト削減の対象として真っ先に思いついたのは、AWSでした。 インフラの費用は金額が大きいので、削れた時の効果もそのぶん大きくなります。 とはいえ、どこにムダがあるのかを自力で探し回るのは大変です。 そこで今回はAWS Cost Optimization Hubを使いました。 Cost Optimization Hub(コスト最適化ハブ)とは Cost Optimization Hubとは、コスト最適化に関する推奨事項を統合的に閲覧できるAWSのコストツールです。 どのリソースでどのくらいコスト削減できそうかがわかります。 また、表示される削減額は購入済みのReserved InstancesやSavings Plans等を考慮した上で、請求額がどれだけ変わるかを見積もった金額になっているようです。 そのため、定価どうしの単純な比較ではなく、実際の請求に近い形で優先順位を付けられます。 Cost Optimization Hub による機会の特定 - AWS コスト管理 削減額機会のページには、下記の項目があります。 削減額機会の一覧のヘッダ 削減額機会の一覧のヘッダ2 「最も推奨されるアクション」の欄には、「アップグレード」「アイドル状態または未使用のリソースを削除」「適切なサイズ設定」など、どのような方法でコスト削減が期待できるかが表示されます。 そのため、明確なアクションを計画することができます。 また、「実装作業」の欄には、実際にアクションする際の作業コストが「非常に低い」「高」などランクづけされて表示されます。 ただし、実装作業コストが低いからといって、安易に実行してよいとは限りません。 例えばReserved InstancesやSavings Plansの購入は、作業としては購入するだけなので手間はありませんが、年単位のコミットメントを負うことになり、購入後に条件を変更することはできません。 作業の手間と判断の重さは、別のものとして考えたほうがよさそうです。 結果 今回は比較的実装作業コストが低い、不要なリソースの削除や開発時に使用しているリソースのスケールダウンなどを行いました。 その結果、導入したかったツールの検証費用分は削減できました。 コスト削減に向き合う中で得た気づき 実際にコスト削減をしてみて、改めて大事だと思ったことがいくつかありました。 無駄を減らす 当たり前のことではあるのですが、コスト削減において無駄を減らすのは最も確実な手段だと思います。 使われていないリソースは、止めても何かが動かなくなるわけではありません。 そのため誰かが困って報告することもなく、気づかれないまま動き続ける可能性があります。 一方で、一旦使われていないことがわかれば、削除作業自体はとても簡単にできます。 技術的負債の解消でコストも減る 技術的負債の解消により、実装コストだけでなく、ツールやインフラのコストも減る可能性はあると思いました。 監視ツールを例に挙げると、多くは扱うデータ量に応じた従量課金です。 無駄な処理が多ければ、そのぶん送られるデータも増えて料金が上がります。 逆に処理を整理すればデータ量が減り、その分安くなります。 負債を抱えたままでも動いてはいるので、普段は困りません。 ですが動かし続けるための費用は、その裏で払い続けていることになります。 もっとも、これは削減額として測りにくい部分でもあります。 「この負債を解消したから月いくら下がった」と切り出すのは難しいので、あくまで副次的な効果として捉えています。 また、上述の「無駄を減らす」にも繋がるのですが、使用していないツールやインフラのリソースは、それ自体がメンバーの認知負荷を高める負債にもなり得ます。 そのため、負債を減らすと言う意味でもやはり「無駄を減らす」のは大切だと思いました。 キャッチアップが大事 コスト削減においても技術的な情報のキャッチアップは大事だと思いました。 AWSなどの外部サービスを使っていると、新サービス・新機能を使ったり、バージョンをアップデートするだけで料金が下がることがあります。 たとえばAWSで言うと、 EBSをgp2からgp3にアップデートする インスタンスをx86からGravitonに移行する などでコスト削減を行うこともできます。 Amazon EBS 汎用 SSD ボリューム - Amazon EBS ARM Processor - パフォーマンスプロセッサ - AWS EC2 Graviton - AWS こういったことは、日々キャッチアップをしていないとなかなか気づきづらいかなと思います。 というのも、一度組んだ構成は動いている限り見直す機会は多くありません。 そのため、安くなる選択肢が出ていても、こちらから探しにいかないと気づけないままになります。 その点では、Cost Optimization Hubのようなツールに頼るのも一つの手だと思いました。 アップグレードの推奨を出してくれるので、自分が追いきれていない部分を拾ってもらえます。 まとめ 本記事では、有料ツールの導入に向けてAWSのコストを削減した話を紹介しました。 Cost Optimization Hubを使うと、どこにムダがあるかと、それを直す作業のコストまで一覧で見られます。 まずはここを見て、作業コストの低いものから手を付けるのが取りかかりやすいと思います。 そして今回やってみて感じたのは、コスト削減は一度やって終わりではないということです。 無駄なリソースは気づかないうちに増えますし、新しい機能を追えていないだけで払い続けている分もあります。 最後まで読んでいただきありがとうございました! 参考文献 Cost Optimization Hub による機会の特定 - AWS コスト管理 削減の機会の表示 - AWS コスト管理 月間節約額の見積り - AWS コスト管理
こんにちは。開発1部でデリッシュキッチンのプレミアム機能を開発している新卒エンジニアの野村です。 初めて渡されたタスクの話です。実装がほぼ終わったタイミングで、大きな手戻りに気づきました。新しく追加するはずだった機能の一部が、すでに存在していました。 なぜ最後まで気づけなかったのかを振り返り、AIエージェントを使った開発で何を見落としやすいか、既存のシステムにどう向き合うべきかを考えました。 Claude Codeと進めたタスクで、既存機能を見落とした 2026年4月にエブリーへ新卒として入社し、研修を終えて最初に渡されたタスクは、アプリのLPに出すボタンの種類を切り替える機能でした。 デリッシュキッチンには個人プランとファミリープランの2種類の課金プランがあり、それぞれに無料期間があります。どちらのプランを出すかと、その無料期間を何日にするかを、それぞれダッシュボードから変更できるようにする、というのが依頼の内容でした。 タスクの進め方は、DesignDocument(DD)を作成してレビューを受け、サーバーを実装し、最後にダッシュボードを実装する流れでした。DDには、何を作るかに軽く触れたうえで、どう作るかを中心に書きます。エブリーではClaude Codeが全社で使えるようになっていたので、DDの作成からサーバーの実装まで、Claude Codeに相談しながら進めました。 フロントエンドの実装に入ったとき、修正箇所のコードに「無料期間」と書かれたフィールドがすでにあることに気づきました。調べてみると、個人プランの無料期間は、すでにダッシュボードから変更できるようになっていました。DDを見返すと、テーブル設計にもAPI設計にも、既存の無料期間フィールドはきちんと書かれていました。 DDはClaude Codeと相談しながら自分で出したものでしたが、そこに書かれていた既存の無料期間を、実装が終わるまで読み取れていませんでした。 ゼロから作っていた学生時代は、AIの出力を判断できた 学生時代は、インターン先でiOSアプリやWebサービスの開発をしていました。2023年から2025年にかけての時期で、何を作るかは案件ごとに違いましたが、共通していたのは、設計から実装まで自分でゼロから考えて作っていたことです。 当時はまだAgentのように自律的に動くAIはなく、ChatGPTへのコピペや、コード補完としてAIを使う程度でした。システムがどう動いているかは自分自身で作っているので、人に詳しく説明できる状態で開発を進めていました。 2025年の半ばにClaude Codeを使い始めてからは、それまでの実装時間よりもずっと速く開発できるようになりました。この速さを知った状態で、2026年4月にエブリーへ入社しました。 ゼロから作っていた開発では、AIが何を出力しても、それが正しいかどうかを自分の頭の中にある設計と照らし合わせて判断できました。そう判断できたのは、システムがどう動くべきかという理解が、判断軸として自分の中に自然にあったからです。 判断軸がないまま、AIに進めてもらった 私が渡されたタスクは、自分でゼロから作るものではありませんでした。何年も運用されてきた既存のシステムに、新しい機能を追加するものでした。 学生時代の開発速度をイメージしていましたが、実際に進めてみると、想像していたよりも、私のタスクを進めるスピードは遅いと感じていました。AIの出力の意味が自分にはわからないことが、進みを遅くしていました。 説明されてもそれが事実かどうか腑に落ちないまま、新卒として早く成果を出したい気持ちと、以前の開発速度への意識に押されて、そのまま進めていました。DDに対してはPRでレビューをもらえる仕組みがあり、そこで安心感を得ていた面もあります。 既存のシステムで実際に製品として触れる部分があっても、自分の手で触るのではなく、AIに調べてもらうという進め方をしていました。 AIとのやり取り越しでは、既存の仕様に気づけない 無料期間フィールドの存在に気づかなかったのは、コードを読む以前の話です。プロダクトのUIを自分で触っていれば、あるいはAPIの入出力を自分で確認していれば、個人プランの無料期間がすでにダッシュボードから変更できると気づけたはずでした。AIとのやり取り越しに見ているだけでは、そこに気づく機会がありませんでした。 自分が頼んだのは「個人プランの表示・非表示を切り替え、表示する場合は無料期間を設定できるようにする」という指示でした。この指示自体に、既存の無料期間フィールドとの整合性を確認する視点が入っていませんでした。既存にすでにある機能を、新しくAPIに追加しようとしている、という違和感に、指示を出す前に気づく余地はありました。 そこに気づかないまま、AIが返す説明に納得してしまうという状態が続いていました。たとえば「本当にそうなっていますか」とAIに確認しても、返ってくるのはこちらが納得できる説明です。その説明が実際に妥当かどうかを見極める判断軸がないまま、説明を読んで納得してしまう、という繰り返しでした。 DDを自分の手で書き、コードを自分の手で追った この見落としのあと、進め方を変えました。DDは自分の手で書き、AIは補助として使うようにしました。 DDのテンプレートに、目的、ゴール、非ゴール、システムの概要図、DBとAPIの変更、といった項目を自分で作りました。このテンプレートに沿って、まず自分の言葉で埋めていくようにすると、タスクを進めるうえで意識しなければならないことが、それまで抜け落ちていたと気づきました。 なかでも効いたのは、ゴールの項目に「どうなれば成功と言えるか」を自分の言葉で書く作業でした。ここが埋められていなければ、AIが出した実装がそれを満たしているかどうかも判断できません。 コードについても、AIに解説してもらうことはありましたが、最終的には自分の手で追うようにしました。この2つを変えただけで、考慮漏れは明らかに減りました。 AIと対話を重ねて理解しようとする進め方には、限界がありました。目の前のタスクは解決しますが、次の課題に当たったときにはまた同じように対話を重ねる必要があり、理解が場当たり的になっている感覚がありました。コードという一次情報を自分で追うようにしてからは、理解が積み上がっていく実感がありました。 まとめ: 判断軸は、一次情報からしか作れない 検証する判断軸は、AIの解説を聞くだけでは作れないと感じています。AIの解説は、こちらが理解できているかどうかにかかわらず、同じようにわかりやすく返ってきます。そのため、判断軸がないままでも、わかったつもりになってしまいます。 判断軸を作るには、DDを自分の手で書く、コードを自分の手で追うといった、一次情報に自分であたる作業が必要だと思います。ゼロから作る開発では、実装そのものが一次情報になるので、判断軸は作業の中で自然にできあがります。既存のシステムに新しく加わる開発では、自分からあたりにいかない限り判断軸はできあがらないというのが、今回の経験でした。その作業を積み重ねることが、次の課題にも使える判断軸を作る方法だと考えています。 新卒として早く成果を出したい、AIを使って早く実装したい、という気持ちは今もあります。同じように感じている方は多いのではないかと思います。ただ、急いで進めた結果が今回の手戻りでした。遠回りに見えても、一次情報にあたって理解を積み上げていくほうが、最終的には早いのだと感じています。 今回は新卒として入社した自分の経験ですが、新卒に限った話ではないとも思っています。中途入社や異動で既存のシステムに新しく参画するときも、そのシステムについての判断軸はまだ持っていない状態から始まります。自分が理解できていないシステムに携わるときは、同じことが当てはまるのではないかと感じています。 ここに書いたのは、新卒としてエブリーで働き始めてまだ数ヶ月の自分が、今の時点でたどり着いた解決策です。自分が経験を重ねることでも、AIの精度が上がっていくことでも、この考え方自体は更新されていくのだと思います。
こんにちは、トモニテ開発部 iOS エンジニアの村田です。 iOS エンジニアもしくは Android・クロスプラットフォームを含めてモバイルエンジニアの皆さんに対して気になっていることがあります。 みなさん AI 開発どんな感じでやってますか?どんなハーネス組んでますか? エンジニアリング業界では、単に指示を出して書いてもらう「バイブコーディング」の次の段階として、AI エージェントの自律化や「ハーネスエンジニアリング」「ループエンジニアリング」といった話題が急速に広がっています。 Web やサーバーサイド領域では、こうした最新の AI 活用の情報が活発に共有されている一方、iOS(モバイル)開発における実践的なナレッジはまだまだ各所に散らばっており個々で孤軍奮闘している印象を受けています。 私自身、久しぶりに iOS 開発に取り組んでいて、Claude Code と git worktree を用いた並行開発をする中で iOS 特有のハマりどころをいくつか感じました。 今回は「並行開発」という観点にフォーカスして、iOS で並行開発したときに感じた課題と対処方法を記載します。 開発環境 前提として、以下のような環境・仕組みで開発しています。 使用技術 AIエージェント : Claude Code エディタ : VSCode 並行開発 : Git Worktree 対象 : iOS アプリ(Swift / UIKit / SPM / .xcodeproj) ビルド方法 : XcodeBuildMCP(Claude 経由の MCP)・XcodeBuildMCP(CLI 版)・Xcode(GUI) ディレクトリ構成 <repo>-trees/ ← worktree develop/ ← メイン worktree(base ブランチ) feature-A/ ← タスクごとの worktree(並列) feature-B/ ← タスクごとの worktree(並列) refactor-C/ ← タスクごとの worktree(並列) ... 開発手順 タスク開始時に git worktree add で develop ブランチから新規 worktree を切る worktree 配下で Claude Code のセッションを開始し、要件定義 → 実装 → PR 作成など開発フローを進行 タスクが終わったら、その worktree ごと片付ける ---bin なぜ並行開発が欠かせないのか あちこちで語られている話なので、要点だけ。 AI に開発させると、人間の役割は「実装する人」から「複数のエージェントを監督する人」に変わります。「どこまで自律的に AI に開発させられているか」にも依りますが、設計・実装・ビルド・テストと多くのフェーズで人間の手が空くようになるため、1 タスクを直列で進めるよりも複数タスクを並行で回す方が効率よく進められます。 そこで注目を浴びたのが git worktree です。ブランチごとに独立した作業ディレクトリ(worktree)を持てるため、作業ファイルの競合を気にせず、安全に複数タスクを同時進行できます。 そうして git worktree を用いて iOS 開発を始めたのですが、いくつか課題が発生しました。 問題その1: DerivedData がストレージを食い尽くす 何が起きたか iOS のビルドでは DerivedData を生成します。DerivedData には Xcode がビルドのたびに吐き出す中間生成物(ビルドキャッシュ・インデックス・成果物など)が含まれており、デフォルトでは ~/Library/Developer/Xcode/DerivedData/ に生成されます。XcodeBuildMCP でビルドする場合は、 ~/Library/Developer/XcodeBuildMCP/workspaces/<worktree>-<hash>/DerivedData/<プロジェクト名>-<hash> に生成されます。 DerivedData は worktree の内部ではなく、ユーザー共通の場所にまとめて溜まるため、worktree の数に比例して独立したビルドキャッシュが蓄積されていきます。 私の環境では 1 worktree あたり数 GB〜20 GB 台、合計およそ 86 GB になっていました。 結果としてディスクの空き容量が枯渇し、スワップ領域も確保できなくなって、ビルドどころではなくなりました。 # Xcode(GUI)の既定 — プロジェクト名 + ハッシュ名 ~/Library/Developer/Xcode/DerivedData/ ├── <プロジェクト名>-a1b2c3d4efgh…/ ├── <プロジェクト名>-e5f6g7h8ijkl…/ ├── <プロジェクト名>-i9j0k1l2mnop…/ ├── <プロジェクト名>-q7r8s9t0uvwx…/ └── … # XcodeBuildMCP の既定 — worktree 名 + ハッシュ名 ~/Library/Developer/XcodeBuildMCP/workspaces/ ├── develop-a1b2c3…/DerivedData/ 19 GB ├── feature-A-d4e5f6…/DerivedData/ 21 GB ├── feature-B-g7h8i9…/DerivedData/ 11 GB ├── feature-C-j0k1l2…/DerivedData/ 8.8 GB └── …(他 4 worktree) 26 GB 計 86 GB キャッシュを削除しようと試みたところで Xcode の場合、DerivedData のフォルダ名がハッシュ化されていて、フォルダ名だけではどの worktree に対応するかわからない ビルドしなくてもインデックス更新などで更新日時が変わるため、「更新日が古い=不要」という判断も効かない といった理由により、使い終わった worktree のゴミだけを削除することが難しかったです。 かといって全部消すと、全 worktree がコールドビルドに逆戻りしてしまいます。 XcodeBuildMCP はデフォルトでフォルダ名に worktree 名が入るため対応関係は分かりやすいのですが、 git worktree remove (worktree の削除)をしても、この孤児フォルダが残り続ける点は Xcode の既定と同じです。 対処方針: DerivedData を worktree 配下に保存する 対応策として DerivedData の置き場所を worktree フォルダの直下( <worktree>/DerivedData )に固定すると、次のメリットが得られました。 どのキャッシュがどの worktree のものか、置き場所を見れば分かる git worktree remove すれば DerivedData も一緒に消える 開発時のライフサイクルは以下のようなイメージです。 DerivedData の置き場所を変更する方法 ① Xcode の GUI でビルドする場合 全プロジェクト一律でよい場合 : Xcode → Settings → Locations → Derived Data を Default から Relative に変える 特定のプロジェクトだけ有効にしたい場合 :対象プロジェクトを Xcode で開いた状態でメニューの File → Workspace Settings… ( .xcworkspace を開いていない場合は Project Settings… )を選び、 Derived Data を Workspace-relative Location に切り替える 後者の場合、実態としてはプロジェクト内の WorkspaceSettings.xcsettings ( xcuserdata 配下・通常は Git 管理外のユーザーローカル)の設定と同等のため、GUI を使わず次の内容を直接書いても実現できます。 <? xml version = "1.0" encoding = "UTF-8" ?> <!-- <project>.xcodeproj/project.xcworkspace/xcuserdata/<user>.xcuserdatad/WorkspaceSettings.xcsettings --> <! DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd" > <plist version = "1.0" > <dict> <key> DerivedDataLocationStyle </key> <string> WorkspaceRelativePath </string> <key> DerivedDataCustomLocation </key> <string> DerivedData </string> </dict> </plist> ② XcodeBuildMCP でビルドする場合 こちらは .xcodebuildmcp/config.yaml の derivedDataPath で決まります(worktree のルートからの相対パスで解決されます)。 # <worktree>/.xcodebuildmcp/config.yaml schemaVersion : 1 sessionDefaults : projectPath : "<プロジェクトパス>" scheme : "<スキーム名>" derivedDataPath : "./DerivedData" platform : "iOS" useLatestOS : false bundleId : "<バンドル ID>" 💡 どちらの方法でも DerivedData がリポジトリ配下に生成されるため、 .gitignore に DerivedData/ を追加する必要があります。 ただし「Xcode 版で特定のプロジェクトだけ Relative にしている場合」や「XcodeBuildMCP 版で .xcodebuildmcp/config.yaml を Git 管理していない場合」は、新しい worktree を作るたびにこれらの設定を行う必要があります。毎回手動で設定するのは面倒なので、Git の post-checkout hook で worktree の作成時に自動設定されるようにするのがおすすめです。 post-checkout hook で DerivedData の設定を自動化する git worktree add や git checkout を実行すると、 post-checkout という hook が発火します。hook は共通の Git ディレクトリ( git rev-parse --git-common-dir )に置かれ全 worktree で共有されるので、そこに設定することで新規 worktree 作成時の処理を仕込むことができます。 下記のような処理を .git/hooks/post-checkout に記述することで、新規 worktree 作成時に「DerivedData を各 worktree 配下( <worktree>/DerivedData )に保存する」ように設定できます。 なお以下の hook では ② の config.yaml を直接出力していますが、正の config.yaml をデフォルトブランチなどで管理し、post-checkout で cp する方式でも構いません。 #!/bin/bash # .git/hooks/post-checkout if [ " $3 " = "1" ]; then PROJECT = $( find . -maxdepth 1 -name " *.xcodeproj " | head -1 ) if [ -n " $PROJECT " ]; then # ① Xcode GUI 用: WorkspaceSettings に worktree 相対の DerivedData を書く DIR = " ${PROJECT} /project.xcworkspace/xcuserdata/ $( whoami ) .xcuserdatad " PLIST = " ${DIR} /WorkspaceSettings.xcsettings " mkdir -p " $DIR " [ ! -f " $PLIST " ] && plutil -create xml1 " $PLIST " plutil -replace DerivedDataLocationStyle -string WorkspaceRelativePath " $PLIST " plutil -replace DerivedDataCustomLocation -string DerivedData " $PLIST " # ② XcodeBuildMCP 用: config.yaml を worktree 直下に生成 if [ ! -f .xcodebuildmcp/config.yaml ]; then mkdir -p .xcodebuildmcp cat > .xcodebuildmcp/config.yaml <<'YAML' schemaVersion: 1 sessionDefaults: projectPath: "<プロジェクトパス>" scheme: "<スキーム名>" derivedDataPath: "./DerivedData" platform: "iOS" useLatestOS: false bundleId: "<バンドル ID>" YAML fi fi fi 問題その2: シミュレータを複数セッションが奪い合う 何が起きたか iOS 開発では、シミュレータ上での実操作が必要な場面が多々あります。 画面情報・遷移情報の取得 コード変更後の動作確認 E2E テストの実行 AI に並行開発させている中でこれらの動作をさせようとすると、1 台のシミュレータを複数のセッション(エージェント)が奪い合い、開発が滞る問題が発生しました。 操作の割り込み・競合: あるエージェントの検証中に、別のエージェントが起動・操作を行って画面を奪い合う 状態の破壊: 実行中のアプリ領域やデータが上書きされ、E2E テストや動作確認が誤判定される 処理の順番待ち: シミュレータの空き待ちが発生し、並行開発のスピード感が失われる 対処方針: worktree ごとに専用シミュレータを持たせる 対策として、 worktree ごとに専用シミュレータを持たせる運用にしました。 具体的にはシミュレータ名を <worktree 名> - <元の機種名> (例: feature-A - iPhone 16 Pro )のように紐付けます。これにより「このセッションが触っていいのはこの 1 台のみ」と明確にし、他のセッションで稼働中のシミュレータへの誤干渉を防いでいます。タスクが完了して役目を終えたシミュレータはシャットダウンし、別の worktree での開発で名前を変更して再利用する流れです。 💡 基本的には AI による並行開発を前提としていますが、人間が最終的な動作確認を行う場合にもメリットがあります。各 worktree 専用のシミュレータ上にビルド済みアプリがそのまま残っているため、スムーズに動作確認を進められます。 シミュレータの選定ルール ある worktree の開発で使うシミュレータの選定ルールは、以下のようにしました。 worktree 名で始まるシミュレータが起動済みなら、それをそのまま使う worktree 名で始まるシミュレータが未起動なら、起動して使う 無ければ、起動していないシミュレータを <worktree 名> - <元の機種名> にリネームして起動する これを実装に落とし込んだものが以下のコードです。 resolve_udid は ①→③ の順に「その条件に合うシミュレータがあるか」を確認していき、最初に見つかった 1 台を、その worktree に対応するシミュレータの UDID(デバイスの一意 ID)として採用します(見つかった時点で残りは確認しません)。あとはこの UDID を指定してビルドすれば、その worktree 専用のシミュレータに向けて実行できます。 wt = " $( basename " $PWD " ) " # worktree 名(例: feature-A)をシミュレータ名の接頭辞に使う # シミュレータ一覧を JSON で取得して devices_json にキャッシュする refresh_devices() { devices_json = $( xcrun simctl list devices available --json ) ; } # 未起動のシミュレータを起動する boot_sim() { xcrun simctl boot " $1 " 2 > /dev/null ; } # UDID から元の機種名を引く(既に worktree 名が付いていれば落とす。付け足すと再利用のたびに接頭辞が積み重なるため) sim_name() { printf ' %s ' " $devices_json " | jq -r --arg u " $1 " \ ' [.devices[][] | select(.udid == $u) | .name][0] // empty | sub("^.+ - "; "") ' } # 指定した起動状態(booted / unbooted)で、worktree 名で始まるシミュレータの UDID を返す(無ければ空文字) pick_named() { printf ' %s ' " $devices_json " | jq -r --arg wt " $wt " --arg want " $1 " \ ' [.devices[][] | select((.name | startswith($wt + " - ")) and (if $want == "booted" then .state == "Booted" else .state != "Booted" end)) | .udid][0] // empty ' } # 未起動(Shutdown)の空きシミュレータを1台返す(無ければ空文字) pick_spare() { printf ' %s ' " $devices_json " | jq -r \ ' [.devices[][] | select(.state == "Shutdown") | .udid][0] // empty ' } resolve_udid() { refresh_devices # ① worktree 名で始まるシミュレータが起動済みなら、そのまま使う udid = $( pick_named booted ) ; [ -n " $udid " ] && { echo " $udid "; return; } # ② worktree 名で始まるシミュレータが未起動なら、起動して使う udid = $( pick_named unbooted ) ; [ -n " $udid " ] && { boot_sim " $udid "; echo " $udid "; return; } # ③ 無ければ、空きシミュレータの接頭辞を「<worktree 名> - 」に付け替えて起動する spare = $( pick_spare ) [ -z " $spare " ] && { echo " 空きシミュレータがありません " >&2; return 1 ; } xcrun simctl rename " $spare " " $wt - $( sim_name " $spare " ) " boot_sim " $spare " echo " $spare " } 開発フローとクロージング処理 ここまでの処理を開発フローに沿って並べると次のようになります。 開始 : タスクごとに worktree を切り、専用の作業場を用意する 実装 : その worktree で Claude セッションを開始し、1 つの機能を実装する 動作確認 : その worktree 専用のシミュレータを起動し、ビルド & 実行・テストを行う レビュー : 実装が固まったら PR を作成する クロージング処理 : PR マージと同時に、worktree 削除・Issue クローズ・シミュレータのシャットダウンを行う 開発フローの最後には、クロージング処理を置いています。 close-feature のようなスキルにまとめ、PR マージ → Issue クローズ → worktree 削除 → 専用シミュレータのシャットダウンを一括で実行しています。 このクロージング処理をフローに組み込むことで、問題その1で挙げた DerivedData によるストレージ圧迫を防ぎつつ(worktree を削除すれば配下の DerivedData も一緒に消える)、起動したままのシミュレータが積み上がってメモリを圧迫するのも同時に抑えられます(シャットダウンした端末は、次のタスクで再利用される)。 問題その3: .xcodeproj のコンフリクトが多発する .xcodeproj を Git 管理しているとブランチの切り替えやマージのたびにコンフリクトが起きやすい、という問題があります。これ自体は昔からある iOS 開発の悩みですが、AI に複数タスクを並行開発させるようになってコンフリクトの頻度も増え、無視できないコストになったと感じています。 トモニテの PJ では実現できていませんが、下記の理由により XcodeGen を用いた YAML 管理への移行を検討しています。 1. 並行開発でのコンフリクト軽減 git worktree などを活用して複数ブランチでの並行開発を進める場合、 project.pbxproj のコンフリクトが多発する可能性があります。 特に AI の活用によって開発の速度や並行性が上がるほど、その発生頻度も多くなりがちです。 XcodeGen を導入して .xcodeproj を自動生成の成果物として扱い .gitignore に追加することで、 .xcodeproj でのコンフリクト問題を解消できると考えています。 2. AI と YAML の相性 Xcode のプロジェクト管理は GUI 操作を前提とした仕組みであり、AI エージェントとは相性が良くありません。これを project.yml による宣言的なテキスト管理に切り替えることで、「YAML での管理・変更 → コマンド実行( xcodegen generate )」という AI に適したフローで構成を変更できるようになると考えています。 3. コードレビューのしやすさ コード差分が複雑な pbxproj からシンプルな project.yml に変わることで、変更内容を容易に把握できます。 AI がコードを書き、人間がレビューするフェーズでは可読性の観点でもメリットがあると考えています。 まとめと残課題 ここまで git worktree を用いた iOS の並行開発で出会った問題点と、その対処方法を紹介してきました。 とはいえ、こうして並行タスクを回す仕組みを整えても、human-in-the-loop 的な体制では並行開発の効果も限界があると感じています。監督する人間のコンテキストスイッチがボトルネックになるため私の場合、同時に見られるのは 3〜4 タスクほどでした。これでは開発生産性も頭打ちになり、「プロダクトや事業をどう伸ばすか」という本質的な問いに集中できないと感じています。 この課題を突破するためには、やはり「ループエンジニアリング」など AI がより自律的に開発を回せるような仕組みを追求していくことが不可欠だと感じています。 関連リンク XcodeBuildMCP XcodeGen
こんにちは、開発1部で食事管理アプリ ヘルシカ の開発をしている井上です。 App Store のオファーは種類が多く、対象になるユーザーも、適用のしかたも、サーバ署名の要否も、種類ごとに違います。オファーごとの対象ユーザーと、種類が絡んで分かりにくい所を1本にまとめてみました。 オファーは4種。「誰に出すか」で選ぶ サブスクリプションの月額や年額といったプランは、 サブスクリプショングループ という単位でまとまります(同じグループで同時に有効なのは1つ)。 オファー は、一定期間だけ無料や割引で購読してもらう仕組みで、プランごとに設定します。オファーには、新規向けの お試しオファー (Introductory Offer)、購読履歴のある人向けの プロモーションオファー (Promotional Offer)、解約者を呼び戻す 再獲得オファー (Win-back Offer)、コードを配って引き換えてもらう オファーコード (Offer Codes)の4種類があります。どのオファーを選択するかは、ユーザーがどの購読状態にいるかで決まります。 ユーザーのサブスクリプションの購読状態は、次の3つに分類されます。 新規 :まだ加入していない人 既存 :購読中の人 離脱 :解約して今は購読していない人 段階と対応づけて、オファーの種類ごとの違いを次の表と図にまとめます。 オファー種類 主な対象 適用のしかた ① お試し 新規と、お試し未使用の離脱者 資格があれば自動で提示 ② プロモーション 既存か離脱のユーザー サーバ署名を付けて購入 ③ オファーコード 新規/既存/離脱(配布先で指定) コードを配布し引換入力 ④ 再獲得 離脱 Apple が資格判定。App Store にも表示 購読ライフサイクル(新規→既存→離脱)と各段階で使えるオファーの対応図 オファーコードは、どの段階にも配れます。 また、プロモーションはそのユーザーがプロモーションを受け取れるユーザーであることをサーバー署名を行い証明する必要があります。 オファーの出し方(支払いモード) どの種類でも、オファーの出し方は共通で、3つの 支払いモード から選びます。 支払いモード 課金のしかた 例 無料トライアル( freeTrial ) 一定期間は無料 7日間無料 継続割引( payAsYouGo ) 割引価格を毎請求期間、指定回数ぶん払う 3ヶ月間、毎月300円(通常600円) 前払い割引( payUpFront ) 割引価格をまとめて一括前払い 1年分を6,000円(通常7,200円) オファー期間が終わったあと、通常価格で継続課金するか、終了するかは、設定によって決まります。期間は3日から1年までの決まった選択肢から選びます。割引率を直接指定する枠はなく、地域ごとの価格設定の差が結果的な割引率になります。 オファーやプランが絡むと迷うところ オファーは単体なら分かりやすいものの、お試しやオファーコード、プラン変更が絡むと途端に分かりにくくなります。 お試しはいつ使えなくなるのか お試しを使えるかどうかは、プランごとではなくサブスクリプショングループ単位で判定されます。そして、同じグループで使えるのは一度だけです。たとえば月額と年額が同じグループにあるとします。新規のユーザーは必ず対象になります。過去に解約した離脱者も、同じグループでまだお試しを使っていなければ対象になりえます。逆に、月額でお試しを一度使うと、同じグループの年額ではもう使えなくなります。 プロモーションは新規の獲得に使えるのか 割引を配れるのだから、プロモーションは新規の獲得にも使えそうに見えます。ところが実際には、購読履歴があることが大前提で、新規には使用できません。対象になるのは、既存か離脱のユーザーです。資格は2段構えです。 ① Apple の判定 :いま購読中の人か、購読が期限切れになった人だけを対象と認めます。 ② 自社の絞り込み :Apple が認めた対象から、独自の条件で「誰に出すか」を決め、署名してオファーを提示します。 購読履歴のない新規は①の時点で対象外なので、署名しても購入は失敗します。新規に強く訴求したいなら、お試しかオファーコードを使います。 オファーコードの「自動更新」と「お試し併用」 オファーコードを作るときに選ぶ「自動更新」と「お試し併用」は、適用後の課金の挙動を大きく変えます。 オファーコードの自動更新ON/OFFとお試し併用による課金の時間推移図 自動更新 ON :コードのオファー期間が終わったあと、通常価格で更新が続きます。 自動更新 OFF :オファー期間で終わり、更新されずに失効します。設定できるのは無料オファーだけで、お試し併用は選べません。 お試し併用 :お試しを先に適用すると、その分だけコードのオファー期間と更新が後ろにずれます。適用しなければ、コードだけになり、お試しの資格は残るので、あとで改めてユーザーに提示できます。 オファーコードは、配布先に特定のユーザーを指定することができません。対象は、 New(未購読)/Existing(現在購読中)/Expired(解約や期限切れ) の3カテゴリと、配信先の国や地域で絞ります。カテゴリは作成後に変えられず、1つのコードは1つのプランに紐づきます。 コードには、ワンタイムとカスタムの2種類があります。 ワンタイム :特定の1人が1回だけ。有効期限は必須(最大6ヶ月)。 カスタム :上限まで何人でも。無期限にもできます。 お試しも使ってもらって、ちょうど6ヶ月無料をオファーコードで配れるか たとえば「お試しも実際に使ってもらったうえで、ちょうど6ヶ月を無料にし、コードで配りたい」。一見できそうですが、3つを同時には満たせません。お試しを使ってもらうにはコードの「お試し併用」を Yes にするしかなく、するとお試し期間がコード期間の前に上乗せされます。無料の合計が「お試し+コード期間」になるうえ、選べる期間も決まった値だけなので、ちょうど6ヶ月には合わせられません。 無料トライアルだけで解約した人は呼び戻せるか 無料トライアルだけで解約した人を呼び戻すなら、解約者向けの再獲得オファーが使えそうに見えます。ところが、再獲得オファーの対象には含まれません。 再獲得オファーの資格は、App Store Connect で条件を設定して決めます。設定できるのは、有料購読期間の最小月数、失効(購読の終了)からの経過期間、前回のオファーからの間隔です。いずれも有料で購読した実績を前提にしています。無料トライアルだけで解約した人は、有料で購読した期間が0か月です。そのため、有料購読期間を条件にすると、資格を満たせません。 無料トライアルだけで解約した人に各オファーが届くかを示す分岐図 呼び戻すには、プロモーションかオファーコードを使います。プロモーションは期限切れの購読履歴がある人を離脱者として対象にでき、オファーコードは対象に Expired を含められます。プロモーションもオファーコードも有料で購読した実績を条件にしません。 プラン変更(乗り換え)とオファーの関係 同じサブスクリプショングループのプランには、グレード(上位と下位の序列)をつけて階層構造で管理します。プラン変更(乗り換え)の挙動は、変更前と変更後のグレードで決まります。上位へのアップグレードは即時に反映され、未使用分が日割り返金されます。下位へのダウングレードや、期間の違う同じグレードのプランへの変更(クロスグレード)は、次の更新で反映され、返金はありません。 プラン変更に、オファーは必ずしも必要ありません。上位プランへ移るだけなら、購入すれば自動的にアップグレードされて上位のプランが適用されます。割引してプランのアップグレードを促したいときにだけ、プロモーションオファー(サーバ署名が必要)を添えてプランを提示します。(個人プランからファミリープランへの移行を初回だけ割引するなど) まとめ オファーを選ぶ軸は、機能の名前ではなく「誰に、いつ出すか」です。新規にはお試し、購読履歴のある人へ自社が対象を決めて出すならプロモーション、どの層にも配りたいならオファーコード、解約者を App Store 経由で呼び戻すなら再獲得を選びます。 自分の理解を整理するために書いた記事ですが、同じようにオファーの種類の多さに戸惑っている人の理解の助けになればうれしいです。 出典 Implementing introductory offers in your app Implementing promotional offers in your app Set up win-back offers Set up subscription offer codes Offer auto-renewable subscriptions
こんにちは。開発本部の河野です。 このたび、社内の運用チームから寄せられる問い合わせに一次対応する Bot を、Claude Managed Agents を使って構築しました。本記事では、アーキテクチャ・ツールの使い分け・設計上の判断を中心に、検討の過程を紹介します。これから導入を検討される方の参考になれば幸いです。 本記事について Claude Managed Agents は、本記事の執筆時点(2026 年 7 月)では パブリックベータ です。今後の正式提供(GA)に向けて、仕様や挙動が変わる可能性がある点にご留意ください。最新の情報は公式ドキュメント( Claude Managed Agents overview )をご確認ください。 背景:実データを確認しないと答えられない問い合わせ はじめに、前提を簡単に共有します。 社内には、キャンペーン応募の運用を担う管理画面つきの業務ツールがあります。ビジネス職はこの画面から、応募フォームの設問や表示条件を組み立て、集まった応募データの変換ルールを定義し、クライアントへ送付するデータの形式を設定します。 このツールは、案件ごとに設問や変換ルールを自由に組み合わせられるぶん、設定次第で挙動が変わり、意図どおり動くかの判断が難しくなります。そのため開発チームには、次のような問い合わせが日々寄せられていました。 設定方法や仕様の質問 :「この設問に回答した人にだけ画像を表示するには?」「この項目は設定できない認識で合っているか」 エラーやデータ不整合の調査 :「テスト時に出力データの件数が想定と合わない」「応募フォームを修正して公開したが、修正前の内容が表示される」 前者はドキュメントや仕様を調べれば答えられますが、後者は設定の内容・変換処理の実行状況・出力されたデータを、その都度確認しなければ答えられません。 つまり、あらかじめ用意した FAQ を返すだけでは、後者のような問い合わせに一般論しか返せません。そこで求めていたのが、実データまで確認したうえで一次回答を返すエージェントでした。これが今回の出発点です。 なぜ Claude Managed Agents を選んだか この問い合わせは、どこか一箇所を検索すれば済むものではありません。回答を組み立てるには、管理画面の設定、その裏側で変換処理を動かしている AWS、ドキュメント、ソースコードといった複数の情報源を横断しながら考える必要があります。 自前でエージェントのループ(モデルに推論させ、ツールを呼び出し、その結果を再び渡す、という処理を繰り返す仕組み)を実装する選択肢もありました。しかし、そのループの実行をマネージド側に任せられれば、私たちは「どのようなツールを持たせるか」「プロンプトをどう設計するか」に集中できます。今回の課題ではこの点が最も効くと考え、Claude Managed Agents を採用しました。あわせて、この取り組みは新しい技術に挑戦する社内の機会「挑戦WEEK」の中で始まったもので、当時登場して間もなかった Claude Managed Agents を実地で使ってみたい、という動機もありました。 補足 同様のことは、Amazon Bedrock AgentCore をはじめとする他のマネージドなエージェント基盤でも実現できます。今回は「新しい技術を試す」という挑戦WEEK の主旨から Claude Managed Agents を選びましたが、これから腰を据えて構築するのであれば、こうした選択肢も比較検討に加える価値があります。 Claude Managed Agents とは 本題に入る前に、前提となる部分だけ簡単に整理します。 Claude Managed Agents は、大まかに言うと、プロンプト・ツール・スキルをまとめた "Agent" を定義しておくと、推論ループの実行自体はマネージド側が担ってくれる仕組みです。 自前でループを実装する場合と比べると、開発側が担う範囲は次の3つに絞られます。 Agent 定義 (プロンプト・利用するツール・スキル・MCP の接続設定のまとまり) custom tool の実装 (自社システムを呼び出すコード) セッションの運用 (会話やイベントのハンドリング) 主なプリミティブは以下のとおりです。まずは名称だけ挙げておきます。 Agent :バージョン管理される Agent 定義 Session :会話の単位(Sessions API) custom tool :自前で実装するツール MCP :外部サービスとの既製の連携 skill / memory store :手順やナレッジ、過去事例の蓄積先 custom tool と MCP について補足 このあと繰り返し登場するため、この2つだけ先に補足します。 custom tool は、モデルに持たせる「道具」です。モデルが「この道具をこの引数で使いたい」と判断すると、実際に動作するのは開発側が実装したコードで、その結果を返すとモデルが推論を続けます。定義は name / description / input_schema からなり、とりわけ description (その道具が何をするものか)の記述が精度を大きく左右します。 一方の MCP は、外部サービスやデータ源をエージェントに接続するための標準的な仕組みです。Confluence や Slack のように公式の MCP サーバがすでに提供されているものは、それを繋ぐだけで使えます。ただし MCP サーバは自作することもできるため、「MCP か custom tool か」は "既製か自前か" という単純な対立ではありません。 では、この2つをどう使い分けたのか。ここが本記事の中心となるため、次章でまとめて扱います。 構成と、ツールの使い分け・設計上の判断 ここからが本題です。 全体の流れ Bot の動作自体はシンプルです。 運用担当が Slack でメンションして質問する 実行環境がセッションを開始し、イベントを受け取る Agent が必要な custom tool / MCP を呼び出しながら、実データを集めて推論する まとまった一次回答を Slack のスレッドに返す 図で示すと、Slack を入口として、実行環境がセッションとツール実行を担い、サーバ側の Agent が custom tool と MCP を使い分けながら回答を組み立てる、という構成です。 持たせているツールと、その使い分け Bot に持たせているツールは、現時点ではすべて read-only(参照のみ)です。設定の書き換えやジョブの再実行は行いません。まずは「調べて答える」ことに用途を絞りました。 情報源ごとに、custom tool にするか・MCP にするか・リポジトリを参照させるかを分けています。 情報源 参照するもの 実現方法 社内管理画面 現在の設定(案件・変換・送付設定など) custom tool(管理画面 API を呼び出す) AWS のジョブ実行状況 ジョブが成功したか、どこで失敗したか custom tool AWS の出力データ 出力データ(テーブル・カラム)が実在するか custom tool Confluence 運用手順・仕様のドキュメント MCP Slack 問い合わせ元スレッドの文脈 MCP GitHub 設定や画面では分からない「実際の挙動」 リポジトリをマウントして参照 AWS 側では、変換ジョブとその出力データを確認しています。内部的には一般的な構成ですが、本記事では「AWS 上のジョブと出力データを custom tool 経由で確認している」程度の粒度にとどめます。 設計上の判断①:custom tool と MCP をどう使い分けたか ツールを整理するうえで最も悩んだのが、「この情報源は custom tool と MCP のどちらにすべきか」という使い分けでした。一般論としての比較ではなく、今回の Bot で実際にどう判断したかを述べます。 判断は、大きく2段階でした。 まず、 公式の MCP サーバがすでにある情報源は、MCP で繋ぐ ことにしました。Confluence や Slack がこれにあたります。既製のものがあるのに、わざわざ自作する理由はありません。 問題は、管理画面や AWS のように 既製の連携が存在しない情報源 です。これらはエージェントから触れるようにするために、何かしら自分たちで実装する必要があります。ここで MCP サーバを自作する道もありましたが、 MCP サーバを立てるよりも、custom tool として実装するほうがコストが低く、早く動かせます 。まずは動くものを優先したかったので、これらは custom tool にしました。 公式の MCP がある(Confluence / Slack)→ MCP で繋ぐ 既製の連携がない(管理画面 / AWS)→ 実装が必要。より軽い custom tool を選択 コードを事実として参照させたい(GitHub)→ リポジトリをマウントして参照 (後述) ここで大事なのは、「MCP か custom tool か」は "既製か自前か" では決まらない、という点です。MCP サーバも自作できるので、実際に効いてくるのは "どちらのほうが軽く・早く目的を果たせるか" でした。 なお、GitHub には公式の MCP も用意されています。それでもリポジトリをマウントする方式にしたのは、用途がソースコードの読解だったためです。MCP 経由ではファイルを API で1つずつ取得する形になりがちですが、リポジトリをマウントしてしまえば、エージェントがコード全体を grep や横断参照でたどれます。「実際の挙動をコードで確認する」という用途には、こちらのほうが向いていました。MCP が力を発揮するのは、issue や PR の操作といった場面です。ここでも、「MCP があるかどうか」だけで機械的に決めるのではなく、その情報源に対して何をしたいかで選ぶ、という判断でした。 設計上の判断②:調べる範囲を先に絞る 情報源を渡す際には、範囲を絞ってから渡すことを徹底しました。 Confluence は「正典」とするページに限定する :関連しそうなページを無制限に参照させると、古い記述や書きかけのページに引きずられ、誤った回答につながります。「これが正である」と定めたページのみを参照先とすることで、誤読を防いでいます。あわせて、その正典ページ自体を最新に保ち続ける運用も欠かせません。参照先を絞るほど、そのページの正しさがそのまま回答の質に直結するためです。 ツールは read-only に限定する :前述のとおり、書き込み系の操作はまだ持たせていません。参照に用途を絞ることで、安心して社内に展開できる状態を先に整えました。 範囲をあとから広げるのは容易ですが、広げすぎたものを絞り込むのは困難です。そのため、先に狭く定めておく方針としました。 設計上の判断③:self-hosted 型ではなく Cloud 型を選んだ Claude Managed Agents には、実行基盤を自前で持つ self-hosted 型 と、マネージドな Cloud 型があります。当初は self-hosted 型を検討していましたが、最終的に Cloud 型を選びました。その経緯を書きます。 self-hosted 型では、マネージド側のエージェントが「このツールを実行してほしい」と判断したとき、その実行を受け取って処理するワーカーを、自社の環境で常時動かしておく必要があります。ワーカーというプロセスを一つ立て、接続を保ち、動き続けているかを監視する。エージェントのループ自体はマネージドに任せられても、その足回りは自分たちで抱えることになります。 さらに決め手になったのは、運用負荷そのものよりも、私たちが最も頼りにしたかった機能との噛み合わせでした。過去事例を蓄積する memory store や、マウントしたソースコードをエージェント自身に読ませる仕組みは、いずれもマネージドな環境の中で動くことを前提に設計されています。self-hosted 型ではその実行が自前ワーカー側に委譲され、期待どおりに動かない場面がありました。活かしたい機能ほど、実質的に Cloud 型を前提としていたのです。 結局 self-hosted 型は、「ワーカーの運用という手間が増える」一方で「使いたかったマネージド機能は活かしきれない」という、狙いと逆向きの選択になっていました。「実行を任せて設計に集中する」という当初の目的からすると本末転倒です。そこで Cloud 型に切り替えました。ワーカーは不要になり、構成は Bot 本体ひとつに単純化され、サーバ側の機能もそのまま利用できるようになりました。 補足:self-hosted 型が適する場面もあります。 たとえばツールの実行を自社ネットワーク内に閉じ込めたい、といった要件がある場合です。今回はそうした制約がなく、マネージドの利点が上回ったため Cloud 型を選びました。要件次第で判断は変わる、という点は添えておきます。 設計上の判断④:デプロイを2種類に分ける 運用する中で、変更には性質の異なる2種類があることが分かってきました。 プロンプトやツール定義のみの変更 → agents.update で新しいバージョンを作成すれば反映される(コンテナの再ビルドは不要) custom tool のコードの変更 → コンテナの更新が必要になる この2つを分けて扱うようにしたことで、「プロンプトを少し修正したいだけ」という場合にコンテナのデプロイを待たずに済み、改善のサイクルを回しやすくなりました。 実際にできるようになったこと ここまでの構成により、Bot は実際に次のような回答を返せるようになりました。 設定の確認:「この案件の現在の設定はこうなっています」 エラーの一次切り分け:ジョブの実行状況を確認し「ここで失敗しています」 出力データの確認:「データは生成されています/されていません」 手順の案内:Confluence の正典ページを参照して手順を返す 挙動の確認:GitHub のソースコードを参照し「実際の動作はこうです」 文脈の把握:Slack のやり取りから状況を把握する そして、この Bot の最大の強みは合わせ技にあると考えています。たとえば「一般的な手順(Confluence)」と「その案件の現在の状態(管理画面・AWS)」を突き合わせ、1回の回答としてまとめて返すことができます。 固定的な FAQ との最大の違いはここにあります。ドキュメント・ソースコード・実データを組み合わせ、その案件に固有の一次回答を返せることが、実データを確認しにいくエージェントとして構築した狙いそのものでした。 運用して効果を感じた工夫 description を丁寧に書く :custom tool の説明が不十分だと、モデルが道具を適切に選べません。「どのような場合に使うツールか」まで記述すると精度が向上しました。 参照範囲を固定する :前述の「正典」ページの例と同様に、参照させる範囲を絞るほど誤読が減ります。 read-only の境界を保つ :安全に展開できるため、社内に広げる際のハードルが下がります。 skill / memory store に過去事例を蓄積する :類似の問い合わせに関するナレッジを蓄積し、次回以降の回答に活かしています。 成果 まだ試運転の段階ですが、当初ねらっていた形は実現できています。 一次調査の負荷が下がった :これまで開発チームが都度、管理画面や AWS を確認して切り分けていた類型的な問い合わせについて、その最初の調査をエージェントが肩代わりできるようになりました。試運転として開発チームのチャンネルで運用し、これまでに約30件の実際の問い合わせへ一次回答を返しています。件数は多いが定型的な「まず状況を調べる」部分を任せられるようになったのが、大きな変化です。 回答が推測ではなく実データにもとづくものになった :固定的な FAQ では「一般的にはこうです」までしか言えませんでしたが、6つの情報源(管理画面・AWS のジョブ実行状況・AWS の出力データ・Confluence・Slack・GitHub)を横断し、その案件の現在の状態まで確認したうえで回答できるようになりました。 回答品質を数値で追えるようになった :実際の問い合わせを集めた32件の評価用データセットを用意し、回答を5つの観点・計10点満点で自動採点する仕組みを整えました。現時点の平均は8.1点/10点(32件中21件が合格ライン)です。この仕組みがあることで、「プロンプトやツールを直す → 同じデータセットで測り直す」という改善ループを、感覚ではなく数値で回せるようになりました。実際、点数の内訳を見ると「原因の特定」が弱点として表れており、次に何を直すべきかが具体的に分かります。 補足:採点の仕組み。 採点そのものも Claude に担わせています(いわゆる LLM-as-a-judge)。各問い合わせにはあらかじめ「期待される原因・対処」を正解として添えてあり、採点役はそれと Bot の回答を突き合わせて、次の5つの観点に各0〜2点をつけます。(1) 原因を特定できているか、(2) 対処が管理画面の正式な操作まで具体的か、(3) 申告した確信度は妥当か、(4) 開発へエスカレーションすべき場面を正しく見極められているか、(5) 読み手に伝わる構成か。合計10点満点で、8点以上を「合格」としています。単発のスコアは多少ぶれるため、絶対値そのものより「どの観点が弱いか」という傾向を読み、改善の的を絞るのに使っています。 散在していた知見が集約された(副次的な効果) :エージェントに正しく答えさせるには、担当者の頭の中や個別のやり取りに散らばっていた運用知識を、参照可能な形に整える必要がありました。正典ページの整備や過去事例の蓄積を進めた結果、Bot のためだけでなく、人が参照する資産としても知見がまとまりました。 課題とこれから もちろん、まだ発展途上です。 対象範囲は、安全に広げられるところから段階的に拡大しています。本番データを扱う範囲については、アクセス制御の設計を前提に、慎重に進めていきます。 回答精度や確信度の調整は、引き続きの課題です。「自信がない場合にどう振る舞うか」の扱いは、今後詰めていきます。 そもそも Managed Agents 自体の事例がまだ少なく、運用しながら整備している状況です。 今後目指しているのは、確信度によって振り分けを行い、ビジネス職が自ら一次回答にたどり着ける状態です。「自信のある回答はそのまま返し、不確かなものは人へエスカレーションする」といった振り分けが実現できれば、より安心して任せられるようになると考えています。 最後に。Claude Managed Agents は、うまく活用すれば「実データを調べて答える」エージェントを現実的な工数で構築できる仕組みだと感じています。本記事が、これから導入を検討される方の一助になれば幸いです。
AI ファースト・カンパニーに向けて 株式会社エブリーでCTOを務めている今井( @imakei_ )です。 本記事は AIブログリレー 第10本目 、そして最終回です。7/1から開発部長陣がリレー形式で「組織とAI」について書いてきて、3人で計9本を積み上げてきました。 書いているうちに気づいたのですが、9本はバラバラのトピックを並べたようでいて、実は一つの共通した背骨で繋がっていました。結論から言うと、それは 「オントロジー」 です。会社の現実を人間とAIの共通言語として定義するというこの考え方が、組織・データ・プロダクトという別々のレイヤーで、姿を変えながら何度も顔を出していました。この最終回では、その背骨に沿って全体を振り返ります。 まずは9本の振り返り はじめに、各記事を一言ずつで振り返っておきます。読み返す入口として使ってもらえればと思います。 オントロジーと組織OSとこれからのエンジニア 会社の現実を「名詞・動詞・ルール」として定義し、人とAIが意思決定を回す 組織OS をつくる。これはエンジニア組織が主導すべきで、最初の一歩は社内FDE。 全社のAIファーストを牽引するエンジニアの役割 Claudeの全社導入で「業務に一番詳しい人が作るものが一番使える」状態が生まれた。次はタスク効率化から 業務フローの再設計 へ、個人から組織へ。それを担うのがFDE。 AIエージェントのハーネスとは何か 同じモデルでも実力差が出るのは ハーネス (モデルを実世界のタスクに接続する装備一式)の差。コンテキスト・ツール・権限・検証ループという要素で捉え直す。 AIファーストな組織デザイン 組織OSという「仕組み」に対して、それを動かす「かたち」の話。 少数化 × 事業部アライン(縦の深掘り) × 横のつながり(横の連携) で組織を編む。 組織のAI活用を支えるMCPゲートウェイ 個人の「使ってみる」と組織の「運用する」は別物。MCPが増えると統制と活用の両面で壁にぶつかり、それを支えるのが MCPゲートウェイ というコンセプト。 レガシーシステムをAIでどうアップデートしていくか 単純リライトは機能しない。まず 正しさを定義できる状態 へ。理解する → 検証可能にする(特性テスト)→ 段階的に移行する(ストラングラーフィグ)。 AI活用をどう評価するか 評価指標はフェーズで乗り換える。 TokenMaxxing(使う)→ TokenOptimization(使いこなす)→ アウトカム へ。良い指標ほど、いずれ自らを不要にしていく。 AIエージェントを "動かす" データ基盤 「読ませる」から「動かす」へ。参照できる(メダリオン)→ 解釈を間違えない(セマンティックレイヤー)→ 行動できる(オントロジー) の3ステップ。 AI時代、ソフトウェアは3層で考える 生成が安くなり「作って捨てる」が合理になる。 Core / Connectors / Disposable の境界を引く鍵は、プロダクトの世界観(=オントロジー)を定義すること。 レイヤーによらず、AI時代のテーマは「オントロジー」である 改めて並べてみると、1本目で持ち出した「オントロジー」が、連載の後半で二度、別のレイヤーに姿を変えて再登場しています。 組織のレイヤー (1本目)では、会社の現実を「名詞・動詞・ルール」として定義し、人とAIが意思決定を回す土台にする、という話でした。 データのレイヤー (8本目)では、それが業務のオブジェクト・関係・アクションを機械可読にする、データ基盤の最上段として現れました。参照できる・解釈を間違えない、の先にある「行動できる」を支えるものです。 プロダクトのレイヤー (9本目)では、そのソフトウェアの世界観を定義することが、そのまま「長く残す Core」と「捨てて作り直せる Disposable」の境界を引くことになる、という形で戻ってきました。 同じ考え方が、組織・データ・プロダクトの三段で繰り返し効いてくる。これは事前に設計したわけではなく、書き進めるうちに自然とそうなったものです。裏を返せば、 AIを現実に接地させるという課題は、どのレイヤーでも本質的に同じ形をしている のだと思います。何が中心的な概念で、何ができて、どんな制約があるのか——この「意味の定義」を人とAIで共有できるかどうかが、あらゆる場面で成否を分けていました。 三段で読むと、全体像が見えてくる オントロジーを背骨とすると、9本は大きく三つの塊に分けて読めます。 1つ目は「土台をつくる」話です。 組織OS(1)、ハーネス(3)、MCPゲートウェイ(5)、データ基盤(8)。これらはすべて、AIを実世界のタスクに安全に接続するための装備の話でした。モデルそのものは誰でもAPIで呼べる。難しいのはその先、つまりAIを自社のデータ・権限・業務プロセスに配線し、信頼して任せられる状態まで持っていく部分です。ハーネスはそれを一つのエージェントの単位で、MCPゲートウェイとデータ基盤は組織全体の単位で解こうとした、と整理できます。 2つ目は「組織のかたちを変える」話です。 エンジニアの役割(2)と組織デザイン(4)。AIで一人あたりの成果が変わると、人を増やして解く発想から、少数のチームがAIをレバレッジに事業を丸ごと引き受ける発想へと移ります。縦(事業)で深掘りし、横(職能・AI活用の知見)で編む。そしてその現場で課題定義から実装まで担うのがFDEでした。 3つ目は「つくり方・回し方を変える」話です。 レガシー刷新(6)、評価(7)、ソフトウェア3層(9)。ここに共通していたのは、 AIに任せる範囲と、人間が握り続ける範囲の線引き です。レガシー刷新なら「正しさを定義する判断」、評価なら「指標を乗り換え、廃止する判断」、ソフトウェア設計なら「Coreとして残すものの判断」。手を動かす難しさが、考える難しさへ移っていく、という点で3本は響き合っていました。 ここから、どうAIファーストにしていくか 背骨(オントロジー)と三つの塊で連載全体を整理してきましたが、では ここからエブリーをどうAIファーストにしていくのか 。9本を書き終えて、その方向は二つに定まったと感じています。 一つは、 「個人から組織へ」を進めきる ことです。Claudeの全社導入で、個人のAI活用は一気に進みました。ここからの勝負は、そこで生まれた便利ツールやプロンプト、スキルを個人に閉じたままにせず、共有資産へと育てられるかどうかです。組織OSも、横のつながりも、MCPゲートウェイも、評価指標の組織展開も、狙いはすべて「個人技を組織の力に変える」の一点にあります。個人の「使ってみる」を、組織の「運用する」へ引き上げる——AIファーストへの一番大きな一歩は、ここだと考えています。 もう一つは、 人間の役割を、意思決定と設計へ寄せていく ことです。「決まった仕様を実装する」から「何を意思決定すべきかの土台を整える」へ。実装者から、業務とシステムの両方を握るFDEへ。画面を手で磨く人から、世界観と境界を設計する人へ。AIに任せられる範囲が広がるほど、人間の価値は、Howそのものよりも 「What(何をやるか)」と「Why(なぜそうするか)」を握る ところに移っていきます。AIはHowを高速に片づけられても、WhatとWhyは決められないからです。この重心移動を組織として後押しできるかが、AIファーストになれるかどうかを分けると考えています。 この二つの方向は、どちらも「まだ道半ば」です。実際、ここまで書いてきたことの多くは、正直まだ「これから」の段階でもあります。社内FDEの立ち上げも、MCPゲートウェイの本格運用も、評価指標のTokenOptimizationへの移行も、走りながら具体化している最中です。この連載は完成した答えの発表ではなく、いま自分たちが立っている場所と、これから向かう方向をまとめた地図のようなものだと思っています。 おわりに 一つだけ確かなのは、ここで書いた「仕組み・かたち・つくり方」は一度作って終わりではなく、事業とAIの進化に合わせて組み替え続けるものだ、ということです。指標が役目を終えたら廃止するように、組織のかたちもソフトウェアのCoreも、更新され続ける前提で設計していく。その組み替えの一つひとつが、また次のブログのネタになるはずです。得られた学びは、折を見てまた書ければと思います。 エブリーは「AI ファースト・カンパニー」として、個人のAI活用から組織のAI活用へと軸足を移そうとしている最中です。ここで書いてきたテーマに面白さを感じてくれる方がいれば、ぜひ一緒に手を動かせればうれしいです。 この連載の全記事 オントロジーと組織OSとこれからのエンジニア 全社のAIファーストを牽引するエンジニアの役割 AIエージェントのハーネスとは何か AIファーストな組織デザイン 組織のAI活用を支えるMCPゲートウェイ レガシーシステムをAIでどうアップデートしていくか AI活用をどう評価するか AIエージェントを "動かす" データ基盤 AI時代、ソフトウェアは3層で考える AI ファースト・カンパニーへ —— AIブログリレーを終えて(本記事)
AI時代、ソフトウェアは3層で考える 株式会社エブリーでCTOを務めている今井( @imakei_ )です。 本記事は AIブログリレー 第9本目 です。これまで自分は、組織OSや組織デザイン、AI活用の評価といった「AIを活かす土台」を、主に組織の側から書いてきました。今回はその視点を、作られるソフトウェアの側に移します。 結論を先に言うと、AI時代は ソフトウェアの作り方そのものを変える 必要があり、その鍵は ソフトウェアを3つの層で捉え、「長く残す Core」と「捨てて作り直せる Disposable な部分」の境界をどう引くか にある、と考えています。そしてこの境界を引く作業は、組織の回で触れた「オントロジー」を、今度はプロダクトの世界観として定義していく作業でもあります。難しいですが、だからこそ面白い。順に書きます。 「作って長く保守する」前提が崩れる きっかけは、Tuan-Anh Tran氏の "Architecture for Disposable Systems" という記事です。要点はシンプルで、 コーディングエージェントによって生成が安くなると、ソフトウェアは「作って、使って、捨てる」ものへと変わっていく 、というものです。 これまでは「一度作って、長く保守する」のが当たり前でした。作り直しが高くつくからこそ、丁寧に設計し、負債を返し、長期を見据えて磨いてきた。ところが、エージェントが数分で同等の代替物を作れるなら、その前提は崩れます。生成が安くなると、むしろ「保守し続けること」のほうが高コストになる。壊れたら直すより、捨てて作り直す——そういう作り方が合理になっていきます。 だとすれば、 ソフトウェアの作り方も、この変化に合わせて組み替えないといけません 。全部を等しく丁寧に磨く発想から、「何を残し、何を捨てるか」を設計する発想へ、です。 Core と Disposable の境界を、どう引くか ここが本題です。当然ながら、すべてを Disposable にできるわけではありません。参考記事は、ソフトウェアを三つの層で整理しています。長く生き残る Core (耐久コア=中核のロジックやデータモデル)、それらをつなぐ Connectors (契約=インターフェース)、そしてその上で動く Disposable な層 (UIやグルーコード)です。 大事なのは、 Disposable な部分を安心して捨てたり作り直したりできるのは、Core と Connectors が堅いからこそ 、という点です。逆に言えば、AIに任せられる範囲を広げたい——つまりAIを活かしたい——なら、まず「捨てない中心」をきちんと定義することが先になります。境界が曖昧なままAIに作らせると、捨てていいものと捨てられないものが混ざり、結局作り直せなくなる。 AIを活かすための第一歩は、実は「何を残すか」を決めることなのです。 そしてこの「捨てない中心を定義する」作業は、連載で書いてきた オントロジー の話とそのまま地続きです。組織の回では、会社の現実を「名詞・動詞・ルール」として定義する話をしました。同じことをプロダクトの側でやると、 そのソフトウェアの世界観を定義する ことになります。何が中心的な概念(名詞)で、どんな操作(動詞)が許され、どんな制約(ルール)があるのか。この世界観こそが Core であり、それを外に見せる形が Connectors です。 世界観がきちんと定義されていれば、その上に乗るUIや繋ぎこみは、AIに生成させ、要らなくなったら捨てて作り直せばいい。 世界観(オントロジー)を定義することが、そのまま Core と Disposable の境界を引くことになる ——ここが、組織の話とソフトウェアの話がつながるポイントだと考えています。 とくにアプリ開発では、境界がくっきりする ここまでは一般論ですが、自分の出身でもあるアプリ(モバイル)開発では、この Core と Disposable な層の境界が、より生々しくはっきりします。 サーバーサイドと違い、アプリは 利用者の端末にインストールされ、古いバージョンが世の中に残り続けます 。サーバーのように「作り直して即差し替え」とはいきません。だからこそ、簡単には捨てられない中心が明確です。クライアントとサーバーの通信契約(=アプリにおける Connectors にあたる部分)、ローカルに溜まったデータのスキーマとマイグレーション、認証やセッションといったローカルの状態——このあたりは、Disposable にはできない Core です。ナビゲーションの構造も、Deep Link や通知の入口として外部と繋がっている限りは、簡単には作り変えられない Core 寄りの存在です。逆に、個々の画面やレイアウト、View まわりのコードは、生成して作り直せる Disposable な層に寄っていきます。 つまりアプリエンジニアの価値は、 一枚一枚の画面を手で磨くこと から、 アプリの世界観(ドメインモデル・状態の契約・デザインシステム)を定義すること へ移っていきます。ここで強調したいのは、これまで培ってきたUXやインタラクションへのこだわりが不要になるわけではない、ということです。むしろその感性を、 デザインシステムやコンポーネント、レビューの基準として Core 側に埋め込む 。そうすれば、生成された画面もその基準を満たすようになります。手で守っていた品質を、仕組みとして守る側に回る——これは、アプリエンジニアにとってむしろ面白い変化だと自分は思っています。 ここがいちばん難しい とはいえ、この境界を引く作業はかなり難しい。いくつか挙げます。 まず、 何を Core に置き、何を Disposable に落とすかの線引き そのものが難しい。間違えると、捨てられるはずの場所に大事なロジックが紛れ込み、まるごと作り直す羽目になります。 次に、 Connectors は「完璧に」保ち続ける 必要があります。Disposable 側を雑に作れるのは Connectors が堅いからこそで、「中は AI に任せて雑でいい」と「境界は完璧に」という 非対称な厳しさ を同時に成立させないといけません。 さらに、 データやユーザーの状態は簡単には捨てられません 。UIやロジックは作り直せても、蓄積されたデータや利用者からの信頼は作り直せない。捨てていいものと、絶対に捨ててはいけないものを見極める目が要ります。 そして最大の逆説は、 「作り直せる」前提が、かえって設計判断の重みを増す ことです。実装を磨く負担は減る一方で、「どこに境界を引くか」という判断の一発勝負の重要性が上がる。手を動かす難しさが、考える難しさへ移っていく、とも言えます。 だからこそ、これからのソフトウェアづくりは面白い この難しさは、そのまま面白さの裏返しだと思っています。 エンジニアの腕の見せ所が、 「実装をどれだけ丁寧に磨けるか」から、「世界観を定義し、何を残し何を捨てるかの境界を設計できるか」へ移る 。コードの美しさそのものより、捨てられる構造を見抜いて設計する力が問われる。かなり知的な挑戦であり、設計者としての醍醐味が詰まった仕事です。 忘れてはいけないのは、 Disposable を受け入れることは「雑に作る」ことではない という点です。むしろ逆で、「きれいに捨てられるように、世界観と境界を丁寧に設計する」という、より高度な仕事を求められます。 もう一つ、心構えとして大事なのは、 自分が書いたコードへの執着を手放せるか です。時間をかけて磨いたコードほど、捨てるのは惜しい。でも、これからは「惜しくて捨てられないコード」こそがリスクになり得ます。愛着の対象を、個々の実装から、それを生み出し続けられる世界観や境界のほうへ移していく。作品としてのコードから、更新され続ける仕組みとしての設計へ——この切り替えができる人にとって、これからのソフトウェアづくりはとても面白い時代になると思います。 おわりに AI時代のソフトウェアづくりは、「長く磨き上げる」一辺倒から、「世界観を定義し、Core と Disposable の境界を引く」営みへと変わっていきます。それは簡単ではありませんが、難しいからこそ、考えることそのものが面白くなる。組織で定義してきたオントロジーを、今度はプロダクトの世界観として引き直していく——その境界設計にこそ、これからのソフトウェアづくりの面白さがあると感じています。 出典・参考 本記事における「Disposable Systems」の考え方は、以下の記事を参考にしています。 - Tuan-Anh Tran, " Architecture for Disposable Systems "
こんにちは。開発1部の村上です。 本記事は AIブログリレー 8本目 です。 エブリーではAIエージェントを社内のあらゆる業務で活用していくことを目指しています。そのAIエージェントたちを支えるのがデータ基盤です。そしてこの基盤を、AIにデータを「読ませる」ためのものから、AIエージェントを「動かす」ためのものへ進化させていきたいと考えています。本記事では、そのために必要なステップを整理します。 人のための基盤から、AIエージェントを "動かす" 基盤へ これまでのデータ基盤は、暗黙のうちに「人が使う」前提で設計されてきました。ダッシュボードを見るのも、SQLを書くのも人です。「この売上には手数料が含まれているんだっけ?」という定義の曖昧さも、人が文脈と経験で補完してきました。 利用者がAIエージェントに変わると、この暗黙の補完が効かなくなります。さらにエージェントが増えていくことを前提に立つと、基盤は特定の誰かの道具ではなく、すべてのエージェントが立つ共通の足場になります。足場が曖昧なままエージェントを増やすと、曖昧さの解釈がエージェントの数だけ生まれてしまいます。 さらにAIエージェント時代のデータ基盤は、データを参照して質問に答えるといった、データを「読める」ようにするだけでは不十分だと考えています。データにもとづいて業務の中で行動するエージェントを支える、つまりAIエージェントを「動かす」ところまでを、基盤の責務として考えていく必要があります。 このような基盤には、次の3つのステップがあると考えています。 参照できる : あらゆるデータを収集し、AIが参照可能な状態にする(メダリオンアーキテクチャ) 解釈を間違えない : 指標や用語の意味を一元定義する(セマンティックレイヤー) 行動できる : 業務のオブジェクト・関係・アクションを機械可読にする(オントロジー) 順に見ていきます。 あらゆるデータを集め、AIが参照できる状態にする 最初のステップは、構造化・非構造化を問わずデータを収集し、AIが参照できる状態にすることです。ここで採用しているのがメダリオンアーキテクチャです。 メダリオンアーキテクチャは、データをBronze(生データ)、Silver(クレンジング・整形済み)、Gold(ビジネス利用可能)という層に分けて、段階的に品質を昇格させていく設計です。 (出典: What is a Medallion Architecture? | Databricks ) ポイントは「きれいなデータを一発で作る」のではなく、生データを捨てずに保持したまま、信頼できる状態へ段階的に到達させることにあります。AIエージェント時代には、この層の分離がもう一つの意味を持ちます。エージェントにどの層を見せるかを制御できることです。品質保証されたGold層だけをエージェントの参照先にすることで、生データの揺らぎに引きずられた回答を構造的に防げます。 このステップまで整うと、Text to SQLが動き始めます。「先月のチャネル別売上は?」と聞けばエージェントがSQLを書いて答えてくれる。人が結果を確かめながら使う形であれば、AI活用はここから十分始められます。 ただし、「参照できる」と「正しく解釈できる」の間には溝があります。テーブルとカラムが見えることと、その数字が何を意味するかを理解していることは、別の問題だからです。 AIが解釈を間違えない状態にする 2つ目のステップは、セマンティックレイヤーの整備です。指標の定義、ディメンション、シノニム、用語といったビジネス上の意味を、BIツールやエージェントの側ではなくデータ層で一元的に定義します。 たとえばCAC(顧客獲得コスト)の定義がエージェント間で曖昧だったとします。すると、事業KPI分析エージェントとマーケティングエージェントが異なる計算式のCACを見て動いてしまう、といったことが起こります。しかもどちらのSQLも正しいため、この食い違いに気づくのは困難です。 Goldに計算済みのCACテーブルを置く手もありますが、CACのような比率指標は計算済みの値を再集計できません。「全チャネル合算では?」と粒度の違う質問が来た瞬間、エージェントはCACの平均を取って間違えます。だから必要なのは計算結果ではなく、計算式の定義です。 セマンティックレイヤーは、この定義をデータ層で管理します。Databricksの実装で言えば Unity Catalog Business Semantics がこれにあたります。中核となるmetric viewは、測度(CACの計算式そのもの)と、それを集計するディメンションを分離して定義する仕組みで、SQL・ダッシュボード・エージェントのどこから利用しても、同じ定義から同じ計算が決定的に実行されます。加えて glossaryやdomains といった用語・文脈を整備する機能の発表も続いており、この領域への投資はプラットフォーム側でも加速しています。 効果は数字にも表れています。dbtが2026年に再実施した ベンチマーク では、Text to SQL単体の精度は最新モデルで64.5%まで改善した一方、セマンティックレイヤー経由ではカバーされた質問に対してほぼ100%に到達しています。モデルの進化だけでは埋まらない差が、定義の一元化で埋まるということです。 ここまで整うと、エージェントは指標を正しく計算し、要因を正しく分解できるようになります。「読む」はほぼ完成です。しかし、分析だけではなく行動まで促そうとすると、まだ決定的に足りないものがあります。 AIが行動できる状態にする オントロジーとは何か 3つ目のステップがオントロジーの構築です。このブログリレーの 1本目でCTOも紹介 していましたが、オントロジーとは、業務を構成する オブジェクト (顧客、受注、商品...)、その 関係 、そしてそれぞれに実行できる アクション を、機械可読な形で定義したものです。 もともとオントロジーは知識工学の用語で、古典的にはオブジェクトと関係の記述を指します。エンタープライズの文脈ではPalantirがこれを拡張し、オブジェクト・プロパティ・関係というセマンティックな要素に加えて、アクションという「世界を変更する操作」までをオントロジーに含めています(参考: Palantir Ontology )。 業界の現在地 この領域は、まさに製品化が始まったところです。Databricksも2026年6月のData + AI Summitで独自のオントロジーである Genie Ontology を発表しました(現在プレビュー)。テーブル・クエリ・ダッシュボードから事業の文脈を自動抽出して生きたグラフを構築するもので、Unity Catalogで定義したセマンティクスがこのオントロジーに供給される構造になっています。アクション定義までは含まないかもしれませんが、オブジェクトと関係の自動構築という意味で同じ方向に進んでいます。 複数のエージェントが、同じ地図の上で動く 例として、定期購入型のEC(サブスクEC)でオントロジーの一部を考えてみます。 構成要素は次の4つです。 オブジェクト : 顧客、定期契約、定期受注(第n回の個別のお届け)、商品、在庫引当、配送 関係 : 顧客は定期契約を持つ。定期契約は定期受注を生成する。定期受注は商品を含み、在庫を引き当て、配送に紐づく 状態 : 定期受注は「受付中 → 出荷確定 → 発送済み」と遷移する。「お届け日の2日前に出荷確定へ移る」という締切の定義もここに属する アクション : 各オブジェクトに対する操作。前提条件・効果・権限がセットで定義される 配送先を変更する(前提: 状態が受付中) メニューを差し替える(前提: 状態が受付中、かつ、おまかせコース) 次回分の変更を予約する(対象: 定期契約。いつでも可) このオントロジーの上で、複数のエージェントが動くとどうなるか。同じサブスクECで動くCSエージェントと在庫オペレーションエージェントがいるケースを考えます。ここで見たいのは、互いに無関係な2つの出来事です。ある日、CSエージェントには顧客から「配送先を変えたい」という問い合わせが届きます。一方、在庫オペレーションエージェントの側では、入荷遅延によって木曜出荷分の在庫が不足していました。別々のトリガで、2体はそれぞれ独立に動き出します。それぞれの動きを並べるとこうなります。 CSエージェント 在庫オペレーションエージェント 起きたこと 顧客「配送先を変えたい」 入荷遅延で木曜出荷分の在庫が不足 関係の辿り方 顧客 → 定期契約 → 定期受注 商品 → 在庫引当 → 定期受注 受付中の受注への行動 「配送先を変更する」を実行 「メニューを差し替える」で欠品を吸収 出荷確定済みの受注への行動 「次回分の変更を予約する」に切り替え、「次回分から新しい住所にお届けします」と案内 引当済みのため対象外。手を付けない この2体は、会話もしていなければ、仕事の引き継ぎもしていません。起点も違います。片方は顧客から、もう片方は商品から関係を辿り、同じ定期受注オブジェクトに到達しているだけです。そして2体が共通して参照しているのは、定期受注の「状態」と、その状態を前提条件に持つアクションの定義です。顧客対応と欠品対応という別々の業務が矛盾しないのは、「出荷確定後は変更できない」というルールがアクションの前提条件として基盤に一つだけ存在して、両方がそれを参照しているからです。 ルールを各エージェントのプロンプトやMCPツールの説明文に書けば済む、と思うかもしれません。実際、エージェントが1〜2体のうちはそれで動きます。しかしそれは定義のコピーです。10体に定義がコピーされた世界では、ルール変更のたびに10箇所の改修が発生し、直し漏れたエージェントは旧ルールで動き続けます。API側で変更を拒否することはできますが、それで防げるのは誤った実行までで、エージェントは「変更できますよ」と案内してから実行に失敗する可能性もあるかもしれません。オントロジーはこの知識を参照に変えます。エージェントが何体いても、参照先は1つです。 この構造の強さは、ルールが変わる日にはっきり現れます。出荷締切を前日から2日前に早める、という業務判断が下りたとします。変更するのは基盤上の定義1箇所。その瞬間から、CSエージェントの案内も、在庫オペレーションエージェントの組み替え範囲も、将来作られる何体目かのエージェントの行動も、すべて同時に新しいルールに従います。 3層の上でエージェントを動かす ここまでの3ステップを一度に眺めると、こうなります。ステップ1でデータが見える。ステップ2で数字を正しく読める。ステップ3で「何ができて、実行すると何がどう変わるか」が分かる。 ここまではCSと在庫オペレーションの2体で見てきましたが、この土台の上には、マーケティングエージェント、予実管理エージェント、と業務ごとのエージェントを並べていけます。全員が同じ指標定義を読み、同じオブジェクトとアクション定義の上で動く。データ収集だけを進めてエージェントを増やすと、指標・フロー・ルールの定義が各エージェントのプロンプトへサイロ化していきますが、3層が整った基盤の上では、すべてのエージェントが同じ世界を見て行動します。 エブリーはどう取り組むか エブリーではステップ1にこれまで投資を続けてきており、メダリオンアーキテクチャによる基盤は整いつつあります。ステップ3のオントロジーは技術的にもまだ新しく、すぐに全面適用できる段階ではありません。そこで今期は、ステップ3を意識しながら、ステップ2のセマンティックレイヤーを整備していきます。 このステップ2と3は、アプリケーションのコードと人の暗黙知に散在している世界の定義を、基盤上の宣言的で機械可読な一箇所へ引き上げていく作業です。「CACの計算式」も「出荷確定後は変更できない」という定義も、今この瞬間もアプリケーションの実装の中に、そしてオペレーションを担う人の頭の中に存在しています。 そして、ここが重要なのですが、この作業はデータチームが外から観測するだけでは完遂できません。「締切を何時にするか」「CACに何を含めるか」は、データの中に答えがある問題ではなく、ビジネスの意思決定そのものだからです。セマンティックレイヤーもオントロジーも、技術の問題である以前に、ビジネスと一緒に定義を決めにいく組織の問題です。だからこそ、このリレーの 1本目でCTOが書いた 、エンジニアが事業の中に入ってその基盤を作っていくという話になるのだと思っています。 基盤を育てることと、ビジネスと共に定義を決めること。この両方が揃ったとき、データ基盤はAIにデータを読ませる基盤から、AIエージェントを動かす基盤になります。 さいごに 本記事では、AIエージェントを「動かす」ためのデータ基盤を、参照できる・解釈を間違えない・行動できる、という3つのステップで整理しました。エブリーではこの基盤づくりをこれから本格化させていきます。進捗や学びは、またこのブログで共有していく予定です。 エブリーでは一緒に働く仲間を募集中です! エンジニアブログをきっかけに少しでも興味も持っていただけたら、まずはカジュアルに面談しましょう!
AI活用をどう評価するか —— TokenMaxxing から TokenOptimization へ 株式会社エブリーでCTOを務めている今井( @imakei_ )です。 本記事は AIブログリレー 第7本目 です。自分はこれまで、第1本目で「 オントロジーと組織OS 」、第4本目で「 AIファーストな組織デザイン 」について書いてきました。今回はそれらと地続きのテーマとして、 AI活用をどう評価するか について書きます。 結論を先に言うと、AI活用の評価指標は固定するものではなく、フェーズに応じて TokenMaxxing → TokenOptimization と乗り換えていくもの、そして最終的には役目を終えて廃止すべきもの、だと考えています。 なぜAI活用の「評価」は難しいのか AI活用がどれくらい進んでいるかを測ろうとすると、すぐに壁にぶつかります。従来の生産性指標——コード行数、PR数、ベロシティ——は、AIを前提にするとうまく機能しないどころか、むしろ人をミスリードします。AIが書いた大量のコードを行数で評価すれば的外れですし、逆に「丁寧に少しずつ」を美徳とする指標は、AIに任せる動きにブレーキをかけてしまいます。 さらに厄介なのは、「そもそも、うちのメンバーはAIを使えているのか?」という一次情報すら、最初は曖昧だという点です。評価の設計は、この「まず現状が見えない」ところから始まります。 フェーズ1: TokenMaxxing —— まず「使い倒す」 弊社でCC(Claude Code)の利用ログを分析してまず見えてきたのは、 人間レビュー時代の習慣がAIの伸びしろに上限をかけている という構造でした。小さめのPR、慎重すぎる委譲、なんでも自分の目で最終確認する——CLIの利用時間が短いメンバーほど、この傾向が強く出ます。悪いことではないのですが、これは「人間が全部レビューできる範囲」に成果を縛る動き方で、AIを前提にすると足かせになります。 そこで導入したのが TokenMaxxing です。ざっくり言えば「トークン使用量を思いきり増やせ」という号令で、AIにどれだけ委ねたかを量で可視化し、行動そのものを変えにいく取り組みです。ここで大事なのは、これは あえて粗い指標 だということ。目的は精緻な測定ではなく、旧来の習慣を壊すための強制力(forcing function)です。いまはDatabricks上に利用ログを蓄積している段階で、個人単位での可視化はこれからですが、まずは「使っていい、むしろ使い倒せ」という空気を明確に作りました。 そしてもう一つ重要なのは、 これは半年程度の過渡期に限定した指標 であり、期末には不要になることを最初から織り込んでいる、という点です。TokenMaxxing は永続する評価軸ではありません。 TokenMaxxing の限界 —— 量は価値ではない TokenMaxxing には明確な限界があります。グッドハートの法則、すなわち「指標が目標になると、その指標は指標として機能しなくなる」という問題です。トークンを増やすこと自体が目的化すれば、無駄な生成や過剰な試行が増え、量が成果と乖離していきます。当然、コストも膨らみます。 つまり TokenMaxxing は、「使う」が当たり前になるまでの、期間を区切った指標です。使用が日常になった瞬間から、量を追うことは無駄を生む方向に反転します。だからこそ、次のフェーズへ乗り換える必要があります。 フェーズ2: TokenOptimization —— 「使いこなす」へ 次のフェーズが TokenOptimization です。ここでの軸は「量」から「質」へ、言い換えれば トークンあたりのアウトカム(value per token) へと移ります。同じ成果を、より少なく、より賢く出す方向です。 具体的には、タスクに応じたモデル選択(軽い作業に重いモデルを使わない)、コンテキストの効率化、harnessやスキル・サブエージェントの整備、そして「どこまでAIに委ね、どこは人が持つか」の見極め、といった話になります。 そしてここで効いてくるのが、これまでの連載で書いてきた土台です。第1本目のオントロジー・組織OSが整っているほど、AIは現実に正しく接地でき、少ないやり取りで的確に動きます——接地は、それ自体が最良の最適化です。また、有効だったプロンプトやスキルを個人に閉じず、第4本目で書いた「横糸」(勉強会・横断コミュニティ)で共有することで、TokenOptimization は個人技ではなく 組織の共有資産 になります。使いこなしは、横で流通させて初めて組織の力になります。 評価指標は「廃止する前提」で設計してもいい Token Maxxing から Token Optimization、アウトカムへの移行 ここまでを一段引いて眺めると、見えてくる原則があります。 過渡期の評価指標は、行動が定着したら廃止する前提で設計しておくと扱いやすい 、ということです。 TokenMaxxing は「使う」を、TokenOptimization は「使いこなす」を、組織に定着させるための指標です。定着すれば、その指標はもう見なくてよくなります。最終的に見るべきなのは、トークンのような手段の指標ではなく、事業に接続した アウトカム です。たとえば「ある事象の検知から、判断・実行・システム反映までが何分で回るか」といった、意思決定のループそのものの速さ。ここへ収斂させていくのが理想だと考えています。 裏を返せば、良い過渡期の指標には共通の条件があります。①行動をはっきり変えられること、②多少粗くてよいこと、そして③終了条件(いつ廃止するか)が決まっていること、です。廃止を前提にしない指標は、いつの間にか目的化して組織を縛ります。 おわりに TokenMaxxing で「使う」を、TokenOptimization で「使いこなす」を組織に定着させ、最後はトークンで測ること自体をやめて、事業のアウトカムで測る。評価指標を固定の正解として崇めるのではなく、フェーズに合わせて設計し、乗り換え、役目を終えたら廃止していく——これがAI活用の評価に対する、いまの自分の考え方です。 指標は、組織を導くための道具であって、目的ではありません。良い指標ほど、いずれ自らを不要にしていくものだと思います。
開発2部の内原です。 本記事は AIブログリレー 第6本目 です。 長く運用されてきたシステムというものは、様々な背景からいわゆるレガシー化していることも多いと思います。またそのシステムを担当していく際、多くの場合で似たような問題が発生します。 仕様書が古い or 存在しない 最初に実装したメンバーがいない テストがない このような開発・運用・保守しづらい状況だと、抜本的な対策をしたいが動かなくなるリスクを考慮して、都度継ぎ足し継ぎ足しの改修を繰り返すことになり、結果としてより開発・運用・保守が辛くなるという負のループに陥ることが多いと思います。 最近は生成AIがコードを書くのが当たり前の状態になっています。なので、AIに丸ごとリライトさせるということも不可能ではなくなっています。 しかし結論から言うと、レガシーシステムの刷新において単純なリライトでは機能しないことが多いと考えています。 この記事では、なぜそのような結論になるのかを整理したうえで、AIをレガシー刷新のための魔法としてではなく、理解と段階的移行を促進する道具として使う現実的な進め方を考えてみます。 なぜレガシー刷新は難しいのか そもそもなぜレガシーシステムの刷新は難しいと言えるのでしょうか。理由を分解すると、AIの使用未使用に関わらず共通している本質的な問題があります。 全体像を誰も把握していない=正しい仕様が不明 動いているコードだけが唯一の正であり、本来どう動くべきかを判断できる人がいない テストがない=正しさの基準がない リライト結果の動作が正しいものかどうかを判定する手段が存在しない 暗黙の依存・歴史的経緯が随所に残っている 一見特に重要ではないと思われるコードが、実は特別な処理のために必要だったりする ここで共通しているのは、これらがいずれも正しさを定義できていないことに起因している点です。 AIにリライトさせても、その結果が正しいかどうかを検証できなければ意味がありません。AIはそれっぽいコードを高速に大量生産することができますが、それが元の挙動を保っている保証はどこにもないためです。 つまりレガシー刷新においてまず行うべきことは、いきなりリライトすることではなく、正しさを定義できる状態に持っていくことです。 以下、その順序を3つのステップで見ていきます。 まず理解にAIを使う AIの最初の使いどころは、書くことではなく読むことです。レガシーコードの最大の問題は前述のとおり誰も全体を把握していないことなので、ここを埋めるのにAIは非常に向いています。 具体的には、次のような用途です。 コードの挙動説明 特定の関数やモジュールが何をしているのか、自然言語で要約させる 依存関係の可視化 どのモジュールがどこから呼ばれているか、影響範囲を洗い出させる デッドコード候補の洗い出し 到達不能なコードや、もはや使われていない分岐の候補を挙げさせる ポイントは、ドメイン知識を持つ人間と、横断的に大量のコードを読めるAIの分業が可能になる点です。 AIはコードが何をしているか(How)を高速に説明してくれますが、なぜそうなっているか(Why)は知りません。例えばある特殊処理が特定顧客向けの実装だった、といった背景です。AIに挙動を説明させ、人間がその背景知識と照らし合わせて確認していくことで、正しい仕様の確定を早めることができます。 ここで得た理解は、後のステップで何を保証すべきかを決める土台になります。 検証可能にする 理解が進んだら、次はリライト前の安全対策を実施します。テストがないコードをリライトするのはリスクが高いので、まず現状の挙動を固定するテストを用意します。 ここで有効なのが特性テスト(Characterization Test)という考え方です。これは正しい仕様をテストに書き起こすのではなく、現状のコードが今出している出力をそのまま期待値として固定するという手法です。レガシーコードでは正しい仕様が分からないので、ひとまず現状の挙動を基準にし、リライト後もそれが変わらないことを保証する、という発想です。 このようなテストの雛形づくりはAIが得意とするところです。入力と出力のパターンを大量に列挙させ、テストコードの雛形を量産させる。ただし、どのテストが妥当か、何を保証すべきかを判断するのは人間の仕事です。AIが生成したテストには、たまたま現状のバグまで正しい挙動として固定してしまうものも混ざります。それを取捨選択するのは背景を知る人間にしかできません。 この段階の本質は、正しさをAIや機械が判定できる形に問題を変換することです。一度テストという形で正しさが定義できれば、以降のリライトはテストが通るかという機械的に検証可能な問題に変えることができます。ここまで来て初めて、AIによるリライトが安全に回せるようになります。 段階的に移行する 安全対策が実施できたら、いよいよリライトです。ただしここでも一括リライトは避けます。大きな単位を一度に置き換えると、問題が起きたときに切り分けや切り戻しが難しくなるためです。 原則は、小さい単位に分解して、少しずつ置き換えることです。代表的なのがストラングラーフィグパターンで、新旧のコードを並行稼働させ、機能単位で徐々に新しい実装へ切り替えていく手法です。フィーチャーフラグで新旧を切り替えられるようにしておけば、問題が出てもすぐ元に戻せます。各ステップは小さく、テストを通し、差分をレビューできる大きさに保ちます。 このとき、変更を2種類に切り分けると見通しがよくなります。 機械的変換で済む部分 構文の置き換え、APIの一括リネーム、フォーマット統一など 決まったルールで変換できるものは、機械的ツール(codemodのような)やAIに任せやすい 意味的判断が必要な部分 データ構造の設計変更、業務ロジックの再構成など なぜそうするかの判断が伴うため、人間の関与が必要 AIは、前者を高速に処理し、後者においてはテスト補強や選択肢提示で人間を支援する。この両輪が機能することで、少しずつ移行を進めることが可能になります。 AIと人間の責任境界 ここまで見てきたとおり、レガシー刷新ではAIに任せていい部分と、人間が握り続けるべき部分とがあります。以下にその線引きを整理しておきます。 AIが苦手とするのは、次のような領域です。 暗黙の業務ルール コードには現れない、運用でカバーされている前提 なぜそうなっているかの歴史的背景 過去の障害対応や顧客対応の名残 影響範囲の見積もり 失敗したとき被害がどこまで及ぶか そして何より気をつけるべきは、一見もっともらしく動いているように見えて、実は元の挙動を微妙に変えてしまうような誤変換が発生し得ることです。テストが不十分なら、それも通り抜けてしまいます。これを見抜けるのは、背景を理解し、最終的に判断責任を持つ人間だけです。 自動化してよい判断と人間が最後に責任を持つ判断との線引きを意識する、AIを信用しすぎない、これがレガシー刷新でAIを安全に使うための重要なポイントと考えます。 参考:リファクタ実施例 ここまでの3ステップ(理解する → 検証可能にする → 段階的に移行する)を、実際に運用中のレガシーシステムで試してみたので、ステップに沿って紹介します。 ステップ1:まず理解する 最初に考えたのは、何を守れれば挙動が変わっていないと言えるのか、という点です。 今回のリライトで守りたかったのは、個々の関数やクラスの挙動というよりも、リクエストを受けてからレスポンスを返すまでの統合的な挙動でした。 Webサーバの設定やルーティング、フレームワークを経由した一連の処理は、単体テストの粒度では確認しきれません。単体テストを足していくやり方では抜け漏れが発生するリスクがありました。 そこで、アプリを一つの箱とみなし、HTTPリクエストという入力と、返ってくるレスポンスという出力だけで挙動を固定する方針にしました。これならWebサーバからフレームワークまでを通した実際の挙動をまるごと対象にできます。 これはまさに前述した特性テストの考え方そのものです。 ステップ2:検証可能にする 守るべき対象が決まったので、それを機械的に検証できる形にします。 ここで採用したのは、アプリをHTTPの外側から叩き、レスポンスを記録しておき、リライト後に同じ入力で照合して差分が出ないことを確認する Golden Master Testといわれる手法です。以下のような利点があると考えました。 アプリを改修せず、現状のまま丸ごと検証できる システム全体を一つのブラックボックスとして確認するので、テストのために内部を分割・差し替え可能にするような改修が不要になる 検証ツールがアプリの言語・フレームワークに依存しない HTTPさえ動けばよく、ツール側を別の言語で書いても成立する なおこの方式は記録したリクエストの分しか挙動を担保できない、という網羅性の限界があります。実際に叩いた経路しかカバーされないので、どのケースを記録対象に選ぶかという設計の判断が重要です。 実際にテストを実装し始めると安定しない要因が次々と出てきました。以下のようなものが実際にありました。 A/Bテストによる画面の出し分け そもそもA/Bテストの実装が入っていることを把握していなかった(テスト自体は当然終了しているはず) 出力がリクエストごとに変わるため、入力となるCookieを固定して結果を決定化した 日時に依存する挙動 時刻を凍結する拡張を導入し、日付に依存するページを再現可能にした 認証に依存する挙動 認証を前提とする箇所は、認証を突破するテスト用実装を追加(テスト環境でのみ有効) こうした調整を経て、公開ページや、認証前提の複数フローの導線、登録系ページについて自動的に検証できる状態まで到達できたと言えます。リライトの前後で、外部から見た挙動が変わっていないことを機械的に保証する安全機構を獲得できたことになります。 ステップ3:段階的に移行する(今後の予定) この時点では、一部のエンドポイントに安全機構を用意できたという段階で、ここから先こそが本題のリライトになります。 (というわけで現時点ではリライトできたという状況ではありません) 安全網ができたことで、小さい単位で置き換えてはテストで差分がないことを確認する、という段階的な移行が可能になります。 検証対象のエンドポイントを徐々に広げていくという、こうしたテストの横展開はまさにAIが得意とするところです。 まとめ レガシーシステムの刷新におけるAIの本質は、理解の加速と、検証可能な単位への分解の支援にあります。簡単にリライトしてくれる銀の弾丸ではないことがほとんどでしょう。 しかし、これまで仕様が分からない、テストがない、どこから手をつければいいか分からない、といった理由で腰が重かった刷新作業の速度を大きく上げられるのは確かです。 読んで理解し、安全対策を実施し、小さく置き換えていく、またその一連の流れをAIで加速する。そのような使い方をすることで、これまで手が出せなかったレガシーシステムに少しずつ手を入れていけるようになることがAIを利用する利点であると考えています。
こんにちは。開発1部の村上です。 本記事は AIブログリレー 5本目 です。 弊社ではすでに 全社共通ゲートウェイによる社内リモートMCPサーバー を構築したり、それをもとにMCPを社内で内製して多くの社員が使っていたりと、社外の公式MCPの利用も盛んになっています。本記事では、今後組織のMCP活用が拡大するとぶつかる課題を整理し、それを支える基盤としてのMCPゲートウェイというコンセプトについて書きます。 MCP is deadは本当か 基盤の話に入る前に、そもそもMCP自体必要でしょうか。今年2月末、 「MCP is dead. Long live the CLI」 という記事が反響を呼びました。LLMはCLIとドキュメントさえあれば勝手にやれる、認証は aws sso login や gh auth login という実績あるフローで済む、MCPサーバーは初期化が不安定で再認証が終わらない、権限の制御も粗いという主張です。日々Claude Codeを使っている人ほど、思い当たる内容だと思います。 一方で、GitHubのMCPサーバーを開発するエンジニアは、 MCP Dev Summit NA 2026の講演「MCP vs CLIs」 で、この論争が過熱していたまさにその時期にMCPの利用は急増しており、GitHub MCPサーバーは過去最大の週間利用量を記録したと語っています。「死んだ」と言われるものが、史上最も使われている状態なわけです。 CLIで十分か 改めてMCPとCLIの違いを整理してみます。 CLI MCP 設計の向き先 人間向けに設計済みのコマンド AI向けに設計されたツール・リソース モデルとの相性 学習データに豊富。パイプで合成できる スキーマで型が明確。素朴な全部載せはコンテキストを圧迫 認証・権限 トークン権限を全て委譲。 gh auth token などで露出し、環境変数から漏れやすい OAuth 2.1。ツール単位で操作面を絞れ、トークン権限をモデルから隔離できる 利用者・環境 シェルがある環境。主に開発者個人 リモート・非エンジニアにも届く 象徴的なのは認証です。CLIではトークンにできることはエージェントにもすべてできてしまう。しかも gh auth token 一発でトークン自体が露出します。一方でMCPのOAuthフローはトークンをモデルから隔離し、ツール単位で操作面を絞れます。 結局のところ、この論争は道具の優劣ではなく環境に依存してしまいます。CLIが成立するには、認証・権限・監査という関心事をOSの権限モデルと個人の責任が引き受けられる環境が必要です。数百人が複数のクライアントを使い、非エンジニアも含まれ、監査要件がある組織では、この前提が崩れます。個人は「使ってみる」で完結しますが、組織は、そこから「運用する」ことが求められます。そうなると組織がAIを活用していく上でMCPのメリットは十分にあり、引き続き有用な選択肢となっており、組織でどうMCPを管理していくかは重要なテーマだと思っています。 あらゆるシステムがMCPとしてエージェントと繋がる 増えるMCPサーバーとAIエージェント エブリーでは現在、外部MCPと社内MCPを合わせて数十程度のMCPが設定され、使われています。とはいえ、まだまだ発展途上だと思っており、エージェントに仕事を任せる範囲が広がるほど、CRM、チケット管理、社内Wiki、データ基盤と、社内外のあらゆるシステムがMCPを通してエージェントと接続されていきます。Uberでは、社内の1万を超えるサービスのエンドポイントをMCPツールとして公開できる状態まで到達しています( AAIF公式ブログ )。 そして増えるのはMCPサーバーの数だけではありません。呼び出し元も人間がClaudeを使うときにMCPを呼ぶだけでなく、社内で作られたエージェントが自らの判断でMCPを呼ぶようになります。定常業務を回す常駐エージェント、夜間にスケジュール起動するエージェント、コードを書き続けるバックグラウンドエージェントなど数百、数千の社内エージェントが、当たり前に稼働している未来が想像できます。 今はまだこのエージェントやMCPサーバー自体を増やしていき業務をエージェントに委譲することに注力していますが、同時にそれを推進することで新たに二つの課題に直面していくと考えています。 課題①: 統制が効かなくなる 一つ目は統制面です。誰がどのMCPサーバーに繋いでいるか分からない。各自のmcp.jsonに認証情報が散らばり、退職者のトークンがどこで生きているか追えない。エージェントに渡した権限が適正かを検証する仕組みがなく、何かが起きたときに「誰の委任で、どのエージェントが、何をしたか」を再構成できない。 エージェントに強い権限を渡せば、誤動作ひとつで本番データの削除や誤送信が起き、セキュリティ面ではエージェントそのものを禁止したくなります。かといって安全側に倒して権限を必要最小限まで削れば、今度は誰の役にも立たないエージェントになり、投資が回収できません。人間が誤操作で壊せる範囲には手間という上限がありますが、ループで動くエージェントにはそれがなく、簡単に大きな被害が出るインシデントを起こしかねません。だからこそ、それぞれのエージェントに何をさせられるかを管理できることが、組織のAI活用では大切になってきます。 課題②: 活用が進まなくなる 二つ目は活用面です。ここで言う活用とは、エージェントが正しくツールを選べること(精度)、社員が使い始められること(導入の手間)、そして改善が回ること(計測)の3つを指します。 まず精度という観点ではツール定義はそれ自体がコンテキストを消費します。数百のツール定義の読み込みだけで何万ものトークンを消費することもあります。ユーザーが何かを言う前に、この量が流れ込むのです。MCPが増えれば、モデルは進化しているとはいえ本題より先にツールの説明を読むことになり、選択を誤り、遅く、高く、不正確になります。 また、導入の手間という観点ではMCPが増えるほど、サーバーごと・ユーザーごとにOAuth認証を通したり、設定ファイルを書く作業は、非エンジニアも含めた全員の活用を考えると障壁になりえます。最後に計測という観点ではどのツールがどう誤選択され、どこで失敗しているかが見えなければ、ツール定義を改善するループが回りません。 MCP運用におけるゲートウェイというコンセプト 重要なのは、これらの課題がMCPというプロトコルの欠陥ではないことです。MCPが標準化したのは「どう話すか」だけであり、誰が・誰の権限で・何を・どこまで使い・誰がそれを見ているかという運用の関心事は、意図的に規定していません。だから薄く、速く普及しましたが、組織活用ではこの問題を解かないといけません。 その実装として業界が向かっているのが、MCPゲートウェイです。承認済みサーバーのカタログ(レジストリ)と、全トラフィックが通る中継点(ゲートウェイ)という構成です。レジストリが「何を使ってよいか」を定義し、ゲートウェイが「実際にそう使われているか」を実行時に強制する、という役割分担で、多くの製品はこの二つをセットで提供しています。2026年4月の MCP Dev Summit では多くの企業がMCPゲートウェイの上で社内のAI活用を推進しており、もはやそれを前提とした上でゲートウェイに関する機能の発表も多い印象です。Uberは 自社のエンジニアリングブログ でも、すべてのエージェントとサービスの間にMCP Gatewayを置き、呼び出し元の認証とツール実行の認可を通過したリクエストだけを下流に中継する構成を解説しています。 MCPゲートウェイが目指しているところ 何ができるのか ではゲートウェイは何ができるのか。業界で合意されているのは構成の型までで、機能の切り分けは各社各様です。今回は各社の実装を横断して、6つに整理します。 # 機能 統制面 活用面 1 単一経路化(集約) 野良MCPの遮断、統制点の一元化 1エンドポイントの追加で適切な権限範囲の全ツールに接続完了 2 認証・認可・シークレット管理 トークンの集中保管と即時失効 各自のOAuth設定が不要になる 3 ツール単位のポリシーとガードレール 削除系の禁止、引数の固定、レートリミット、PII検査 用途ごとに安全な形でツールを開放でき、自律的なエージェントやAI活用を促進 4 レジストリ(カタログ) 承認済みサーバーだけが流通する 「何が使えるか」を全員が発見できる 5 ツールの絞り込み・変換 モデルに見せる操作面そのものを縮小 必要なツールだけを動的にロードしコンテキストを削減 6 可観測性・監査 誰の委任で何が実行されたかの証跡 誤選択・失敗の計測とツール定義の改善 MCPゲートウェイはセキュリティ対策のみで切り取られがちですが、どの機能もAI活用自体を支える重要な役割を果たしていることがわかります。例えば認証仲介は、セキュリティ文脈ではトークン管理の話ですが、利用者から見れば効率的なオンボーディングの話です。ツール絞り込みは、統制文脈では操作面の縮小ですが、精度文脈ではコンテキスト削減そのものです。こうした安全な仕組みを作ってLLMに判断させない箇所を増やすことが、統制であると同時に信頼性の向上にもつながっていきます。 ユーザーの権限は「上限」であって「適正」ではない 各MCPサーバーがOAuthでユーザーを認証し、本人の権限の範囲で動く委任実行は正しい土台で、仕様もその方向に進んでいます。エージェント経由で本人以上の権限が使える、という権限昇格型の事故はこれで原理的に防げます。 しかし、ユーザーの権限は「上限」であって「適正」ではありません。自分の全メールを削除できますが、エージェントにそうさせたいわけではありません。エージェントは非決定的で、ハルシネーション1回の誤操作も「本人の正当な操作」として実行されます。必要なのは「このエージェントに許された操作」と「このユーザーの権限」の積集合を実行時に毎回評価することであり、自己規律に頼れない以上、この評価はエージェントの外側で行うしかありません。ゲートウェイとは、この評価を全リクエストに対して行う場所です。 現時点での技術的な選択肢 最後に、全てではないですが、このコンセプトを実装する際の現時点(2026年中期)でのゲートウェイを一部紹介します。 名前 特徴 agentgateway Linux Foundation傘下のOSS(Apache 2.0)。MCP/A2A対応のデータプレーンで、集約・ポリシー・可観測性が骨格の中立インフラ ToolHive Stacklok開発のOSS(Apache 2.0)。コンテナ隔離ランタイム・仮想MCPゲートウェイ・公式Registry API互換のレジストリサーバーまで揃うプラットフォーム型 Obot ゲートウェイ+カタログ+RBACを管理UI込みで提供する製品型OSS(MIT/オープンコア) AWS AgentCore Gateway AWSのマネージドサービス。セマンティック検索によるツール絞り込みが特徴で、既存API/LambdaのMCP化も担う Databricks Unity AI Gateway Databricksのマネージドサービス。Unity Catalogの権限モデルとエージェントトレーシングの延長でMCPを統治できる 選定の観点は既存スタックとの整合、運用体制で変わってくると思いますが、まだまだこの領域自体も発展途上なのでプレイヤーが大きく変わることも予想されます。 おわりに 今回はエージェントやMCPが組織で増えていった際にどういったことを考えないといけないのかを先行している企業の事例や技術的なトレンドから整理してみました。 エブリーでも今後エージェントを量産していきますが、その歩みを止めないためには、MCPゲートウェイのような基盤側の整備を同時並行で進めることが重要になります。エンジニア組織として、こうした基盤の構築を進めながら全社のAI活用を支えていきたいと思っています。 AIブログリレーは、このあとも開発部長陣が続けていきます。次回もぜひご覧ください。 エブリーでは一緒に働く仲間を募集中です! エンジニアブログをきっかけに少しでも興味も持っていただけたら、まずはカジュアルに面談しましょう!
AIファーストな組織デザイン 株式会社エブリーでCTOを務めている今井( @imakei_ )です。 本記事は AIブログリレー 第4本目 です。第1本目の「 オントロジーと組織OSとこれからのエンジニア 」(以下、前回)では、会社の現実を共通言語(オントロジー)として定義し、その上で人とAIが意思決定を回す「組織OS」を、エンジニア組織が主導して作っていく、という話を書きました。 今回はその続きとして、 AI時代の組織デザイン について書きたいと思います。組織OSという「仕組み」の話に対して、今回はそれを動かす「組織のかたち」の話です。結論から言うと、これからの組織は、 より少数で、事業にアラインし、その上で横のつながりを別途つくる ——という方向に向かうと考えています。 なぜ今、組織のかたちを問い直すのか 大前提として、AIによって一人あたりが生み出せる成果の量が大きく変わりました。これまでは「解きたい課題が増えたら、人を増やして対応する」のが基本の発想でしたが、AIを前提にすると、同じ課題をより少ない人数で解けるようになってきています。 この変化は、単に「生産性が上がった」で終わる話ではありません。 人を増やして解く時代の組織のかたちと、少数×AIで解く時代の組織のかたちは、そもそも設計思想が違う はずだ、というのが今回の出発点です。前回の組織OSが「AIが動ける土台」の話だったとすれば、今回はその土台を最大限に活かす「人の並べ方」の話だと捉えてください。 1. より少数な組織にする まず向かうべきは、少数化です。 人を増やすと成果が増える、という関係はAI以前から必ずしも成り立っていませんでした。人が増えれば増えるほど、コミュニケーションのコストや調整の手間が増え、意思決定は遅くなります。いわゆる「人を足したら余計に遅くなる」現象です。 AIを前提にすると、この構図はさらにはっきりします。これまで人手で埋めていた領域をAIに任せられるようになるほど、 人数を増やさずに対応できる範囲が広がる からです。だとすれば、やみくもに人を増やすのではなく、少数のメンバーがAIをレバレッジとして使い、一人あたりの担当範囲を広げていく方が、速くて強い組織になります。 ここで大事なのは、少数化は「人を減らすこと」が目的ではない、という点です。目的は、一人ひとりが事業の課題から実装までを見通せる状態をつくること。前回触れた社内FDE(現場に入り込み、課題定義から手を動かすエンジニア)が成立するのも、少数で担当範囲が広いからこそです。少数化とFDE的な動き方は、セットで効いてくると考えています。 2. 事業部にアラインした組織にする 次に、組織の切り方です。 エンジニア組織を「iOS」「バックエンド」「インフラ」といった職能で切る方法は、専門性を高めるうえでは合理的でした。ただこの切り方だと、一つの事業を前に進めるたびに複数の職能をまたいだ調整が必要になり、意思決定のたびに受け渡しが発生します。 弊社はデリッシュキッチン・トモニテ・retail HUBと複数ドメインのプロダクトを展開しており、職能ではなく 事業(ドメイン)にアラインした組織構造 をとっています。この組織へは1年ほど前に移行することを決め、すでに運用を始めています。1年前はあくまで仮説に基づくチャレンジ的な位置付けでしたが、1年動かしてきたうえでこの考え方が足元では正しかったと確信みたいなものを感じています。 この「事業(価値の流れ)にアラインした少数チーム」は、チームトポロジーで言う ストリームアラインド・チーム 、Spotifyモデルで言う スクワッド(Squad) にあたります。弊社の組織は、チームトポロジーをベースにしつつ、Spotifyモデルの教訓を取り込む形で設計しています。チームの人数を「ピザ2枚で足りる規模(5〜9人)」に抑えるのも、少数化と同じ狙いです。 なお、チームトポロジーにはこのほかに、共通基盤を担う プラットフォーム・チーム や、動画処理・機械学習などを扱う コンプリケイテッド・サブシステム・チーム もあります。本記事ではそこには踏み込まず、「縦=ストリームアラインド」と、後述する「横=イネイブリング/チャプター」の2つの軸に絞って話します。 この切り方には、AI時代に効く理由がいくつかあります。 一つは、意思決定のループが一つのチームの中で完結しやすいこと。「検知して、判断して、実行して、システムに反映する」という一連の流れが、職能をまたがずに閉じるので、少数でも速く回せます。 もう一つは、前回のオントロジーの話と地続きだという点です。組織OSの土台となるオントロジーは、「事業の現実(=名詞)」を中心にモデルを切ります。組織そのものが事業にアラインしていれば、チームの境界とオントロジーの境界が自然と揃う。エンジニアが事業のすぐ近くに座っているからこそ、現実に即した「名詞・動詞・ルール」を定義でき、社内FDE的な動きも構造的に成立します。 少数化と事業部アラインは、組み合わさって初めて力を持ちます。少数のチームが、一つの事業を丸ごと、課題定義から実装まで引き受ける。これがAI時代の基本ユニットになると考えています。 3. 横のつながりを、勉強会などで意図的につくる ここまでの「少数×事業部アライン」には、当然ながら弱点があります。 職能の知見が縦割りに分断されやすい という点です。 iOSエンジニアが各事業部に散らばると、iOS全体の知見をどう蓄積し、共有するのかが弱くなります。事業ごとに最適化が進む一方で、「あの事業部で解いた課題を、別の事業部がまた一から解いている」といった車輪の再発明が起きやすい。組織を縦(事業)で切ると、横(職能・技術)の糸が細くなるのは避けられません。 これを補うのが、 横のつながりを意図的につくる場 です。職能ごとの勉強会や、技術テーマごとの横断コミュニティといった、縦の組織図とは別のレイヤーの糸を通す。ここは自然発生に任せず、意図的に設計することが重要だと考えています。事業部アラインにすると横のつながりは「放っておくと消える」ものになるからです。 これは、Spotifyモデルが残した教訓とも重なります。スクワッドに自律性だけを与えた結果、サイロ化や車輪の再発明、全体最適の欠如といった問題が生まれた——という話です。「自律」だけでは組織は立ち行かず、意図的な横の連携という「ガードレール」が要る。Spotifyモデルの チャプターやギルド 、チームトポロジーの イネイブリング・チーム が担っていたのは、まさにこの横糸の役割です。弊社でも、縦(事業)に寄せた組織だからこそ、横糸を意図的に設計することを次の一手と位置づけています。 そしてAI時代には、この横糸を通す対象がもう一つ増えます。 AI活用の知見そのもの です。有効だったプロンプトや、業務を自動化するスキル、エージェントの使いこなし方——こうしたノウハウは、各事業部に閉じていると全社では育ちません。前回、組織OSの文脈で「便利ツールを共有資産へと育てる」という話をしましたが、その資産を横で流通させる場が、まさにこの横のつながりです。縦で事業を深掘りし、横でAI活用と技術知見を流通させる。この二層で組織を編むイメージです。 全体像:縦で深掘りし、横で編む 整理すると、こうなります。 少数化 で、一人あたりのレバレッジと担当範囲を広げる 事業部アライン で、少数のチームが事業を丸ごと、速く回す(縦の糸) 横のつながり で、職能の専門性とAI活用の知見を全社に流通させる(横の糸) 縦だけでは知見が分断され、横だけでは事業が進まない。両方を意図的に設計して初めて、少数でも強い組織になると考えています。そしてこの組織のかたちは、前回書いた組織OSと補い合う関係にあります。組織OSがAIに任せられる領域を広げるから少数化が成り立ち、事業部アラインだからオントロジーを現実に即して定義でき、横のつながりがAI活用の知見を共有資産へと育てる。仕組み(組織OS)と組織のかたちは、片方だけでは機能しません。 おわりに AI時代の組織デザインを、自分は「少数で、事業に張りつき、横で編む」という言葉で捉えています。人を増やして課題を解く発想から、少数のチームがAIをレバレッジに事業を丸ごと引き受け、横のつながりで知見を流通させる発想へ。これは一度作って終わりではなく、事業やAIの進化に合わせて組み替え続けていくものだと考えています。 前回の組織OSと合わせて、「仕組み」と「組織のかたち」の両輪で、AIファーストな組織づくりを進めていきたいと思います。 参考 Spotifyモデル: https://www.atlassian.com/ja/agile/agile-at-scale/spotify チームトポロジー: https://www.atlassian.com/ja/devops/frameworks/team-topologies
開発2部の内原です。 AIエージェントを使って開発していると、同じモデルを使っているはずなのにツールやエージェントによって賢さがまるで違う、という体験をすることがよくあります。モデルそのものは変わらなくても差が出る理由を考えてみます。 その差を生んでいるのが、モデルを取り巻く装備、いわゆるハーネスです。ハーネスという言葉はなんとなく使われがちですが、何を指しているのかは意外とふわっとしています(少なくとも自分の理解は割と曖昧でした)。 この記事では、この言葉を構成要素に分解して、何がエージェントの実力を決めているのかを整理してみます。 エブリーにおけるAIエージェントの活用状況とハーネスの必要性 先日の 村上からの投稿 全社のAIファーストを牽引するエンジニアの役割 でも言及がありましたが、エブリーでは今年から全社的にClaudeの活用を進めてきました。 それ以前からも特に開発部においてはCopilotやCursorなどのAIエージェントが利用されていましたが、当初は主にコーディング用途に使われていました。それが、開発部に閉じない業務改善、業務遂行のためにAIが用いられるようになってくると、エンジニアの役割も単なる実装者から、よりプロダクトや業務の理解を求められるようになり、業務フロー全体を考慮したオーケストレーションを実施する必要がでてきました。 その中で、より自律的なAI活用のためにはハーネスが重要になってくると考えています。AIに対しどのように振る舞うべきかを伝える必要があるためです。 なお、ハーネスの考え方自体はあらゆるAIエージェントに共通しますが、本記事では話を具体的にするため、特に開発で使うコーディングエージェントを念頭に置いて進めます。 モデル単体とハーネスの違い まずLLM単体は何をするものなのかを考えます。LLMは、突き詰めれば入力テキストに対して出力テキストを返すだけの関数であると言えます。それ自体ではファイルを読むことも、コマンドを実行することも、前回の作業を覚えていることすらできません。 一方実用的なAIエージェントは、そのモデルの周りに情報を渡す仕組みや道具、結果を確かめる仕組みを組み合わせ、それらを繰り返し動かしています。この一式をまとめてハーネスと呼びます。本記事では、ハーネスについてモデルを実世界におけるタスクに接続するための装備一式であると定義します。 ハーネスという言葉は、もともとは犬や馬のような対象に取り付けてその力を御し、目的の方向へ引き出すための装具を指します。ソフトウェアにおいても意味合いは同じく、テスト対象を動かすためのテストハーネス(スタブ、ドライバなど)のように、中心にある対象を制御して動かすための周辺の仕組みを指してきました。 AIエージェントのハーネスも同じで、モデルそのものではなく、その力を制御して実世界のタスクに向かわせるための装備だと捉えると分かりやすいです。 ハーネスを構成する4つの要素 ハーネスを、コンテキスト、ツール、権限・実行環境、検証ループの4つの要素に分けて見ていきます。 ただこれらの分類は絶対的なものではなく、目的や環境に応じて変化し得るものではあります。下記では汎用的に有効と思われるアプローチを考えます。 コンテキスト(何を渡すか) モデルに渡す情報の取捨選択です。モデルはコンテキストに入っている情報しか処理できないので、必要な情報をいかに過不足なく届けるかが重要です。 ただし、多ければよいというわけではありません。不要なものも大量に含めてしまうと、肝心の情報が埋もれて精度が落ちることになります。 関連するファイルやドキュメントのパスを渡す 長い履歴は要約して圧縮する 過去の経緯はメモリとして持たせ、必要なときに参照させる 過去の経緯を覚えておくメモリも、結局はその時々でモデルに渡すコンテキストの一部です。何を入れ、何を入れないかを設計することがコンテキストという要素の肝になります。 ツール(何ができるか) ファイルの読み書き、コマンド実行、検索、外部APIの呼び出しなど、モデルが現実の世界に働きかけるための道具です。 ツールがあって初めて、テキストを生成するだけのモデルが実際にコードを書き換えたり、テストを実行したりできるようになります。このとき、ツールの粒度や説明をモデルが正しく選択できる状態になっているかによって精度は大きく変動します。利用方法や目的が曖昧なツールだと、モデルに誤った使い方をされやすくなります。 権限・実行環境(どこまで許すか) ツールを与えるということは、モデルに実環境を触らせるということです。そのため、どこまでを自動で許すかの設計が必要になります。 サンドボックスで隔離する、権限モードによって実行範囲を絞る、破壊的な操作の前には確認を挟む、といった仕組みがこれに該当します。自動的に実行される範囲を広げるほど待機時間は減りますが、想定していない現象が発生したときの被害も大きくなります。 速さと安全のトレードオフの設計が重要です。 検証ループ(どう確かめるか) モデルの出力が正しいかどうかを、機械的なフィードバックとしてモデルに戻す仕組みです。テスト結果、型チェック、lint、実際に動かしたときの出力検証などがこれに該当します。 結果の検証が可能かどうかで成果は大きく変化します。検証ループの速さと確かさは、エージェントの賢さの大きな要因です。 4つの要素を動かすもの 4つの要素はいわば部品なので、これらを組み合わせて実際に仕事をさせるには、部品を方向づけ繰り返し動かす仕組みが必要です。 システムプロンプト モデルに対し、どのような役割、どのような方針で動いてほしいかを伝える指示です。 役割やルール、守ってほしい制約をあらかじめ与えるこの指示もハーネスの一部と考えることができます。ここではその場限りの指示を毎回書くのではなく、ハーネスの一部として作り込んでおく対象に変わったと言えます。 エージェントループ 部品をつなぎ、実際にタスクを前に進めるのがエージェントループです。考える→ツールを使う→結果を観測→考える、という繰り返しの制御フローを指します。 このループによって一度の応答で終わらず、失敗を踏まえて何度もやり直しながらゴールに近づくことができます。同時に、いつ止めるか、何回までやり直すかといった歯止めの設計も重要です。終了条件がなければエージェントは延々と動き続けてしまいます。 全体像と具体例 ここまでの要素を図にすると、おおよそ次のような関係になります。 Claude Code でいうと もう少し具体的に、コーディングエージェントのClaude Codeに当てはめてみます。 一般的なAIエージェントは自前でハーネスを構築していることが多いため、ユーザーが用意するファイル群はハーネスの一部にすぎず、ツールやループといった土台はClaude Code本体が提供しているという点に注意が必要です。 ユーザーが用意する層 コンテキスト CLAUDE.md、メモリ、作業中に渡すファイル システムプロンプト CLAUDE.md やスキルで与える役割・方針 権限・実行環境 settings.json でのツール許可やサンドボックスの設定 Claude Code本体が提供する層 ツール ファイルの読み書き、検索、コマンド実行、MCPなど 検証ループ hooks やテスト実行の仕組み エージェントループ 考える→ツール→観測→また考える、を回す中核 ただしこの線引きは必ずしも固定されていません。本体が提供する層であっても、検証ループは hooks やテスト実行の指示で何をいつ確かめるかを、エージェントループは進め方の指示で振る舞いを、ユーザー側からある程度調整することができます。 たとえばCLAUDE.mdには、方針(システムプロンプト)や参照(コンテキスト)に加えて、検証や進め方の指示も書けます。1つのファイルが複数の要素に対応していることになります。 # CLAUDE.md ## 方針(システムプロンプト) - コミットメッセージは英語、conventional commits 形式で書く - 既存コードのスタイルに合わせる ## 進め方(エージェントループ) - 大きな変更は、まず計画を示してから実装する ## 検証(検証ループ) - 変更後は npm test と npm run lint を必ず通す - テストが落ちたら、修正してから完了とする ## 参照(コンテキスト) - API仕様は docs/api.md を参照する 権限・実行環境のほうは .claude/settings.json などで設定します。 { " permissions ": { " allow ": [ " Read ", " Edit ", " Bash(npm test) " ] , " deny ": [ " Bash(rm:*) " ] } } これらはいずれもハーネスの一部です。ツールやループといった土台はClaude Code本体が担っており、両者を合わせて初めて一つのハーネスとして機能することになります。 AI-DLC との関係 最近では、AWSが提唱するAI-DLC(AI-Driven Development Life Cycle)のように、AIを中心に据えた開発方法論も出てきています。AgileやScrumに代わる開発プロセスそのものを再設計しようとするものです。 ポイントとしては、こうした方法論はハーネスの上に乗る上位のレイヤーであるということです。AI-DLCが掲げるAIが計画して人間が承認し実装に進むという流れも、成果物を蓄積して引き継ぐ仕組みも、各作業単位で良いハーネスが組まれていることが前提になっています。 このような方法論を導入してもうまくいかないとしたら、その下のハーネスが整っていない可能性があります。 まとめ AIエージェントの賢さとは、モデルとしての性能が全てではなく、コンテキスト、ツール、権限・実行環境、検証ループといった環境に左右されます。 AIエージェントを使いこなすうえでは、ハーネスの設計がエンジニアに求められる重要なタスクになると考えています。
こんにちは。開発1部の村上です。 本記事は、エブリーの開発部長陣がリレー形式で組織とAIについて書いていく「AIブログリレー」の第2本目です。 第1本目で、CTOの今井が 「オントロジーと組織OSとこれからのエンジニア」 という記事を書きました。会社の現実を人間とAIの共通言語として定義し、その上で意思決定が回り続ける「組織OS」を作る。そしてその組織OSづくりはエンジニア組織が主導すべきであり、最初の一歩として社内FDE(Forward Deployed Engineer)を立ち上げる、という内容です。 エブリーは 「AIファースト・カンパニー」 を掲げています。AIを単なる業務効率化ツールではなく、あらゆる領域で私たちの力を増幅してくれる存在と捉え、働き方もプロダクトもAIを前提に変えていく。この方針のもと、全職種でのAI活用を進めてきました。 本記事では、その現場で実際にどうAI活用がされているのか、AIファーストを実現するためにエンジニアは何をしていくべきかを書いていきます。全社のAIファーストを推進していくことは、自社プロダクトの開発と並行して、エンジニアが価値を出すべき領域になってきています。そしてその領域を牽引していくことこそが、エンジニアが業務ドメインに深く入り込み、社内FDEとして動くことだと考えています。 Claudeの全社導入で起きたこと エブリーでは今年の2月ごろから、段階的にClaudeの全社導入を進めてきました。対象はエンジニアに限りません。営業、マーケティング、CX、広報、クリエイターまで、全職種です。 導入後の変化は、数字にはっきり表れています。OpenTelemetryで計測している非エンジニア職のClaude Codeのアクティブユーザー数は、導入当初から約4倍に拡大しました。今ではエンジニア全体よりも多くの人がClaude Codeを活用しており、チャットでの利用にとどまらず、非エンジニアがClaude Codeを使いこなし、チームで作ったスキルをGitHubで管理する運用まで、エンジニア組織の外側で自然に立ち上がっています。 活用の中身も、当初想定していた文章作成やリサーチの域を越えています。 自然言語でデータに問い合わせ、自分の業務の分析を自分で回す レポート作成のような定型業務を仕組み化し、実際に事業成果へつなげる 手作業では年単位かかる規模の作業を、自動化ツールに置き換える コードを書いたことのないメンバーが、自分の業務に合わせた専用のダッシュボードや業務ツールを自分で作る こうした事例が、特定の部署に限らず全社のあちこちで同時多発的に生まれています。 そして、これらを横から見ていて感じるのは、 その業務に一番詳しい人が作るものが、一番使えるものになる ということです。 当たり前のことかもしれません。しかし、これまではそれが実現できていませんでした。業務に精通した人は、業務上の課題も、何が事業にとって重要なインパクトを持つのかもよく知っています。それでも自分では作れないため、エンジニアに依頼するしかなかった。そしてその過程で、やりたいことの意図や、言葉にしきれない業務上の肌感覚が抜け落ち、絶妙に求めているものと違うものが出来上がる。業務をやる人と作る人が分かれていたからこそ起きていた問題です。 AIによって「作ること」のコストが下がり、この壁は急速になくなりつつあります。分析ダッシュボードや業務効率化ツールの開発において、「エンジニアにしか作れないもの」は確実に減ってきています。価値の源泉が、実装できることから、業務を知っていることへ移り始めている。これが、全社導入から数ヶ月の現場で起きている変化です。 タスクの効率化から、業務フローの再設計へ この変化により、単一のタスクの効率化にとどまらず、業務の中で連続する複数のタスクをまとめて圧縮する動きも進み、業務時間そのものが削減されています。 そして、活用がここまで進んだからこそ、エブリーは次のステージも見えてきました。 これまで速くなってきたのは、既存の業務フローを構成する個々のタスクです。一方で業務フローそのものは、AIが存在しない前提で、多くの人間が関わることを前提に設計された当時のまま残っています。次は工程の並びと役割分担そのものをAI前提で組み直す番であり、エブリーの現状はタスクレベルの活用が中心だからこそ、ここには大きな伸びしろが残っています。 実際に、ここで大きな差が生まれることを示すデータがあります。 McKinseyの The State of AI(2025年11月版) :AIを利用する企業は 88% に達した一方、AIから大きな価値(EBIT=利払前・税引前利益の5%以上)を実現できている企業は 約6% にとどまる 同調査の2025年3月版 :検証した25の組織的要因のうち、生成AIのEBITインパクトに最も大きく効いたのは「ワークフローの根本的な再設計」だった つまり、AI活用の成果を分けるのはツールの導入量ではなく、業務フローそのものをAI前提で組み直したかどうかだ、ということです。 これは、冒頭で紹介したAIファースト・カンパニーの方針とも重なります。CEOの吉田が 社内に向けて語った のも、まさにこのことでした。 多くの人間が関わることを前提として設計された既存のオペレーションに対して少しずつAI対応を進めても、働き方の大きな変化を得る可能性は低いです。多くの場合は、1からAIを前提としたオペレーションを設計し直す必要があります。 タスクレベルの活用で得た成果は入口であって、本丸はその先にあります。エブリーが真の意味でAIファーストになっていくために越えるべきマイルストーンは、次の2つだと考えています。 AIを前提とした業務フロー全体の再構築 : 個々のタスクの効率化ではなく、どの工程をAIに任せ、どこで人が判断するのかという前提から業務を組み直すこと AI活用の、個人から組織への標準化 : 現状の活用は個人のスキルとツールに依存しています。これを組織として標準的に使え、学習し、育てていける基盤にすること そして、この2つを推進する役割こそが、冒頭で述べた社内FDEだと考えています。 FDEという役割 FDE(Forward Deployed Engineer)とは、顧客の現場に深く入り込み、その業務を理解したうえで、自社のプロダクトを軸にシステムを組み上げ、成果が出るまで伴走するエンジニアのことです。Palantirが確立した役割で、同社では一時期、FDEの数がプロダクト側のソフトウェアエンジニアを上回っていたほど、事業の中核を担ってきました。 なぜAI時代に求められるのか 生成AI時代に入り、OpenAIやGoogle、Microsoftといった代表的な企業が相次いでFDE組織の立ち上げや大規模な採用を進めるなど、この役割はいま世界的に再注目されています。 なぜこれほど求められているのか。モデル自体はAPIで誰でも呼べるようになった一方で、本当に難しいのはその先、つまりAIを企業ごとのデータ・権限・業務プロセスに接続し、信頼して任せられる状態まで持っていく部分だからです。そしてこの仕事には、業務を知っていること(何が正しく、どこが本当の課題か)と、システムを作れること(それをどう実装し、安全に動かすか)の両方が必要です。片方の知識だけでは成立しません。 さらに、前のセクションで見たとおり、AIで大きな価値を出すには既存の業務にAIを足すのではなく、業務フロー自体を再設計する必要があります。業務に深く入り込み、業務とシステムを一体で作り変えられるエンジニア。FDEへの需要の高まりは、AI活用の主戦場がモデルを作ることからAIモデルがフルに活用できるように業務や基盤を作り変えることへ移ったことの表れだと捉えています。 社内FDEという考え方 エブリーでは、このFDEの動きを社内にも向けます。事業部の業務に深く入り込み、AIを前提とした業務フローへの再設計を、業務とシステムの両面から進めていく。これが、冒頭から述べている社内FDEです。 もっとも、エンジニアが社内の業務に関わること自体は、これまでもやってきました。では何が違うのか。立ち位置と責任範囲が変わります。 これまでの社内向けの開発は、事業部が設計した業務フローを前提に、その中で使う一部の業務効率化ツールを作ることが中心でした。業務フロー自体は所与のもので、エンジニアが担うのはツールを完成させるところまでです。 社内FDEは、この立ち位置を変えます。Forward Deployedという名前のとおり、エンジニアが業務の現場に出ていき、課題の特定と業務の再設計から関わります。どの工程をAIに任せ、どこで人が判断し、そのためにデータや既存システムをどう作り変えるかまでを、業務側で携わるビジネスメンバーと一緒に決めていく。作る対象は業務フローの中の一部のツールではなく業務フロー全体であり、責任を持つ範囲はツールの完成ではなく、業務が実際に変わり、成果につながるところまでです。 なぜ社内FDEをエンジニアがやるのか 1本目で今井は、組織OSづくりをエンジニア組織が主導すべき理由を、組織の観点から4つ挙げていました。ここでは業務フローの再構築という現場の目線から、私の考えを重ねます。 タスクレベルの改善であれば、担い手はその業務に一番詳しい人です。それが一番使えるものになることは、いまエブリーの現場で起きている変化として紹介したとおりです。 しかし、業務フローの再設計となると、業務に詳しいだけでは踏み込めない領域が出てきます。業務側から見えているのは、画面と手順、つまり業務フローの表側です。表側だけを見ていると「この画面をこう改善する」までしか描けません。一方エンジニアは、社内基盤・社内ツール・自社プロダクトの裏側まで、システムの全体像を一気通貫で把握しています。裏側のデータ構造やシステム間の連携まで分かっていれば、「そもそもこの工程は要らない」「ここはAIに渡せる形にデータ構造から作り直そう」と、より広く、根本から設計できます。 実際、AI導入が最後につまずくのは決まって現場の業務・データ・既存システムであり、そこを日常的に握っているのもエンジニアです。業務の作り変えをいちばん深く、いちばん速く進められる位置に、すでに立っています。 一方で、これは「エンジニアだけでできる」という意味ではありません。業務フローの再設計にはその業務の解像度が不可欠で、それを持っているのは業務の当事者です。だからエブリーでは、社内FDEを、ビジネス側とエンジニア側でタッグを組んだプロジェクトとして進めます。 現在地と、これから FDEの活動としてではないですが、直近でも確かな手応えがすでにあります。 全社共通ゲートウェイによるセキュアな社内リモートMCPサーバー を整備したり、既存サービスの保有しているデータをMCPサーバーとして展開するだけでも、すでに現場でAIに任せられる業務は格段に増え、非エンジニアによるAIへの委譲が進んだ実感があります。 これらはいわば、業務の外側からAIとの接続を配線してきた取り組みです。だとすれば、業務の内側に入り込み、業務フローそのものと一体で配線し直せば、そのレバレッジはさらに大きくなるはずです。それを検証しにいくのが、社内FDEだと考えています。 必要に応じて今後は以下のような整備を横断して取り組んでいきます。 散らばったデータの意味を揃え、人もAIも同じ意味で扱える状態にするデータ基盤(セマンティックレイヤー) 社内のシステムやデータへ、安全に読み書きできる操作の層(MCP、API) 個人の環境に依存しない、権限と監査の効いたエージェントの実行基盤 AIに業務を渡せる形への、既存システムやデータ構造そのものの組み替え これらは一度作って完成するものではなく、業務に入り込むたびに磨き上げていく、社内FDEの道具であり成果物です。 ただし、どの業務から、どの粒度で手をつけるかを、机上で決めきるつもりはありません。どの工程が本当のボトルネックで、どのデータが現場で信用されているのかは、業務の中に入って初めて分かることだからです。ロードマップがあって社内FDEが動くのではなく、社内FDEが現場で掴んだものがロードマップになる。この順序で進めていきます。 社内FDEとして意識すること 最後に、社内FDEとして業務に入っていくうえで、大切にしたいと考えていることを3つ書きます。 1次情報を取りに行く 1つ目は、業務を1次情報で理解することです。 これまでのやり方の延長では、誰かが整理した資料や、又聞きの説明で業務を理解したつもりになってしまいます。しかし、整理された情報からは、業務フローを再設計するうえで本当に重要な情報やニュアンスが抜け落ちています。資料には書かれない例外処理、担当者が無意識にやっているリカバリー、数字に表れない現場の判断。再設計の勘所は、たいていそこにあります。 FDEの原点であるPalantirには、FDEがFBIの捜査官の隣に座り、捜査のプロセスをその場で観察しながらシステムを組み上げていったといった話もありますが、社内FDEも同じで、泥臭く現場に出て業務を観測し、向き合う業務を行っている人と同じ解像度になるところまでやる。ドメインに深く入り込むとは、具体的にはこういうことだと考えています。 御用聞きにはならない 2つ目は、現場に深く入り込みながらも、言われたものをそのまま作る存在にはならないことです。 現場の要望には必ず理由がありますが、要望の形をそのまま実装することが最適とは限りません。その裏にある本当の課題は何か、業務フロー全体で見たときにどこを変えるのが根本的か。業務の当事者と同じ解像度に立ったうえで、システムの全体像を知る者としての選択肢を出し、一緒に決めていく。 深く入り込むからこそ、頼まれたものを作る関係に流れやすくなります。そこで踏みとどまって業務フロー全体の再設計に立ち返れるかどうかが、社内FDEと従来の社内ツール開発の分かれ目だと考えています。 アウトプットではなく、アウトカムを追う 3つ目は、作ったものではなく、変わった業務で成果を測ることです。 MCPやエージェント、ダッシュボードを作ること自体は手段にすぎません。その先で業務はどれだけ圧縮されたのか、それによって事業の数値にどう貢献できたのか。そこまで追いかけて、初めて社内FDEの仕事は完了します。 作ること自体の満足に流れないために、社内FDEのプロジェクトには、アウトプットの完成ではなくアウトカムの指標を置きます。先に紹介したMcKinseyの調査が示すように、AIは導入しただけでは大きな価値につながりません。成果から逆算して業務に入り、成果で締める。この規律は、動きが自由なぶんだけ強く持つ必要があると考えています。 おわりに AIによって「作ること」のコストが下がり、エブリーの現場では、業務に一番詳しい人が自分の道具を自分で作る変化が起きています。実装が民主化されていくこれからの時代に、エンジニアの価値は、業務の裏側までを理解したうえで「何を、なぜ作り変えるのか」を描き、実現できることに移っていきます。 だからこそエンジニアが業務ドメインに深く入り込み、社内FDEとして業務フローの再構築と、AI活用の個人から組織への標準化を牽引していく。それがエブリーの目指すAIファーストへの道であり、これからのエンジニアの大きな価値の出しどころだと考えています。 この転換はまだ始まったばかりです。完成した仕組みの上で働くのではなく、業務とシステムをどう作り変えるかを描くところから関われる。エンジニアにとって、これほど面白いフェーズはなかなかないと思っています。興味を持っていただけた方は、ぜひ一度お話ししましょう。 AIブログリレーは、このあとも開発部長陣が続けていきます。次回もぜひご覧ください。 エブリーでは一緒に働く仲間を募集中です! エンジニアブログをきっかけに少しでも興味も持っていただけたら、まずはカジュアルに面談しましょう!