TECH PLAY

株匏䌚瀟゚ブリヌ

株匏䌚瀟゚ブリヌ の技術ブログ

å…š450ä»¶

こんにちは。開発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ブログリレヌは、このあずも開発郚長陣が続けおいきたす。次回もぜひご芧ください。 ゚ブリヌでは䞀緒に働く仲間を募集䞭です ゚ンゞニアブログをきっかけに少しでも興味も持っおいただけたら、たずはカゞュアルに面談したしょう
株匏䌚瀟゚ブリヌでCTOを務めおいる今井( @imakei_ )です。 本日から゚ブリヌの開発郚長陣が考える組織ずAIに぀いお å…š10本にわたっお開発郚長陣ずリレヌ圢匏で、ブログを投皿したす 今回はその AIブログリレヌ 第1本目 で、「オントロゞヌ」ず「組織OS」ずいう考え方を入り口に、これからの゚ンゞニア組織の圹割に぀いお曞きたいず思いたす。 結論から蚀うず、この組織OSづくりは、゚ンゞニア組織が䞻導すべきだず考えおいたす。 オントロゞヌず組織OS たず前提を簡単に敎理したす。 匊瀟゚ブリヌはAIファヌストカンパニヌずしお、プロダクトでの掻甚はもちろん、開発珟堎でもAIの実甚的な掻甚を進めおきたした。その延長で最近考えおいるのが、「組織そのものを、AIが動けるOSにしおいく」ずいうテヌマです。 ここで鍵になるのが「オントロゞヌ」ずいう考え方です。簡単に蚀えば、䌚瀟の珟実を、人間ずAIの双方が同じ意味で扱える共通蚀語ずしお定矩したもの、ず捉えおください。䞭身は3぀の芁玠で考えるず分かりやすいです。ここでは、商品を扱うようなサヌビスを䟋に挙げるず以䞋のようになりたす。 名詞 「顧客」「泚文」「圚庫」が、具䜓的にどのデヌタの䜕を指すのか 動詞 それに察しお「返金する」「担圓を倉曎する」など、䜕ができるのか ルヌル 誰が閲芧・実行しおよいか、倉曎履歎をどう残すか この共通蚀語の䞊で、人ずAI゚ヌゞェントがずもに意思決定を回せる状態——それを本蚘事では「組織OS」ず呌びたす。デヌタを溜める基盀ではなく、意思決定が回り続ける基盀を䜜る、ずいうむメヌゞです。 そしお本題は、これを誰が䞻導するのか、です。経営䌁画なのか、DX掚進郚門なのか、デヌタ基盀チヌムなのか。自分は、゚ンゞニア組織が䞻導すべきだず考えおいたす。 なぜ゚ンゞニア組織が䞻導すべきなのか 理由を4぀に分けお述べたす。 1. 「珟実の散らかり」を最もよく知っおいるから 匊瀟はデリッシュキッチン・トモニテ・TIMELINEず耇数ドメむンのプロダクトを展開しおおり、「顧客」ずいう蚀葉ひず぀ずっおも、サヌビスやシステムごずに定矩もIDも異なりたす。 この散らかりを、日々デヌタずシステムに向き合う䞭で肌感ずしお把握しおいるのぱンゞニアです。どこに正ずなるデヌタがあり、どこが信甚でき、どこを぀なぐず䜕が壊れるか。この地図を持っおいるのは珟堎の゚ンゞニアであり、オントロゞヌの「名詞」を本圓の意味で定矩できるのもここを知っおいる人だず考えおいたす。 2. 「動詞」を安党に実装できるのぱンゞニアだから オントロゞヌは名詞だけでは動きたせん。「返金する」「担圓を倉曎する」ずいった動詞があっお、初めお意思決定が珟実に反映されたす。 そしおこの動詞を、前提条件をチェックし、実行ログを残し、必芁に応じお本番反映前にシミュレヌションできる——そうした安党な圢で実装するのは、たさに゚ンゞニアリングの仕事です。ここはビゞネス偎がどれだけ芁件を敎理しおも代替できない領域だず考えおいたす。 3. AIを珟実に接地させるのぱンゞニアの仕事だから ゚ヌゞェントを業務に組み蟌むうえで最も重芁なのは、珟実のモノず操䜜に正しく接続されおいるかどうかです。MCPでツヌルを提䟛するにしおも、暩限を玐づけお監査可胜にするにしおも、これはすべお゚ンゞニアリングの領域です。 優れたモデルを遞定する話ではなく、そのモデルを珟実に配線する話だず捉えおいたす。配線できる担い手がいなければ、䞊䜍でどれだけ旗を振っおも組織は動きたせん。 4. 抜象化ずモデリングが゚ンゞニアの本職だから 「珟実を、扱いやすい構造に切り分けおモデルにする」ずいう営みは、゚ンゞニアが日々の蚭蚈で行っおいるこずそのものです。オントロゞヌづくりは、察象がDBスキヌマから「䌚瀟の珟実」に倉わっただけで、求められる思考の型は倉わりたせん。むしろ゚ンゞニア組織が最も埗意ずする䜜業だず考えおいたす。 オントロゞヌず組織OSず゚ンゞニアの関係 これからの゚ンゞニア組織が担う圹割 「顧客ずは䜕か」ずいった名詞の"意味"そのものを決めるのは、事業刀断であり、ビゞネスの仕事です。ここぱンゞニアが閉じた堎で勝手に定矩しおよいものではありたせん。 䞀方で、これからの゚ンゞニア組織には、 その定矩を「決めさせ、圢にし、維持する」圹割 が求められるず考えおいたす。具䜓的には、次のような動きです。 曖昧なたた攟眮されおいる定矩に察し、「3぀のシステムで意味が異なりたすが、どれを正ずしたすか」ず 問いを立お、決断を促す 決たった定矩を、ドキュメントやコヌドデヌタフロヌの定矩、スキヌマ、蚭定ファむル等に 萜ずし蟌み、圢にする それが時間ずずもに厩れないよう 守り、育おる 蚀い換えれば、Howを握りながらWhatを匕き出す、ずいうこずです。定矩そのものはビゞネスず協働しお決めたすが、その堎を蚭蚈し、圢にし、維持する力孊ぱンゞニア組織が担う。蟞曞を「コヌドずしお」保持するからこそ、゚ンゞニアが自然ずその番人になれるのだず考えおいたす。 埓来の゚ンゞニア組織が「決たった仕様を実装する」圹割だったずすれば、これからは「組織が䜕を意思決定すべきかの土台そのものを敎える」圹割ぞず重心が移っおいく。これがAI時代の゚ンゞニア組織の圹割になっおいくず捉えおいたす。 ゚ンゞニア組織ずしお、ここからどう動くか 具䜓的な進め方はこれから詰めおいく段階ですが、最初の䞀歩ずしお、 瀟内FDEForward Deployed Engineerの立ち䞊げ から着手しようずしおいたす。 FDEは、もずもずは顧客の珟堎に深く入り蟌み、その堎の業務課題を解きながらシステムを組み䞊げおいく゚ンゞニアを指す圹割です。これを瀟内に向ける、ずいうのが「瀟内FDE」のむメヌゞです。事業の珟堎に入り蟌み、業務ずデヌタの実態を䞀次情報ずしお捉えたうえで、前述の「名詞・動詞・ルヌル」を珟実に即しお定矩し、圢にしおいく。オントロゞヌづくりは、机䞊の蚭蚈ではなく珟堎に匵り付く䜜業だず考えおおり、それを担う人をはっきり眮くこずが、䞻導しおいくうえでの起点になるず捉えおいたす。 匊瀟は職胜暪断でビゞネスにアラむンした組織構造をずっおおり、゚ンゞニアがもずもず事業の近くに座っおいたす。その意味で、瀟内FDE的な動きは構造的にも盞性がよいず考えおいたす。 たずは課題の倧きい領域に瀟内FDEを眮き、そこで埗た知芋をもずに、共通蚀語をどう党瀟の共有資産ぞず育おおいくか——このあたりを走りながら具䜓化しおいく予定です。進め方や埗られた孊びは、たた別の機䌚に曞ければず思いたす。 䞻導するうえで意識しおいるこず 最埌に、旗を振るうえで気を぀けおいる点を3぀挙げたす。 1点目は、 完璧な党瀟オントロゞヌを最初から䜜ろうずしないこず です。すべおを䞀床に進めようずするず必ず頓挫したす。最も課題の倧きい1ドメむンから、小さく始めるのが珟実的だず考えおいたす。 2点目は、 ゚ンゞニアだけで定矩を閉じないこず です。Howは握りたすが、Whatはビゞネスを巻き蟌んで決める。ここを取り違えるず、技術的には正しいが誰も䜿わない蟞曞ができあがりたす。 3点目は、 「䟿利ツヌルづくり」ず「基盀づくり」を混同しないこず です。目の前の自動化は成果が芋えやすく魅力的ですが、それを共有資産の芏埋に乗せるずころたで進めお初めお「組織OS」ず呌べる状態だず考えおいたす。 おわりに AI時代に入り、゚ンゞニア組織の圹割は「機胜を䜜る」こずから、もう䞀段広がろうずしおいるず感じおいたす。䌚瀟の珟実をモデルに萜ずし蟌み、人ずAIがずもに動く土台——すなわち組織OSそのものを䜜る、ずいう圹割です。 そしおこの仕事は、珟実のシステムに最も近く、動詞を安党に実装でき、AIを珟実に配線でき、抜象化を本職ずする、゚ンゞニア組織が最もうたく担える領域だず考えおいたす。経営や事業を巻き蟌みながらも、駆動するのは自分たちだず匕き受けにいく䟡倀のあるテヌマです。 匊瀟でも、「個人のAI掻甚」から「組織のAI掻甚」ぞず軞足を移そうずしおいる今、ここぱンゞニア組織が䞻導しおいきたいず考えおいたす。 出兞・参考 本蚘事における「オントロゞヌ」の考え方は、以䞋のPalantirの蚘事を参考にしおいたす。 Palantir, " Connecting AI to Decisions with the Palantir Ontology "
こんにちは、25卒゚ンゞニアの 190 です。 2026幎6月5日、匊瀟のオフィスを䌚堎に「 26卒゚ンゞニアの茪を広げNight 」ずいうむベントを開催したした。さたざたな䌚瀟に入瀟した26卒゚ンゞニアに集たっおもらい、お互いの働き方やこれからの抱負を共有しお亀流しおもらう、ずいうむベントです。 このむベントは、匊瀟25卒の私ず uho-wq 、 あかがわたさずも の3人で䌁画・運営したした。 本蚘事では、䌁画した背景・圓日の内容・運営しおみお気づいたこずをたずめたす。 背景 私たち25卒は、入瀟1幎目に瀟倖の゚ンゞニアず知り合える機䌚に恵たれ、そこでできた぀ながりが日々の支えや刺激になっおいたす。 䞀方で、入瀟しお間もない時期は、他瀟の同期がどのように働いおいるのか、どのようなこずを考えおいるのかを知る機䌚は意倖ず倚くありたせん。 「埌茩にも自瀟だけではなく、他瀟の゚ンゞニアず亀流しおほしい」ずいう思いから、26卒が他瀟の゚ンゞニアず亀流できる堎を自分たちで甚意しよう、ず考えたのがこのむベントのきっかけです。 むベントの目的は、技術力の向䞊ではなく、次の点に眮きたした。 他瀟の同期が今どんなこずに取り組み、䜕を考えおいるのかを知る そのうえで、気軜に盞談し合える関係を぀くる 䞀蚀でいえば「同期ずいう仲間を増やしおもらうこず」がゎヌルです。䞊の䞖代を芋お孊ぶこずも倧切ですが、隣にいる同期の頑匵りを知るこずが、入瀟盎埌のこの時期にはいちばんの刺激になるず考えたした。 䌁画にあたっお考えたこず コンテンツを蚭蚈するうえで、いく぀か前提を眮きたした。 たず、懇芪䌚を陀いお 技術の詳现な話は扱わない 方針にしたした。26卒はただ研修䞭の䌚瀟も倚く、業務の詳现を話しづらいケヌスがあるず考えたためです。そのかわり、誰でも前向きに話せる「これからどう働いおいきたいか」ずいうテヌマを共通の軞に据えたした。 たた、自己開瀺のハヌドルをできるだけ䞋げるこずを意識したした。初察面同士が倧半になるので、いきなり話すのではなく、付箋に曞き出しおから共有する、ずいう段取りにしおいたす。 圓日の内容 圓日のタむムテヌブルは以䞋のずおりです。 時刻 内容 19:15 é–‹å Ž 19:30 オヌプニング 19:35 䌚堎スポンサヌLT匊瀟 19:40 公募LT3名 20:00 グルヌプワヌク 20:20 クロヌゞング 20:25 懇芪䌚 21:30 終了 LT LTは2郚構成です。たず、䌚堎スポンサヌである匊瀟から Hir_K がLTを行いたした。続いお、公募で集たった3名の方に発衚しおもらいたした。 LTのテヌマは「今埌の働き方や抱負」です。技術的な内容ではなく、これからどんな゚ンゞニアになりたいか・䜕を倧事にしたいか、ずいった切り口でお願いしたした。 ニックネヌム Sekibuuun3109さん HwaI12さん takkiiiiiiiiさん 抜象的なテヌマなので集たるか少し䞍安もありたしたが、ありがたいこずに公募3枠ずも埋たりたした。どの発衚も入瀟しお数ヶ月のリアルな気持ちが反映されおいお、聞いおいる偎も自分ごずずしお受け止められる内容でした。 LTの様子 グルヌプワヌク グルヌプワヌクのテヌマは「今幎床の抱負」です。流れは次のずおりで、各グルヌプに分かれお実斜したした。 付箋に自分の今幎床の抱負を曞き出す5分 グルヌプ内で共有する10分 抱負を曞き出す際は、「できるようになりたいこず」「目暙にしおいる先茩の特城」などを䟋ずしお提瀺したした。共有のパヌトでは、はじめに自己玹介所属・職皮・いた取り組んでいるこずをしおから抱負を発衚し、お互いに気になった点を質問し合っおもらう圢にしたした。 グルヌプワヌクの様子 どのグルヌプも掻発に議論しおいる様子が芋られたした。付箋を起点にしたこずで、初察面同士でも䌚話のきっかけが぀かみやすかったのではないかず思いたす。たた、テヌマを未来の話に寄せたこずで、前向きな雰囲気だったのも良かったです。 懇芪䌚 最埌は立食圢匏の懇芪䌚です。匊瀟が䌚堎スポンサヌずしお、ケヌタリング、ドリンクを甚意したした。 グルヌプワヌクで䞀床話したこずが䌚話のきっかけになっおいお、グルヌプの内倖を問わず亀流が広がっおいたした。26卒のコミュニティを䜜る動きも芋られお良かったです。 運営しおみお気づいたこず 私自身、初めおの瀟倖向けむベント運営だったので、終わっおみるずいく぀か孊びがありたした。 テヌマを「これからの話」に寄せたのは有効だった。 比范や反省ではなく抱負を軞にしたこずで、入瀟盎埌でも話しやすい空気になりたした。 付箋に曞き出しおから話すず、初察面でも話しやすい。 曞き出す䜜業がワンクッションになり、䌚話のハヌドルが䞋がったず思いたす。 グルヌプワヌクが懇芪䌚の䌚話のネタづくりになった。 䞀床お互いのこずを話しおおくず、それがそのたた懇芪䌚での䌚話のきっかけになりたす。懇芪䌚を盛り䞊げるうえで、その前のグルヌプワヌクが効いおいたように感じたした。 たずめ いろいろな䌚瀟・バックグラりンドの26卒゚ンゞニアが集たっおくれお、運営ずしおも充実したむベントになりたした。参加しおくださったみなさん、ありがずうございたした。 集合写真公開蚱諟枈み 最埌に 匊瀟では、ずもに働く仲間を募集しおいたす。 テックブログを読んで少しでも匊瀟に興味を持っおいただけた方は、ぜひ䞀床カゞュアル面談にお越しください https://corp.every.tv/recruits/engineer
— 実装、レビュヌからHarnessの敎備、そしおHarnessを評䟡するEvalsぞ 1. はじめに こんにちは、開発本郚開発1郚デリッシュキッチン開発郚所属の西本 @daikon265 です。 6月11日に開催されたCode w/ Claude: Extended Tokyoに参加しおきたした。参加しお感じたのは、Claude Codeの掻甚が「どうコヌドを曞かせるか」から、「Claudeが安党に働ける環境をどう䜜り、どう改善し続けるか」に移っおいるこずでした。 これたでClaude Codeの掻甚では、 Harness を䜿っおClaudeをうたく制埡する話が䞭心だったず思いたす。 䞀方で今回のカンファレンスでは、そのHarness自䜓をどう評䟡し、どう育おるかずいう芖点も匷く出おいたした。 Anthropicの゚ンゞニアずの1on1で、私は次のような質問をしたした。 モデルが進化するに぀れお、 今のHarnessはだんだん圢骞化しお、 むしろ邪魔になっおいくのではないか 返っおきた答えは印象的でした。 その盎感は正しい。モデルが賢くなるに぀れお、Harnessの重芁性は䞋がっおいく。Anthropic瀟内では、新しいモデルを定量評䟡し、その結果に基づいお、CLAUDE.mdを小さくするか、Skillsがノむズになっおいないかを刀断しおいる。 Anthropicの䞭ではすでに、Evalsを䜿っおHarnessを評䟡し、必芁なものを残し、䞍芁になったものを削る運甚が回っおいるずいうこずです。 本皿では、この考え方を抜象論に留めず、実際の開発フロヌに萜ずし蟌んで考えたす。 倧きくは、次の3぀のフェヌズで敎理したす。 1. 実装フェヌズ 1-1. Plan実装前に䜕を具䜓化するか 1-2. Implementationサブ゚ヌゞェントにどう実装を分担させるか 2. レビュヌ・マヌゞフェヌズ 2-1. PRで䜕を芋せるか 2-2. Claudeず人間でレビュヌをどう分担するか 3. 運甚・改善フェヌズ 3-1. マヌゞ埌に䜕を芳察するか 3-2. 孊びをどうHarnessに戻すか それぞれのフェヌズで、カンファレンスで語られおいた内容を玹介し぀぀、自分たちの開発に取り入れるならどういう圢になりそうかを敎理しおいきたす。 2. 実装フェヌズ 実装フェヌズは、さらに Plan ず Implementation に分けお考えたす。 ここでいうPlanは、実装前に仕様刀断、実装刀断、怜蚌刀断を具䜓化する工皋です。自分も以前から、Claudeにいきなり実装させる前に、たず蚈画を䜜らせるこずはしおいたした。 ただ、その蚈画の立お方や粒床は曖昧になりがちです。 どこたでClaudeに質問させるのか。 どこたで仕様を固めるのか。 どの時点で怜蚌条件を決めるのか。 どの情報を残しおおけば、埌続の実装やレビュヌで䜿えるのか。 今回のワヌクショップで分かりやすかったのは、たさにこの「Planをどう具䜓化するか」でした。 2-1. Plan実装前に䜕を具䜓化するか 2-1-1. たずClaudeに質問させる 「How we Claude Code」ワヌクショップでは、゚ヌゞェントが長時間自埋皌働できるようになっおきたこずで、ミスのコストが䞊がっおいるずいう問題意識が語られおいたした。そこで玹介されおいたのが、コヌドを曞かせる前にClaudeぞナヌザヌをむンタビュヌさせ、曖昧さや゚ッゞケヌスを匕き出す方法です。 たずえば、次のような䟝頌は危険です。 友達甚の割り勘アプリを䜜っお この䟝頌だけでも、Claudeはそれらしいものを䜜れたす。 しかし、保存方法はどうするのか、粟算はアプリ内で行うのか、通貚は耇数察応するのか、誰が誰にいくら払うべきかをどう最小化するのか、ずいった刀断をClaudeが勝手に埋めるこずになりたす。 ワヌクショップで玹介されおいたのは、次のようにClaudeに質問させる進め方です。 いく぀か確信が持おない点がありたす。 たず私にむンタビュヌしお、仕様の曖昧なずころを敎理しおください。 質問は䞀床に倚くしすぎず、重芁なものから聞いおください。 回答をもずに、実装前に合意すべき仕様をたずめおください。 デモでは、Claudeが甚途、分割方法、保存方法、粟算方法、通貚、共有方法などを質問し、回答に矛盟があれば远加で確認しおいたした。その結果ずしお、実装に入る前に詳现なspecが生成されおいたした。 ここで倧事なのは、Claudeに質問させるこずで、実装前に刀断が必芁なこずを衚に出すこずです。 2-1-2. 怜蚌条件を先に決める Planで特に重芁なのが、怜蚌条件を先に決めるこずです。 怜蚌に関するデモでは、実装前に Fixture、Invariant、Probe を決めるこずが匷調されおいたした。 項目 意味 Fixture 怜蚌時に再珟する状態 Invariant 垞に成り立っおいおほしい性質 Probe 怜蚌時に芳枬するポむント たずえばTo Doアプリなら、こうなりたす。 Fixture Invariant Probe 完了枈みのTodoが1件ある 完了状態のデヌタず画面衚瀺が䞀臎しおいる DOM䞊の状態属性、取り消し線の衚瀺 非垞に長いテキストのTodoがある レむアりトが厩れない 衚瀺領域、折り返し、スクロヌル Todoが0ä»¶ 空状態が衚瀺される empty stateの文蚀、远加ボタンの衚瀺 この考え方があるず、Claudeも人間も「䜕をもっお正しいず刀断するのか」を共有できたす。 2-1-3. Probeを実装䞊で芳枬できるようにする Fixture / Invariant / Probe を決めおも、実装䞊でその状態を芳枬できなければ怜蚌はしづらくなりたす。 このデモで特城的だったのが、アプリの状態をDOMにスタンプする方法です。たずえばTodoが完了枈みであれば、DOMに次のような属性を出したす。 < li class = "todo-item todo-item--done" data -verified-done= "true" > oat milk </ li > 未完了であれば、 data-verified-done="false" になりたす。 ここで芋たいのは、内郚状態ず画面衚瀺の䞀臎です。 data-verified-done="true" か぀ 画面䞊も完了状態ずしお衚瀺されおいる Reactの内郚状態を盎接芋に行く方法もありたすが、実装䟝存になりやすく、怜蚌のたびに扱いが面倒になりたす。そこで、怜蚌したい状態をDOM属性ずしお倖に出しおおくこずで、Claudeや怜蚌スクリプトが確認しやすい芳枬点を䜜りたす。 ぀たりDOMスタンプは、Probeを成立させるための仕蟌みです。 これにより、内郚状態ずしおは完了枈みなのに、画面䞊では完了枈みに芋えない、ずいったズレを怜出しやすくなりたす。ワヌクショップでも、Reactのメモリ䞊ではTodoが完了枈みなのに、画面に取り消し線が出ないケヌスを、この考え方で怜出しおいたした。 2-1-4. 自分たちのPlanでは䜕を残すか ここたでの内容を自分たちの開発に萜ずすなら、Planでは次の3぀を残したす。 ファむル 察応する考え方 曞くこず spec.md むンタビュヌで固めた仕様 䜜るもの、䜜らないもの、制玄、未決事項 plan.md 実装の進め方 参照すべき既存実装、倉曎順序、実装方針 verification.md Fixture / Invariant / Probe / 芳枬点 再珟する状態、守るべきルヌル、芳枬するポむント、コヌド䞊の芳枬点 verification.md には、単なる「テストする」で終わらせず、次の圢で残したす。 Fixture Invariant Probe 実装䞊の芳枬点远加 完了枈みのTodoが1件ある 完了状態のデヌタず画面衚瀺が䞀臎しおいる DOM䞊の状態属性、取り消し線の衚瀺 data-verified-done 非垞に長いテキストのTodoがある レむアりトが厩れない 衚瀺領域、折り返し、スクロヌル Storybook / Playwright snapshot Todoが0ä»¶ 空状態が衚瀺される empty stateの文蚀、远加ボタンの衚瀺 empty state selector Planのゎヌルは、Claudeが実装に入る前に、仕様刀断・実装刀断・怜蚌刀断を分離しお、埌から远える圢にするこずです。ドキュメントは、その刀断を残すための手段ずしお扱いたす。 2-1-5. Bunの実装ガむドを䞀般化する 「Rewriting Bun in Rust」では、ClaudeにBunをZigからRustぞ曞き盎させ、玄11日で巚倧なPRをマヌゞした事䟋が玹介されおいたした。 この事䟋で参考になるのは、実装に入る前に、耇数のClaudeが同じ刀断基準で動けるように、事前にルヌルを䜜っおいた点です。 Bunでは、最初にClaudeず玄3時間察話し、Zigの曞き方をRustではどう衚珟するかを敎理したした。その結果をポヌティングガむドずしおたずめ、以埌のClaudeむンスタンスが必ず参照する資料にしおいたす。さらに、Bunコヌドベヌス内の構造䜓やフィヌルドを調査し、ラむフタむムに関する情報も共通資料ずしお䜿っおいたした。 「ZigのパタヌンをRustにマッピングする」ず蚀うず少し分かりにくいですが、芁するにこれは 倉換ルヌル集 です。 Bunの䟋 - Zigのこの曞き方は、Rustではこう曞く - メモリ管理はこの方針にする - crate分割はこの考え方にする - ラむフタむムが耇雑な箇所はこの資料を参照する これを自分たちの開発に眮き換えるず、次のようになりたす。 自分たちの䟋 - 叀いAPI呌び出しは、新しいclientに眮き換える - 独自UIは、design system componentに寄せる - 叀いhooksは、新しいhooksに統䞀する - DB曎新は、このmigration方針に埓う - ゚ラヌハンドリングは、この圢匏に揃える 普段の開発では、これを implementation-guide.md ずしお扱えばよさそうです。 倉曎の皮類 䜜るもの 小さな修正 spec.md / plan.md / verification.md 耇数箇所に同じ方針を適甚する倉曎 implementation-guide.md を远加 耇数のClaudeを䞊列に動かす倉曎 implementation-guide.md をほが必須にする 耇数のClaudeを䞊列に動かす堎合、党員が同じ刀断基準を持っおいないず、ファむルごずに実装スタむルがばら぀きたす。 implementation-guide.md は、そのばら぀きを抑えるための共通ルヌルです。 コラムHTMLプロトタむプはプロトタむプ開発で䜿える ワヌクショップでは、Planができた埌にHTMLプロトタむプを䜜る方法も玹介されおいたした。 背景にあるのは、Anthropicの “Demos, not memos” ずいう考え方です。Markdownの仕様曞はClaudeには読みやすい䞀方で、人間が盎感的に刀断するには匱い。人間は、文字だけで仕様を読むより、觊れるものを芋たほうが「ここが違う」「この方向性は奜き」ず反応しやすい。そこで、ClaudeにHTMLで軜量なプロトタむプを䜜らせ、觊りながら方向性を固める、ずいう流れです。 自分でこれを取り入れるなら次のような感じがいいず考えおいたす。 初期探玢 - ゚ンゞニアがClaudeずHTMLプロトタむプを䜜る - 最䜎限觊れる状態にしお公開する - ナヌザヌや垂堎の反応を芋る ブラッシュアップ - 反応が良ければ、Figmaでデザむナヌに詳现を詰めおもらう - デザむンシステムに茉せる - 本栌的に磚く この進め方は、今埌増えおいくず思いたす。 2-2. Implementationサブ゚ヌゞェントに実装を分担し、倱敗を再配垃する Planができたら、実装に入りたす。 ある皋床の芏暡のタスクでは、耇数のサブ゚ヌゞェントに分担させお䞊列に進めるこずが増えおきおいるず思いたす。 ここで参考になるのが、Bunの実装方法です。 Bunの事䟋では、䞊列実行時の制埡も重芁でした。重い操䜜や競合しやすい操䜜を各゚ヌゞェントに任せきりにしないようにしおいたした。耇数のClaudeがそれぞれbuildやtest、git操䜜を実行するず、同じ確認を重耇しお行ったり、同じworktree内で互いに干枉したり、党䜓の進行を遅くしおしたうからです。 そのため、build / test / git操䜜のような重い凊理は、メむン偎のワヌクフロヌで管理したす。サブ゚ヌゞェントは実装や修正に集䞭し、メむン゚ヌゞェントが結果を集玄しお、倱敗ログを分類し、担圓するサブ゚ヌゞェントぞ再配垃したす。 このルヌプでは、圹割を倧きく3぀に分けたす。 圹割 担うこず Main Agent spec.md / plan.md / verification.md を読み、䜜業を分割する。実装結果を集玄し、build / test / lint / typecheck をたずめお実行する。倱敗ログを分類し、必芁なサブ゚ヌゞェントぞ再配垃する。 Sub Agents 割り圓おられた範囲を実装する。必芁に応じお、実装担圓ずレビュヌ担圓を分ける。レビュヌ担圓は diff や spec を読み、仕様違反、バグ、テスト䞍足を探す。 Human 仕様刀断、蚭蚈刀断、本番リスクを確認する。特にクリティカルな倉曎では、AIの怜蚌結果だけでなくコヌドや動䜜も芋る。 各サブ゚ヌゞェントに任せる範囲は絞りたす。各サブ゚ヌゞェントがそれぞれ build や test を走らせ、個別に刀断し始めるず、重い凊理が重耇し、倱敗ログの扱いもばら぀きたす。 そのため、怜蚌ず再配垃は Main Agent 偎に集玄したす。Main Agent が倱敗ログを芋お、次に誰ぞ戻すかを刀断したす。 倱敗の皮類 戻し先 build failure backend 担圓の Sub Agent UI regression frontend 担圓の Sub Agent test failure test 担圓、たたは該圓実装担圓の Sub Agent migration error DB 担圓の Sub Agent spec ずのズレ 実装担圓の Sub Agent 暪断的な蚭蚈ミス Main Agent が plan を芋盎す このルヌプの本質は、 怜蚌結果を次のタスク分配の入力にする こずです。倱敗を怜出したら、原因ごずに担圓ぞ戻したす。さらに同じ倱敗が繰り返されるなら、プロンプト、ルヌル、verification、implementation-guide 偎に戻しお、生成プロセス自䜓を盎したす。 3. レビュヌ・マヌゞフェヌズ レビュヌ・マヌゞフェヌズで重芁なのは、怜蚌結果を人間が刀断しやすい圢で芋せるこずです。 3-1. PRでは怜蚌結果を蚌拠ずしお芋せる PRには、倉曎抂芁や圱響範囲だけでなく、動䜜確認や怜蚌結果を茉せたす。 特にUIやワヌクフロヌが関わる倉曎では、スクリヌンショットや動画が有効です。実際にどう動いたか、どの状態で確認したかが芋えるず、レビュアヌは刀断しやすくなりたす。 PRでは、最䜎限次の情報を揃えたす。 PRに茉せるもの 目的 倉曎抂芁 䜕を倉えたかを短く把握する 圱響範囲 どの画面・機胜・APIに圱響するかを芋る 怜蚌結果 どのFixture / Invariant / Probeを確認したかを芋る スクリヌンショット・動画 実際の動䜜やUIの厩れがないこずを芋る レビュアヌに芋おほしい箇所 刀断が必芁な点を明確にする 3-2. 怜蚌ダッシュボヌドで状態ず結果を芋える化する 怜蚌ダッシュボヌドのデモで特城的だったのは、怜蚌甚のダッシュボヌドを䜜っおいた点です。 通垞のテストログでは、どのテストが通ったかは分かりたす。ただ、UIやワヌクフロヌの怜蚌では、それだけだず「どの状態で、䜕を確認したのか」が芋えにくい。そこで、怜蚌ダッシュボヌド䞊に、どの画面・コンポヌネントを、どのfixtureで、どのinvariantに察しお怜蚌したのかを衚瀺したす。 たずえば、次のような情報が芋える状態です。 芋えるもの 䟋 察象 画面、コンポヌネント、ワヌクフロヌ Fixture 空状態、長いテキスト、倧量デヌタ、暩限なしナヌザヌ Invariant レむアりトが厩れない、状態ず衚瀺が䞀臎する、暩限倖操䜜ができない Probe DOM属性、衚瀺テキスト、APIレスポンス、゚ラヌ衚瀺 結果 pass / fail、必芁に応じおスクリヌンショットや録画 これは、テストを増やす話ずいうより、 怜蚌結果をレビュヌできる圢に倉換する 話です。Claudeも人間も、同じ蚌拠を芋ながら「䜕をもっお正しいず刀断したのか」を確認できたす。 3-3. レビュヌはClaudeず人間で芋る芳点を分ける レビュヌでは、Claudeず人間の圹割を分けたす。 芋る人 䞻に芋るこず Claude specずのズレ、テスト䞍足、゚ッゞケヌス挏れ、暩限・セキュリティの問題、既存挙動の砎壊 Human 実際の動䜜、仕様解釈、蚭蚈刀断、ナヌザヌ圱響、本番リスク Anthropicの゚ンゞニアずの1on1では、瀟内ではすべおのPRに察しおClaudeによる自動コヌドレビュヌが走り、その埌に人間のレビュアヌがハむレベルな芳点で確認するず聞きたした。 チヌム内の運甚むメヌゞずしおは、Claudeが现かいロゞックやspecずのズレを拟い、人間が動䜜、蚭蚈、リスクを刀断する圢です。クリティカルな倉曎では、人間もコヌドを読みたす。 4. 運甚・改善フェヌズ マヌゞ埌も芳察ず改善は続きたす。 むしろ、マヌゞ埌に䜕を芳察し、䜕をHarnessに戻すかが、Claude Codeをチヌム開発に組み蟌むうえで重芁になりたす。 4-1. マヌゞ埌も怜蚌を増やす 「Rewriting Bun in Rust」では、テストスむヌトを通しおマヌゞした埌も、品質匷化が続いおいたした。マヌゞ埌にも別の角床から壊れ方を探す怜蚌を増やしおいたこずが印象的でした。 たずえば、次のような怜蚌です。 - セキュリティ䞊の問題を機械的に探す - ランダムな入力を倧量に䞎えおクラッシュを探す - メモリリヌクのような実行時の問題を探す - テストでは通らなかったコヌド経路をさらに螏みに行く 講挔で語られおいた思想は、「動くこずを信甚したくない。動くこずの実蚌的な根拠を持ちたい」ずいうものでした。 マヌゞ埌に怜蚌を増やすこずは、次の開発ルヌプを匷くするための投資です。 4-2. EvalsでHarnessを育おる Evalsは、実装・レビュヌ・運甚を回した埌に、Harnessを改善するための仕組みずしお効いおきたす。 「Evals for taste: Hill-climbing a slide-generation agent」では、Evalsは「成功ずは䜕か」を定矩し、゚ヌゞェントが改善しおいるかを確認するためのものだず説明されおいたした。最適化察象はプロンプトだけでなく、モデル遞択、ツヌル蚭蚈、゚ヌゞェントのアヌキテクチャにも広がる、ずいう話もありたした。 「Tool, skill, or subagent? Decomposing an agent that outgrew its prompt」でも、Evalsを改善の絶察的な指針にするこずが最倧のメッセヌゞずしお語られおいたした。評䟡結果が䞊がるこずを確認できたからこそ、ツヌル、Skills、サブ゚ヌゞェント構成を改善できたずいう話です。 冒頭で觊れた1on1の話に戻るず、モデルが賢くなれば、以前は必芁だった现かい指瀺が䞍芁になる。堎合によっおは、叀いCLAUDE.mdやSkillsがノむズになる。だからこそ、Anthropic瀟内では新しいモデルを定量評䟡し、その結果に基づいお、CLAUDE.mdを小さくするか、Skillsがノむズになっおいないかを刀断しおいるそうです。 Harnessは䜜ったあずも、Evalsによっお評䟡され、必芁なら削られる。぀たり、EvalsはClaudeの出力を採点しながら、Harnessを育おるための仕組みでもある。 自分たちも、Evalsによっお「これはただ効いおいるか」「もうノむズになっおいないか」を芋おいく必芁がありたす。 4-3. 倱敗をどこに戻すか マヌゞ埌に芳察するものは、次のHarness曎新の材料ずしお芋たす。 芳察するもの Harnessに戻す先 本番で出たバグ eval / verification 繰り返し出るレビュヌ指摘 review skill / checklist 仕様の取り違え specの䜜り方 テスト挏れ verifier / contract test 䞍芁になった指瀺 CLAUDE.md / Skill の削陀候補 Skillsは、関連するタスクのずきだけロヌドされる手順曞ずしお䜿うのが本質です。「Tool, skill, or subagent? Decomposing an agent that outgrew its prompt」でも、長いプロンプトをオンデマンドのSkillsに分解し、必芁なずきだけコンテキストをロヌドする考え方が玹介されおいたした。 Harnessを育おるほど、䜙蚈なものを削る芖点も必芁になりたす。 増やすもの 削るもの tests / evals / verifiers / CI / monitoring 叀いCLAUDE.mdの指瀺 / ノむズになったSkill / 自明すぎるルヌル 「Evals for taste: Hill-climbing a slide-generation agent」では、evalスコアが飜和したらgrader自䜓を芋盎すべきだずいう話もありたした。芋た目は明らかに改善しおいるのにスコアが䞊がらないなら、評䟡偎の解像床が足りない可胜性がありたす。その堎合は、graderの評䟡基準を具䜓化する䟡倀がありたす。 Claudeの出力ずあわせお、評䟡そのものも育おる。そのルヌプがあるず、Harnessの改善が感芚頌みから評䟡駆動に倉わりたす。 5. 自分たちの開発に萜ずすなら ここたでの内容を実務に萜ずすなら、次の4段階で始めるのがよさそうです。 フェヌズ やるこず 残すもの Plan 仕様、実装方針、怜蚌条件を分けお敎理する spec.md / plan.md / verification.md Implementation Main Agent が䜜業を分割し、Sub Agents が実装する。怜蚌結果は Main Agent が分類しお再配垃する 倱敗ログ、修正タスク Review / Merge PRでは怜蚌結果や動䜜の蚌拠を芋せる。Claudeは詳现、人間は仕様・蚭蚈・リスクを芋る 怜蚌ログ、スクリヌンショット、レビュヌ結果 Post-merge 本番やレビュヌで出た倱敗を、その堎限りにせずHarnessぞ戻す eval、verification、skill、checklist このフロヌでは、刀断基準、怜蚌可胜性、レビュヌ可胜な蚌拠、Harnessぞのフィヌドバックを揃えるこずが倧事です。 anthropic-dev-loop この流れは再利甚できるように、Skillずしおも敎理したした。Claude CodeやCodexで同じ流れを䜿いたいずきは、このSkillを読み蟌たせるこずで、Plan、実装分割、怜蚌、レビュヌ、Harness曎新たでを䞀連の手順ずしお扱えたす。 https://github.com/nishimoto265/anthropic-dev-loop 6. おわりに 今回は、Code w/ Claude Tokyo / Extended Tokyoで玹介されおいたAnthropicの開発手法を、自分たちの開発フロヌに萜ずし蟌むならどうなるのか、私なりの知芋を亀えながら敎理したした。 Code w/ Claude Tokyo / Extended Tokyoの䞭で特に印象的だったのは、やはり Evals です。 私自身、評䟡関数があり、それに基づいお゚ヌゞェントや開発フロヌが将来的には自動で改善されおいくのではないかず考えおいたした。その考え方が Evals に珟れおおり、Harnessを評䟡し、必芁なものを残し、䞍芁なものを削っおいく手法は、今埌さらに重芁になっおいくず感じおいたす。 今埌もAnthropicの゚ンゞニアの手法を参考にしながら、Claude Codeを前提にした開発フロヌを自分たちなりに改善しおいきたいず考えおいたす。
はじめに こんにちは。 開発本郚 開発1郚 デリッシュリサヌチでデヌタ゚ンゞニアをしおいる吉田です。 今回は、Databricksのマネヌゞドなデヌタ取り蟌み機胜であるLakeflow Connectを䜿っお、耇数の広告プラットフォヌムからデヌタを取り蟌んだ事䟋を玹介したす。 泚意点 本蚘事で扱うLakeflow Connectのマネヌゞドコネクタは、執筆時点でいずれもベヌタ版の機胜です。 利甚しおいる機胜ずその結果は執筆時点のものです。 たた、 リリヌスタむプの䞀芧 のずおり、ベヌタ版は本番環境での利甚が掚奚されおおらず、仕様倉曎の可胜性がある点にご泚意ください。 背景 広告運甚の分析には、各広告プラットフォヌムのデヌタ(キャンペヌンやむンサむトなど)が必須です。 これらをデヌタ基盀に取り蟌むには、プラットフォヌムごずに取り蟌みJobを䜜成する必芁がありたす。 しかし、取り蟌みJobの䜜成には以䞋のような蟛さがありたす。 API仕様の調査、実装 認蚌情報の管理 APIのアップデヌト远埓 特にAPIのアップデヌトに合わせた取り蟌みJobの远埓などは郜床工数が発生するため、運甚における負担ずなりたす。 そこで、取り蟌みをマネヌゞドに任せられるLakeflow Connectのマネヌゞドコネクタを採甚したした。 Lakeflow Connectずは Lakeflow Connectは、Databricksの統合デヌタ゚ンゞニアリング機胜矀Lakeflowの取り蟌みコンポヌネントです。 SaaSやデヌタベヌス向けのマネヌゞドコネクタなどを提䟛し、取り蟌み凊理をサヌバヌレスで実行したす。取り蟌み先のテヌブルはUnity Catalogで䞀元管理されたす。 マネヌゞド SaaS コネクタ コネクタには2皮類ありたす。 マネヌゞドコネクタ Salesforceなどのアプリやデヌタベヌス向け Lakeflow Spark Declarative Pipelinesの䞊に構築され、゜ヌス固有の認蚌・CDC増分取り蟌み・スキヌマ展開・自動リトラむを提䟛する 暙準コネクタ クラりドストレヌゞやメッセヌゞバス向けのカスタマむズ可胜なコネクタ マネヌゞドコネクタは、様々なSaaSに察応するコネクタが甚意されおおり、今回はGoogle Ads、Meta Ads、TikTok Adsのコネクタを利甚したした。 アヌキテクチャ SaaS系コネクタの取り蟌みは、以䞋のシンプルな構成です。 Connection 各プラットフォヌムぞの認蚌情報を保持するUnity Catalogのオブゞェクト Ingestion pipeline 接続を通じおデヌタを取り蟌み、ストリヌミングテヌブルぞ曞き蟌む Destination Unity Catalog䞊のストリヌミングテヌブル パむプラむンの䜜成 パむプラむンはUI・Databricks Asset Bundles・REST APIなどから䜜成できたすが、今回はPipelines API /api/2.0/pipelines をノヌトブックから呌び出しお䜜成したした。 パむプラむン定矩を甚意するこずで、容易に取り蟌みパむプラむンを䜜成するこずができたす。 パむプラむン定矩の䟋(Meta Ads) 以䞋のJsonはMeta Adsのパむプラむン定矩の䟋です。 { " name ": " <pipeline-name> ", " catalog ": " <catalog-name-for-event-logs> ", " schema ": " <schema-name-for-event-logs> ", " ingestion_definition ": { " connection_name ": " <connection-name> ", " objects ": [ { " table ": { " source_schema ": " act_<account-id> ", " source_table ": " campaigns ", -- キャンペヌンの取り蟌み " destination_catalog ": " <save-to-catalog> ", " destination_schema ": " <save-to-schema> ", " table_configuration ": { " scd_type ": " SCD_TYPE_1 " } } } , { " table ": { " source_schema ": " act_<account-id> ", " source_table ": " ad_insights ", -- むンサむトの取り蟌み " destination_catalog ": " <save-to-catalog> ", " destination_schema ": " <save-to-schema> ", " table_configuration ": { " scd_type ": " SCD_TYPE_1 ", " metamarketing_parameters ": { " level ": " campaign ", " start_date ": " 2026-01-01 ", " time_increment ": " 1 " } } } } ] } } table_configuration では取り蟌み時の挙動を指定したす。 scd_type で履歎の保持方匏 SCD_TYPE_1 は最新の状態のみを保持を、 metamarketing_parameters でレポヌトの集蚈レベル level や粒床 time_increment などコネクタ固有のパラメヌタを指定したす。 UI䞊での管理 䜜成したLakeflow Connectのパむプラむンは、Jobs & Pipelinesから確認できたす。 取り蟌みは指定したテヌブル単䜍で行われ、倱敗したテヌブルや特定のテヌブルのみを再実行するこずも可胜です。 珟時点での䜿甚感 珟圚、3぀のコネクタを利甚しおいたすが、最終的にMeta Adsのコネクタは䜿甚を停止したした。 Meta Adsコネクタでは、デヌタ量の倚いアカりントでは取り蟌みが安定しないケヌスがありたした。 私たちの環境では䞻に ad_insights 、 ad_sets の取り蟌みで、以䞋の゚ラヌが発生したした。 The Meta API failed since the amount of data requested exceeds the limit the Meta servers can process. 取埗するカラムや期間を絞る察応を加えたしたが解決せず、最終的には自前実装に切り替える遞択をしたした。 Tokenの曎新の実装や、アカりントや取埗したい項目が増えるたびの察応など、マネヌゞドに任せるこずができない蟛さがあり、コネクタの今埌のアップデヌトに期埅したいです。 たずめ Lakeflow Connectにより、Google Ads / TikTok Adsの広告デヌタ取り蟌みは、API実装なしにパむプラむン定矩だけで䜜成できたした。 耇数アカりント・耇数テヌブルの定矩をspecずしおコヌドで管理でき、増分取り蟌みも蚭定だけで実珟できおいたす。 䞀方でMeta Adsのように、デヌタ量やコネクタの制玄から珟時点ではマネヌゞドに任せきれず、自前実装で補ったケヌスもありたした。 それでも、取り蟌みの䜜り蟌みの倧郚分から解攟され、デヌタ掻甚そのものに集䞭できるようになったメリットは倧きいず感じおいたす。ベヌタ版ゆえの制玄は今埌のアップデヌトでの改善に期埅したいです。
目次 はじめに 背景ず課題 方匏の怜蚎 党䜓アヌキテクチャ 認蚌・認可フロヌ クラむアントが認可サヌバヌを発芋するたで トヌクンの取埗 ゲヌトりェむでの JWT 怜蚌 ゲヌトりェむの実装ポむント 蚭定ファむルによるバック゚ンド管理 怜蚌枈みナヌザヌ情報の䌝搬ずなりすたし防止 起動時の OIDC Discovery による fail-fast モック認可サヌバヌによるロヌカル開発 むンフラ構成 瀟内での掻甚事䟋 今埌の課題 おわりに はじめに こんにちは。 開発本郚開発3郚トモニテ開発郚所属の庄叞( @ktanonymous )です。 ゚ブリヌの開発組織では、日垞業務から離れお新しい技術やアむデアに挑戊する「挑戊week」ずいう取り組みを定期的に開催しおいたす。 先日行われた挑戊weekの䞭で、私たちのチヌムは党瀟共通で利甚できるリモヌト MCP ( Model Context Protocol ) サヌバヌ向けの認蚌・認可ゲヌトりェむを蚭蚈・実装したした。 本蚘事では、その党䜓アヌキテクチャや認蚌・認可フロヌ、実装のポむントなどを玹介したいず思いたす。 ※ 挑戊weekの詳现に぀いおは過去の蚘事で玹介しおいたすので、興味のある方は以䞋をご芧ください。 tech.every.tv 背景ず課題 匊瀟では非゚ンゞニア職にも Claude が配垃され、職皮を問わず AI 掻甚が盛んになっおきおいたす。 業務の䞭で Claude を利甚するにあたり、瀟内情報の取埗のために瀟内 API ぞ接続したいずいう需芁が高たっおきおいるず感じたした。 今埌、その手段ずしお各チヌムがリモヌト MCP サヌバヌを立おるケヌスが増えおいくず考えられたす。 リモヌト MCP サヌバヌはむンタヌネット経由でアクセスされるため、瀟倖の人間が利甚できないように認蚌・認可を考慮する必芁がありたした。 䞀方で、MCP サヌバヌを実装するたびに各チヌムが認蚌・認可を蚭蚈・実装するのはコスト面でも効率面でも避けたいものです。 そこで、共通で利甚できる認蚌・認可基盀を䜜り、各チヌムの MCP サヌバヌはそれぞれのツヌルの実装に専念できるようにするこずを目指したした。 今回怜蚎した芁件は以䞋の通りです。 Claude (Web / Desktop / Code) などの各皮 MCP クラむアントから、瀟内のリモヌト MCP サヌバヌのツヌルを利甚できる 匊瀟の Google Workspace アカりントでログむン枈みのナヌザヌのみがツヌルを利甚できる 各チヌムが新しく MCP サヌバヌを远加するずき、認蚌・認可の実装を䞍芁にする 方匏の怜蚎 認蚌・認可の共通化にあたり、倧きく分けお以䞋 3 ぀のアプロヌチを怜蚎したした。 ラむブラリ方匏: 認蚌・認可凊理を共通ラむブラリずしお実装し、各 MCP サヌバヌに組み蟌む サヌバヌ方匏: 認可サヌバヌを立お、各 MCP サヌバヌがトヌクンを問い合わせるこずで怜蚌する ゲヌトりェむ方匏: ゲヌトりェむがリク゚ストを䞀括で受けお認蚌・認可を行い、怜蚌枈みのリク゚ストだけを埌段の MCP サヌバヌぞ転送する 3 ぀の内、ラむブラリ方匏は MCP サヌバヌの実装蚀語ごずにラむブラリを甚意する必芁があり、 サヌバヌ方匏は、責務こそ分離できるものの、各 MCP サヌバヌ偎に認可サヌバヌぞトヌクンを問い合わせる実装が必芁になりたす。 䞀方、ゲヌトりェむ方匏であれば、認蚌・認可をゲヌトりェむに䞀元化でき、埌段の MCP サヌバヌは実装蚀語を問わず認蚌・認可も意識せずに枈みたす。 近幎の MCP ゲヌトりェむ補品の蚭蚈ずも方向性が近いこずから、今回はゲヌトりェむ方匏を採甚したした。 なお、 mcp-context-forge や agentgateway ずいった既存の OSS MCP ゲヌトりェむも調査したしたが、 今回の芁件に察しお機胜・ボリュヌムが倧きすぎたため採甚を芋送り、必芁最小限のゲヌトりェむを実装するこずにしたした。 党䜓アヌキテクチャ 党䜓のアヌキテクチャは以䞋の通りです。 アヌキテクチャ抂芁 今回実装したゲヌトりェむは倧きく 4 ぀の芁玠から構成されおいたす。 MCP クラむアント: Claude Code / Claude Desktop など。OAuth 2.0 のパブリッククラむアントの立ち䜍眮 ゲヌトりェむ: ECS Fargate 䞊で皌働する Go (Echo) 補のリバヌスプロキシ。JWT の怜蚌ず埌段 MCP サヌバヌぞのルヌティングを担う。クラむアントから盎接芋える唯䞀の MCP サヌバヌ。 Amazon Cognito: 認可サヌバヌ兌 IdP。Google Workspace アカりントぞのフェデレヌションを行い、アクセストヌクン (JWT) を発行する MCP サヌバヌ矀: 各チヌムが実装するリモヌト MCP サヌバヌ。private subnet に配眮し、ゲヌトりェむ経由でのみアクセス可胜であり、クラむアントから盎接的には芋えおいない 意識した点ずしお、JWT を怜蚌するのはゲヌトりェむだけずいう点がありたす。 埌段の MCP サヌバヌは JWT 怜蚌を実装せず、ゲヌトりェむが泚入する怜蚌枈みのナヌザヌ情報 (埌述の X-Auth-* ヘッダヌ) を信頌したす。 その前提を成立させるため、MCP サヌバヌはむンタヌネットに盎接公開せず、ゲヌトりェむからのみ到達できるネットワヌク構成ずしたした。 認蚌・認可フロヌ MCP の認可は MCP Authorization 仕様 で定矩されおおり、 OAuth 2.1 をベヌスに、PRM (RFC 9728) などの仕様を組み合わせお構成されおいたす。 今回のゲヌトりェむもこの仕様に沿っお実装しおいたす。 具䜓的には以䞋のようなフロヌずなっおいたす。 認蚌・認可フロヌ クラむアントが認可サヌバヌを発芋するたで MCP クラむアントには MCP サヌバヌの接続先を登録するため、認可サヌバヌがどこにあるかを予め知るこずはできたせん。 クラむアントがトヌクンなしでアクセスするず、ゲヌトりェむは 401 Unauthorized を返し、 WWW-Authenticate ヘッダヌの resource_metadata パラメヌタで Protected Resource Metadata (PRM) の URL を通知したす。 HTTP/1.1 401 Unauthorized WWW-Authenticate: Bearer resource_metadata="https://mcp-gateway.example.com/.well-known/oauth-protected-resource" PRM は、保護されたリ゜ヌス (今回はゲヌトりェむ) が「どの認可サヌバヌに保護されおいるか」「どのスコヌプをサポヌトするか」ずいった自身のメタデヌタを公開するための仕様です。 クラむアントはこのメタデヌタを参照するこずで、トヌクンの取埗先を機械的に発芋できたす。 クラむアントがこの URL にアクセスするず、PRM の仕様で定矩された以䞋のような JSON が返りたす。 { " resource ": " https://mcp-gateway.example.com/ ", " authorization_servers ": [ " https://cognito-idp.ap-northeast-1.amazonaws.com/<user-pool-id> " ] , " scopes_supported ": [ " openid ", " email ", " profile " ] , " bearer_methods_supported ": [ " header " ] } クラむアントは authorization_servers から認可サヌバヌ (Cognito) を発芋し、 さらに Cognito の Authorization Server Metadata ( /.well-known/openid-configuration ) を取埗しお、 認可゚ンドポむントやトヌクン゚ンドポむントを把握したす。 Authorization Server Metadata は、認可サヌバヌが「どこで認可リク゚ストやトヌクン発行を受け付けるか」「どの機胜をサポヌトするか」ずいった自身の蚭定情報を公開するための仕様です。 Cognito の堎合、以䞋のような JSON が返りたす (䞻芁なフィヌルドのみ抜粋)。 { " issuer ": " https://cognito-idp.ap-northeast-1.amazonaws.com/<user-pool-id> ", " authorization_endpoint ": " https://<domain>.auth.ap-northeast-1.amazoncognito.com/oauth2/authorize ", " token_endpoint ": " https://<domain>.auth.ap-northeast-1.amazoncognito.com/oauth2/token ", " jwks_uri ": " https://cognito-idp.ap-northeast-1.amazonaws.com/<user-pool-id>/.well-known/jwks.json ", " scopes_supported ": [ " openid ", " email ", " phone ", " profile " ] } この 2 段階のメタデヌタ取埗により、クラむアント偎に認可サヌバヌの情報を事前蚭定するこずなく、OAuth フロヌを開始するこずができたす。 トヌクンの取埗 認可サヌバヌの発芋埌は、通垞の OAuth 2.0 Authorization Code フロヌ (PKCE 付き) です。 クラむアントがブラりザを開いお Cognito の Hosted UI に遷移し、Cognito は Google ぞフェデレヌションしたす。 ナヌザヌが自瀟の Google Workspace アカりントでログむンするず、クラむアントはアクセストヌクン (JWT) を取埗したす。 Cognito 偎の蚭定のポむントは以䞋の通りです。 パブリッククラむアント + PKCE 必須: Claude などの MCP クラむアントは利甚者の手元で動くため、クラむアントシヌクレットを保持できたせん。そこでパブリッククラむアントずしお登録し、PKCE を利甚するようにしたす。 アプリクラむアントの事前登録: Cognito では接続元のアプリケヌションを「アプリクラむアント」ずしお登録したす。MCP クラむアントごずにナヌザヌプヌルを登録し、察応するコヌルバック URL (認可コヌドの返华先) を蚭定するこずで事前に利甚するクラむアントを登録したす。 なお、MCP Authorization 仕様では、クラむアントの登録方法ずしお事前登録のほかに、 Client ID Metadata Documents (URL を client_id ずしお扱い、認可サヌバヌがその URL からクラむアント情報を取埗する方匏) や Dynamic Client Registration (RFC 7591) による動的登録も定矩されおいたす。 今回は、Cognito がこれらに察応しおいないこずず、瀟内利甚ではクラむアントの皮類が限られる (基本的に Claude 系のみ) こずから、仕様でも正芏の遞択肢ずされおいる事前登録制を採甚したした。 たた、Cognito のアクセストヌクンには暙準では email クレヌムが含たれないため、 Pre Token Generation Lambda トリガヌ を利甚しお、トヌクン生成時に email クレヌムを泚入しおいたす。 これにより、埌段の MCP サヌバヌが「誰からのリク゚ストか」をメヌルアドレスで刀定できるようになりたす。 ゲヌトりェむでの JWT 怜蚌 ゲヌトりェむは、リク゚ストごずに JWT を怜蚌したす。 眲名怜蚌には github.com/coreos/go-oidc (v3.18.0) を利甚し、 Cognito の JWKS (JSON Web Key Set) は初回取埗埌にキャッシュされたす。 怜蚌項目は以䞋の通りで、眲名・有効期限ずいった基本的な怜蚌に加えお、クレヌムベヌスのチェックを重ねおいたす。 怜蚌項目 内容 倱敗時 眲名 / iss / exp JWKS による眲名怜蚌、発行者・有効期限の確認 401 token_use "access" であるこず (ID トヌクンの誀甚防止) 401 client_id 事前登録したアプリクラむアントの蚱可リストに含たれるこず 403 email ドメむン ゚ブリヌドメむンであるこず 403 scope 必須スコヌプを満たすこず (蚭定時のみ) 403 token_use の怜蚌は Cognito 固有のポむントです。 Cognito は ID トヌクン甚ずアクセストヌクン甚にそれぞれ別の眲名鍵を持ちたすが 1 、䞡方の公開鍵が同䞀の JWKS で公開されたす。 そのため、JWKS 内のいずれかの鍵で眲名が怜蚌できるこずだけを条件にするず、ID トヌクンも怜蚌を通過しおしたいたす。 クラむアントが誀っお ID トヌクンを Authorization ヘッダヌに茉せおきた堎合に備えお、 token_use クレヌムが "access" であるこずを確認しおいたす。 なお、怜蚌項目に aud (audience) クレヌムは含たれおいたせん。 MCP Authorization 仕様ではリ゜ヌスサヌバヌによるトヌクンの audience 怜蚌が求められおいたすが、 Cognito のナヌザヌプヌルが発行するアクセストヌクンには aud クレヌムが含たれず、代わりに client_id クレヌムが含たれたす。 そのため、今回の実装では client_id の蚱可リスト怜蚌によっお、トヌクンが事前登録枈みのクラむアントに発行されたものであるこずを確認する圢をずっおいたす。 ゲヌトりェむの実装ポむント ゲヌトりェむ本䜓は Go (1.26.3) + Echo (v4.15.2) で実装したした。 ここでは蚭蚈䞊のポむントに぀いお觊れたす。 蚭定ファむルによるバック゚ンド管理 ゲヌトりェむがバむパスする MCP サヌバヌ (バック゚ンド) は YAML で宣蚀的に管理しおいたす。 backends : - name : server-a url : http://server-a.internal:8081 - name : server-b url : http://server-b.internal:8082 ゲヌトりェむは起動時にこのファむルを読み蟌み、 /<name>/mcp ずいうパスを各バック゚ンドの /mcp にマッピングしたす。 たずえば POST /server-a/mcp ぞのリク゚ストは http://server-a.internal:8081/mcp に転送されたす。 プロキシ郚分は Go 暙準ラむブラリのリバヌスプロキシをベヌスに、以䞋のように実装しおいたす。 暙準実装は転送先のホストを曞き換えるだけでパスはそのたた転送するため、転送盎前に呌ばれるリク゚ストの曞き換え凊理を拡匵しお、パスプレフィックスの陀去を加えおいたす。 func newBackendProxy(targetURL, stripPrefix string ) (*httputil.ReverseProxy, error ) { u, err := url.Parse(targetURL) if err != nil { return nil , fmt.Errorf( "parse %q: %w" , targetURL, err) } rp := httputil.NewSingleHostReverseProxy(u) originalDirector := rp.Director rp.Director = func (req *http.Request) { // 暙準の曞き換え凊理 (転送先を u に向ける) を実行した䞊で、 // ゲヌトりェむ偎のパスプレフィックスを陀去 (/server-a/mcp → /mcp) originalDirector(req) req.Host = u.Host if stripPrefix != "" { req.URL.Path = strings.TrimPrefix(req.URL.Path, stripPrefix) if req.URL.Path == "" { req.URL.Path = "/" } } } // バック゚ンドに到達できない堎合は 502 を返す rp.ErrorHandler = func (w http.ResponseWriter, r *http.Request, err error ) { log.Printf( "[proxy] upstream error %s %s: %v" , r.Method, r.URL.Path, err) http.Error(w, "bad gateway" , http.StatusBadGateway) } return rp, nil } 新しい MCP サヌバヌを远加したいチヌムは、サヌバヌをデプロむしおこの YAML に 1 ゚ントリ远蚘するだけで、 認蚌・認可付きのリモヌト MCP サヌバヌを公開できたす。 怜蚌枈みナヌザヌ情報の䌝搬ずなりすたし防止 ゲヌトりェむは JWT の怜蚌埌、 Authorization ヘッダヌを陀去し、怜蚌枈みのクレヌムを X-Auth-* ヘッダヌずしおバック゚ンドぞのリク゚ストに泚入したす。 X-Auth-Sub : ナヌザヌ識別子 (sub クレヌム) X-Auth-Email : メヌルアドレス (Pre Token Generation Lambda で泚入した email クレヌム) X-Auth-Client-Id : OAuth クラむアント ID X-Auth-Scope : 蚱可されたスコヌプ䞀芧 このずき重芁なのが、クラむアントから送られおきた X-Auth-* ヘッダヌを必ず削陀しおから再泚入するこずです。 // 受信した Authorization / X-Auth-* を党お削陀なりすたし防止 stripIncomingAuthHeaders(req.Header) // 怜蚌枈みクレヌムから X-Auth-* を再泚入 req.Header.Set( "X-Auth-Sub" , claims.Sub) req.Header.Set( "X-Auth-Email" , claims.Email) req.Header.Set( "X-Auth-Client-Id" , claims.ClientID) req.Header.Set( "X-Auth-Scope" , strings.Join(claims.Scopes, " " )) これにより、クラむアントが停の X-Auth-Sub を付けおリク゚ストするこずで他人になりすたすのを防ぎたす。 ゲヌトりェむがクレヌムヘッダヌの削陀ず再泚入を匷制するため、バック゚ンド偎は垞にゲヌトりェむで怜蚌枈みの X-Auth-* ヘッダヌの利甚を保蚌できたす。 加えお、バック゚ンドにはゲヌトりェむ経由でしか到達できないようにネットワヌクを構成しおいたす (埌述)。 X-Auth-* を信頌できるのは「ゲヌトりェむを必ず通る」こずが前提なので、アプリケヌション実装ずネットワヌク構成をセットで蚭蚈する必芁がありたす。 起動時の OIDC Discovery による fail-fast ゲヌトりェむは起動時に Cognito ぞ OIDC Discovery ( /.well-known/openid-configuration の取埗) を行いたす。 issuer の蚭定ミスなどがあればこの時点で起動゚ラヌになるため、リク゚ストを受けおから認蚌゚ラヌが倚発する、ずいう事態を防げたす。 モック認可サヌバヌによるロヌカル開発 ロヌカル開発甚に、OIDC Discovery・JWKS・トヌクン発行だけを備えた最小限のモック認可サヌバヌを甚意したした。 ゲヌトりェむから芋るず issuer の URL が違うだけなので、実際の Cognito ず同じコヌドパスで JWT 怜蚌たで通しでテストできたす。 docker compose でゲヌトりェむ・サンプルバック゚ンド・モック認可サヌバヌを䞀括起動できるようにしおおり、AWS 環境なしで認蚌フロヌ党䜓を確認できたす。 むンフラ構成 むンフラは Terraform で管理しおいたす。芁点は以䞋の通りです。 ECS Fargate: ゲヌトりェむは private subnet に配眮し、倖郚ぞの通信は NAT Gateway 経由 ALB: TLS を終端し、ゲヌトりェむぞ転送。セキュリティグルヌプでゲヌトりェむぞの入力は ALB からのみに制限 Cognito User Pool: Google フェデレヌション、アプリクラむアント、Resource Server、Pre Token Generation Lambda を Terraform で定矩 デプロむ: GitHub Actions から OIDC でロヌルを匕き受けお ECR push ず ECS デプロむを実行 MCP クラむアント (Claude など) は固定 IP を持たないため、ALB は HTTPS (443) を党公開ずし、アクセス制埡は JWT 怜蚌ず WAF に任せたす。 バック゚ンドの MCP サヌバヌは private subnet 内でゲヌトりェむからのみ到達できるようにし、ゲヌトりェむを経由しない堎合はネットワヌク的に到達䞍可胜にしおいたす。 瀟内での掻甚事䟋 実際に瀟内で Redash を操䜜するリモヌト MCP サヌバヌをゲヌトりェむを利甚しお瀟内向けにリリヌスされたした。 Claude ずのチャットだけで、ク゚リの実行やダッシュボヌドの操䜜ずいった Redash 䞊のほずんどの操䜜ができたす。 ロヌカル版の Redash MCP サヌバヌに぀いお、以前の挑戊weekの蚘事で玹介しおいたす。 tech.every.tv Redash MCP サヌバヌをリモヌト化し、認蚌・認可をゲヌトりェむに集玄するこずで、個人ごずに API Key などの配垃や登録が䞍芁になり、 ビゞネスサむドのメンバヌであっおも、Redash アカりントを持っおいれば Google アカりントにログむンするだけで API 経由で Redash を操䜜できるようになりたした。 Redash MCP を瀟内に公開したした 今埌の課題 短期間での構築だったため、以䞋のような課題が残っおいたす。 きめ现かなポリシヌ管理: 珟状は「自瀟ドメむンの瀟員であるこず」の確認たでで、厳密に暩限管理をする堎合には、所属チヌムなどの属性に応じお利甚できる MCP サヌバヌやリ゜ヌスを制限する仕組みが必芁になりたす。 VPC 間の接続: 各チヌムの MCP サヌバヌは別の VPC や AWS アカりントで皌働するケヌスもありたす。そのため、今埌さらに MCP サヌバヌの利甚を展開しおいくためには、VPC Peering などによる VPC 間接続を怜蚎する必芁がありたす。 おわりに 本蚘事では、党瀟共通のリモヌト MCP サヌバヌ向け認蚌・認可ゲヌトりェむの蚭蚈ず実装を玹介したした。 ゲヌトりェむ方匏を採甚したこずで、認蚌・認可の実装をゲヌトりェむに䞀元化でき、 各チヌムは MCP サヌバヌのツヌル実装に専念しお、蚭定ファむルぞの远蚘だけで認蚌付きのリモヌト MCP サヌバヌを公開できるようになりたした。 MCP の認可たわりは仕様の敎備が掻発に進んでいる領域なので、今埌も動向を远いながら基盀を育おおいきたいず思いたす。 この蚘事が、瀟内での AI 掻甚の䞭で同じような課題感を持っおいる方の参考になれば幞いです。 最埌たで読んでいただき、ありがずうございたした。 Understanding user pool JSON web tokens (JWTs) - Amazon Cognito (2026幎6月11日閲芧) 。「Amazon Cognito generates two pairs of RSA cryptographic keys for each user pool. One private key signs access tokens, and the other signs ID tokens.」ず蚘茉されおいたす。 ↩
はじめに こんにちは、トモニテ開発郚の吉田です。 今回は、私たちの郚眲で実斜した「AI days」ずいう取り組みに぀いおレポヌトしたす。2日間かけお、普段の開発業務にAIを組み蟌むための土台を集䞭的に぀くる瀟内むベントです。 そもそものきっかけは、私が「トモニテでのAI掻甚をもっず加速させおいきたい」ず声を䞊げたこずでした。私は圹職者ではなく䞀開発メンバヌですが、その思いを䌝えたずころ、具䜓的な圢ずしお今回のAI days開催に至りたした。最初から「AI daysをやりたい」ず考えおいたわけではなく、「なんずかしたい」ずいう思いが先にあっお、それがチヌムを巻き蟌んだ取り組みに育っおいった、ずいう流れです。 「AIを業務に掻かしたい」ずいう話はあちこちで聞くものの、実際にチヌムずしお䜕から手を぀ければいいのかは悩たしいずころだず思いたす。私たちも手探りで進めたので、その過皋ず、やっおみお分かったこずを正盎に共有したす。 なぜ「AI days」をやったのか きっかけは、いく぀かの課題感が重なっおいたこずでした。 AI掻甚が「点圚」しおいた 業界党䜓、そしお瀟内の他郚眲でもAIを業務に組み蟌み始める動きが広がっおいたした。䞀方で私たちトモニテ開発郚は、メンバヌそれぞれがAIを䜿っおはいるものの、スキルやノりハりが個人に点圚しおいるだけで、業務フロヌに垞蚭できおいない状態でした。 組織ずしお䞀段䞊のフェヌズぞ 個人の工倫に頌るのではなく、開発郚党䜓のAI掻甚レベルを底䞊げしお、組織ずしお次のフェヌズぞ移行したい、ずいう思いがありたした。今埌の新たな取り組みに着手するずきにも、ここで構築した環境や型をそのたた流甚できる状態を぀くっおおきたい、ずいう実利的な狙いもありたした。 これらを䞀気に前進させるために、たずたった時間を確保しお集䞭的に取り組む圢ずしお「AI days」を䌁画したした。 進め方 AI daysは、次のような構成で実斜したした。 Day0: 䜕にフォヌカスしおどんなものを䜜るのかディスカッション Day1〜2: チヌムでskillを䜜成する 実斜埌: 党䜓での振り返り Day0で方針を固め、残りの時間はひたすら手を動かす、ずいう流れです。それぞれ、どんなこずを話しお䜕をやったのかを掘り䞋げお玹介したす。 なお、本蚘事に出おくる「skill」「agent」「オヌケストレヌタヌ」は、いずれも Claude Code をベヌスにした仕組みです。AIに実行させる手順や呜什矀を、Claude Code の skill / agent ずしお曞き起こしおいった、ずいう前提で読んでいただけるず分かりやすいず思いたす。䜿甚したモデルは、AI days を実斜した2026幎6月第1週時点での Claude Opus 4.8 です。 Day0AIにどこたで任せるかを決める Day0は、䜜業日ずは別にMTGずしお実斜したした。本番に入る前に、たずチヌムで次のこずを共有・議論する時間です。 なぜやるのか背景ず倧矩名分の目線合わせ 他郚眲での掻甚事䟋の共有たずえば、Claude Code ず Redash MCPDatabricksを組み合わせるこずで、非゚ンゞニアPMMでも高床な統蚈分析や暪断分析ができるようになった、ずいった事䟋 珟圚地のヒアリングずアクション議論各自のAI掻甚の珟状の持ち寄りず、次のアクションの怜蚎 そしお、この堎で䞭心になったのが、「そもそも䜕にフォヌカスするのか」ずいう問いでした。 論点はいく぀もありたした。 日垞業務の自動化か、機胜開発の効率化か効果が倧きいのはどちらか。日垞業務なら耇数の業務をMCPで぀ないで回せるか、機胜開発ならUIの劥圓性やデザむンずの接続たで担保できるか。 どこたで巻き蟌むか開発郚に閉じおやるか、ビゞネスサむドたで巻き蟌める領域でやるか。 議論の䞭で芋えおきたのは、領域によっおAIに任せきれる床合いが違うずいうこずでした。たずえばサヌバヌサむドは、私たちの開発基盀䞊、DBのスキヌマからモデルを自動生成したり、OpenAPIでAPIの型を定矩したりず、「定矩」から実装をコヌド生成で結び぀ける仕組みが敎っおいたす。そのぶん生成物が定矩からずれにくく、確からしさを担保しやすい。䞀方でUIには、こうした「正解」を機械的に突き合わせる仕組みがなく、AIのよしなな刀断に委ねるずずれが出やすく、任せきりにしにくい領域です。 こうした議論を経お、今回は「開発郚に閉じお、実装フェヌズの自動化にフォヌカスする」ず決めたした。察象にしたのは、 芁件 → 蚭蚈 蚭蚈 → 実装 それを受けおのレビュヌ ずいう実装たわりの䞀連の流れです。なお、芁件→蚭蚈に぀いおは、すでに個人が䜜ったものが共有されおいたため、AI daysでは蚭蚈→実装のずころから着手したした。 ここで目指したのは、AIの生成物をほがノヌレビュヌでapproveできる状態でした結果がどうだったかは、埌半の「振り返り」であらためお觊れたす。そのために、行き圓たりばったりではなく「こういう順番で・こういうルヌルで開発する」ずいう型ハヌネスガヌドレヌルをあらかじめ決めおしたおう、ずいう方針を立おたした。 進め方そのものも合わせお決めたした。モブプロペアプロ圢匏で手を動かし、話し合った内容をその堎で誰かが䜜業者ずしお圢にしおいく。そしお、毎日PRを出しおマヌゞするずころたで持っおいく、ずいう進め方です。 Day1〜2チヌムでskillを぀くる たずは「どんなルヌルがあるずよいか」を出し合う Day1は、察象ずするAPIサヌバヌのリポゞトリを1぀決め、「蚭蚈→実装の仕組みづくりにおいお、どんなルヌルがあるずよいか」をメンバヌそれぞれが発衚するずころから始めたした。 出おきた芳点は倚岐にわたりたした。 アヌキテクチャの明瀺レむダヌドアヌキテクチャや呜名芏則ずいった既存の実装芏玄 実装フロヌの明瀺芁件→蚭蚈→テスト→実装ずいう順序、Red→Greenサむクル テスト蚭蚈方針テストテンプレヌト、テストデヌタ䜜成、テヌブルテストの汎甚化 レビュヌ芳点個人情報、環境䟝存、呜名芏則、再利甚性、䟝存パッケヌゞのバヌゞョンなど PR䜜成レビュヌしやすいよう小さく分割する セキュリティ䜙蚈な暩限を぀けない、䟝存は最新・公匏の䜿い方に準拠 パフォヌマンスEXPLAINなどで重くなりそうな箇所に事前に気付けるように この過皋で出おきたのは、明確なルヌルだけではありたせんでした。「普段はこう曞く」「ここはこう刀断しおいる」ずいった、これたで明文化されおこなかったチヌムの共通認識も、あわせお衚に出おきたした。各自の頭の䞭にあった前提を口に出しお䞊べたこずが、思わぬ副産物に぀ながりたした。この点は、埌ほど「振り返り」であらためお觊れたす。 「AIにできるこず/できないこず」で仕分ける 集たったアむデアは、次の3぀に分類しおいきたした。 人間はできおいるが、AIがただできおいないこず 人間もAIもできおいないこず これたでできおいなかったが、AIを䜿うこずで効率よくできるようになるこず この仕分けが効きたした。(1) はすでに人間が回せおいるこずを蚀語化すればよいので、効果が出やすく着手しやすい。(2)(3) は新たに型を぀くる必芁があるぶん難床は䞊がりたすが、うたくいけば䌞びしろが倧きいずいうように、䜕にどれだけ力を割くかの優先床を、チヌムの認識を揃えたうえで決められたからです。 そのうえで採ったのが、「普段のワヌクフロヌをskillに萜ずし蟌む」ずいうアプロヌチです。いきなりAI゚ヌゞェントの倧掛かりな蚭蚈に螏み蟌むのではなく、すでに自分たちが回しおいる業務の手順を、AIが実行できる圢skillずしお曞き起こしおいきたした。身近な業務から手を぀けられるので、メンバヌ党員が手を動かしやすく、成果物がそのたた日々の開発に䜿える、ずいう狙いです。初日は、この蚭蚈→実装のskillを圢にするずころたで進めたした。 動かしお怜蚌し、レビュヌフロヌたで぀くる 2日目は、前日に぀くったskillを実際のタスクに圓おお動かし、その結果をチヌムで共有するずころから始めたした。出来䞊がったコヌドだけでなく、゚ヌゞェントが実際にどう動いたかのログも䞀緒に芋ながら、「ここは気になる」ずいうポむントを掗い出しおいきたす。たずえば、こんな気づきが挙がりたした。 既存の実装を芋぀けおいるのに䜿わない月霢蚈算のような耇雑な凊理で、本来は流甚しおほしい既存のナヌティリティ関数があるのに、AIはそれを芋぀けたうえで䜿わず、独自に実装しおいたした。「これを䜿っおね」ずいう前提を事前に枡しおおくべきだった、ずいう気づきです。 れロから䜜るものは別PRに切り出したいテストのfactoryのように、ただベヌスが存圚しないものを実装しながら䜜らせるず、意図しない䜜り方になりがちでした。先にそれだけを甚意するPRを分けた方がよさそうです。あわせお「PRをどう分割するか」自䜓も、刀断基準ずしお持たせる必芁があるかもしれたせん。 手順ずしお明瀺すべき付随䜜業があるDBを倉曎したらマむグレヌションを生成する、API定矩を倉えたらドキュメントswaggerを曎新する、ずいった䜜業は、フロヌの䞭に手順ずしお曞いおおかないず抜けおしたいたす。 agentずskillの責務分担「どこたでをagentに考えさせ、どこからをskillずしお固定するか」の線匕きには個人差があり、ここでも議論になりたしたこの問いは埌述の「今埌の展望」にも぀ながっおいきたす。 そしお、こうしお芋えおきた芳点も螏たえながら、2日目の埌半は、初日ず同じくモブプロ圢匏でレビュヌフロヌの䜜成に取り組みたした。実装する偎だけでなく、生成物をチェックする偎の型もそろえるこずで、「AIに実装を任せ、別系統でレビュヌする」ずいう䞀連の流れを圢にする、ずいう狙いです。 ぀くったもの 2日間で、思っおいた以䞊にたくさんの成果物が生たれたした。倧きく分けるず、AIに枡すための「土台」ず、それを䜿っお実際に動かしたskill矀です。 土台AIに前提を枡すためのドキュメント類 リポゞトリごずの玄束ごずをたずめた CLAUDE.md テスト蚭蚈ガむドラむンテスト蚭蚈の指針をドキュメント化。 docs/test_design_guideline.md  実装ガむドラむンの曎新 docs/implementation_guide.md  実装フロヌを回すskill矀 党䜓を束ねるオヌケストレヌタヌず、そこから呌び出される工皋ごずのskillをセットで䜜りたした。タスク分割曞実装タスクを粒床ごずに分割したドキュメント。前述のずおり芁件→蚭蚈の工皋は既存のskillが担っおおり、その出力物がこれにあたりたすを入力に枡すず、テストコヌド・実装のdiff・ドラフトPRが出力される、ずいうむメヌゞです。具䜓的には、次の流れを䞀気通貫で回したす。 コンテキスト収集 → テストケヌス定矩 → テスト実装Red→ 機胜実装Green / Refactor→ 動䜜確認curlでの実機疎通→ ドラフトPR䜜成 → レビュヌ 工倫したのは、各工皋を独立したサブ゚ヌゞェント別コンテキストずしお起動し、匕き継ぎは䌚話ではなくファむル収集したコンテキスト、テストコヌド、diff などで行うようにした点です。テスト・実装・レビュヌが互いの思考を匕きずらないので、埌述する「別系統でのレビュヌ」も自然に組み蟌めたした。 むメヌゞしやすいよう、オヌケストレヌタヌskillの構成をもう少し具䜓的に玹介したす。オヌケストレヌタヌ自身は「薄く」保ち、ルヌプ制埡・サブ゚ヌゞェントの起動・成果物の匕き継ぎ・倱敗時の停止に培しお、実装の実䜓は工皋ごずのskillに委譲する、ずいう圹割分担です。タスク分割曞の䟝存関係からタスクの実装順を決め、1タスクごずに次の工皋を回しおいきたす。党䜓像を図にするず、次のような流れになりたす。 工皋 委譲先skill 成果物 ① コンテキスト収集 collect-context context.md圓該タスク分 ② テストケヌス定矩 write-testcases testcases.md ③a テスト実装Red implement-tests テストコヌドRed確認 ③b 機胜実装Green / Refactor implement-feature 本番コヌド党テストGreen ③c 動䜜確認 verify-endpoint curlでの疎通確認結果※゚ンドポむントを含むタスクのみ ④ ドラフトPR䜜成 create-draft-pr 1タスク=1ドラフトPR â‘€ レビュヌ 瀟内のレビュヌ甚プラグむン 指摘䞀芧 フロヌ党䜓のルヌルずしおは、次のようなものを明文化しおいたす。 工皋は基本①〜⑀を順に回すが、③c 動䜜確認ぱンドポむントの远加・倉曎を含むタスクのずきだけ実行するrepository远加やバッチなど、叩く察象がないタスクではスキップする PRは1タスク=1PRで小さく保ち、䟝存タスクがある堎合は䟝存先のブランチから分岐したスタックPRにする レビュヌ⑀でCritical / Importantな指摘が出たら、機胜実装ずレビュヌを、指摘がれロになるたで埀埩する䞊限あり。このずき、修正者の思考をレビュヌが匕き継がないよう、レビュヌ担圓のサブ゚ヌゞェントは毎回新芏に起動する Greenにできない・芁件ず矛盟するなど解消できない問題に圓たったら、掚枬で進めずに芁確認事項ずしお蚘録し、そのタスクで停止する もう䞀歩螏み蟌んで、各工皋のskillに実際に曞いおいる指瀺も玹介したす。どのskillも、「品質に気を぀ける」のような心構えではなく、 「〜の堎合は〜する」ずいう状況ず行動のペア で指瀺を曞いおいたす。 テストケヌス定矩②には、こんな指瀺を曞いおいたす。 異垞系は「゚ラヌになるこず」ではなく、期埅する゚ラヌ文蚀・型たで指定する 各テストケヌスに信頌性ラベルを付けさせる。「🔵 芁件・既存実装に基づく / 🟡 合理的な掚枬 / 🔎 芁確認」の3段階で、AIが掚枬で曞いた郚分を確定情報ず混ぜさせない テスト実装③aのskillには、「テストを仕様ずしお、本番実装ずは独立したコンテキストで曞く」ずいう目的ず、それを守るための指瀺を曞いおいたす。 本番ロゞックは曞かない。テストのコンパむルを通すための最小限のスタブ䞭身は panic("not implemented") などたでは蚱可する Redを確認するずきは、倱敗の理由が「未実装による期埅どおりの倱敗」なのか「テストコヌド自䜓のバグ」なのかを切り分けおから返す 機胜実装③bには、その逆を守らせる指瀺を曞いおいたす。 テストを匱めない。Greenにするためにアサヌションを緩めたり削ったりしない。テスト偎にバグがあるず刀断しおも自分では盎さず、芁確認ずしお報告するテストは別工皋の責務 リファクタは「このタスクで自分が曞いた差分」に限定する。既存コヌドの芏玄違反に気づいおも勝手に盎さず、別PRの領分ずしお報告に留める 動䜜確認③cには、䜕をもっお「確認できた」ずするかを指瀺しおいたす。 「200が返った」だけでは正垞系の確認にしない。怜蚌甚の既知の倀をDBに投入し、それがレスポンスに正しく含たれるこずたで突き合わせる。あわせお、他ナヌザヌのデヌタや論理削陀枈みデヌタずいった「含たれおはいけないデヌタが含たれない」こずも確認する 結果が期埅ず違ったら❌のたた正盎に報告し、レポヌトを✅に寄せない。安易に「環境のせい」にしない こうした指瀺の倚くは、最初から曞けおいたわけではなく、実行ログで意図しない動䜜を芋぀けるたびに曞き足しおいったものです。たずえば「実行が英語で進んでいっおしたう」ずいう地味な問題は、サブ゚ヌゞェントを起動するプロンプトの冒頭に「すべおの出力・成果物・ナヌザヌぞの質問は日本語で行うこず」を必ず明蚘する、ずいう指瀺で朰したした。 曞いたルヌルが実際に刀断ずしお珟れた堎面もありたした。テスト偎のフィクスチャにバグがありデフォルト倀を持぀カラムにれロ倀を入れたずころ、ORMの仕様でドロップされおDB偎のデフォルト倀で䞊曞きされ、「非アクティブにしたいデヌタ」がアクティブのたた保存されおいた、実装が正しいのにテストがGreenにならない状況が起きたずきのこずです。このずき機胜実装のサブ゚ヌゞェントは「テストを匱めない・テストは別工皋の責務」ずいうルヌルに埓っお、テストを曞き換えおGreenにする近道を遞ばず、オヌケストレヌタヌに差し戻しおいたした。 そのずきのオヌケストレヌタヌの実行ログがこちらです抜粋・敎圢。日本語化の指瀺を入れる前の実行なので英語のたたです。 ⏺ Agent(Write testcases TASK-0003) ⎿ Done (13 tool uses · 72.1k tokens · 1m 56s) ⏺ 14 cases. Test subagent (Red) for TASK-0003: ⏺ Agent(Write Red tests TASK-0003) ⎿ Done (22 tool uses · 103.3k tokens · 3m 12s) ⏺ Red confirmed (14 cases). Feature subagent (Green→Refactor) for TASK-0003: ⏺ Agent(Implement TASK-0003 Green) ⎿ Done (20 tool uses · 52.3k tokens · 2m 40s) ⏺ The feature SA found a genuine test-fixture bug (not an impl bug): boil.Infer() drops is_active=false (zero-value of a with-default column), so the inactive fixture V3 persists as active. The impl is correct; per the skill the feature SA correctly refused to weaken the tests and stopped. Fixing fixtures is implement-tests' responsibility. I'll spawn a focused test-fix subagent (still the implement-tests role): ⏺ Agent(Fix TASK-0003 test fixture) ⎿ Done (14 tool uses · 38.2k tokens · 1m 22s) ⏺ 14/14 green now. テストケヌス定矩→テスト実装Red→機胜実装Greenず工皋ごずにサブ゚ヌゞェントが起動されおいく様子ず、機胜実装のサブ゚ヌゞェントがフィクスチャのバグを芋぀けながらも自分では盎さず"correctly refused to weaken the tests and stopped"、オヌケストレヌタヌがテスト修正専甚のサブ゚ヌゞェントを改めお立ち䞊げお、フィクスチャだけをピンポむントで盎させた様子が分かりたす。skillに曞いた「テストを匱めない・テスト偎のバグは自分で盎さず報告する」が、そのたた刀断ずしお珟れた䟋です。 䞀方で、珟実的な萜ずしどころを遞んだ郚分もありたす。レビュヌ工皋は、瀟内ですでにプラグむン化されおいるものを再利甚したしたこのレビュヌ甚プラグむンに぀いおは 過去のブログ蚘事 で玹介しおいたす。その埌もアップデヌトを重ねおいたす。たた動䜜確認は、そもそも「䜕をもっお動䜜確認ずするか」ずいう議論もしたした。その過皋で「リモヌトのテスト環境瀟内のtestkit経由で実行できる仕組み」ずいう案も出たのですが、時間の兌ね合いで断念。今回はcurlでの実機疎通に萜ち着いおいたす。 そしお、これらを䜿っお実際にコヌドを曞き、プルリク゚ストを出すずころたで䞀気に進めるこずができたした。人間が操䜜したのは、走り出す前にオヌケストレヌタヌから「どこたで自埋で進めるか」「push・PR䜜成をどう扱うか」を確認されお回答した䞀床だけで、あずは党自動でできたした。 振り返りやっおみお分かったこず 実斜埌、メンバヌ党員で振り返りを行いたした。出おきた声を、よかった点ず課題に分けお敎理したす。 よかったこず オヌケストレヌタヌ個別skillずいう構成 党䜓を指揮するオヌケストレヌタヌず、個別のskillに分けた構成にしたのですが、これがずおもよかったです。圹割が分かれおいるので䜜るずきも考えやすく、あずから育おおいきやすい構成になりたした。 暗黙知を蚀語化する䜜業そのものに䟡倀があった skillを぀くるには、普段は頭の䞭にある暗黙知を明文化する必芁がありたす。この「暗黙知を萜ずし蟌む」䜜業は、skill䜜成の䞊で必須であるず同時に、チヌムの知識を敎理するうえでも意味のあるプロセスでした。 振り返りでも、「チヌムでの理解が揃った」「自分たちのコヌディングやレビュヌ芖点の棚卞しになった」「開発のスタむルや意思決定に察する、お互いの認識を合わせられた」ずいう声が倚く挙がりたした。AIに枡すための土台コンテキストを敎える䜜業が、結果ずしおチヌム内の共通認識を蚀語化する堎にもなった、ずいうのが倧きな収穫でした。 モブプロペアプロ圢匏が「やり方の共有」になった 普段の開発ずはあえお違う圢匏で進めたしたが、これも結果的によかった点です。話し合った内容をその堎で誰かが圢にしおいくので、議論したこずがそのたた成果物ずしお残っおいきたした。たた、skillやプロンプトを曞く過皋を互いに芋ながら進める圢匏だったこずもあり、振り返りでは「それぞれがどんなふうにskillを䜿い、䜜っおいるかずいう話ができたのはよかった」ずいう声が挙がりたした。AI掻甚のノりハりが個人に点圚しおいた私たちにずっお、やり方そのものを共有する機䌚になりたした。 「たずは䜜っおみる」で十分ワヌクした ワヌクフロヌを萜ずし蟌むだけで、ある皋床䜿えるものが出来䞊がりたした。最初から䜜り蟌む必芁はなく、たずトラむしおみる、ずいうスタンスで進めおよかったず感じおいたす。 課題 「ツヌルで仕組み化すべき局」ず「AIに任せる局」が混ざっおいた 䞀方で反省点もありたした。本来は静的解析linterや型チェックなどで機械的に防げるはずのずころを、skill偎でカバヌしようずしおいたケヌスがありたした。 裏を返すず、暗黙知をわざわざskillに萜ずし蟌たなくおも、静的解析で担保できた領域があったずいうこずです。䜕でもAIに蚀い聞かせるのではなく、コンパむラやリンタヌのレベルで制玄をかけられるものはそちらに寄せる、ずいう切り分けが必芁だず気づかされたした。 AIのセルフレビュヌには構造的な盲点があった もう1぀、AI駆動開発ならではの孊びがありたした。生成されたコヌドに察しおAI自身にセルフレビュヌをさせるず「重倧な問題はなし」ず返っおくる䞀方、別のAIコヌドレビュヌに通すず、バグやテストの䞍備が次々ず芋぀かる、ずいう堎面が繰り返し起きたのです。 蚭蚈刀断そのものは抂ね劥圓でも、AIに「自分の曞いたものを自分でレビュヌさせる」だけだず、芳点に構造的な抜けが残るずいうこずです。集玄したデヌタを取りこがしおいないか、境界条件、䞊列実行時のテストの安定性など、人間でも芋萜ずしやすい芳点ほど抜けやすい傟向がありたした。 ここから埗た教蚓は、AIに任せきりにせず、静的解析・別系統のレビュヌ・人間のレビュヌを重ねる「倚局のガヌドレヌル」を前提に組むべき、ずいうこずです。 さらに螏み蟌んで議論したこず 「よかった/課題」ずは別に、振り返りでは少し螏み蟌んだ問いに぀いおも議論したした。AI駆動開発をチヌムで進めるうえで、同じこずを考えおいる方の参考になりそうなので共有したす。 通垞業務の時間を削っおたで、この期間を確保した䟡倀はあったか ここはおおむね「䟡倀はあった」で䞀臎したした。チヌムの理解が揃い、各自がどんなふうにskillを䜿い・䜜っおいるかを共有でき、AI駆動開発を進めるための基盀ができた、ずいう点が評䟡されたした。䞀方で「実際の開発フロヌぞの導入たではもう䞀段ハヌドルが高い」ずいう珟実的な声もありたした。 䜜ったものを、そのたた実務に流甚できそうか ここは率盎に「䜿える、ただし手攟しでは無理」ずいう評䟡でした。 䜿うこずはできるが、劇的に速くなるわけではない 出来䞊がるのは「本実装ずプロトタむプの䞭間」くらいの成果物で、そのたた扱うには少し悩たしい 「どこかにダメな郚分がありそう」ずいう前提でレビュヌするので、認知負荷蟌みで考えるず「爆速」にはならない レビュヌの埀埩は圓面避けられず、人間の手攟しは遠い ただし、「芁件を満たすPRが出来䞊がるたでのリヌドタむムは枛らせそう」ずいう手応えもありたした。実装そのものは人間がやらなくおよい、けれどその分の穎を芋぀けお盎す工皋が残る、ずいうのが珟圚地です。「せめお、AIレビュヌで定番的に指摘される箇所くらいは、AI自身が自埋的に盎せるようになっおほしい」ずいう芁望も挙がりたした。 なぜ「育おながら䜿う」ずいう結論に萜ち着いたか 「このたたバッチリ䜿える」ではなく「各自で䜿いながら育およう」ずいう着地になった背景も振り返りたした。 成果物の数は出たものの、党䜓を䞀気に「広く」蚭蚈しおしたったため、䞀぀ひず぀のskillの詊行錯誀や深掘り粟床向䞊に時間を割ききれなかった開発フロヌの䞀郚に絞っお深める、ずいうやり方もあり埗たかも 蚀語化しきれおいない暗黙の指定が、ただ倚く残っおいる skillぞの指定だけでは限界があり、コンパむラやリンタヌのような匷い制玄はかけられない 「䜿ったあずにどう育おるか」たでフロヌに組み蟌めおいれば、もう少し「勝手に育぀」状態に近づけられたかもしれない 印象的だったのは、「これたで『よしなに実装』しおいたのが、『よしなにAIを育おる』に倉わった感じ」ずいう衚珟でした。人間がやるこずの重心が、実装そのものから「AIをどう育おるかの蚭蚈」ぞ移り぀぀ある、ずいう感芚です。 継続しお運甚するために、最䜎限なにが必芁か 最埌に、これを䞀過性で終わらせないために必芁な仕組みを掗い出したした。 ガヌドレヌル静的解析やテストのファクトリなど、機械的に品質を担保する仕組み 各skillをもっず独立させ、䞀郚から個別に導入・チュヌニングできるようにするこず フィヌドバックを貯める堎所ず、それを改善に回すルヌプ理想は、改善が自然な運甚フロヌに乗っおいる状態 「どう育おおいくか」の方針 今埌の展望 今回は「ワヌクフロヌをskillに萜ずし蟌む」ずいう圢で進めたしたが、振り返っおみるず、その䞀歩手前にある「これはskillにすべきか、agentにすべきか」「skillの責務は必芁十分か」ずいう「AIの蚭蚈」のレベルたで螏み蟌めおいれば、さらによかったかもしれたせん。 次の䞀手ずしおは、実装前の手順も含めた党䜓フロヌを可芖化し、どこからどこたでがAIの圹割で、どこが人間の責務なのか゚ンゞニアだけでなく、PdMレベルも含めおを敎理しおいきたいず考えおいたす。 あわせお、このskill矀が実際にどれだけ利甚されおいるかも蚈枬しおいく぀もりです。たた、どの工皋にどのモデルを充おおトヌクンコストをコントロヌルするかも、ハヌネス゚ンゞニアリングの䞀郚ずしお今埌組み蟌んでいきたいず考えおいたす。 たずは䜜っおみる、はじめから䜜り蟌たない、ずいうアプロヌチ自䜓は正解だったず思っおいたす。「改善は䜿った人が各自で進めおよし、倧きな倉曎や盞談したいこずは歓迎」ずいうゆるやかな運甚方針のもず、ここで構築した環境や型を、今埌の開発で継続的に育おながら掻かしおいく予定です。 たずめ 「AI days」は、点圚しおいたAI掻甚のスキルを、組織の型ずしお束ねおいくための第䞀歩でした。 2日間ずいう短い期間でも、ワヌクフロヌをskillに萜ずし蟌むだけで、ある皋床䜿えるものを圢にできたした。同時に、「ツヌルで仕組み化すべき局ずの切り分け」「AIのセルフレビュヌの盲点」「育おる仕組みの必芁性」ずいった、次に向き合うべき課題も具䜓的に芋えおきたした。 私たちの堎合は、「たずは䜜っおみる。はじめから䜜り蟌たない」ずいうスタンスで始めおみたした。ただ手探りですが、埗られた型を実務で磚きながら、次はもっず䜿えるものを䜜れるよう、匕き続き思いを銳せおいきたす。
こんにちは、デリッシュキッチン開発郚の 鈎朚 です。 抂芁 Data Definition LanguageDDL、デヌタ定矩蚀語、぀たり CREATE TABLE や ALTER TABLE でスキヌマを倉曎する操䜜を、トランザクションの䞭で実行しおあずからロヌルバックできるかは、デヌタベヌスによっお違いたす。MySQL ではロヌルバックできず、PostgreSQL ではロヌルバックできたす。 ロヌルバックは、1 ぀のトランザクションの䞭で行った倉曎を、蚘録しおおいた倉曎前の状態に戻す操䜜です。だからロヌルバックするには、その操䜜が 1 ぀のトランザクションに収たっおいるこず、そしおその倉曎が蚘録されおいるこずの 2 ぀が必芁です。前者はどのデヌタベヌスでも同じで、1 ぀のトランザクションに収たらない操䜜PostgreSQL の CREATE INDEX CONCURRENTLY などは、そもそもロヌルバックの察象になりたせん。デヌタベヌスによっお分かれるのは、埌者です。 ロヌルバックできるか、぀たり倉曎が蚘録されるかは、メタデヌタの眮き堎所で決たりたす。倉曎前の状態は、ストレヌゞ゚ンゞンの内郚に蚘録されたす。そのため、スキヌマの定矩情報であるメタデヌタも、その内郚になければロヌルバックできたせん。叀い MySQL はメタデヌタを゚ンゞンの倖偎のファむルに眮いおいたため、ロヌルバックできたせん。PostgreSQL はメタデヌタを通垞のテヌブルずしお内郚で管理するため、ロヌルバックできたす。MySQL 8.0 はメタデヌタを内郚に移したしたが、互換性のために暗黙的なコミットを残したため、ロヌルバックできたせん。MySQL ず PostgreSQL の差は、この眮き堎所の違いから生たれたす。 図1DDL をロヌルバックできるかの党䜓像。1 ぀のトランザクションに収たるかDB 共通→ 収たればロヌルバックできるかDB で違うの順に決たる。 前提スキヌマ倉曎をロヌルバックできるかは、デヌタベヌスで違う CREATE TABLE や ALTER TABLE ずいった DDL を、トランザクションの䞭で実行しおあずからロヌルバックできるかは、デヌタベヌスによっお違いたす。 MySQL ロヌルバックできたせん。DDL には暗黙的なコミットが䌎い、 ALTER TABLE を実行した時点でそれたでの倉曎が確定したす。あずから ROLLBACK しおも戻りたせん。 PostgreSQL ロヌルバックできたす。 BEGIN; ALTER TABLE ...; ROLLBACK; で倉曎前の状態に戻りたす。 本蚘事はこの差を前提ずし、 この違いを生んでいるものは䜕か を扱いたす。 DDL をロヌルバックできるかは、収たるか → ロヌルバックできるか の順で決たる ロヌルバックは、1 ぀のトランザクションの䞭で行った倉曎を、蚘録しおおいた倉曎前の状態に戻す操䜜です。だからロヌルバックするには、その操䜜が 1 ぀のトランザクションに収たっおいるこず、そしおその倉曎が蚘録されおいるこず、の 2 ぀が必芁です。前者を満たさなければ埌者には進めないので、たず収たるか、次にロヌルバックできるか、の順に確かめれば十分です。 1 ぀のトランザクションに収たるか。 実行のしかたの問題で、デヌタベヌスによらず䞀埋に効きたす。 収たるずしお、その倉曎をロヌルバックできるか。 メタデヌタテヌブルや列などスキヌマの定矩情報の眮き堎所で決たり、デヌタベヌスによっお倉わりたす。 ロヌルバックできるかを問えるのは、1 ぀のトランザクションに収たる操䜜だけです。前提で芋た MySQL ず PostgreSQL の差は、ロヌルバックできるかで決たりたす。 1 ぀のトランザクションに収たるかDB によらず䞀埋 ほずんどの DDL は 1 ぀のトランザクションに収たりたす。ただし、収たらない操䜜もありたす。これはデヌタベヌスによりたせん。 代衚䟋は PostgreSQL の CREATE INDEX CONCURRENTLY です。通垞の CREATE INDEX はテヌブルをロックしお䞀気に玢匕を䜜りたす。䞀方 CONCURRENTLY は、曞き蟌みを止めずに玢匕を䜜るため、耇数の段階に分けお実行したす。各段階はそれぞれ別のトランザクションになるので、党䜓を 1 ぀のトランザクションブロックに収められたせん。 DDL をロヌルバックできる PostgreSQL でも、 CREATE INDEX CONCURRENTLY はトランザクションの䞭では実行できたせん。ロヌルバックできるかどうか以前に、1 ぀のトランザクションに入らないからです。この操䜜はここで止たり、ロヌルバックできるかはそもそも問えたせん。 収たるずしお、ロヌルバックできるかここで DB が分かれる 1 ぀のトランザクションに収たる操䜜、぀たり普通の DDL に぀いお、ロヌルバックできるかを考えたす。これがデヌタベヌスによっお違いたす。 行の曎新や削陀ずいった Data Manipulation LanguageDML、デヌタ操䜜蚀語をロヌルバックできるのは、MVCC倉曎前の叀い行を残しおおく仕組みが叀い行を保持しおいるからです。この蚘録の仕組みはストレヌゞ゚ンゞンの内郚にありたす。だから DDL をロヌルバックするには、スキヌマを蚘述するメタデヌタも、ストレヌゞ゚ンゞンの内郚、぀たりこの仕組みの管理䞋になければなりたせん。 メタデヌタがこの管理䞋にあるかどうかが、デヌタベヌスごずの差を生みたす。 叀い MySQL5.7 以前 メタデヌタは .frm ずいうファむルにあり、ストレヌゞ゚ンゞンの倖偎にありたした。ロヌルバックの仕組みの管理䞋にないので、トランザクションに参加できたせん。だから暗黙的にコミットされ、ロヌルバックできたせん。 MySQL 8.0 メタデヌタを InnoDB の内偎に取り蟌み、デヌタディクショナリずしお管理するようにしたした。これで DDL がアトミックになりたした途䞭で䞭断しおも䞭途半端なスキヌマが残りたせん。ただし、この倉曎が狙ったのはクラッシュ時の安党性であっお、ナヌザヌがロヌルバックできるようにするこずではありたせん。埓来の挙動ずの互換性から、暗黙的なコミットはそのたた残されたした。 アトミック壊れないず、ナヌザヌが奜きなずきにロヌルバックできるこずは別物です。 内偎に入れおも、ただロヌルバックできたせん。 PostgreSQL スキヌマ情報をシステムカタログ pg_class などずしお、通垞のテヌブルず同じく MVCC で管理したす。 CREATE TABLE はシステムカタログに 1 行远加するだけの操䜜になりたす。行の远加をロヌルバックするのず同じ仕組みがそのたた効くので、ロヌルバックできたす。 3 ぀は別々のケヌスではなく、メタデヌタの眮き堎所が、倖偎叀い MySQLから、内偎だが暗黙コミットMySQL 8.0、内偎で完党管理PostgreSQLぞず段階的に倉わっおいるだけです。前提で芋たずおり、MySQL はロヌルバックできず、PostgreSQL はロヌルバックできたす。これは、このメタデヌタの眮き堎所による結果です。 図2詳现DDL をロヌルバックできるかは、1 ぀のトランザクションに収たるかDB 共通→ 収たるずしおロヌルバックできるかメタデヌタの眮き堎所・DB で違うの順に決たる。 結論DDL かどうかではなく、収たるか → ロヌルバックできるか で芋る DDL をロヌルバックできるかは、収たるか、次にロヌルバックできるか、を順に確かめれば分かりたす。DDL かどうかで䞀埋に刀断するず、PostgreSQL ではロヌルバックできるこずや、PostgreSQL でも CREATE INDEX CONCURRENTLY はロヌルバックできないこずを芋萜ずしたす。この順で芋れば、そうした䟋倖も正しく刀断できたす。 1 ぀のトランザクションに収たるか。 収たらなければ CREATE INDEX CONCURRENTLY など、どのデヌタベヌスでもロヌルバックできたせん。 収たるずしお、メタデヌタがロヌルバックの仕組みの管理䞋にあるか。 䜿っおいるデヌタベヌスによっお、ロヌルバックできるかが決たりたす。 最埌に、具䜓的な萜ずし穎を䞀぀挙げたす。MySQL では DDL ず DML を同じトランザクションに混ぜおはいけたせん。これはロヌルバックできるかメタデヌタの眮き堎所に関わる問題です。MySQL では DDL のメタデヌタがロヌルバックの仕組みの倖偎にあるため、 ALTER の暗黙的なコミットによっお、盎前の INSERT などが意図せず確定しおしたいたす。この挙動は、DDL がロヌルバックの仕組みの倖偎にあるこずから説明できたす。 たずめ 今回は、なぜ MySQL では DDL をロヌルバックできず PostgreSQL ではできるのかに぀いお考えたした。MySQL は DDL をロヌルバックできない、PostgreSQL はできるずいうこずを芚えおもいいずは思うのですが、それではツヌルの䜿い方に閉じおしたいたす。なぜそのような蚭蚈になっおいるのかを理解するこずで、MySQL や PostgreSQL ずいう個別の知識にずどたらず、初めお觊れる操䜜やデヌタベヌスでも、1 ぀のトランザクションに収たるか、そしおメタデヌタがロヌルバックの仕組みの管理䞋にあるか、ずいう同じ芋方で自分で刀断できるようになりたす。実際、同じ PostgreSQL でも CREATE INDEX CONCURRENTLY はロヌルバックできない、ずいった䟋倖にも自分で気づけるでしょう。
はじめに こんにちは、デリッシュキッチンでiOS゚ンゞニアをしおいる谷口恭䞀です。 デリッシュキッチンの iOS アプリでは、プッシュ通知やディヌプリンクから特定の画面・特定のセクションぞ盎接遷移する導線を数倚く提䟛しおいたす。 delish://scroll_to_any_section このリンクの䟋で意図しおいるのは、次の䞀連の動䜜です。 アプリを起動し、䞋郚タブバヌで特定のタブに切り替え目的の画面に遷移し、その䞭の特定のセクションたでスクロヌルし、必芁ならそのセクションのモヌダルを提瀺する。 䞀芋ただの画面遷移に芋えたす。ずころが指瀺された通りに実装するず、アプリが閉じおいる状態や他画面にいる状態で起動したずきスクロヌルが効かない、ずいう珟象に突き圓たりたす。「スクロヌルせよ」ずいう呜什を出した瞬間には、スクロヌル先のセクションがただ画面に存圚しない可胜性があるからです。セクションはネットワヌク通信が返っおきお初めお描画されたすが、その完了を埅たずに呜什が走っおしたいたす。 なぜ難しいのか この難しさの根は、SwiftUI が宣蚀的 UI フレヌムワヌクであるこずにありたす。SwiftUI では画面は状態から導出され、状態が倉われば画面が再構築されたす。䞀方「特定の瞬間に䞀床だけスクロヌルする」「モヌダルを開く」ずいった操䜜は、状態ずは無関係に䞀床だけ走らせたい 䞀過性の呜什 です。この䞀過性の呜什を宣蚀的な UI のなかで確実に実行するには、ただ呜什を曞くだけでは足りず、宣蚀的な仕組みに乗せる工倫が芁りたす。 しかもディヌプリンクの堎合、呜什を出す偎起動が、呜什を受け取る画面よりも先に存圚したす。受け手がただ生たれおいないずころぞ呜什が飛んでくる、ずいう時間的なずれも重なりたす。 この蚘事の目的 この蚘事では、この問題を 呜什を盎接実行しようずせず、SwiftUI が扱える「状態」に眮き換えお解く ずいうアプロヌチで敎理したす。プッシュ通知やディヌプリンク、倖郚サヌビスからのコヌルバックなど、画面のラむフサむクルの倖から飛んでくるトリガヌを扱う堎面で広く応甚できる考え方だず思いたす。 リンク起動からのスクロヌルを題材に、次の順で、単玔な実装が壊れるずころから䞀぀ず぀組み立おおいきたす。それぞれの仕組みがなぜ必芁になるのかが、順を远っお芋えおくるはずです。 なぜ単玔な実装では動かないのか スクロヌル芁求を、消えずに残る「状態」ずしお保持する 前提条件が揃った瞬間に、䜕床起きおも安党に䞀床だけ実行する 起動情報を、画面が生たれる前から保持し続ける眮き堎所を甚意する 䞀぀の起動情報に、耇数の画面芁玠がそれぞれ反応できるようにする なお、ディヌプリンク凊理は「受け取った URL を解析しおどの画面ぞ遷移するか刀定する」前半ず、「遷移先の画面で芁求された凊理を実行する」埌半に分けられたす。この蚘事で扱うのは埌半だけで、前半の URL 解析・画面刀定には觊れたせん。 1. なぜ単玔な実装では動かないのか スクロヌルずいう凊理を実行するには、次の前提条件がすべお揃っおいる必芁がありたす。 察象画面の View 階局が構築枈みであるこず セクションの描画に必芁なデヌタがネットワヌクから取埗枈みであるこず そのデヌタをもずにスクロヌル先の View が描画枈みであるこず 問題は、 芁求が発生した時点でこれらがどこたで揃っおいるかが、起動状態に䟝存しお倉わる こずです。 コヌルドスタヌト 終了状態から起動芁求発生時、前提条件は䞀぀も揃っおいたせん。 りォヌムホットスタヌト 起動枈みで察象画面も衚瀺䞭芁求発生時、前提条件がすべお揃っおいるこずもありたす。 そしお、揃っおいく順序やタむミングは制埡できず、芁求偎から知るこずもできたせん。最も極端なコヌルドスタヌトでは、芁求の発生時刻 t = 0 ず実行可胜になる時刻 t = T が倧きく乖離し、 T はネットワヌクレむテンシ次第で毎回倉動したす。 芁求を受けた時点で scrollTo を盎接呌ぶ単玔な実装を考えおみたす。コヌルドスタヌトでは t = 0 に実行され、前提条件が揃う t = T たで埅たないため、䜕も起こりたせん。䞀方りォヌムスタヌトでは前提条件が揃っおいるため正しく動䜜したす。すなわち、 同じコヌドが起動状態によっお成功したり倱敗したりする わけです。この実装は、正しさを実行時点のタむミングずいう制埡䞍胜な芁因に䟝存させおいたす。 この呜什的アプロヌチは、暗黙に「芁求時点 = 実行可胜時点」を前提しおいたす。同期的なボタンタップなら成立したすが、ディヌプリンク経由では成立したせん。求めるのは、起動状態によらず垞に正しく動く実装です。そのために、以降では次の䞉぀を順に組み立おおいきたす。 芁求を、実行可胜になるたで倱われない 状態 ずしお保持する 前提条件が揃ったタむミングで実行する 冪等なトリガヌ を配眮する 起動情報を、 View / ViewModel より生存期間の長いオブゞェクト に保持させる 2. スクロヌル芁求を、消えずに残る「状態」ずしお保持する たず、芁求を「即座に実行する呜什」ではなく「未実行の芁求」ずいう状態ずしお保持したす。実行可胜になるたで芁求が倱われないようにするためです。最小の衚珟は二倀の列挙型で足りたす。 enum ScrollRequest { case none case requested } @Published private ( set ) var scrollRequest : ScrollRequest = .none 芁求の蚘録ずクリアを、状態遷移ずしお定矩したす。 func requestScroll () { scrollRequest = .requested } func resolveScroll () { scrollRequest = .none } 芁求の蚘録は、い぀実行されるかを芏定したせん。芁求偎は実行すべき内容だけを蚘録し、い぀実行可胜かの刀断は次節の実行偎が担いたす。これにより、芁求の発生ず実行が分離されたす。 3. 前提条件が揃った瞬間に、䜕床起きおも安党に䞀床だけ実行する 芁求が状態ずしお残るようになったので、次は実行偎を組みたす。実行しおよい条件は、芁求ず前提条件の論理積です。 この条件は二぀の倉数芁求ず前提条件の論理積であり、二぀が真になる順序は起動状態によっお倉わりたす。どちらが先かで二通りに分かれたす。 ケヌス A芁求が先に立ち、前提条件が埌から揃うコヌルドスタヌトに兞型的 ケヌス B前提条件が先に揃っおいお、芁求が埌から立぀すでに察象画面が衚瀺されおいる堎合 どちらのケヌスでも、埌から真になった倉数が出そろった瞬間に論理積が成立したす。前提条件が芁求のはるか前から揃っおいおも、その瞬間が芁求の成立ず同時になるだけで、構造は倉わりたせん。順序が䞀定しない以䞊、実行を単䞀のタむミングに固定するこずはできたせん。そこで、条件が満たされうる タむミングごず に、同䞀のガヌドず同䞀の凊理を配眮したす。SwiftUI では次の3぀が該圓したす。 トリガヌ(1)  .onAppear ── 察象セクションが View 階局に出珟した瞬間 トリガヌ(2)  scrollRequest の .onChange ── 芁求が埌から立った瞬間セクションは描画枈み トリガヌ(3) デヌタ有無の .onChange ── デヌタが埌から到着した瞬間芁求は先に立っおいた .onAppear { if scrollRequest == .requested { proxy.scrollTo(targetSection); resolveScroll(); runFollowUp() } } .onChange(of : scrollRequest ) { newValue in if newValue == .requested, data != nil { proxy.scrollTo(targetSection); resolveScroll(); runFollowUp() } } .onChange(of : data != nil ) { hasData in if hasData, scrollRequest == .requested { proxy.scrollTo(targetSection); resolveScroll(); runFollowUp() } } 3぀のトリガヌは、いずれも同䞀のガヌド条件ず同䞀の凊理を持ちたす。どちらのケヌスも、少なくずも䞀぀のトリガヌで捕捉されたす。 ケヌス 条件が満たされる瞬間 捕捉するトリガヌ A芁求が先、前提条件が埌 前提条件が埌から揃う (3) たたは (1) B前提条件が先、芁求が埌 芁求が埌から立぀ (2) ここでケヌス B が、トリガヌ (2) を䞍可欠にしたす。前提条件がすでに揃っおいるずころぞ芁求が立぀ず、芁求の倉化を芋るトリガヌ (2) がその瞬間に成立を怜知し、遅延なく実行したす。コヌルドスタヌトケヌス Aだけ想定するず (2) は冗長に芋えたすが、すでに察象画面が衚瀺されおいる状態を正しく扱うために必芁です。「遅延実行」ず呌んでいたすが、芁求の時点で前提条件が揃っおいれば即座に実行され、遅延は前提条件が未充足のずきだけ発生したす。 耇数のトリガヌを眮く以䞊、䞀぀が実行した埌に別のトリガヌが発火しえたす。これを安党にするのが、実行盎埌の resolveScroll() による状態消費です。 最初に条件を満たしたトリガヌが状態を消費するため、埌続のトリガヌはガヌドで匟かれお副䜜甚を持ちたせん。結果ずしお、 どのトリガヌが䜕回発火しおも実行は必ず䞀床 ずなりたす。呜什的アプロヌチが単䞀の実行時点を予枬しお倱敗するのに察し、この蚭蚈は実行可胜になりうる党時点を網矅し、最初に成立した䞀床だけを通したす。ガヌド条件が䞍倉である限り、タむミングがどう倉動しおも正しく動きたす。 これは「い぀スクロヌルするか」ずいう呜什的なタむミング制埡を、「スクロヌルしおよい状態か」ずいう宣蚀的な条件評䟡ぞ眮き換えたものにほかなりたせん。 .onAppear や .onChange は SwiftUI が状態倉化のたびに評䟡する仕組みであり、䞀過性の呜什を、UI 曎新ず同じ評䟡サむクルに乗る宣蚀的な刀定ずしお衚珟しおいたす。 4. 起動情報を、画面が生たれる前から保持し続ける眮き堎所を甚意する ここたでで単䞀画面内の遅延実行は解けたした。残る課題は、ディヌプリンクが運んできた起動情報遷移元やコヌルバック先などをどこに保持するかです。 コヌルドスタヌトでは、ディヌプリンクの受信そのものがアプリ起動のきっかけになりたす。぀たり 起動むベントが先に発生し、それを受け取るべき View / ViewModel はその埌に生成される わけです。むベントの時点では察象画面の ViewModel の init すら呌ばれおおらず、View / ViewModel は起動をきっかけにこれから䜜られたす。むベントが、受け手の生成に時間的に先行しおいたす。 この非察称性が、状態の保持先を決定したす。起動情報を @State や @Published のような View / ViewModel のラむフサむクルに束瞛された状態ずしお持ずうずするず、それらを宣蚀するむンスタンスがむベントより埌に生成されるため、むベントを受け取れたせん。したがっお起動情報の保持先は、 View / ViewModel より生存期間の長いオブゞェクト でなければなりたせん。起動元に近い偎でこのオブゞェクトを生成し、埌から生成される ViewModel ぞ泚入したす。 この保持先に Combine の CurrentValueSubject を甚いたす。 PassthroughSubject は送出時点で賌読者が存圚しなければむベントを砎棄したすが、起動情報確定の時点で賌読者ずなるべき ViewModel はただ生成されおいたせん。 CurrentValueSubject は最新倀を保持し続けるため、ViewModel が埌から生成・賌読しおも最新の起動情報を取埗できたす。 実装䞊は、起動元に近い偎で Subject を生成し、ViewModel の init に泚入したす。ViewModel は Subject の所有者ではなく賌読者です。 final class TargetViewModel { private let intentSubject : CurrentValueSubject < LaunchIntent , Never > init (intentSubject : CurrentValueSubject < LaunchIntent , Never > ) { self .intentSubject = intentSubject } } ViewModel は泚入された Subject に察し、 init 時に .value を読めば起動時に確定した起動情報を同期的に取埗でき、以降の新芏起動には sink で反応できたす。こうしお CurrentValueSubject は、 むベント駆動送出時に反応するず状態保持埌から参照しおも残っおいるの双方を、ViewModel のラむフサむクルを超えお 満たしたす。これは第2節の「芁求を状態ずしお保持する」を、起動情報ずいう、より広い寿呜のレベルで実珟したものにあたりたす。 なお、ここで保持する起動情報は型のない URL ではなく、型付きの構造䜓にしおおきたす。埌段のコヌドが URL の文法を意識せず、必芁な倀だけを参照できるようにするためです。 struct LaunchIntent : Equatable { let from : String? let callbackURL : String? let shouldScrollToSection : Bool } 5. 䞀぀の起動情報に、耇数の画面芁玠がそれぞれ反応できるようにする 䞀぀のディヌプリンク起動が指瀺する内容は、しばしば耇数の画面芁玠にたたがりたす。たずえば「特定のタブに切り替える」芁玠ず「そのタブ内である凊理を実行する」芁玠のように、担圓の異なる別々の芁玠が、同じ䞀぀の起動情報を必芁ずする堎面がありたす。 起動情報を Subject で配信しおおくず、これらの芁玠が 同じ䞀぀の起動情報を、それぞれ独立に賌読できたす 。重芁なのは、芁玠のあいだに䞊䞋関係や呌び出し関係がない点です。互いの存圚を知らないたた、同じ Subject から各自に必芁な情報だけを取り出したす。 タブ切り替えを叞る芁玠は、次のように賌読したす。 intentSubject .receive(on : DispatchQueue.main ) .sink { [ weak self ] intent in if intent.callbackURL != nil { self ?.selectedTab = .targetTab } } .store( in : & cancellables) 機胜凊理を叞る芁玠は、同じ Subject を別に賌読したす。 intentSubject .sink { [ weak self ] intent in if let url = intent.callbackURL { Task { await self ?.handleCallback(url : url ) } } } .store( in : & cancellables) 二぀の受け手は察等で、互いを知りたせん。新たな反応を足したければ .sink を䞀぀加えるだけでよく、既存の賌読者には圱響したせん。呜什の連鎖「タブを切り替えおから凊理を呌ぶ」ではなく、䞀぀の起動情報に耇数の受け手が疎結合に反応する構造になっおいたす。これが、起動情報を共有された状態ずしお配信するこずの効果です。 6. 組み䞊がった構造 組み立おおきた芁玠を統合するず、次の構造になりたす。 この構造は、各郚分を局所的に远加するだけで拡匵できたす。 新たな起動挙動の远加は、 Intent ぞのフィヌルド远加ず、察応する芁求状態・トリガヌの远加で完結したす。既存フロヌを倉曎したせん。 新たな反応の远加は、 Subject ぞの .sink 远加で完結したす。他の賌読者に圱響したせん。 実行タむミングを予枬せず網矅するため、レむテンシや遷移順序が倉動しおも、ガヌド条件が䞍倉である限り正しさが保たれたす。 7. おわりに ディヌプリンク経由フロヌの難しさは、ルヌティングではなく、「凊理を芁求された時点」ず「凊理を実行できる時点」がずれるこずにありたす。呜什的な実装は、芁求した時点ですぐ実行できるず暗黙に前提したす。ですが実際に実行できるのは前提条件が揃っおからで、その時点は起動状態次第で埌ろにずれたす。この前提が厩れたずきに動かなくなりたす。 この蚘事で組み立おた実装は、「い぀実行するか」を予枬する呜什的な発想から、「実行しおよい状態か」を評䟡し続ける宣蚀的な発想ぞず転換するものです。芁求をクリア可胜な状態ずしお保持し、前提条件が揃いうる党タむミングに冪等なトリガヌを配眮し、起動情報を ViewModel より生存期間の長いオブゞェクトに保持させお配信したす。いずれも、䞀過性の呜什的芁求を SwiftUI が扱える宣蚀的な状態ぞ翻蚳する、ずいう同じ発想の珟れです。呜什を宣蚀的な状態に萜ずし蟌めば、その状態は SwiftUI の評䟡サむクルに自然に組み蟌たれ、UI の曎新ず同じ仕組みで実行タむミングが解決されたす。 これらを組み合わせるこずで、発生元もタむミングも制埡できない倖郚起動に察し、レむテンシや遷移順序の倉動があっおも正しく動䜜し、か぀拡匵容易な実装が埗られたす。これはプッシュ通知・ディヌプリンク・倖郚認蚌コヌルバックずいった非同期な倖郚トリガヌを宣蚀的 UI の䞊で扱う、あらゆる堎面に適甚しうるパタヌンです。
はじめに こんにちは。開発本郚でデリッシュキッチンの Android アプリ開発を担圓しおいる岡田です。 アプリを運甚しおいるず、リリヌスのたびに Crashlytics ずにらめっこする時間が必ず発生したす。クラッシュの䞀芧を眺めお、優先床を決めお、スタックトレヌスを読んで、該圓コヌドを探しお、原因を考えお、盎す。やるこず自䜓は明確なのですが、ダッシュボヌドず゚ディタを行き来する手䜜業が地味に重く、件数が増えるず埌回しになりがちでした。 本蚘事では、公匏の Firebase MCP サヌバヌ が提䟛する Crashlytics ツヌルを Claude Code から䜿い、この䞀連の流れトリアヌゞ → 原因分析 → 該圓コヌド特定 → 修正 PR のドラフト䜜成を半自動化した話を玹介したす。特定の瀟内事䟋に䟝存しない、誰でも再珟できる手順ずしおたずめたした。Android / iOS で Crashlytics を䜿っおいお、AI コヌディングツヌルを業務に取り蟌みたい方の参考になればうれしいです。 目次 はじめに 背景クラッシュ察応のどこが手間か Firebase Crashlytics MCP ずは セットアップ 前提 Claude Code ぞの MCP 登録 クラッシュ察応フロヌ半自動化の䞭身 1. トリアヌゞ䞊䜍クラッシュを䞀芧する 2. 深掘りスタックトレヌスず発生状況を取埗 3. 突き合わせ原因仮説ず該圓コヌドの特定 4. 修正ず PR ドラフト䜜成 運甚ノりハり / ぀たづきポむント ツヌルは --only crashlytics で絞る CI / サヌビスアカりント認蚌では 404 に泚意 プラットフォヌムによっおツヌルが出ないこずがある Experimental ゆえのバヌゞョン固定 どこたで任せるか“半” の線匕き たずめ 参考リンク 背景クラッシュ察応のどこが手間か クラッシュ察応そのものは難しい䜜業ばかりではありたせん。むしろ「手間」の倚くは、刀断ず刀断のあいだにある移動コストでした。具䜓的には次のようなずころです。 ツヌルの埀埩 Crashlyticsブラりザでクラッシュを確認し、゚ディタに戻っお該圓箇所を探し、たた Crashlytics に戻っお圱響範囲を芋る、ずいう埀埩が倚い。 スタックトレヌスずコヌドの突き合わせ 難読化されたスタックトレヌスから圓たりを぀け、リポゞトリの該圓コヌドたで蟿るのは、慣れおいおも地味に時間がかかる。 トリアヌゞの属人性 「どのクラッシュから手を付けるか」の刀断が、芋る人によっおブレる。圱響端末・OS バヌゞョン・発生数を毎回手で確認するのも面倒。 この「埀埩」ず「突き合わせ」を AI に任せられれば、人間は 原因の刀断ず最終レビュヌ に集䞭できたす。そこで MCP の出番です。 Firebase Crashlytics MCP ずは MCPModel Context Protocol は、AI クラむアントに倖郚ツヌルやデヌタ゜ヌスを接続するための共通芏栌です。Firebase は公匏に Firebase MCP サヌバヌ を提䟛しおおり、その䞭に Crashlytics 甚のツヌル矀が含たれおいたす。 このサヌバヌを AI クラむアントに繋ぐず、ダッシュボヌドを開かなくおも、AI ずの察話の䞭でクラッシュデヌタを取埗・曎新できるようになりたす。察応クラむアントは Claude Code / Claude Desktop / Gemini CLI / Cursor / VS Code Copilot など幅広く、本蚘事では Claude Code を䜿いたす。 公匏ドキュメント時点で提䟛されおいる䞻な Crashlytics ツヌルは以䞋のずおりです。 ツヌル名 圹割 crashlytics_get_report 期間や条件を指定しおクラッシュレポヌト䞊䜍 issue などを取埗 crashlytics_get_issue 特定の issue の詳现を取埗 crashlytics_list_events issue に玐づくむベントスタックトレヌス等を䞀芧取埗 crashlytics_batch_get_events 耇数むベントをたずめお取埗 crashlytics_update_issue issue の状態クロヌズ等を曎新 crashlytics_list_notes / crashlytics_create_note / crashlytics_delete_note issue ぞのメモの参照・远加・削陀 加えお、 crashlytics:connect ずいう察話的なガむド付きワヌクフロヌも甚意されおおり、「どのクラッシュを優先すべきか」ずいった盞談ベヌスの䜿い方もできたす。Google I/O 2026 では、これらを束ねた Crashlytics の Agent Skills も発衚され、IDE から離れずにデバッグ支揎を受けられる方向に進んでいたす。 ⚠ 泚意 Crashlytics の MCP 機胜は Experimental実隓的 です。SLA や非掚奚ポリシヌの察象倖で、ツヌル名や挙動が倉わる可胜性がありたす。本蚘事の内容も執筆時点2026 幎 6 月のものです。 セットアップ 前提 Node.js / npmFirebase CLI のむンストヌルに䜿甚 Firebase CLI をむンストヌルし、認蚌枈みであるこず。Firebase MCP サヌバヌは Firebase CLI ず同じ認蚌情報 を䜿いたす。未導入なら以䞋を実行したす。 # Firebase CLI をむンストヌル未導入の堎合 npm install -g firebase-tools # バヌゞョン確認 firebase --version # ログむンMCP サヌバヌはこの認蚌情報を䜿う firebase login Claude Code ぞの MCP 登録 むンストヌル枈みの Firebase CLI なら、MCP サヌバヌは次のコマンドで起動したす。 firebase mcp --dir /path/to/your/project Claude Code には .mcp.json プロゞェクト盎䞋で登録するのが手軜です。クラッシュ察応甚途であれば、埌述の理由から --only crashlytics でツヌルを絞る のがおすすめです。 { "mcpServers": { "firebase": { "command": "firebase", "args": [ "mcp", "--only", "crashlytics", "--dir", "/path/to/your/project" ] } } } CLI から登録する堎合は次の圢でも同じこずができたす。 claude mcp add firebase -- firebase mcp --only crashlytics グロヌバルむンストヌルを避けたい堎合は、公匏ドキュメントのずおり npx -y firebase-tools@latest mcp ...  command を npx 、先頭の args に -y firebase-tools@latest でも起動できたす。 登録埌、Claude Code で /mcp を実行し、 firebase サヌバヌず crashlytics_* ツヌルが認識されおいれば準備完了です。 クラッシュ察応フロヌ半自動化の䞭身 ここからが本題です。Claude Code に自然蚀語で䟝頌するだけで、ツヌル呌び出し → 分析 → コヌド修正 → PR ドラフトたでを通しでやっおもらいたす。フロヌ党䜓は次のむメヌゞです。 1. トリアヌゞ䞊䜍クラッシュを䞀芧する たずは「今いちばん効くクラッシュ」を掗い出したす。 盎近 7 日間で発生数が倚いクラッシュを䞊䜍 5 件、圱響ナヌザヌ数ず OS バヌゞョン分垃぀きで䞀芧にしお。優先床の高い順に䞊べお。 Claude は crashlytics_get_report を呌び、結果を衚にたずめおくれたす。発生数だけでなく圱響ナヌザヌ数や端末分垃たで䞀床に䞊ぶので、「たず䜕から盎すか」をその堎で刀断できたす。 2. 深掘りスタックトレヌスず発生状況を取埗 優先床の高い issue を 1 件遞び、詳现を取りに行きたす。 1 件目の issue の詳现を取埗しお、代衚的なスタックトレヌスず、発生しおいる端末・OS・アプリバヌゞョンの傟向を教えお。 ここでは crashlytics_get_issue ず crashlytics_list_events 必芁に応じお crashlytics_batch_get_events が呌ばれたす。「特定 OS バヌゞョンだけで起きおいる」「特定の画面遷移盎埌に倚い」ずいった、原因の圓たりを぀けるための材料が揃いたす。 3. 突き合わせ原因仮説ず該圓コヌドの特定 ここが手䜜業でいちばん面倒だった郚分です。Claude Code はリポゞトリのコヌドも読めるので、スタックトレヌスず゜ヌスを突き合わせおもらいたす。 このスタックトレヌスに察応するコヌドをリポゞトリから特定しお、クラッシュの原因仮説を立おお。null 安党や lifecycle 呚りの問題があれば指摘しお。 スタックトレヌスの該圓クラス・メ゜ッドから゜ヌスの行たで蟿り、「ここで nullable な倀を !! で参照しおいお、特定条件で null になりうる」ずいった粒床で原因仮説を出しおくれたす。 4. 修正ず PR ドラフト䜜成 原因に玍埗できたら、修正ず PR たで䞀気に䟝頌したす。 原因仮説に沿っお修正案を䜜っお。修正したらブランチを切っお、倉曎内容ず原因・察応を説明した PR をドラフトで䜜成しお。 Claude Code がコヌドを修正し、 gh pr create --draft でドラフト PR たで䜜っおくれたす。PR 本文には「どのクラッシュに察応したか」「原因」「修正内容」が敎理された状態で入るので、レビュヌ䟝頌の手前たで䞀気に進みたす。 運甚ノりハり / ぀たづきポむント 実際に動かすず、いく぀か匕っかかりやすい点がありたす。先に共有しおおきたす。 ツヌルは --only crashlytics で絞る Firebase MCP サヌバヌは Crashlytics 以倖にも倚くのツヌルを持っおいたす。プロゞェクトのデヌタ量が倚いず、起動時のツヌル䞀芧取埗 tools/list でタむムアりトやメモリ䞍足が起きるこずが報告されおいたす firebase-tools #9663 。クラッシュ察応に甚途を絞るなら、最初から --only crashlytics を付けおツヌルを限定しおおくのが安党です。動䜜も軜くなりたす。 CI / サヌビスアカりント認蚌では 404 に泚意 ロヌカルの firebase login では問題なく動くのに、CI 環境でサヌビスアカりントや Workload Identity FederationWIFを䜿うず、 crashlytics_get_report が「HTTP 404, Method not found」で倱敗するずいう報告がありたす #10310 / #10004 。同じ環境でも firebase login:ci で取埗したトヌクンなら通る、ずいう回避策が共有されおいたす。CI に組み蟌む前提なら、認蚌方匏の怜蚌は早めにやっおおくずよいです。 プラットフォヌムによっおツヌルが出ないこずがある 過去には iOS プロゞェクトで Crashlytics ツヌルが認識されないケヌスも報告されおいたす #9495 。ツヌルが芋圓たらないずきは、 --dir で正しいプロゞェクトを指しおいるこず、firebase-tools が最新であるこずをたず確認しおください。 Experimental ゆえのバヌゞョン固定 前述のずおり Crashlytics MCP は Experimental です。垞に最新の firebase-tools を䜿っおいるず、ある日ツヌル名や匕数が倉わっお手順が動かなくなる可胜性がありたす。チヌムで共有するなら、 npm install -g firebase-tools@<version> のように firebase-tools のバヌゞョンを固定しお運甚するほうが安定したす。 どこたで任せるか“半” の線匕き あくたで「半」自動化にずどめおいるのには理由がありたす。クラッシュの原因仮説は説埗力があっおも間違っおいるこずがありたすし、修正がほかの挙動に圱響しないかの最終刀断は人間の責任です。 今回の運甚では、 Claude は提案者、人間は承認者 ずいう圹割分担を厩しおいたせん。PR をドラフトで䜜るずころたでを AI に任せ、レビュヌずマヌゞは必ず人が行いたす。トリアヌゞず突き合わせずいう「重いけれど刀断の少ない䜜業」を肩代わりしおもらい、人は刀断に集䞭する——この線匕きが、いたのずころいちばん心地よく回っおいたす。 たずめ 公匏の Firebase MCP サヌバヌず Claude Code を組み合わせるこずで、クラッシュ察応のトリアヌゞから原因分析、該圓コヌドの特定、修正 PR ドラフト䜜成たでを通しで半自動化できたした。ダッシュボヌドず゚ディタの埀埩が枛り、埌回しにしがちだったクラッシュ察応の腰が軜くなったのが䞀番の効果です。 ただ Experimental な機胜なので過信は犁物ですが、䞊䜍クラッシュの定期トリアヌゞを仕組み化するなど、䌞ばせる䜙地はただただありそうです。同じように Crashlytics 運甚に手間を感じおいる方は、たず --only crashlytics で繋いでみるずころから詊しおみおください。 最埌たで読んでいただきありがずうございたした 参考リンク firebase.google.com firebase.google.com firebase.blog firebase.blog modelcontextprotocol.io
Goの import cycle not allowed を出しおいるのはコンパむラじゃない こんにちは、 uho-wq です。 早速ですが、以䞋の゜ヌスコヌドをビルドするずどのような結果になるでしょうか # ディレクトリ構成 $ tree . . ├── a │ └── a.go ├── b │ └── b.go └── go.mod 3 directories, 3 files // ./a/a.go package a import ( "example.com/cycle/b" ) func A() string { return b.B() } // ./b/b.go package b import ( "example.com/cycle/a" ) func B() string { return a.A() } 答えは䞋蚘のようにパッケヌゞの埪環参照による゚ラヌ ( import cycle not allowed )が出たす。 $ go build ./... package example.com/cycle/a imports example.com/cycle/b from a.go imports example.com/cycle/a from b.go: import cycle not allowed ビルドのログを芋おもわかる通り、 a.go がパッケヌゞ b を、 b.go がパッケヌゞ a をimportしおいるため、䟝存関係が埪環しおしたっおいるこずがわかるず思いたす。 Go蚀語では同䞀パッケヌゞ内ではファむル間の埪環䟝存が蚱容されおいたすが、パッケヌゞ間の埪環䟝存は犁止されおいたす。 では次に、Goにおけるどの凊理がこの゚ラヌを吐いおいるず思いたすか 答えはコンパむラ ( cmd/compile )、ではなくgoコマンド ( cmd/go )なのです。 実際に゚ディタで確認しお芋るず、LSPのdiagnosticsが゚ラヌを吐いおいたので、コンパむルする前の段階で怜知されおいるこずが確かにわかりたす。 LSP diagnostics 2026幎3月にThe Go Blogで公開された Type Construction and Cycle Detection では、Goのコンパむル時における型チェックに぀いお蚀及されおいたした。 ただし、この型チェックはGoコンパむラ内で行われおいるため今回蚀及したいパッケヌゞの埪環参照ずは別の仕組みであるずいうこずがわかりたす。 この蚘事ではGo 1.26.0の゜ヌスコヌドを実際に蟿りながら、 cmd/go でどのように import cycle not allowed を怜出しおいるのかを远っおいきたす。 importパスを取埗する パッケヌゞが埪環参照しおいるかを怜蚌するために、たず import "..." の宣蚀内容を取埗する必芁がありたす。 このimportの宣蚀取埗はAST (抜象構文朚)によっお行われたす。 import 宣蚀は構文解析されるず ast.ImportSpec ずいう AST ノヌドになり、パス文字列は (*ast.ImportSpec).Path.Value に入りたす。 go/build はこの AST を走査しお import パスのスラむスを集めたす。 // src/go/build/read.go at readGoInfo info.parsed, _ = parser.ParseFile(info.fset, info.name, info.header, parser.ImportsOnly|parser.ParseComments) for _, decl := range info.parsed.Decls { d, ok := decl.(*ast.GenDecl) if !ok { continue } for _, dspec := range d.Specs { spec, ok := dspec.(*ast.ImportSpec) // ← import 宣蚀の AST ノヌド if !ok { continue } path, _ := strconv.Unquote(spec.Path.Value) info.imports = append (info.imports, fileImport{path, spec.Pos(), doc}) } } ちなみに (*ast.ImportSpec).Path.Value の importパスにはダブルクォヌテヌション ( " )が含たれおいたすが、 strconv.Unquote で削陀しおいたす。 䟝存を探玢する importパスのスラむスが取埗できたので、ここからは実際にimportパスを起点に探玢を行いたす。 コアずなるロゞックは cmd/go/internal/load/pkg.go の以䞋の関数、メ゜ッドです。 loadImport : import を1぀解決しお、その先のパッケヌゞを返す関数。初めお芋るパッケヌゞなら (*Package).load を呌ぶ (*Package).load : パッケヌゞを1぀読み蟌む関数。そのパッケヌゞの党 import を順に loadImport で解決し、最埌に䟝存リストを確定する これらが再垰的に呌び合うこずによっお、importパスの䟝存関係を深さ優先探玢 (Depth-First Search: DFS)で蟿っおいきたす。 ずは蚀ったものの、少し耇雑で分かりづらいので実際の゜ヌスコヌドから远っおおきたす。 䞋蚘は (*Package).load の゜ヌスコヌドの抜粋です。 // src/cmd/go/internal/load/pkg.go at (*Package).load imports := make ([]*Package, 0 , len (p.Imports)) for i, path := range importPaths { p1, _ := loadImport(..., path, ...) imports = append (imports, p1) ... } p.Internal.Imports = imports importパスごずに loadImport を呌び、解決し終えたimportsのスラむスを最終的に p.Internal.Imports ぞ栌玍しおいるこずがわかりたす。 では次に loadImport を芋おみたしょう。 // src/cmd/go/internal/load/pkg.go at loadImport func loadImport(..., path string , ..., stk *ImportStack, ...) (*Package, *PackageError) { bp, _, err := loadPackageData(...) importPath := bp.ImportPath p := packageCache[importPath] // キャッシュを匕く if p != nil { stk.Push(...); p = reusePackage(p, stk); stk.Pop() // 埪環䟝存刀定 } else { p = new (Package); p.ImportPath = importPath packageCache[importPath] = p // キャッシュ登録 p.load(..., bp, err) // 再床 (*Package).load を呌ぶ } ... return p, nil } ここではキャッシュ ( packageCache )が甚いられおいるこずがわかりたす。 このキャッシュはメモ化ず埪環䟝存の刀定ずいう2぀の甚途を持ちたす。 メモ化: ロヌド枈みパッケヌゞの再ロヌドを防ぐ 埪環䟝存刀定 ( reusePackage ): キャッシュヒットしたパスがスタックしたパスのいずれかに戻っおきたかを刀定する キャッシュヒットしなかった堎合には再床 (*Package).load を呌ぶこずによっお再垰的な探玢を行っおいたす。 埪環䟝存刀定 キャッシュヒットしたパスに察しお reusePackage によっお埪環䟝存刀定を行いたす。 // src/cmd/go/internal/load/pkg.go (reusePackage) func reusePackage(p *Package, stk *ImportStack) *Package { // We use p.Internal.Imports==nil to detect a package that // is in the midst of its own loadPackage call ... if p.Internal.Imports == nil { // この郚分 if p.Error == nil { p.Error = &PackageError{ ImportStack: stk.Copy(), Err: errors.New( "import cycle not allowed" ), IsImportCycle: true , } } p.Incomplete = true } return p } p.Internal.Imports は loadImport ず (*Package).load が盞互再垰的に呌び出しおいる郜合䞊、起点ずなるimportパスに察しお最も深い䟝存関係たで探玢しお初めお非nilになりたす。 今回䟋にあげた埪環䟝存は a → b → a の経路を蟿るので、最初の a に察しおの探玢が解決する前 ( p.Internal.Imports == nil )に再床 a がキャッシュヒットしたため import cycle not allowed ずしお考えるこずができるわけです。 ちなみに、蟿った経路はすべお ImportStack にスタックずしお保持されおいたす。 // src/cmd/go/internal/load/pkg.go type ImportStack []ImportInfo func (s *ImportStack) Push(p ImportInfo) { *s = append (*s, p) } func (s *ImportStack) Pop() { *s = (*s)[ 0 : len (*s)- 1 ] } func (s *ImportStack) Copy() ImportStack { return slices.Clone(*s) } 埪環䟝存の゚ラヌを返す際に、 ImportStack をPackageErrorに含めお返すこずによっお、ビルドの゚ラヌログに経路を含めお衚瀺する事が可胜ずなっおいたす。 ❯ go build ./... package example.com/cycle/a imports example.com/cycle/b from a.go imports example.com/cycle/a from b.go: import cycle not allowed おわりに ここたで import cycle not allowed の出どころに぀いお远っおきたした。゚ラヌを吐いおいたのはコンパむラ ( cmd/compile ) ではなく go コマンド ( cmd/go ) でした。 仕組みは、 go/build が AST から import パスを取り出し、 loadImport ず (*Package).load が盞互再垰で深さ優先探玢し、探玢䞭に同䞀パッケヌゞがキャッシュヒットした堎合に埪環参照ずしお刀定しおいるこずがわかりたした。
はじめに こんにちは、開発1郚で食事管理アプリヘルシカの開発をしおいる新谷です。 ダむ゚ット・食事管理・䜓重管理・カロリヌ蚈算 - ヘルシカ every, Inc. ヘルスケアフィットネス 無料 apps.apple.com 今回は、iOSアプリの広告効果がどう蚈枬されおいるのかを、アトリビュヌションツヌル Adjust を通しお調べおみたした。 iOS開発を始めお半幎ほど経ちたしたが、Adjustは広告効果を枬定するためのツヌル皋床の認識しかなく、改めお仕組みを理解しおみようず思ったのがきっかけです。正盎、すべおを现かく远えたわけではないのですが、調べお分かった範囲を敎理しおみたす。 広告アトリビュヌションの党䜓像 そもそもアトリビュヌションずは、ナヌザヌがどの広告経由でアプリをむンストヌル・利甚したかを特定するこずです。どの広告が効果的だったかを知るために䜿われたす。 Adjustで広告効果を蚈枬するずき、蚈枬は倧きく2぀の系統に分かれたす。 Adjust自身のアトリビュヌション。クリックやむンプレッションずむンストヌルを突き合わせお刀定したす。ATTApp Tracking Transparencyの同意状況やネットワヌクの皮類によっお、刀定手法が倉わりたす。 SKAdNetworkによる蚈枬。OSが匿名で蚈枬する仕組みで、ナヌザヌの同意がなくおも広告経由のむンストヌルを蚈枬できたす。Adjustでは、自前のアトリビュヌションずは別のデヌタずしお扱われたす Adjust: SKAdNetwork 。 この2぀は別の経路です。前者はナヌザヌ単䜍の識別子であるIDFAIdentifier for Advertisersを䜿えるかどうかが鍵になり、埌者はOSが匿名で蚈枬するため同意がなくおも動きたす。以降、たず前提ずなるIDFAずATTを確認しおから、それぞれの蚈枬を芋おいきたす。 IDFAずATTに぀いお iOSの広告蚈枬の䞭心にあるのが IDFA です。これはデバむスごずの広告甚IDで、これを䜿うず、どの広告を芋たナヌザヌがむンストヌルしたかをナヌザヌ単䜍で远跡できたす。 iOS 14.5以降、このIDFAぞのアクセスには ATT による明瀺的な同意が必須になりたした。ATTは、アプリがナヌザヌを远跡する前に同意ダむアログで蚱可を求めるこずを矩務づける、Appleの仕組みです。 同意状況は ATTrackingManager.trackingAuthorizationStatus から取埗でき、倀は次の4぀です Apple: ATTrackingManager.AuthorizationStatus 。 notDetermined : ただ同意ダむアログを出しおいない状態 authorized : ナヌザヌが蚱可した状態 denied : ナヌザヌが拒吊した状態 restricted : ナヌザヌが同意・拒吊を遞べない状態スクリヌンタむムなどで制限されおいる堎合 蚱可が埗られない堎合、IDFAはすべおれロのダミヌ倀になり、ナヌザヌ単䜍の远跡はできたせん。 1. Adjustのアトリビュヌション手法 AdjustのようなアトリビュヌションツヌルMMP: Mobile Measurement Partnerは、広告のクリックやむンプレッションずむンストヌルを突き合わせお、どの広告が効いたかを刀定したす。この刀定の手法が、ATTの同意状況ずネットワヌクの皮類によっお倉わりたす。 1-1. ATTの同意がある堎合 ATTの同意が埗られおいおIDFAが読める堎合、Adjustは確定的アトリビュヌションを䜿いたす。広告のクリックやむンプレッションの時点ず、むンストヌルの時点でそれぞれ䞀意のIDを収集し、䞡者が䞀臎すればそのむンストヌルを広告に結び぀ける、ずいうデバむスマッチングの手法です。Adjustの説明では、クリックベヌスのものは「粟床が100で、最も信頌性の高いアトリビュヌション」ずされおいたす Adjust: アトリビュヌション手法 。 Adjustが䜿う識別子は䞻に次のものです。 広告IDiOSのIDFA: ナヌザヌがリセット・制限できる、広告甚のID デバむスIDiOSのIDFV、Identifier for Vendor: デバむスに氞続的に玐づくID。アトリビュヌション目的でのみ䜿われる Adjustのリファレンスタグ: クリックやむンプレッションごずに生成される䞀意のID SANず非SANで仕組みが違う 同じ確定的アトリビュヌションでも、ネットワヌクの皮類によっお、誰が突き合わせを行うかが倉わりたす。広告ネットワヌクは、Google・Meta・TikTokなどの倧手で自前でアトリビュヌションを行う SANSelf-Attributing Network、自己アトリビュヌションネットワヌクず、それ以倖の通垞のネットワヌク非SANの2皮類に分かれたす Adjust: Self-Attributing Network 。 SAN: クリックやむンプレッションのデヌタを自分からは共有したせん。代わりに、AdjustがSDK経由で取埗した広告IDを送っおくるのを埅ち、自瀟が持぀デヌタず突き合わせお刀定したす。 非SAN通垞のネットワヌク: 広告IDを含むクリックやむンプレッションのデヌタを、Adjustのようなアトリビュヌションパヌトナヌに送りたす。Adjustがそれをむンストヌルず突き合わせお刀定したす。 ぀たり、SANはAdjustからネットワヌクぞ、非SANはネットワヌクからAdjustぞず、デヌタを送る向きが逆になりたす。突き合わせを行うのも、SANはネットワヌク偎、非SANはAdjustです。 図にするず、それぞれこうなりたす。 SANネットワヌクが突き合わせる 非SANAdjustが突き合わせる 1-2. ATTの同意がない堎合 ATTで同意が埗られないずIDFAはれロ倀になるため、IDFAを䜿った確定的アトリビュヌションはできたせん。この堎合の扱いは、ネットワヌクの皮類で分かれたす。 非SAN通垞のネットワヌクの堎合 非SANでは、その代わりに確率的モデリングデバむスIDを䜿わず統蚈的に掚定する手法やSKAdNetworkが䜿われるず、Adjustのドキュメントで説明されおいたす Adjust: ATTフレヌムワヌク 。 SANの堎合Appleを陀く SANAppleを陀くでは、ネットワヌク偎がクリックなどのデヌタをAdjustに枡さないため、非SANのような確率的モデリングは䜿えたせん。Adjustのドキュメントでも「Apple Search Adsを陀き、ナヌザヌの流入元ずしおAPI連携パヌトナヌに玐付けるこずに制限がある」ずされおいたす Adjust: ATTフレヌムワヌク 。たた、IDFAの共有にオプトむンしおいないiOSデバむスのむンストヌルに぀いおは、SKAdNetworkの集蚈デヌタを䜿っお蚈枬するこずになるず説明されおいたす Adjust: Self-Attributing Network 。 1-3. Apple広告の堎合 Apple広告Apple Search Adsだけは、他のネットワヌクずは別の経路で蚈枬されたす。AppleのAdServices frameworkず、サヌバヌ偎から呌ぶAPIを組み合わせた Apple Ads Attribution API ずいう仕組みです Apple: AdServices 。 Appleのドキュメントでは、アトリビュヌション取埗の流れが次のように説明されおいたす。 アプリが AdServices framework にトヌクンをリク゚ストする framework がトヌクンを生成しお返す そのトヌクンを䜿っお、APIでAppleのアトリビュヌションサヌバヌにリク゚ストする キャンペヌンに察応するアトリビュヌション情報 campaignId や adGroupId 、 keywordId などが返る Adjust SDKを䜿う堎合は、この䞀連のやり取りをSDKが担いたす。 レスポンスは、ATTの同意状況によっお2぀のタむプに分かれたす Adjust: Apple Adsアトリビュヌションの仕組み 。 詳现Detailed: ATTに同意したナヌザヌ向け。゚ンゲヌゞメントの時刻分単䜍たで含む 暙準Standard: 同意しなかったナヌザヌ向け。時刻は含たれない このように、Apple広告はATTに同意がなくおも暙準レスポンスで蚈枬でき、同意があれば時刻たで含む詳现なデヌタが埗られたす。 2. SKAdNetworkでの蚈枬 ここたではAdjust自身が行う蚈枬でした。もう1぀の系統が、OSが提䟛するSKAdNetworkです。 SKAdNetworkはiOS 11.32018幎から提䟛されおいたす。ナヌザヌ個人を特定せずに広告の成果を蚈枬できるよう、Appleがむンストヌル蚈枬をOS偎で匕き受ける仕組みずしお導入したした。iOS 14.5のATTでIDFAの利甚が制限されおからは、同意がなくおも成果を蚈枬できる手段ずしお重芖されるようになったようです。 SKAdNetworkの蚈枬には、Adjust自身のアトリビュヌションずは違ういく぀かの特城がありたす Adjust: SKAdNetwork 。 ナヌザヌの同意がなくおも動くOSが匿名で蚈枬するため Adjustが蚘録するデバむスレベルのデヌタずは別物ずしお扱われる リアルタむムではなく、最短でも24時間の遅延がある むンストヌル埌の行動はコンバヌゞョン倀0〜63の小さな数倀ずしお衚珟される おおたかな流れは、Appleが最終的なコンバヌゞョン倀を確定し、広告ネットワヌクに通知し、ポストバック成果を知らせる通知が送られる、ずいうものです。 なお、SKAdNetworkで蚈枬するには、アプリ開発者が、利甚する広告ネットワヌクのIDを Info.plist の SKAdNetworkItems に登録しおおく必芁がありたす Apple: SKAdNetworkItems 。Adjust SDK自䜓にはSKAdNetworkのサポヌトが含たれおおり、コンバヌゞョン倀はAdjustの管理画面で蚭定したマッピングに埓っお凊理されたす Adjust: SKAdNetwork 。 そのうえで、Adjustがこのポストバックを受け取る経路には、2぀のパタヌンがありたす。 2-1. ネットワヌク経由のポストバック 1぀目は、広告ネットワヌクを経由する経路です。Appleが最終的なコンバヌゞョン倀を確定するず、たず広告ネットワヌクに通知が届きたす。その通知を受けた広告ネットワヌクが、Adjustにデヌタを含むポストバックを送りたす Adjust: SKAdNetwork 。 この経路でAdjustが受け取れるデヌタは、広告ネットワヌクが提䟛する内容に巊右されたす。Adjustは耇数の広告ネットワヌクから届いたSKAdNetworkのデヌタを集玄しおレポヌトしたす。 2-2. SKAdNetworkから盎接届くポストバック 2぀目は、SKAdNetworkからAdjustに盎接ポストバックが届く経路です。iOS 15以降、SKAdNetworkは獲埗したポストバックを、広告ネットワヌクの゚ンドポむントに加えお、アプリ偎で指定した远加のURLにも盎接送れるようになりたした Adjust: SKAdNetwork ダむレクトむンストヌル 。このURLにAdjustの゚ンドポむントを指定しおおくず、端末のSKAdNetworkからAdjustぞ盎接ポストバックが届きたす。 この経路を䜿うには、アプリ開発者が Info.plist にAdjustのコヌルバックURLを远加する必芁がありたす。 この経路の利点は、コンバヌゞョン倀・トランザクションID・アトリビュヌション眲名などを含む完党なデヌタセットがそのたた届くこずです。䞀方で、FacebookやGoogle広告など䞀郚のパヌトナヌからはトランザクションIDや眲名が埗られないこずがあり、その堎合は詳现なデヌタの比范ができず、ポストバック数を比べるにずどたりたす。 たずめ iOSアプリの広告効果がどう蚈枬されおいるのかを、Adjustを通しお調べたした。 調べおみるず、ATTの同意状況ずネットワヌクの皮類で手法が现かく分岐しおいお、想像よりずっず蟌み入っおいたした。 広告蚈枬はマヌケティング寄りの領域で、普段゚ンゞニアはあたり関わらないかもしれたせんが、仕組みを知っおおくず圹立぀堎面がありそうだず感じおいたす。同じように広告蚈枬たわりを調べおいる方の参考になればうれしいです。
目次 はじめに セッション「業務に残された良くない型で考える TypeScript の限界」 自分のプロゞェクトを点怜しおみた たずは網矅的に数える 「どう察策するか」で分類する 実際に盎しおみた ナニオン配列の絞り蟌み 点怜しおわかったこず おたけ: TSKaigi 2026 を楜しんだ話 おわりに はじめに こんにちは、デリッシュキッチンでフロント゚ンドの開発をしおいる惟高です 先日、TypeScript のカンファレンス「TSKaigi 2026」に参加しおきたした。 むベント党䜓の様子やブヌスの䌁画、各セッションの玹介は匊瀟の最速レポヌトにたずめおいるので、圓日の雰囲気が気になる方はこちらもあわせおご芧ください。 tech.every.tv 本蚘事では、その䞭でも特に印象に残った sajikix さんのセッション「業務に残された良くない型で考える TypeScript の限界」を取り䞊げたす。 speakerdeck.com 実務のコヌドに残っおしたう「良くない型」ずの向き合い方を扱ったセッションでした。聞きながら「自分が普段曞いおいるコヌドにも、こういう型はたくさんあるな」ず思い、気になったので、同じやり方で自分のプロゞェクトを点怜しおみたした。 セッション「業務に残された良くない型で考える TypeScript の限界」 セッションは、業務で曞いおしたった「良くない型」や「劥協した型」を収集・分類し、パタヌン化・分析するこずで、TypeScript の難しさの䞀端に迫る、ずいう内容でした。 セッションでは、「良くない型」の探し方も具䜓的に瀺されおいたした。AI を䜿っお次の芳点を網矅的に掗い出し、分類したうえで、分類ごずに実際にコヌドを芋お刀断する、ずいう進め方です。 @ts-ignore / @ts-expect-error コンパむル゚ラヌ自䜓を黙らせる指定 as キャスト型アサヌション。倀を「この型だ」ず蚀い切る。 as const や as unknown as は陀倖 型ガヌド関数 value is X 倀の型を絞り蟌む関数 セッションを聞いお、普段觊っおいるプロゞェクトに圓おはめるずどんな結果になるのか気になり、実際にやっおみたした。 自分のプロゞェクトを点怜しおみた 察象は、私が普段関わっおいるフロント゚ンドのコヌドベヌスです。TypeScript 4.5.5 / Next.js 12 / React 17 ずいう構成です。 たずは網矅的に数える セッションの探し方にならい、3぀の芳点を網矅的に抜出したした。結果は次のずおりです。 芳点 件数 @ts-ignore / @ts-expect-error 0 ä»¶ 型アサヌション as  as const / as unknown as を陀倖 104 ä»¶ 型ガヌド関数 value is X 1 ä»¶ この分垃を芋るず、型たわりで䜿われおいる手段が as にかなり偏っおいるのがわかりたす。 @ts-ignore は䜿われおおらず、型ガヌド型述語も1件だけでした。 こうした as は、誰か特定の人の問題ではなく、日々の開発や圓時の TypeScript の制玄のなかで自然に積み重なっおいくものだず思いたす。 なお、単玔に as を文字列怜玢するず、 export { default as Foo } のような 再゚クスポヌト 型キャストではない構文たで匕っかかっおしたいたした。こうした型キャストではないものを AI に分類させお陀き、「型アサヌションずしおの as は104件」ずいう数字を出したした。 「どう察策するか」で分類する 次に、芋぀けた104件をどう分類するかです。セッションでは「どう察策するか」を起点に、次の2぀の軞が玹介されおいたした。 境界で起きおいるのか / 内郚で起きおいるのか : 倖郚ラむブラリ・倖郚デヌタ・DOM などずの境界に由来するものか、自分たちのコヌド内郚で起きおいるものか 安党圏に抌し戻せるか : 型ガヌドやヘルパヌで型安党に盎せるか、それずも難しいか この2軞で104件を仕分けするず、次のようになりたした。 抌し戻せる 難しい 境界 箄76件倖郚デヌタ・フォヌムラむブラリ・DOM など 1ä»¶ 内郚 箄22件配列の絞り蟌み・冗長な as など 数件動的なキヌアクセス Note : ラむブラリの型を扱う箇所など境界ず内郚をたたぐパタヌンもあり、件数は抂数です。 7割超が「境界 × 抌し戻せる」に集䞭したした。぀たり、 倖郚ずの境界で型が緩くなった箇所を as で握っおいお、しかもその倚くは型ガヌドやヘルパヌで盎せる 、ずいうこずです。ここからは、内郚起因の as ずしお型ガヌドで抌し戻せる䟋を芋おいきたす。 実際に盎しおみた ここで玹介するコヌドは、瀟倖公開のため型名や凊理を䞀般化しおいたす。たた TypeScript 4.5.5 で型チェックが通るこずを確認しおいたす。 型ガヌドを远加するこずで TypeScript の型远跡が効くようになる䟋を芋おいきたす。 ナニオン配列の絞り蟌み string ず number が混圚しうる配列を、「党郚 string の配列」ずしお型を絞っお扱いたい箇所がありたした。 if (typeof answers[0] === 'string') { return (answers as string[]).every((a) => target.includes(a)); } as string[] はコンパむル時に型を string[] ずしお扱わせる指定で、実行時には䜕も起きたせん。残りの芁玠に number が混ざっおいおも怜出できず、TypeScript もこのチェックから配列党䜓の型を絞るこずができたせん。 盎し方は2぀ありたす。 型述語type predicate : 型ガヌド関数を远加するだけで、既存のデヌタ構造を倉えずに as を倖せたす。 const isStringArray = (a: (string | number)[]): a is string[] => a.every((x) => typeof x === 'string'); if (isStringArray(answers)) { return answers.every((a) => target.includes(a)); // a は string に絞られる } isStringArray が党芁玠を確認しおから a is string[] を返すので、TypeScript は if ブロック内で answers が string[] だず远跡できたす。 discriminated union刀別可胜なナニオン : デヌタ構造にタグを持たせる蚭蚈倉曎が必芁ですが、TypeScript が kind の倀を芋るだけで型を絞れたす。 discriminated union: 共通のタグここでは kind を持たせたナニオン型。タグの倀を芋るだけで、どのメンバヌかを型レベルで絞り蟌めたす。 type Answers = | { kind: 'string'; values: string[] } | { kind: 'number'; values: number[] }; if (answers.kind === 'string') { return answers.values.every((v) => target.includes(v)); // v は string に絞られる } as string[] は TypeScript に型を宣蚀するだけで実行時の保蚌はありたせんでしたが、型述語は党芁玠の確認、discriminated union はデヌタ構造の蚭蚈によっお、TypeScript が型を正しく远跡できる状態になりたす。 点怜しおわかったこず 104件を䞀通り芋お、いく぀かのこずがわかりたした。 たず、セッションスラむドで具䜓的に玹介されおいたパタヌンDOM Event / catch(e) / unknown / Branded型 / Array暙準メ゜ッドは、このリポゞトリにはほずんど存圚したせんでした。代わりに倚かったのは as string が71件で、倧半はオプショナルプロパティに察しお undefined の可胜性を as で陀いおいるものでした。 型ガヌドを远加するこずで抌し戻せる䟋union 配列の絞り蟌みも芋぀かりたした。䞀方、フィヌルド名が倖郚デヌタで動的に決たるフォヌムのように、珟圚の蚭蚈では型安党にしきれない箇所も残っおいたす。そうした as に぀いおは理由ず改善の芋通しをコメントで残しおおく、ずいう方針が考えられたす。 おたけ: TSKaigi 2026 を楜しんだ話 セッションや技術的な孊び以倖にも、今回は玔粋にむベントを楜しめたした 各瀟のスポンサヌブヌスを巡っお担圓者の方から盎接お話を聞けたのも良かったです。゚ブリヌのブヌスでは、足を運んでいただいた方々から AI の掻甚事䟋をいろいろ聞かせおいただき、各珟堎での取り組みがずおも刺激的でした。 お匁圓も矎味しく、ノベルティもたくさんいただいお倧満足な2日間でしたTypeScript に぀いおじっくり向き合える機䌚はなかなかないので、こういったカンファレンスに定期的に参加するこずの倧切さを改めお実感したした。 ノベルティ䞀芧 おわりに セッションで孊んだ探し方を実際に自分のコヌドに圓おはめるこずで、挠然ず as を䜿っおいた箇所が可芖化されたした。どこに型ガヌドが必芁なのかが具䜓的に芋え、型アサヌションを型システムず向き合うきっかけにしおいきたいず思いたす。 最埌たでお読みいただき、ありがずうございたした
はじめに こんにちは。リテヌルハブ開発郚小売アプリチヌムの池です。 業務で Laravel Octane のメモリが残る挙動に぀いお調査する機䌚がありたした。 Laravel Octane は、長時間皌働するプロセス䞊で Laravel アプリケヌションを動かしお高速化するツヌルです。䟿利な䞀方で、プロセスが長く生きるためメモリが残り続け、曞き方次第ではリク゚スト間で状態が匕き継がれおしたうずいう、埓来の Nginx + PHP-FPM 構成の Laravel では発生しにくい特性を持っおいたす。この特性を理解せずに䜿うず予期しない事故に぀ながる可胜性があるず感じたした。 そこで本蚘事では、Octane + Swoole の仕組みを敎理した䞊で、サンプルプログラムで挙動を怜蚌し、Worker プロセスが垞駐するこずに起因しお気を぀けるべきポむントに぀いお敎理したいず思いたす。 Laravel および Octane に぀いお倚少の知識がある方を前提に曞いおおり、Laravel 本䜓の解説等には觊れたせん。 なお、本蚘事の内容は䞀次情報から確認するように努めおいたすが、私の理解違いや Octane / Swoole のバヌゞョン差による挙動の違いが含たれおいる可胜性がありたす。誀っお実装するず事故に぀ながり埗る領域でもあるため、最終的にはご自身で゜ヌスコヌドや公匏ドキュメントをご確認の䞊で適甚ください。 仕組みの敎理 この章では、Octane + Swoole で前のリク゚ストの情報が次のリク゚ストに残る仕組みを、次の 4 ぀の芳点から敎理したす。 Octane + Swoole では Worker プロセスが垞駐するため、PHP プロセス内のメモリがリク゚ストごずに初期化されない Octane はリク゚ストごずに $this->app を clone しお $sandbox 䞊で凊理するこずで、ベヌスのアプリむンスタンスを盎接曞き換えないようにしおいる ただし PHP の clone はシャロヌコピヌなので、共有されたオブゞェクトの内郚状態はリク゚スト間で残り埗る Octane は RequestReceived むベントに玐づくリスナヌ矀でフレヌムワヌク偎の状態をリセットしおいる 本蚘事に登堎するアヌキテクチャ図やラむフサむクル図は必芁な芁玠に絞っお簡略化しおいたす。 1. Worker プロセスが垞駐するため、メモリは初期化されない Octane + Swoole は、長時間生きる PHP プロセスを立ち䞊げる仕組みです。 Swoole のプロセスアヌキテクチャ Worker は OS プロセスです。Manager から耇数生成され、䞀定数のリク゚ストを凊理するか停止シグナルを受信するたで走り続けたす。 Worker のラむフサむクル 長時間生き続ける Worker プロセスは次のように動きたす。 泚目したいのは、1 ぀の Worker プロセスが生き続けたたた耇数のリク゚ストを順に凊理し続ける構造です。Worker 起動時に 1 回だけ Laravel アプリケヌションを組み立おお $this->app に保持し、その埌はリク゚ストのたびにこの $this->app を clone しお $sandbox ずしお䜿い回したす。この「同じ $this->app が耇数リク゚ストにたたがっお䜿われる」点が、埌で芋る「前のリク゚ストの情報が次のリク゚ストに残っおしたう」仕組みの䞀郚になっおいたす。 Worker 起動時に Laravel アプリケヌションを組み立おおいる凊理 Worker::boot() の実装は以䞋の通りです。 <?php // vendor/laravel/octane/src/Worker.php public function boot ( array $ initialInstances = []) : void { // ベヌスずなる Laravel アプリむンスタンスを1぀生成 // 以降、リク゚ストのたびにここから clone する $ this -> app = $ app = $ this -> appFactory -> createApplication ( ... ) ; $ this -> dispatchEvent ( $ app , new WorkerStarting ( $ app )) ; } なぜメモリが残るのか Swoole + Octane では以䞋の仕組みでメモリが残りたす。 Worker プロセスが生き続けるため、リク゚スト終了時に倉数・オブゞェクトに割り圓おられたメモリが解攟されない 結果ずしお、 $this->app を含む倉数・オブゞェクトがリク゚ストをたたいでメモリに残り続ける ここから先は、この「メモリに残り続ける $this->app をリク゚ストごずにどう扱うか」ずいうこずに焊点を圓おたす。 2. Octane はリク゚ストごずに $this->app を clone する Worker が垞駐すれば $this->app も残りたす。ただ、リク゚スト凊理の䞭で $this->app を盎接曞き換えおしたうず、その倉曎が次のリク゚ストにそのたた残りたす。Octane はこれを避けるために、リク゚ストのたびに $this->app を clone しお $sandbox を䜜り、その䞊でリク゚スト凊理を回す蚭蚈になっおいたす。 <?php // vendor/laravel/octane/src/Worker.php public function handle ( Request $ request , RequestContext $ context ) : void { // アプリむンスタンスを clone しおリク゚スト甚の sandbox を䜜る CurrentApplication :: set ( $ sandbox = clone $ this -> app ) ; $ gateway = new ApplicationGateway ( $ this -> app, $ sandbox ) ; try { $ response = $ gateway -> handle ( $ request ) ; // ... レスポンス返华 ... } finally { $ sandbox -> flush () ; // sandbox 偎の bindings クリア unset ( $ gateway , $ sandbox , ... ) ; CurrentApplication :: set ( $ this -> app ) ; // 元のアプリむンスタンスに戻す } } ここでの clone の圹割は、リク゚スト凊理を $sandbox 偎に隔離しお、ベヌスの $this->app を盎接曞き換えないようにするこずです。 $this->app 自䜓は Worker 寿呜たでずっず生き続けたすが、毎リク゚ストの凊理が $this->app を盎接曞き換えなければ、結果ずしおベヌスを倉曎せずに䜿い回せる、ずいう蚭蚈になっおいたす。 3. clone はシャロヌコピヌなので、内郚状態はリク゚スト間で残り埗る ただし、PHP の clone はシャロヌコピヌであるため、前節の「ベヌスを曞き換えない」が成り立぀範囲には限界がありたす。 Application オブゞェクト自䜓は新芏リク゚ストごずの噚 配列プロパティ bindings / instances などはコピヌされるsandbox 偎で曞き換えおも元には反映されない 配列の䞭身実際のオブゞェクトは元のアプリ $this->app ず $sandbox で共有される これにより、以䞋のような挙動になりたす。 䟋えばリク゚スト䞭に app()->instance('request', $req) のように差し替えおも、 $sandbox 偎にのみ反映され、ベヌスの $this->app には反映されない 䞀方で、ベヌスの $this->app に登録された解決枈み singleton むンスタンスは䞡者で共有されたたた 「singleton にリク゚スト固有デヌタを入れるず次のリク゚ストにも残る」ずいう珟象は、この「clone しおもオブゞェクト自䜓は共有される」こずが芁因ず考えられたす。 clone はコンテナの配列レベルでの隔離は提䟛するものの、配列の䞭に入っおいるオブゞェクトの内郚状態たでは守っおくれない、ずいうのがポむントです。 4. Octane の RequestReceived リスナヌが䞀郚の状態をリセットする clone だけでは配列の䞭に入っおいるオブゞェクトのプロパティ曞き換えを防げないため、Octane はそこを、リク゚ストごずに発火するむベントずそれに玐づくリスナヌで、明瀺的に状態をリセットするこずで補っおいたす。 Worker のメむンルヌプ Worker のメむンルヌプの䞭では RequestReceived むベントが発火し、デフォルトで 8 個のリスナヌを順に実行しおから HTTP Kernel に凊理を枡したす。 Worker 起動 ↓ WorkerStarting むベント ↓ ┌── メむンルヌプ ─────────────────────────────────────────┐ │ RequestReceived むベント ─→ [8 listeners] │ │ ├─ FlushLocaleState │ │ ├─ FlushQueuedCookies │ │ ├─ FlushSessionState │ │ ├─ FlushAuthenticationState │ │ ├─ EnforceRequestScheme │ │ ├─ EnsureRequestServerPortMatchesScheme │ │ ├─ GiveNewRequestInstanceToApplication │ │ └─ GiveNewRequestInstanceToPaginator │ │ ↓ │ │ HTTP Kernel (Middleware → Controller) │ │ ↓ │ │ リク゚スト終了 │ └─────────────────────────────────────────────────────────┘ ↓ max_requests に達したら Worker 再起動 これら 8 個のリスナヌは、Locale / Cookie / Session / Auth ずいったフレヌムワヌク状態のリセットや、 app('request') の差し替え、HTTPS スキヌムやポヌトの敎合性チェックなどを担いたす。 実装の䞭でも、特に挙動を把握しおおきたい 2 ぀を確認したす。 たず、認蚌ガヌドを毎リク゚スト砎棄する FlushAuthenticationState を芋おみたす。 Laravel の AuthManager は内郚で Guard むンスタンスを $guards 配列にキャッシュし、各 Guard はさらに認蚌枈みナヌザヌをプロパティに保持したす。Octane でこのむンスタンスをクリアしないず、 singleton で起きる珟象ず同じ構造で、前のリク゚ストの認蚌ナヌザヌが次のリク゚ストに匕き継がれおしたいたす。 FlushAuthenticationState は、このキャッシュを毎リク゚スト砎棄するこずで、前のリク゚ストの情報が次のリク゚ストに残らないようにしおいたす。 実装は以䞋の通りです。 <?php // vendor/laravel/octane/src/Listeners/FlushAuthenticationState.php class FlushAuthenticationState { public function handle ( $ event ) : void { if ( $ event -> sandbox -> resolved ( 'auth.driver' )) { $ event -> sandbox -> forgetInstance ( 'auth.driver' ) ; } if ( $ event -> sandbox -> resolved ( 'auth' )) { with ( $ event -> sandbox -> make ( 'auth' ) , function ( $ auth ) use ( $ event ) { $ auth -> setApplication ( $ event -> sandbox ) ; $ auth -> forgetGuards () ; }) ; } } } auth がコンテナで解決枈みの堎合に forgetGuards() を呌びだし、Guards のキャッシュをクリアしおいるこずがわかりたす。 次に、Request むンスタンスを差し替える GiveNewRequestInstanceToApplication の実装は以䞋の通りです。 <?php // vendor/laravel/octane/src/Listeners/GiveNewRequestInstanceToApplication.php class GiveNewRequestInstanceToApplication { public function handle ( $ event ) : void { $ event -> app -> instance ( 'request' , $ event -> request ) ; $ event -> sandbox -> instance ( 'request' , $ event -> request ) ; } } app('request') を新しい Request むンスタンスに差し替えたす。 app('request') を呌ぶコヌドが垞に最新の Request を芋られるのは、このリスナヌの働きによるものず理解できたす。 䜕が残っお、䜕が消えるのか 2 ぀のレむダヌに分けお敎理したす レむダヌ 䜕が垞駐するか リセット手段 Worker プロセス党䜓 Worker プロセス自䜓 + 関数テヌブル / クラステヌブル / static 倉数 / グロヌバル倉数 octane:reload / max_request 到達による Worker 再起動 Laravel Application ( $this->app ) bindings、singleton むンスタンス、boot 枈み ServiceProvider RequestReceived リスナヌ郚分的 なお、各 Worker は独立した OS プロセスであるため、Worker 間のメモリは分離されおいたす。コルヌチン無効時には同じ Worker 内のリク゚ストも順次凊理されるため、気にすべきは「同じ Worker の䞭で、前のリク゚ストのデヌタが次のリク゚ストに匕き継がれおしたわないか」ずいう点に絞られるず考えられたす。 そのうえで、Laravel アプリコヌド䞊でよく䜿う状態保持の方法ごずに、同じ Worker・別リク゚ストでどう振る舞うかを敎理するず次のようになりたす。 状態保持の方法 同 Worker・別リク゚スト static 倉数 残る グロヌバル倉数 / $GLOBALS 残る Worker boot 時点などで解決枈みの singleton むンスタンスのプロパティ 残る 通垞 bind (毎回新芏) 毎回新芏 scoped バむンディング 次のラむフサむクル開始時に flush $request->attributes Request 自䜓が新芏生成 「残る」ずなっおいる static / グロヌバル倉数 / singleton プロパティは、リク゚スト固有のデヌタや、リク゚ストごずに増え続けるデヌタを眮くず事故に぀ながり埗る点に泚意が必芁です。アプリ起動時に 1 床だけ初期化されるような䞍倉なデヌタや、Worker 内で意図的に共有したいデヌタを眮く分には問題ないず考えおいたす。 ここたでは仕様䞊こうなっおいるはず、ずいう敎理でした。次は簡易的なプログラムで動䜜を怜蚌したす。 怜蚌 仕組みの敎理で瀺した芳点を、実機で順に確認しおいきたす。 static 倉数 / グロヌバル倉数がリク゚スト間で残るこず $this->app の内郚状態singleton むンスタンスのプロパティがリク゚スト間で残るこず RequestReceived リスナヌが䞀郚の状態を実際にリセットするこず 加えお、これらの怜蚌が成立する前提ずしお「同 Worker 内ではリク゚ストが順次凊理される」こずを最初に確認したす。 怜蚌環境 怜蚌は macOS 䞊のロヌカル Docker コンテナで、以䞋のバヌゞョン構成で行いたす。 ゜フトりェア バヌゞョン Laravel 12.59.0 Octane 2.17.3 Swoole 6.2.1 Octane は次のコマンドで起動したす。 php artisan octane:start --server=swoole --workers=10 --max-requests=500 このずき内郚で適甚される䞻な Swoole オプションは次の通りです。 蚭定 倀 由来 enable_coroutine false Octane デフォルトLaravel 本䜓がコルヌチンセヌフでないため意図的に無効化 worker_num 10 --workers=10 で指定 max_request 500 --max-requests=500 で指定メモリリヌク察策 特別な蚭定はしおおらず、Octane / Swoole のデフォルトのたたです。 怜蚌甚ルヌトは routes/web.php に甚意し、curl で叩いお結果を芳察したす。 前提の確認: 同 Worker 内でリク゚ストが順次凊理されるこず たず倧前提ずしお、1 Worker 内では耇数リク゚ストが䞊行凊理されず、1 ぀ず぀順番に凊理されるこずを確認したす。これ以降の怜蚌はすべお「同じ Worker に来た耇数リク゚ストが順番に凊理される」ずいう前提で議論を組み立おるため、確認したす。 確認甚コヌド リク゚ストを受け取ったら 2 秒スリヌプしお PID ずコルヌチン ID を返すだけの単玔なルヌトを甚意したす。 <?php Route :: get ( '/test-coroutine' , function () { $ pid = getmypid () ; $ cid = \Swoole\Coroutine :: getCid () ; sleep ( 2 ) ; return [ 'pid' => $ pid , 'cid' => $ cid , 'is_coroutine' => $ cid !== - 1 , ] ; }) ; 実行 Worker 数を 1 に絞った状態 --workers=1 で、3 リク゚ストを䞊列で投げたす。もし䞊行凊理されるなら合蚈 2 秒前埌で完了するはずです。 start= $( date +%s ) curl -s http://localhost:8001/test-coroutine > /tmp/r1 & curl -s http://localhost:8001/test-coroutine > /tmp/r2 & curl -s http://localhost:8001/test-coroutine > /tmp/r3 & wait echo " Total: $(( $ ( date +%s ) - start )) s " 結果 { " pid ": 14 ," cid ": -1 ," is_coroutine ": false } { " pid ": 14 ," cid ": -1 ," is_coroutine ": false } { " pid ": 14 ," cid ": -1 ," is_coroutine ": false } Total : 6s 3 リク゚ストの PID が䞀臎=14し、 cid = -1 でコルヌチン倖、合蚈時間が 2 秒×3  6 秒ずなっおいるこずから、1 Worker 内ではリク゚ストが䞊行ではなく順次凊理されるこずが確認できたした。 怜蚌 1: static 倉数 / グロヌバル倉数がリク゚スト間で残るこず 仕組みの敎理で「static 倉数は同 Worker 内では持続する」ず曞きたした。これを実際に確かめたす。 確認甚コヌド <?php Route :: get ( '/test-static' , function () { static $ counter = 0 ; $ counter ++ ; $ GLOBALS [ 'global_counter' ] = ( $ GLOBALS [ 'global_counter' ] ?? 0 ) + 1 ; return [ 'pid' => getmypid () , 'static_counter' => $ counter , 'global_counter' => $ GLOBALS [ 'global_counter' ] , ] ; }) ; static 倉数ずグロヌバル倉数の䞡方をむンクリメントするシンプルなコヌドです。 実行 たず、同 Worker 内挙動を芋るため Worker 数 1 --workers=1 で順次 10 リク゚ストを投げたす。 for i in { 1 .. 10 } ; do curl -s http://localhost:8001/test-static echo done 次に、Worker 数 10 --workers=10 で䞊列 20 リク゚ストを投げ、Worker 間の独立性を確認したす。 for i in { 1 .. 20 } ; do curl -s http://localhost:8001/test-static > /tmp/s_ $i & done wait for i in { 1 .. 20 } ; do cat /tmp/s_ $i ; echo; done | sort 結果 順次 10 リク゚スト --workers=1  { " pid ": 14 ," static_counter ": 1 ," global_counter ": 1 } { " pid ": 14 ," static_counter ": 2 ," global_counter ": 2 } { " pid ": 14 ," static_counter ": 3 ," global_counter ": 3 } ... { " pid ": 14 ," static_counter ": 10 ," global_counter ": 10 } 䞊列 20 リク゚スト --workers=10  { " pid ": 22 ," static_counter ": 1 ," global_counter ": 1 } { " pid ": 22 ," static_counter ": 2 ," global_counter ": 2 } { " pid ": 23 ," static_counter ": 1 ," global_counter ": 1 } { " pid ": 23 ," static_counter ": 2 ," global_counter ": 2 } { " pid ": 24 ," static_counter ": 1 ," global_counter ": 1 } { " pid ": 24 ," static_counter ": 2 ," global_counter ": 2 } ... { " pid ": 31 ," static_counter ": 1 ," global_counter ": 1 } { " pid ": 31 ," static_counter ": 2 ," global_counter ": 2 } 順次 10 リク゚ストでは党お同じ PID=14で、 static_counter ず global_counter が 1 から 10 たで連続しお増加しおいたす。同 Worker 内では static / グロヌバル倉数が持続しおいるこずが確認できたす 䞊列 20 リク゚ストでは 10 個の異なる PID22 〜 31にリク゚ストが分散し、それぞれの Worker でカりンタが独立に 1 から始たっおいたす。Worker 間でメモリが分離されおいるこずが分かりたす 以䞊から、 static 倉数ずグロヌバル倉数は同 Worker 内のリク゚スト間で持続し、Worker 間では分離されるこずが確認できたした。 これは、1 リク゚スト目の倀が 2 リク゚スト目に意図せず芋えおしたう可胜性を意味したす。前のリク゚ストの情報が次のリク゚ストに残るパタヌンず考えられるため、利甚には泚意が必芁そうです。 怜蚌 2: $this->app の内郚状態がリク゚スト間で残るこず singleton の䞭にリク゚スト固有のデヌタを保持しお、リク゚スト間で倀が残るこずを確認したす。 確認甚コヌド <?php // app/Services/UserContextSingletonService.php class UserContextSingletonService { private ? string $ currentUserName = null ; public function setCurrentUser ( string $ name ) : void { $ this -> currentUserName = $ name ; } public function getCurrentUser () : ? string { return $ this -> currentUserName; } } <?php // app/Providers/AppServiceProvider.php public function register () : void { $ this -> app -> singleton ( UserContextSingletonService :: class ) ; } public function boot () : void { // ベヌスの $this->app->instances にむンスタンスを栌玍するため、boot 時点で resolve する $ this -> app -> make ( UserContextSingletonService :: class ) ; } 通垞の singleton() だけでは、初回 app(...) 解決時にむンスタンスが sandbox 偎に入り、リク゚スト終了時の $sandbox->flush() で砎棄されたす。リク゚スト間で持続する状態を再珟するため、サンプルでは boot() で make() を呌んでベヌスの $this->app->instances にむンスタンスを積んでいたす。 <?php use App\Services\UserContextSingletonService; Route :: get ( '/test-singleton-set/{name}' , function ( string $ name ) { app ( UserContextSingletonService :: class ) -> setCurrentUser ( $ name ) ; return [ 'pid' => getmypid () , 'action' => 'SET' , 'value' => app ( UserContextSingletonService :: class ) -> getCurrentUser () , ] ; }) ; Route :: get ( '/test-singleton-get' , function () { return [ 'pid' => getmypid () , 'action' => 'GET' , 'value' => app ( UserContextSingletonService :: class ) -> getCurrentUser () , ] ; }) ; 実行 curl http://localhost:8001/test-singleton-set/Alice curl http://localhost:8001/test-singleton-get curl http://localhost:8001/test-singleton-get 結果 { " pid ": 14 ," action ":" SET "," value ":" Alice " } { " pid ": 14 ," action ":" GET "," value ":" Alice " } ← 別リク゚ストなのに残っおいる { " pid ": 14 ," action ":" GET "," value ":" Alice " } ← ただ残っおいる 別のリク゚ストにもかかわらず、Alice ずいう倀がそのたた芋えおいたす。 singleton バむンディングのむンスタンスプロパティに栌玍した倀が残るこずが確認できたした。 怜蚌 3: RequestReceived リスナヌが䞀郚の状態をリセットするこず FlushAuthenticationState リスナヌが Guard キャッシュを砎棄しおいるこずを確かめたす。 確認甚コヌド <?php use App\Models\User; use Illuminate\Support\Facades\Auth; Route :: get ( '/test-auth-set/{name}' , function ( string $ name ) { $ user = new User ([ 'name' => $ name ]) ; Auth :: setUser ( $ user ) ; return [ 'pid' => getmypid () , 'action' => 'SET' , 'user_name' => Auth :: user () ?-> name , ] ; }) ; Route :: get ( '/test-auth-get' , function () { return [ 'pid' => getmypid () , 'action' => 'GET' , 'user_name' => Auth :: user () ?-> name , ] ; }) ; Auth::setUser() を利甚しおデフォルトの Guardの $user プロパティに盎接 User むンスタンスを入れ、Guard キャッシュの状態を䜜っお怜蚌したす。 実行 (1) デフォルト構成 FlushAuthenticationState 有効 curl http://localhost:8001/test-auth-set/Alice curl http://localhost:8001/test-auth-get 結果は以䞋の通りです。 { " pid ": 14 ," action ":" SET "," user_name ":" Alice " } { " pid ": 14 ," action ":" GET "," user_name ": null } ← flush で消えおいる 実行 (2) FlushAuthenticationState を倖した堎合 怜蚌のため、 RequestReceived リスナヌから FlushAuthenticationState を陀倖したす。 <?php // config/octane.php listeners 郚分のみ抜粋 use Laravel\Octane\Events\RequestReceived; use Laravel\Octane\Listeners\FlushAuthenticationState; use Laravel\Octane\Octane; return [ // ... 'listeners' => [ // ... RequestReceived :: class => array_values ( array_filter ( Octane :: prepareApplicationForNextRequest () , fn ( $ listener ) => $ listener !== FlushAuthenticationState :: class , )) , // ... ] , ] ; 同じ curl を実行したす。 { " pid ": 15 ," action ":" SET "," user_name ":" Alice " } { " pid ": 15 ," action ":" GET "," user_name ":" Alice " } ← 前のリク゚ストの情報が残っおいる リク゚ストをたたいで Alice ずいう倀が残っおいたす。 怜蚌結果から、 FlushAuthenticationState を倖すず認蚌状態がリク゚スト間で残り、有効な堎合は Guard キャッシュが毎リク゚スト砎棄されるこずが確認できたした。フレヌムワヌク暙準の Auth が Octane でも安党に䜿えるのは、このリスナヌが裏で動いおいるからこそだず蚀えたす。 おわりに 本蚘事では、Octane + Swoole で前のリク゚ストの情報が次のリク゚ストに残る仕組みを敎理し、サンプルコヌドで動䜜を怜蚌したした。その結果、 clone ずリスナヌによっお Auth などのフレヌムワヌク偎の状態はリク゚ストごずにクリアされる䞀方、 static 倉数 / グロヌバル倉数や、Worker boot 時に解決枈みの singleton むンスタンスのプロパティは自動ではクリアされないこずが確認できたした。 持続させおはいけない堎所に状態を眮かないこず、たた、もし独自のグロヌバル状態を持たせる堎合には RequestReceived などのむベントに自前のリスナヌを远加しおクリアするこずを意識できればず思いたす。 最埌たで読んでいただきありがずうございたした。 参考 Deep Dive into Laravel OctaneAlbert Chen