こんにちは。株式会社タイミーのバックエンドエンジニアの神山( @ dak2 )です。 2026/4/22 から 24 まで函館で開催された RubyKaigi 2026 に参加し、Day 2 に登壇しました。 タイミーでは、世界中で開催される技術系カンファレンスに無制限で参加できる「 Kaigi Pass 」という制度を活用し、8名が現地でカンファレンスに参加してきました。 登壇内容や参加セッションで得た学びは各レポートにまとめています。気になった方はご覧いただけると幸いです。読者の皆様の今後の学びの参考になれば嬉しいです。 tech.timee.co.jp tech.timee.co.jp tech.timee.co.jp Road To RubyKaigi 2026 地震や飛行機の遅延などもありましたね。皆様の中にも、移動に戸惑った方いらっしゃったのではないでしょうか。 色々大変でしたが、参加者の方々が無事到着されたのを X(旧Twitter)で見て、一安心したのを覚えています。 印象に残ったセッション A Faster FFI rubykaigi.org 自分が作っている gem で Ruby と Rust を使っており、FFI 周りが気になっていたので聞きました。 FFIは、引数の数の確認や型変換(アンボックス)を実行時に行う必要があるため、C拡張に比べてオーバーヘッドが大きいようです。また、ピュアなRubyで書かれたJITコンパイラのFJITはC拡張より速いものの、CRubyの内部データ構造に強く依存していました。そのため仕様変更に弱く、実用的ではなかったとのことです。 FJIT これですね。 fjit.rb · GitHub これに加え、アーロンは hacks gem というものを作っていて、そこから CRuby の 構造体を引っ張ってきて FJIT で使っているみたい。AST をダンプして構造体の名前を元にデータ構造を抽出、メモリのレイアウト情報を計算して Ruby のハッシュに格納して返してるみたいですね。 面白いなー。すごい力技だw FJIT はこのハッシュに依存しているから実用的ではなかったとのこと。 新たな解決策として ffx という gem を作ったみたいです。 Ruby の値を C に変換してネイティブ関数を呼ぶ impl 関数と、実際のコードへジャンプするトランポリン関数を生成。トランポリン関数を生成する際に、アセンブリに impl 関数への jump 命令を書いておき、その次のメモリ領域にマジックマーカーや型情報、パラメータなどのメタデータを書き込んでおく。 通常の実行時には impl 関数へ jump するので、型情報などは読み込まれないけど、ZJIT でのコンパイル時にはマジックマーカーを検知してメタデータを読み取って最適化に使うとのこと。 このハックは単純にすごいなと思いました。感心しながら聞いていたのを覚えています。勉強になります。個人的に印象に残るセッションでした。 Lightning-Fast Method Calls with Ruby 4.1 ZJIT rubykaigi.org speakerdeck.com 行く末が気になる ZJIT ですね。速さは正義ということで、とても期待しています。そこで、このセッションを聞きに行きました。 今の ZJIT はメソッド呼び出し時に全てのパラメータを一度メモリにロードしてしまう課題があるみたいですね。 バックトレースや例外処理、ローカル変数読み込みなどでスタック上に正確なメタデータを残しておく必要があるためとのこと。 これに対し、 Lightweight Frames が提案されていました。 メタデータの書き込みを遅延させ、書き込むフィールドを「JIT Return」の1つなど最小限に限定しつつ、メソッドコール時のメモリライトを削減すると。ただ、ローカル変数の処理や例外時の longjmp などをどうにかしていかないといけないみたいですね。帰ってきてから ZJIT の内部を読んでみています。 Matz Keynote なんか Matz が一番楽しそうだったなあと思う Keynote でした。Ruby という言語を作ってなお、まだ作りたいものがある。AI と一緒に作った Spinel を発表している Matz が楽しそうだった。AI Slop とか色々ありますが、作りたいものを作るって最高ですよね。最高にクールでした。非常にインスピレーションを受けた Keynote でした。 matz リツイート 登壇 登壇時の写真 special thanks to @ginkouno rubykaigi.org speakerdeck.com AI 時代の Ruby では、NoMethodError を静的に解析できたら良いのではないか、という内容で登壇しました。登壇は想像していた何倍も得るものがありました。 きっかけは「日常の疑問」だった このトークの種は、普段の業務で感じた引っかかりでした。型アノテーション付きの Ruby とそうでない Ruby を行き来していると、どうしても型チェックの遅さが気になります。一方で、AI Agent のコーディング能力が一気に上がったことで、「そもそも型をちゃんと書いていく ROI ってどうなんだっけ?」という疑問が、頭の片隅から離れませんでした。 この「気になり」を寝かせていたところ、CFP が1週間延長になった当日、サウナで急に像を結びました。よく「サウナで整うと閃く」と言いますが、実際は逆で、 普段から問題意識を温めていたからこそ、たまたま緩んだ瞬間に繋がったのかな と思っています。整うどころではなくなり、速攻で帰りました。その後、寝る間も惜しんでアイディアを形にし、CFP を提出したのが懐かしいです。 「型ありの Ruby と型なしの Ruby、両方を日常的に書いている自分だからこそ立てられる問い」だと思えたことが、提出のモチベーションになりました。自分の業務の中の違和感は、思っている以上にトークの種になるんだなと。 gem を作って「持論」を形にした セッション内で発表した Method-Ray という gem は、コアロジックに Rust を用いています。命名は X-Ray から着想を得ていて、個人的にも気に入っています。「こうすればできるのでは」という仮説をもとに設計し、最小限で動くものを形にし、gem として公開しました。僕の持論やスタンスを gem に込めた上で CFP を提出しました。 株式会社mov の @pjocprac さんが型関連のセッション内容をまとめてくださっており、僕の発表内容にも触れてくださっているので、詳細に興味があればぜひご覧ください。 RubyKaigiで型まわりの内容をまとめたブログ書きました! RubyKaigi 2026 型まわり4セッション聴講メモ — AI コーディング時代の Ruby の型 #RubyKaigi https://t.co/HZB5PJW7z0 — Takeshi Watanabe (@pjocprac) 2026年4月27日 登壇して初めて得られた3つのもの 発表後、いろんな方に声をかけていただきました。「ここの型解析どうしてる?」「なんでそう思ったんですか?」「英語話せるんですか?」などたくさんお声がけいただき嬉しかったです。 自分の盲点を埋めるフィードバック 質問内容を受けて「自分の gem もこう直さないといけないな」と気づきが連鎖的に出てきました。一人だと気づきにくい視点に気づかせてくれるというのは良い機会だなと。 自分のスタンスを認識する 今回はスタンスを取った発表をしたのですが、それに対していろんな意見をもらえました。賛否両論あると思いますし、いろんな意見があると思いますが、同時に自分の立ち位置もはっきりしました。スタンスを取った発表をして良かったなと思っています。 アイデアの昇華 @okuramasafumi さんとは、いわゆる廊下の話で、「テストが十分速ければ AI が PDCA を回しやすくなって、それは型解析の近似になっているのでは」という方向性を議論しました。登壇内容を、登壇の外で次のテーマへと押し進めてもらえる感覚があり、これは登壇したからこそ発生した会話なんだと思うと、良い機会に恵まれたなと嬉しく思いました。 次にやりたいこと 今後は、 Method-Ray の解析範囲を広げたいのと、RBS の Rust crate の利便性を高めたいですね。自分の gem で RBS のロードを Rust crate から行いたいなと思っています。また、廊下での会話の流れもあって、高速化にも気持ちが出てきています。登壇を経て、自分の中の「次にやること」のリストが、行く前より大きくなっています。 終わりに 今年の Kaigi も最高でした。運営の方々、本当に素敵な機会をありがとうございました。いろんな方と知り合えましたし、思考を深められました。ぼんやりと次にやりたいことが見えてきました。 次の RubyKaigi は宮崎 ですね。次も楽しんで行きましょう!(帰りに青森、秋田に旅行したんですが、それ含め諸々個人ブログで感情を書こうと思います)
はじめに はじめまして、プラットフォームエンジニアリング本部に所属している徳富( @yannKazu1 )です。 みなさん、サプライチェーン攻撃って気にしてますか? npm パッケージの乗っ取り( ua-parser-js 事件 )、GitHub Actions の改ざん( tj-actions/changed-files 事件 )、依存パッケージへのバックドア混入( xz-utils 事件 )……。ここ数年、OSS を取り巻くセキュリティの前提がガラッと変わってきています。正直、「いつ・どこから仕掛けられるかわからない」状況です。 しかもサプライチェーン攻撃って、攻撃側のコストが低いわりに被害範囲が広いのが厄介なんですよね。 そんなわけで、ECS Fargate 環境におけるサプライチェーン攻撃対策を整理してみようと思ったのですが、いきなり全部を洗い出そうとしてもカオスになるだけ。何かいいフレームワークはないかな……と探していたところ、Kubernetes の 4C セキュリティモデル(Cloud → Cluster → Container → Code) の考え方がそのまま使えそうだったので、これをベースにチェックシート的に整理してみました。 「うちの環境だとどこが手薄いんだろう?」を考えるときの参考にしてもらえればと思います。 おことわり: これをやれば完璧!というものではないです。あくまで「見通しよく整理するための道具」として 4C モデルを借りているだけなので、実際にどこまでやるかは環境やリスク許容度に応じて取捨選択してください。 整理に使う 2 つの軸 軸 1:4C セキュリティモデル —「どこを守るか」 Kubernetes の公式ドキュメントで紹介されている、クラウドネイティブセキュリティを 4 つの同心円レイヤー で捉えるモデルです。 参考: クラウドネイティブセキュリティの概要 | Kubernetes ┌─────────────────────────────────────────┐ │ Cloud(クラウド基盤) │ │ ┌─────────────────────────────────────┐ │ │ │ Cluster(オーケストレーター) │ │ │ │ ┌─────────────────────────────────┐ │ │ │ │ │ Container(コンテナランタイム) │ │ │ │ │ │ ┌─────────────────────────────┐ │ │ │ │ │ │ │ Code(アプリケーション) │ │ │ │ │ │ │ └─────────────────────────────┘ │ │ │ │ │ └─────────────────────────────────┘ │ │ │ └─────────────────────────────────────┘ │ └─────────────────────────────────────────┘ ポイントは 各レイヤーが外側のレイヤーの上に構築されている ということ。どれだけアプリのコードを堅牢にしても、基盤レイヤーのセキュリティが低い水準では守りきれません。だからこそ、特定のレイヤーだけに頼るのではなく、すべてのレイヤーを固める 多層防御(Defense in Depth) が基本方針になります。 ECS Fargate への読み替えはこんな感じです。 4C レイヤー K8s での意味 ECS Fargate での対応 サプライチェーン攻撃での主な攻撃面 Cloud クラウド基盤 AWS アカウント・IAM・ネットワーク IAM キー漏洩、ECR への不正 push Cluster オーケストレーター ECS クラスター・CI/CD パイプライン CI/CD アクションの改ざん、パイプライン侵入 Container コンテナランタイム Docker イメージ・Fargate タスク ベースイメージの汚染、OS パッケージへのバックドア混入、実行時の不正プロセス Code アプリケーションコード ソースコード・依存パッケージ パッケージ乗っ取り、typosquatting、悪意ある PR 軸 2:対策の目的 —「何のために守るか」 4C モデルは「どこを守るか」を整理するフレームワークですが、それだけだと対策が偏りがちです。そこでもうひとつ、 「何のために守るか」 という軸を加えてみます。今回は、セキュリティ対策を以下の 4 つの目的に分類して整理してみました。 目的 説明 考え方 🛡 予防(Prevention) 攻撃を未然に防ぐ そもそも悪いものを入れさせない 🔍 検知(Detection) 攻撃や脆弱性を発見する 入り込んだ・紛れ込んだことに気づく 🧱 封じ込め(Containment) 侵入後の被害を最小化する やられても被害を広げさせない 🔎 調査(Investigation) 何が起きたかを追跡する 事後に原因と影響範囲を特定する よくある落とし穴は 「予防」ばかりに意識が向いて、他が手薄になる こと。完璧な予防は不可能なので、入り込まれた後にどう気づいて・どう被害を抑えて・どう調べるか、まで含めて考えるのが多層防御の本質です。 この記事の構成 本記事では 目的(予防・検知・封じ込め・調査)を大項目 にして、それぞれの中で 4C のどのレイヤーに対する対策か を整理していきます。 🛡 予防(Prevention)— そもそも入れさせない 攻撃を未然に防ぐための対策です。「入口を塞ぐ」イメージですね。 Cloud:VPC Endpoint 概要: AWS サービスへの通信をインターネットを経由せずに VPC 内で完結させる。 防げる攻撃: 侵害されたタスクからの外部 AWS アカウントへのデータ持ち出し (Endpoint Policy で自社アカウントに限定) マルウェア感染後の C2 通信・情報送信 (Egress 全遮断下でも AWS サービスは利用可能) 漏洩した IAM 認証情報による外部からの不正アクセス (バケットポリシーで aws:SourceVpce を指定) 設定のポイント: S3 Gateway Endpoint(無料)は必須 ECR、SSM、Secrets Manager、CloudWatch Logs 用の Interface Endpoint を検討 Endpoint Policy で aws:PrincipalAccount を制限 リソース側ポリシーで aws:SourceVpce を指定 Cluster:CI/CD パイプラインのハードニング 概要: GitHub Actions など CI/CD で使うサードパーティアクションを、改ざんされない形で固定する。 防げる攻撃: GitHub Actions の改ざん (tj-actions/changed-files 事件のように、人気アクションのリポジトリが侵害されてタグが書き換えられるケース) バージョンタグの上書きによる 意図しないコードの実行 設定のポイント: GitHub Actions は通常 uses: actions/checkout@v4 のようにタグやブランチで指定しますが、これらは 後から書き換え可能 です。tj-actions/changed-files 事件(2025 年 3 月)では、攻撃者がメンテナーの認証情報を侵害し、既存タグを悪意あるコミットに向け直すことで、汚染されたアクションを使う CI でシークレットがビルドログに書き出されるという被害が広範囲に発生しました。一方、 commit SHA でピンニングしていたユーザーは影響を受けませんでした (侵害期間中に対象 SHA へ更新していなければ)。 対策として、 commit SHA でピンニングする のが推奨されます。 # Before(タグ指定 - 書き換えられる可能性あり) - uses : actions/checkout@v4 # After(commit SHA でピンニング - 改ざんされない) - uses : actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 Dependabot や Renovate Bot で SHA の自動更新を設定 permissions: で各ジョブの GITHUB_TOKEN 権限を最小化 OIDC を使った AWS 認証に切り替え、長期クレデンシャルを廃止 パブリックリポジトリでは特に注意:ビルドログが公開されるため、ログ経由のシークレット漏洩のインパクトが大きい サプライチェーン攻撃との関連: これは Container レイヤーの digest ピンニングと同じ思想です。「同じ名前で違うものを掴まされる」攻撃を防ぐには、暗号学的なハッシュで内容を固定するのが基本になります。 Cluster:Secrets の安全な注入 概要: DB パスワードや API キー等の機密情報を、コードへの直書きではなく SSM Parameter Store や Secrets Manager から注入する。 防げる攻撃: ソースコードやコンテナイメージへのシークレット埋め込み を防止 Git リポジトリの漏洩時に クレデンシャルが直接露出するリスク を排除 KMS 暗号化により、AWS アカウントが侵害されても 暗号化キーなしでは復号不可能 設定のポイント: " secrets ": [ { " name ": " DATABASE_PASSWORD ", " valueFrom ": " /fargate/myapp/database-password " } ] Cluster:ECS Exec の制御 概要: ECS Exec(コンテナへの対話的アクセス)を必要時以外は無効化する。 防げる攻撃: IAM クレデンシャルが漏洩した場合の コンテナへの直接侵入 本番コンテナへの 不正なコマンド実行 設定のポイント: ECS Exec の制御は、サービス (または RunTask 呼び出し)レベル と IAM レベル の二重で行うのが確実です。 enableExecuteCommand はタスク定義のフィールドではなく、サービス(CreateService / UpdateService)または RunTask のパラメータです。 サービス定義(または RunTask 呼び出し)で無効化 : enableExecuteCommand = false を明示。そもそもサービス側で受け付けない状態にしておく。AWS CLI でも aws ecs update-service --no-enable-execute-command のように切り替え可能です。 IAM で ecs:ExecuteCommand を Deny :ECS Exec 専用の API なので、これを Deny するのが最も直接的。なお ECS Exec は内部的に SSM Session Manager の通信レイヤー(ssmmessages API)を利用するため、より厳密に制御したい場合は、タスクロールに ssmmessages:* 系の権限が紛れ込んでいないかも確認する 必要時のみ一時的に有効化する運用フロー :踏み台用の専用サービスを別途用意し、調査時のみそちらを起動する運用が安全。 補足: 後述の封じ込めセクションで紹介する readonlyRootFilesystem: true と ECS Exec は 両立しない 点に注意してください。SSM agent がコンテナファイルシステムへの書き込みを必要とするため、ルートファイルシステムを読み取り専用にすると ECS Exec が動きません(AWS 公式ドキュメントでも明記されています)。本番では readonlyRootFilesystem: true + ECS Exec 無効化、調査用の踏み台サービスでは ECS Exec 有効化、と用途で使い分けるのが現実的です。 Container:ベースイメージの digest ピンニング 概要: Dockerfile のベースイメージ指定を、タグだけでなく digest(SHA256 ハッシュ)で固定する。 防げる攻撃: ベースイメージのタグ上書き攻撃 (同一タグに悪意あるイメージを push) レジストリが侵害された場合の イメージ改ざんの検知 設定例: # Before(タグのみ) FROM ruby:3.3.0-bookworm # After(digest ピンニング) FROM ruby:3.3.0-bookworm@sha256:2e1e76e5b2... 運用のポイント: Dependabot や Renovate Bot で digest の自動更新を設定する digest がまだ付いていないイメージに digest を自動付与する pinning 自体は、現時点では Renovate のほうが運用面で先行 ( pinDigests プリセット)。Dependabot 側でも 2026 年 2 月に PR #14071 が dependabot-core 本体にマージされ、 docker_pin_digests という experiment flag として実装されました。ただし experiment flag は Dependabot サービス側で段階的に展開されるため、GitHub.com の Dependabot で「タグだけのイメージに digest を新規付与する挙動」がデフォルトで使えるかはタイミング次第です(フラグの有効化状況によっては自分の環境で効かないこともある点に注意)。 現時点で「すでに digest 付き」のイメージに対する digest 更新は Dependabot でも問題なくできます。タグだけで運用しているイメージを一括で digest ピン化したい、もしくは version と digest の同時更新・グルーピングや自動マージ条件など細かい制御をしたい場合は、Renovate を選ぶのが堅実です。 サプライチェーン攻撃との関連: Docker Hub のアカウントが侵害されて、同一タグに悪意あるイメージが push されることがあります。digest ピンニングをしておけば、たとえタグが上書きされても意図しないイメージを引っ張ってくることがなくなります。 Container:ECR イミュータブルタグ 概要: ECR リポジトリのタグを上書き不可(IMMUTABLE)に設定する。サプライチェーン攻撃対策の観点では 基本的に有効化しておくべき 設定です。 防げる攻撃: 既存タグへの 悪意あるイメージの上書き CI/CD パイプラインが侵害された際の イメージ差し替え 設定のポイント: ECR のタグ mutability 設定は、 2025 年 7 月 23 日のアップデート で以下の 4 モードに拡張されました。 モード 挙動 MUTABLE すべてのタグを上書き可(従来) IMMUTABLE すべてのタグを上書き不可(従来) MUTABLE_WITH_EXCLUSION デフォルト mutable、特定タグのみ immutable IMMUTABLE_WITH_EXCLUSION デフォルト immutable、特定タグ(例: latest )のみ mutable これにより、たとえば「 本番用の v1.2.3 のようなセマンティックタグや git SHA タグは IMMUTABLE で固めつつ、 latest だけは上書き可能にしておきたい 」という現実的な要件にも対応できるようになりました。 IMMUTABLE 化(または IMMUTABLE_WITH_EXCLUSION )すると同じタグでの再 push ができなくなるため、デプロイフローを以下のいずれかに合わせる必要があります。 タグを毎回ユニークにする : repo:v1.0.1 、 repo:gitsha-abc1234 のように、デプロイのたびに別タグを振る。既存のタグベースのデプロイフローを大きく変えずに済むので導入しやすい。 digest ベースのデプロイに移行する :ecspresso 等で image: repo:tag → image: repo@sha256:xxxxx に変更。改ざん検知の観点でもより堅牢で、究極的にはこちらが望ましい。 IMMUTABLE_WITH_EXCLUSION を活用する : latest のような可変運用が必要なタグだけを除外し、それ以外のタグは IMMUTABLE で固める。 まずは (1) のタグユニーク化で IMMUTABLE 化(必要に応じて (3) で latest を除外) から始めて、余裕があれば (2) の digest ベースに進化させていく、というステップ方式が現実的です。 注意: 現在 MUTABLE で運用している場合、デプロイ失敗時のイメージ再 push に依存していないか事前に確認してください。CI のリトライ等でタグの上書きが発生する構成だと、IMMUTABLE 化で詰まります。 Container:イメージ署名(AWS Signer / ECR Managed Signing) 概要: CI でビルドしたイメージに暗号署名を付与し、デプロイ時に署名を検証する。 防げる攻撃: ECR リポジトリが侵害された場合の 未署名イメージのデプロイ CI パイプラインをバイパスした 不正なイメージの注入 「CI でビルドされたイメージと本番で動くイメージが同一である」ことの 暗号学的な保証 実現方法: ECS には EKS の admission controller のような署名検証機構が長らくネイティブには用意されていませんでしたが、近年は AWS 側でも仕組みが整ってきています。代表的なパターンは以下の通り。 (1) 署名フェーズ : (a) Amazon ECR Managed Signing を使う(2025 年 11 月 21 日 GA、AWS の推奨アプローチ) :ECR にシグニングルールを登録しておくと、push 時に ECR が AWS Signer を呼んで自動で署名してくれる。クライアント側に Notation を入れる必要がなく、署名キーやその証明書ライフサイクルも AWS が完全マネージドで管理する。新規導入ならまずこちらを検討するのが筋。 (b) 自前で notation sign を実行(manual signing) :CI のビルドステップでイメージ push 後に Notation CLI + AWS Signer プラグインで署名する。署名タイミングや対象を細かく制御したい場合に選択。プラットフォーム ID は Notation-OCI-SHA384-ECDSA 。 いずれの場合も 署名キー自体は AWS Signer が完全マネージドで管理するため、利用者が KMS キー等を別途用意する必要はありません 。 (2) 検証フェーズ : (a) ECS Service Lifecycle Hook(PRE_SCALE_UP)で Lambda を呼び、 notation verify を実行 :ECS のサービスデプロイ時にイメージ署名を検証し、失敗時はデプロイをブロックできる。 現在 AWS が公開している ECS 向け公式パターンであり、 BLOCK_ON_FAILURE (厳格モード)と LOG_ON_FAILURE (監査のみモード)の両方をサポート 。 2025 年 7 月 18 日の ECS ネイティブ Blue/Green デプロイメント GA 以降、PRE_SCALE_UP hook は rolling update 戦略でも利用可能 (rolling update で使えるのは PRE_SCALE_UP のみで、それ以外の hook は Blue/Green 専用)。 (b) EventBridge → Lambda で push 直後に検証 :監査・アラート用途。Lifecycle Hook と違ってデプロイ自体はブロックできない非同期パターン。 (c) CodePipeline / CI のデプロイ前ステップで notation verify を実行 :パイプラインの中でブロックする方式。 注意: ECR イミュータブルタグと組み合わせると効果が高まります(タグの差し替え + 署名なしイメージのデプロイの両方を防げる)。Lifecycle Hook ベースの検証はデプロイをブロックできるため、本気の防御として AWS が現在推奨している実装パターンです。実装工数はそれなりにかかるので、リスク許容度と相談して導入判断するのがよいでしょう。まずは EventBridge 経由のアラート運用(監査)から始めて、本格運用で Lifecycle Hook に移行する、というステップでも問題ありません。 EKS との対比(参考): EKS の場合は Kubernetes admission controller(Kyverno、OPA Gatekeeper、Connaisseur 等)を使って、Pod 起動前に署名を検証するのが定石です。ECS Service Lifecycle Hook はこれに相当する仕組みを ECS 側で提供する位置づけと考えると理解しやすいです。 🔍 検知(Detection)— 入り込んだことに気づく 予防を突破された場合に、異常や脆弱性を発見するための対策です。 Cloud:GuardDuty + ECS Runtime Monitoring 概要: AWS 環境全体の脅威検知サービス。ECS Runtime Monitoring を有効にすると、Fargate タスク内の不審な振る舞いをリアルタイムで検知できる(ECS Fargate 向けは re:Invent 2023 で一般提供開始)。 防げる攻撃: コンテナ内での クリプトマイニングプロセスの実行 C2(Command & Control)サーバーへの通信 コンテナ内での リバースシェルの起動 既知のマルウェアバイナリの実行 設定のポイント: Fargate の場合、セキュリティエージェントは GuardDuty が自動でサイドカーとしてデプロイするため、タスク定義の変更は不要 Organizations の委任管理者から一括有効化が可能 サプライチェーン攻撃との関連: 汚染された npm パッケージや gem が実行時にこっそりマイニングスクリプトを起動したり、バックドアが C2 サーバーに接続したり……といったケースをリアルタイムで検知してくれます。「入り込まれた後」の最後の砦ですね。 Cloud:Security Hub(セキュリティポスチャ管理) 概要: AWS Foundational Security Best Practices (FSBP) などのセキュリティ標準に基づき、設定の逸脱を検出する。 防げる攻撃: セキュリティグループの過剰な公開、暗号化の欠如など、 設定ミスに起因する攻撃面の拡大 を防止 Inspector や GuardDuty の検出結果を一元的に集約し、 見逃しを減らす Container:イメージスキャン(CI + ECR Enhanced Scanning) 概要: コンテナイメージに含まれる脆弱性を、CI のビルド時とレジストリの両方でスキャンする。サプライチェーン攻撃対策の観点では OS パッケージレイヤーへの攻撃(xz-utils 事件のような)を捕まえるための要 となる対策です。 防げる攻撃: 既知の脆弱性を持つ OS パッケージ・言語ライブラリ がプロダクションに到達するのを検知 xz-utils 事件のように OS パッケージレベルでバックドアが混入したケース (CVE 公開後)を検知 アプリ側の依存パッケージマネージャー(Bundler / npm 等)では拾えない、 OS レイヤーの脆弱性 をカバー サプライチェーン防御の基本は 複数のポイントでチェックする ことです。CI でのビルド時スキャンとレジストリでの継続スキャンを組み合わせて、異なるタイミングで網をかけるのが効果的です。 CI ビルド時スキャン → レジストリスキャン(継続) → ランタイム監視 (Trivy / Inspector 等) (ECR Enhanced Scanning) (GuardDuty) デプロイ前にブロック 新規 CVE も自動で再スキャン 実行時の異常検知 CI でのスキャン 代表的なアプローチは大きく 2 系統あります。 (a) OSS スキャナ(Trivy / Grype 等) docker build 後にスキャンを実行し、脆弱性が閾値を超えたらデプロイをブロック セットアップが軽く、外部 API への依存もないので導入ハードルが低い Dockerfile の Linting(hadolint 等)も合わせて入れると効果的 (b) Amazon Inspector SBOM Generator (sbomgen) + Inspector Scan API AWS 公式アプローチ。 sbomgen でイメージから CycloneDX 形式の SBOM を生成し、Inspector Scan API に投げて脆弱性スキャンを実行 GitHub Actions なら AWS 公式の aws-actions/vulnerability-scan-github-action-for-amazon-inspector が使える。SBOM 生成からスキャン、結果のサマリー表示までワンステップで完結 Jenkins 用のプラグインも公式提供あり Inspector を既に有効化している環境なら、ECR Enhanced Scanning と 同じ脆弱性データベース・同じ判定基準 で CI 段階から検査できるのがメリット 生成された SBOM をアーティファクトとして保存しておけば、調査セクションで触れる SBOM 管理にもそのまま流用可能 CI で push 前に止められる のがこのレイヤーの最大の価値(シフトレフト)です。AWS 中心の構成なら (b) が一気通貫で扱いやすく、ツール選択の自由度を取りたいなら (a) という選び方になります。 ECR Enhanced Scanning(Inspector 統合) ECR push 時 + 新規 CVE 公開時に自動で再スキャン( CONTINUOUS_SCAN ) OS パッケージに加えて言語ライブラリも対象 Security Hub にネイティブ統合されるため、検出結果を一元管理できる Basic Scan Enhanced Scan (Inspector) 対象 OS パッケージのみ OS パッケージ + 言語ライブラリ(gem, npm, pip 等) スキャン頻度 push 時のみ push 時 + 新規 CVE 公開時(CONTINUOUS_SCAN) Security Hub 統合 なし あり 組織一括管理 なし あり(Organizations 委任管理者から) xz-utils 事件との関連: xz-utilsのような OS パッケージレベルのバックドアは、アプリケーションの依存パッケージマネージャー(Bundler / npm)レベルの SCA では検知できません。 コンテナイメージスキャンの OS パッケージレイヤー で拾うのが正しい守備範囲です。なお、xz-utils のバックドアはビルドプロセス中に難読化されたペイロードを段階的に展開する極めて巧妙な手口で、CVE 公開「前」の検知は実質的に困難でした。だからこそ、CVE 公開後にどれだけ早く対応できるかが勝負になります( CONTINUOUS_SCAN のような新規 CVE への自動再スキャンが効いてくるのはこのため)。 Code:SCA(ソフトウェア構成分析) 概要: アプリケーションが依存するパッケージ(Bundler の gem、npm のパッケージ等)の既知脆弱性および悪意あるバージョンへの依存を検出し、更新を促す。 アプリケーション依存パッケージレイヤーのサプライチェーン攻撃対策の中核 となる対策です。 防げる攻撃: 既知の脆弱性を持つアプリ依存パッケージ への依存を早期発見 パッケージの乗っ取り (ua-parser-js 事件、event-stream 事件のような)で注入された悪意あるバージョンへの自動更新を抑止 typosquatting (正規パッケージに似た名前の悪意あるパッケージ)への気づき ツール例: Dependabot(GitHub ネイティブ、Bundler / npm / Docker 対応) Renovate Bot(digest ピン対応、細かい設定が可能) GitHub Advanced Security の Dependency Review 設定のポイント: パッケージマネージャー(Bundler、npm)と GitHub Actions の両方を対象に daily または weekly でスキャン versioning-strategy の設定で意図しないメジャーバージョンアップを防止(npm なら lockfile-only 、Bundler なら lockfile-only 相当の制約をかける) 更新を即座に取り込まない :新バージョンに悪意が混入していた場合に備え、リリースから一定期間(例:3〜7 日)寝かせてからマージするポリシーも検討に値する 守備範囲の整理: SCA は アプリの依存パッケージマネージャー(Bundler / npm 等)の領域 が対象です。OS パッケージ(apt / yum / apk)レベルの脆弱性は SCA ではなく、前述のコンテナイメージスキャンが守備範囲になります。 ua-parser-js のような npm パッケージ乗っ取りは SCA、xz-utils のような OS パッケージへのバックドア混入はイメージスキャン、と分けて考えるとスッキリします。 Code:SAST(静的アプリケーションセキュリティテスト) 概要: ソースコードを静的に解析し、セキュリティ上の問題を検出する。 位置づけの注意: SAST はサプライチェーン攻撃そのものへの直接対策ではなく、 自前コードの脆弱性検出ツール です。ただし、攻撃者が悪意ある PR を送り込んできた場合(社外コントリビューターからの PR や、内部アカウントが乗っ取られた場合)に、危険なコードパターンを検出できる可能性があります。多層防御の一環として位置づけてください。 防げる攻撃: SQL インジェクション、XSS、CSRF 等の コーディングレベルの脆弱性 フレームワーク固有の危険なパターン(Rails なら Brakeman、Node.js なら ESLint Security Plugin 等) 悪意ある PR に含まれる 明らかに怪しいコードパターン 設定のポイント: CI で全 PR に対して実行し、マージ前に検出 言語・フレームワーク固有のツールを選定 🧱 封じ込め(Containment)— やられても被害を広げさせない 予防も検知もすり抜けて侵入された場合に、被害の範囲を最小限にするための対策です。「入られた前提」で考えるのがポイント。 Cloud:ネットワーク制御(Egress 制限) 概要: コンテナからのアウトバウンド通信を必要最小限に制限する。侵害が起きた後にデータ持ち出しや C2 通信を成立させにくくする、封じ込めとしての効果が大きい。 防げる攻撃: ランタイム侵害後の C2 サーバーへの通信をネットワークレベルで遮断 悪意あるパッケージや侵害されたコンテナによる外部へのデータ送信をブロック xz-utils 事件のようなバックドアが仮にコンテナ内に入り込んでも、外部との通信路を断つことで攻撃者の活動を阻害 設定のポイント: AWS Network Firewall:FQDN ベースのアウトバウンド許可リスト方式で必要なドメインのみ通す Route 53 DNS Firewall:悪意あるドメインへの DNS クエリをブロック Security Group:NAT Gateway 経由のアウトバウンドを最小化し、不要なポート・宛先を塞ぐ Cluster:IAM ロール分離(タスクロール / 実行ロール) 概要: ECS の実行ロール(ECR pull、ログ出力等)とタスクロール(アプリケーションが使う権限)を分離する。最小権限の原則そのものなので予防の性質も持ちますが、真価を発揮するのは侵害が起きた後—— 横移動の範囲を制限する封じ込めとしての効果が大きい ため、ここで扱います。 防げる攻撃: アプリケーションが侵害された場合でも、 ECR へのイメージ push や他タスクへの影響を防止 権限の最小化により、 ラテラルムーブメント(横移動)の範囲を制限 設定のポイント: 実行ロール :ECR pull、CloudWatch Logs、SSM パラメータ取得のみ タスクロール :アプリケーションが実際に必要とする権限のみ ssm:GetParameters の Resource は ではなくパラメータパス(例: /fargate/myapp/* )で制限 タスクロールに ecr:PutImage 等の書き込み権限が紛れ込んでいないか定期確認 Container:コンテナハードニング コンテナが侵害された後の被害を最小限にするための設定群です。まさに「封じ込め」の代表格。 readonlyRootFilesystem 概要: コンテナのルートファイルシステムを読み取り専用にする。 防げる攻撃: コンテナ侵害時の マルウェアのファイルシステムへの書き込み・永続化 攻撃ツールの 追加ダウンロードと配置 Web シェルの設置 設定例: { " containerDefinitions ": [ { " name ": " app ", " readonlyRootFilesystem ": true , " mountPoints ": [ { " sourceVolume ": " tmp ", " containerPath ": " /tmp " } , { " sourceVolume ": " app-tmp ", " containerPath ": " /app/tmp " } ] } ] , " volumes ": [ { " name ": " tmp " } , { " name ": " app-tmp " } ] } 注意 1: アプリケーションによっては /tmp や /app/tmp 、 /app/log 等への書き込みが必要です。tmpfs ボリュームをマウントして書き込み先を確保してください。 注意 2: readonlyRootFilesystem: true は ECS Exec と両立しません 。SSM agent がコンテナファイルシステムへの書き込みを必要とするためです( AWS 公式ドキュメント で明記)。本番タスクは readonlyRootFilesystem: true + ECS Exec 無効化、調査用の踏み台サービスは readonlyRootFilesystem: false + ECS Exec 有効化、と用途で分けるのが現実的です。 Linux capabilities の DROP ALL 概要: コンテナに付与される Linux capabilities をすべて削除する。 防げる攻撃: コンテナ内からの 不要な特権操作 を制限 権限昇格(setuid バイナリ経由、カーネル脆弱性等)を試みた際の 被害を抑制 USER ディレクティブが何らかの理由で無視・上書きされた場合の 保険 設定例: { " linuxParameters ": { " initProcessEnabled ": true , " capabilities ": { " drop ": [ " ALL " ] } } } 補足: Fargate では元々 capability の add は不可でしたが、プラットフォームバージョン 1.4.0 以降、 SYS_PTRACE の 1 つだけは追加可能 になりました(Sysdig Falco のような観測ツール用途のために 2020 年に解禁された経緯がある)。一方、 drop は問題なく可能 です。EC2 launch type ではすべての capability が利用できますが、Fargate で add できるのは依然として SYS_PTRACE のみという制約があります。非 root で実行していれば実質的な効果は限定的ですが、多層防御(Defense in Depth)の観点から「保険として入れておく」温度感で設定しておくと安心です。 非 root 実行 概要: コンテナプロセスを root 以外のユーザーで実行する。 防げる攻撃: コンテナ侵害時の ホストへのエスケープリスクを低減 ファイルシステムやプロセスへの不正操作の範囲を制限 設定方法: Dockerfile で USER app:1000 のように非 root ユーザーを指定 サイドカー(fluent-bit 等)も可能な限り非 root 化 🔎 調査(Investigation)— 何が起きたかを追える状態にする インシデントが起きた後に「何が起きたか」「影響範囲はどこまでか」を追跡するための対策です。地味ですが、ここが抜けていると事後対応でめちゃくちゃ苦労します。 Cloud:CloudTrail(監査ログ) 概要: AWS API コールの監査ログを記録・保全する。 防げる攻撃・実現できること: IAM クレデンシャルが漏洩した場合の 事後調査(フォレンジック) が可能になる 「誰が・いつ・どの API を叩いたか」を追跡でき、不正な ECR push や IAM 変更を特定できる ECS のコントロールプレーン操作(クラスター / タスク定義 / サービスの作成・更新・削除など)も AWS API コール経由で行われるため CloudTrail でカバーされる 。Cluster 層で「誰が悪意あるタスク定義を登録したか」「サービスが書き換えられたのはいつか」を追えるのはここ S3 Object Lock でログの改ざん・削除を防止 CloudTrail ログファイルの整合性の検証(CloudTrail log file integrity validation)でログ自体が改ざん・削除されていないことを事後検証できる 。CloudTrail が 1 時間ごとに、その間に配信されたログファイルのハッシュを含むダイジェストファイルを RSA で署名して S3 に配置するので、 aws cloudtrail validate-logs で「保管されているログが配信時のものと一致するか」を検証できる 設定のポイント: 組織トレイルでマルチリージョン・全管理イベントを記録 S3 Object Lock(GOVERNANCE モード以上)でログの不変性を担保 ログファイルの検証(Log file validation)を有効化 (コンソール作成時のオプション、CLI なら --enable-log-file-validation )。S3 Object Lock が「改ざんさせない」予防策、ログファイルの整合性の検証が「改ざんされていないことを示す」検出策で、両方揃えると証跡としての信頼性が一段上がる Advanced Event Selectors で S3 データイベントも記録 サプライチェーン攻撃との関連: たとえば攻撃者が CI/CD の認証情報を奪って ECR にイメージを push した場合、CloudTrail がなければ「いつ・どのアカウントから push されたか」すら追えません。同様に、奪った認証情報で RegisterTaskDefinition や UpdateService を叩かれた場合も、CloudTrail があれば Cluster 層での改ざんを追跡できます。防御だけでなく「何が起きたか調べられる状態にしておく」のも大事です。 Cloud:VPC フローログ / DNS クエリログ(ネットワークレベルの追跡) 概要: VPC 内の通信メタデータと DNS 名前解決を記録し、「どこから・どこへ・何が通信したか」を追跡可能にする。 実現できること: 侵害されたタスクが どこに通信していたか (C2 サーバー、不審な外部エンドポイント、想定外の内部リソース)を特定できる VPC フローログは ECS タスクの ENI 単位で取得可能で、 タスクごとの通信を追跡 できる( ECS 向けの VPC フローログ機能 ) VPC フローログと Route 53 Resolver クエリログを組み合わせて分析することで、「いつ・どのドメインに対して通信したか」まで踏み込んだ調査ができる 。フローログ単体だと宛先 IP しか分からず、CDN やクラウドサービス相手だと「結局どこと話していたのか」が判然としない。クエリログで名前解決の履歴を突き合わせることで、IP → ドメインのマッピングが復元でき、不審な通信先の正体を特定しやすくなる マルウェアが DGA(ドメイン生成アルゴリズム)で生成したドメインへ問い合わせた痕跡など、フローログだけでは見えない挙動も DNS クエリログ側で捕捉できる 設定のポイント: VPC フローログは S3 / CloudWatch Logs に出力。長期保管なら S3 + Object Lock カスタムフォーマットで pkt-srcaddr / pkt-dstaddr を含めると、NAT 越しでも実際の送信元・宛先が分かる Route 53 Resolver クエリログを VPC に紐づけておけば、タスクからの DNS 問い合わせも記録される サプライチェーン攻撃との関連: 悪意ある依存パッケージが侵入した場合、最終的に外部 C2 への通信を試みるケースが多いです。CloudTrail は API コールの記録なので、こうした データプレーン上の通信 までは追えません。VPC フローログ + DNS クエリログを揃えて組み合わせ分析できる状態にしておけば、「侵害されたタスクがどのドメインを名前解決し、その IP に対して実際にどれだけのトラフィックを流したか」まで一連の流れで再構成でき、情報流出先や C2 ドメインの特定が一気に現実的になります。 Code:SBOM(ソフトウェア部品表) 概要: アプリケーションが依存するすべてのパッケージとそのバージョンを一覧化する。 実現できること: インシデント発生時に 「何のバージョンの何が動いていたか」 を即座に特定 新たな CVE が公開された際に 影響範囲を迅速に判断 xz-utils 事件のように 依存関係に紛れ込んだバックドア が後から発覚した場合の影響調査を効率化 実現方法: CI 段階で sbomgen を使う:検知セクションで触れた aws-actions/vulnerability-scan-github-action-for-amazon-inspector 等は、副産物として CycloneDX 形式の SBOM を出力する。脆弱性スキャンと SBOM 保存が同時にできるので一石二鳥 Amazon Inspector の SBOM エクスポート機能 を使うと、Inspector でスキャン済みのリソース(ECR イメージ等)の SBOM を CycloneDX または SPDX 形式で S3 にエクスポート できる。リアルタイム生成ではなく一括エクスポート方式なので、定期実行ジョブとして仕込んでおくのが現実的 いずれの場合も、イメージのバージョン(できれば digest)と SBOM を紐づけて保管 しておくのがポイント。インシデント時に「あの時動いていたバージョン」の SBOM をすぐ参照できるようにする サプライチェーン攻撃との関連: 「うちで動いてるイメージに xz-utils の脆弱バージョンって入ってたっけ?」を即答できる状態を作っておく、というのが SBOM の本質です。インシデント時に手作業で全イメージを掘り返すのは現実的ではないので、平時から仕組み化しておきましょう。SBOM は OS パッケージとアプリ依存パッケージの両方をカバーするため、「SCA で見える範囲」と「イメージスキャンで見える範囲」を横断して影響調査できる のが強みです まとめ 正直、セキュリティ対策って「どこまでやればいいの?」が永遠の問いだと思うんですが、まずはこのマトリクスで現状を棚卸しして「ここが手薄いな」と見えるようにするだけでも一歩前進です。 この記事が、ECS Fargate 環境のサプライチェーン攻撃対策を考える際のチェックシートとして使ってもらえれば嬉しいです。 参考資料 クラウドネイティブセキュリティの概要 | Kubernetes Amazon GuardDuty ECS Runtime Monitoring Amazon Inspector ECR scanning Amazon Inspector SBOM Generator (sbomgen) Integrating Amazon Inspector scans into your CI/CD pipeline aws-actions/vulnerability-scan-github-action-for-amazon-inspector Amazon Inspector SBOM export AWS Signer for container images Streamline container image signatures with Amazon ECR managed signing Amazon ECR now supports managed container image signing (2025-11-21) Extending deployment pipelines with Amazon ECS blue green deployments and lifecycle hooks Container image signing and verification using AWS Signer for Amazon ECS and AWS Fargate Amazon ECR now supports exceptions to tag immutability (2025-07-23) Preventing image tags from being overwritten in Amazon ECR ECS タスク定義 - linuxParameters KernelCapabilities - Amazon ECS Fargate security best practices in Amazon ECS Monitor Amazon ECS containers with ECS Exec (readonlyRootFilesystem との非互換について) Security hardening for GitHub Actions GHSA-mrrh-fwg8-r2c3: tj-actions/changed-files supply chain compromise CISA: Supply Chain Compromise of Third-Party tj-actions/changed-files (CVE-2025-30066) and reviewdog/action-setup (CVE-2025-30154) CVE-2024-3094: XZ Utils Backdoor Renovate Docker Presets Dependabot: Add digest pinning when updating Docker image tags (#14065 / PR #14071, 2026-02-04 マージ済み)
はじめに タイミーでは、世界中で開催される技術系カンファレンスに無制限で参加できる「Kaigi Pass」という制度を活用し、8名がRubyKaigi 2026 in 函館に現地参加しました。 また今年はDay2に、タイミーから @ dak2 さんが "No Types Needed, Just Callable Method Check" というタイトルで登壇しました。 本レポートでは、参加したエンジニアが注目したセッションごとに、ポイントや得た知見をまとめてご紹介します。 各セッションごとに内容を整理し、参加者自身の視点から学びや気づきをまとめています。読者の皆様にとって、今後の学びの参考になれば幸いです。 Surviving Black Friday: 329 billion requests with Falcon! rubykaigi.org Shopify社のSamuel Williamsさん、Marc-André Cournoyerさん、Josh TeeterさんがFalconを導入することでブラックフライデー・サイバーマンデー(BFCM)期間の合計3,290億リクエストを乗り切ったお話でした。 自身は普段Webのバックエンドエンジニアとしてユーザートラフィックのパフォーマンス課題について関心を持っており、その流れでFalconや基礎技術のAsyncにも興味を持っていました。 Falconの開発者であるSamuelさんから、本番稼働中の高トラフィックなプロダクトにFalconを導入する際のコストや注意点、そして得られる効果を聞けると期待して、このセッションを聴講しました。 前提として、FalconとはAsyncベースのRack互換Webサーバーです。 AsyncとはRubyの軽量スレッドであるFiberを利用した非同期I/Oフレームワーク(ノンブロッキングI/O)です。 github.com Falconは単一プロセスの中で複数のHTTPリクエストに対応するFiberを割り当てます。 FiberでI/Oが発生すると、処理を別のFiberに移すことで、大量のリクエストの処理を実現します。 OSネイティブのプロセスやスレッドではなく、Fiberで並行処理を実現するためメモリ効率が良く、PumaやUnicornと比較してランニングコストが低いという特徴があります。 セッションではFalconのアーキテクチャの解説と導入に伴う段階的なスケールテストを通して多くの課題を解決していった様子を発表されていました。 取り組みの結果、従前のUnicornよりもスループット・コアあたりのリクエスト数・レイテンシが改善し、冒頭にもあったBFCM期間の3,290億リクエストを捌き切りました。 まず最初に自分が抱いた感想として、プロダクトの課題を解決しつつOSSコミュニティへの還元を忘れないという点に感銘を受けました。 導入の過程でFalconに対して行われた改善は誰もが利用できるようになっています。 Falconを実際のプロダクトに導入し、入念なテストを重ねてブラッシュアップしたうえで、個社最適化にとどめずOSSとして誰もが使える形で公開し、Rubyコミュニティ全体へ還元する姿勢に、エンジニアとしてとても憧れました。 また、発表の中でスケールテストの重要性について強くお話をされていたのが印象的でした。 最近の自身の関心ごとの一つとして、以下にテストをしやすい環境を作るか・本番に近い環境でテストができるかというものがありました。 Shopify社は「Genghis」というツールを用いてこれを行っているそうなのですが、詳しい情報が見つけられなかったのでご存知の方がいれば教えていただけると嬉しいです。 また、同社のテックブログを読むと「Game Day」と称してスケールテスト以外にもカオスエンジニアリングや障害のシミュレーションなどかなり大規模で入念なテストを行っていたことがわかります。 shopify.engineering ユーザー増加やキャンペーン施策によるトラフィックの増加は、パフォーマンスだけではなくランニングコストという面においても重大な関心事です。そうした状況で、Falconは有効な選択肢の一つだと感じました。 実際に触ってみて他のRack互換アプリケーションサーバーとどのような違いがあるか試してみたくなったので、まずは自身のローカルのRailsでFalconを動かしてみようと思います。 FalconのRuby on Railsの導入に関しては2025年のKaigi on RailsのキーノートでSamuelさんが発表しておりこちらもおすすめです。 kaigionrails.org 志賀( @akitoshiga ) Practical TypeProf: Lessons from Analyzing Optcarrot speakerdeck.com @mametter さんによる、Rubyの型解析ツールTypeProfを、Ruby製8ビットマシンシミュレータであるOptcarrotに適用し、偽陽性の型エラーをゼロにするまでに何をしたのかという話でした。 TypeProfは、最小限の型注釈でエラー表示、定義ジャンプ、補完を提供するエディタ支援ツールです。型検査機にはSteepやSorbetがありますが、TypeProfはそれらとは異なり、型注釈をほとんど書かずにコードから型を推論します。 偽陽性の型エラーの原因は、実行時の不変条件が伝わらず、コード上nilになり得る型に対するメソッド呼び出しによるもの、動的メソッドで解析自体が難しいものなどがありましたが、本発表ではそれらをどう見つけどう直したかというものをAIの活用も含めてお話しされていました。 原因調査の中で、AIがキーポイントの調査において有効であることが語られました。実装全体の把握やその中でも特に多く呼び出される処理の特定は人間が調査するにはコストが高く不向きであると思うので、その部分をAIが十分に代替できるというのは素晴らしいなと思いました。 一方で、RBSでの型付けはAI任せだと雑になりがちなので一部は自分の手で直したと語られていました。まだまだAIは万能ではなく、人間が有効に使えているかどうかを判断する必要があり、場合によっては人の手で修正することが必要であるというメッセージとして受け取りました。 話の最後には 同氏が以前公開された記事 を踏まえ、型を書かないRubyがAIコーディングとの相性が良い可能性について触れており、その中で型の役割についてもガードレールとして機能するとされていたが、定量効果については慎重に評価すべきではないだろうか、としていました。 今後の展望としては、まずは人間向けに改善を進めていき、AIの使い勝手が安定してきた頃にAIエージェントを助けるためのツールとしての改良も検討しているとしていました。 RubyがAIコーディングと相性が良いかもしれないという示唆は、Rubyをメインで使っている者として、今後も使っていく価値のある言語である可能性を示されたような安心がありました。一方で動的言語であるが故に実行時エラーの懸念が常に付き纏いますが、そこを少ないコストで軽減できるツールとしてTypeProfの進化には期待したいです。 Rubyにおける型は、人によって意見が分かれると思います。個人的には、「型はあるに越したことはない。しかし、自分でわざわざ型注釈は書きたくない」という意見です。TypeProfは僕のようなRubyistにとって理想のツールとなる可能性があります。 RubyKaigi後、早速TypeProfを試してみようと思いましたが、RBSでモジュールエイリアスを定義しているとエラーによりTypeProfが起動しない問題に遭遇したので、PRを作成しました。 github.com 今後も自分にできる範囲でTypeProfの進化に貢献していきたいです。 rhiroe( @buta_botti ) Ruby Releases Ruby rubykaigi.org @hsbt さんによるRubyのリリースを支えるRubyによる仕組みづくりについての発表でした。 今回の発表で印象的だったのは、数値で示されたリリースプロセスの進化と「徹底してRubyを使い込むこと」でした。 かつてRubyのセキュリティリリース現場では、最大4つの安定版ブランチにパッチを当てるために複数名のコミッターが5〜6時間に及ぶ深夜作業をされていたそうです。インフラ構成管理やリリーススクリプト、各種自動化ツールをRubyで揃えて改善を進めたことで、それが今や1名が1時間程度の作業で完了できる体制になったといいます。自動化による効率性向上に加えて、緊急性が高いセキュリティパッチ対応におけるRubyコミュニティのアジリティが底上げされたと感じました。 更に、リリースの頻度についても、2022年の年間9回から2024年の15回へと約1.5倍に加速しています。hsbtさん自身が、Ruby 4.0以降は「2週間に1回の頻度でリリースする」という目標を立てられているといい、既にRuby 4.0リリース以降から10回のリリースが実現できているようです。テスト基盤はGitHub ActionsとRuby CIの2系統で運用され、GitHub Actionsには約120のworkflowが存在するなど、幅広いプラットフォーム・ビルドパターン・コンフィギュレーションを継続的に検証できる体制が紹介されていました。 特に、開発版Rubyにおけるパフォーマンス向上やメモリ削減などの成果を現行の安定バージョンに還元するバックポートの仕組みや、OIDC連携によるTrusted Publisher、Sigstoreを用いた署名など、Bundlerを含むエコシステム全体に最新のセキュリティ標準が組み込まれていくことが紹介され、Rubyエコシステムの揺るぎない技術的信頼を感じました。 RubyによるRubyのためのリリースプロセスの改善が、あらゆるRubyistへの良質なユーザー体験を形作っているのだと感じられる発表でした。 江田( @edy629s ) Lightning-Fast Method Calls with Ruby 4.1 ZJIT speakerdeck.com こちらのセッションでは今後のRubyの進化には欠かすことのできないZJITに関する内容でした。 特にメソッドコールに関する詳細なアプローチについて話されていました。 このセッションは今回の会場で一番広いホールで行われたのですが、そのほとんどの座席が埋まっているという状態で始まりました。 これはRubyにおけるZJITの注目度の高さが伺えますし、ShopifyのJIT開発チームでもYJITの頃から活躍されているk0kubun氏のトークであることからも多くの人を集めたセッションとなったのだと思います。 セッションの内容はメソッドコールにおけるRuby内部のアプローチについてRuby VMとYJIT、そしてZJITについて比較を行いながら話されていました。 まず最初にZJITのメソッドコール最適化の方法はいかにmemory writeを減らすかということに主眼をおいていることがわかりました。 メソッドコールはコードの実行においては多くの割合を占めるものであり、ここの部分での最適化の積み重ねが最終的に大きな改善となりうる箇所です。 本セッションではmemoryに加えてregisterの活用とそれぞれの活用順序を組み合わせることで、YJITと比べてもより高効率な最適化を目指したことを個々のステップを丁寧に説明されていました。 私はこのセッションにおいて、情報工学において誰もが習うであろうmemory, registerの組み合わせがいかに重要かを改めて認識することになりました。 CRubyという巨大な処理系においてもコンピューターの基礎となるアーキテクチャを駆使することで改善を積み重ねられるという事実に、ZJITという大きな取り組みの中にも基礎ありき、という重要さを再認識させられました。 関口亮一 ( @ryopeko ) Blazing-fast Code Indexing for Smarter Ruby Tools rubykaigi.org この発表では Rubydex という Rust 製の Ruby Code Indexer が紹介されていました。RubyLSP や Tapioca に統合することで最大10倍の高速化と2倍のメモリ削減を実現したという内容でした。 また、Ruby ツールのための統一的なコードインデックス基盤としてのビジョンも示されていました。Shopify の Ruby DX チームが9名関わっていることから、Rubydexに対するShopifyの本気度がうかがえます。 個人的に RubyKaigi で最も注目していたのはこの Rubydex でした。というのも、これからの時代の言語選定において、大きな要素となるのがトークン効率の高さだと考えているからです。 mame さんによる Ruby はトークン効率が高い言語なのではないか という記事が話題を呼びましたが、私は言語自体のトークン効率と同程度もしくはそれ以上にトークン効率を高める補助ツールの存在が重要なのではないかと考えています。 AI エージェントにコードベースを調査させると、Grep → Read → また Grep…というループが延々と続き、トークンを湯水のごとく消費します。人間はこんなことはせず、エディタのコードジャンプや「このコードはこのあたりのファイルにあるはずだ」と当たりをつけて調べます。これと同じことを AI エージェントが行えるようになればトークン効率は劇的に改善するはずです。 実際にタイミーのモノリス Rails で Rubydex MCP を試したところ、簡単なベンチマークではトークン消費量を3〜4割削減できました。 tech.timee.co.jp トークン効率の改善としては、Claude Code の LSP サポートはまさにそのための機能だと思いますが、Rubydex は LSP 以外でも活用できます。Rubydex を基盤として、コードを静的解析してデッドコードを検出し、自動で削除・改善するワークフローを組むことができるかもしれませんし、AI によるコードレビュー時に「この Pull Request で変更したメソッドの全呼び出し元」をインプットとして与えることでシステム全体への影響をより詳しく検証できるようになるかもしれません。Rubydex は Ruby が “AI 時代にとっても最高の言語” であるための重要な技術基盤になると確信しています。 Rust 実装なのでコントリビュートの敷居が高いというのは正直なところなのですが、自分でできることを探して貢献したいと思っています。 新谷( @euglena1215 ) Matz Keynote rubykaigi.org 「Claude Codeでこんなの作ってみました」という話は最近よく目にしますが、今年のキーノートではRubyの生みの親であるMatzがそんな話をしだして自分は終始テンションが上がりっぱなしでした。ここ数年のMatzキーノートの中でも一番印象に残る内容だったかもしれません。 最近のMatzはあえて自分ではコードを書かない制約を課してClaude Codeで様々なプロジェクトに取り組んでいるといいます。自身の日常的な課題を解決するためにRSSリーダーをRuby on Railsで作ったり、組み込み向けRubyであるmrubyの実装の改善をしたり、そして極めつけは今回の目玉、RubyのAOT(Ahead of Time)コンパイラであるSpinelを開発したりと驚くべきスピード感で具体的なアウトプットを次々と生み出しています。 同日の『Ruby Committers and the World』では後継者問題も話題にのぼりましたが、そんな懸念をよそに新しい技術に目を輝かせ、誰よりも楽しそうにプロダクトを作り続けるMatzの姿には非常に感銘を受けました。 また、リーナス・トーバルズがLinuxとGitという世界的に利用されているプロダクトを複数世に送り出していることに触れ、自分もRuby以外でもう一発当てたいと話していたのも良かったです。Spinelがそのひとつになるかはわかりませんが、彼の手からまた新しい何かが生まれてくるんじゃないかという期待を抱かずにはいられない、最高のキーノートでした。 須貝( @sugaishun ) おわりに RubyKaigi 2026は、Rubyコミュニティの熱量と、言語としての更なる可能性を肌で感じられる3日間でした。 スピーカーの発表内容や企業ブースでの会話、DrinkUpイベントなどを通じて得た繋がりは、単なる情報交換に留まらず、新たな技術的な挑戦への大きな原動力となっています。 タイミーはRubyコミュニティの一員としてこれからも技術への探究心を燃やし続けていきます。 また来年、宮崎で開催されるRubyKaigi 2027でお会いしましょう!
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 に記録しておきます。 ## Code Repositories - < dbt-repo > (feature/ < intent _name> ) - < composer-dag-repo > (feature/ < intent _name> ) - < composer-infra-repo > (feature/ < intent _name> ) - < gcp-terraform-repo > (feature/ < intent _name> ) Intent を再開するときも、Claude Code がどのブランチをチェックアウトすればよいか即判断できます。 横断ドキュメントとして蓄積される Inception で作る requirements.md や application-design.md は、複数リポジトリにまたがる機能の「横断的な設計書」になります。公式ペーパーではこうした成果物を "semantically rich context memory" と呼んでいて、AI がライフサイクル全体で参照する知識として機能します。 「1 機能 = 複数リポジトリ」というデータチーム特有の性質と、AI-DLC のコンテキストメモリの思想が、意外とうまくかみ合った部分です。 並列 Unit と audit.md 分散 モブとは別に、1 つの Intent の中で独立した複数 Unit を並列処理で進めるケースもあります。これは、Worktree で複数の Claude Code Agent を同時起動する方式です。このとき地味に困ったのが audit.md の Git コンフリクトです。並列の Agent が 1 つの audit.md に書き込もうとして衝突します。 対策として、 audit.md は Intent レベルのマイルストーンのみ記録する役割に限定し、Unit 内の詳細ログは construction/<unit>/audit.md に分散する運用にしました。このルールは .claude/rules/parallel-unit-audit.md に定義しています。 6. モブでの意思決定: なぜモブにしたか DREチームではメンバー 5〜6 名でモブワークを組み、1 日 3 ~ 4 時間をこれに充てています。全員フルリモートのため、公式ペーパー推奨の「物理集合 + 共有スクリーン」ではなく、Google Meet を接続して画面共有しながら進めています。本章では「なぜモブにしたか」と「どう使い分けているか」を DRE 視点で書きます。 3 つの狙い モブを採用する狙いは、マーク・パール『モブプログラミング・ベストプラクティス』で挙げられている利点と重なります。特に以下の 3 つが今の DRE に効いています。 フロー効率(Loss function を強化する) 章 2 で触れた通り、AI-DLC の各ステップには人間の検証・承認ゲートがあります("human oversight functions like a 'loss function'")。この承認が詰まるとフロー全体が止まる構造です。 AI の確認質問(clarifying questions)に即答できる人がその場にいないと、承認ゲートで数時間〜半日止まることもあります。Intent 単位で開発を進める AI-DLC では、並行して複数の Intent を抱えるより、少数に集中する方がリードタイムが短くなります。 少人数のDREチームでモブをやると、WIP は 1〜2 Intent に絞られ、意思決定の待ち時間がほぼゼロになります。モブは AI-DLC の Loss function を強化する実装とも言えます。ただし、外部チームへの依存がある場合はこの限りではなく、PR レビュー待ちや情報提供待ちになることはあります。 キーパーソンに頼らない Cloud Composer の統合や TROCCO から dlt への移行など、DRE は新しい基盤への切り替えを多く抱えています。こうした新基盤は「誰か一人だけが仕組みを分かっている」状態になりがちで、障害対応や次の意思決定がその 1 人に依存するリスクがあります。 モブで設計判断を進めると、全員が同時に基盤の意図を理解していきます。ドキュメントで読むのと、設計を議論しながら作るのとでは、後の理解度の深さが違います。 加えて、Intent の議論は Claude Code の audit.md に自然と記録されていくので、後から加入したメンバーが「なぜこの設計にしたか」を追えるようになります。口頭の議論を議事録に起こす手間が、AI-DLC の運用中に自動で払われる形です。 AI の出力の欠陥を減らす モブで AI の出力をその場でレビューすると、一人では見逃しがちな欠陥が減ります。厳密に比較計測したわけではないのですが、集合知がうまく効いている実感はあります。 AI の提案に対して「そこは業務仕様的にこう違う」「その構成だと監視が弱くなる」「別の選択肢の方が運用が楽」といった指摘が即座に入るので、Intent 完了後に気づく修正が減っていると感じます。 使い分け: 全員モブ / 2 分割 / 個人 タスクの性質に応じて、モブの粒度を変えています。 粒度 想定シーン 全員モブ(チーム全員) Intent の Inception、新基盤の設計判断、障害対応 2 分割モブ(2 ~ 3 人 × 2) 複数 Unit を並列で進められる Construction 個人ワーク 既知パターンの実装、軽微なドキュメント整備 判断基準は「不確実性」と「依存関係」です。不確実性が高いものは全員モブ。独立した Unit に切れるなら 2 分割。どちらも低い軽微な作業は個人。 公式ペーパーでも Mob Elaboration(Inception 相当)は必須、Mob Programming(Construction 相当)は分岐可能、と書き分けられていて、DRE の使い分けもほぼこの原則通りです。 リモートモブの実装と未解決の課題 公式ペーパーが想定するモブは「物理集合 + 共有スクリーン + ファシリテーター」ですが、DRE は全員フルリモートなので、ここを読み替える必要がありました。現在の構成は Google Meet + 画面共有 + 各メンバーのローカルエディタ(VS Code / Zed / Vim など人により様々)+ Claude Code です。 タイピスト交代 タイピスト交代は時間交代式(30 分サイクル)で、現タイピストが /aidlc-intent-save スキルで作業を保存・マージし、次のタイピストが自分のマシンで /aidlc-intent-continue で引き継ぎます。 試して撤退したもの VS Code Live Share : タイピスト交代のスイッチングコストを下げる狙いで試しましたが、ターミナル共有はできても接続環境によって表示が崩れ、肝心の Claude Code 拡張機能自体は Live Share で共有できなかったため断念しました タイマーの Claude Code スキル化 : タイピスト交代を時間で促すスキルを試作したものの、時間ベースで AI セッションに割り込む仕組みが安定せず、一旦撤退。今は Google Meet のタイマー機能で運用しています バットマン 『モブプログラミング・ベストプラクティス』に登場する「バットマン」(モブの外で外部からの問い合わせや割り込みに対応するメンバー)に倣い、その日の障害対応当番はタイピストに入れない運用にしています。データ基盤の障害対応はアラート監視と並行処理が必要で、モブに入ると集中を妨げるためです。 未解決の課題: スイッチングコスト 『モブプログラミング・ベストプラクティス』では 10 分ごとの交代が目安として紹介されていますが、DRE では現状 30 分が限界です。AI-DLC を始めた当初は 1 時間以上かかっていたのを、保存・再開処理の高速化や Google Meet のタイマーで短縮してきました。それでも、各メンバーが自分のマシンで作業するスタイルでは、保存・再開を速くしても、セッションを次の人のマシンに同期し直すスイッチングコストが残ります。10 分にはまだ遠いのが現状で、ここはリモートモブの構成上の制約として残っています。 7. 3 ヶ月の数字 AI-DLC を運用してみて、何が数字で変わったかを見ていきます。 計測の方針 2025 年 10 月〜 2026 年 4 月の PR を集計しました(4 月は 4/24 時点)。対象は、DREチームのメンバー(5〜6 名程度)が author の PR に限定しています。なお、ドキュメント中心の Workspace リポは /aidlc-intent-save で作られる即マージ PR が多く数字を歪めるため、集計は コードリポジトリのみ にしています。また、他チーム調整が必要で構造的に長い PR は、上位 5% を外れ値として除外しています。 Intent 完了数 一番わかりやすい変化は、Intent 単位で開発を進められるようになったことです。 月 完了 Intent ドキュメント成果物 2026-02 0(初月、進行中 1) 60 2026-03 14 263 2026-04(4/24 時点) 17 215 2 月は AI-DLC 導入初月で Intent の完了は 3 月にずれ込みました。3 月は 14 件完了、ドキュメントは 263 ファイルが積み上がりました。4 月は月途中(4/24 時点)で既に 17 件の Intent が完了しています。 PR 数 コードリポジトリのマージ済み PR 数(DRE メンバー author 分)です。 月 コードリポ PR 2025-11 36 2025-12 24 2026-01 43 2026-02 41 2026-03 74 2026-04(4/24 時点) 58 1 日 3 ~ 4 時間をモブに充てているので、「モブで時間を使っている分、実装量は減るのでは?」という懸念もありましたが、少なくとも PR 数の面では減っていません。2026-03 で 74 件、4 月は月途中で既に 58 件のペースです。 PR サイクルタイム DRE メンバーの PR サイクルタイム(作成〜マージ)です。外れ値除外後の値です。 月 PR 数 中央値 P90 2025-10 19 1.5h 64.9h 2025-11 36 10.6h 104.7h 2025-12 24 21.2h 94.5h 2026-01 43 2.1h 89.1h 2026-02 41 6.5h 137.5h 2026-03 74 2.6h 96.5h 2026-04(4/24 時点) 58 2.2h 89.6h 月ごとのばらつきが大きく、AI-DLC 導入前後で劇的な改善があるとは言いにくい数字です。ただ、モブで 1 日 3 ~ 4 時間を使いつつ中央値 2〜3 時間台で安定しているので、モブによる時間投入に見合う速度は維持できているとは言えそうです。 注記 この期間の数字を AI-DLC の効果だけで説明するのは慎重にしたいところです。大型案件の時期的な偏りや、メンバーの稼働割合など、他の要因も混ざっています。 それでも、Intent 単位で開発を進める仕組みが 2 月から稼働し、3 月に 14 件の Intent 完了まで回せるようになったのは定量的な変化です。PR サイクルタイムの劇的改善は見えていませんが、モブで使う時間分の生産性ロスが起きていない点は、少なくともマイナスの兆候は出ていないと言えます。 何が効いていそうか(仮説) PR サイクルタイムが変わっていない一方で Intent 完了数は増えている、という組み合わせから、いくつか仮説を立てられます(断定はできません)。 WIP の削減 : 少数の Intent にチーム全員が集中することで、リードタイムのばらつきが抑えられている可能性 レビュー待ちの削減 : モブで合意してから PR を作るので、PR 段階での非同期レビュー待ちが実質なくなっている(中央値を押し下げる方向) 外部依存が P90 を支配 : P90 は 60〜140h 台で大きく変わっていません。他チームとの調整や権限待ちで止まる PR が混ざっているためと思われ、ここは AI-DLC 単独では改善しにくい部分 記事執筆時点での仮説として記録しておきます。 8. やれていないこと 3 ヶ月で骨格はできた感覚がありますが、まだうまく回せていない領域もあります。 Operations フェーズ : DRE では /aidlc-ops-incident という障害対応スキルに留まっています。chanyou さんの記事で紹介されている Operations ワークフローを取り込むのが次のステップです ハーネスエンジニアリング寄りの自動化 : コードレビューはモブで全員でやっていますが、AI にコードをレビューさせる仕組み、Claude Code の Hooks / Agents の活用、AI 出力の評価ループなど、人間介入を減らす方向(いわゆるハーネスエンジニアリング)の仕組みはまだ薄いです。モブの検証密度は保ちつつ、自動化できる部分はそちらに寄せていきたいと考えています 本記事で触れなかった工夫 本記事は Inception と Construction フェーズの実装に絞ったため、以下のような工夫は紙面の都合で触れていません。続編で書く予定です。 多角的レビュー : コンテキスト分離型のサブエージェントで Inception / Construction 成果物をレビューする仕組み Knowledge Base 体系 : Intent 横断の仕様・運用ノウハウを knowledge-base/ に蓄積し、Intent 完了時に差分提案するルール 他チームとの擦り合わせルールの統合 : 連携する別チームとの合意事項を AI-DLC ワークフローに組み込み、PR 差分の自動準拠レビューも用意 効果計測・導入促進 : 月次効果計測レポートの自動生成と GitHub Discussions 投稿、社内全体の AI-DLC 導入状況レポート 運用ガードレール : 本番環境への破壊的操作を一律禁止するルール、bash コマンド実行規約 9. おわりに 3 ヶ月運用して現時点で落ち着いている構成を書き残しました。完成形ではないですが、この方向で続けるメリットはあると感じています。 公式ドキュメントには書かれていない実装の隙間を埋める例として、同じようにデータチームで AI-DLC を運用している方の参考になれば嬉しいです。 参考 AI-Driven Development Life Cycle: Reimagining Software Engineering — AI-DLC の理念を紹介した AWS DevOps Blog AI-DLC Method Definition(Raja SP, AWS)— https://prod.d13rzhkk8cj2z0.amplifyapp.com/ — 本記事で引用した "Human oversight as loss function" 等の出典 awslabs/aidlc-workflows — AI-DLC ワークフローの原典リポジトリ(MIT-0) Building with AI-DLC using Amazon Q Developer — Amazon Q Developer を使った実践ガイド マーク・パール『モブプログラミング・ベストプラクティス — ソフトウェアの品質と生産性をチームで高める』オライリー・ジャパン タイミーのデータエンジニアリング部 DRE G では、こうしたデータ基盤の構築と AI-DLC の運用に取り組んでいます。興味がある方は、以下よりプロダクト採用サイトをご覧いただけますので、ぜひカジュアル面談などお申込みください! 株式会社タイミー | プロダクト採用サイト
こんにちは、タイミーでSRE業務を担当している徳富(@yannKazu1)です。 先日、函館で開催されたRubyKaigi 2026に参加してきました。Ruby本体やパーサ、GC、JITといった「言語の中身」を深掘りするカンファレンスなので、普段アプリケーションコードよりインフラ寄りの仕事をしている自分が行って楽しめるのか、という気持ちも少しありました。ですが、結果としてとても楽しめたので、感想を書いておきます。 SREが行っても普通に楽しめた 普段の仕事はRailsアプリケーションを安定して動かしたり、スケールさせたり、観測したりすることが中心です。Ruby本体にコミットするわけでも、パーサを書くわけでもないので、専門外の話も多いだろうと思っていました。 実際、聞いていて全部の細部までは追えないセッションもありました。それでも、 普段ブラックボックスとして扱っているGCやランタイムの中身が、作っている人の口から語られる 他社のRails運用をやっている人たちと直接話せる このあたりだけでも参加する価値を感じました。 Day 1のブースが意外と良かった 参加されたことがある方ならわかると思いますが、Day 2以降はブース巡りが意外と慌ただしくなります。スタンプラリーで人が流れたり、セッションの合間で時間が限られていたり。 その点、 Day 1はスタンプラリーがまだ始まっていないので、ブースが比較的空いていてゆっくり話せる時間帯 でした。立ち寄っても順番待ちがほとんどなく、エンジニアの方とじっくり話せます。 RubyKaigiにはほぼ例外なくRailsを本番運用している会社さんがスポンサーとして出展しているので、SREとしては「他社さんのアーキテクチャや困りごとを直接聞ける場」として、これがかなり面白かったです。 Railsで完結する vs クラウドネイティブに振り切る 複数の会社さんと話して興味深かったのが、「Railsの中で完結させるか、AWSのマネージドサービスに切り出すか」の判断基準が会社によって全然違うことです。 Railsはよくできていて、ActiveJob + Sidekiq、ActiveStorage、ActionCableなどを組み合わせれば、大抵のユースケースはRailsの世界の中で完結します。わざわざクラウドネイティブなマネージドサービスに切り出さなくても、運用負荷を抑えながら回せるケースは多い。 一方で、「ジョブの遅延が事業KPIに直結するので、マネージドサービスに切り出して水平スケールを確実にしている」と話す会社さんもあれば、逆に「今のスタックで十分捌けているし、Rubyエンジニアが運用できる構成に揃えたほうが組織的に強い」と話す会社さんもありました。 技術選定の基準として挙がっていたのは、ざっくりこんな観点です。 スパイク耐性が事業上クリティカルかどうか 運用するチームのスキルセットと採用市場 コールドスタートを許容できるワークロードか RubyKaigiは登壇者も来場者もアプリケーションエンジニアが中心です。そのため、「Sidekiqのままいくか、それとも切り出すか」といったテーマひとつとっても、「アプリケーション側からどう見えているか、何が嬉しいかつらいか」という視点で語られていたのが印象的でした。 普段、SRE系のイベントで「インフラ側の都合」としてこの手の話を聞くことが多い私にとっては、この視点の対比が非常に新鮮に感じられました。 「正解は一つじゃない」と頭ではわかっていても、SRE目線とアプリ目線では同じ意思決定でも見えている景色が違います。両方の視点を持っておくことが大事だなと、改めて感じました。 AI活用の温度感 もう一つ、多くのブースでも話題になったのが AI活用 です。プロダクトへの組み込み、社内開発フローへの導入、営業・カスタマーサポートへの活用と、レイヤーごとに状況が違っていて面白かったです。 特に印象に残ったのが、SmartBankさんのブースで展示されていた「スマートバンクで働くAI Agentたち」のポスターでした。アプリユーザー向けの「 ワンバンフレンズ 」(家計を読み解いて気づきを届けるAIアシスタント)、社内メンバー向けの「 Ask! ワンバン 」(自然言語で社内データを検索・分析する分析AI)、そして開発者向けの「 Guardie 」(エラーや異常を検知してログ・コード・変更履歴を横断して原因特定を支援する番犬AI)という三本立てで、 ユーザー向け / 社内向け / 開発者向けの3レイヤーに対してそれぞれAIエージェントを配置している のがすごく整理されていて印象的でした。 特にGuardieはSRE視点でめちゃくちゃ刺さりました。「2時間覚悟していた調査が10分で終わった」という社内の声が紹介されていて、これは障害対応における MTTR(平均復旧時間)を本質的に短縮しに行っている 事例だなと。エラー検知 → ログ・コード・変更履歴を横断した原因特定までをAIに任せる、というのはこれから我々も作っていこうと思っていた仕組みが普通に動いていて、刺激を受けました。 ブース担当の方とは「どこまでをAIに任せて、どこから人間がやるべきか」「誤検知や暴走への安全装置をどう設計しているか」みたいな話までできて、こういう一次情報が聞けるのもRubyKaigiならではでした。 気になった話は、その後のアフターパーティでさらに深掘りできました。資料には載らない現場のリアルな知見が交換される場として、ブース + アフターパーティの組み合わせは、セッションと同じくらい価値があったと感じます。 参加したセッションを日ごとに振り返る ここからは、自分が参加して特に印象に残ったセッションを日ごとに紹介していきます。 Day 1: Exploring RuboCop with MCP (Koichi ITO さん) 1日目に聴いたのが、RuboCopコアチーム・MCP Ruby SDKチームメンバーのKoichi ITOさんによる、 RuboCopとMCP(Model Context Protocol) を組み合わせる試みについてのセッションです。 これまでRuboCopは「人間」または「他のプログラム(CIなど)」をきっかけに実行されてきました。そこにAI時代になって、 AIエージェントという新しい実行のきっかけ が登場した、というのが導入の話です。生成AIとリンター/フォーマッターをどう組み合わせるか、Rubyで実装されたMCPサーバーをエージェントの隣で走らせるとどうなるか、という内容でした。 技術的には、 MCP SDKの構造(サーバーとクライアントそれぞれのSDKがあること) トランスポート層として stdio と Streamable HTTP の2種類があり、用途で使い分けること HTTPトランスポートではセッション管理が肝になり、Pumaのようなスレッドモデル + シングルプロセス構成だと素直に動くが、複数プロセス・複数ホストに横断するとセッションの保持が難しくなること ただし Stateless Mode ( stateless: true )を使えば、Pumaの複数ワーカーやUnicornのような複数プロセス構成にも対応できること。ただしこれは リクエストごとに新しいtransportインスタンスが生成されるためMCP-Session-Idを共有できない という制約とのトレードオフであり、「セッション保持を諦める代わりに複数ワーカー/プロセスでもスケールできる」という割り切り あたりが特に勉強になりました。特にセッション管理の話は、MCPサーバーをWebアプリケーションとして本番に乗せようとすると、ロードバランサーやスケールアウトとの兼ね合いが出てくるという点で実践的でした。 ステートフル/ステートレスをどう使い分けるか は、これから考えないといけないテーマになりそうです。 セッションの締めくくりで「LLMの 確率的な性質 を決定的なツールに組み込むことで、これまでの決定的なツールとは違う未来が描ける」という話があって、そこも印象的でした。MCPの サンプリング (サーバーがクライアント経由でLLM補完を要求する仕組み)や、 Elicitation (実行中にユーザーへ追加情報を問い合わせる仕組み)といった機能は、ツールの形そのものを変えそうな予感があります。 スライド: https://speakerdeck.com/koic/exploring-rubocop-with-mcp Day 2: Chasing Real-Time Observability for CRuby (Shintaro Otsuka さん) 2日目で一番テンションが上がったのがこのセッション。CRubyの実行状態を リアルタイムに3D可視化する というツール「rrtrace」の話でした。 普通のプロファイラはサンプリングベースで、後から集計して結果を見る形が多いですが、このツールは「いまこの瞬間にCRubyの中で何が起きているか」を、複数スレッドのスタック状態として3次元空間にレンダリングしながら見せる、というアプローチです。デモを見せてもらった時、IRBに入力するたびにスタックが積み上がっていく様子がリアルタイムで見えて、純粋に「すごいものを見ている」という感覚になりました。 技術的なポイントとしては、 計測側のC拡張は軽量に保つ設計 で、イベントの収集と転送に特化している イベントは TracePoint API ( CALL / RETURN / INTERNAL_GC_ENTER / INTERNAL_GC_EXIT )や内部のスレッドイベント( INTERNAL_THREAD_EVENT 、こちらはWindowsでは利用不可)から収集し、timestamp(60bit) + event type(4bit) + method id/thread id(64bit)の合計16バイトの構造体に統一 C拡張(計測側)とビジュアライザプロセスの間は OS管理の共有メモリ上のリングバッファ で受け渡し ビジュアライザ側はCRubyのコアを使っていない別プロセスなので、可視化処理が重くてもCRubyの実行を直接ブロックしない スタックシミュレーションが重いため、 Parallel Scanアルゴリズム で並列化している という設計でした。ただし、スライドのベンチマーク結果を見ると、rrtrace有効時は 関数呼び出しスループットがplain CRubyの17%程度 (73,417,127 → 12,760,131 calls/s、約5.9倍遅くなる)、 Railsサーバーのrpsもplain CRubyの55%程度 (203.19 → 110.84 rps)になるとのことで、 計測のオーバーヘッド自体は「小さくない(not small)」 とスライドでも明記されていました。TracePointフックのコストが支配的で、ここは今後の課題とのことです。 それでも、「 重い処理を別プロセスに全部寄せる 」というアーキテクチャの考え方は面白かったです。計測側はできるだけ軽く保って、分析・可視化は別のリソースでやる。この割り切りが設計をシンプルにしていて、きれいだなと思いました。 「現代のマシンは10コア以上あるのが普通で、CRubyが1コアで動くなら残りのコアを観測やビジュアライズに自由に使える」という、リソースの捉え方の話も新鮮でした。GVLがある世界での観測ツールの設計思想として、納得感が強かったです。 スライド: https://speakerdeck.com/whitegreen/chasing-real-time-observability-for-cruby Day 3: The Less-Told Story of Socket Timeouts (Misaki Shioi さん) 3日目に聴いたのがこれ。ソケットライブラリのタイムアウトの 歴史と内部実装 を、Issue/Commitを参照しながらRuby 4.0までの流れに沿って解説していくセッションでした。タイトルからして気になっていたけど、期待以上の内容でした。 Socket.tcp / TCPSocket.new には、 resolv_timeout (名前解決のタイムアウト) connect_timeout (接続のタイムアウト) そしてRuby 4.0で追加された open_timeout (全体のタイムアウト) の3種類があります。「この3つがなぜ必要で、どういう順番で導入され、どんな歴史的な紆余曲折があったのか」を、Issue/Commitを参照しながら丁寧に追っていく構成でした。 特に印象的だったのが、 まず Socket.tcp に connect_timeout が導入され、続いて Addrinfo.getaddrinfo への timeout および Socket.tcp への resolv_timeout が追加されたこと resolv_timeout と connect_timeout を両方指定しても、全体のタイムアウト時間は制御できない (複数アドレスに対して逐次接続を試行するため、合計時間が想定より長くなりうる) これらの問題を解決するために、Ruby 4.0で 全体時間を管理する open_timeout が追加された という話の流れです。普段、HTTPクライアントの open_timeout / read_timeout / write_timeout を「だいたいこのくらい」で設定しがちですが、その下のレイヤーでは名前解決と接続が並行で走っていて、 タイムアウトの組み合わせによっては想定と全然違う挙動になる ということを、改めて意識させられました。 また、歴史的な経緯として特に面白かったのが、 名前解決の中断可能化(interruptible)をめぐる話 です。 getaddrinfo(3) はブロッキング呼び出しで、 Ctrl+C でも中断できないという問題が長年ありました。これを解決するアプローチとして、まず 2020年1月に「 Addrinfo.getaddrinfo が timeout をサポートする」提案が行われ、そのパッチで Addrinfo.getaddrinfo に timeout 、 Socket.tcp に resolv_timeout が追加されると同時に、内部的に「GNU拡張の getaddrinfo_a(3) が利用可能ならそれを使う」実装が入りました ( getaddrinfo_a(3) はワーカースレッドで非同期に名前解決を行う仕組み)。その後 2020年8月には「Make Socket.getaddrinfo interruptible」がマージされ、 Socket.getaddrinfo の内部もこの getaddrinfo_a(3) を使うように利用範囲が拡張 、さらに 2020年9月には TCPSocket.new にも resolv_timeout / connect_timeout が追加 され、名前解決を中断可能にする方向で進められました。 ところがその後、 Rails ActiveJobの統合テストが失敗するようになった という報告が入り、調査の結果、 fork後の子プロセスで getaddrinfo_a(3) を呼び出すとハングする ことが判明します。 getaddrinfo_a(3) は内部で再利用可能なワーカースレッドを保持しているのですが、forkでコピーされる子プロセスにはワーカースレッドが存在しないにもかかわらず内部状態は「ワーカースレッドが待機中」のままになっており、これによってデッドロックが発生する、という仕組みでした。 2ヶ月以上の調査と回避策の検討を経て、最終的には getaddrinfo_a(3) の導入自体が撤回 され、関連変更もrevertされました。その代わり、後に別アプローチとして 「名前解決ごとに専用のpthreadを立てて getaddrinfo(3) を実行する」方式 (mameさん提案、 ruby/ruby#8695 )が採用され、こちらは rsock_getaddrinfo 内に実装されることで、内部的に rsock_getaddrinfo を呼んでいる Addrinfo.getaddrinfo や Socket.getaddrinfo を含む幅広いメソッド で名前解決のブロッキング問題が解消された、という流れです。 外部API連携で「タイムアウトを設定したはずなのにハングする」「 connect_timeout を短くしたのに、複数アドレスがあるホストで合計時間が想定の何倍もかかる」みたいな経験がある人は少なくないと思いますが、まさにあれの背景にある話でした。タイムアウト設計の見直しや、Ruby 4.0以降は open_timeout を積極的に使っていくこと、テストでタイムアウト周りの挙動を確認しておくことなど、すぐに持ち帰れる学びがいくつもありました。 スライド: https://speakerdeck.com/coe401_/the-less-told-story-of-socket-timeouts リモートワーク時代の副次効果 もう一つ書いておきたいのが 社内メンバーとの関係性 の話です。 弊社エンジニアはリモートワーク中心で、普段の業務だと開発チームの全員と毎日話すわけではありません。SlackやZoomでは話すけれど、雑談ベースで「最近どう?」みたいな会話になりにくい人もいます。 それが、RubyKaigiで3日間一緒に過ごすと一気に距離が縮まります。一緒にセッションを聞いて、休憩中に「今のどう思った?」と話して、夜は飲みに行って、移動中に雑談する。この3日間の密度は、リモートでの数ヶ月分のコミュニケーションに相当するんじゃないかと思います。 おわりに RubyKaigiは「Ruby本体に関わっている人たちのお祭り」という側面が強いカンファレンスですが、Rubyを本番で動かしている側の人間にとっても十分に楽しめる場でした。SREとしても、ランタイムの理解が深まったり、他社の運用知見をもらえたり、社内の関係性が深まったりと、副次効果を含めて満足度の高い3日間でした。 普段Railsを動かしているSREの方や、これからRubyKaigiどうしようかなと迷っている方の参考になれば嬉しいです。
※ 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! タイミーでは、ともに働くメンバーを募集しています! データアナリストのポジションも募集中です。カジュアル面談も行っていますので、少しでも興味がありましたら、お気軽にご連絡ください。 データ | 採用情報 |株式会社タイミー
こんにちは、タイミーのバックエンド/Webフロント基盤チーム マネージャーの新谷( @euglena1215 )です。 先日開催された RubyKaigi 2026 に参加してきました。その中で特に気になったのが、Shopify の Alexandre Terrasa さんによる「 Blazing-fast Code Indexing for Smarter Ruby Tools 」という発表です。 この発表では rubydex という Rust 製の Ruby Code Indexer が紹介されていました。RubyLSP や Tapioca に統合することで最大10倍の高速化と2倍のメモリ削減を実現したという内容でした。また、Ruby ツールのための統一的なコードインデックス基盤としてのビジョンも示されていました。Shopify の Ruby DX チームが9名関わっているということで、Shopify への rubydex への本気度が伺えます。 発表の中では、Experimental ながら MCP サーバー(rubydex-mcp) も提供されていることが紹介されていました。Claude Code などの AI アシスタントからセマンティックにコードベースを検索できるようになっています。 AI Coding Agent にコードベースを調査させると、 Grep → Read → また Grep …というループが延々と続き、トークンがみるみる消費されていきます。rubydex-mcp を使えば、クラス定義やリファレンス、継承ツリーといった構造的な情報を、1回の MCP ツール呼び出しで取得できます。そのため、このループを大幅に削減できそうです。 実際にどの程度効果があるのか、タイミーのバックエンドリポジトリで定量的に検証してみました。 rubydex とは rubydex は Shopify が開発した Ruby Code Indexer です。 github.com Rust 製の Indexer がコードベースを解析し、MCP(Model Context Protocol)サーバーとして以下のツールを提供します。 ツール 機能 search_declarations 名前によるファジー検索(クラス、モジュール、メソッド、定数) get_declaration 完全修飾名による定義情報の取得(ドキュメント、祖先チェーン、メンバー) find_constant_references 定数の参照箇所をコードベース全体から検索 get_descendants クラス/モジュールの継承ツリーを取得 get_file_declarations ファイル内の構造一覧 codebase_stats コードベース全体の統計情報 通常、AI Coding Agent がコードベースを調査する際は grep や find でファイルを探し、 Read で中身を読み、また grep で次のファイルを探し…というループを繰り返します。rubydex を使うと、このループの多くが1回の MCP ツール呼び出しで完結できる可能性があります。 検証方法 概要 claude -p (Claude Code の非インタラクティブモード)を使い、rubydex あり/なし の2条件で同じプロンプトを実行し、トークン消費量と回答品質を比較しました。 検証環境 ツール:Claude Code CLI ( claude -p ) モデル:claude-sonnet-4-6 rubydex_mcp バージョン:0.1.0 対象リポジトリ:タイミーのバックエンド(モジュラーモノリス、70パッケージ) 条件の制御 外部要因を排除するため、以下の共通オプションを使用しました。 claude -p "<prompt>" \\ --output-format json \\ # トークン使用量を含む JSON 出力 --model sonnet \\ # モデル固定 --bare \\ # hooks, CLAUDE.md 等を無効化 --strict-mcp-config \\ # .mcp.json を無視し引数の MCP 設定のみ使用 --mcp-config <config> \\ # 条件別の MCP 設定 --tools "Read,Bash,Edit" \\ --no-session-persistence --bare で CLAUDE.md の自動読み込み等の副作用を排除し、 --strict-mcp-config により MCP サーバーの有効/無効を制御しています。これにより、2条件間の差は rubydex の有無のみになります。 プロンプト rubydex のツール群が効果を発揮しそうな質問を5種類用意しました。 ID プロンプト class_hierarchy XXXモデルのクラス継承チェーンと、includeしているモジュールの一覧を教えてください。それぞれのモジュールがどのファイルで定義されているかも含めてください。 find_references YYYモデルがコードベース全体でどこから参照されているか調査してください。参照元をコントローラ、モデル、サービス等のカテゴリ別に分類して一覧にしてください。 descendants ApplicationRecordを継承しているクラスの一覧を取得し、packs/ディレクトリ配下のパッケージごとに何個のモデルが存在するか集計してください。上位10パッケージを表示してください。 method_investigation XXXモデルに定義されているpublicインスタンスメソッドのうち、名前に'status'を含むものをすべてリストアップしてください。各メソッドの定義場所(ファイルパスと行番号)と、そのメソッドが何をしているかの簡単な説明を付けてください。 codebase_overview このRailsプロジェクトのpacks/ディレクトリ配下のパッケージ構成を調査してください。各パッケージに含まれるモデル数、主要なクラス名を一覧にし、パッケージ間の依存関係で特に密結合なものがあれば指摘してください。 各条件 × 各プロンプトで5回ずつ、合計50回実行しました。LLM の出力は非決定的なので、複数回実行して平均を取ることでばらつきの影響を軽減しています。 結果 トークン消費量 プロンプト rubydex なし(平均トークン) rubydex あり(平均トークン) 変化率 class_hierarchy 144,076 85,958 -40.3% codebase_overview 1,187,722 664,761 -44.0% descendants 46,501 165,795 +256.5% find_references 770,404 332,369 -56.9% method_investigation 986,840 636,411 -35.5% 5つ中4つのプロンプトで 35〜57% のトークン削減 を達成しました 🎉 コスト・速度 プロンプト コスト変化 実行時間変化 ターン数変化 class_hierarchy -16.7% -48.6% -35.4% codebase_overview -34.3% -19.6% -13.7% descendants +294.6% +261.0% +62.7% find_references -33.5% -19.0% -11.9% method_investigation -30.7% -50.1% -38.1% ターン数(エージェントのツール呼び出し回数)の削減がトークン削減の主因です。rubydex のセマンティック検索が Grep → Read の繰り返しを置き換えることで、エージェントループが短縮されています。 回答品質(LLM-as-a-Judge) トークンが減っても回答品質が下がっては意味がありません。別の Claude セッションを立ち上げ両条件の回答を渡し、正確性・網羅性・有用性の3観点で5点満点のスコアリングを行いました。 プロンプト rubydex なし(平均) rubydex あり(平均) 差分 class_hierarchy 4.33 4.00 -0.33 codebase_overview 4.33 4.00 -0.33 descendants 3.00 4.67 +1.67 find_references 4.00 4.00 0.00 method_investigation 3.33 4.33 +1.00 平均 3.80 4.20 +0.40 回答品質はむしろ改善しています 👏 Judge のコメントから見えた傾向を簡単にまとめます。 rubydex ありで改善した点(正確性) rubydex なしの場合、grep の結果をもとに関連しそうなクラスやメソッドを補足情報として列挙する傾向があった。目視では誤情報は確認できなかったが、裏取りが不十分な状態で情報を出しているため信頼性の判断がしにくい( method_investigation など) rubydex ありではインデックスに基づいた情報を返すため、出力の根拠が明確になっている rubydex なしが勝った点(網羅性・有用性) grep ベースの調査は探索範囲が広いため、rubydex が返さないカテゴリ(Policy、Mailer 等)の参照元も拾えていた( find_references ) rubydex なしの回答はファイルのフルパスや構造図を含むなど、開発者がすぐに使える形に整理されている傾向があった( class_hierarchy , codebase_overview ) 総じて、 rubydex ありは正確性で優位、rubydex なしは網羅性で優位 という傾向が見られました。また、いくつかのプロンプトの回答を目視でも確認しましたが、rubydex ありで明らかにおかしな内容を回答しているケースは見られませんでした。 descendants が悪化したケース 唯一、 descendants プロンプトではトークンが +256.5% と大幅に悪化しました。 このプロンプトは「ApplicationRecord の子孫クラスをパッケージ別に集計する」という内容です。rubydex の get_descendants ツールは全子孫を忠実に返します。(我々の環境では346クラス)一方、rubydex なしの場合は grep -r "< ApplicationRecord" のような検索で主要なものだけを拾うため、結果的にトークンが少なく済んでいました。 つまり、 大量の結果を返すような網羅的な検索では、rubydex がかえってトークンを増やす ケースがあります。ただし、品質面では rubydex ありの方が +1.67pt と最も大きく改善しており、正確性とのトレードオフと言えます。 まとめ 5つ中4つのプロンプトで 35〜57% のトークン削減 と 17〜34% のコスト削減 を達成しつつ、回答品質は LLM-as-a-Judge の評価で同等以上(5点満点で 3.80 → 4.20)でした。特に「クラスの参照元を探す」「メソッドの定義場所を調べる」といった構造的な検索タスクで効果が顕著です。 一方、全件取得のような網羅的検索ではトークンが増えるケースもあり、万能ではありません。rubydex が提供するツールの特性を理解した上で導入すると、より効果的に活用できそうです。 また、現状 rubydex-mcp を利用するには Rust ツールチェーン(cargo)が必要で、ソースからのビルドが求められます。開発環境の依存が増えることになるため、チーム全員が使える形に整備するかどうかはもう少し見極めたいところです。とはいえ、トークン35〜57%削減という効果は十分に大きく、rubydex-mcp への期待はとても高まる結果となりました。 検証の制約 今回の検証にはいくつかの制約があります。結果を解釈する際の参考にしてください。 --bare モードでの検証 : CLAUDE.md 等が無効化されているため、通常利用時とはベースのトークン消費量が異なります キャッシュの影響 : 実行順序や間隔によってキャッシュヒット率が変わるため、コスト比較は参考値です 回答品質の評価 : LLM-as-a-Judge による自動評価のみで、正解データとの突合は行っていません プロンプトの偏り : rubydex が得意そうなタスクを選んでいるため、実際の利用での改善幅はこれより小さくなる可能性があります
はじめに こんにちは、株式会社タイミーでデータサイエンティストをしている藤井です。 普段は推薦システムの改善を担当しています。 早速ですが、皆さんは推薦モデルの改善実験を月に何本回せていますか? 仮説を立てて、実装し、実験し、結果を整理し、次を考える。 1サイクル回すだけでも、相応の負荷がかかります。片手間でサイクル数を増やすのは簡単ではありません。 しかし、もし「仮説を立てる」から「結果を整理する」までを AI が担えるとしたら? 実際に AI の案から改善が生まれています。しかも、人間が担うのは方針の選択、コードレビュー、実験の実行に絞れています。 では、実際にどれだけ回せて、どれだけ当たるのか? 人間が思いつかない切り口は出てくるのか? 私たちはそれを確かめるために、Claude Code の Skill 機能を使った半自動の実験プロセスを組み、実際に回してみましたので、紹介したいと思います。 先に結論 AI が出した改善案は 13件で、そのうち実験まで進めたのは 8件でした。 改善が確認できたのは 3件、横ばいが 2件、下落が 3件です。 打率だけを見ると突出して高いわけではありません。 ただ、人間が手を動かしたのは方針の選択、コードレビューと実験の実行だけで、それ以外は AI が担っています。通常業務と並行しながら、このサイクル数を回せたこと自体が、この取り組みのいちばんの成果でした。 モデル改善は 1回ごとの改善幅だけでなく、試行回数を増やせるかどうかが効いてくる領域です。 片手間で回せる仕組みがあれば、改善の累積速度が変わります。 解決したかった課題 AI に推薦モデルの改善案を聞くだけなら、チャットでもできます。 しかし、それを継続的な実験プロセスとして回そうとすると、運用上のボトルネックがいくつか出てきます。 長期記憶がない セッションが切れるたびに AI は過去の実験を忘れます。 同じ失敗を繰り返すリスクがあるだけでなく、過去の失敗を踏まえて次の方向を絞る、改善が出た方向を深掘りするといった、蓄積を活かした提案ができません。 コンテキストの無駄遣い 毎回生のログや大量のファイルを読ませると、トークンを消費するだけで、期待したほど精度も上がりません。 必要な情報を構造化して渡す仕組みがないと、コストだけが膨らみます。 これらを解決するために、Claude Code の Skill 機能を使って半自動の実験プロセスを組みました。 Skill と記憶の設計 このプロセスには 2種類の記憶があります。 knowledge(長期記憶) 過去の実験記録を構造化した Markdown ファイルとして蓄積するフォルダです。 各 Skill はここを読み、過去の試行を把握した状態から動きます。 実験結果はサマリとして圧縮されて書き戻されるので、サイクルを重ねてもトークン消費が膨らみにくい設計です。 scratch(作業記憶) サイクル途中の方針メモや実装の下書きなど、一時的な情報を置く場所です。 長期記憶に残すほどではないが、セッション内では参照したい情報がここに入ります。 また、AI のコンテキストウィンドウが圧縮された場合でも、ファイルとして残っていれば再読み込みで復元できるため、意図しないコンテキスト消失への備えにもなっています。 Skill Skill 自体には、参照すべきファイルパスやテーブル定義、コーディングルールに加えて、実験コストの前提、安全性チェックの観点、実装原則、過去実験との重複を避けるための自問自答リストなどを埋め込んでいます。 これにより、毎回ゼロから指示しなくても、各フェーズで必要な文脈と制約が揃った状態で AI が動けます。 また、長期記憶と作業記憶はリポジトリ上に存在するため、Cursor など別の AI ツールからも同じ情報を参照でき、Claude Code の提案を独立に検証することも可能です。 半自動実験プロセスの仕組み このプロセスは、上記の Skill と記憶の仕組みを使って構築しています。 1サイクルの流れ AI がテーブル定義やコーディングルールを確認する AI が過去の実験記録を読み、現状を把握する AI が次に試す改善案を複数提案する 人間が方針を選ぶ AI が実装する AI が変更の安全性を確認する AI が実施予定の内容を記録する 人間が実験を実行する AI が結果を記録に反映する 人間が手を動かすのは、方針の選択、コードレビュー、実験の実行だけです。 定義の確認、過去実験の整理、提案、実装、安全性チェック、記録は主に AI が担います。 実験結果 個別の実験内容の詳細は割愛し、ここでは改善幅の傾向のみを共有します。 13件の提案のうち、実験に進めなかった 5件を除いた 8件の結果です。 実験 主要な機械学習指標の改善幅(複数指標の範囲) A +2〜+7% B +0.5〜+3% C +1〜+3% D ±2%以内 E ±2%以内 F -3〜-7% G -3〜-6% H -35〜-20% 学び 以下はあくまで運用を通じた感想であり、厳密に検証された結論ではありません。 提案の方向性 変更が小さくなりがちな傾向がある。 AI に自走させると、実験結果の正確性を担保しやすい方向、つまり対照実験がしやすい最小限の変更に寄りやすい傾向がありました。 指示を入れると質が変わる。 「小さい改善ではなく構造ごと変える改善を考えてほしい」と明示的に伝えたところ、論文の知識を参照した鋭い提案が複数出てきました。AI の提案の質は、渡す制約や方向付けに強く依存します。 既存手法の非自明な応用が出てくる。 たとえば、DIN(Deep Interest Network)の target-aware attention を two-tower モデルに持ち込む提案がありました。two-tower では推論時に候補アイテムが不明なためそのまま適用できませんが、AI は「学習時だけ正例を attention query として使い、推論時はフォールバックする」という変形を考えました。この切り口自体、推薦チーム内では出ていなかったもので私たちには非自明でした。当然、学習と推論の不一致(train-serve skew)がリスクになりますが、提案自体にそのリスクと失敗した場合に何がわかるかが含まれていました。成功の保証はなく、失敗する可能性は高そうですが、失敗しても学びが得られる実験設計になっています。また、仮にこの方式がそのまま機能しなくても、事前学習フェーズでのみ target-aware に学習させるといった派生が考えられ、アイデアの種として意味のある提案でした。 壁打ち相手としては十分実用的だった。 厳密な比較をしたわけではありませんが、少なくとも今回の運用では、AI が出す提案は人間の壁打ち相手として十分実用的だと感じました。場面によっては、自分たちだけではすぐに出なかった切り口が出てくることもありました。 蓄積と学習 最も鋭い提案は最後に出てきた。 偶然の可能性はありますが、サイクルを重ねて過去実験の蓄積が増えたタイミングで、最も構造的な提案が出ています。蓄積が提案の質に寄与している可能性は否定できません。 過去の失敗を踏まえた推論が出てくる。 AI が提案を出す際に、「過去にこの実験は失敗したので、こういう可能性がある。だからこちらの方向を試してみましょう」といった推論のログを出してくることがよくありました。蓄積された記憶を参照しながら提案理由を組み立てている様子が見て取れます。 運用コスト 人間の作業時間の大半はバグ対応。 実験が問題なく動く回では、人間の仕事は方針を選び、コードをレビューし、実験を実行することに絞られます。一方でバグが出ると調査・修正・再実行に手を取られ、体感で人間の作業時間の 8〜9割はバグ起因でした。逆にいえば、バグが出た回を無理に立て直さず次の実験に進めば、手数自体はさらに増やせる可能性があります。実装にバグが出た実験案も、提案自体は knowledge に記録しておけば、AI のコーディング能力が向上した時点で低コストに再挑戦できます。 現時点でまだ分かっていないこと サンプルサイズが不足している。 この半自動改善プロセスを運用し始めたのは最近であり、実験数は 8 件です。ここから得られた傾向が一般化できるかは、まだわかりません。 長期記憶の効果は未検証。 長期記憶なしのフローと比較した実験は行っていません。蓄積が提案の質に寄与している可能性は示唆されますが、長期記憶が本当に効いているのか、それとも同じ品質の提案が記憶なしでも出るのかは、現時点では検証できていません。 まとめ このプロセスの価値は、AI が良い改善案を出すことそのものではなく、試行の回転数を上げられることにあります。 13件の提案から 8件を実験し、3件の改善を得る。個々の実験の改善幅は小さくても、改善を積み重ねれば累積的な効果は大きくなります。 つまり、モデル改善は打率ではなく打席数が効いてくる可能性が高い。この取り組みの価値は、試行錯誤を片手間でも継続して回せるようになる点にあります。 長期記憶の効果や AI の提案精度については、まだ言い切れることは多くありません。 ただ、少なくとも「AI に改善案を出させて回す」というサイクル自体は、実用的に機能しています。今後はサンプルを増やしながら、このプロセス自体の改善も続けていきます。 こうした推薦改善の試行錯誤や、評価・運用の仕組みづくりに興味がある方は、ぜひ以下もご覧ください。 We’re hiring! 現在、タイミーではデータサイエンスやエンジニアリングの分野で、共に成長し、革新を推し進めてくれる新たなチームメンバーを積極的に探しています! データ | 採用情報 |株式会社タイミー また、気軽な雰囲気での カジュアル面談 も随時行っておりますので、ぜひお気軽にエントリーしてください。↓ hrmos.co hrmos.co hrmos.co Reference Skillを作成するにあたっては、Y Combinator の Garry Tan さんによる gstack リポジトリ(MITライセンス)を大いに参考にしました。 GitHub - garrytan/gstack: Use Garry Tan's exact Claude Code setup: 23 opinionated tools that serve as CEO, Designer, Eng Manager, Release Manager, Doc Engineer, and QA · GitHub なお、本記事を書いている途中に、AI に継続的に作業させる方向の動きがいくつか出ていました。今回の取り組みと直接の関係はありませんが、同じ方向性の事例としてメモ的に置いておきます。 Automated Alignment Researchers: Using large language models to scale scalable oversight (Anthropic, 2026/04/14)― 9 体の Claude Opus 4.6 を自律的なアライメント研究者として走らせた実験。複数 AI に役割分担させて探索を回す、という方向の一例。 Introducing routines in Claude Code (Anthropic, 2026/04/14)― Claude Code にスケジュール実行や webhook トリガーで動かせる routines が追加。今回は Skill で手動起動していますが、こうした仕組みに載せれば定期的な提案・記録反映まで自動化できそうです。
はじめに こんにちは。タイミー プロダクトエンジニアの津守です。今年1月にタイミーに入社し、気づけば早3ヶ月が経ちました。 この記事では、入社して数ヶ月働いて感じた「AIツールがオンボーディングプロセスをどう変えたか」という体験をまとめます。技術的な深掘りというより、新しい環境に飛び込んだエンジニアの個人的な気づきとして読んでもらえると嬉しいです。 従来のオンボーディングプロセスのイメージ 新しい会社に入ったとき、多くのエンジニアは最初の数週間を ドキュメントを読む。コードベースを読む。アーキテクチャを把握する。チームの開発スタイルを理解する。そして、ある程度理解できたと感じてから、ようやく手を動かし始める。 というような順序で過ごしてきたと思います。 言ってみれば「インプット先行」の学習スタイルです。この期間は"情報を受け取る期間"と暗黙的に認識されていることが多く、アウトプットは後回しになりがちでした。チームへの貢献よりも、まず「追いつくこと」が優先されるイメージです。 AI活用によって感じた変化 入社して最も強く感じたのは、この「順序」が変わったということです。 AIツールを使うことで、コードベースへの理解が浅い段階でも、まず動くものを作ることが現実的になりました。実際Cursor や Claude Code を主体に実装を進めると、知識のギャップをAIがある程度埋めてくれます。おかげで、入社初期からチームメンバーやステークホルダーのレビューやフィードバックを素早く受け取ることができました。 実際、チームメンバーやステークホルダーからのフィードバックやレビューには、基礎的な知識だけでなく、「タイミーではこうやってる」といった暗黙のコンテキストが含まれており、ドキュメントから得られる知識に加えて、より多くの背景情報を得られる場面があります。 開発アプローチとして広く受け入れられている アジャイル では、「いかに早くステークホルダーがレビューできる状態を作るか」が重要な論点のひとつです。これは、個人が環境に適応するうえでも重要な要件だと思います。完璧な理解を待ってから動くのではなく、まず動くものを見せてフィードバックをもらう。そのサイクルを素早く回すことが、結果的に最も効率的な学習を生み出し、属する組織で求められる行動を起こせるようになるために重要と考えています。 適切に学習サイクルが回るための条件 ただ、このアウトプット先行の学習サイクルが機能するには、2つの環境が整っている必要があると感じました。どちらもAIツールの登場で新たに生まれた課題ではなく、組織の開発体験として元々重要だったものですが、AIツールの発達によってその重要性はさらに増しています。 1. AIが適切なアウトプットを出せる環境 AIが出すアウトプットの質は与えるコンテキストに大きく左右されます。学習サイクルの中でフィードバックを通じて暗黙のコンテキストを受け取れるとはいえ、そもそも明示的に言語化されているほうが望ましく、AIのアウトプットの精度も上がります。 実際、タイミーではバックエンド開発Handbookを通じて、開発プロセスを明示的に言語化する動きがあります。設計・実装・運用にまたがるガイドラインが体系的にまとめられており、さらにそれがAIエージェントのスキルとして提供されています(詳しくは新谷さんの記事「 バックエンド開発Handbookを届けるために ― AI時代の知の高速道路を敷く 」をご覧ください)。 Handbookが生まれた背景のひとつには、メンバーの増加やAIツールの進化により、バックエンド以外のエンジニアが越境してコードを書く機会が増えたという事情があります。ただ実際に使ってみて感じたのは、暗黙知をまだ何も持っていない入社直後のメンバーにこそ、そのインパクトが大きいということです。「そもそも何を知らないかもわからない」状態でも、AIがHandbookに沿ったアウトプットを出してくれることは、単なる品質担保以上の意味を持ちます。 自分がHandbookを意識していなくても、AIがガイドラインに沿った設計や実装を提案してくれる——「気づいたらタイミー流の書き方になっていた」という感覚は、入社して間もない時期にとても心強いものでした。 2. フィードバックをもらえる環境・体制 もうひとつの前提条件は、フィードバックの環境です。どんなに早くアウトプットを出しても、適切なフィードバックが返ってこなければ学習サイクルは止まります。 この3ヶ月間は、チームメンバーやステークホルダーから丁寧なフィードバックをもらえる環境にあり、そのおかげで学習が加速しました。特に、PRベースのコードレビューは厳密に行われており、そこでの指摘やディスカッションがとても多くの学びになりました。 ただ、3ヶ月を通じて感じたのは、現状ではフィードバックの質が運用や状況によってばらつきが出やすい状態にあるということです。体制として担保されているというよりは、チームメンバーの意識や余裕に左右される面があり、持続的に機能させるには仕組みとしての設計が必要だと感じています。 もうひとつ、AIがアウトプットを加速させることで生まれるトレードオフも見えてきました。学ぶ側が早く動けるようになった分、レビューする側が見るべきPRの量も増えます。学習サイクルが速くなった恩恵が、レビュワーの負荷という形で偏在してしまうわけです。 また、PRベースのレビューは厳密に行われている一方で、暗黙知やコンテキストを深く共有したうえでのフィードバックを、どう生み出すかという問いも残ります。これらに対してモブプログラミングやペアプログラミングのような形式は有効な解のひとつだと思っていて、後からまとめてレビューするコストを分散させながら、よりリッチなフィードバックを生みやすい構造だと感じています。 持続的に相互フィードバックが行われる開発体制をどう設計するか——これはまだ答えの出ていない問いですが、AIが学習サイクルを高速化させるほど、フィードバックを循環させる体制の重要性は増していくと感じています。 おわりに 3ヶ月を振り返ると、AIは入社直後の学習の「量」を変えたのではなく、「順序」を変えた、というのが一番しっくりくる表現です。 以前なら「理解してから作る」だったものが、「作りながら理解する」に変わりました。この変化は、入社直後という時期をより能動的に過ごす後押しをしてくれると感じています。 ただし、そのサイクルを本当に機能させるには、AIが適切なアウトプットを出せる環境と、フィードバックを届ける体制という、人間側の設計が不可欠だと感じました。Handbookをはじめとした環境を整えてくれたチームには、改めて感謝しています。 同じように新しい環境に飛び込んでいる方や、新しいメンバーを迎える立場の方に、少しでも参考になれば嬉しいです。
こんにちは。タイミーでプロダクトエンジニアをしている福島(taishi)と大竹(otake)です。 EMConf JP 2026が3月4日に開催されました。 2026.emconf.jp タイミーは今年、EMConf JP 2026のスポンサーをさせていただきました。 タイミーには、世界中で開催されているすべての技術カンファレンスに無制限で参加できる「Kaigi Pass」という制度があります。今回はこの制度を使って参加しました。 詳細は以下をご覧ください。 productpr.timee.co.jp EMConf はエンジニアリングマネージャー(EM)向けのカンファレンスですが、私たちのようなマネジメントをしていないメンバーにとっても学びの多いイベントでした。 本記事では、印象に残ったセッションをいくつかピックアップしてご紹介します。 冒険する組織のつくりかた 著書「冒険する組織のつくりかた」を執筆された、株式会社MIMIGURIの安斎勇樹さんによるセッション。メンバーの興味傾向を把握し、目標と個人の動機を接続する場をデザインするための具体的なアプローチや、思考のフレームワークが紹介されていました。 目標のマネジメント:SMARTからALIVEへ 目標設定において、管理側の論理である「SMART」と、取り組む側の視点である「ALIVE」を両立させることが重要です。 SMARTの法則 : 業務を精緻に遂行させるための指標(Specific, Measurable, Achievable, Relevant, Time-bound) ALIVEの法則 : メンバーが前向きな意味を感じられる指標 Adaptive(適応) : 変化に適応し、将来役立つ能力を身につけている安心感 Learningful(学習) : 学びの機会となる Interesting(興味) : 好奇心をそそる Visionary(未来) : 未来を見据える Experimental(実験) : 実験的な試みである さらに重要なのは、目標設定の「前」と「後」のプロセスです。目標を単に提示するのではなく、メンバーの内発的動機と目標を「ミート」させることが肝心です。 設定するまで : ヒアリングで意見を踏まえ、参加型デザインで一緒に考える 設定したあと : リーダーがストーリーテリングで意図を語り、ダイアログ(対話)で取り組む意味を共有する 興味のマネジメント:8つの「活動スタイル」 個人の「興味のツボ」を把握することで、目標にALIVEな要素を組み込めます。興味は「ヒト」か「コト」か、そして「どのレンズ(役割)で見るか」の組み合わせで8タイプに分類されます。 興味のレンズ ヒトに興味がある コトに興味がある 創造 新しいコミュニティやカルチャーを生み出したい 新しいプロダクトやビジネスモデルを創出したい 解明 人間の心理や集団の力学を明らかにしたい 現象のデータを分析し法則性を明らかにしたい 介入 人やチームに寄り添い、変化や成長を支援したい 現場の課題に働きかけ、状況を改善・解決したい 運用 秩序や制度を維持し、公平に運営したい 手続きを正しく回し、品質を保ちたい コメント これまで「SMARTの法則」に則った目標設定は意識していましたが、それは管理する側の視点でした。そのため、取り組む側のモチベーションの観点が不足しうる、という指摘が興味深かったです。SMARTとALIVE両方の観点を取り入れることで、メンバーが主体性をもって取り組めるようになり、結果的に目標達成の確度が上がります。生成AIの急速な進歩で目まぐるしく変化する世の中だからこそ、モチベーションを高く保ち、腰を据えて取り組める目標設定のアプローチとして、私も心がけてみようと思いました。(taishi) 数年後のキャリアプランを立てることに難しさを感じていましたが、「今この瞬間の興味(好奇心)」を起点にするというアプローチは非常に腹落ちしました。技術トレンドの移り変わりが激しいからこそ、無理に未来を固定するのではなく、自分の「好き」や「気になる」を組織の課題と接続し、適応しながら進んでいけるよう、前向きな気持ちで業務に取り組んでいきたいと感じました。(otake) 「ストレッチゾーンに挑戦し続ける」ことって難しくないですか? speakerdeck.com 成長には、現状のスキルで難なくこなせるコンフォートゾーンを抜け出し、適度な負荷がかかるストレッチゾーンに身を置き続けることが不可欠です。しかし、実際には「今の自分に最適な挑戦が不明」「日々の忙しさによる自然消滅」「外部要因による阻害」といった要因で、ストレッチゾーンに居続けることが難しい場合があります。本セッションでは、これらを克服するための環境設計が示されました。 現状分析 : Will/Can/Mustのフレームワークに加え、具体的な事象を問い(Why)で抽象化し、新たなアクション(How)に繋げる「具体と抽象の往復」が重要 目標設定 : コンフォートゾーンの誘惑を断ち切るための武器として、具体的で測定可能な「SMART」だけでなく、チームで共有・可視化され野心的な「FAST」な目標設定を活用する 仕組み化 : マネージャーの支援前提ではなく、権限委譲やシステム思考(因果ループ図など)を用いて、組織として挑戦が推奨される構造を作る コメント 特に印象的だったのは、スナッキング(簡単で達成感はあるが学びが少ない仕事)の誘惑という概念です。忙しいときほど慣れた仕事に逃げてしまいがちですが、それを防ぐために自らFASTな目標を掲げ、周囲に宣言することで、意識的にストレッチゾーンに身を置く工夫を取り入れたいと感じました。 また、SMARTな目標は達成までの道のりが具体的にイメージできる反面、大きな成長につながる目標が生まれにくい側面もあります。これまでチームで目標を共有しても、協力体制が生まれたり切磋琢磨する状態になったりしにくかったため、その点でもFASTな目標設定を取り入れてみたいと思いました。(otake) 「事業目線」の正体 〜3つのフェーズのCTO経験から見えてきた、EMが持つべき視点 speakerdeck.com EMが持つべき「事業目線」を、3つのステップで具体化したセッションです。 Lv.1 数字を知る : 自組織に関わる数字(売上、MAU等)を把握し、事業予算の構造を因数分解して、自分のエンジニアリング組織がどこに作用しているかを理解する Lv.2 お客さまと隣接組織を知る : 数字の裏にある「なぜそうなっているか」を知るために、お客さまの声(生の声)を聞き、経理・営業・CSといった他部門の力学(大切にしていること)を理解する Lv.3 戦略に反映する : 得られた知見をエンジニアリング戦略や組織の仕組み(ダッシュボード化や研修等)に落とし込み、「明日」の大きな問題を解決するために「今日」何をすべきかを決める。 コメント 事業目線という言葉の解像度が劇的に上がったセッションでした。特に隣接組織の構造を知ることで、自分の開発が他部署のオペレーションにどう影響するかまで想像を膨らませるという視点は、シニアなエンジニアを目指す上で欠かせないものだと痛感しました。また、何のために開発しているのかを改めて考えてみて、価値を最大化できるように日々の行動を変えてみたいと思いました。まずは自分のチームに関わる数字を言えるようにするという小さな一歩から始めてみます(otake) 技術的負債の泥沼から組織を救う3つの転換点 speakerdeck.com 著書「アーキテクチャモダナイゼーション 組織とビジネスの未来を設計する」の翻訳を担当された、株式会社スリーシェイクのnwiizoさんによるセッション。技術的負債は「技術」の問題ではなく、組織構造やプロセスの問題が技術的な問題として表出したものだと捉え、モダナイゼーションを推進する手法が紹介されていました。最初に組織に学習する構造を持たせ(転換点1)、次にどこに集中投資するかを意思決定者の言語で語り(転換点2)、最後に不確実性を受け入れつつ小さく始め、学習するサイクルを作る(転換点3)。そのための手法や考え方について詳細に解説いただきました。 転換点1:学ぶ力(組織に学習する構造を持たせる) 組織が自律的にシステムとビジネスの構造を理解し、学び続ける状態を作る段階です。AMET(Architecture Modernization Enabling Team)を触媒として、イベントストーミングやワードリーマッピングなどの手法を活用しつつ、チームが自律的に学習を続けられるようになるまで支援します。 転換点2:語る力(意思決定者の言語で投資判断を促す) 技術的な課題を「コードが汚い」といった技術者の言葉ではなく、経営や事業の成長を阻害する「ビジネスリスク」として翻訳する段階です。Core Domain Chartで自社のドメインを「差別化度」と「複雑性」の2軸で整理した上で、それを事業の選択肢の制約として提示することで、経営層が自分の判断軸で技術投資を評価できる構造を作ることが重要です。 転換点3:始める力(不確実性を受け入れ、小さくサイクルを回す) 成果を出しながら段階的に変革を進める段階です。1つのバリューストリームで小さく始め、3〜6ヶ月以内にモダナイゼーションの第一歩となる成果を出すことを目指します。逆コンウェイ戦略に基づき、理想のアーキテクチャに合わせて組織構造も同時にデザインします。 コメント モダナイゼーションにおける具体的なステップと実践的な手法が紹介されており、とても良質なセッションでした。変革の推進力を高めるだけでなく、変化を阻む摩擦を取り除く重要性とアプローチについても語られており、現場目線で参考になりました。「モダナイゼーションで最も難しいのは着手すること。2番目に難しいのは勢いを維持すること」という言葉も印象に残りました。チームがいかに強い意志をもって持続可能な変化を続けられるかが最重要だと感じています。著書「アーキテクチャモダナイゼーション 組織とビジネスの未来を設計する」もぜひ読んでみたいです。(taishi) まとめ 今回のEMConf JP 2026では、エンジニアリング組織における幅広いテーマが取り上げられていました。 メンバーの視点でも、今この瞬間の興味を起点にした成長戦略、ストレッチゾーンに身を置くための仕組みづくり、事業の数字や隣接組織への解像度を上げることなど、自身の成長とチームへの貢献を加速させるヒントが詰まっていました。 EMConfという名前ではありますが、エンジニアリングに関わるすべての人にとって価値のあるイベントだと感じています。 得られた知見を日々の業務に活かして、個人と組織の両方で成長できるように努力したいと思います!
はじめに タイミー 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 もエンジニアも、今後同じ作業をし続けるわけではなく、その 業務内容自体が変わっていく」 という話がありました。エンジニアという職業はなくならないものの、担う内容は大きく変化していきます。 「ものを作り上げる」という過程そのものは変わりません。しかし、 どうやって作るのか、なぜ作るのか、作った後にどう運用するのか といった、従来のエンジニアリングよりも幅広い領域に踏み込むことが求められるようになります。 QA においても同様です。プロダクトの品質保証にとどまらず、 プロダクトを通じて自社にどのようなリスクが潜んでいるかを提示する ことが必要になります。 例えば、QA がPdMだけでなく事業部や経営層ともつながり、プロジェクトの意思決定に必要な情報を提示する役割を担うとことも、今後は視野に入れていくことが重要です。 品質保証の 範囲・方法・効果の説明責任 などが、今後のエンジニアの責務の一つとして求められていくと感じました。 まとめ JaSST Tokyo'26 を通じて、以上の 3つのキーワード を持ち帰ることができました。 これらはいずれも、 AI 時代により一層求められる力 だと感じました。今回の学びを今後の業務に活かしていきたいと思います。 おわりに 弊社ではQA、SETの採用も積極的に行っております。 hrmos.co タイミーのQA、ソフトウェアテストについてもっと知りたいという方はぜひカジュアル面談でお話ししましょう。 product-recruit.timee.co.jp
はじめに こんにちは。タイミーのデータアナリティクス部でデータアナリストをしているishidaです。普段は、タイミーのプロダクトに関する分析業務に従事しています。 タイミーのデータアナリスト(DA)チームでは、プロダクト施策の効果検証としてABテストを頻繁に実施しています。ABテストの業務は、大きく「 実験設計 」「 クエリ作成 」「 可視化・レポート 」の3工程に分かれますが、これらすべてをDAが担当しています。 施策の数が増えるにつれ、ABテストの “回転数” がボトルネックになりつつありました。そこで私たちは Claude / Cursor を活用し、まず実験設計のレビューを自動化する取り組みを始めました。 本記事では、その仕組みと設計思想をご紹介します。 なお、タイミーにおけるABテストは「① 実験設計 → ② クエリ作成 → ③ 可視化・レポート」の3ステップで進みます。本記事で扱うのは、①の実験設計レビューの自動化です。 1. 実験設計レビューの自動化 課題:レビューの属人化 ABテストの実験設計にはいくつかの重要なチェックポイントがあります。 チェックポイント 確認内容 SUTVA TG/CG間でリソースの奪い合いが起きないか Unit Alignment ランダマイズ単位とメトリクス集計単位は一致しているか SRM サンプル比率のミスマッチを検知できる設計か Novelty/Primacy 経時的変化を考慮した期間設定か Multiple Testing 多重比較の問題を制御できているか Guardrail 副作用を監視するガードレール指標は定義されているか これらのレビューは経験や前提知識によって見落としが生じやすく、属人化しがちでした。 解決策:AIによるチェックリストレビュー 私たちは、実験設計チェックリストを Claude / Cursor のコンテキストに含め、 実験設計ドキュメントを入力するとチェックポイントごとにレビューが返る ようにしました。 具体的には、以下の2種類のファイルをプロジェクトのルールとして設定し、AIに読み込ませています。 実験設計ドキュメントのテンプレート : テスト概要・テスト設計・評価指標などの項目が定義されたMarkdown チェックポイント定義 : 6つの観点それぞれについて「判定の観点」「よくある違反例」「対応方針」を構造化したドキュメント AIレビューの出力イメージ ## CP1: SUTVA ⚠️ リスクあり -TG/CG間でリソースの奪い合いが発生する可能性があります -推奨: クラスタ単位でのランダマイズを検討してください ## CP2: Unit Alignment ✅ 問題なし -ランダマイズ単位と集計単位が一致しています ## CP3: SRM ✅ 設計済み -Debugging Metric として介入の影響を受けない指標を設定 -カイ二乗検定を実験開始時に実行する設計 ... ポイント:AIレビューは「最低限の品質保証」として位置づける 重要なのは、AIレビューを 人間のレビューの代替 としてではなく、 最低限実行されるべきレビュー として位置づけていることです。 AIレビュー = チェックリストの網羅的な確認(漏れ防止) 人間レビュー = ビジネスコンテキストを踏まえた判断(例:この施策ならSUTVA違反は許容範囲か) これにより、レビュー依頼を受けたDAは「AIが見つけた問題点」を起点に議論できます。 学び AIレビューは「ゲートキーパー」ではなく「下書き」 AIレビューの結果を鵜呑みにせず、「少なくともこのレベルのレビューは済んでいる」という 品質の下限保証 として使っています。最終判断は必ず人間が行います。 この位置づけにしたことで、「AIに任せて大丈夫か」という心理的なハードルも下がります。 We’re Hiring! 私たちは、ともに働くメンバーを募集しています!! データアナリストの募集ページはこちら カジュアル面談も行っていますので、少しでも興味がありましたら、気軽にご連絡ください。
はじめに こんにちは。プラットフォームエンジニアリングチームに所属している徳富( @yannKazu1 )です。 新規プロダクトを立ち上げるとき、インフラ構築って意外とやることが多いですよね。その中でも地味にめんどくさいのが DBユーザーの作成と権限付与 。手動でやると「あ、権限つけ忘れた」「このユーザー名スペルミスってない?」みたいなヒヤリハットが発生しがちです。 今回は、この作業をTerraformでIaC化した話を書いていきます。 背景:ボイラープレートでインフラ構築を爆速にしている 弊社では Terraformのボイラープレート と、それをもとにインフラを構築するための Devinへの指示プロンプト をセットで管理しているリポジトリがあります。 新規プロダクトのインフラが必要になったら、このリポを使ってDevinにお願いするだけ。数時間もあれば、AWSアカウントの作成、VPC・ECS・Auroraなどの基盤構築、Terraform実行に必要なIAMロール・バックエンド・CI/CDワークフローの設定に加え、Datadog設定、監査設定、ログ基盤の作成まで、必要なインフラがひととおり立ち上がります。 このボイラープレートを整備するにあたって目指したのは、「Devinにお願いするだけで、新規プロダクトのインフラを簡単に作れる状態」でした。ところが、 DBユーザーの作成だけはどうしても手動作業が残ってしまっていました 。 せっかくDevinに投げれば数時間でインフラができるのに、DBユーザーだけは人間が踏み台経由でDBに繋いで CREATE USER して GRANT して……とやらないといけない。これだとボイラープレートの意味が薄れてしまいますし、手動オペレーションにはミスのリスクもあります。 ここをTerraformでIaC化できれば、ボイラープレートにサクッと組み込めて、Devinに任せるだけでインフラ構築が完結するようになります。 なぜTerraform? DBユーザーの管理といえばAnsibleを使うパターンも考えました。ただ、弊社のインフラは基本的にTerraformで一元管理しているので、できればTerraformの中で完結させたい。ツールが増えると学習コストも運用コストも増えますし、ボイラープレートにAnsibleのステップを追加するよりも、Terraformモジュールとして組み込む方がシンプルです。 というわけで、Terraformでなんとかする方向で調査を進めました。 Aurora Data APIという選択肢 弊社ではAurora MySQLを使用しており、バージョン3.07以降でRDS Data APIに対応しています。 Data APIは、HTTPSエンドポイント経由でSQLを実行できるAPIです。従来のようにVPC内から直接DBに接続する必要がなく、AWS CLIやSDKからサクッとSQLを叩けます。 これを terraform_data リソースの local-exec プロビジョナーと組み合わせれば、Terraformの中からDBユーザーを作成できるというわけです。 モジュールの実装 実際に作ったTerraformモジュールを紹介します。 DBユーザーの作成・削除 resource "terraform_data" "db_user" { input = { rds_cluster_arn = var.rds_cluster_arn rds_secret_arn = var.rds_secret_arn database_name = var.database_name username = var.username ssm_parameter_name = var.ssm_parameter_name } provisioner "local-exec" { command = <<-EOT PASSWORD=$(aws ssm get-parameter --name "$ { self.input.ssm_parameter_name } " --with-decryption --query 'Parameter.Value' --output text) aws rds-data execute-statement \ --resource-arn "$ { self.input.rds_cluster_arn } " \ --secret-arn "$ { self.input.rds_secret_arn } " \ --database "$ { self.input.database_name } " \ --sql "CREATE USER IF NOT EXISTS '$ { self.input.username } '@'%' IDENTIFIED BY '$PASSWORD'" EOT } provisioner "local-exec" { when = destroy command = <<-EOT aws rds-data execute-statement \ --resource-arn "$ { self.input.rds_cluster_arn } " \ --secret-arn "$ { self.input.rds_secret_arn } " \ --database "$ { self.input.database_name } " \ --sql "DROP USER IF EXISTS '$ { self.input.username } '@'%'" EOT } } ポイントは以下のとおりです。 terraform_data リソースを使って、 local-exec プロビジョナーでData API経由のSQLを実行 CREATE USER IF NOT EXISTS で冪等性を担保 when = destroy のプロビジョナーで、 terraform destroy 時にユーザーを自動削除 パスワードはSSM Parameter Storeから取得(後述の工夫で安全に管理) 権限の付与・取り消し resource "terraform_data" "db_grant" { for_each = { for idx, grant in var.grants : idx => grant } depends_on = [ terraform_data.db_user ] input = { rds_cluster_arn = var.rds_cluster_arn rds_secret_arn = var.rds_secret_arn database_name = var.database_name username = var.username privileges = each.value.privileges grant_database = coalesce (each.value.database, var.database_name) grant_table = coalesce (each.value.table, "*" ) } provisioner "local-exec" { command = <<-EOT aws rds-data execute-statement \ --resource-arn "$ { self.input.rds_cluster_arn } " \ --secret-arn "$ { self.input.rds_secret_arn } " \ --database "$ { self.input.database_name } " \ --sql "GRANT $ { self.input.privileges } ON $ { self.input.grant_database } .$ { self.input.grant_table } TO '$ { self.input.username } '@'%'" EOT } provisioner "local-exec" { when = destroy command = <<-EOT aws rds-data execute-statement \ --resource-arn "$ { self.input.rds_cluster_arn } " \ --secret-arn "$ { self.input.rds_secret_arn } " \ --database "$ { self.input.database_name } " \ --sql "REVOKE $ { self.input.privileges } ON $ { self.input.grant_database } .$ { self.input.grant_table } FROM '$ { self.input.username } '@'%'" || true EOT } } for_each で権限セットを柔軟に定義できるようにしています。DMLとDDLを分けて付与したい、みたいなケースにも対応可能です。 使い方 モジュールの呼び出しはこんな感じです。 module "db_user_app" { source = "../../modules/db_user" rds_cluster_arn = module.aurora_main.cluster_arn rds_secret_arn = module.aurora_main.cluster_master_user_secret [ 0 ] .secret_arn database_name = "hoge_db" username = "hoge_app_user" ssm_parameter_name = aws_ssm_parameter.app_db_password.name depends_on = [ aws_ssm_parameter.app_db_password, module.aurora_main, ] grants = [ { # DML権限: データの読み書き privileges = "SELECT, INSERT, UPDATE, DELETE" } , { # DDL権限: マイグレーション実行用(テーブル作成・変更・削除、インデックス操作) privileges = "CREATE, ALTER, DROP, INDEX, REFERENCES" } ] } DMLとDDLの権限を分けて書けるのが個人的に気に入っています。どの権限を付与しているかが一目でわかりますし、将来的に読み取り専用ユーザーを追加したいときもモジュールを再利用するだけでOKです。 パスワードをstateに残さない工夫 ここが今回一番こだわったポイントです。 Terraformでパスワードを扱うとき、普通にやるとstateファイルにパスワードが平文で残ってしまいます。 sensitive = true をつけても、plan出力でマスクされるだけでstateには書き込まれてしまう。これはセキュリティ的によろしくないですよね。 そこで活用したのが、 Terraform 1.10で導入された ephemeral リソース と、 Terraform 1.11で導入された value_wo (write-only引数) です。 ephemeral "random_password" "app_db" { length = 32 special = false } resource "aws_ssm_parameter" "app_db_password" { name = "/$ { var.app_name } /$ { var.env } /db/app_user_password" type = "SecureString" value_wo = ephemeral.random_password.app_db.result value_wo_version = 1 } ephemeral リソースとは Terraform 1.10で登場した新しいリソースタイプです。通常の resource や data と違い、planやstateに一切値が保存されません。毎回のplan/apply時に一時的に生成され、使い終わったら破棄されます。 ephemeral "random_password" を使うことで、パスワードの生成結果がstateに残ることを防げます。従来の resource "random_password" だと、生成したパスワードがstateファイルにそのまま記録されてしまっていたので、これは大きな改善です。 value_wo (write-only引数)とは Terraform 1.11で導入されたwrite-only引数の仕組みです。 aws_ssm_parameter リソースの value_wo を使うと、SSM Parameter Storeへの書き込みは行われますが、その値がTerraformのstateやplanファイルに保存されることはありません。 value_wo_version は変更検知のためのバージョン番号です。パスワードをローテーションしたい場合はこの値をインクリメントすれば、次のapply時に新しいパスワードが生成・設定されます。逆にバージョンを変えなければ、 ephemeral が毎回新しいパスワードを生成しても、SSM Parameter Storeの値は更新されません。 この2つを組み合わせることで、パスワードの生成から保存まで、 一度もstateファイルにパスワードが記録されない フローが実現できました。 現時点での制約:パスワードの更新には対応していない ここまで読んで「パスワードのローテーションはどうするの?」と思った方もいるかもしれません。正直に言うと、 このモジュールはパスワードの更新( ALTER USER )には対応していません 。 理由はシンプルで、Terraformのプロビジョナーには when = create と when = destroy しかなく、 when = update が存在しない からです。つまり、リソースの入力値が変わったときに「更新用のSQLを実行する」ということができません。 terraform_data の input が変わると、Terraformは古いリソースをdestroyしてから新しいリソースをcreateする(replace)動きになります。DBユーザーの場合、これは DROP USER → CREATE USER という流れになるので、パスワード変更だけしたいケースには少々大げさです。 この when = update の追加については、HashiCorpのGitHubリポジトリにIssueが上がっています( hashicorp/terraform#35825 )。いつか実装されれば、パスワードローテーションもこのモジュールの中でスマートに対応できるようになるはずです。それまでは、パスワードの更新が必要になった場合は手動対応か、別の仕組みで対応する必要があります。 とはいえ、新規プロダクト立ち上げ時の初期ユーザー作成という用途においては、create/destroyだけで十分に機能しています。 まとめ やったことをまとめると以下のとおりです。 Aurora MySQLのData API(3.07以降で利用可能)を使って、Terraformの terraform_data + local-exec でDBユーザーの作成・権限付与をIaC化 Terraform 1.10の ephemeral リソースと1.11の value_wo を活用して、パスワードをstateに残さないセキュアな構成を実現 これらをモジュール化してボイラープレートに組み込み、新規プロダクトのインフラ構築をさらにスムーズに プロビジョナーに when = update がないため、パスワードの更新には現時点では未対応 Terraformの ephemeral や value_wo はまだ比較的新しい機能なので、知らない方も多いかもしれません。パスワード管理で困っている方はぜひ試してみてください。 参考リンク Amazon Aurora MySQL で RDS Data API のサポートを開始 RDS Data API でサポートされているリージョンと Aurora DB エンジン - Amazon Aurora Terraform 1.11 brings ephemeral values to managed resources with write-only arguments Ephemeral values in Terraform Ephemeral values in resources | Terraform | HashiCorp Developer Use temporary write-only arguments | Terraform | HashiCorp Developer I would like provisioner/s to support when=update - hashicorp/terraform#35825
はじめに こんにちは、株式会社タイミーでプロダクトAIエンジニアとして働いている貝出です。直近は、タイミーの求人内容などのコンテンツモデレーションにLLMを利用した、システム開発や性能改善を行っています。 2026年3月9日(月)〜3月13日(金)に開催された「言語処理学会第32回年次大会(NLP2026)」に、今年は初めて現地参加しました。大会2日目は記録的な大雪に見舞われ、会場にたどり着くだけでひと苦労でしたが、それでも現地ならではの熱気は格別で、ポスター発表や他社エンジニアとの立ち話など、オンラインでは得られない学びが随所にありました。 NLP2026では多くの発表がありましたが、本記事ではLLMの評価・品質保証・安全性に関する発表に絞って紹介します。単に発表内容を紹介するだけでなく、実際のプロダクト開発や評価データ設計にどう接続できるかという観点で読み解きます。研究と実務をつなぐ視点として、評価設計やベンチマーク整備のヒントになれば幸いです。 大会2日目の大雪 言語処理学会年次大会について 会場内看板 anlp.jp 言語処理学会年次大会は 言語処理学会 が主催する学術会議であり、国内における言語処理の研究成果発表の場として最大規模のイベントです。 今年で第32回を迎え、発表件数は797件、最終日までの参加者数は2,316人と過去最大を記録しました。年々規模が拡大しており、NLP分野への関心の高さが伺えます。LLMの登場により一時は「研究することがなくなるのでは?」という懸念もあり、2023年には「 ChatGPTで自然言語処理は終わるのか 」というテーマでパネルディスカッションが行われたこともありました。しかしその懸念に反して、近年は「安全にLLMをどう使うか」「LLMの挙動をどう解釈するか」といった観点の研究が増えてきており、まだまだ研究題材は尽きない印象です。 なお、発表論文は言語処理学会のWebページで公開されているため、当日参加できなかった方でも閲覧可能です。 私自身も今回、社会人大学院での研究内容をもとに ポスター発表 を行いました。多くの方と議論でき、大変刺激になりました。合計90分間、ポスターの前で参加者に説明したり質問に答えたりと、途中で酸欠になりそうなほど白熱したセッションでしたが、ありがたいことにスポンサー賞としてレトリバ賞をいただくことができ、とても良い思い出になりました。 興味深かった発表 普段の業務では、「LLMを活用してビジネス課題をいかに解決するか」という問いと同時に、「LLMの出力をどう評価するか」「そのための評価データをどう設計するか」といった問題にも日々向き合っています。今回は、こうしたLLMの評価・品質保証・安全性というテーマを軸に、特に業務課題と関連の深かった4件の発表を取り上げます。 チュートリアル3:信頼できるAIへのソフトウェア工学からのアプローチ:「品質」技術の動向と課題 発表内容 本チュートリアルでは、ソフトウェア工学の観点から「信頼できるAI」の品質保証技術について解説されました。 まず、品質は「複数の特性から構成され、様々なニーズや要求を満たすこと」と定義されると説明されていました。また、品質には、対象システム自体に対して測るもの(例: レイテンシなど)と、実際にシステムを利用する段階で計測可能なもの(例: 顧客満足度など)の2種類が存在するとのことでしたした。そのうえで、価値やリスクはシステム全体で評価されるべきであり、AI部品ごとに適切に評価することの重要性が強調されていました。 AIの品質保証に関するガイドラインとしては、AIQMやQA4AIなどが紹介されました。これらのガイドラインでは、「AIパフォーマンス」「リスク回避性」「公平性」といった機械学習に特有の品質や、それを評価するための「被覆性(事例パターンが網羅的に含まれているか)」や「均一性(実際の母集団の分布に近いか)」などのデータセットにおける品質の重要性も整理されていました。 一方で、LLMの普及に伴い、入出力が非定型になってタスクの境界が曖昧になっています。また、正解が一意に決めづらくなったことで、評価・改善の難易度と工数が増大しているという現場課題も指摘されていました。LLMの手軽さからシステム開発自体は進めやすくなった反面、活動の重心は「開発」から「評価・改善」へと移行しています。しかし、「開発」と違って「評価・改善」では、工数換算をする意識が低くなりがちです。そのため、評価・改善の継続的サイクルを定着させることが困難だという課題が挙げられていました。 また、モデル評価の文脈としてソフトウェア工学における「自動テスト生成」の手法が紹介されました。代表的なものの一つが、テスト生成を最適化問題に帰着させてメタヒューリスティックに解く Search-Based Testing(探索的テスト) です。たとえば自動運転の分野では、この手法を用いることで事故が起きやすい弱点領域を探索したり、モデルの性能限界の境界を可視化したりすることが可能になっています。 最後に、言語モデルが今後ロボットや自動運転など物理世界にも応用されていく中で、よりリスクベースの評価が必要になるという展望が示されました。 感想 「開発」から「評価・改善」にエンジニアの工数の主なタスクが移り変わっているというところも、たしかになと思わずうなずいてしまいました。今後は「モデル開発」よりも、どう評価するか、どうデータセットを作るのかにML/AIエンジニアの重心が移るのかもしれません。 また、Search-Based Testingは初めて聞いたのですが、LLM審査のコンテキストに当てはめると、微妙な偽陽性・偽陰性を生む「境界線にある言い回し」を自動探索し、モデルやプロンプトの弱点を事前に洗い出す、といった使い方ができそうだと感じました。 [ B2-1 ] chakoshi Fine: 多層防御に基づくLLM向けガードレールの設計と実装および評価 発表内容 本研究は、生成AIの安全な業務利用のためのガードレール構築に関するものです。前年のNLP2025で発表された chakoshi の発展系にあたります。 chakoshi では単一モデルに複数の役割を担わせていたため、あるリスクの検知精度を伸ばそうとすると別の精度が低下しやすいという構造的な制約が課題でした。本研究ではこの課題に対し、リスクごとに特化した5つの独立した防御機構を段階的かつ選択的に適用する多層アーキテクチャ chakoshi Fine を提案しています。複数のコンポーネントに分割したパイプライン構造にすることで、単一モデルでの全体最適化を避け、各ポリシーが専門性を高めつつ相互に弱点を補完する設計になっています。この結果、既存の商用ガードレールサービスと比較して高い検知精度を達成していました。 さらに、擬似業務タスクを通じて実際の業務を想定した有用性評価も行われています。ガードレール導入の有無が人間のタスク正答率や平均所要時間に統計的な差を与えなかったという結果が示されており、過剰検知によるユーザー体験の悪化や業務効率の低下を防ぎつつ、パスワード漏洩のような不正な入出力に対しては、98%の確率で遮断できていました。 感想 ガードレールを利用する際は、どうしても使用感が気になります。本研究が、検知精度だけでなく処理速度や「ユーザー体験を損なわないか」という点まで踏み込んで評価してくれているのは、実務側としてありがたいです。また、4B程度の軽量なLLMでもガードレールのスコープによっては、ある程度検知精度が担保できるという点も個人的には発見でした。 [ Q4-3 ] LegalRikai: Open Benchmark - 法務ドメインの日本語ベンチマーク 発表内容 本研究は、実際の法務業務のワークフローを模した、法務ドメインにおける新たな日本語ベンチマーク LegalRikai を提案しています。 このデータセットは、弁護士の監修のもとで人手による精緻なアノテーションが行われており、高コストではあるものの高品質な内容となっています。法令改正の要約や指示に基づく契約書編集など、実際の法務業務を模した4つの複雑なタスクから構成されており、法務文書特有の長文インプットに対して構造化された出力を求める設計になっています。 評価においては、単一の指標ではなく、指示の遵守度・契約書全体の構造の一貫性・不要な変更の有無など、実務に即した複数の観点から評価する尺度が採用されています。正解データの作成から評価に至るまで専門家が深く関与しているため、データ数は各タスク25件と少数ながら厳選された内容です。さらに、評価者間の一致度(Cohen の κ スコア)を計測することで、アノテーションの妥当性やガイドラインの信頼性を担保しており、LLMの法務実務における実力を正確に測るための堅牢な基盤を提供しています。データセットは公開されており、論文内のリンクから参照可能です。 感想 「専門ドメインのベンチマークをどう設計するか」という観点で非常に参考になる研究でした。特に、評価観点を実務の複数軸に分解している設計や、少数でも質を担保するためにアノテーターの一致度を計測している点は、評価データを整備する際にも応用できそうです。「データ数は少なくても、専門家による厳密な設計で品質を担保する」というアプローチは、社内の評価データ構築においても積極的に取り入れたい考え方です。 [ B8-13 ] 医療系対話AIにおける評価基準の策定と自動評価手法の比較検証 発表内容 本研究は、日本の医療事情に即した独自の評価データセットを構築し、医療系対話AIにおける「LLM-as-a-Judge」を用いた3つの自動評価手法を比較検証したものです。具体的には以下の3手法が比較されました。 総合評点方式 :詳細なガイドラインに基づき1〜10点でスコア化 総合評点方式(簡易版) :評価の観点のみを提示 項目別評価方式(チェックリスト形式) :具体的な評価項目に対してTrue/False判定を行い加重スコア化 実験の結果、モデル間の全体的な性能差を識別する能力においては、意外にも詳細な指示を与えない「総合評点方式(簡易版)」が最も優れていることが分かりました。一方で、個別の会話に対する評価の「一貫性」や、医学的に危険な回答を確実に除外するといった「説明可能性・安全性」の観点では、「項目別評価方式」が最も優れていることが示されています。目的(モデル全体の性能比較か、個別回答の厳密な品質保証か)に応じて適切な評価アプローチを使い分ける重要性が裏付けられた研究です。 感想 「簡易版のほうがモデル間の性能差を検出しやすい」という結果は、直感に反していて面白かったです。評価指標によっては、どの形式の評価にするかを実施前に比較しておくといいのかもしれません。 「項目別評価のルーブリック設計には専門家のコストがかかる」という点は、スポンサーブースで他社のエンジニアと話していたときにも、全く同じ悩みとして挙がっていました。「評価の精度を上げたいが、設計コストをどこまでかけられるか」というトレードオフは、ドメインを問わず共通の課題なのだと改めて実感しました。スモールスタートする場合は「まず簡易版で全体傾向を把握し、問題が疑われる領域だけ項目別で深掘りする」という使い分けが現実的かもしれません。 おわりに 今回取り上げた4つの発表は、主に評価、評価データ、そして安全性に関するものでした。LLMの能力が飛躍的に向上した今、「人間の期待通りに生成できているのか」「安全にLLMを利用できているのか」という問いへの関心はますます高まっており、研究も着実に進んでいる印象です。 NLP2026では今回紹介しきれなかった魅力的な研究も数多くあり、この領域の裾野の広がりを実感しました。タイミーを安心・安全なプラットフォームとして維持するためのLLM活用について、多くの示唆を持ち帰ることができた大会でした。 We’re hiring! 現在、タイミーでは、データサイエンスやエンジニアリングの分野で、共に成長し、革新を推し進めてくれる新たなチームメンバーを積極的に探しています! product-recruit.timee.co.jp また、気軽な雰囲気での カジュアル面談 も随時行っておりますので、ぜひお気軽にエントリーしてください。↓ hrmos.co hrmos.co hrmos.co
福岡Rubyist会議05 参加レポート こんにちは!Timeeでバックエンドエンジニアをしている志賀( @akitoshiga )です。 表題の通り「福岡Rubyist会議05 」に参加してきたのでそちらのレポートを書きたいと思います! regional.rubykaigi.org 今回「Kaigi Pass」という社内制度を利用して参加しました。 「Kaigi Pass」とは、世界中で開催されているあらゆる技術カンファレンスへの参加を支援する制度です。 productpr.timee.co.jp 会場の様子 当日は福岡県福岡市博多区にある「リファレンス駅東ビル」というところで行われました。 会場いっぱいに来場者が集まりとても賑わっていました。 また、会場には福岡県八女市の名物である八女茶が提供されていました。 自分もいただいたのですがとても美味しかったです。 セッション 特に自分の関心が高かったセッションを3つほど紹介したいと思います。 SQLQL とは何だったのか 発表者 : yancya( @yancya )さん www.slideshare.net yancyaさんが取り組まれているSQLQLについての概要と、技術の変遷に伴ったアップデートのお話でした。 SQLQLとはWebクライアントからSQLクエリを送信して、その実行結果をJSONで返すというコンセプトです。 GraphQLのSQL版と考えるとイメージが掴みやすいと思います。 SQLQLに関しては以下で詳しく解説されています。 SQLQL #Rails - Qiita Client Challenge なお、ここではRDBMSにPostgresを使用することを前提としています。 SQLQLはクライアントが任意でSQLを送信できるので、これを安全に使えるようにするためにさまざまな工夫が施されていました。 WITH句によるCTEを使って取得対象のDBをラップすることでアクセスできる属性を絞り、秘匿すべきデータへのアクセスを制限しています。 INSERT, UPDATE, DELETEといった副作用を伴う操作に関しては自由に実行できないようにSELECTのみの権限しか実行ユーザーには与えず、定義した書き込み権限のあるストアドプロシージャでしか副作用のある操作を実行できないような仕組みを取られていました。 また、悪意のあるクエリの対策としてpg_queryによってクエリをパースしてAST(抽象構文木)をチェックしていました。 課題も存在していて、再帰処理にはうまく対応できないそうです。 SQL ServerやMySQLは再帰処理の深さを設定できるのですが、Postgresだと存在していないため代わりにタイムアウトのみで設定しているそうです。 クライアントでクエリをフェッチすることが可能になるので、これを用いたときにAPI開発コストの削減に繋がるのは良さそうだなと思いました。 ビジネスロジックがストアドプロシージャに集中してしまわないかなというのと、サーバー側ではクエリを効率化できないのでデータ量が多かったりリレーションの複雑なテーブルからデータを取得する場合はクライアント側で工夫が必要だなと感じました。 SQLをそのままパラメーターにしてWeb経由でクエリを投げるアイデアと、安全性を担保するためのさまざまな試みに技術者のロマンを感じました。 再帰処理に関してはPostgreSQLに存在するCYCLE句を使えば安全に扱えそうなのですが、そうすると特定のRDBMSに依存してしまうのと、クライアントとクエリの決め打ちをしなければならずコンセプトと乖離しそうな気がするので悩みどころだなと感じました。 今回はこのSQLQLのアップデートとしてWAL監視のアイデアを取り込んだデモアプリを披露されていました。 WAL(先行書き込みログ)とはデータベースに変更を行う前に操作内容を記録するログのことであり、このWALを監視することでリアルタイムなデータストリームの観測が可能で、このアイデアをSQLQLに応用されていました。 WAL監視については自分は初見だったのですが、CDC(Change Data Capture)の実装に利用されたりしているそうです。e.g. Debezium Server このほかにもSQL標準の変遷やLive QueryなどSQLQLを起点としてDB 、データ基盤についての幅広いお話を伺いました。 Live Queryで話に上がっていたKafka Streamsについては内部動作と構造に興味が湧いたので後日その深掘りをしてみました。 また、WAL監視については今後複数コンポーネント間でリアルタイムにデータ更新を検知したいときなどにこのアイデアが役立ちそうだなと思いました。 型を書かないRuby開発への挑戦 発表者 : shia( @riseshia )さん speakerdeck.com 自作GemのTypeGuessrのお話。 TypeGuessrは「型情報を開発者が追加せずに型情報を得る」ことをコンセプトに開発されたGemで、Ruby LSPのアドオンという形で使用します。 github.com Rubyに型情報をもたらすツールはいろいろありますが、SteepやSorbetといったような型定義を行い正確な型情報を得るものとは明確に棲み分ける形で開発されています。 Hash/Arrayに対してStructural Typing(構造的部分型)をサポートしつつも複雑な型推論が走りそうな場合はあえてuntypedにして計算量をコントロールしています。 特徴として、Duck Typingに基づくヒューリスティックな推論を用いて型情報を取得しており、クラスに定義されたメソッドをそのレシーバーから辿ることによってこれを実現しています。 この方法でも行数が10万行以上のRailsプロジェクトであれば平均10%〜20%で型情報を得られるそうです。 Duck Typingを利用して振る舞いから型を推論する部分はRubyらしさを感じるとともにユニークで興味深いなと思いました。 まだできたばかりでパフォーマンスには向上の余地があるそうで、このアプローチでどのようにこれらを解決していくのか動向を追ってみたいなと思いました。 少し話は逸れますが、型検査ツールのパフォーマンス改善という話でふと去年の関西Ruby会議で聞いたpockeさんのこのキーノートを思い出しました。 speakerdeck.com Steepのメモリ削減のために自作のプロファイラで観測してプロセス間通信のレベルまで踏み込んで改善に取り組んだ過程がとても面白かったので、よかったらこちらもチェックしてみてください。 Ecosystem on parse.y 発表 : S.H.さん S.H.さんが開発されているparse.yを利用したGemであるkanayagoとigata、そしてこれらを組み合わせたエコシステムのお話 parse.yとはRubyの文法定義ファイルのことで、昨今のRubyist界隈を取り巻くパーサームーブメントを語る上で欠かせないものです。 parse.yはRubyコミッターのydahさんの以下のスライドがparse.y周辺の情報やパーサー自体についても丁寧に解説されていて理解しやすいです たのしいparse.y - Speaker Deck S.Hさんはこのparse.yを利用して、パースしたAST(抽象構文木)ノードをRubyクラスとして扱うことができるkanayagoを開発されました。 github.com ASTをRubyオブジェクトにすることで従来よりももっと手軽にASTを扱えるようになり、パターンマッチングにも対応可能になっています。 これによってコード解析・構文チェックなどといったRubyの文法のASTに関する操作がとても直感的・簡単に行えるようになっています。 またS.Hさんはこのkanayagoをベースとしてigataとkanayago-lspを開発されました。 github.com igataはkanayagoが生成するRubyクラス名、メソッド名、引数の情報などを抽出してMinitestやRSpecに対応したテストファイルを自動作成します。 これに加えてLLMと組み合わせて、テストの中身まで自動補完させる運用も想定されています。 kanayago-lspはkanayagoを用いてVSCodeやVimなどで利用でき、Rubyの新しいパーサーであるPrismでは検知できないものも検知できるそうです。 S.Hさんはこのparse.y、これを利用したkanayagoを利用したエコシステムの構築を目指しており今後はLinterの開発を目指しているそうです。 S.HさんのASTに使われる各ノードを体系立った独自のRubyクラス群にラップするというアイデアがとても素晴らしいなと思いました。 parse.yから生成できるノードは100種類以上あるのでかなり根気がいる作業だと思いましたが、ここは生成AIをうまく活用されたそうです。 Ruby3.4からデフォルトパーサーがparse.yから生成されるパーサーからPrismに置き換わりましたがparse.yの根強い人気というか盛り上がりを感じました。 先ほど紹介したTypeGuessrもそうなのですが、何かを作るにあたりよりRubyらしさを追求するアプローチをみなさんされていて、このマインドはRubyistに通じるものなのかなと感じていました。 これらは開発のお手伝いをしてくれる方を絶賛募集中とのことです。自分もとても興味があるので機会があればパッチを投げたいなと思いました。 そのためにkanayago自体も積極的に使ってみたいと思います。 これらの他にもこの日のセッションはPicoRuby、VM、Deep Researchなど、とてもバラエティに富んでいて非常に面白かったです。 まとめ 福岡Rubyist会議に参加したのは初めてだったのですが、自分は人との距離が近い地域Ruby会議が好きなので今回行くことができて良かったなと思いました。 セッション終了後にも以前からオンラインでお世話になっていたコミュニティの方や、現地コミュニティの方々とも交流できたのも非常に嬉しかったです。 ぜひまた次回も参加したいと思います!
こんにちは。タイミーでAndroid Chapter Leadをしているmurataです。 普段はAndroidコミュニティの運営やTech Lead的な動きをすることが多いのですが、今回はいつもの技術領域とは少し異なる視点を得たくて、今回のEngineering Management Conference Japan 2026(以下、EM Conf)に参加しました。 EM系のカンファレンスは初参加でしたが、新たな世界を見ることができた1日でした。 📝 注記 各セッションの「聞いたこと」は、私なりに理解し印象に残ったポイントの 抜粋 です。実際の講演内容と齟齬がある可能性があるためご了承ください。 印象に残ったセッション 冒険する組織のつくりかた 安斎 勇樹(Yuki Anzai)さんによる基調講演です。 「これまでのマネジメントは軍事的世界観で語られがちだったが、これからは“冒険的世界観”で組織づくりをする」という話が軸でした。 EM業に不慣れな自分でも理解しやすく、すぐに実践できそうな内容が多いセッションでした。朝イチから目が覚めるような学びがありました。 セッションで聞いたこと(抜粋) 危機感を煽るマネジメントは、いまの環境だと人が離れるだけになりやすい “冒険的”な組織は、外向きで、感情を重視する 「今すぐ改善できる、半径5mのもの」 目標のマネジメント 目標が機能しない背景に「納得がない」「内発的動機がない」「みんなでやる意味がない」がある 軍事的マネジメントは目標に対する視野狭窄をつくることだった SMARTだけでなく、ALIVEのような「取り組む側が前向きな意味を感じられる指標」も両立させる 会議のマネジメント 「何かいいアイデアないですか?」「FBないですか?」という問いは、発言を引き出しにくい 「この企画案、どこか1つ変えるとしたら?」「もしお客さんなら何点をつけますか?」のように具体で答えやすい問いにすると発言がすぐ飛び出す 興味のマネジメント 以前は「3年後のwill」を起点に目標を逆算しがちだったが、いまはwillが出てこないことも多い 「興味があるもの」「面白いと思っているもの」を聞いてキャリア支援する方が今に向いている 学び・感想 目標設定は感覚で“SMARTっぽく”やっていましたが、ALIVE *1 の観点は初耳だったので次から意識してやってみます 会議で「何かありますか?」を幾度となくやってしまっていたので、問いの設計を今日から変えます タイミーで取り入れているファイブフィンガー(手の本数で賛成度・懸念度を示すシンプルな意思表示の方法)は、この「問いかけを工夫して発言を引き出す」方向性と相性が良さそうだと感じました 「ストレッチゾーンに挑戦し続ける」ことって難しくないですか? メンバーの持続的成長を支えるEMの環境設計 (ぎーにょさん) 「自分の目標ですらストレッチし続けるのは大変なのに、EMはメンバーにどのようにストレッチさせているのか?」という関心から、このセッションに飛び込みました。辛いですよね、目標設定。 セッションで聞いたこと(抜粋) 「ストレッチゾーンが無い」状態には、いくつかのパターンがある 今の自分に最適なチャレンジが分からない → 現状を分析する 途中で自然消滅しそう → 目標を立てる 外部要因で止まりそう → 実行を支援する EMが全部を背負うとボトルネックになるため、スケールに備えた“持続可能な仕組み”が重要 心理的ハードルを下げて変化を起こす施策として、ADRを用いて、コードベース全体に影響する提案と承認のプロセスをルール化する例が紹介されていた 学び・感想 ADRの話は、以前導入した タイミーAndroidChapter式LADR と狙いが近く、方向性は間違っていなさそうだと勇気づけられました 一方で、紹介されていた取り組みは“施策の寄せ集め”ではなく、「なぜストレッチが難しいのか」を構造として捉え、分析したうえで仮説→検証で進めている点が強かったです 自分は点でhowを増やしがちなので、システム的に捉える筋力を身につけたいです 余談ですが、スライドの写真と登壇者の雰囲気に違いがあり印象に残りました(どちらも素敵でした!) 守る「だけ」の優しいEMを抜けて、事業とチームを両方見る視点を身につけた話(Mitsuiさん) 「チームを守る盾」と「成果を出す槍」を状況に応じて使い分ける、実体験に根ざした話で、リアリティが強かったです。 セッションで聞いたこと(抜粋) 立て直しの局面では、まずチームを外圧から守りきることが重要 ただし、それだけを絶対視すると、求められる事業の成果とズレる局面が出てくる EMは、事業とチームの両方を見て判断するための軸と、実行の引き出しが求められる 学び・感想 mitsuiさんが「理想のEM像」として信じていた以下のポイントは、たしかに大事(で、私の理想ともほぼ一致しています)。 サーバントリーダーシップ ピープルマネジメントの徹底 ボトムアップの組織 ただし“常にそれが正”ではなく、最終的には事業貢献・企業価値への影響を最大化するのが目的。 その目的に照らして、状況で使い分ける意思とスキルが必要なのだ、と腹落ちしました 「開発生産性」ではなく「事業生産性」こそが本質(江副 廉人さん) セッションで聞いたこと(抜粋) EMとして「事業生産性」を意識し、投下資本に対する利益率(ROIC)の観点から“稼ぐ力”を最大化していくことが重要 企業価値の算出方法としてDCF法 *2 がある 学び・感想 自分の中で「ROICを意識する重要性」を理解できました ただ、現実の会話に落とす難しさも同時に強く感じました 各変数をそもそも数値化するためのスキルが必要 EMになると、こういった数字が“即答できて当たり前”なのか それとも、会社として“取りに行けば取れる”状態にしておくのが前提なのか 後者の観点で、全社としてROICや関連指標がパッと出るようにイネイブリングされると、指標としての活用が進み、事業生産性への意識も広まりやすいのではないかと無邪気に感じました ブースで印象に残ったこと(DRESS CODE様) DRESS CODE様のブースでは、写真のように「EMの取り組みとして無くなっていくもの」と「今後期待されるもの」について、たくさんの付箋が貼られていました。 一見「え、そうなの?」と思うものもあり、興味深かったです。特に目に留まったのは、「無くなっていくもの」にあった以下の2点です。 「睡眠時間!!」 エンジニアのAI活用によりアウトプットが増え、結果として仕事量が増えるため、という文脈 「定量的な評価」 今後はAIがデータを収集し、定量評価を代替していくため、という文脈 不要になるのかと思いきや、役割がスライドしたということですね さいごに 普段参加する技術系カンファレンスとは見える景色が全く違い、とても面白かったです。 特に印象に残ったのは、テクニックの話に入る前に「そもそも何を大事にするのか」がどのセッションでもきちんと語られていたことでした。 学んだら実践ということで、まずは半径5mの範囲で、問いの立て方や目標の置き方を変えるところから始めます。 「知った」で終わらせず、仕事の中で試して定着させ、“増殖”させていきます! *1 : 目標の精度を高めるSMARTに対し、実行者の『感情・価値観・継続性』に焦点を当てた目標設定フレームワーク。 参照: 組織を活性化する目標設定:SMARTからALIVEへ ビズユーコンサルティング *2 : 将来期待されるキャッシュフローを、リスクを考慮した割引率で現在の価値に換算して企業価値を算出する手法。 参照: 【完全版】DCF法の計算手順や欠点を基礎からわかりやすく図解 株式会社STRコンサルティング
こんにちは。タイミーでPlatform Engineeringグループのマネージャーを務める橋本( @kaz-under-the-bridge )です。 2026年1月26日〜28日の3日間、AWS様と共同で AI-DLC Unicorn Gym (以下UG)を開催しました。私はタイミー側のカウンターパートとして、企画・準備から当日の運営、振り返りまでを担当しました。 AI-DLC(AI-Driven Development Life Cycle)は、要件定義からリリースまでの開発プロセス全体にAIを深く組み込むことで、従来のアジャイル開発を大幅に加速するアプローチです。Unicorn Gymは、AI-DLCを実際のプロダクト開発テーマで短期集中的に実践できる体験的な取り組みです。AWS様の支援のもと、国内でも多くの企業が参加・開催しています。 タイミーでは11チーム・約69名が参加し、各チームが実際にプロダクション搭載予定の機能をテーマにAI-DLCを実践しました。当日の実施内容、各チームの成果、参加者の声についてはAWS様の執筆レポートに詳しく書かれていますので、ぜひそちらもご覧ください。 株式会社タイミー様の AI-DLC Unicorn Gym 開催レポート: 全社横断で挑む開発生産性の変革 本記事では、UG当日の内容ではなく 「UGの後、組織に何が起きたのか」 を、実施から約1ヶ月時点のデータを交えてレポートします。 個の生産性改善から、組織のムーブメントへ UG以前、タイミーにおけるAIツールの活用はエンジニアが個人個人で使いこなす 「個の生産性改善」 が主たるものでした。各自がCopilotやCursor、Claude Codeなどを独自に活用し、それぞれのやり方で生産性を高めていました。 それがUGを経て、 チーム・組織単位でCoding Agentを使いこなす方向に大きくシフトした と見ています。以下、データでその変化を追っていきます。 Claude Code利用者数の変化 タイミーのプロダクト開発組織では、以下のCoding Agentを利用しており、申請制で自由に使えるようにしています。 利用しているCodingAgent 私は上記ツール群の管理者でもあります。UG後に最初に気づいた変化は Claude Codeの利用申請が明らかに増えた ことでした。 CCシート数推移 UG前は週1〜2名ペースだったシート追加が、UG後は 週8名と約5倍に加速 しています。1ヶ月で85名から118名へ、1.4倍に拡大しました。 Skills/Plugin整備の加速 —— 組織的なAI活用への転換 利用者数の増加だけでなく、 GitHubリポジトリ上のAI-DLC関連アクティビティ にも顕著な変化が見られました。 ここで言う「Skills」とは、Claude CodeのSkills機能を指します。指示・テンプレート・スクリプトをパッケージ化してリポジトリに配置すると、Claudeが会話内容に応じて自動で発見・ロードする仕組みです。たとえば「PRレビューの観点」や「テスト設計の手順」をSkillとして定義しておけば、チームの誰がClaude Codeを使っても同じ品質で作業できるようになります。 指標 UG前 UG後(1ヶ月時点) 変化 CLAUDE.md 保有リポジトリ 3 37 +34 Skills保有リポジトリ 1 11 +10 Skills総数 3 78 +75 UG前、Skillsを持つリポジトリは たった1つで 3 Skillsだけでした。それがUG後は 11リポジトリ・78 Skills に急拡大しています。 CLAUDE.md(Claude Codeのプロジェクト設定ファイル)を持つリポジトリも3から37へ。これは「AIにプロジェクトの文脈を伝える」取り組みが組織全体に広がりつつあると見ています。 つまり、個人がAIツールを使いこなすフェーズから、 チームがSkillsを整備して組織的にAIを活用するフェーズ へ移行していると見ています。 エンジニア以外の職種への広がり この組織的なAI活用の進展を補強するデータとして、 利用者の職種構成の変化 があります。 プロダクト組織の人数と照らし合わせると、エンジニアのClaude Code利用率はUG前の約70%からUG後 約89% へ上昇し、ほぼ全員が使っている状態になっています。一方、エンジニア以外の方の利用率はUG前の7%からUG後 約27% へ。まだ道半ばではありますが、エンジニア以外の方もClaude Codeを使い始める段階に来ていると言えます。 UG前後でのCC普及率比較 Skillsの整備によってチーム単位でのAI活用基盤が整ったことで、PdMやデザイナーにとってもCoding Agentが使える環境が生まれつつあると見ています。 何が変わったのか —— 代表的な変化のパターン Skillsの急増を支える具体的な動きを、いくつかのパターンに分類して紹介します。 既存リポジトリのAI-DLC駆動への変容 最も大きな変化を見せたのが、UG参加チームの既存プロダクトリポジトリです。UG前はCursorのコマンド設定がある程度だったリポジトリが、UG後には 23のSkillsと独自のAI-DLCフレームワーク を構築するまでに至りました。 コミットの中身を見ると、UG後は、Skillsの追加やAI-DLCフレームワークの構築、Inceptionの成果物(ユーザーストーリー、受け入れ基準、コンテキストマップ等)といった AI-DLCに関するコミットが大きな割合を占める ようになっています。これにより、個人がAIツールを使う段階から、チーム全体でAI-DLCのInception(要件定義)フェーズを実践し、プロダクト機能の設計にAIを組み込む段階へとシフトしたと見ています。 このチームの取り組みについては以下の記事もご覧ください。 失敗から学んだ仕様駆動開発――チームの暗黙知を形式知化した1ヶ月の実践と次の課題 ゼロからのAI-DLCワークスペース構築 UGをきっかけに、新たにリポジトリを立ち上げたチームも複数あります。UG初日に作成されたワークスペースの中には、backend・iOS・Androidなどのドメイン別Skills(7つ)や、inception・constructionといったAI-DLCのフェーズ別コマンド体系が整備され、今もSkillsやテンプレートの追加・改善を重ねているものもあります。 Knowledge-as-Code 特筆すべきは、 ハンドブック(社内ナレッジ)をAI Skillsとしてコード化 する取り組みです。バックエンド開発のベストプラクティス、API設計指針、テスト設計、法的考慮事項の参照といった組織知を22のSkillsとして整備し、Claude Code Pluginとして提供しています。さらに、Cursor向けへの変換パイプラインも構築されており、複数のCodingAgentで活用できる仕組みになっています。 これは単なるツール活用を超えた、 組織の暗黙知をAIが活用可能な形式知に変換する 取り組みと言えます。 こちらの取り組みについては以下の記事もご覧ください。 バックエンド開発Handbookを届けるために ― AI時代の知の高速道路を敷く Claude Skill を Cursor の Agent Skill として使えるようにした話 UG中の学びの即時適用 既にClaude Codeを活用していたチームの中には、 UG 3日目(1/28)に新しいSkillsを追加 した事例もあります。agentsやcommandsで安定運用していた状態から、UGでSkillsという新しいレイヤーを学び、その場で自チームのリポジトリに適用しているケースもありました。 UG非参加チームへの波及 興味深いのは、 UGに参加していないチームにもAI-DLCの動きが広がっている ことです。UG非参加のチームが8つのSkills(ワークフロー自動化特化)を持つリポジトリを立ち上げるなど、UG参加チームの取り組みが周囲に波及しています。 これらの変化をどう見るか 数字を俯瞰すると、UGを境に起きた変化の本質は 「個のAI活用」から「組織のAI-DLC実践」へのシフト だと考えています。 利用者の拡大 : 週1.5名 → 週8名(5倍加速)、エンジニア以外の職種にも拡大 Skillsの整備 : 1リポジトリ3 Skills → 11リポジトリ78 Skills(個人の効率化ではなく、チームの知識をAIに教える方向) チームを超えた波及 : UG非参加チームにも動きが広がっている UGはあくまできっかけであり、3日間のイベントです。しかし、そのきっかけが 1ヶ月で組織全体の行動パターンを変えた ことは、データが示しているのではないかと思います。 おわりに 現時点では、ムーブメントはまだ初速の段階です。ただ、この動きは定着していくだろうと見ています。次にやるべきことは、AIを安全に使うためのセキュリティ面の整備と、より大きなうねりにしていくためのブロッカーを一つひとつ排除することだと考えています。 もちろん、本記事で取り上げたのはClaude Codeを中心とした変化に限っています。CursorやCopilotを活用して成果を出しているケースも多くあり、組織全体のAI活用はさらに広がりを見せています。 UG開催を検討されている方へ 最後に、主催者としてひとこと。UGの開催にあたって最初に立ちはだかる壁は、「参加者が乗り気になるかどうか」かもしれません。3日間という拘束時間の長さ、AI-DLCという新しい手法への不確実性——二の足を踏む気持ちは十分にわかります。 ただ、本記事でお伝えしたとおり、タイミーではUGの3日間をきっかけに1ヶ月で組織の行動パターンが変わりました。利用者の急増、Skillsの整備、エンジニア以外への波及。これらは3日間の投資に対して余りある効果だったと感じています。開催を迷っている方にとって、一つの事例として参考になれば幸いです。 最後まで読んでいただき、ありがとうございました。こうした取り組みに興味を持っていただけた方、一緒にチャレンジしてくれる方を募集しています! タイミーの採用情報はこちら
こんにちは!タイミーでバックエンドエンジニアとして働いている福井 ( bary822 ) です。 皆さんは「Claude Code の Skills を社内の Cursor ユーザーも使えるようにしたい」と思ったことはないでしょうか? Claude Code には Claude Plugin という仕組みがあり、社内で共有したい Skills を簡単に配布できます。しかし、Cursor には Claude Plugin に相当する機能がなく、さらに Claude Code の Skills は独自の構文をサポートしているため、そのままでは動作しません。 この記事では、Claude Plugin 形式で配布している Skills を Cursor でも利用できるようにした取り組みについてご紹介します。 背景 タイミーでは、社内の開発ガイドラインに沿った開発を行いやすくすることを目的に、Claude Code の Skills を整備し、Claude Plugin 経由で配布しています。 tech.timee.co.jp Claude Code の Skills はエージェントに対してタスク実行時のコンテキストや手順を提供する機能です。この機能はもともと Claude Code 独自のものでしたが、現在では Agent Skills としてファイル名やディレクトリ構成、メタデータの種類などのオープンスタンダードが確立されつつあり、さまざまなAIプラットフォームで再利用できるようになっています。 Skills for organizations, partners, the ecosystem | Claude Overview - Agent Skills 課題: Claude Plugin で配布している Skills を Cursor で使えない Agent Skills の仕様自体は標準化が進んでいますが、配布の仕組みやサポートされる構文にはプラットフォーム間で差分があります。 配布の仕組みの差分 Claude Code には Plugin という仕組みがあり、Skills のインストール・アップデートを簡単に行えます。一方、Cursor には同等の配布機構がサポートされていません。 構文の差分 Claude Code の Skills には、Cursor でサポートされていない独自構文がいくつかあります。 !command 構文: SKILL.md 内で許可されたシェルコマンドを実行する構文。たとえば !gh api ... と書くことで GitHub API 経由でドキュメントを動的に取得できる。Cursor ではサポートされていない $ARGUMENTS 変数: スキル実行時にユーザーが渡す引数を受け取るための変数。こちらもCursor ではサポートされていない つまり、Claude Plugin で配布している Skills をそのまま Cursor に持ってきても、動的なコンテンツ取得ができず引数も渡せないため、まともに動作しない状態でした。 Cursor ユーザーにも同じ体験を提供するために、これらの構文を Cursor が理解できる形式に変換し、適切なディレクトリに配置する必要がありました。 解決策:変換スクリプトの作成 Claude Plugin 形式の Skills を Cursor 互換形式に変換するシェルスクリプト build-cursor-skills.sh を作成しました。 このスクリプトは以下の変換を行います。 動的コンテンツの埋め込み: !command 構文で動的に取得していたコンテンツを、ローカルのファイルから読み取ってテキストとして直接 SKILL.md に埋め込む 変数の変換: $ARGUMENTS を「ユーザーの指示に従って」という固定テキストに置換する 補助ファイルのコピー: Skills が参照する補助ファイル( intro.md , workflow.md , troubleshooting.md など)もコピーする 変換後の Skills を構成する各種ファイルは、ユーザー領域( ~/.cursor/skills/ )に配置されるようにしました。Cursor はこのディレクトリを自動的に走査するため、配置するだけで Skills が利用可能になります。 # Skills を管理するリポジトリで実行するだけ ./scripts/build-cursor-skills.sh 変換処理の具体例 たとえばある Claude Code Skill の SKILL.md には、以下のように GitHub API 経由でドキュメントを動的に取得する構文が含まれています。 # API設計ガイドライン 以下のガイドラインに従って API を設計してください。 ! ` gh api /repos/org/repo/contents/docs/web_api_design.md ... ` 変換スクリプトはドキュメントを管理するリポジトリ上に配置します。こうすることで、この !gh の行をローカルにあるドキュメントの内容で置き換えることができます。 # API設計ガイドライン 以下のガイドラインに従って API を設計してください。 (ローカル参照した web _ api _ design.md の内容がここに展開される) これにより、GitHub API を呼び出さなくてもドキュメントの全文がスキルに含まれるようになり、Cursor でも問題なく動作します。 動的に取得する Claude Code 形式と比較すると、ドキュメントに変更があるたびにスクリプトの再実行が必要になります。この点に関しては Claude Plugin を使っていたとしても手動でアップデート( claude plugin update <plugin> )する必要があるため、大きな差はないだろうと判断して許容しました。 出力されるディレクトリ構造 スクリプトを実行するとユーザー領域に下記のようなディレクトリ構成でファイルが展開されます。 ~/.cursor/skills/ ├── skill-ref-design-api/ │ └── SKILL.md # ドキュメントが埋め込まれたスキル ├── skill-ref-design-table/ │ └── SKILL.md ├── skill-wf-design/ │ ├── SKILL.md │ ├── intro.md │ ├── workflow.md │ ├── troubleshooting.md │ └── samples/ │ └── default.md ... Dev Container 環境への対応 変換スクリプトをリリースした後、Cursor で Dev Container を使って開発しているメンバーから「スキルが認識されない」という報告がありました。 原因はシンプルで、Dev Container 内からはホスト側の ~/.cursor/skills/ が参照できないためです。 これを解決するためにいくつかの方法を検討しました。 方法 メリット デメリット devcontainer.json で ~/.cursor をマウント 設定一箇所で済む Cursor を使っていない人のホストにも ~/.cursor/ が作成されてしまう ワークスペース直下に配置 マウント不要(ワークスペースはデフォルトでマウント済み) gitignore の設定が必要 チーム内には Cursor を使っていないメンバーもいるため、 devcontainer.json にマウント設定を追加する方法は副作用が大きいと判断し、ワークスペース直下に配置する方法を選択しました。 具体的には、変換スクリプトに --target オプションを追加し、出力先ディレクトリを指定できるようにしました。 # Dev Container 環境向け:ワークスペース直下に配置 ./scripts/build-cursor-skills.sh --target /path/to/repo これにより、スキルファイルはワークスペース直下( <repo>/.cursor/skills/ )に配置されます。ワークスペースはデフォルトで Dev Container にマウントされているため、追加のマウント設定なしでスキルが認識されます。 ただし、ドキュメントが更新されてスクリプトを再実行すると、そのたびに更新された Skills を構成するファイルに差分が出てしまいます。そこで、利用する側のリポジトリでスクリプトによって配置されるディレクトリ以下を gitignore する対応も合わせて行いました。 今後の展望 現在はビルドスクリプトを手動で実行する必要がありますが、Cursor 側で Claude Plugin と同等の配布機構や !command 構文がサポートされれば、変換スクリプト自体が不要になる可能性もあります。その動向もウォッチしつつ、現時点で最もシンプルに課題を解決できる方法として、この変換スクリプトによるアプローチを採用しています。 また、元のドキュメントに更新が入った時に手元の Skills をアップデートすることを促す通知を送信するなど、ユーザーの利便性に配慮した仕組みづくりも進めていきます。 おわりに 今回は、Claude Plugin 形式で配布している Agent Skills を Cursor でも利用できるようにした取り組みをご紹介しました。 「Claude Code で便利に使っている Skills を他のツールでも使いたい、でもプラットフォームごとに構文や配布の仕組みが違って大変」というのは、多くのチームが直面しうる課題だと思います。私たちのアプローチはシンプルなシェルスクリプトによる変換という泥臭い方法ですが、低コストで確実に課題を解決できました。少なくとも今後 Agent Skills の配布の仕組みが Cursor に搭載されるまでの暫定対応としては十分に機能していると思っています。 この記事が、同じような課題に取り組む方の参考になれば幸いです。 最後までお読みいただき、ありがとうございました!
こんにちは、タイミーでバックエンドのテックリードをしている新谷( @euglena1215 )です。 今回は、社内向けに公開したバックエンド開発Handbookと、それをClaude CodeやCursorといったAIエージェント向けスキルとして届けることで、気づいたらHandbookを参照している状態を目指した取り組みについて紹介します。 バックエンド開発Handbookとは何か バックエンド開発Handbookは、タイミーのバックエンド開発における設計・実装・運用のガイドラインをまとめたドキュメント集です。GitHub Pages でホスティングし、開発者が見やすい形で公開しています。 タイミーでは GitHub Enterprise Cloud を利用しているため、GitHub Pages のアクセス制御機能でリポジトリの読み取り権限を持つメンバーのみに公開範囲を制限できます。 バックエンド開発トップページ なぜ書き始めたのか 事業の成長・変化に伴い、バックエンド開発に関わるエンジニアが増えてきました。AIツールの進化も相まって、バックエンド以外を専門とするエンジニアが越境してコードを書く機会も増えています。 こうした変化の中で、これまでチーム内で暗黙的に共有されてきたノウハウや設計思想を形式知として残し、誰でもアクセスできる状態にしておく必要がありました。 たとえば戦略的プログラミングの重要性、概念モデリングの進め方、テーブル設計の注意点など、日々の開発で繰り返し必要になる判断基準を体系化しています。 カバー範囲 Handbookは開発プロセスの全体を一気通貫でカバーしています。 フェーズ トピック はじめに 戦略的プログラミングの心構え、秘匿情報の取り扱い、タイミーを取り巻く法律 設計 概念モデリング、ギャップ分析、テーブル設計、Web API設計、クラス設計、非同期処理設計、バッチ処理設計 実装・レビュー 実装ガイドライン、コードレビュー、自動テスト設計、コードの整頓 運用・保守 ログ設計、監視、障害対応 リリース デプロイ・リリース 設計に重点を置いているのは、バックエンド開発に慣れていない人がAIエージェントを使ったとしても、カバーしにくい領域だからです。実装やレビューのプラクティスはある程度一般化されていますが、「タイミーのバックエンドとしてどう設計するか」はチーム固有の知見が多く、形式知にする価値が高いと考えました。 たとえばタイミーでは、Sidekiq ジョブ実行中にデプロイが行われると、Sidekiq プロセスに SIGTERM が送信されます。その25秒後にたとえ実行途中であってもジョブをキューに戻す、という実装上の制約があります。開発者はこれを考慮してジョブの処理をべき等にしたり、25秒を超えないように処理対象を分割してジョブに切り出すなどの対策を行う必要があります。このような暗黙的かつ独自の制約は特に Handbook として残すべきだろうと考えていました。 Handbookをどう届けるか Handbookを書いて公開するだけでも価値はありますが、ドキュメントは自分から読みに行く必要があり、ひと手間かかります。存在を知っていても、忙しい開発中には思い出せないこともあると思います。 いま、社内の多くのエンジニアがAIエージェントを日常的に使って開発しています。Claude CodeやCursorなどのツールが開発フローに組み込まれているのであれば、 AIエージェント経由でガイドラインを届ける という選択肢があります。 開発者が意識しなくても、AIエージェントがガイドラインを参照しながら設計や実装を支援してくれる。そうすれば、「気づいたらガイドラインに沿った開発をしていた」という状態を作れます。 この考えから、Handbook公開と同時にAIエージェント向けスキルとしても提供することにしました。現在、Claude Code Plugin と Cursor Agent Skills の2つの形式で配布しています。 ここからは、AIエージェント向けスキルの技術的な仕組みと、人間側の学びを促す工夫の2つの観点で説明します。 スキルの技術設計 リポジトリ構成 1つの工夫として、Handbookのマークダウンドキュメントとスキル定義を同じリポジトリに同居させています。 handbook/ ├── backend/ # Handbookドキュメント(マークダウン) │ ├── design/ │ │ ├── web_api_design.md │ │ ├── table_design.md │ │ └── ... │ ├── implementation/ │ └── operation/ ├── .claude-plugin/ # AIエージェント向けスキル定義 │ └── timee-backend-handbook/ │ ├── plugin.json │ └── skills/ │ ├── ref-design-api/ │ ├── wf-code-reading/ │ └── ... └── scripts/ └── build-cursor-skills.sh # Cursor向け変換スクリプト ガイドラインの原文とスキル定義が同じリポジトリにあるため、ドキュメントの更新とスキルの更新を同じPRで行えます。ドキュメントとスキルが乖離するリスクを構造的に減らせます。 Reference SkillsとWorkflow Skills Handbookの内容を、AIエージェントのスラッシュコマンドで呼び出せるSkillsとして提供しています。今回、スキルの役割に応じて Reference Skills と Workflow Skills という2種類の分類を独自に定義しました。これはClaude CodeやCursorの公式な分類ではなく、Handbookスキル群の設計方針として導入した概念です。 Workflow Skill(高レベル) ├── Reference Skill A を呼び出し ├── Reference Skill B を呼び出し └── Reference Skill N を呼び出し(必要に応じて) Reference Skills Reference SkillsはHandbookの各ページと1対1で対応します。 /handbook-ref-design-api # Web API設計 /handbook-ref-design-table # テーブル設計 /handbook-ref-design-class # クラス設計 /handbook-ref-impl-code-review # コードレビュー ... たとえばAPI設計のReference Skillsは以下のように定義されています。 --- name: handbook-ref-design-api description: Web API設計のガイドラインを参照してエンドポイント設計をレビュー・提案 context: fork agent: general-purpose allowed-tools: Bash(gh *) --- ## Web API設計ガイドライン !`gh api /repos/my-org/handbook/contents/backend/design/web_api_design.md -H "Accept: application/vnd.github.raw"` ## タスク 上記のガイドラインに従って、$ARGUMENTS のWeb API設計をレビュー・提案してください。 ポイントは context: fork です。サブエージェントとして独立したセッションで実行されるため、メインセッションのコンテキストウィンドウを消費しません。情報量の多いHandbookの取得をサブエージェントに委譲し、要約のみを返すことで効率的に運用できます。 また、 gh api -H "Accept: application/vnd.github.raw" でマークダウンの原文をそのまま取得できます。Handbookが更新されれば自動的に最新の内容が反映されます。 Workflow Skills Workflow Skillsは、状況に応じて複数のReference Skillsを組み合わせるユースケース特化型のスキルです。 context: current でメインセッション上で実行されます。 現在はWorkflow Skillsを4つ提供しています。 スキル フェーズ 内容 /handbook-wf-code-reading 理解 既存機能を体系的に理解する /handbook-wf-modeling モデリング 概念モデリングを実施する /handbook-wf-plan 計画 開発中: 詳細設計を行いつつ、複数個の実装計画に落とし込む /handbook-wf-implement 実装 開発中: 与えられた入力を元に実装する たとえばモデリングフェーズのWorkflow Skillsを実行すると、以下のような流れで進みます。 イントロダクション : 概念モデリングの重要性とギャップ分析の考え方を説明 ガイドライン取得 : 必要なReference Skills(概念モデリング、ギャップ分析など)を自動で選択・呼び出し 意図の深掘りと目標の合意 : 何をモデリングしたいのか、スコープを確認 すり合わせの質問 : ドメインの境界やビジネスルールについて質問を提示 メインセッションでモデリング実行 : 回答を踏まえて一緒にモデリングを進める 開発者はスラッシュコマンドを1つ実行するだけで、必要なガイドラインの参照からモデリング作業までを一気通貫で進められます。ガイドラインの存在を知らなくても、Workflow Skillsが自動的に適用してくれます。 階層構造のメリット Reference SkillsとWorkflow Skillsの2層構造には、以下のメリットがあります。 再利用性: 同じReference Skills(たとえばギャップ分析)が理解・モデリング・設計の各Workflowから呼ばれる 動的選択: Workflow Skillsがユーザーの入力や状況に応じて、必要なReference Skillsだけを選択的に呼び出す コンテキスト効率: ガイドラインの取得処理はサブエージェントに委譲され、メインセッションには要約のみが返る また、Workflow Skillsは自作も可能です。既存のWorkflow Skillsを参考にしながら、チームの開発フローに合わせたワークフローを追加していけます。こうしたスキルが充実すれば、どのタスクに取り組むときでもHandbookの知見にガイドされる状態が作れます。新しくチームに加わった開発者でも、スキルを通じてすぐにチーム固有の設計方針をキャッチアップできるはずです。 人間の理解を置き去りにしない設計 スキルの技術設計だけでは不十分です。ここが一番気をつけたポイントです。 AWSが提唱しているAI-DLC(AI Driven Development Life Cycle) は、AIの出力を妥当にジャッジできる人間の存在を前提としています。人間側の理解が伴わなければ成り立ちません。 しかし現実には、AIの出力を「なんか良さそうだから」とそのまま使ってしまい、人間側の理解が追いつかないケースも起きがちです。AIの進化によって実装の詳細を人間が把握しなくてよくなる部分はあるでしょう。ですが、背景にある考え方を理解していなければ、AIと適切にコミュニケーションを取ることはできません。 だからこそ、このスキル群では人間に考え方やインサイトをインプットする工夫を随所に入れています。いわば、いつでも質問できるメンターをAIで実現する試みです。 工夫点1:イントロダクションで「なぜ」を伝える 各Workflow Skillsの冒頭にイントロダクションを設けています。ここではいきなり作業に入るのではなく、「なぜこのフェーズが重要なのか」「このフェーズで何を学ぶのか」を説明します。 たとえば理解フェーズのイントロでは、コード理解には概念・構造・実装の3段階があり、概念レベルから順に深めるアプローチが有効であることを説明しています。 ## 推奨アプローチ 概念レベルから順に理解を深めることを推奨します: 1. 概念レベル: まず全体像を掴む(どんな世界なのか) 2. 構造レベル: データとクラスの設計を理解(どう表現されているか) 3. 実装レベル: 具体的なロジックを理解(どう動くのか) 工夫点2:ガイドラインURLの提示 全てのスキルで、参照したガイドラインのホスティングしているURLを、ユーザーに必ず提示するようにしています。 重要: 参照したガイドライン(https://{my-org}.github.io/handbook/backend/design/web _ api _ design.html) をユーザーに必ず提示してください。 AIの要約だけで完結させず、元のドキュメントに戻れる導線を用意しています。全体像を掴んだ上で、気になった箇所は原文で深掘りできます。Handbookそのものの認知と活用が進む効果も期待しています。 工夫点3:抽象から具体へ段階的に Workflow Skillsのフロー全体が、抽象度を段階的に下げていく設計になっています。 ワークフローの4フェーズ(理解→モデリング→計画→実装)がそうですし、各フェーズ内でも同様です。理解フェーズでは概念→構造→実装と段階的に深め、計画フェーズでは概念モデルの出来事やモノをAPIエンドポイントやテーブルへ変換していきます。 一気に情報を出すのではなく、フェーズごとにすり合わせの質問を挟むことで、開発者自身が考える余白を作っています。 以下は、思考実験として「タイミーで企業合併を表現するなら?」というお題で、モデリングのWorkflow Skillsを試したときの様子です。 「将来の新設合併対応を見据えて、今回のモデルはどの程度汎用的にすべきですか?」「合併には時間的なフェーズがありますか?」という質問が飛んできました。そもそも合併に吸収・新設のパターンがあることを私は知りませんでした。Handbookの設計ガイドラインを熟知したエキスパートと、ドメイン知識を持ったエキスパートが悪魔合体するとこんな体験になるのか、と末恐ろしくなった瞬間です。 工夫点4:各ステップに学習ポイントを明示 Workflow Skills内の各ステップには「なぜそうするのか」「ここで何を学ぶか」を明示しています。 📚 学習ポイント: - 出来事(申請する、承認する)→ APIエンドポイント - モノ(勤務実績、勤務時間)→ リソースとリクエスト/レスポンス - ビジネスルール → バリデーションとエラーハンドリング 💡 ガイドラインのポイント: - 出来事は動詞で考え、APIでは名詞(リソース)として表現 - 選択された名前(例:「勤務実績」)をリソース名に反映 作業の手順だけでなく、その背景にある考え方を一緒に伝えることで、AIが出す結果の「なぜ」を開発者自身が理解できる状態を目指しています。 使ってみての感想 自分自身の所感 実際に使ってみて、これまでとは一線を画す体験だと感じています。 従来のAIエージェントの出力は、一気にたくさんの情報を出してくることが多く、情報量に圧倒されて消化しきれないことがありました。ですが、このワークフローでは抽象度を段階的に下げながら教えてくれるので理解がしやすいです。普段の会話で賢いなと感じる人は、抽象的なところから徐々に具体へ落としていくのが上手ですが、このワークフローにも同じ感覚があります。 AIエージェントは便利な開発アシストツールだと思いつつも、開発のギアが上がる感覚はこれまでありませんでした。ですが、このワークフローは明確にゲームチェンジャーだと感じています。 VPoEの反応 VPoEに実際に動かしながら紹介したところ、その場でEMチャンネルに @here 付きで共有してくれました。特に、AIエージェントが段階的にガイドラインを適用しながら開発者と対話する体験に手応えを感じてもらえたようです。 語彙力が下がっているVPoE 他開発チームメンバーの反応 現在、社内への全体発信を終えて各チームへのハンズオンを順次進めているところですが、すでに手応えを感じ始めています。 既に普段の開発で使ってくれているエンジニアからはこんなコメントをもらっています。ありがたい限りです。 handbookはここ1,2年で一番自分に刺さったプロダクトです おわりに この記事では、バックエンド開発Handbookと、それをAIエージェント向けスキルとして届ける取り組みについて紹介しました。 ドキュメントを書くだけでなく、AIエージェントを介して開発フローへ自然に組み込むことで、ガイドラインを届ける新しいアプローチを模索しています。AIへ任せきりにせず人間側の理解を促すことが、知の高速道路を敷くうえで最も大事なポイントだと考えています。 今回の取り組みを通じて、AI時代の開発組織に必要な要素が見えてきた気がしています。短期目線での開発の高速化だけでは不十分で、「全タスクがオンボーディングタスクになっていること」「メンターを基本的にAIが担い、いくらでも質問できて自走できる環境が整っていること」。この2つが揃えば、誰でもどのチームに移っても素早く立ち上がれるようになります。つまり、必要な場所に必要な人材を配置できる人員の流動性の高さに直結します。Handbookとスキルの取り組みは、その第一歩です。 今回作成した Agent Skills はカジュアル面談でもデモできるので、興味ある方はお気軽にお声がけください!実際に触ってみたい方は、ぜひタイミーに入社してください! product-recruit.timee.co.jp
こんにちは!プロダクトエンジニアの @kazzhira です。 私たちのチームでは、2025年の夏ごろから「AI活用による開発生産性の向上」に取り組んできました。しかし、当初の取り組みは抽象的なガードレールの提示や個々人の実践にとどまり、チームとして大きな成果には結びつきませんでした。 その後、SDD(仕様駆動開発)というアプローチに出会い、オープンソースの cc-sdd フレームワークをベースに試行錯誤を重ねてきました。 本記事では、AI開発標準の策定に失敗した経験から何を学び、どのように仕様駆動開発に辿り着いたのか、そして、実践を通じて得た成果と学びをご紹介します。 チームのAI導入でうまくいかなかった話 AI活用の個人最適化 当初、チームでは Cursor、Claude Code、Devin、GitHub Copilot、Gemini などの AI ツールを個々人の判断で利用できる状態でした。 しかし、AI活用の状況は個々人に閉じており、チームとしてのナレッジ共有や標準化は進んでいませんでした。 AI開発標準策定の失敗 そこで「AI開発標準」の策定を試みました。情報を収集したうえで、Planモードで実装計画を立て、途中でレビューを挟む開発スタイルを言語化しました。しかし、結果的にこの取り組みは失敗に終わりました。 資料の説明が抽象的で、チームが具体的に動きようがなかった 開発手法の共通項を抜き出しただけのガードレールに過ぎなかった 実際の開発プロセスに落とし込めず、絵に描いた餅になった 参考: 当時の考えを振り返った記事 なぜSDDをやろうと思ったのか 理想の開発体験の議論 チームで理想の開発体験・開発生産性の課題を話し合った結果、以下の課題が明確になりました。 リファインメント(仕様を決める会議)で議論が発散して収束に時間がかかる AIは顧客課題、ユーザーストーリーを知らず、要件の精度が高くない AIの出力が微妙で、整理されたコンテキストが足りない SDDとの出会い これらの課題を解決する方法として、 SDD(仕様駆動開発) に辿り着きました。 SDDの本質は、 仕様書を「単なるドキュメント」ではなく、AI と人間の両方が参照する SSoT(Single Source of Truth)として機能させる ことです。 定性面 AIがユーザーストーリー、背景、受け入れ条件から精度の良い仕様書を生成する →「AIは顧客課題、ユーザーストーリーを知らず、要件の精度が高くない」の解決 構造化された要件定義書・設計書・開発ルールで一貫したコンテキストを提供する →「AIの出力が微妙で、整理されたコンテキストが足りない」の解決 定量面 価値提供速度の向上 これらの効果を期待し、投機的に取り組んでみることを決めました。 ちなみに、「リファインメントで議論が発散して収束に時間がかかる」は当時Notion AIでの解決も試しました。しかし本題から外れるため、本記事では割愛します。 SDDの実践と工夫 cc-sddフレームワークの採用 SDD を実践するにあたり、私たちはオープンソースの cc-sdd (Spec-Driven Development フレームワーク)を採用しました。 深い理由はなく、筆者が各所で目にして実験的に入れていた背景があります。 チーム固有の課題 cc-sdd の基本的なアプローチを導入した上で、私たちのチームは以下の課題に直面しました。 複数のリポジトリを AI が横断的に操作できない チーム固有のタスク分割・実行ルールがなく、AI の出力がチームの開発フローに合わない Rails 固有の設計パターンが AI に伝わらない プロダクトのドメイン知識が AI に渡っていない 私たち独自のソリューション これらの課題に対し、私たちは以下の解決策を構築しました。 1. マルチリポジトリ横断ワークスペース Cursorによる開発を前提に、code-workspaceを生成して複数リポジトリを統合的に扱う仕組みを実装しました。 【my-team.code-workspace】 { " folders ": [ { " name ": " my-team ", " path ": " . " } , { " name ": " backend ", " path ": " ~/workspace/backend-repository " } , { " name ": " frontend ", " path ": " ~/workspace/frontend-repository " } , ... ] } これにより以下のメリットが得られました。 AI エージェント(Cursor / Claude Code 等)がリポジトリを横断して操作可能 仕様書リポジトリ(my-team)とコードベースを統合管理 私たちの最初の実装では、my-team・backend・frontendをセットで管理しました。 今はもう少し増えています。 2. タスク生成・実行ルールの整備 チーム固有のタスク生成・実行ルールを定義しました。 ルール種別 内容 タスク分割ポリシー "デプロイ可能な最小粒度" にタスク分割 Commit・Push・PRのルール 例示することで、意図した生成に誘導する。例えば "commitには変更理由とリファレンスを必ず含める"、"PRテンプレートに従う" など。 タスク実行順序の定義 Swaggerを定義してからfrontendとbackendの作業に移行する。 3. カスタムステアリングドキュメント Rails 固有の設計パターンやプロダクトのドメイン知識をステアリングドキュメントとして整備しました。 Controller Patterns( before_action の濫用禁止、個別でエラーハンドリング不要など) プロダクト固有の名称、用語、ユースケース リポジトリ構造のサマリ 採用している技術の詳細 例として「プロダクト固有の名称、用語、ユースケース」を定義した例を示します。 # Product Overview タイミーアプリのAPIサーバー、クライアント向けWebアプリケーションのAPIサーバー、 ワーカー向けモバイルアプリケーション、社内管理ツールを提供するプラットフォーム。 ## Core Capabilities 1. **ワーカー・クライアント管理**: ワーカーとクライアント企業のアカウント管理、認証、プロフィール管理 2. **求人・マッチング**: 求人作成、公開、ワーカーとのマッチング機能 3. **勤怠・給与管理**: 出勤管理、給与計算、支払い処理 4. **コミュニケーション**: チャット機能、レビュー・フィードバック機能 5. **管理機能**: 社内管理ツール、各種レポート・分析機能 ## Target Use Cases - **クライアント企業**: 求人作成・管理、ワーカー管理、勤怠確認、給与支払い - **ワーカー**: 求人検索・応募、勤怠管理、給与確認 - **社内管理者**: システム管理、データ分析、各種レポート生成 ## Value Proposition - ワーカーとクライアント企業を効率的にマッチングするプラットフォーム - 勤怠管理から給与計算まで一貫した業務フローを提供 4. カスタムコマンド cc-sddのコマンド体系以外で、チームで必要な成果物を保管するためのコマンドを用意しました。内容は長いため省略します。 QAチェックリストの自動生成「spec-qa-checklist」 Playwright MCPによるQA自動実行「playwright-mcp-qa」 最終的なファイルツリーを示します。 my-team/ ├── my-team.code-workspace # マルチリポジトリ統合ワークスペース定義(独自作成) ├── repos.yml # 対象リポジトリ一覧(独自作成) ├── repos.template.yml # ↑のテンプレート(独自作成) ├── docs/ # プロジェクト横断ドキュメント │ ├── scripts/ │ ├── setup.sh # 初期セットアップ(独自作成) │ ├── setup-workspace.sh # ワークスペース構成生成(独自作成) │ └── sync-*.sh # リポジトリ・設定の同期(独自作成) │ ├── .cursor/ │ └── commands/ # カスタムコマンド(独自作成) │ ├── spec-qa-checklist.md # QAチェックリスト生成 │ └── kiro/ # Kiro Spec-Driven コマンド群 │ └── .kiro/ ├── steering/ # アーキテクチャ制約 │ ├── product.md # プロダクト原則 │ ├── tech.md # 技術標準 │ └── structure.md # コード構造パターン ├── settings/ │ ├── rules/ # 設計・実行ルール(独自) │ │ ├── tasks-generation.md # タスク生成(プレフィクス規約・分割順序)(独自作成) │ │ └── task-execution-policy.md # 実行ポリシー(環境・Git・コミット規約)(独自作成) │ └── templates/ │ ├── specs/ # 仕様テンプレート │ └── steering/ # ステアリングテンプレート └── specs/{feature}/ # 機能単位で生成 ├── requirements.md # 要件 ├── design.md # 設計 ├── tasks.md # タスク └── e2e-qa-checklist.md # QA(独自作成) 評価 ポジティブな評価 cc-sddの短期間の導入で最も価値を感じたのは、実装速度の向上ではなく、 開発プロセスの質の向上 でした。 暗黙知の形式知化 — これまで個人の頭の中にあった仕様判断が、requirements / design / task の3つの成果物を通して言語化・共有された 手戻りの減少 — 仕様書によってコンテキストが整理されたことで、AIの出力品質が安定し、実装後の手戻りが体感として減った 合意形成の質の向上 — 仕様を厳格に言語化するプロセスが、チーム内の認識齟齬を早期に解消した モブワークとの親和性 — 構造化された仕様書が共通言語として機能し、スプリント初期の設計作業を効率的に進めることができた ネガティブな評価 一方で、チームで改善すべき課題も挙がっています。 モノにもよるが、仕様書を作る工程で同期的に1日〜1.5日の時間を使う 仕様書を精査する工程の疲労感 実装スピードとデプロイ頻度は、以前と同等か、微増している感覚 シンプルに練度不足 リファインメントが引き続きボトルネック。実装が効率化しても、要求の供給が追いつかなければ全体のスループットは上がらない 中間生成物のレビューがリファインメントに次ぐボトルネック。AIが高速に生成するアウトプットに対し、人間のレビューが追いつかない etc. データで見る事実:cc-sdd導入でデプロイ頻度は向上しなかった 前提として、開発者が3名のスクラムチームです。 【デプロイ頻度の移動平均推移】 デプロイ頻度の移動平均推移 開発生産性を測るFour Keysの1つの指標であるデプロイ頻度に着目しました。 cc-sdd導入前後でデプロイ頻度が向上していないことを観測 AIを本格導入してきた過去6ヶ月で見るとデプロイ頻度は増加傾向 先ほどのネガティブな評価の「実装スピードとデプロイ頻度は、以前と同等か、微増している感覚」とも一致しています。 ここで、他の視点も入れてみます。 【デプロイ頻度と変更リードタイムの移動平均推移】 デプロイ頻度と変更リードタイムの移動平均推移 【平均レビュープルリク数とレビューからアプルーブまでの平均時間の移動平均推移】 平均レビュープルリク数とレビューからアプルーブまでの平均時間の移動平均推移 【マージ済みプルリク数のアクティビティの推移】 マージ済みプルリク数のアクティビティの推移 これらの結果から、cc-sddによる開発について3つの事実が分かりました。 変更リードタイムは以前の開発繁忙期の時と同程度の推移 ※sddに関連するドキュメント更新のアクティビティは計測対象外です レビュー時間は以前よりも下がっている 瞬間風速的にはPR作成数が過去半年で最多を記録した cc-sddによって、設計からレビューの効率化には成功しているが、デプロイまでの流れを阻害しているボトルネックが別に存在すると読み取れます。 これまでの経緯を含めて考察すると、それはリファインメントによる要件の供給速度だということがわかります。 今後の取り組み ここまでの取り組みでは事実としてデプロイ頻度が上がりませんでした。 ネガティブな評価であがった課題を “のびしろ” と捉え、インパクトの大きい課題をコツコツ解消していく予定です。 直近では、AI-DLCのアプローチとスクラム開発と組み合わせ、リファインメントを改善する方針で以下の取り組みを進めています。 AIを要求・デザインフェーズにも適用し、仕様策定のボトルネックを解消する 仮説の壁打ち プロトタイプ作成を回す AIがアクセス可能なSSoTの範囲拡充(ビジネスコンテキスト、ユーザーリサーチ等) 価値提供のフィードバックループを短縮し、次の要求定義に繋げる まとめ cc-sddの導入で仕様の認識齟齬が早期に解消され、意図した仕様どおりの実装に到達しやすくなりました。 しかし世間で語られるようなAIによる劇的な生産性向上には至っていません。 仕様策定フェーズのボトルネックやレビュー負荷など、AIを適用できる余地は多く残されています。 私たちのチームでは、思考をAI Drivenに変化させ、要求定義から価値提供までの全体フローを、改めてAI前提で組み直す必要があることが見えてきました。 この記事を書いている時点でも新たな取り組みで急速に進化していることを実感しています。 私自身も置いていかれないように、チームに貢献できるように成果を出し続けようと思います。 引き続きこの領域に挑戦していきます。 タイミーには、こうした挑戦と学び、そして発信を歓迎する文化があります。 ともに挑戦し成長していきたい方、興味があればぜひ1度お話ししましょう! プロダクト採用サイトTOP カジュアル面談申込はこちら