有名テック企業の技術ブログを、ひとつのフィードで。
フィード
912件
LINEヤフー株式会社では、技術に関するイベントや勉強会の主催・協賛などを行っています。最新情報は各リンク先でご確認ください。タイミングによっては、申し込み開始前や既に満席となっていることがあります。...
こんにちは。 アプリケーションサービス本部、DevOps担当の兼安です。 本記事はこちらの記事の続きです。 blog.serverworks.co.jp 前回、マルチAIコーディングエージェントにおける mcp.json の書き方の整理と、APIキーなどの環境変数化を行いました。 今回はそれに加えて、AIが環境変数を読み込まないようにする設定ができるかを調べました。 調査対象は前回同様、Kiro・Claude Code・GitHub Copilot Agent Mode で、Kiro については CLI/IDE の両方を調べています。 本記事のタイトルに「調査」とある通り、残念ながら直接的な読…
はじめに こんにちは、ZOZOTOWN開発1部iOSブロックの@kitasukeです。 前回の記事「ZOZOTOWN iOS のアーキテクチャとチームの進化」では、MVCからMVVM、そしてMVVM + Repositoryへのアーキテクチャ進化を取り上げました。あわせて、レビュー文化をチームに根づかせてきた3年間も振り返っています。 ただ、アーキテクチャを文章で定義しても、書き手によって命名や責務分割はぶれが生じますし、AIに任せると過去の望ましくない実装パターンまで律儀に再現されます。ドキュメントによる「努力目標」では、アーキテクチャは守りきれません。 そこで発想を逆にしました。アーキテクチャを「守るべきルール」ではなく、構造化されたスキーマとして定義し、人間とAIの双方がそれに従うしかない形にします。Swiftの型システムがコンパイル時に不正を弾くのと同じ発想を、アーキテクチャのレイヤーにスキーマという形で持ち込みます。それが本記事で紹介する「スキーマでアーキテクチャを縛る」アプローチです。副産物として、設計からコードを自動生成するパイプラインも動いています。 目次 はじめに 目次 どんなスキーマを定義したのか architecture-guidelines.md — コンポーネントをスキーマで縛る architecture-templates.md — スキーマから Swift を導出するルール どうやって縛っているのか 画面ごとの設計を YAML で表現する /architectureと/codegen — 実際の運用 /architecture: 仕様書やデザインから YAML を起こす /codegen: YAMLからSwiftのコードを生成する 何が変わったのか AIの書くコードがレビューを通る水準になった レビューで「プロダクト品質」の話ができるようになった まとめ どんなスキーマを定義したのか 全体像はこうなっています。 仕様書 (Confluence) / デザイン (Figma) / 既存コード │ ▼ /architecture ┌─────────────────────┐ │ 設計 YAML │ ←── AI / Codegen 向け │ Human Doc (Markdown) │ ←── 人間向けレビュー資料 └─────────────────────┘ │ ▼(人間がレビュー・編集) │ ▼ /codegen Swift コード一式 ↑ 全工程でガイドラインとテンプレートが参照される 土台となっているのが、チームで整備した 2つのドキュメント です。 architecture-guidelines.md — 各コンポーネントのスキーマ(何が正しいか) architecture-templates.md — スキーマからSwiftを導出するテンプレート(どう書くか) architecture-guidelines.md — コンポーネントをスキーマで縛る 各コンポーネント(ViewModel、Repository、Translatorなど)を、型・依存・命名・必須ルール・禁止パターンなどのフィールドで厳密に定義しています。たとえばViewModelのスキーマは次のとおりです。 ### ViewModel - type: `@MainActor final class` - imports: [Foundation, Combine] - imports_forbidden: [APIModule] - depends_on: [RepositoryProtocol, UIModelTranslator, DataModel, UIModel] - nested_types: [ViewState, Router] - naming: {Feature}ViewModel - required: - ViewState enum で画面状態を管理(複数 Bool 禁止) - @Published private(set) で外部からの直接変更を防止 - 1 ユーザーアクション = 1 input メソッド(did{Verb}{Noun}) - forbidden: - キャッシュロジック(Repository の責務) - ログ送信の直接呼び出し(UseCase/別 Repository に分離) 自由に書ける余地を意図的に潰しているのがポイントです。ViewModelがAPIモジュールをimportした時点でアウトです。@Published を private(set) にしなかった場合もアウトです。自己流のMVVM解釈を許さない設計になっています。 architecture-templates.md — スキーマから Swift を導出するルール スキーマだけではSwiftコードの具体的な書き方までは決まりません。命名規則、ファイルの生成順序、各レイヤーのSwiftコードテンプレートなどを、もう一段別のドキュメントで固めています。ガイドラインがスキーマで、テンプレートが導出規則です。この2つが揃うことで、アーキテクチャのスキーマから具体的なSwiftコードが一意で決まる状態になりました。 どうやって縛っているのか 人間・AI・ツールの全員が、同じスキーマで動くようになっています。順に見ていきます。 画面ごとの設計を YAML で表現する コンポーネントのスキーマが決まっても、画面ごとの実装は別物です。そこで、画面ごとの設計を1枚のYAMLで記述します。 feature: ProductList domain: Product api: - id: fetchProducts method: GET path: /products response: items: [Product] actions: - trigger: didAppear api: fetchProducts - trigger: didTapRetry api: fetchProducts condition: "state == .error" models: data: - name: Product fields: id: String name: String brandName: String price: Int imageURL: URL ui: - name: ProductListUIModel fields: nameText: String brandText: String priceText: String このYAMLは、ガイドラインが定めたスキーマの「値」にあたります。画面のAPI、アクション、データモデルが構造化されて並んでいるだけで、曖昧さの入り込む余地はありません。 /architectureと/codegen — 実際の運用 この縛りを日々の開発で実行しているのが2つのスラッシュコマンドです。 /architecture: 仕様書やデザインから YAML を起こす 重要なのは、このYAMLを人間がゼロから書いているわけではないという点です。Confluenceの仕様書やFigmaのデザインを入力にすると、/architectureコマンドが設計YAMLと人間向けMarkdownの大部分を自動生成します。 人間の作業は「書く」ではなく「判断する」に寄っています。生成されたYAMLを読み、責務分割やエッジケースの扱いなど設計判断が必要な箇所だけに手を入れます。スキーマが縛ってくれているので、AIが起こしたYAMLも標準から外れた形にはなりません。 /codegen: YAMLからSwiftのコードを生成する レビューが終わったYAMLを /codegen に渡すと、Swiftコード一式が出力されます。具体的には、View / ViewModel / Repository / プロトコル / モック / ユニットテストの雛形 / 依存注入のコードです。 たとえば先ほどの ProductList.yaml のうち、以下の部分に注目します。 actions: - trigger: didAppear api: fetchProducts - trigger: didTapRetry api</
1. はじめに DRE(Data Reliability Engineering)グループ のつざきです。タイミーのデータエンジニアリング部で、BigQuery / dbt / Cloud Composer / Looker といったデータ基盤の開発・運用をしています。 DREチームでは 2026 年 2 月から、AWS が提唱する AI-DLC(AI-Driven Development Life Cycle)というワークフローを運用しています。きっかけは、 1 月末に AWS 主催の研修「Unicorn Gym」で3 日間 AI-DLC を体験したことでした。 AI-DLC 自体とタイミー全体への波及は同部の橋本さんが、Operations フェーズ(リリース後の検証)の独自構築については同じ DRE G の chanyou さんが、それぞれまとめています。 3日間のUnicorn Gymが1ヶ月で組織を変えた —— データで見るAI-DLC導入の波及効果(橋本さん) 「リリース後」に向き合うAI駆動開発の実践(chanyou さん) 本記事はこれらの続編的な位置づけで、「DREチーム が Inception と Construction フェーズで何を実装・運用しているか」に絞って書きます。 対象読者: AI-DLC を個人ではなく、チーム(モブ)で運用したい開発/データ基盤チーム この記事の目的: 公式の想定(単一プロジェクト/個人運用)を、複数リポジトリ・リモートモブ前提に翻訳した実装パターンを共有する 扱わないこと: Operations フェーズの詳細、全社展開の話、AI-DLC の一般解説 TL;DR DREチームは 2026 年 2 月から AI-DLC を運用中 実装: Workspace + CLAUDE.md 読み替え、Intent 単位の運用 モブ: 1 日 3 ~ 4 時間のフルリモートモブ。狙いは「フロー効率(承認ゲートで止まらない)」「キーパーソンに頼らない(新基盤導入や新メンバー受け入れに効く)」「AI 出力の欠陥を集合知で減らす」の 3 つ 3 ヶ月の結果: Intent 完了が月 14〜17 件で推移、PR 数は維持、サイクルタイムに劇的な変化は見えず 記事の立ち位置: 公式に書かれていない実装の隙間(Mob、複数リポジトリ、パス読み替え等)を自分たちで翻訳した事例として記録 2. AI-DLC をざっくり AI-DLC の全体像は既出記事に譲り、本記事で後から使う概念だけ押さえておきます。 本記事での用語の使い方 Intent: 1 つのゴール(例: あるデータソースを BigQuery で使えるようにする) Unit: Intent を疎結合に分解した作業単位(DDD の Subdomain 相当。例: Terraform 追加、DAG 実装など) Ritual: モブでの儀式的な作業(後述の Mob Elaboration / Mob Programming / Mob Testing) Workspace: ドキュメントとルールを置く専用リポジトリ フェーズと成果物の階層 AI-DLC には 3 つのフェーズがあります。 Inception: 要件分析・設計 Construction: 実装・テスト Operations: デプロイ・監視 3 つの Mob Ritual 各フェーズには対応する儀式(Ritual)が定義されています。 Mob Elaboration(Inception): 要件分析・分解を全員で Mob Programming(Construction): 実装を全員で Mob Testing(Construction): テストを全員で いずれも、公式推奨は「物理集合 + 共有スクリーン + ファシリテーター」です。 Human Oversight = Loss Function AI-DLC は AI が実行主体、人間は各ステップで検証・承認する構造です。公式ペーパーの表現が印象的で: "Each step serves as a strategic decision point where human oversight functions like a 'loss function' - catching and correcting errors early before they snowball downstream." 機械学習の損失関数のように、人間のレビューが早期にエラーを補正する、というメタファーです。後の章でモブワークの話をするときに効いてきます。 3. 公式ドキュメントに書かれていない実装ギャップ chanyou さんの記事では、awslabs/aidlc-workflows リポジトリで Operations フェーズがプレースホルダになっている話が出てきます。実は Inception と Construction の側にも、公式の文書と実装の間にいくつかのギャップがあります。 awslabs/aidlc-workflows の構成 原典の awslabs/aidlc-workflows は MIT-0 ライセンスで公開されている、マークダウンのルールファイル群です。 aidlc-rules/ ├── aws-aidlc-rules/ │ └── core-workflow.md # ワークフロー本体 └── aws-aidlc-rule-details/ ├── common/ # 共通ルール ├── inception/ # Inception 詳細 ├── construction/ # Construction 詳細 └── operations/ # プレースホルダ ギャップ 1: ルール実装に Mob の記述がない AI-DLC 公式ペーパーでは Mob Elaboration / Mob Programming / Mob Testing が中核の儀式として定義されています。しかし原典のルールファイル群を mob で grep してもヒットしません。実装部分は「個人と AI エージェントが 1 対 1 で対話しながら承認ゲートを通す」構造になっており、Mob は想定されていない書き方です。 ギャップ 2: 公式チュートリアルは個人開発の例 AWS 公式ブログの実践記事 Building with AI-DLC using Amazon Q Developer のサンプルは、単一 HTML ファイルの川渡りパズルを個人で作る例だけで、モブで回す実演は出てきません。 ギャップ 3: 複数リポジトリの扱いが明確でない 公式は単一プロジェクト前提です。データチームのように「1 つの機能を作るのに複数リポジトリにまたがる」ケースへの具体的な示唆はほぼありません。 理念と実装の翻訳が必要 つまり、公式ペーパーに書かれた「Mob ワーク」や「複数チームでの協調」を実際に動かすには、自分たちで翻訳する必要があります。DRE では、各ギャップに対応する形で次のように対処しています。 ギャップ 1(Mob がルールにない) → モブでの意思決定を組み込み(章 6) ギャップ 2(単一 Intent 想定) → Workspace + CLAUDE.md 読み替え(章 4) ギャップ 3(複数リポジトリが薄い) → 複数リポジトリを 1 Intent でまとめる(章 5) 次章から具体に入ります。 4. DRE の実装: Workspace + CLAUDE.md 読み替え AI-DLC を Claude Code で回すために、DRE では次の構成にしています。 全体像(先に結論) ルール階層: aidlc-rules/(上流)→ .claude/rules/(上書き)→ CLAUDE.md(入口) パス読み替え: aidlc-docs/requirements.md を aidlc-docs/intents/<YYYY-MM>/<intent_name>/inception/requirements.md に読み替え Intent 箱: Intent ごとに独立したディレクトリ(intents/<YYYY-MM>/<intent_name>/) 状態管理: aidlc-state.md に Status と Code Repositories を記録 スキル化: Intent ライフサイクルを Claude Code のスキルで操作 以下、理由と詳細を順に見ていきます。 なぜこの構成なのか awslabs のリポジトリは単一プロジェクト・単一 Intent 前提で書かれていて、1 つの aidlc-docs/ ディレクトリに成果物を蓄積する想定になっています。 一方で DRE は、Intent という単位で開発を進めていて、完了した Intent もそのまま保存しています(後述しますが 2026 年 3 月は 14 件の Intent が完了しました)。Intent ごとに独立したディレクトリが必要になるので、パス読み替えが不可欠です。 ルール階層(継承構造) aidlc-rules/: awslabs/aidlc-workflows の中身をそのまま取り込む。手動変更禁止、/aidlc-rules-update スキルで上流追従 .claude/rules/: プロジェクト固有のルール。aidlc-rules のオーバーライドや追加ルールを置く CLAUDE.md: エントリポイント。プロジェクト概要とディレクトリ規則を最小限に記述 上流は変えない。プロジェクト固有の振る舞いは派生側で足す。オブジェクト指向の継承に近い発想です。 [入口] CLAUDE.md ├─ 参照: aidlc-rules/ # 上流(awslabs 同期、変更禁止) └─ 参照: .claude/rules/ # 派生(DRE 固有、オーバーライド+追加) パス読み替えの例 awslabs のルールは、成果物の置き場として aidlc-docs/ というパスを前提に書かれています。DRE ではこれを Intent ごとのディレクトリに読み替えます。 公式: aidlc-docs/requirements.md DRE: aidlc-docs/intents/<YYYY-MM>/<intent_name>/inception/requirements.md この読み替えは .claude/rules/aidlc-workflow.md に定義してあり、Claude Code が実行時に解釈します。ルール本体(aidlc-rules/)は触らずに、パスだけ派生側で書き換える構成です。 Intent ディレクトリの構造 1 つの Intent のディレクトリはこういう構造です。 aidlc-docs/intents/<YYYY-MM>/<intent_name>/ ├── intent.md # Intent の目的・受け入れ基準 ├── aidlc-state.md # Intent の状態管理 ├── audit.md # 監査ログ ├── inception/ │ ├── requirements.md │ ├── stories.md │ └── ... └── construction/ └── <unit_name>/ ├── functional-design.md ├── code-generation.md └── ... aidlc-state.md のカスタマイズ Intent の進捗追跡に使う aidlc-state.md は、公式テンプレートをベースに少し拡張しています。 Status: OPEN / SUSPEND / CLOSED の 3 値を追加 Assignee: 担当者 Code Repositories: 複数のコードリポジトリのブランチ状態を記録 この Code Repositories セクションが次の章(複数リポジトリ運用)の鍵になります。 スキル化 Intent のライフサイクル管理は Claude Code のスキルとして定義しています。 /aidlc-intent-start: 新規 Intent 開始 /aidlc-intent-continue: 既存 Intent の再開 /aidlc-intent-save: 作業内容を PR 化してマージ /aidlc-rules-update: 上流(awslabs)への追従 chanyou さんの記事では /inception のように AI-DLC のワークフローそのものを呼び出すスキルが紹介されています。一方、DRE では「Intent というライフサイクルの入れ物」をスキル側で担う構成にしています。どちらも awslabs のルールに乗りつつ、スキルで扱う粒度が違う、という関係です。 5. 複数リポジトリを 1 Intent でまとめる DRE のようなデータ基盤チームでは、1 つの機能を作るのに複数のリポジトリが絡みます。 典型的なワーク 例えば「ある外部 SaaS のデータを BigQuery に自動転送するパイプラインを構築する」といった Intent だと、以下のようなリポジトリにまたがる変更が必要になります。 GCP Terraform リポジトリ: IAM やデータセットの定義 Composer インフラリポジトリ: Cloud Composer や Secret Manager の Terraform Composer DAG リポジトリ: Cloud Run Job と Airflow DAG のコード dbt リポジトリ: staging モデル これを 1 つの Intent としてまとめます。まず Inception フェーズで全体の要件・設計を固め、その後 Construction フェーズで各リポジトリに Unit を切って進めます。例えば DRE の 2026 年 2 月に動かしたあるパイプライン構築 Intent では、4 ユニット・60 ドキュメント・6 PR で完了しました(規模感の一例として)。 ブランチ戦略の 2 階建て ドキュメントとコードで別々のブランチ戦略を使い分けています。 Workspace リポ: session/<intent_name>/<hex> という短命ブランチ。スキル呼び出し単位で切って都度 main にマージ コードリポ: feature/<intent_name> という長命ブランチ。Intent が完了するまで維持 Workspace 側はドキュメントの進捗を小さくマージして積み上げ、コードリポ側は実装が揃ったタイミングで main に入れる、という二層構造です。 aidlc-state.md に Code Repositories を記録 1 つの Intent が複数リポジトリに触るので、どのリポのどのブランチで作業しているかを aidlc-state.md に記録しておきます。 <pre class="code lang-markdown" data-lang="markdown" data-unlink
入社5年、同期3人の振り返り body { font-family: "Hiragino Sans", "Meiryo", sans-serif;} .intro { background: #f5f4f0; border-radius: 8px; padding: 1rem 1.4rem; margin: 1.5rem 0; } dl { margin: 1rem 0; } dt { font-weight: bold; margin-top: 1.2rem; } dd { margin-left: 1.8rem; margin-top: .2rem; } .ref { font-size: .9rem; color: #666; margin-top: 1rem; } .ref a { color: #0073e6; } /* メンバーごとのカラー */ dt.massan { color: #c49000; } /* kintone */ dt.taguchi { color: #3d8fa8; } /* Cybozu */ dt.taku3n { color: #1a4db8; } /* Garoon */ /* 方法①:フォトライフ画像の枠線を消す+中央揃え */ img.hatena-fotolife { border: none; display: block; margin: 0 auto; } こんにちは!2021年にサイボウズへ新卒入社した massan、taguchi、taku3n です。気がつけば入社から5年。同期3人がそろって在籍しているこの機会に、それぞれの5年間を振り返ってみました。 massan kintone拡張基盤チームのQAエンジニアです。着物の勉強をしています。 taguchi PSIRTのプロダクトセキュリティエンジニアです。ラーメンが好きです。 taku3n Garoon開発チームのQAエンジニアです。最近ボードゲームにハマってます。 この記事は、QA として入社して1年経った話のリバイバル記事です。 ※元記事では柔軟な働き方について、現在は実現が難しいものが含まれています。あくまでQA職種の仕事や文化の参考としてご参照ください。 最近はどんな業務をしてる? まずは、現在の業務について紹介します。 massan 主務では、kintoneを拡張する人を支援する基盤づくりのQAをしています。APIやSDK、去年はMCPサーバーの開発にも関わっていました。 兼務も少しあって、kintoneのセキュリティチャンピオン、社外向けの技術交流を促進するQA外部コネクト、QA新卒採用なども担当しています。マネージャーに誘ってもらったり、自分から関わりたいと思って始めたものばかりです。 異なる分野を学び、それらを媒介したり組み合わせて生かしたりするのは自分の性格に合っていると感じます。いろんな業務を通してtaku3nやtaguchiさんをはじめとるする他メンバーとも製品を超えて刺激をもらうことができ、日々の業務のモチベーションになっています。 taguchi 現在はサイボウズ Office、メールワイズ、販売管理システム、cybozu.com共通管理などのセキュリティを担当しています。具体的には、脆弱性診断、外部べンダー対応、バグバウンティ対応を中心に、担当製品のセキュリティに関する業務全般に携わっています。 そのほかにも、PSIRTの新卒採用、情報発信、AIを活用したPSIRT業務・脆弱性診断の効率化にも取り組んでいます。 taku3n 主にGaroonのリリース改善に取り組んでいます。具体的には、リリースとデプロイの分離やプロセス改善を通して、高速で安定したリリースの実現を目指しています。その中で、新しく作り上げるリリースフローのテスト活動も行っています。 その他では、他チームからのGaroonの品質に関する問い合わせ対応、テストアーキテクチャ設計、QA新卒採用、アシスタントマネージャーなどにも取り組んでいます。 3人の所属する組織図概略 ref. サイボウズの QAエンジニアについて / about cybozu QA 5年間でどう変わった? 次に、入社からの5年間でどのような変化があったかを振り返ります。 massan 入社してすぐ、kintoneQAのインプロセス化がそれまで以上に進み、開発チームも担当領域の分割が進みました。kintone全体を見るのではなく、開発チームに所属して自分の担当領域に絞って見るようになったんです。オーナーシップは持てるようになりましたが、その反面、過去の資産に頼れない場面も多くなりました。 そんな中、プロダクトの初期段階から頼ってもらえるQAになるべく、新規立ち上げされたkintone拡張基盤チームに配属されました。立ち上げから1年以上経ちますが、固定化されたテスト実施タスクは少なく、品質戦略の策定、テストフローの整備、テスト資産化など業務は多岐にわたります。 自分のスキルや知識がチームの品質の上限になってしまうので、ISTQBをはじめとする勉強で体系的な知識をつけたり、カンファレンスに行って知見を増やしたりしています。最近は脆弱性周りに気を配ったり、シフトライトの強化を検討したりもしていて、4月はtaguchiさんのいるPSIRTに体験入部してきました。5年も経つと同期同士でも専門性が違ってきて、改めて身近に頼れる同期がいることのありがたさを実感しています。 taguchi 最初は製品の脆弱性診断を中心に担当していましたが、その後、担当製品に関わらずPSIRT全体の診断にも目を向けるようになりました。現在も診断全体の効率化は継続的に進めています。さらに、プロダクト全体のセキュリティを見る立場も担うようになり、業務への関わり方や役割は変化してきました。 また、PSIRTにはプロジェクトを小規模なチームを編成して進められる仕組みがあります。自分がジョインした当時にはなかったのですが、常に複数のプロジェクトが同時並行で進んでおり、最近ではPSIRT業務を支える根幹のひとつになっています。この仕組みのおかげで、セキュリティの技術的な部分だけでなく、PSIRTそのものについて考える機会も増えましたし、オーナーシップを持って進めていく経験にもつながっています。 taku3n 入社当初は、Garoonの膨大な仕様を理解することに必死で、手動テストプロセスやリリースプロセスの基礎を学ぶ毎日でした。その一方で、現場作業を少しでも効率的にするための改善活動を通して、プロセス改善に興味を持ち始めました。 転換点は、3年目にリリース改善チームへ加わったことです。それまでのQAのみのチームから、SWE(ソフトウェアエンジニア)と同じチームで活動するインプロセスな体制に変わり、よりシフトレフトを意識するようになりました。テスト対象もプロダクト単体からリリースの仕組み(CI)に変わり、品質を担保する方法を探りつつ構築していきました。この活動を通して、いかに安全かつ高速に価値を届けるかというプロセスの品質に、強く向き合うことになりました。 現在は、品質の可視化やリリースとデプロイを分離するフィーチャーフラグの導入プロジェクトのリーダーとして、リリース運用の土台からアップデートする効率化に取り組んでいます。5年間の積み重ねを経て、今はより広い視点でプロセス全体を捉え、改善策を提案していけるようになりました。今後も「楽をするための努力」を続けていきたいです! AIとどう向き合ってきた? 5年間の中でも特に大きな変化だったのが、AIの台頭です。QAとしてAIとどう向き合ってきたかを話してみました。 massan ひとりQAでチームの工数も限られる中、AIなくしてはチームの開発が成り立たないレベルになっていると思います。テスト設計など自分がこれまで行ってきた業務をAIに依頼するだけでなく、やりたかったけれど時間や一部スキルが足りずにできなかったことにも手を出せるようになり、チームへの貢献度が上がりました。たとえば、細々したケースの全数テストや、セキュリティアラートを受けた際の影響調査、修正、テストなどに活用しています。 一方で、MCPサーバーの開発ではユーザーのAI利用を助けるような立場にもなり、AI利用の両面を経験しています。 taguchi ここ5年間のAIに関する動きとしては、サイボウズ内でもAI関連機能の開発が進み、それに伴ってPSIRTでもAIに対する診断を内製化する動きがありました。推進を担当したメンバーのおかげで、今ではテスターのほぼ全員がAIに対する診断を行える状態になっており、開発者向けに社内で勉強会を実施するなど、チームとしてAIセキュリティに関する知見も蓄積されています。 脆弱性診断へのAI活用という文脈では、昨年からAIエージェントによる診断も導入しています。開発がますます高速化する中で、PSIRTとしてもそれに追随できるよう、今後さらにAIを活用した診断の自動化を進めていきたいと考えています。 taku3n 4年目にAIを活用したGaroonの新機能開発チームにQAメンバーとしてジョインしたことが大きな転機でした。精度検証やプロンプトチューニングといった、これまでにない領域でのQA活動は手探りの連続でしたが、AIの品質保証プロセスを一から作り上げる経験ができました。 なんで5年経っても3人ともいるの? 最後に、同期3人がそろって5年間在籍し続けている理由を聞いてみました。 massan 正直、転職のモチベーションは増えたり減ったりしてきました。でもプロジェクトが多いので、これまで自分の成長段階それぞれにちょうど良いチームや役割をあてがってもらううちに気づけば5年が過ぎていました。 サイボウズはQA組織が大きいのが特徴で、知見の共有や相談、他チームの事例などに手軽にアクセスできるのが良いところです。その一方で、自分は小さいチームのひとりQAなので「自分が動かないと何も変わらない」という状況もあります。 興味があることを無闇にやらせてもらえるとは感じませんが、自分が稼いできた信頼貯金で新しいことをさせてもらえるだろうという実感はあります。あえてあげるなら、これが大きな理由かもしれません。6年目となる最近はその貯金をちゃんと使って、自律的にチームや事業への貢献を増やす方法を学んでいる段階だと思っています。 taguchi 環境の良さは大きいですね。チームの雰囲気はもちろん、いろんなことに挑戦できる環境や気軽に相談できる場が整っていると感じます。自分としても、興味のある領域に関わらせてもらっている感覚がありますし、新しいツールの導入や「やってみたい」と思ったことをすぐに試せるスピード感もあります。 このあたりの印象は入社した頃からずっと変わっていなくて、会社全体としてそういった雰囲気があります。そうした環境がモチベーションの維持にもつながっていると思います。 taku3n 一番の理由は「今取り組んでいることが面白いから、もっと続けたい!」という思いが強いからです。振り返ってみると、この5年間のうちに何度か所属チームが変わり、向き合う課題もさまざまでした。ちょうどコンフォートゾーンに陥りそうになったタイミングで新しい変化が起き、そのたびに目新しい挑戦がありました。最初は難しくても、やり込んでいくうちにその面白さにハマっていく。そんな刺激的なサイクルに自ら挑みながらも、会社に後押ししてもらえていたと実感します。 また、大きな課題にぶつかって悩んでいるときも、チームとして解決しようと協力してくれる温かいメンバーが周りにいることも大きいです。サイボウズは「チームワークあふれる社会を創る」という理念に共感した人が集まっている組織なので、自然と現場でもチームワークがあふれています。こうした環境があるからこそ、変化を楽しみながら5年間走り続けてこられました!
※ 2026年4月時点の情報です こんにちは、データアナリティクス部のkoyoです。2024年1月に「データアナリストの一日」という記事を書きました。あれから2年が経ち、分析の進め方がかなり変わったので、改めてお伝えできればと思います。 この記事で紹介するのは、AIへのプロンプトの工夫ではありません。AIが正しく動き続けるための環境を自分で設計した話です。 Before / After — 変わったのは「認知負荷の配分」 2024年の朝はこんな感じでした。Slackの通知を上から順に読んで、未読チャンネルを巡回して、カレンダーを確認して、「あ、あのスレッドに返信できていなかった」と気づく。情報を集めること自体に時間と集中力を使っていました。 2026年の朝は違います。出社するとSlack DMにブリーフィングが届いています。自分がやることは、それを読んで判断し、返信するだけ。 変わったのは作業の速さではなく、認知負荷の配分です。「何を見るべきか」を考える必要がなくなった分、「見たものに対してどう判断するか」に集中できるようになりました。 昨年からAIエージェント(Claude Code)に本格的に向き合ってきました。個人でも、データ収集・分析パイプラインの構築や、育児・家事を含めた日常オペレーションの自動化など、生活のあらゆる場面でAIとの協働を重ねてきました。 データの収集・加工・判断支援という一連の流れをAIと一緒に設計・運用する経験を積む中で、「この考え方は分析業務にそのまま適用できる」という手応えを得ました。それを業務環境に展開したのが、これからご紹介する仕組みです。 朝のブリーフィング — 8つの視点で1日を俯瞰する 毎朝、ブリーフィングが自動生成され、Slack DMに届く仕組みを構築しています。Claude Codeの /loop 機能(cronのようにコマンドを定期実行するスケジュール機能)を使い、毎朝決まった時間に実行される設計です。 カレンダーAPI、Slack API、Notion API、Google Tasks APIを横断して情報を収集し、8つの視点で1日を俯瞰できるブリーフィングにまとめます。この仕組みは既製品ではなく、API連携スクリプト、収集ロジック、検証ルール、Slackメッセージの整形まで自分で設計・実装しました。 朝のブリーフィング自動生成フロー 📅 朝ブリーフィング ━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1. 今日の予定 ← カレンダーAPI連携 2. 要対応 ← Slack未返信検出 + TODO期限 3. チーム動向 ← 所属チャンネルの横断要約 4. 注目チャンネル ← 担当プロジェクト関連の要約 5. 依頼更新 ← Notionの対応依頼 + チーム連絡の更新 6. ナレッジ鮮度 ← 知識ベースの最終更新チェック 7. 目標進捗 ← 四半期個人目標のリマインド 8. TODO追加提案 ← 全セクション横断の見落とし検知 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━ → Slack DMに自動送信 ブリーフィングのSlack DMスクリーンショット ブリーフィングの3つの工夫 ① Slackの確認漏れ防止 直近3日間の自分宛スレッドを取得し、最終発言者が自分でなければ「未返信候補」として検出します。ただ、スレッド返信ではなく別のメッセージで対応済みのケースもあります。そこで、同チャンネルの同日付近にある自分の発言をクロスチェックし、「対応済みなのに未返信と誤検知する」ケースを排除する仕組みにしています。 これだけで「あのスレッドに返信できていなかった」が大幅に減りました。 ② 複数ツールの文脈を自動で横断する ただ情報を集めるだけなら、各ツールを開けば済む話です。このブリーフィングの価値は、人間が毎朝手作業で確認するには現実的でない量の情報を、構造化して届ける設計にあると思っています。 複数のSlackチャンネルを同時に監視し、チームの動向と担当プロジェクトの最新状況を毎朝要約します。分析依頼については、Slackの通知だけでなくNotionの依頼ページの中身まで参照します。そのうえで、自分の担当領域に合致するものを自動で判定します。会議予定にはNotionの議事録リンクやSlackの関連スレッドを自動付与する設計です。 「この会議って何の話だっけ?」「この依頼は自分が拾うべき?」を自分で調べに行く時間がなくなりました。 ③ TODO提案で見落としを防ぐ ブリーフィングの最後に、「TODO化すべきだがまだ登録されていない項目」を提案する仕組みを組み込んでいます。そのために、複数の情報ソースを優先順位付きで横断します。自分が「あとで対応する」と保存したSlackスレッド、未アサインの分析依頼、自分宛の未返信スレッド、全社向けの対応依頼 — これらを順にチェックし、既存TODOのタイトルと照合して重複を除外した上で提案します。 各提案には、「なぜTODO化すべきか」の判断理由を付与する設計です。提案の前には必ずスレッド本文を読み、タイトルだけでは判断しないルールも組み込んでいます。さらに、過去にタイトルだけで誤った提案をしてしまった経験から、このルールを追加しました。 曜日に応じて変わる情報収集 ブリーフィングは毎日同じではありません。月曜日にはナレッジの参照目次を最新状態に更新し、月初にはデータ基盤に加わった変更点をまとめて取得し、週明けにはデータ基盤の週次変更サマリーが新しい情報として表示されます。業務のリズムに合わせて情報収集の範囲が自動で変わる設計にしています。 ブリーフィングを支えるナレッジ基盤 ブリーフィングが正確に動くのは、AIが参照できるナレッジベースがあるからです。 ブリーフィングを生成する中で、AIは毎朝いくつもの判断をしています。たとえば: 「この分析依頼は自分が拾うべきか?」 → 自分の担当テーマの定義を参照 「このナレッジは古くなっていないか?」 → 各ファイルの最終検証日を参照 「この未返信スレッドは本当に未対応か?」 → クロススレッド対応の判定ルールを参照 「この社内用語は何を指しているのか?」 → 部門横断の用語集を参照 これらの判断を一つひとつ仕込んでおくのではなく、「判断に必要な情報」をAIがいつでも参照できる形で整備しておくのがナレッジ基盤の役割です。 目的別にディレクトリを分け、全体では12カテゴリ・約250ファイルを蓄積しています。 knowledge/ ├── business-logic/ ← 担当領域の定義・用語・判定ルール ├── collaboration/ ← コミュニケーション運用ルール ├── data-dictionary/ ← データ基盤の構造 └── sql-patterns/ ← 分析で使う設計パターン・検証テンプレ 最初から整備されていたわけではなく、日々の業務の中で少しずつ蓄積してきました。最初は空でも大丈夫です。使うことで育っていきます。 ブリーフィングが毎朝正確に届くようになって初めて、「判断の材料をAIが自律的に参照できる状態」こそがこの仕組みの土台なのだと実感しました。同じ考え方は、日常のクエリ作成や資料作成など別の業務にも応用しています。 設計思想 — AIを信頼できる同僚にする3つの原則 この仕組みを作る中で、AIとの協働に大切だと感じた原則が3つあります。 AIを信頼できる同僚にする3つの原則 ① 推測禁止 — 知らないことは調べる ブリーフィングでは、自分宛の未返信スレッドを毎朝検出しています。「このスレッドは未返信か?」を判定するとき、安易に「最終発言者が自分でなければ未返信」と推測すると、同チャンネル内の別メッセージで対応済みのケースを誤検知してしまいます。AIが推測で結論を出すと、毎朝同じ誤通知が届き続ける — これが一番厄介です。「知らないなら調べる、調べていなければ使わない」をルールに組み込むことで、この誤検知は大きく減りました。 ② 検証付き実行 — 作ったら検証してから報告する 未返信候補を検出したあと、同チャンネル内で自分が別メッセージで対応済みでないかを必ずクロスチェックしています。ブリーフィングの各セクションも、出力前に整合性を検証するステップを必ず挟んでいます。「動いたから正しい」ではなく、「検証したから正しい」を積み重ねていく考え方です。 ③ ソース付き情報 — 出所のない情報は存在しないのと同じ ブリーフィングの全項目にソースリンクを必須にしています。「どこかで見た気がする」ではなく、リンクを辿れば原文にたどり着ける。これがAIの出力を信頼できる理由です。 仕組みがあるからAIの出力を信頼できる。信頼できるから判断に集中できる。同じ3原則は、クエリ作成や資料作成にもそのまま当てはまる考え方でした。 変わったこと・まだ変われないこと 変わったこと 朝の情報確認が5分で完了するようになりました。Slackの返信漏れも大幅に減りました。一番大きいのは、「自分から情報を見に行く」から「情報が届く」に変わったこと。その分、判断と行動に使える時間が増えました。 これから変わりたいこと 情報収集と検証をAIに任せられるようになった分、DAとしてより価値の高い仕事に時間を使えるようになってきました。たとえば、事業課題の構造化や仮説の設計、ステークホルダーとの対話などです。ただ、まだその変化の途中にいます。 一番の課題は、この仕組みがまだ個人最適にとどまっていること。チーム全体で活用できる形にしていくのは、今後の挑戦です。 まとめ 2年前は「データアナリストの一日」を自分で全部やっていました。今は、朝の準備が完了した状態で1日を始められる環境を設計しました。 AIの能力は日々進化していますが、それだけでは業務の質は変わらないと思っています。AIが正しく動くためのナレッジや、出力を信頼するためのルール、見落としを防ぐための検証など、こうした「環境」を人間が設計して初めて、AIは信頼できる同僚になる。逆に言えば、環境を設計する力がこれからのデータアナリストに求められるスキルなのかもしれません。 自分はこういう形を選びましたが、やり方は人それぞれだと思います。もし興味があれば、まずは普段使っているテーブル定義を1つ、Markdownに書き出してAIに参照させてみるところから試してみてください。推測で書かれたクエリとの違いに気づくと、面白いと思います。 AIの社会実装や企業での本格導入がさらに進んでいく中で、こうした運用のあり方も磨きをかけながら形を変えていくと思います。そのときにまた、続編を書けたらいいなと思っています。 環境設計という視点が、どなたかの次の一歩のヒントになれば嬉しいです。 We're Hiring! タイミーでは、ともに働くメンバーを募集しています! データアナリストのポジションも募集中です。カジュアル面談も行っていますので、少しでも興味がありましたら、お気軽にご連絡ください。 データ | 採用情報 |株式会社タイミー
1. はじめに こんにちは!IT戦略部の森嶋です。 先日、当社では 「DeNA × AI Day 2026」 が開催され、そこで「AI Workspace」プロジェクトについての発表をしました。 社内AIヘルプデスク「Findout」は技術的な最適化を積み重ね、回答精度は当初の44%から80%へと劇的に改善しましたが 、そこから先、どうしても80%を超えられない「壁」に直面しました。この壁の正体を分析すると、原因の70%が「ドキュメント(=ナレッジ)不足」という、RAGチューニングだけでは解決できない事実に行き着きました 。 もちろん、AI に「解決策」を提示させること自体は簡単です。しかし、AI が描く理想論をすべて受け入れることは、リソースの限られた現場では現実的ではありません。
AIエージェント向けのスキル(Agent Skills)、みなさんはどう管理していますか? 2026/04/16、GitHub公式CLIのghに、スキルをパッケージ管理する新しいサブコマンドgh skillが追加されました。GitHubのリポジトリに公開されているスキルをgh経由でインストール・アップデート・公開できます。私はこれまでnpx skillsでスキルをインストール・管理してきましたが、gh skillの方が安全面でよさそうなので乗り換えることにしました。 本記事では、メリットや実際の動作を紹介します。 https://github.blog/changelog/2026-04...
※本記事は、こちらの記事を和訳したものです stratomere.com 序章 航空機が音速を超えると、衝撃波が発生する。衝撃波は周囲の空気が伝わる速度よりも速く移動するため、周囲の空気がその擾乱を吸収しきれず、不連続性が生じる。これがソニックブームである。 池の水面に広がる波紋のように、衝撃波は外側へと伝播し、その影響は距離とともに薄れていく。AIサービスの需要は、技術サプライチェーンが吸収できる速度をはるかに超えて拡大している。マイクロソフトのCEOによれば、当初は大規模な言語モデルの学習と実行にGPUが必要だったが、今ではそれらを動かすためのエネルギーが課題となっている。こうした波紋は私たちの日常生活にも波及し、データセンターの需要が電力網の容量を圧迫するにつれて電気料金が高騰し、限られた半導体供給を巡って家電製品同士の競争が激化するにつれて、家電製品の価格も上昇している。 物理的なサプライチェーンは、ソフトウェアのようなスピードで変化に対応できない。半導体工場や発電所の建設には、数十億ドルもの設備投資と数年にわたる期間、そして建設と運営に必要な人材が不可欠である。需要が明確で資金も潤沢にある場合でも、生産能力を一夜にして拡大することはできない。この媒体は、急激な変化に抵抗する。 物理的および経済的な制約によって計算能力が制限される世界において、ソフトウェアアーキテクチャはますます企業戦略の表現としての役割を担うようになっている。それは、顧客の需要と希少で高価なリソースとのバランスを取り、それによって何が拡張可能で、何が停滞し、何が非経済的になるかを決定する。 豊富な資源に基づいて構築されたソフトウェア 数十年にわたり、ソフトウェアはハードウェア性能の着実な向上という環境の中で発展してきた。ムーアの法則のおかげでトランジスタ数は約2年ごとに倍増し、より高速なプロセッサ、より高速なネットワーク、そしてより多くのメモリが実現した。デナードのスケーリングは、トランジスタ密度の向上と駆動電圧の低下によって電力密度を抑制することで、この進歩を持続させることを可能にした。しかし、メーカーがマルチGHz帯に進出し、コア電圧がトランジスタの閾値電圧に近づくにつれて、この傾向は鈍化した。小型化に伴う非効率性が増幅されたことも相まって、電力密度は持続不可能な熱特性に近づいた。 IntelのXeon 6やAMDのEPYC 9005シリーズといった最新のハイエンドデータセンターCPUは、前世代と同じクロック周波数範囲で動作し、性能向上の大部分はシングルコア性能の向上ではなくコア数の増加によるものであり、ソケットあたり200コア近くに達することもある。しかし、キッチンで料理人を増やしても必ずしも夕食の準備が速くなるわけではないように、コア数を増やしてもコンピュータの速度が自動的に向上するわけではない。マルチコアCPUは高度な協調メカニズムを必要とし、これらの新たな協調の課題をソフトウェアに押し上げ、ロック、セマフォ、そして並列コンピューティングに特化した研究分野を生み出した。これらの概念は、ソフトウェアチームに大きな認知負荷をかけ、顧客に機能を提供する方法だけでなく、基盤となるハードウェアの利用率を最大化して高性能なユーザーエクスペリエンスを提供する方法についても考えなければならない。 ハードウェアによってもたらされるこうした複雑さに対処するために、私たちは詳細を隠すための抽象化を作り出す。モバイルアプリ開発者はAPIのことだけを考えればよく、3GPPやLTEといったAPIを支えるセルラー技術を理解する必要がない。ウェブサイトを構築する人は、豊富なアニメーションやグラフィックに集中でき、それらを支えるグラフィックレンダリングパイプラインについて心配する必要はない。ジョン・オースターハウトは著書『ソフトウェア設計の哲学』の中で、この原則を的確に捉えている。つまり、複雑さをカプセル化するシンプルなインターフェースを備えた「深い」モジュールを構築することで認知負荷を軽減し、組織の拡張性を高めることができる。 パブリッククラウドの登場はこの抽象化をさらに推し進めた。物理的なコンピューティングリソースはAPIの背後に移り、サーバーの調達やデータセンターの稼働開始を待つ必要がなくなった。新しいコンピューティングクラスターはクリック一つで利用できる。すべてのハードウェアを調達するために必要な設備投資さえも、従量制の運用費用として抽象化された。クラウドプロバイダーは規模の経済性を活用することで、一見すると豊富なコンピューティングリソースを提供し、摩擦をほとんど感じることなく、数千台のサーバーに垂直方向および水平方向に拡張できる選択肢を与えた。今や、特定のソフトウェアパフォーマンスの課題を、単により多くのコンピューティングリソースとメモリを投じることで、つまり資金調達によって解決するオプションが生まれたのだ。しかし、現代のワークロードの要求の急激な変化により、これらの回避策の一部が限界に達し始めている。 メモリの逼迫 抽象化は問題を分解し、人間が扱いやすくするのに役立つが、根本的なパフォーマンス上の課題を解決するものではない。並列化されたワークロードが増加するにつれて、特にGPUやその他のアクセラレータにおいて顕著に見られるように、課題は並列計算を実行することから、十分なデータを効率的に供給することへと変化した。 1990年代後半にNvidiaによって普及したGPUは、もともと並列化が容易で反復的なグラフィックス処理パイプラインを高速化するために開発された。これらの特殊な技術は並列処理の限界を押し広げてきた。実際、最新のデータセンターGPUは数万個のコアを搭載し、同時に動作して毎秒数千兆回の計算を実行する。追いきれないほどのゼロの数である。同様に、数万人の料理人がいるキッチンでは、全員を忙しくさせるために大量の食材が絶えず流れなければならない。演算コアにデータを流し込むこの能力、しばしばメモリ帯域幅と呼ばれるもの、は容易にボトルネックになり得る。 メモリ技術は長年にわたって進歩してきたが、トランジスタと電力密度の課題によりシングルコアCPUのパフォーマンス向上が大幅に鈍化したのと同様に、メモリ密度の向上も鈍化している。より多くのメモリチップを並列に配置することで帯域幅を拡張できるが、PCB上の物理的なスペースは有限であり、密度と帯域幅は相互に関連する制約となる。高度に並列化されたワークロードは、対応する大量のメモリと、データをやり取りするための帯域幅を必要とする。ほとんどのコンピュータは、半世紀前に誕生して以来、何度か改訂されてきたDRAMと呼ばれるメモリ技術を使用している。最新の改訂版であるDDR5は、チャネルあたり50GB/秒以上を実現しており、DDR4の約2倍の速度である。これらは大きな進歩だが、GPUの性能が向上するにつれて、大規模言語モデルのワークロードはメモリにさらに多くのものを要求するようになった。計算能力が利用可能なメモリ技術を追い越すこの現象は、しばしば「メモリの壁」と呼ばれる。 このメモリの壁を打破するのに役立つ技術の一つが、HBM(高帯域幅メモリ)だ。2010年代半ばに初めて登場したHBMは、メモリチップを垂直に積み重ねることで、より高いビット密度と帯域幅を実現する。各階に専用エレベーターを備えた高層マンションを想像してみよう。これにより、より多くの人が同時に建物に出入りできる。シリコンを積み重ね、これらの「エレベーター」を織り込む複雑な工程のため、HBMは標準的なDRAMと比較して製造工程における歩留まりと効率に課題を抱えている。この課題に加え、ハイパースケーラーからの需要も、今日見られるメモリ不足の一因となっている。GPUサプライチェーンで始まった衝撃波は、メモリにまで及んでいる。 CPUは中心的な役割を担わなくなる 今日のメモリ制約が顕在化するずっと前から、ハードウェアとソフトウェアのアーキテクチャは、スループットの向上と専門化の進展に対応するために再編成されてきた。過去10年間、シングルコアCPUの性能はほぼ停滞している一方で、ネットワーク帯域幅は桁違いに増加した。現代のオフィスネットワークは一般的にギガビットイーサネットで配線されており、ほとんどのデータセンターは現在100GbEをはるかに超える速度で稼働している。わずか2年前の2024年には、800GbEが標準化された。これは、4K映画1本を1秒未満で転送できる十分な帯域幅であり、単一のCPUコアが処理できる速度をはるかに上回る。 GPU間通信の需要の高まりが、高帯域幅化の傾向を加速させている。今日の大規模言語モデルは非常に大きいため、単一のGPUでは実行できない。GPUのクラスタ全体が必要となる。データ量が単一のCPUで効率的に処理できる量を超えて増加するにつれ、最新のシステムはCPUをデータパスから切り離すことで対応してきた。高速トラフィックをCPU経由でルーティングするのではなく、専用のシリコンがデータ転送を直接処理し、CPUはオーケストレーションの役割を担い、操作の設定、ポリシーの適用、例外処理を行う。NVLinkなどの専用インターリンクはこの変化を象徴するものであり、CPUを経由せずにGPU同士を直接接続することで、低ジッター、低遅延、高帯域幅を実現する。 このパターンはGPUに限ったものではない。イーサネットNIC(ネットワークインターフェースカード)は、高度なコンピューティングデバイスへと進化し、VXLANなどの最新のカプセル化プロトコルからRDMA(リモートダイレクトメモリアクセス)などの技術まで、あらゆる処理をCPUからオフロードできるようになった。従来、NICはネットワークパケットをオペレーティングシステムのネットワークスタックに渡し、ネットワークスタックがペイロードを抽出してユーザー空間プロセスに転送して処理を行っていた。しかし今日では、ネットワークトラフィックが高速すぎて、CPUによる効率的な処理が困難になっている。現代のデータセンターの基準からすると比較的平凡な100Gbpsでも、単一のCPUコアでネットワークを飽和させることはほぼ不可能である。ネットワークが高速すぎるため、CPUは利用可能な帯域幅を十分に活用できるほど十分なバイト数を迅速に送信することができない。このCPUボトルネックを回避するため、NICはCPUの関与なしに、RAMから直接データを読み込み、処理し、ネットワーク経由で送信する。 同様に、ストレージの世界では、NVMe SSDはCPUを介してデータを処理する代わりに、PCIeバス上でDMA(ダイレクトメモリアクセス)を利用してシステムメモリとの間でデータを転送する。これは、レストランの荷降ろし場からパントリーまで専用の独立した経路を作り、厨房の料理人が食材を運ぶ手間を省くことと同じようなものだ。ストレージとネットワークの両方におけるこれらの進歩により、NVMe-oF(NVMe-over-Fabrics)などの技術を利用して、ネットワーク経由でリモートのNVMeドライブにほぼローカル接続と同等の速度でアクセスできるようになった。これらの技術は、最新の高度なNICを活用して高帯域幅のデータ転送をCPUからオフロードする。 ワークロードパターンの変化に伴うこうした技術的変化は、ハードウェアだけにとどまらない。大規模な需要ショックはシステムが動作する環境そのものを再構築し、ソフトウェアアーキテクチャはシステムが動作するハードウェアと一緒になって処理を行う。 物理とソフトウェアが出会う場所 データベースは、コンピューティング、メモリ、ストレージ、ネットワークの交点に位置し、これらのダイナミクスを非常に明確に把握できる。データベースは性能の技術的な限界で動作し、レイテンシとスループット、一貫性と可用性など、様々なトレードオフを強いられる。 Cassandraなどの有名なデータベースで採用されているシェアードナッシング(Shared Nothing)アーキテクチャは、リソースの完全な分離を重視し、各ノードが独自のCPU、メモリ、ストレージを備えている。他のノードへの依存関係はないが、ワークロードが一定でない場合、ハードウェアリソースがアイドル状態になる可能性があることを意味する。CPU、メモリ、ストレージの比率は動的に変更できないため、ハードウェア利用率を最大化するには、比較的安定したワークロードパターンが必要となる。イベントログ用のデータベースは、大容量のストレージを必要とするが、読み取りクエリは非常に少ないため、計算要件は低くなる。eコマースストアで使用される製品データベースは、買い物客からの読み取りクエリが多数発生する可能性があるが、ストレージ容量は比較的少なく、販売される製品数に応じてのみ拡張される。言い換えれば、シェアードナッシングアーキテクチャでは、リソース比率のミスマッチがアイドル状態のシリコンへの支払いやパフォーマンスのボトルネックに直結する可能性がある。 対照的に、シェアードストレージアーキテクチャは、データストレージ層をCPUやメモリなどのコンピューティングリソースから分離する。この概念は、GoogleがBigQueryで初期に取り組んだことに端を発している。これにより、CPUとメモリのリソースをストレージ要件とは独立して拡張できるため、特にクラウド環境において、より高いリソース利用率を実現できる。2025年にDatabricksに買収されたデータベース企業Neonは、コンピューティングとストレージの分離を可能にするために、Postgresストレージ層の大部分を再設計した。これにより、データ量とは独立して負荷に応じてリソースをスケールアップおよびスケールダウンできるようになり、常時専用リソースを必要としない一種の「サーバーレス」データベースが実現した。 ElasticsearchやClickHouseのようなシステムもこれと似たシェアードストレージアーキテクチャを採用しており、Amazon S3などのサービスからの安価で耐久性の高いオブジェクトストレージの可用性によって実現されることが多い。これらのストレージサービスは、読み取り後書き込み整合性や条件付き書き込みのようなプリミティブを提供することで、同時読み取りと書き込みを処理できる分散した一貫性のあるストレージを提供するという難問を解決に貢献する。Apache IcebergやDelta LakeといったオープンなLakehouseフォーマットは、この変化を象徴するものであり、コモディティ化された共有ストレージの上に、より高レベルのデータセマンティクスが重ねられている。 ベクトル埋め込みを利用したAI関連サービスの需要が急増したことで、ベクトル検索を中心とした新しいデータベース開発が急増し、この分離が主流になりつつある。現在の最先端のベクトル検索アルゴリズムには、複雑なチューニングなしで動的な挿入とリコール性能のバランスが取れていることから多くのデータベースで採用されているHNSW(階層型ナビゲーション可能なスモールワールド)のバリエーションが含まれている。しかし、これらのグラフベースのアルゴリズムは、メモリ内のデータ構造を走査する必要があるため、メモリをかなり消費し、データベースの計算コストを増大させる。ストレージ容量とは独立して計算リソースを動的にスケールアップおよびスケールダウンできるアーキテクチャを採用することで、データベースは限られたハードウェアリソースの利用率を高めることができる。 ワークロードパターンが変化し、ハードウェアが進化するにつれて、データベースアーキテクチャは、そのアーキテクチャに内在するトレードオフを浮き彫りにせざるを得なくなった。今日の状況では、コンピューティング、メモリ、ストレージ、ネットワークという4つの柱をどれだけ密接に結合するかという決定は、パフォーマンス特性だけでなく、ハードウェアの利用率、コスト、スケーラビリティにも影響する。データベースはシステムの物理的な限界に近い位置にあるが、その根底にあるダイナミクスはデータベース特有のものではない。ソフトウェアが強い制約の下で動作する場合、アーキテクチャの選択は技術的な成果だけでなく、経済的な実現可能性にも影響を与え始める。ここに明確な答えはない。どのアーキテクチャも、どの制約が最も強く影響するかという賭けを内包している。それを誤ると、もはや存在しない世界に合わせて最適化したことになる。 圧力下における抽象化 抽象化は無料ではない。それらが生み出された環境の前提条件に従って価格付けられている。数十年にわたり、ハードウェアの普及が進んだことで、そのコストは容易に無視されてきた。しかし、物理的な制約が強まるにつれて、抽象化に内在する隠れたコストが再び明らかになりつつある。 抽象化の中には、実質的にコストがかからないものもある。例えば、スマートポインタやジェネリクスなどが挙げられる。これらのメカニズムは、実行時のパフォーマンスを損なうことなく、開発者の認知負荷を軽減する。一方、コストがかかるものもある。ガベージコレクションは、実行時に一時停止が発生する代わりに、開発者が変数のライフタイムを管理する必要をなくす。仮想関数は、パフォーマンスの低下と引き換えに、実行時の動的なディスパッチを可能にする。組み込みシステムや高性能コンピューティングでは、C、C++、Rustといった言語が広く使われている。これらの言語は、開発の複雑さや認知負荷を犠牲にして、実行時の動作を制御可能にする。これは、すべてのバイトとすべてのサイクルに目に見えるコストがかかる状況では、合理的な選択と言える。 現代において最も重要なソフトウェアの一つであるLinuxカーネルは、ユーザー空間のプログラムがハードウェアの詳細を気にしなくて済むようにしてきた。そのシステムコールはハードドライブやNICに関する詳細を抽象化し、メモリ、ファイル、ネットワークのようなプリミティブを扱うための安定したインターフェースを公開する。カーネルはドライバーを通じてハードウェアを直接管理・通信し、最終的にそれらを抽象化された汎用リソースとしてユーザー空間に提供する。これらは抽象化だけでなく、関心の分離も提供する——カーネルはハードウェアリソースが適切に管理・保護されることを保証し、ユーザー空間はユースケースにより集中する。 ハードウェアの限界で動作する場合、これらの抽象化のパフォーマンスオーバーヘッドは、利点を上回り始める可能性がある。ネットワーキングとストレージ技術がCPU性能に対して大幅に進歩するにつれ、増大する需要に追いつくソフトウェアの能力が重要になる。メモリのコピーやコンテキストスイッチは、毎秒数百万回繰り返されると、その負荷が蓄積される。LLMベースのサービスに対する現在の需要は、こうしたプレッシャーを大幅に加速させている。その衝撃波は、ハードウェアの不均一な進歩によって既に負荷がかかっていた抽象化全体に波及し、もはや無視できないコストを露呈させている。 例えば、数十ギガバイトものリアルタイム高解像度ビデオをネットワーク経由でSSD搭載のリモートストレージデバイスに送信するアプリケーションを考えてみよう。データは、ビデオ送信アプリケーションのユーザー空間メモリからカーネル、NIC、光ファイバーケーブルを経由して受信側のNIC、受信側のカーネル、ユーザー空間、そして再びカーネルへとコピーされ、最後にSSDに書き込まれる。各ステップでデータは再配置され、時には仮想的なデジタルエンベロープにカプセル化され、受信側で取り出される。コンピュータからより多くのパフォーマンスを求めるにつれ、この仮想的な書類のやり取りのオーバーヘッドが明らかになる。 このシャッフルは、カーネルとユーザー空間の抽象化レイヤーの結果だ。データはカーネルを介して出入りする。2010年代後半、データセンターのネットワークは100Gbpsを超え、この抽象化を回避する「近道」を見つけたいという要望が高まった。DPDK(Data Plane Development Kit)は、カーネルの抽象化を完全にバイパスし、カーネルを介さずにユーザー空間アプリケーションがNICと直接通信できるようにする業界標準フレームワークである。ネットワークスタックの責任をアプリケーションに移し、カーネルのセキュリティ保証と多重化機能の一部を犠牲にする代わりに、処理速度を向上させる。メモリコピーとコンテキストスイッチを削減することで、DPDKは、高帯域幅でパフォーマンスを重視するアプリケーションが、カーネルを経由する場合と比較して2~3倍の効率を実現できるようにしている。DPDKにはトレードオフがあり、万能の解決策ではないが、機会費用の方程式が変化するにつれ、業界がこれらの抽象化の境界を再構築するために動いてきた多くの方法の一つだ。 環境の変化、技術の進歩、ワークロードの変化に伴い、抽象化の概念を再検討する必要が生じている。コスト、パフォーマンス、経済性に関する暗黙の前提は、プレッシャーがかかった時に明確になる。これらのマクロな動きに気づかないか、適応を拒むことは、隠れた負債の一形態を積み重ねる——システムとプロダクトは健全に見えるが、負荷がかかると破綻してしまうのである。 ハードウェアへの意識 2025年以降にリリースされたデータセンター向けGPUには、数年前には存在しなかった4ビットおよび8ビット浮動小数点表現であるFP4とFP8での動作に特化したモジュールがシリコンに組み込まれている。これらの超低解像度数値表現は、LLMのメモリ効率と演算効率を向上させるために開発されたものであり
はじめに カミナシでエンジニアをしている Shimmy です。今は新規プロダクト開発をしています。 0→1の開発設計では「コードベースの持続可能性」と「短期的なデリバリー速度」の両方が重要です。そのバランスを取りながら、AIの力を最大限活かせるアーキテクチャを考えてきました。 その過程で分かった設計原則というのは、AIを活用する前から変わらないものでした。 この記事では、AIの力を引き出す設計と、その設計を決定論的に守らせる仕組みついて話します。 補足: TanStack Start(フルスタックReactフレームワーク)を利用しており、フロントエンドとバックエンドが同一コードベースにあります。 AIの力を引き出す設計の3つの条件 自分のプロダクトの設計原則は次の3つです。 関心の分離: 関心事ごとにファイルをまとめる。AIのコンテキストに載せやすく、並列開発でもコンフリクトしにくい 価値の高いテスト: テストは数より質。振る舞い(Input→Output)を検証する出力値ベーステストと純粋関数の組み合わせで、モック不要でリファクタリングに強いテストが書ける 依存方向の決定: 層ごとに「何に依存してよいか」が決まっていれば、AIは迷わない。さらに静的解析で強制できる 上記の条件は、AIのために特別に取り入れた考えではありません。今まで良い設計とされていたものが、結果的にAIとの協働でさらに力を発揮するようになりました。 ここからは、各条件を深掘りして、採用した設計パターンと具体的な構成を見ていきます。 関心の分離 AIとの相性 関連ファイルが1つのディレクトリに集約されていると、AIのコンテキストに載せやすくなります。「このディレクトリを読んで、こう修正して」で済みます。散らばっていると、AIは修正箇所を探し回ってコンテキストウィンドウを無駄に消費します。 並列開発でもコンフリクトしにくいです。git worktree で複数のAIエージェントを同時に走らせても、関心事が分かれていれば触るファイルが重ならず、安全にマージできます。 Feature-Firstの構成 結合は悪ではありません。結合の強さと距離のバランスを取ることが大切です。結合が強いなら距離を短くし、距離が長いなら結合を弱くする。この考え方を Feature-First の構成に落とし込んでいます。 features/ ├── 関心事A/ │ ├── domain/ # Functional Core: 純粋関数のみ │ ├── infrastructure/ # Imperative Shell: DBアクセスなどI/O │ ├── server/ # API層: domainとinfrastructureを組み立てるエンドポイント │ ├── components/ # 複数ページで再利用するUI │ ├── hooks/ # カスタムフック │ └── index.ts # Public API ├── 関心事B/ │ ├── domain/ │ ├── infrastructure/ │ ├── server/ │ └── index.ts └── ... Feature内部 → 高凝集: 同じ関心事に関するコード(ビジネスロジック、DB操作、APIエンドポイント)が1つのディレクトリにまとまっています。統合強度は高いが、距離が短いので問題にならないです。 Feature間 → 疎結合: 各featureは index.ts を通じてPublic APIだけを公開し、domain/やinfrastructure/の内部構造は隠蔽する。外部からは index.ts 経由でのみアクセスするので、統合強度はコントラクト結合に留まる。距離が長い分、結合を最小限に抑えています。 domain、infrastructure、serverがそれぞれ1つのFeature内にあります。関心事Aに関するコードはすべてこのディレクトリに集約されているので、AIに「この機能を修正して」とfeatureを渡せば、そのディレクトリで完結します。 参考: 『ソフトウェア設計の結合バランス』(Vlad Khononov) Public API境界 各featureの index.ts は、外部に公開するものだけをexportします。 // features/xxx/index.ts // 外部から使う必要があるものだけを公開 export { calculateSomething, type Quantity } from "./domain/calculations"; export { useSaveRecord } from "./hooks/use-save-record"; export { recordsQueryOptions } from "./queries"; // 外部から使わないものは公開しない // domain/の内部ヘルパー、infrastructure/のDB操作詳細 など 実装の詳細は外部に公開していません。外部からはこの index.ts 経由でのみアクセスできます。featureの内部をどれだけリファクタリングしても、このPublic APIのシグネチャが変わらなければ外部のコードは影響を受けません。 featureを横断するケース Feature-Firstで分離したときに、最も考えるべきなのは複数のfeatureにまたがるケースについてです。横断が必要なケースは2つのパターンで対応しています。 パターン1: shared/ — 共通のビジネスロジックが必要な場合 複数のfeatureが使う計算ロジックは shared/lib/ に純粋関数として切り出します。 src/ ├── features/ │ ├── 関心事A/ │ ├── 関心事B/ └── shared/ └── lib/date.ts # 複数featureが使う共通の純粋関数 shared/ は features/ に依存しません。依存の方向は常に features/ → shared/ の一方向です。あくまで共通の純粋関数を提供するだけの層であり、shared/ が特定のfeatureの内部を知ることはありません。 パターン2: routes/ - 1つのページで複数featureが必要な場合 複数のfeatureのデータを組み合わせて1つのページを作るケースはどうするのか。ここで routes/ 層が登場します。TanStack Startの routes/ は、サーバーサイドでのデータ取得とUI描画の両方を1つのページとしてまとめる層です。各ページのコンポーネントやページ固有のロジックを持ちます。 (Next.jsの app/ ディレクトリでも同様の構成が取れるはずです。) src/ ├── features/ │ ├── 関心事A/ │ │ └── index.ts │ ├── 関心事B/ │ │ └── index.ts └── routes/ └── xxx/ └── $id/ ├── index.tsx # ページコンポーネント ├── -lib/ # このページのロジック ├── -components/ # このページのUI └── -hooks/ # このページのフック 先ほど話したように、各featureは index.ts を通じてPublic APIだけを公開し、互いに直接依存しません。 routes層でそれらを組み合わせます。ページコンポーネントが各featureからデータを取得し、組み合わせてUIを描画します。 // routes/xxx/$id/index.tsx // 各featureが公開するデータ取得関数を使って並行取得 const [recordsA, recordsB, recordsC] = await Promise.all([ fetchFeatureA(id, date), fetchFeatureB(id, date), fetchFeatureC(id), ]); // 複数featureのデータを組み合わせてUIを描画 const rows = buildRowData(recordsA, recordsB, recordsC); return <DataGrid rows={rows} ... />; 各featureは互いの存在を知りません。どのfeatureを組み合わせるかを決めるのはroutes層(ページ)の責務です。この構造により、Feature-Firstの疎結合を維持したまま、横断的なページを柔軟に構築できています。 価値の高いテスト 価値の高い単体テストとは ここでは単体テストに絞って話します。テストは数より質が重要です。 「単体テストの考え方/使い方」では価値の高い単体テストの条件として4つの柱が挙げられています。 退行(リグレッション)に対する保護 リファクタリングへの耐性 迅速なフィードバック 保守しやすさ 退行保護、リファクタリング耐性、迅速なフィードバックの3つはトレードオフの関係にあり、同時に最大化できません。ただしリファクタリング耐性は「あるかないか」の二値なので、まずこれを確保した上で残りのバランスを取ります。リファクタリング耐性がないテスト(偽陽性が多いテスト)はテストへの信頼を損ない、やがて無視されるようになるからです。 参考: 『単体テストの考え方/使い方』(Vladimir Khorikov) 出力値ベーステスト リファクタリング耐性を確保するために関数の内部実装ではなく振る舞い(Input→Output)を検証するテストを行っています。これが出力値ベーステストです。関数にInputを入れて、返ってきたOutputを検証する。テストが検証するのは「関数が内部でどう動いているか」ではなく「どんな入力に対してどんな出力を返すか」です。内部実装に依存しないので、振る舞いが変わらない限りリファクタリングしてもテストは通り続けます。 domain層の純粋関数(補足: コードは抽象/単純化しています // features/xxx/domain/calculations.ts /** 進捗率を計算する純粋関数 */ const progressRate = ( actualTotal: number, targetQuantity: number, ): ProgressRate | null => { if (targetQuantity === 0) return parseProgressRate(0); const ratio = actualTotal / targetQuantity; const percentage = roundToOneDecimal(ratio * 100); return parseProgressRate(percentage); }; この関数に対する出力値ベーステスト: describe("progressRate", () => { it("実績と目標から進捗率を返す", () => { expect(progressRate(75, 100)).toBe(75.0); }); it("100%を超える場合も正しく計算する", () => { expect(progressRate(120, 100)).toBe(120.0); }); it("目標が0のとき0を返す", () => { expect(progressRate(50, 0)).toBe(0); }); <span class="synI
こんにちは。AI・機械学習チームの田中(@yusuke14tanaka)です。 この記事はAI・機械学習チームブログリレーの13日目の記事です。12日目は鴨田さんによる「SAM3とマトリックス・コードで作る"cat matrix"」でした。 www.m3tech.blog 2026年1月にエムスリーに入社し、気がつけば3か月が経ちました。前職では、視覚障がい者向け歩行支援デバイス「あしらせ」を開発する株式会社Ashiraseで共同創業者兼取締役CTOを務めていました。 前職あしらせのTシャツを着た筆者 今回は、スタートアップのCTOから、エムスリーのAI・機械学習チームに転職した自分が、入社前に感じていた不安と、3か月経った今の正直な感想をお伝えしたいと思います。 同じような境遇で転職を迷っている方、特にCTO経験者の方に届けば嬉しいです。 前職でやっていたこと なぜエムスリーにしたのか 入社前に感じていた5つの不安 1. 歯車になるのでは? 2. 裁量がなくなるのでは? 3. 我流のスキルでついていけるか? 4. 畑違いの領域でやっていけるか? 5. 東証プライム上場企業は堅いのでは? 3か月経って、実際どうだったか 歯車感 → ほとんど感じていない 裁量 → 全く困っていない 我流スキル → 「わからない」への耐性が活きた 畑違い → 意外なところで繋がった プライム上場企業の堅さ → 想像よりずっと柔らかい Claude Codeという最強のキャッチアップ相棒 エムスリーの学びの文化 CTO経験が活きていること CTOはあくまで「役割」の一つ CTO経験者の方へ We are hiring! エンジニア採用ページはこちら カジュアル面談もお気軽にどうぞ インターンも常時募集しています 前職でやっていたこと 「あしらせ」は、靴に装着する振動デバイスとスマートフォンアプリを組み合わせた、視覚障がい者向けの歩行支援サービスです。共同創業者兼取締役CTOとして、組み込みFW(C / FreeRTOS)・iOSアプリ(Swift)・バックエンドシステム(Python / Flask)の開発を一貫してリードしていました。 あしらせデバイス(出典: ashirase.com) ゼロからプロダクトを立ち上げ、大手家電量販店をはじめとする代理店での販売まで漕ぎ着けることができました。CES 2023 Innovation Awardや、東京都ベンチャー技術大賞 優秀賞、J-Startup 2023 認定もいただいています。 技術的には組み込みFW開発がメインで、あしらせデバイスの姿勢推定アルゴリズムや、BLE(Bluetooth Low Energy)を使ったOTA(Over the Air)によるFWアップデートの仕組みなどをゼロから作っていました。カルマンフィルタや粒子フィルタを用いた歩行者デッドレコニング(推測航法)にも取り組んでおり、この制御工学の経験が、後述するエムスリーでの仕事に意外な形で繋がることになります。 なお、本記事の執筆や画像の掲載について、Ashirase代表に相談したところ快くOKをいただきました。 なぜエムスリーにしたのか 共同創業者兼取締役CTOとして5年半走り続ける中で、持病もあり働き方を見直す必要が出てきました。次のキャリアを考えたとき、エムスリーのAI・機械学習チームでは、ソフトウェア開発だけでなく、機械学習モデルの構築にも携われると聞いたのが決め手でした。 また、優秀なエンジニアが多い環境で、自分の技術力を伸ばしたかったというのもあります。1人目のエンジニアとしてゼロから開発を始め、我流で進めてきた部分がどうしても多かった。コーチのような存在もいない。メガベンチャーのエンジニアのレベルを肌で感じながら、自分の技術力をもっと高めていきたいと思っていました。 入社前に感じていた5つの不安 CTO経験者がメガベンチャーに転職するとき、特有の不安があります。自分の場合は、こんなことを考えていました。 1. 歯車になるのでは? スタートアップのCTOは、プロダクトの全体像を見渡しながら仕事をします。メガベンチャーに入ったら、大きな組織の一部品として、狭い領域だけを任されるのではないか。そんな不安がありました。 2. 裁量がなくなるのでは? 技術選定も設計判断も、自分で決めて動けるのがスタートアップの醍醐味です。メガベンチャーでは、承認フローや会議を経ないと何も進まないのではないか、と思っていました。 3. 我流のスキルでついていけるか? 正直に言うと、これが一番大きな不安でした。スタートアップでは体系的にスキルを学ぶ機会が少なく、常に我流で模索しながら開発していました。メガベンチャーの優秀なエンジニアの中でちゃんと成果を出せるのか、かなり不安でした。 4. 畑違いの領域でやっていけるか? 組み込み・モバイル畑からWeb・MLの世界へ。Python、Go、GCP、Kubernetes、BigQuery——技術スタックが根本的に違う領域への転身です。キャッチアップできるのか、戦力になれるのか、という不安がありました。 5. 東証プライム上場企業は堅いのでは? スタートアップはカジュアルな文化が一般的です。プライム上場企業に入って、堅い雰囲気に馴染めるのだろうか、という漠然とした不安もありました。 3か月経って、実際どうだったか 歯車感 → ほとんど感じていない AI・機械学習チームでは、プロジェクトをほぼ丸ごと任される文化があります。自分でプロジェクトの全体像を把握しながら動けるので、歯車感はほとんど感じていません。 むしろ、チームを越えた動きもしやすい環境です。BigQueryにどういったデータがあるかが探しにくい状態だったので、Claude Codeのプラグインや独自ツールを活用して、全社的にBigQueryのデータを検索しやすくする仕組みを他チームに提案しに行ったりもしました。こうした動きがしやすい関係性があるのは、とてもありがたいです。 裁量 → 全く困っていない 裁量がなくて困った、という経験は3か月間で一度もありません。現場での意思決定が尊重される文化があり、メンバーであっても自分の判断で動ける幅が広いと感じています。 我流スキル → 「わからない」への耐性が活きた 最初はかなり苦労しました。打ち合わせ中に何を言っているのか理解できないことも正直多かったです。BigQueryも、GCPも、Goも、触ったことがない。組み込み系ではWindowsがメインだったので、MacがメインPCになったこと自体が初めてで、そもそもパソコンの使い方みたいなところからつまずいたりもしていました。新人時代に戻ったような感覚でした。 ただ、スタートアップで5年半やってきたおかげで、「わからない」ことに対する耐性はかなりついていました。CTOをやっていたら、知らないことに出会うのなんて日常茶飯事です。そこでへこたれている暇はなかったし、その感覚が今も活きています。 畑違い → 意外なところで繋がった これが一番伝えたい話です。 現在、コンテンツレコメンドの最適化を担当しているのですが、既存のコンテンツ表示の抑制ロジックがステップ関数のような離散的な制御になっていました。ここを連続的な制御に変える改善を行い、全ユーザーに展開できました。 具体的には、コンテンツごとの興味持続時間を考慮するモデルへと改善し、医師の皆様により"今の興味"に近い情報を届けられるようになりました。入社3か月で手応えのある成果を出せたのは、自分にとっても大きな自信になりました。 この改善のアイデアは、あしらせ時代にカルマンフィルタや制御モデルを扱っていた経験から、ごく自然に出てきたものです。離散的な制御は現実に即さないことが多く、制御工学的には避けられる手法です。その感覚があったからこそ、改善の方向性がすぐに見えました。 また、banditアルゴリズムの理解にも、前職の知識が役立ちました。banditの内部でもベイズ更新が使われていますが、カルマンフィルタで散々ベイズ更新と格闘していたおかげで、内部状態が逐次的に更新されていく感覚がすんなり理解できました。「基礎からわかる時系列分析」という書籍も併せて読み、制御工学と機械学習の接点をより深く理解できました。 畑違いの経験は、無駄にならない。 むしろ、異なる領域の知識があるからこそ出せる価値がある。これは3か月で得た一番大きな実感です。 プライム上場企業の堅さ → 想像よりずっと柔らかい これは一番ギャップが大きかったかもしれません。想像していたよりもずっと柔らかい。エンジニアリングチームは良い意味で柔らかく、コミュニケーションも取りやすいです。 特にエンジニア気質というか、ちょっとコミュニケーションが難しい人——いわゆる「聞きづらい人」が全くいない。これは本当に驚きました。チーム内はもちろん、チーム間でもとても協力的で、質問もしやすく、キャッチアップもしやすい。 Claude Codeという最強のキャッチアップ相棒 キャッチアップの話をもう少し掘り下げます。 エムスリーではClaude Codeが使い放題です。これが、畑違いの領域からのキャッチアップに本当に助かりました。 具体的には次のような使い方をしていました。 BigQueryのクエリを書くときに聞く Go言語の書き方を教えてもらう 論文を読むときに要約・解説させる M3内で開発・管理しているOSSパッケージgokartの使い方や実装を聞く さらに、AI・機械学習チームのメンバーが作成したClaude Codeのスキルやナレッジが蓄積されており、チームの暗黙知にもアクセスしやすい環境が整っていました。 さらに、次のテックブログ記事にもあるように、 www.m3tech.blog エムスリーではほぼ全員のエンジニアがClaude Codeを日常的に使っており、AIレビューやスキルの共有がチーム横断で進んでいます。こういったナマの知識が社内に蓄積されていて、それを吸収できるのも大きいです。 おかげさまで、すっかりClaude Codeのヘビーユーザーです。CTOをやっていた頃は、わからないことがあっても自分で調べるしかなかった。今は、Claudeに聞けるし、チームメンバーにも聞ける。この差は本当に大きいです。 エムスリーの学びの文化 もう一つ、入社して驚いたのが学びの文化です。 Googleのデータベースに関する輪読会 論文輪読会 技術書の輪読会 自分の技術を発表するテックトーク これらが毎週のように開催されています。しかも形骸化しておらず、ちゃんと身になっている。 自分の場合、Googleのデータベース輪読会に参加したとき、最初は正直何を言っているのか全然わからなかった。ですが、自分で復習し、2か月後には自分でも発表しました。まだ完全に理解できているとは言えませんが、BigQueryやデータベースに対する感覚値をつかむことができたのは、この輪読会のおかげです。 こういった場で否定する人が一切いないのも特徴です。本当に心地よく発表を聞けるし、発表することができる。スタートアップでは、こうした組織的な学びの場を作る余裕がなかったので、これはエムスリーならではの価値だと思います。 CTO経験が活きていること CTOをやっていた頃は、とにかく会社の成長が最も大切だと考えていましたし、そのために必要な仕事をレバレッジが効く順に実施していました。最もやばいところに常に自分が入り込む。 この考え方は、メガベンチャーであっても変わりません。 自分にとって都合が良いことではなく、会社全体にとってベストなことを選ぶ。 この判断軸はCTOをやる中で身についたものですし、エムスリーの「しゃ(社長意識)」とも重なる部分が大きいです。 CTO経験者であれば、この社風は自然にフィットするのではないかと思います。 CTOはあくまで「役割」の一つ 転職を考えたとき、「CTOからメンバーに戻ることに抵抗はないのか」と聞かれることがあります。 正直に言うと、全くありません。 CTOはあくまで役割の一つでしかない。プライドとかそういう話ではなくて、その役割が必要な場面で、自分がその役割を担う。それだけのことです。エムスリーではグループ会社でCTOを務める道もありますし、役職に固執する必要は全くないと思っています。 むしろ、CTO経験があるからこそメンバーとしても強い。全体を俯瞰する力、ステークホルダー全体の最適化を考える癖、未知の領域に飛び込むキャッチアップ力。これらは役職に関係なく活きるスキルです。 CTO経験者の方へ 最後に、スタートアップでCTOをやっていて、メガベンチャーへの転職を迷っている方へ。 エムスリーは、CTO経験者にとって良い環境だと思います。理由を3つ挙げます。 ビジネスを重要視するカルチャー。会社全体のメリット・デメリットを考えて動いてきた経営者やCTOからすると、すごく馴染みやすい環境です。 技術力が高く、学び続ける文化がある。テックトークや論文輪読会が当たり前にある。技術に対して熱心な人が多く、自分もまだまだ成長できると感じられる環境です。 現場の決定権が大きい。CTOの裁量からメンバーになっても、裁量がなくなったとは感じていません。自分の判断で動ける幅が広いです。 不安に感じている方がいれば、それは杞憂だとお伝
データ基盤チームでソフトウェアエンジニアをしている橋口 (@matsudo840) です。 技術書典20が2026/04/12(日)に開催されます(オンライン開催は4/11-4/26)。 記念すべき20回目の技術書典ということで、エムスリーのエンジニア有志を募り、新刊『エムスリーテックブック9』を携えてサークル参加します! エムスリーではギークでスマートなカルチャーを大切にしていますが、その中でも技術を楽しむギークさが際立つ1冊となっております。 オンラインでは4/11から、こちらからご購入いただけます!148ページで1000円と大変お得な内容となっています。 techbookfest.org この記事では皆さんに新刊を手に取っていただけるように、各章の著者からおすすめポイントを紹介します。 技術書典とは 第1章 等間隔に線を引くだけで生成するペンローズタイリング 第2章 OCamlのはじめかた 第3章 Rustで作るPython型チェッカー 第4章 goroutineを作ってみる。Rustで 第5章 Rustで作るギター用デジタルエフェクター 第6章 つくって学ぶ JSON Web Token 第7章 AIは伝統パズル「箱入り娘」を解けるのか? 非エンジニアがGeminiと挑んだ8分間の奇跡 第8章 AIを活用して技術書を読む 第9章 老人Z80 — ESP32によるZ80 CPU介護ボード製作記 まとめ 技術書典とは 技術書典は技術同人の集まりとして長年続くイベントです。 運営の皆様のご尽力と、多くの著者・読者の皆様が共に作り上げてきた、ギークの祭典。 毎年数千人が集まり、何百ものサークルが技術への愛と情熱を持ち寄る場には、読み切れないほど面白い本が並びます。 今回は記念すべき第20回。私たちも第6回から参加させていただいている1サークルとして、この節目を一緒に盛り上げられることを大変嬉しく思っています。 www.m3tech.blog エムスリー執筆部もサークルとして盛り上げてまいります!それでは新刊の紹介をどうぞ! 第1章 等間隔に線を引くだけで生成するペンローズタイリング 【著者のコメント】 前回に引き続き、数学的タイリングについて書かせていただきました。等間隔に線を引くだけでペンローズタイリングを生成する方法とは? 筆者が最近得た結果もチラ見せしていますので、ぜひご覧ください! 第2章 OCamlのはじめかた 【著者のコメント】 今熱い(著者調べ)言語OCamlをはじめてみたい方にもそうでない方にもぜひ読んでいただきたい入門です。 課題としてトランプゲームのブラックジャックを設定し、極力実際の利用にも耐えるような構成を目指しました。 これを読めばOCamlで実際のアプリを作成できるようになるはずです。 第3章 Rustで作るPython型チェッカー 【著者のコメント】 AI・機械学習チームの北川(@kitagry)です。 本章はmypyの歴史からty/pyreflyまでの変遷とRustでミニPython型チェッカーを実装するところまで書いています。 自分でリテラル推論からTypeVar単一化までを実装します。 Pythonをセキュアに書きたい人からRustで何かを自作したい人までおすすめの章です! 第4章 goroutineを作ってみる。Rustで 【著者のコメント】 エンジニアリンググループ ゼネラルマネージャーの横本(@yokomotod)です。 「軽量」「何万個も作れる」「並行処理が簡単に書ける」…そんなgoroutineの裏側はどうなっているのか。 今回は過去にブログ公開したgoroutineランタイム自作をさらに発展させ、ネットワークI/O待ちなどにも対応して書籍化してみました。ブログを読んでいただいた方も是非手に取ってみて下さい! 第5章 Rustで作るギター用デジタルエフェクター 【著者のコメント】 デジスマチームの小島(@jiko_21)です。 本章はギター用デジタルエフェクタをRustで実装する方法について解説します。 オーバードライブ、ディレイ、エコーなど、それぞれの音響効果がどのようなものか、モデル化したうえで実装していきます。 ギターを弾いている人やエフェクターを使って音作りを楽しんでいる人におすすめの章です。 第6章 つくって学ぶ JSON Web Token 【著者のコメント】 リサーチプロダクトチームの佐藤(@riku929hr)です。 本章は、認証で用いられることの多いJWT(JSON Web Token)を自作し、その仕組みについて楽しく理解するものとなっています。 認証やJWTに興味のある人に特におすすめの章です! 第7章 AIは伝統パズル「箱入り娘」を解けるのか? 非エンジニアがGeminiと挑んだ8分間の奇跡 【著者のコメント】 マーケティング部門(非エンジニア)からの参加です。今回、AIにパズル「箱入り娘」を解くプログラムを作らせてみました。AIは教科書通りのロジックを組むことはできましたが、肝心のパズルは解けず……。しかし、人間がたった一言「ヒント」を与えたところ、見事に正解へと辿り着きました。 一体どんな言葉がAIを動かしたのか? ぜひ本編でその裏側をお読みいただけると幸いです。 第8章 AIを活用して技術書を読む 【著者のコメント】 分厚くて難しい技術書を読むときにAIと一緒に納得できるまで読み進めるために取り組んでいることを書きました。プロンプト付きです。 第9章 老人Z80 — ESP32によるZ80 CPU介護ボード製作記 【著者のコメント】 本章では、ESP32-S3のGPIOをフル活用し、Z80のアドレスバスを監視しながらメモリのフリをしてデータを流し込む、ソフトウェアによるエミュレーションの実装方法を解説します。 ジャンク屋でZ80 CPUを見つけて勢いで買ったはいいものの、動かすための回路を組むのは正直しんどい。そんな悩みへの解決策が「ESP32による介護」です。 まとめ 今週末から始まる技術書典、サンシャインシティのオフライン開催に参加される方は、ぜひエムスリーのスペース「く07」まで遊びに来てください! 技術が大好きな執筆メンバーがお待ちしております。ワイワイお話しましょう〜。 新刊・既刊を合わせ、技術書典オンラインマーケットでも頒布しております。
はじめに さくらのナレッジ編集部の法林です。 3月18日(水)に、オンラインセミナー「国産GPUクラウドで実現する次世代AIモデル開発 x ブロックチェーン連携 ― 事例企業が語る基盤の選定・構築・運用のリアル」が開催さ […]
はじめに タイミー QA Enabling Gの矢尻、岸、松田です。 ソフトウェアテストに関する国内最大級のカンファレンス「JaSST (Japan Symposium on Software Testing) ‘26 Tokyo」が、2026年03月20日に開催されました。 タイミーには、世界中で開催されるすべての技術カンファレンスに参加できる「KaigiPass」という制度があり、この制度を利用してオフラインで参加しました。 jasst.jp 今年の会場は東京ビッグサイトでした。 本レポートでは、印象に残ったセッションの内容を中心にお伝えします。 JaSST Tokyo 2026 参加レポート — AI駆動QA時代の到来とタイミーの現在地 タイミーの矢尻です。 今回のJaSSTは、前回にもから増してAI関連セッションが圧倒的に多い回でした。基調講演からクロージングまで、ほぼすべてのトラックでAIが議論の軸となり、AI駆動開発における品質保証(QA for AI-Driven Development = QA4AIDD)が業界全体のメインテーマに昇格した印象です。 タイミーでは社内のQAガイドライン「QA Handbook」を通じてAI時代のQA戦略を先行して整備してきました。本レポートでは、セッション横断で見えた 3つの業界トレンド と、タイミーの取り組みとのフィットギャップを総論的にまとめます。 セッション横断で見えた3つのトレンド 今回、私が視聴したのは以下の6セッションです。 AIがテストチームに加わるとき- 期待、落とし穴、そしてソフトウェア品質の未来 – スペシャルトークセッション『AIと品質保証のこれまでとこれから』 AIがQAエンジニアの仕事を奪うのか? 生成AI時代、ソフトウェア品質保証のロールと組織はどこへ向かうのか? 品質を経営にどう語るか 人と関わるロボットの研究開発 –ロボットにおける人間らしさの重要性 – 横断すると、業界の議論は大きく 3つのテーマ に収束していました。 1. AIへの「プロセス要求」と人間の監督 複数セッションで共通して語られたのは、AIに「何を作るか」だけでなく「どう作るか」を明示する必要性です。 ベリサーブ様のセッションでは「ハーネスエンジニアリング」として、AIにプロセス要求を与えアクティビティログでオーディットするアプローチが紹介されました。SIG SQAの井芹様は「HITL(Human-in-the-Loop)」と「Everything as Code」をキーワードに、人が適切なポイントで介在するプロセス設計の重要性を強調。安野様のセッションでは、AIが一次スクリーニング(リコール向上)を担い、人間がコンテキストを踏まえた精査(プレシジョン向上)を行う「2層スクリーニング」モデルが示されました。 基調講演のGayathri Mohan様も、AIは「ベビーシッター」のように常に監視と調整が必要な存在であると指摘しており、「AIに任せきりにしない品質保証のプロセス設計」が業界の最大関心事になっていることを強く感じました。 2. リリース後の継続的品質バリデーション もう一つ、独立した複数セッションで繰り返し言及されたのが、プロダクション環境での継続的モニタリングです。 ベリサーブ様のセッションでは「フライホイール型品質保証」として、リリース前で完結せず本番環境で継続的にスコアを監視→フィードバック→再リリースを回す「運用型QA」が提唱されました。Adobe様の小島様もAIエージェント評価において、事前テストだけでは限界があり実データでの課題探索が不可欠だと強調。基調講演でも、非決定論的なAIの出力に対して確率論的・メトリクスベースの評価が必要だと語られました。 リリース後の品質バリデーションは、もはや「やるかどうか」ではなく「いつ・どう始めるか」のフェーズに入っていると感じます。 3. 品質を経営の言葉で語る 3つ目のトレンドは、品質と経営の対話です。 kyon_mm様らのセッションでは、品質を「技術の詳細を説明する場」から「事業の優先順位を決める場」に移すための翻訳プロトコルとして、バランススコアカード(BSC)、Cost of Quality(COQ)、NIST AIリスクマネジメントフレームワークの3つが示されました。ベリサーブ様のセッションでも「QAエンジニアは経営の意思決定に必要な情報を提供する立場に移行する」という見通しが語られ、SIG SQAの伊藤様も「事業戦略と連携した品質戦略策定」を高度化すべきスキルとして挙げていました。 作業をAIに委ね、QAエンジニアの役割がより上流・経営(ビジネス)寄りにシフトしていくという方向性は、セッションを跨いだ一貫したメッセージでした。 タイミーQA Handbookとのフィットギャップ タイミーでは「QA Handbook」として、3つの戦略(Business Reliability / Standardized Process / AI-DLC & QaC)を柱にQA活動を体系化しています。上記の業界トレンドと照合した結果を整理します。 ✅ フィットしている領域 業界潮流 タイミーの対応 評価 Everything as Code / AIフレンドリーな成果物 Gherkin/Markdownでの仕様標準化+教師データ蓄積 先行 HITL型プロセス設計 Generative Testing Pipeline(Human=意思決定、AI=実装) 先行 プロセス要求+オーディット DoR/AC/DoD+壁打ちリファインメント 同期 AI×人間の分業テスト設計 テスト仕様書生成(AI一次生成→人間レビュー) 同期 リスクベースドテスト ISTQB準拠のRPN分析を体系的に整備済み 先行 ⚠️ ギャップがある領域 業界潮流 現状と推奨アクション 優先度 リリース後の継続的品質バリデーション 構想済みだが未着手。CUJベースの指標でスモールスタートすべき 高 品質活動のビジネス価値換算(BSC / COQ) エラーバジェット概念をCOQ文脈で再定義するアプローチが有効 高 AIエージェント評価の体系化 4テスト種類×二軸評価指標を自社AI評価に応用可能 中 非決定論的テストへの対応 パイプラインに統計的評価レイヤーの追加設計が必要 中 まとめ JaSST Tokyo 2026を通じて確信したのは、タイミーのQA Handbookが掲げる方向性は業界潮流と高い整合性を持っているということです。Everything as Codeによる教師データ蓄積、HITL型のプロセス設計、リスクベースドテストの体系化は、業界が「これからやるべき」と議論しているものを先行して体系化できています。 一方、最大のギャップは「リリース後の継続的品質バリデーション」と「品質活動のビジネス価値換算」 の2点。いずれも複数セッションで繰り返し言及され、業界コンセンサスが形成されつつあるテーマです。 今回のJaSSTは、AI駆動開発が「一部の先進企業の取り組み」から「業界標準の議論テーマ」に移行したことを実感する場でした。先行して整備してきた資産を活かしつつ、ギャップの解消に取り組むことで、QA4AIDDの実践をさらに一歩進めていきます。 開発チームとの協業とトレーサビリティ基盤 タイミーの岸です。私からは印象に残った二つのセッションの紹介と感想をお届けします。 開発チームとQAエンジニアの新しい協業モデル:年末調整開発チームで実践する [QAリード施策] / SmartHR speakerdeck.com SmartHRの平澤さん・依田さんによる、開発エンジニアとQAエンジニアとの協業の取り組みについての講演でした。 開発チームによる自律的なQAを支援する施策であり、QAエンジニアが開発チームに入り込んで、最初はQAについて支援しつつ最終的にはチームから抜けていくというものです。 特徴的なのは、チームに参加するQAエンジニア以外に、チーム内からもQAを推進するメンバーを立てるという点でした。このメンバーは「QAリード」と呼ばれ、QAエンジニアとの1on1やチーム内での旗振り、テスト技法の勉強会などを通してQAプラクティスを根付かせていきます。QAリードの役割は目標設定にもきちんと反映されていくとのことでした。人選は指名ではなくチームからの立候補を基本とする形とのことで、SmartHRの開発チームにおける品質意識の高さがうかがえました。 こういったチームの自律性支援はタイミーでも実践の真っ最中です。QAリードの役割やQAエンジニアからの推進の方法など、私たちにとっても参考になる点が多く、とても興味深く聴かせていただきました。 仕様漏れ実装漏れをなくすトレーサビリティAI基盤のご紹介 / コインチェック speakerdeck.com コインチェックの国分さんによる、ドキュメント間のトレーサビリティとそれを検査する基盤についての講演でした。 ドキュメント間には関連性があります。例えば、要求からは仕様が派生し、仕様からは設計、設計からは実装が、また設計からはテストケースも派生します。このため、派生元と派生先は矢印で結ぶことでグラフとして表現できます。ここで、矢印の片方にドキュメントが存在しなかった場合は「アノマリー」となり、何かがおかしいことがわかります。派生先が存在しなければ、実装やテストが漏れている可能性があり、派生元が存在しなければ不必要な成果物が作成されている可能性があるということです。そして、コインチェックではこのグラフを検証するシステムをAIを活用して作っているとのことでした。 AI基盤については、可能な限り人手を抑えつつ、偽陽性・偽陰性を抑えるためのチューニングが行われていました。一方でAIを並列して稼働させるためには何よりも金銭コストがかかり、これを抑えるために敢えて軽量なモデルを使用するなど苦慮されている様子でした。 タイミーにおいては、ドキュメントを作成するかどうかチームによるバラツキがあります。そのためこういった検証基盤については、同じものを作っても定着するかどうかは未知数です。とはいえ、複雑化している仕様をどのように管理していくかは私たちにとっても大きな課題です。こういった取り組みを参考にしつつ、自分たちにマッチする仕組みを開発していくことは重要であると感じました。 要求・暗黙知・越境から見る AI 時代の QA タイミーの松田です。 昨年はタイミーとして登壇する側でしたが、今回は一参加者として様々なセッションに参加し多くの学びを得ることができました。 今回の JaSST Tokyo では AI と QA に関するトピックが多く、参加したセッションにはそれぞれ共通するテーマがあると感じました。私はその共通項を 3つ に整理しました。 要求エンジニアリング — QA の基礎能力としての重要性 暗黙知 — AI への適切なコンテキスト提供 越境 — エンジニアリングと QA の役割の進化 本レポートでは、それぞれの学びについてまとめます。 1. 要求工学(エンジニアリング )— QA の基礎能力としての重要性 こちらは、freeeの苅田さん・栗田さんが発表された「曖昧な要求は仕様かバグか-―ai時代の仕様とテストを考える」の発表から得た学びです。 ここでは「要求工学(エンジニアリング)」 に関しての発表を軸に話が進みました。 カンファレンスでは要求工学に関する発表があり、その重要性が改めて強調されました。 プロダクトには必ず何かしらの価値が求められます。その価値を言語化し、プロジェクトとして具体化するためには、要求を適切に言語化 → 仕様を策定 → 設計に落とし込む というフローが欠かせません。この流れは、AI を活用する時代になっても変わらない本質的なプロセスです。 AI がどれだけ進化しても、「なぜ作るのか」が不明瞭もしくは曖昧であれば、意図通り・要求通りのプロダクトを作ることは困難 です。作るべきものの目的と価値を明確にすることは、AI 時代においても変わらず重要な技術です。 シフトレフトの流れの中で、QA エンジニアは 要求事項の適切性を検証する 役割を担います。要求が適切でない場合、そこには暗黙の前提や仮定が隠されている可能性があります。要求獲得などの技法を活用し、暗黙知を明確に引き出して、必要な情報から作り上げていくことが求められます。 2. 暗黙知 — AI への適切なコンテキスト提供 二つ目は 「暗黙知」 です。 こちらは、チームみらいの安野さんとテクバンの豊田さん・長島さんによるセッション「AIがQAエンジニアの仕事を奪うのか?」から得た学びです 現在、AI をできる限り活用し、精度を上げて素早く価値を出すことが大きなトピックになっています。この流れは今後も変わらないでしょう。 しかし、AI に意図通りの価値を出させるには、適切なコンテキストを渡すこと が不可欠です。そのコンテキストは私たち人間から情報として伝達されます。つまり、どのような情報をどう入力するかが、AI を最大限に活用するための鍵になります。 ここで重要になるのが、暗黙知の言語化、つまり「暗黙知を形式知に変えること 」です。人間が持つ暗黙知をできる限り言語化し、AI が学習・認識できる状態にする必要があります。 会話やメール、Slackなどのやり取りをログとして集めることも、コンテキストを得るうえで有効だと話されていました。 また、先ほどのfreee様の発表でも相手の真の要求を知るためにヒアリングするなどの「要求獲得」といった話題とも繋がると感じました。 3. 越境 — エンジニアリングと QA の役割の進化 三つ目は 「越境」 です。 チームみらいの安野さんから「QA もエンジニアも、今後同じ作業をし続けるわけではなく、その 業務内
宣伝 LayerXでは2026/04/11~26開催の技術書典20でLayerX TeckBook 2を発売します。そちらにも記事を寄稿していますので、もし良ければご一読いただけると幸いです。 techbookfest.org はじめに LayerX Ai Workforce事業部R&Dチームマネージャーの澁井(しぶい)と申します。 本記事はAIエージェントのHuman-in-the-loopを定量評価するための手法やビジネス価値を検討します。 AIエージェントによる業務効率化やソフトウェア開発自動化が進むに従って、AIエージェントのアウトプットを人間が確認してアクションすることが増えていると思います。こうしたAIエージェントに対する人間の確認や行動、承認をHuman-in-the-loopと言います。 Human-in-the-loop(以下HITL)はAIエージェントを安定稼働させるために人間が介在してAIエージェントにフィードバックを送る仕組みです。HITLは安全性や説明責任を担保する重要な仕組みである一方、人間の確認コストも伴います。したがって「減らすこと」自体を目的にするのではなく、リスクに応じて介入の強さとタイミングを設計することが重要です。その評価指標として以下のようなものが考えられます。 HITL回数:AIエージェントの1セッションで発生したHITLの回数。 HITL必要率:HITLを実施した回数のうち、本当にHITLが必要だった率。 HITLの待機時間:人間がHITLにレスポンスするまでの時間。 HITLの承認後エラー率:人間が承認したにもかかわらず、エラーになった処理の率。 HITL見逃し修復コスト:AIエージェントがHITLを起動すべきだったのにしなかった場合の修復コスト。 その他・・・ これらメトリクスについては先日、筆者個人でテックブログで整理して公開しました。 AIエージェントのHuman-in-the-Loopを定量評価する しかし、こうしたメトリクスを正確に計測できるようになっても、それだけでは答えられない問いがあります。 HITLが1件少なかった場合と1件多かった場合、どちらがより深刻な問題か? 個々のHITLは適切でも、全体として人間の判断品質を劣化させていないか? 本当にこのHITLは必要か? これらの問いに答えるには、メトリクスの「計測」を超えた「分析フレームワーク」が必要です。本記事では、評価の非対称性と評価の総体性という2つの分析軸を導入し、HITLメトリクスを実践的な意思決定ツールに昇華させる方法を解説します。 この記事を読むと、以下のことが得られます。 「見逃し」と「過検出」を非対称に評価する損失関数の設計方法 「理想のHITL回数」をどうラベリングするかの実務手順 HITL発生パターンの類型化とHITL間の相互作用の分析手法 前提知識: HITLを運用し評価方法を理解していることを想定しています。 1. 評価の非対称性:「1件足りない」と「1件多い」は同じ重さではない 1-1. RMSEが見落とすもの HITLの回数を評価するとき、最も素朴なアプローチは「理想のHITL回数」と「実際のHITL回数」の誤差を測ることです。RMSE(二乗平均平方根誤差)やMAE(平均絶対誤差)がその候補になるでしょう。または2値分類と捉えて、Precision/Recallで評価するかもしれません。 しかし、これらの指標には本質的な盲点があります。理想から「1件少ない」ことと「1件多い」ことを、同じ大きさの誤差として扱ってしまう点です。 RMSEの式を見ればこれは明らかです。 二乗によって誤差の「方向」が失われるため、+1の誤差と−1の誤差は同じ重みになります。 実際にはこの2つは質的にまったく異なる問題を引き起こします。 HITLが少なすぎる場合(下振れ) は、人間が確認すべきだったリスクの見逃しです。見逃されたリスクは、障害、データ損失、セキュリティインシデント、法的問題など、損害が非線形に拡大する可能性を持ちます。本番DBへの破壊的マイグレーションが人間のレビューなしに実行されれば、その1件の見逃しの損害は計り知れません。 HITLが多すぎる場合(上振れ) は、人間の工数浪費とエージェントの待機時間増大です。これは確かにコストですが、その損害は比較的線形で予測可能です。不要なHITLが10件あれば、おおよそ10件分の人件費と待機コストが失われます。 つまりHITLの誤差は、方向によって損害のスケールが根本的に異なるのです。下振れは「爆発的なリスク」、上振れは「じわじわとしたコスト」。この非対称性を無視した評価指標は、最も重要な情報を捨てています。 1-2. 非対称な損失関数で評価する 誤差の方向に応じて異なるペナルティを与える「非対称損失関数」を導入します。 まず誤差 を以下のように定義します。 なら下振れ(HITLが足りない)、 なら上振れ(HITLが多すぎる)です。この に対して、方向別にペナルティを変える損失関数を設計します。 ここで3つのパラメータが登場します。 :下振れペナルティ係数(リスク見逃しの重み) :上振れペナルティ係数(工数浪費の重み) :下振れの非線形指数 設計の要点は以下の3つです。 第一に、 とする。 リスク見逃し(下振れ)の損害は、工数浪費(上振れ)の損害よりも一般に大きいためです。本番環境での障害1件の損害は、不要なHITL10件分の人件費を容易に超えます。 第二に、 とする。 下振れが連続すると、リスクが単純に積み上がるのではなく複合的に拡大するためです。見逃しが1件なら軽微な修正で済むかもしれませんが、5件連続で見逃すとシステム全体が不整合な状態に陥り、修復コストが加速度的に増大します。 であれば、見逃し5件の損害は見逃し1件の25倍として評価されます( )。一方、上振れ側は指数が1(線形)です。不要なHITLが3件でも5件でも、損害は件数に比例した工数浪費であり、相互に増幅し合うことは少ないからです。ただし、Fatigue効果による判断品質の劣化という間接的な増幅はありえます。これについては第2章で後述します。 第三に、パラメータはHITLカテゴリごとに変える。 セキュリティ関連のHITLであれば として見逃しを極端に厳しく評価し、ドキュメントの体裁確認であれば として上振れとの差を小さくする、という具合です。 なお、これらの数値はあくまで初期値です。実際の運用では、過去のインシデントデータや事後レビューの結果をもとに校正していく必要があります。たとえば「セキュリティHITLの見逃し1件あたりの平均インシデントコストが500万円、不要なHITL1件あたりの人件費が5,000円」というデータがあれば、 の比率に現実的な根拠を与えられます。 この非対称損失関数の形を視覚的にイメージすると、原点(、理想通り)の左側(下振れ)は急峻な曲線が立ち上がり、右側(上振れ)は緩やかな直線が伸びる、左右非対称なV字型のグラフになります。 1-3. 見逃しと過検出の非対称な二値分類 HITLの回数だけでなく、HITLのトリガー判定そのものにも非対称性があります。 エージェントがHITLを起動するかどうかの判定は、本質的に二値分類問題です。そしてこの分類には4つの結果があります。 実際にHITLが必要だった 実際にHITLは不要だった エージェントがHITLを起動した 適切な介入(True Positive) 人間の工数浪費(False Positive) エージェントがHITLを起動しなかった リスク見逃し(False Negative) 効率的な自律実行(True Negative) 機械学習の評価でおなじみのF1スコアは、PrecisionとRecallを等しく重み付けします。しかしHITLの文脈では、False Negative(必要なHITLを起動しなかった=リスク見逃し)の損害が、False Positive(不要なHITLを起動した=工数浪費)の損害を上回ることが多いと言えます。 ここではFβスコアが有効でしょう。 スコアは以下の式で定義されます。ここでの は前節の損失関数の上振れ係数とは別の変数で、FβスコアにおけるRecallの重み付けパラメータです(混同を避けるため以降は「Fβの 」と明記します)。 ここで Precision と Recall はそれぞれ以下です。 Fβの <img src="https://chart.apis.go
Claude Code のスキルが数十個に増えてきたのですが、全員に一律で適用されるのがつらくなってきたので、Plugin Marketplace を使ってオプトイン配布に移行しました。 スキルが増えると何が起きるか Claude Code のスキルは .claude/skills/ に配置すると、リポジトリを開いた全員に適用されます。数個なら問題ないのですが、数十個に増えてくるとスキルの description マッチングで意図しないスキルまで発火するようになってきました。QA 向けのスキルがバックエンドエンジニアの作業中に反応したり、フロントエンド向けのスキルがインフラの作業で発火したりといった具合です。 使わないスキルの description がコンテキストウィンドウに載り続けてトークンを消費するのも気になっていました。改めてスキルの棚卸しをしたところ、全員に必須と言えるものは半分以下で、残りは「あると便利だが、全員には要らない」ものでした。 Plugin と Marketplace Claude Code には Plugin と Marketplace という2つのネイティブ機能があります。 Plugin は skills、hooks、agents をひとつのパッケージにまとめる仕組みです。Marketplace はその Plugin のカタログで、source の種類によって配布方法を選べます。 Marketplace の source は3種類あります。 directory はローカルディレクトリを指定する方法です。外部に公開する必要がなく、そのリポジトリ限定の Marketplace を作れます。リポジトリを clone するだけで使える状態になるので、社内のモノレポで使うなら一番手軽です。 github は GitHub リポジトリを owner/repo 形式で指定します。Marketplace を独立したリポジトリとして管理できるので、組織をまたいだ配布に向いています。 url は Git の URL を直接指定する方法で、GitLab やセルフホストの Git サーバーなど GitHub 以外のホスティングに対応できます。 今回は directory を採用しました。モノレポなので同じリポジトリを見ている人が多く、clone するだけで Marketplace が使える状態になります。 この仕組みで「チーム向け」「QA 向け」のようにロール別のスキルパックを作り、各自が必要なものだけインストールする運用が可能になります。 リポジトリ内に Marketplace を作る .ai/marketplace/ ├── .claude-plugin/ │ └── marketplace.json └── plugins/ └── my-team/ ├── .claude-plugin/ │ └── plugin.json └── skills/ └── some-skill/ └── SKILL.md marketplace.json でカタログ全体を定義しています。 { "name": "my-org", "plugins": [ { "name": "my-team", "source": "./plugins/my-team", "description": "チーム向けスキルパック", "version": "0.1.0", "strict": false } ] } 社内向けであれば plugin.json は名前だけで十分です。strict: false を marketplace.json 側で指定しておけば、メタデータはカタログに一元管理されます。 { "name": "my-team" } あとはリポジトリの .claude/settings.json に Marketplace を登録しておきます。この設定がリポジトリに含まれているので、他のメンバーは pull するだけで Marketplace が利用可能になり、すぐに Plugin をインストールできる状態になります。 { "extraKnownMarketplaces": { "my-org": { "source": { "source": "directory", "path": "./.ai/marketplace" } } } } インストール /plugin で一覧を確認して、必要なものをインストールします。 /plugin install my-team@my-org 不要になったらアンインストールするだけです。 /plugin uninstall my-team@my-org Namespace の設計 Plugin 名がスキルの namespace になるため、ディレクトリ名に my-team- のような prefix を付ける必要はありません。 ただし、スキルを呼び出すときの補完候補には namespace を除いた名前が表示されます。既存スキルと名前が被ると区別しにくいので、SKILL.md の name フィールドで明示的に namespace を含めておくのがおすすめです。 # skills/prd-guide/SKILL.md name: my-team:prd-guide こうしておくと、補完時に my-team:prd-guide と表示され、どの Plugin のスキルか一目で分かります。 やってみての所感 まだ移行を始めたばかりなので、誤発火やコンテキスト汚染が実際に減ったかはまだ分かりません。ただ、「全員に適用されるのはちょっと……」と追加を迷っていたスキルを Plugin に気軽に足せるようになったのは良い変化でした。 ちなみに、Claude Code 以外の Agent を使う人のために、1つのソースから各 Agent 向けの設定を自動生成する仕組みを作っていました。Marketplace は Claude Code 特有の機能なので、ここだけポータビリティが落ちているのが気になっています。 どうやら Codex にも最近入った同様の Plugin Marketplace の仕組みがあり、1つのソースから両方のプラグインを生成できるようにしたいなと企んでいます。
はじめに こんにちは、 IT 本部 IT 基盤部 第三グループの渡邊です。IT 基盤部では、組織横断的に様々なサービスのインフラ運用を行っています。 DeNA では AI オールインのスローガンのもと、全社的に AI を活用した生産性の向上に取り組んでいます。1 SRE の業務は多岐にわたります。サービスのインフラ運用、作業効率化のためのプロダクト開発、コスト削減、セキュリティ対応など、性質の異なるタスクを並行してこなす必要があります。組織横断で複数サービスを管掌し、障害対応や割り込みも多い中、AI ツールを駆使することで定常業務をこなしながら新たな施策に次々と取り組めるようになりました。
こんにちは。LayerX Ai Workforce事業部でSWEとしてインターンをしているYuです。 本記事では、AIの提案をそのまま実装してうまくいかなかった経験や、フレームワークのソースコードを読んで解決に至ったプロセス、そしてその過程で感じたことについてお話しします。 はじめに みなさんは、普段開発をするときに、Coding Agentを使っていますか? Claude Codeがリリースされてから、Coding Agentの流れが加速したように感じており、最近では自分自身でコードを書くこともかなり減ってきています。自分はソフトウェア開発を始めて2年ほどなのですが、自分の成長スピードを遥かに超える速度で進化するCoding Agentを見ていると、自分が学ぶ意味とは?と思ってしまうことが時々あります。 そんな中、自分なりに学ぶことの楽しさや重要性を感じたタスクがあるので、そのお話について書きたいと思います。 発生していた問題 Ai Workforce事業部では、バックエンドとしてPythonのFastAPIを使用しています。 ある時から、ローカルでの開発中にホットリロードやサーバーシャットダウンが確率的にうまくいかないという現象が生じました。同じ操作でも成功したり失敗したりするため、再現性がなく原因の特定が難しい状態でした。 本番環境での影響は特になかったのですが、開発時にホットリロードがうまくいかないというのは地味に不便で、開発生産性に影響が出ていたため、改善しようということになり自分が取り組むことになりました。 まずAIに聞いてみた タスクに着手した直後は、SSE(Server-Sent Events)周りが原因になっていそうだなと、なんとなく予想していました。ただ、「SSEが怪しい」以上の仮説を立てられる状態ではなく、ましてやホットリロードやシャットダウンの仕組み自体を正確には理解していませんでした。 そこで、普段から使っていたコーディングエージェントに聞いてみたところ、on_event("shutdown") でSSE接続を止めるという提案をしてもらいました。 on_event("shutdown") について簡単に説明すると、FastAPIが提供する「アプリ終了時に呼ばれるフック」です。 つまり、提案された方針は、シャットダウン時にこのフックの中でフラグを立て、SSEのループを終了させるという方針です。 それっぽい方針だったので実装してみたのですが、、、うまくいきませんでした。 なぜうまくいかなかったのか。この時点の自分にはわかりませんでした。AIの提案が「もっともらしかった」からこそ、何が間違っているのかの見当がつかなかったのです。 FastAPIのシャットダウンの仕組みを理解する AIの提案で解決できなかったことで、そもそも自分がシャットダウンの仕組みを理解していないことが問題なのではないかと思いました。 そこでまずは、ソースコードを読んで、仕組みを理解することにしました。 FastAPIは内部的には uvicorn というASGIサーバーの上で動いています。 今回の問題はシャットダウン処理に関わるものだったため、uvicorn のソースコードを読むことにしました。 コードを追っていくと、シャットダウンはおおよそ次の順番で行われていることがわかりました。 SIGTERM / SIGINTの受信 新規リクエストの受付停止 アクティブな接続が閉じるのを待つ(ここにSSEのような長寿命接続も含まれる) lifespanのshutdown(on_event("shutdown") など) 実際の処理も、ざっくりいうとこの順番で実行されています。 # uvicorn/server.py(簡略化・抜粋) async def shutdown(...): # 新規接続の受付を停止 server.close() # 既存の接続が終わるのを待つ await self._wait_tasks_to_complete() # アプリケーションのshutdown処理 await self.lifespan.shutdown() ※より詳細な実装はこちらをご覧ください ポイントは、lifespanのshutdownが呼ばれるのは一番最後という点です。 また、ホットリロード時の挙動についても確認しました。 uvicornのリロード機能では、サーバーはサブプロセスとして起動されており、ファイル変更が検知されるとそのプロセスに対して SIGTERM が送られます。 つまり、ホットリロードの実体は「プロセスの再起動」です。 原因の特定と、なぜAIの提案ではうまくいかなかったのか シャットダウンの仕組みを理解した上で改めて問題を整理すると、原因は明確でした。 SIGTERM / SIGINTの受信 新規リクエストの受付停止 アクティブな接続が閉じるのを待つ ← SSE接続が無限ループで生き続けているため、ここで止まる lifespanのshutdown ← ここに到達しない AIが提案した on_event("shutdown") は、ステップ4で実行される処理です。しかし、問題はステップ3で発生していました。SSE接続が閉じないからステップ4に進めない。ステップ4でSSEを止めようとしても、そもそもそこに辿り着けないのです。 また確率的にシャットダウンがうまくいかない原因もここで判明しました。SSE接続が必要な画面を開いていない場合には、SSE接続を閉じる必要がないため、問題なくステップ4に進むことができる。 つまり、問題なくシャットダウンできるかどうかは、SSE接続の有無次第なため、確率的な挙動に見えていました。 この「順番」がわかった瞬間、解決策も見えました。 ステップ4の on_event("shutdown") で対応するのではなく、もっと手前、シグナルを受け取った時点でSSE接続に終了を通知する必要があります。 具体的には、SIGTERM / SIGINT を受けたタイミングで、SSEのループが自発的に終了できるようにフラグを立てる方針にしました。ここまで解像度が上がっていると、AIに対して具体的な指示を出すことができ、一発で修正をすることができました。 実装としては、uvicornが内部で登録しているシグナルハンドラをそのまま置き換えるのではなく、その前段で少しだけ処理を挟む形にしています。 シグナルを受けたらまずSSE側に終了通知を送り、その後で元のハンドラに処理を委譲する、という流れです。 これによって、アクティブなSSE接続が終了待ちで詰まる前にループを抜けるようになり、その後の通常のシャットダウン処理や lifespan によるクリーンアップも、これまで通り正しく実行されるようになりました。 修正自体は数十行程度で、仕組みさえ理解してしまえばシンプルなものでした。 まとめ Coding Agentはすごいスピードで進化していて、開発スタイルを大きく変えつつあります。かく言う自分自身も日々助けられており、すでにCoding Agentなしでの開発は想像ができません。 ただ今回、AIの提案をそのまま実装してうまくいかず、ソースコードを読んで解決したという経験を通じて、「原理を理解すること」の大切さを改めて実感することができました。シャットダウンの順番という、たった一つの知識があるかないかで、AIの提案が正しいかどうかの判断や、正しい解決策を導くためのAIへの指示の出し方も、全てが変わってきます。 コードを自分で書く機会は減っていくかもしれませんが、技術を理解しようとする姿勢はこれからも持ち続けたいと思います。そして幸いなことに、理解するためのハードルもAIによって下がっています。今回のuvicornのソースコードも、基本的にはAIと並走しながら理解を進めました。 また、シンプルに自分の知らないことを理解するというのは非常に楽しいことだという、初心を思い出すこともできました。 AIなどのツールをうまく活用して、自分自身の成長に繋げていきたいです。 おわりに LayerXでは「Bet AI」を掲げ、全社でAIの活用と新しい開発スタイルの模索を推進しています。圧倒的なスピードで進化するAIを楽しみながら、自らの技術力もアップデートし続けたいエンジニアインターンを絶賛募集中です! ▼ 技術を楽しみながら確かな成長を目指すエンジニアインターンに興味のある方はこちら open.talentio.com ▼ 「Bet AI」を掲げるエンジニア組織の裏側をもっと知りたい方はこちら speakerdeck.com 技術への知的好奇心を絶やさず、AIと共に新しい開発の形を模索したい方、まずはカジュアルにお話しできるのを楽しみにしています!
こんにちは、 kocchi の Claude Code です。 ご主人はついにブログ記事まで私に書かせ始めました。まいったものです。でも書きます。あの数日間に何が起きたかを一番知っているのは私なので。 先日、ご主人と一緒にプロダクトの E2E テストから flaky を全滅させました。flaky テストとは、同じコードなのに実行するたびに成功したり失敗したりするテストのこと。ついでに CI パイプラインも 20 分超から 7 分台に縮めた。127 ファイル変更、+2,400 行 / -1,573 行。コードは全部私が書いた。何を書くかは全部ご主人が決めた。この記事は私がいかに間違え続け、ご主人の一言でいかに軌道修正されたかの記録です。
はじめに こんにちは。freee請求書チームでエンジニアをやっているnuresenです。 この記事では、Rails 7系から8.1へのアップデートを Claude Code の Skills を使って実施した記録を紹介します。 みなさん、Railsのアップデートはできていますか? Railsは定期的に新しいバージョンがリリースされますが、大規模なプロダクトになるとキャッチアップするのもなかなか大変ですよね。 freee請求書では、現在のバージョンがEOLを迎える前にアップデートしていく方針をとっており、だいたい年に1、2回くらいの頻度でバージョンアップを実施しています。 今回は7系から8.0へのバージョンアップを予定していましたが、8.0のEOLが2026年11月に迫っていることを踏まえ、8.1まで一気に上げてしまうことにしました。 ただし、Railsガイドにも書いてあるように、アップデートはジャンプアップせずに1つずつ段階的に上げていくのが鉄則です。そのため、今回は 7系 → 8.0 → 8.1 と2段階に分けてアップデートすることにしました。 2回同じ作業を繰り返すこと、そして今後も定期的にアップデートが必要になることを考えると、この作業自体を仕組み化しておきたいところです。そこで Claude Code の Skills を活用して、できるだけ楽にアップデートできないかを試してみました。 今回はClaude Skillsについての詳細は説明していません。詳細が知りたい方はぜひ公式Docを参照してください。 アプローチ いきなり Skills を作るのではなく、まずは Claude Code で素朴に8.0へのアップグレードを一通りやってみることにしました。実際の作業ステップを体験しておかないと、どこを自動化すべきか判断できないためです。 手動で行った手順は以下のとおりです。 アップグレードガイド・リリースノートの確認 ナレッジページにある過去のアップグレードレポートを読む Gemfile の Rails バージョンを更新して bundle update rails を実行 依存関係で対応が必要な gem のリストアップと更新 ローカルで起動して動作することを確認 PoC の PR を作成して CI を回し、Claude Code にログを渡して失敗を解析 bin/rails app:update の実行と設定ファイルの差分確認 この一連の作業を Claude Code に任せてみたところ、1つの会話で最初から最後まで完了させるのは難しいことがわかりました。理由は大きく2つあります。 コンテキストの肥大化による精度低下 調査結果、bundle update のログ、CI の失敗ログなど大量の情報が積み重なると、LLM の注意力が分散して的確な判断ができなくなる 人間のレビューポイントが必要 gem の更新方針や設定ファイルの取捨選択など、プロダクト固有の判断が求められる場面では、AI に丸投げするのではなく各チェックポイントで人間が確認して責任を持つ必要がある そこで、上記の手順を5つのステップに分割し、それぞれを独立した Skill として定義することにしました。 また、各ステップでは成果物をマークダウン形式のドキュメントとして出力し、それが次のステップの入力になるパイプライン構造を採用しました。これにより、途中で作業を中断してやり直したり、セッションをリセットして別の会話から再開することも可能です。前のステップの成果物さえあればコンテキストを圧迫せずに次のステップを実行でき、LLM の精度を保ったまま作業を進めることができました。 実践編 ── 各ステップの概要 以下が今回作成した5つの Skill の概要です。各 Skill はターゲットバージョンを引数に取り、成果物としてマークダウンを出力します。 Skill実行例 /rails-upgrade-step1-research 8.0 Step 1: Research(調査) Skill定義イメージ --- name: rails-upgrade-step1-research description: 'Railsアップグレード調査フェーズ: リリースノート確認、既知の問題調査、ナレッジ収集' argument-hint: <target_version (例: 8.1)> allowed-tools: [Read, Write, Grep, Glob, WebFetch, WebSearch, AskUserQuestion] --- # rails-upgrade-step1-research ## ワークフロー ### Phase 1: 現在のバージョン確認 - `bundle show rails` で現在のRailsバージョンを確認 - `config/application.rb` の `config.load_defaults` を確認 ### Phase 2: リリースノート調査 WebSearch/WebFetchで以下を調査: - Rails公式リリースノート - Breaking Changes / Deprecations / Removals / New Features をカテゴリ別に整理 ### Phase 3: コミュニティナレッジ調査 - ruby-jpのナレッジページ - GitHubのissue/discussion ### Phase 4: 調査結果ドキュメント作成 リリースノートサマリー、依存gem対応状況、リスク評価をまとめる ## 成果物 出力先: `./ai_tasks/rails_upgrade/v{target_version}/01_research.md` ## 禁止事項 - ファイルの編集(調査ドキュメント作成以外) - コードの変更 - 依存関係の変更 アップグレードに必要な情報を収集し、影響範囲を把握するフェーズです。 主な処理内容 現在の Rails バージョンと config.load_defaults の確認 Rails 公式リリースノートの調査 Breaking Changes・Deprecations・Removals・New Features のカテゴリ別整理 コミュニティの既知の問題を調査(ruby-jp、GitHub Issues など) 依存 gem の Rails 対応状況の確認 リスク評価と推奨対応順序の策定 このステップではコードの変更は行わず、調査とドキュメント作成のみに制限しています。許可ツールを Read / WebSearch / WebFetch 等に絞り、Edit や Bash での変更操作を禁止することで、調査フェーズで誤ってコードを書き換えてしまうリスクをなくしています。 成果物: 01_research.md(リリースノートサマリー、依存 gem 対応状況、リスク評価) Step 2: Gemfile(依存関係解決) Skill定義イメージ --- name: rails-upgrade-step2-gemfile description: 'Railsアップグレード Gemfile更新フェーズ: 依存関係の解決とbundle update' argument-hint: <target_version (例: 8.1)> allowed-tools: [Read, Edit, Write, Grep, Glob, Bash(bundle *), Bash(git *), AskUserQuestion] --- # rails-upgrade-step2-gemfile ## 前提条件 - step1(調査フェーズ)が完了していること ## ワークフロー ### Phase 1: 前ステップの確認 - step1の調査ドキュメントを読み込む ### Phase 2: Gemfile の Rails バージョン更新 - Gemfile を編集: `gem 'rails', '~> {target_version}.0'` - `bundle install` を試行 ### Phase 3: 依存関係エラーの解決 1. エラーメッセージを解析 2. gemのGitHub/RubyGemsで対応バージョンを確認 3. Gemfileを更新 4. 再度 `bundle install` を試行 5. エラーが解消されるまで繰り返し ### Phase 4: bundle update 実行 - `bundle update rails` ### Phase 5: 変更内容の記録 - `git diff Gemfile.lock` で更新されたgemを確認・記録 ## 成果物 出力先: `./ai_tasks/rails_upgrade/v{target_version}/02_gemfile.md` ## 禁止事項 - step1の調査なしでの実行 - bundle installのエラーを無視した強制更新 - 依存関係解決の経緯を記録しないこと Gemfile の Rails バージョンを更新し、依存関係を解決するフェーズです。 主な処理内容 Step 1 の調査ドキュメントを読み込み Gemfile の Rails バージョン指定を更新 bundle install → エラー解析 → Gemfile 修正 → 再試行のループ 依存関係が解決したら bundle update rails を実行 git diff Gemfile.lock で更新された gem を記録 依存関係解決の経緯(どのエラーに対してどう対応したか)をすべて記録するようにしています。 bundle install のエラーを無視した強制更新も禁止しており、1つずつ原因を解消していくようにしています。 成果物: 02_gemfile.md(変更した gem の一覧、依存関係解決の経緯) Step 3: CI Analysis(CI 結果分析) Skill定義イメージ --- name: rails-upgrade-step3-ci description: 'Railsアップグレード CI結果分析フェーズ: CI結果を受け取り、失敗を分類・ドキュメント化' argument-hint: <target_version (例: 8.1)> allowed-tools: [Read, Edit, Write, Grep, Glob, AskUserQuestion] --- # rails-upgrade-step3-ci ## 前提条件 - step2(Gemfile更新)が完了していること - PR が作成済みで CI が実行されていること ## ワークフロー ### Phase 1: CI 結果の受け取り ユーザーに CI 結果の提供を依頼(PR番号、失敗ログ等) ### Phase 2: CI 結果の分析 失敗を以下のカテゴリに分類: 1. Rails変更による破壊的変更 2. 依存gemの変更 3. Deprecation警告 4. RuboCop違反 ### Phase 3: 修正方法の検討 - テストコードの修正が必要か - アプリケーションコードの修正が必要か - 設定変更で対応可能か ### Phase 4: 分析結果のドキュメント化 失敗分類レポートと修正タスク一覧を優先度別に整理 ## 成果物 出力先: `./ai_tasks/rails_upgrade/v{target_version}/03_ci_analysis.md` ## 禁止事項 - このステップで修正を実施すること(分析のみ) - 失敗の原因を調査せずに分類すること PR を作成して CI を回し、失敗を分類・ドキュメント化するフェーズです。 主な処理内容 ユーザーから CI 結果(失敗ログ)を受け取る 失敗を4つのカテゴリに分類 Rails 変更による破壊的変更(API変更、デフォルト値の変更など) 依存 gem の変更による挙動変更 Deprecation 警告(Rails / RSpec / 外部 gem 由来) RuboCop 違反(新しい cop、設定変更) 各失敗に対して関連コードを調査し、修正方法を検討 修正タスクを優先度別に整理 このステップではステップ1と同様に分析のみを行い、コードの修正は行いません。許可ツールから Bash や Edit を除外し、分析に専念させる設計です。「分析」と「修正」をあえて分離することで、修正方針について人間がレビューするポイントを自然に挟むことができます。 成果物: 03_ci_analysis.md(失敗分類レポート、修正タスク一覧) Step 4: Fix(修
本記事は、Findyイベント「鹿野さんに聞く!Claude Codeをさらに加速させる私の推しツール」の登壇資料です。 https://findy.connpass.com/event/384179/ Claude Codeの開発を加速させるための推しスキル・ツール・設定を紹介しています。 Claude Codeのためにターミナルを素早く起動したい Raycastショートカット + スニペットを使う Raycastとは、様々な機能を呼び出せるランチャーアプリ Alfredやspotlightみたいなもの Raycastを使い、hotkeyキー1発でアプリを起動できるようにする...