Pub/Sub + Cloud Run Jobs を Cloud Tasks に置き換えて、一斉配信のレート制限問題を解決した話

はじめに

こんにちは、tacomsでエンジニアをしている高橋です。

飲食チェーン向けに「メニューをデリバリープラットフォームへ一斉配信する」プロダクトMenu Managerの開発・運用に携わっています。

www.camel-series.com

ある大手飲食チェーンの利用開始時に、1回の配信中にプラットフォーム側のレート制限に起因する配信エラーが大量に発生してしまったので、このタイミングで配信基盤のアーキテクチャを再設計しました。

前提として、この配信の構造を少し説明します。デリバリープラットフォーム各社の API では、ほとんどがメニューは店舗ごとに登録する仕様になっています。チェーンでは全店ほぼ同じメニューを使うため送る内容(ペイロード)はほとんど共通なのですが、それでも「A店のプラットフォームXのメニュー」「B店のプラットフォームXのメニュー」…と、店舗 × プラットフォームの数だけ API を呼んで反映する必要があります。本記事ではこの配信単位をチャンネルと呼んでいます(例: 100店舗 × 3プラットフォームに展開しているチェーンなら 300 チャンネル)。

チャンネル = 店舗 × プラットフォームの配信単位のマトリクス図
チャンネル = 店舗 × プラットフォームの配信単位のマトリクス図

1回のメニュー改定で、ほぼ同じ内容のリクエストを店舗数ぶん送ることになる——これが後述するレート制限問題の土台です。

チェーンの本部がメニュー改定をすると、全店舗・全プラットフォームへ一斉に反映する必要があります。価格改定や新商品の発売日は事前に決まっているため、メニューは前もって作成しておき、指定時刻に全店一斉で切り替えなければなりません。 この基盤は「予約した時刻に全チャンネルへメニューを届ける」役割を担っています。

このシステムには特徴的な性質が3つあります。

  • 稼働が偏っている: メニュー改定は月の特定タイミングに集中する。動くときは1回で千数百〜数千チャンネルを配信するが、それ以外の時間はほぼ何もしていない
  • 秒単位の同時性は要らない: 外部 API のレート制限がある以上、全チャンネルをまったく同じ瞬間に更新することはそもそもできない。店舗が開店する前に配信が完了していればいいので、ある程度のコールドスタート(停止状態からの起動待ち)も許容できる
  • 使っていない時間のコストは最小にしたい: 稼働が偏っている分、アイドル時間の定常コストは限りなくゼロにしたい

本記事では、大規模配信で外部 API のレート制限の問題に直面したことを機に、この基盤を Pub/Sub(push サブスクリプション)+ Cloud Run Service + Cloud Run Jobs の構成から Cloud Tasks + Cloud Run Service に置き換えた設計を紹介します。

Before: ポーリングベースの構成

当初の構成要素は Pub/Sub(push 配信)+ Cloud Run Service(配信ワーカー)+ Cloud Run Jobs(定期ジョブ2本)で、3つの層がそれぞれ定期ポーリングで動いていました。Cloud Run Service はリクエストを受けて動く常駐型、Cloud Run Jobs は実行して終わるバッチ型(AWS でいう Fargate service と Fargate task の関係に近い)です。

Before: ポーリング + Pub/Sub 一斉配信のアーキテクチャ
Before: ポーリング + Pub/Sub 一斉配信のアーキテクチャ

  • 起動: ジョブが6分間隔で DB をスキャンし、時刻が来た予約を起動する(Cloud Run Jobs + Cloud Scheduler)
  • fan-out(1件の予約を多数のチャンネルに展開すること): 展開した全チャンネルを Pub/Sub へ一斉 publish。push サブスクリプションなので、メッセージは Pub/Sub 側から購読先(配信ワーカー)へ HTTP POST で押し込まれる
  • 完了集約: 別のジョブが5分間隔で全配信の完了/失敗を確認し、予約全体のステータスを確定

配信ゼロの日も含めて、定期起動は合計 528回/日(6分毎の240回 + 5分毎の288回)。当時の規模では、これで問題なく動いていました。

大規模配信で顕在化したレート制限エラー

大手飲食チェーンの利用開始で配信規模がそれまでの数倍になり、1回の配信が千数百チャンネルに達したタイミングで、大規模な配信失敗が発生しました。

数分間でレート制限エラー(HTTP 429 Too Many Requests)が数千件発生し、配信対象の大半のチャンネルに影響。 リトライ回数も使い切り、一部のチャンネルは配信失敗として終わった

何が起きていたのかを時系列にすると、こうなります。

調査の結果、このレート制限は店舗単位のものではなく、アプリケーション全体(全チャンネル合算)に効くグローバルなレート制限で、その閾値は公開ドキュメントには現れないものでした。いつ再試行すべきかの手掛かり(Retry-After)も得られず、待ち方は自分たちで設計するしかありません。翌日の配信でも再発し、恒常的な問題であることが分かりました。

原因: 同時実行数ではレートを制御できない

当時も無制御だったわけではなく、同時リクエスト数は絞っていました。Cloud Run は(Lambda のような1実行=1リクエストではなく)1インスタンスが複数リクエストを同時に処理するモデルなので、総同時実行数は「max_instances × concurrency(インスタンス数 × 1インスタンスあたりの並行数)」で決まります。当時はこれで流量を絞っていました。

しかしこの方式には構造的な問題が2つあります。

1. 同時実行数は req/s ではない。 1リクエストの処理が速いほど、同じ同時実行数でも秒間リクエスト数は増えます。「同時50」に絞っても、処理が数百msで返るなら秒間数百リクエストが外部に飛びます。(クライアント側で並列リクエストを N 本に制限する場合も同じです。同時数の上限は流量の上限ではありません)

同じ「同時50」でも処理速度で req/s が変わる2段比較図
同じ「同時50」でも処理速度で req/s が変わる2段比較図

2. あふれた分はエラーになる。 Cloud Run はインスタンス数の上限に達すると、受けられないリクエストを最大30秒待たせた後 429 で弾きます(前述の 429 は配信先 API が返したものですが、こちらは Cloud Run 自身が返す 429 です)。さらに急スパイク時には、上限に達していなくてもインスタンスの起動が追いつかず 500 が返ることがあります(いずれも公式ドキュメント: Troubleshoot Cloud Run issuesAbout maximum instances に記載の挙動です)。実際、大規模配信時にはこの 500 で処理記録すら残らない失敗も起きました。

さらに Pub/Sub のリトライ設定が minimum_backoff = maximum_backoff = 60s になっており、指数バックオフ(失敗のたびに再試行間隔を延ばす仕組み)が実質無効化されていました。時系列図の通り、失敗した数百チャンネルが60秒ごとに同時に再試行しては、毎回まとめてレート制限に衝突する、を繰り返し続けていたのです。

どこで絞っても、あふれた分がエラーになる。必要なのは「捨てずに待たせる」仕組みでした。

再設計: ポーリング駆動からタスクキュー駆動へ

検討の軸は「既存スタックの延長で解く」です。Cloud Tasks は当時すでにシステムの別機能で運用実績があり、新しいミドルウェアを増やさずに賄えます。アプリ層レートリミッター(インスタンス間のレート共有に Redis が要る)や Kafka(チーム規模に過剰)は採用しませんでした。

Before の3層(起動 / fan-out / 完了集約)を、それぞれ Cloud Tasks の仕組みで置き換えました。

Before/After: 3層それぞれの置き換え対応
Before/After: 3層それぞれの置き換え対応

移行前後の全体像を並べるとこうなります(Before は再掲)。

Before: ポーリング + Pub/Sub 一斉配信のアーキテクチャ
Before: ポーリング + Pub/Sub 一斉配信のアーキテクチャ

After: Cloud Tasks によるタスクキュー駆動のアーキテクチャ
After: Cloud Tasks によるタスクキュー駆動のアーキテクチャ

1. レート制御: queue に req/s を宣言する

fan-out 先を Pub/Sub からプラットフォーム別の Cloud Tasks queue に変えました。queue の max_dispatches_per_second が、queue からワーカーへのタスク配信(dispatch)レート= req/s(1秒あたりのリクエスト数)を宣言的に表現します。

このレート制御はトークンバケット方式です。一定速度でトークンが補充される「バケツ」があり、タスクは1件送り出すごとにトークンを1つ消費します。トークンが無ければタスクは queue に溜まったまま待つ——だから、どれだけ一気に投入してもレートを超えません。

トークンバケット: queue が流量の蛇口になる
トークンバケット: queue が流量の蛇口になる

  • あふれた分はエラーではなく「まだ送っていないタスク」として queue に残る——満杯時に弾くしかなかった Cloud Run とは対照的
  • Before で問題だった固定60秒リトライも、queue の retry 設定(指数バックオフ)に置き換えた
  • レート調整は queue 設定1行の変更で完結し、コード変更もデプロイも不要

2. 時刻指定タスクでポーリングを置き換える

Cloud Tasks はレート制御だけでなく、「未来の時刻に HTTP リクエストを1本予約する」用途にも使えます。

  • 起動: 予約作成時に配信時刻を指定したタスクを1本積む。6分間隔のポーリングは廃止され、発火の遅れは最大6分から秒単位に(要件は分単位だったので、十分すぎる精度)
  • 完了集約: fan-out 時に完了確認タスクを同時に予約し、全チャンネルの結果が出そろうまで Cloud Tasks の自動リトライで待つ

時刻を見張るプロセスを常駐させなくても、時刻になればリクエストが飛んでくる。ポーリングジョブ2本はコードごと削除しました。

3. ポーリング廃止後の安全網

定期見回りには「遅くてもいつかは拾う」という性質がありました。廃止する以上、代わりの安全網が要ります。移行に合わせて、次の3つを新設しました。

ポーリング廃止後の安全網×3
ポーリング廃止後の安全網×3

  • 網① 完了チェック: fan-out 時に予約した確認タスクが「全チャンネル出そろったか」を判定し、未完なら自動リトライで待つ
  • 網② 失敗の書き残し: リトライが尽きるタスクは最終試行で「失敗」を必ず記録する(Cloud Tasks には DLQ =処理しきれなかったタスクの退避先が無いため)
  • 網③ 時間切れの確認: T+1h / T+2h に発火する最終確認タスクが強制的にステータスを確定する

なお、安全網③自身も Cloud Tasks のタスクなので同じ故障モードを持ちます。ここは queue の滞留メトリクスと失敗ログのアラートで監視しており、「番人の番人」は監視側が担います。

③も「未来の実行予約」で実装しており、定期実行はどこにも復活していません。副産物として、旧見回りが「未開始」を「失敗」と誤判定していた通知バグも解消できました。

コスト: アイドル時間の課金がゼロになった

課金の変化を、移行先・新規リソースも含めて同じ土俵で並べます。

リソース Before After
Cloud Run Jobs(ポーリングジョブ2本) 配信の有無に関わらず毎日課金 廃止
Cloud Run Service(完了集約ハンドラ) 配信がある日だけ僅かに課金
Cloud Tasks(新規) 無料枠内(月間のオペレーション数は枠の1割に満たない)

(配信ワーカーは移行前後で共通・費用も同等のため比較から除外。Pub/Sub → Cloud Tasks の置換分はどちらも無料枠内です)

もともと金額として大きなコストではありません。得られたのは削減額そのものよりも、コストが配信量に比例するだけの構造になったことです。配信すればその分ワーカーの稼働費は掛かりますが、何もしていない時間の固定費はほぼゼロ——「使った分だけ払う」形が、「たまにまとめて動く」という利用特性と噛み合います。

移行後の運用: レート調整は設定変更のみ

移行後、障害時を上回る規模の配信で、再びレート制限エラーが少数発生しました。原因は「1 dispatch の中で外部 API を2回呼んでいる」こと。queue のレート ≠ API コールレートです。

1 dispatch = API 2コールで、queue レートの2倍が外部に届く図
1 dispatch = API 2コールで、queue レートの2倍が外部に届く図

対応は、レート予算を2コールで按分し直して設定値を1行変更するだけでした。コード変更もデプロイも不要です。発生分も全件リトライで自動回復しており、レート制御を宣言的にした効果がそのまま出た形です。

Cloud Tasks を使うときの注意点

「設定1行」の1行にも仕様があります。実際に運用して確認した・調べたものを挙げます。

  • バケットの補充は「平均」レート。アイドル中にトークンが溜まるため、初動は設定レートを超えるバーストが出得る(max_burst_size で抑制。既定は自動・最大500)
  • dispatch_deadline は既定10分。これを超えると「応答が無い」と見なされて再配信=二重実行になる。長い処理は明示的に延長する
  • 配信は at-least-once(最低1回、まれに複数回届く配信保証)。deadline 超過に限らず、稀に同一タスクが2回配送され得る。今回の配信ワーカーは各社 API へ全量洗い替え(同じ内容を2回反映しても最終状態が変わらない冪等な操作)で反映するため実害がないが、副作用が冪等でないワークロードではここの設計が必須になる
  • DLQ が無いmax_attempts(リトライ上限回数)を超えたタスクはサイレント削除される(対処は前述の安全網②)

まとめ

今回の再設計は、突き詰めると Cloud Tasks の2つの使い方に集約されます。

① レートを宣言する queue として

  • max_dispatches_per_second で req/s を宣言し、あふれた分はエラーではなく「まだ送っていないタスク」として待たせる
  • 同時実行数の制限では req/s は絞れない。レートは、レートを宣言できる場所で絞る

② 未来の実行予約として

  • 「指定時刻に HTTP リクエストを1本予約する」だけで、時刻を見張る定期ジョブが要らなくなる
  • 配信トリガも、完了確認も、時間切れの見張りも、すべてこの予約で実装した——定期実行はゼロに

この2つを、すでに運用実績のあるマネージドサービスの範囲で賄えたのが今回の再設計の肝でした。外部 API のレート制限が公開ドキュメントに無く Retry-After も返らない状況でも、設定1行でレートを調整できる形に寄せておけば運用で追随できます。

本記事が、同じように「たまにまとめて動く」ワークロードを扱う方の参考になれば幸いです。

付録: もし AWS でやるなら?

同じ設計を AWS に移植できるか、概念対応を調べてみました。

Google Cloud(今回) AWS でやるなら
Cloud Tasks — 時刻指定タスク(未来の実行予約) EventBridge Scheduler(one-time + 完了後自動削除)✅ 発火粒度は1分
Cloud Run — ゼロスケールの実行環境 Lambda ✅ ※同時実行モデルは異なる(Lambda は1実行1リクエスト・最大15分)
Cloud Tasks — 遅延実行(+1h/+2h の確認) EventBridge Scheduler(SQS delay は最大15分)✅
Cloud Tasks — queue が req/s と同時実行数を独立に宣言して push 制御の主体が逆 ⚠ SQS は pull 型で、絞れるのは消費側の同時実行数だけ

差が出るのはレート制御の主体です。Cloud Tasks は queue 側(push 側)が req/s(max_dispatches_per_second)と同時実行数(max_concurrent_dispatches)を独立に宣言して呼び出します。一方 SQS + Lambda では、消費側の同時実行数(event source mapping の MaximumConcurrency、最小2)や、2025年に追加された Provisioned Mode(ポーラー数によるスループット制御)で絞ることになり、いずれも req/s そのものの宣言ではありません——つまり、今回移行元で課題になった「同時実行数で絞る」方式と同じ構図です。裏を返せば「Lambda の reserved concurrency で絞っているから大丈夫」という構成も、1実行が速ければ req/s は膨らむという同じ穴を持っています。

なお、AWS でも EventBridge API destinations であれば、呼び出しレート/秒(1〜300、引き上げ申請可)を宣言でき、超過分はキューイングされて最大24時間かけてレート内で配送されます。ターゲットが HTTP API 呼び出しに限られるなどの違いはありますが、Cloud Tasks のレート宣言に最も近い選択肢です。

第2回 プロダクトチームオフサイトを開催しました!

2026年5月14日、第2回 プロダクトチームオフサイトを開催しました!

技術戦略の共有から始まり、エンジニア2名+AIで既存プロダクトを作り直すハッカソン「天下一武闘会」を実施しました。

本記事では、tacomsのエンジニアチーム全員で丸一日かけて開催したオフサイトの様子と、8チームのハッカソン成果を紹介します。 最後に、それぞれのチームがAIをどう活用していたのか「2名+AI」での開発をふりかえります。

オフサイトの開催概要

目的

今回のオフサイトの目的は、大きく二つです。

  • 技術戦略の背景を共有し、「構造の再発明」を日々のプロダクト開発における共通の方向とする
  • 「2名+AI」で既存プロダクトをゼロから作り直し、1バリューストリームを完結させる開発を実際に経験する

この二つの目的に向けて、午前は技術戦略の共有と、ハッカソンで組むペアとの相互理解に時間を使いました。ランチを挟み、午後は4時間のハッカソンとデモ発表を行いました。

AWS 様のおしゃれオフィスをお借りして開催しました

技術戦略の共有

最初に、技術戦略の長期方針として「バーティカルエンタープライズソフトウェアの『構造』を再発明し、外食産業の利益創出プラットフォームになる」という方向性が共有されました。

その実現に向け、組織面ではリーダーレベルのエンジニア1〜2名とPdM、AIで自律的に開発を進め、人間は要求や要件の整理と判断に集中する構想です。午後のハッカソンは、この「2名+AI」での開発を実際に手を動かして理解するためのプログラムです。

やる気スイッチ紹介・ムービングモチベーター

ハッカソンの前には、仕事の動機をカードで選び、その理由を共有する「ムービングモチベーター」を、いつものチームとハッカソンのペアで実施しました。普段一緒に働くメンバーでもやる気のスイッチは意外と違い、別チームで働くペアならなおさら。開発前のアイスブレイクにちょうどよい時間でした。

私のやる気スイッチ Best 3 をお互いに発表

ハッカソン「天下一武闘会 — プロダクト・リビルドチャレンジ」

コンセプトは、「僕たちの考える最強の〇〇を、2人+AIでゼロから作り直そうチャレンジ」です!!

Claude Code、Codex、各種LLM ProviderのAPIなど、使用するAIツールは無制限。各チームは弊社の既存プロダクトから一つを選び、4時間でAI Nativeにリビルドします。 発表は各チーム5分で、動くものを見せることが条件です。

発表後は参加者全員の投票で、プロダクトの切り口を評価するアイデア賞と、AIの活用方法を評価するAIプロセス賞を選出します!

ハッカソンに取り組む様子

各チームで構想中
部屋の外のワーキングスペースもお借りして作戦会議
あまりの眺めの良さにリラックスするチーム

8チームの成果発表

ここから各チームの発表です!

AI Native Admin — チャットで組み立てる管理画面

稲葉・大田チームの「AI Native Admin」は、やりたい業務をチャットで伝えると、その場で管理画面を組み立てるRetool代替です。AIは店舗一覧や一括登録フォームなど、あらかじめ用意された8種類のブロックを選び、設定を組み合わせます。

このプロダクトでは、完成した画面ではなく、業務に必要なブロックとAPIとの結びつきが資産になります。人間が使える部品を決め、AIには組み立てを任せることで、自然言語による柔軟さと、業務画面に必要な安定性を両立させようとしています。

🎉 アイデア賞 受賞! 🎉 Brandscope — ブランド内の店舗選びをレビューで支援

出川・進林チームの「Brandscope」は、行きたい飲食ブランドを決めた後の「どの店舗に行くか」を、複数サイトのレビューをまとめて支援するプロダクトです。

店舗単位だった口コミを、ブランド、メニュー、店内・デリバリーなどのチャネル単位のデータへ組み替えた点が、このプロダクトの核です。この切り口が評価され、アイデア賞に選ばれました。サイトごとのHTMLをLLMで構造化するため、レビューを見せる画面だけでなく、店舗やメニューを横断して比較できるデータそのものが資産として残ります。

Drift — 散在する情報からプロジェクトの現在地を再構成

河崎・竹添チームの「Drift」は、Slack、Notion、Google Docsなどに散らばる会話から、プロジェクトの現在地と計画のずれを再構成するワークスペースです。知りたいことを自然言語で伝えると、その場で必要なビューを生成します。

固定したのは画面ではなく、人物、意思決定、マイルストーン、リスクなどを表す共通のデータ構造です。抽出した情報には出典、確信度、レビュー状態を持たせる一方、画面はAIが自由に生成します。判断の根拠へ戻れることと、問いに応じた見せ方を両立させるための分け方です。

🎉 AIプロセス賞 🎉 Restaurant Admin — 店舗管理CSVをAIで取り込む

梶野・與野チームの「Restaurant Admin」は、会社ごとに列名や形式が異なる店舗管理CSVを、AIが既存のマスタ項目へ割り当て、人間の確認後に一括登録する管理ツールです。

プロダクト内のAIは、形式のばらつきを解釈する列の割り当てに絞られています。一方、開発ではIssueごとに仕様、振る舞い、設計を文書化し、依存関係とマージ順を管理しながら、複数のClaudeセッションへ実装を分配しました。AIへ実装を分配するために、人間の承認点と作業間の境界を明確にした進め方が評価され、AIプロセス賞に選ばれました。

Biriken — PagerDutyの中核フローを内製

羽渕・澤田チームの「Biriken」は、社内で利用しているPagerDutyから、インシデントの受信、通知、確認、解決という中核フローを切り出して内製したプロダクトです。

8チームの中で、このプロダクト自体にはLLMが組み込まれていません。AIによって作るコストが下がれば、既製のSaaSをそのまま使うか、必要な機能だけを内製するかという判断も変わります。AI Nativeを、AI機能の有無ではなく、作れるものの経済性が変わることから捉えた案です。

オヒネリ — 店員への感謝を見える形にする

田所・神谷チームの「オヒネリ」は、飲食店で働く店員への感謝を「お捻り」として届けるプロダクトです。お客さまがKioskから送ると店員へ通知され、日次サマリやAIが作る月次レポートに残ります。金額に応じて通知音が変わる演出や月次レポートまで含め、感謝が残る体験として設計されました。

開発前にはPRD、仕様、ブランド、データモデル、AIプロンプト、デモシナリオなど9つの文書を用意し、AIが迷ったときの判断基準まで言葉にしていました。プロダクトの体験と、それを実装するときの判断基準を先に揃えてからAIへ渡した例です。

動的アンケート基盤 — 注文に合わせて質問し、回答を分析する

高橋・西野チームの「動的アンケート基盤」は、注文内容に応じたアンケートを作り、会話形式で集めた回答を分析するプロダクトです。AIには質問づくりと分析を任せますが、何を評価するかという軸と回答形式は人間があらかじめ決めています。質問は注文ごとに変わっても、結果は同じ軸で比較できる設計です。

開発では、質問を生成する側と会話形式で回答を集める側を別々のClaudeセッションで進められるよう、両者の境界をCONTRACT.mdで決めていました。プロダクト内の拡張点と、二人がAIと並行して開発するための分割点が、どちらも先に契約として表現されています。

ふじみん — 2回の質問で料理を提案する注文コンシェルジュ

藤澤・南チームの「ふじみん」は、お客さまが自分のスマートフォンでAIと会話しながら注文するコンシェルジュです。最大2回の質問で、本命、対抗、軽めの3品を提案します。

自由に会話させるのではなく、質問回数に上限を置くことで、「当てにいく接客」として必ず提案まで進むようにしています。注文時にはAIが出したメニューIDをコード側で照合し、実在する商品だけをカートへ追加します。会話の楽しさはAIに任せ、間違いを許容できない注文の確定はコードが担う設計です。

受賞2チームおめでとうございます!🎉

AIに任せた領域と、人間・コードで確定した領域

成果発表を見て感じたのは、結果を一意に確定させる領域と、同じ入力でも出力が一意に決まらないAIに任せる領域を分けていたことです。AI Native Adminは使える画面部品を人間が決め、AIが組み合わせます。動的アンケート基盤は評価軸と回答形式を固定し、質問づくりと分析をAIへ任せています。ふじみんは会話をAIへ任せ、注文できる商品はコードで確定しています。

何を確定するかは、プロダクトが守りたい価値によって異なりました。AI Native Adminが画面部品を固定した一方、Driftは出典を持つ共通データを固定し、画面はAIに自由に作らせています。これらの成果で先に考えられていたのは、AIに何をさせるかだけでなく、プロダクトとして何を必ず確定できなければならないかでした。人間やコードで結果を一意に確定する領域を定め、言い回し、解釈、構成のように一意である必要がない領域をAIへ任せていました。

要求・仕様・評価へ軸足を移すことで、構想から動作検証までが速くなる

午前の技術戦略では、リーダーレベルのエンジニア1〜2名とPdM、AIで開発を進め、人間は要求や要件の整理と判断に集中する構想が共有されました。今回の文脈でのリーダーレベルとは、実装を多くこなす人ではなく、何を作るか、どこまでを仕様として確定し、何をもって良しとするかを考える立場です。

決定領域と非決定領域を分けるには、求める体験を要求として表し、守るべき振る舞いを仕様にし、生成結果を評価する基準を先に考える必要があります。成果を見て、LLMを使いこなすほど、エンジニアは実装者の役割を離れるのではなく、自然とこのリーダー的な役割へ軸足を移すのだと気づきました。

課題もAIの使い方も異なる8チームすべてが、4時間でコア体験の動くデモまで進みました。印象に残ったのは、一人がコードを速く書いたことより、人間が判断を先に置き、AIへ実装を任せ、動くものを評価するところまでをチームで短く回していたことです。このハッカソンで「2名+AI」は、リーダーレベルの二人が要求・仕様・評価を担い、AIへ実装を渡すことで、構想から動作検証までを素早く回す体制として具体的になりました。

まとめ

プロダクトを考え、動く形にしていくのはやはり楽しいですね! AIを活用しながら、このチームで圧倒的な速度で価値を届けていきたいと思います。次にどんなプロダクトを生み出せるのか、楽しみです。

エンジニアからPdMへ - キャリアチェンジとAIを活用したキャッチアップ -

はじめに

こんにちは、4月にtacomsにPdMとして入社した Asakura です。

前職では新卒から約12年間 Webエンジニアとしてフロントエンド・バックエンド・アプリ開発とコードを書き続けてきましたが、今年からプロダクトマネージャーという新しい職種にキャリアチェンジしました。

この記事では「なぜエンジニアからPdMになったのか」と、「入社後2ヶ月でAIをどう活用してキャッチアップしてきたか」を書きます。同じようにエンジニアからのキャリアチェンジを考えている方や、PdMとしてAIをもっと活かしたい方の参考になれば嬉しいです。


なぜエンジニアをやめてPdMになったのか

きっかけは、AIによるコード生成の急速な進化を肌で感じたことです。

Claude CodeやGitHub Copilotなどのツールを使っていると、「どう実装するか」の部分は明らかにAIが得意な領域になってきていると感じました。自分がこれまで価値を発揮してきた「コードを書けるスキル」の相対的な重要性が下がっていく一方で、「何を作るか」「誰のどんな課題を解くか」を定めるスキルの重要性は逆に上がっていると感じ始めていました。

そこで「自分はどちらのスキルを伸ばしていくべきか?」を自問しました。

自分のバックグラウンドを振り返ると、技術による解決アプローチ以上にユーザーの課題や事業の文脈を考えているときの方がモチベーションが高いと気づきました。ちょうどそのタイミングで、tacomsの飲食系Vertical SaaSプロダクト ”Camel” のPdMポジションを紹介してもらい、「これだ」と思って飛び込むことにしました。


入社直後の壁:2種類のキャッチアップを同時に

いざPdMとして入社してみると、立ちはだかる2つの壁がありました。

1つ目は「ドメイン知識のキャッチアップ」です。 Camelは飲食店向けの注文一元管理プラットフォームです。DSP(デリバリーサービスプロバイダー)との連携、店舗オペレーション、POSシステムとの関係など、業界固有の知識が山積みでした。これは社内メンバーへのヒアリングや顧客へのインタビューを重ねるしかない、人との対話によって背景やインサイトを理解していく必要があります。

2つ目は「システム理解のキャッチアップ」です。 PdMとして要件を定義するには、既存システムの構造・制約・依存関係を把握する必要があります。でも複数のリポジトリにまたがるコードベースを「読んでください」と渡されても、エンジニア時代とは違い、ゼロからコードと履歴を丁寧に追う余裕はありませんでした。

この2つを同時に進めながら、毎日新しいことを吸収しなければいけないことで、最初の1ヶ月はかなり消耗しました。

そこで武器にしたのが「AI」です。


AIを活用して「他者の認知コスト」を使わずに自分で調べる

AIキャッチアップで意識したのは、「まず自分でAIに調べさせてから、人に相談する」という点です。

チームメンバーの時間は有限で、特にエンジニアのリソースは貴重です。分からないことがあるたびにイチから人に聞いていたら、相手の集中を何度も分断してしまう。AIを使えば、他者の認知コストを消費せずにまず自分でベースラインの理解を作れます。そのうえで「こういう理解で合ってますか?」と聞ける状態になってから相談することで、やりとりや理解がスムーズになりました。

tacomsでは「AI First」を掲げ、あらゆる業務を、AIを前提に構想する。という考え方であるため、積極的にAIを利用することができました。

限られたエンジニアのリソースを価値ある作業に集中してもらうために、自分でできる調査・整理・自動化はAIに任せる。これがPdMとしての今の自分のスタンスになっています。

補足:社内のメンバーはなんでも聞いてね!と快く受け入れてくださり、たくさん相談もさせてもらえています!


AI活用事例① Claudeでシステム構成図を自動生成してキャッチアップ

システム理解の壁を突破するために最も効果的だったのが、ClaudeにGitのソースコードを読ませて、FigJamにダイアグラムやシステム構成図を生成させたことです。

Camelは複数のレイヤーで構成されており、リポジトリも複数に分かれています。これを手動で自分用のドキュメント化をするのは大変ですが、Claude CodeでFigma MCPと連携させると、コードから直接システム構成図を生成できます。

バックエンドのコードを読み込んだClaudeに「このサービスのアーキテクチャをFigmaにダイアグラムで出力して」と指示すると、ものの数分でサービス間の依存関係や主要なデータフローが可視化された図が出来上がります。

これは自分のキャッチアップだけでなく、顧客への説明資料としてもそのまま使えるものになりました。「Camelのシステムってどういう構成?」と聞かれたときに、コードから生成した図を出せるのは信頼感にもつながります。

Figmaだけでなく、NotionやSlackへのアウトプットも同じくMCPで連携しています。 調査結果はそのままNotionのドキュメントとして清書して保存、必要に応じてSlackチャンネルに要約を投稿など。この一連のフローをClaudeに指示するだけで完結するので、情報を分散させず、チームへの共有まで進められる仕組みができました。

sample_system_diagram

sample_sequence_diagram

※ 図のイメージ、サンプル用ダミーです


AI活用事例② Claude Coworkで定期キャッチアップタスクを自動化

もう1つの事例は、日常的な情報収集の自動化です。

PdMとして、DSP各社の状況を定期的に把握しておくことはドメイン理解の一環として重要です。しかし毎回手動で確認・整理・共有するのは、エンジニアに依頼するほどでもないけれど、自分でこなすには手間がかかる作業でした。

そこでClaude Coworkを活用して、定期的な情報収集・整理・Slack投稿を自動化する仕組みを構築しました。

自分自身でAIエージェントのワークフローを設定できたのがポイントです。「エンジニアのリソースを使うほどでもないけど、毎回手動でやるのは非効率」という類の作業を自分で解決できるのは、エンジニア出身PdMならではの強みだと考えています。


エンジニア出身PdMがAIを使うと強い理由

2ヶ月を振り返って感じるのは、エンジニア出身のPdMはAI活用において有利な点が多いということです。

  • AIを活用してベースラインの理解を深めてから相談するので、他者の認知コストを最小化できる
  • システム構成や処理フロー、リスクが理解できるので、AIへの指示が具体的にできる
  • システム制約を理解した上でAIに要件や設計の壁打ちができる
  • 自分でAIエージェントや自動化フローを組み、エンジニアのリソースを温存できる

エンジニアとしての「どう作るか」の知識があるからこそ、AIに任せられる範囲が広がります。システム理解の調査、ドキュメントの草案、定期タスクの自動化などの作業をAIに委任することで、PdMとして本来集中すべき「なぜ作るのか」「何を作るか / 作らないのか」を考える時間を最大化できる。AIは能力の代替ではなく「本質的な思考に集中させてくれるアシスタント」と捉えています。

エンジニアからPdMへのキャリアチェンジを不安に思っている方がいたら、自信を持って言いたいです。「システムを理解できる / 開発できる」というバックグラウンドは、PdMとしての強みになります。


まとめ

  • ENG→PdMへのキャリアチェンジでは、ドメイン知識とシステム理解のキャッチアップを同時進行する難しさがあった
    • ClaudeでGitソースやドキュメントからFigma・Notion・SlackへMCPで直接アウトプットしてキャッチアップと情報共有を効率化
    • Claude Coworkで情報収集や定常作業を自動化し、重要な作業に集中
  • エンジニア出身のPdMはAI活用において強みを発揮しやすい!

これからもAIをフル活用しながらプロダクトを成長させていきます。引き続きよろしくお願いします!

AIでAIをテストするー音声AIエージェントの品質保証戦略

こんにちは、tacomsのMorixです。
私は現在Camel AI Callという飲食店向けの電話応対エージェントの開発・運用を行っています。
このプロダクトではAIを利用した品質保証を行っているのでその紹介をします!

www.camel-series.com

なお、この記事の内容は三田データ vol.4 音声AI祭りで発表した内容と同じです。(いくつか補足をします)

mita-data.connpass.com

音声AIの開発・運用は思ってたより大変

Camel AI Callは次のような会話をしてテイクアウト注文を受け付けます。

  1. あいさつ
  2. テイクアウト注文内容を聞き取る
  3. お客様に注文内容確認をする
  4. 注文確定をする

流れは単純ではありますが、音声での会話ということもあり入力パターンが無数にあります。
また注文を確定するまで無事会話を完了するには、LLMの応対精度次第ということもあり、どんな入力をされてもLLMの精度を安定させる必要があります。

そこで感じた音声AIならではの大変さがこちら

  • LLMの出力は非決定的
    • 毎回必ず同じ応答をしてくれるわけではないため、テストの期待値設定が難しい
  • プロンプト1行変えただけでデグレする
    • プロンプトを少しだけで思わぬところに影響が出ることがある
  • 音声でのテストは自動化しづらい
    • APIやフロントエンドのE2Eテストのようにエコシステムが整っていない
    • 人間が毎回AIと喋って動作確認をする羽目になる

要はテストがしんどいって話です。

音声AIでテストしたい観点は色々ある

上記の大変さをもうちょっと落とし込むと、以下のようなテスト観点の整理になると思います。

  • プロンプトの品質
    • LLMが期待通りの振る舞いを毎回してくれるか?
  • LLMと他のシステムとの連携
    • 人間との会話の結果がAPIやDBにどう反映されているか?
  • STT/TTS/電話との実挙動
    • STT(Speech To Text)の結果は意図通りLLMに渡っているか?
    • LLMの結果はTTS(Text To Speech)でどう発話されているか?
    • 電話で正しく応対できるか?

3層テスト戦略

このプロダクトでは次のテスト手法でテスト観点をカバーしています。この3層のテスト戦略を用いてプロダクト全体の品質保証をしています。

テスト観点 テスト手法
プロンプトの品質 LLM振る舞いテスト
LLMと他のシステムとの連携 E2Eテスト
STT/TTS/電話との実挙動 テストエージェント

それぞれのテスト手法について説明していきます。

LLM振る舞いテスト

LLM振る舞いテストとは、LLMがプロンプトの指示通りの振る舞いをするかをテストする手法です。テスト対象はLLMのみです。
どんなテストをしているかというと、次のような会話の流れをテストの1ケースとして作成し、LLMが期待通りの応対をしているか検証しています。

  • ユーザー「カレー1つ」
  • LLM「カレー1つでよろしいですか?」
  • ユーザー「はい」
  • LLMはツールを呼び出し注文確定

他にも例えばカレーが品切れだった場合の応対とか、トッピングが追加された場合の応対とか、会話のパターンがたくさんあるので、そのような会話の組み合わせを多数用意し、プロンプトの修正が発生したら全部テストしデグレを防いでいます。

次はコード例です。

# 受取時間を伝える
result = await self.run_with_context(session, agent, "明日の18時でお願いします")
next_event = result.expect.next_event()
assert next_event.is_message(role="assistant")
content = next_event.event().item.content[0]
assert "18時" in content or "18:00" in content or "午後6時" in content
result.expect.no_more_events()

# 受取時間を承諾
result = await self.run_with_context(session, agent, "はい")
next_event = result.expect.next_event()
assert next_event.is_message(role="assistant")
content = next_event.event().item.content[0]
assert "商品" in content or "ご注文" in content
result.expect.no_more_events()

このテストコードは次のような内容になっています。
ユーザーが「明日の18時でお願いします」といったら、LLMは「明日の18時でよろしいでしょうか?」という復唱をすべきというテストをしています。
1文字1句同じ文章を生成するとは限らないので、復唱してるかの確認は「18時」あるいは「午後6時」というワードが入ってるかという静的な検証をしています。
そしてその復唱に対しユーザーが「はい」と言ったら、次に注文商品の確認をするための確認文言を発話しているかテストをしています。

しかし、このようにある程度決まった出力をする場合は強引に静的な検証をすることができますが、そうではなく非決定的な応対をすることもあります。
例えば「今何を頼んだっけ?もう一度言ってみて」とユーザーが言った場合、LLMは今までの注文内容を復唱したうえで、追加注文を聞くことを期待しますが、どういう文章を生成するかわかりません。
こういった場合、LLMの生成結果をLLMに判定させています。

result = await self.run_with_context(session, agent, "今何を頼んだっけ?もう一度言ってもらえますか?")
chat_assert = result.expect.next_event().is_message(role="assistant")
await chat_assert.judge(
  judge_llm,
  intent="注文内容を伝えた上で、追加注文確認をしている",
)
result.expect.no_more_events()

このようにLLMの振る舞いをLLMで検証することで、非決定性へ向き合っています。

E2Eテスト

LLMが関連システムと連携し期待通りの会話ができるかをテストする手法です。テスト対象はLLMとAPIとDB(などの外部システム)となります。
よくあるようなE2Eテストとは異なり、その都度会話シナリオを用意し実行しています。

このE2Eテストは、コーディングエージェントのために存在します。
コーディングエージェントで良い成果物を出すためには検証する手段を用意する必要がありますが、コーディングエージェントは音声対話できないので音声対話するための手段を用意しました。
このE2Eテストをコーディングエージェントの開発ワークフローの組み込み、E2Eテストを成功しないと開発完了とならないようにしています。

このE2EテストはClaude Codeのスキルとして用意しており、次のようにスキルに会話シナリオを渡すと会話履歴・DBの内容などを出力します。

E2Eテストスキルの仕組みは次のようになっています。

  1. Claude Codeスキル経由で起動し、テストシナリオを渡す
  2. E2Eテストエージェントが電話注文エージェントを起動
  3. E2Eテストエージェントが電話注文エージェントのログを監視
  4. 電話注文エージェントは仮想オーディオデバイスを使って音声入出力
  5. E2Eテストエージェントは仮想オーディオデバイスを使って音声入力
  6. 会話が完了したら結果をClaude Codeに報告

E2Eテストエージェントは、渡されたシナリオ通りに電話注文エージェントと会話するための音声AIです。

ここでの工夫ですが、電話注文エージェントの発話音声をE2Eテストエージェントは受け取っていません。代わりに、電話注文エージェントのログに発話内容が記録されるためその文字列を見て発話内容を生成しています。
こうすることで、電話注文エージェントの発話速度を最大まで高めることができ、高速に会話をすることができます。

テストエージェント

テストエージェントは、電話をかけることができる音声AIエージェントです。
テストエージェントを使って、Staging環境(検証環境)のテストを行います。

こちらのテストもE2Eテストと同様、修正内容に合わせて都度会話シナリオを用意してテストを実行します。
実行イメージは以下のように、プルリクエスト上でシナリオのコメントをするとそのシナリオに沿って会話を始めてくれます。

プルリクエスト上でStaging環境にデプロイすることができるので、デプロイ完了後にこのようなテストを行っています。
テストが完了したら、テスト結果をコメントしてくれます。テスト結果に管理ツールへのリンクがあり、そこで会話の録音や文字起こしデータが見れるので、どんなテストをしたか証跡が残ります。

このテストエージェントは電話注文エージェントと同様、会話をするために必要なすべての機能に加え、架電機能も持っています。
なので、次のような仕組みでテストエージェントとStagingの電話注文エージェントを会話させています。

さて、なぜわざわざテスト用のAIエージェントを作ったかという話ですが、主に2つの理由があります。

  • 時間の節約のため。人間がやると時間を取られるから
    • 電話の応対はどうしても時間がかかる。しかもうっかり言い間違えるときもある
    • 人間のリソースはもっと別のことに注ぐべき
  • 並列実行できる
    • 複数パターン会話したい場合、人間がやると1個1個確認することになり時間がかかる
    • テストエージェントならこれを同時に出来る

3層テストを開発フローにどう組み込んでいるのか

Camel AI Callの開発はコーディングエージェントを使って開発をしています。
AIに自律的な開発をさせるため、開発フローを定義し、そのとおり実行させています。
その開発フローは以下のようになっており、赤い箇所が今回の3層テストです。

緑丸がついているところが人間が関与するところです。ほかはAIや自動スクリプトでやっています。

実装はTDDで行っていますので、UnitTestを作って実装をしてます。プロンプトを修正する際もRedGreenになるように開発をするために、LLM振る舞いテストを実装後、プロンプト実装するような流れにしています。

まとめ

  • 音声AIのテストを人間がやるのはしんどい
  • 音声AIのテストはAIでやろう
    • LLMのプロンプト品質チェックはLLM振る舞いテストで確認
    • コーディングエージェントの成果物品質チェックはE2Eテストスキルで確認
    • 全体的な動作確認はテストエージェントで確認
  • テストをAIに任せることで開発速度向上と品質向上を実現できた!

勉強会での発表資料

speakerdeck.com

Claude Codeの/ultrareviewを試してみた所感

こんにちは! racode です。 Claude Codeの新機能 /ultrareview を試してみたので、その仕組み・料金・制約・実際の出力を整理します。

エージェント AI が量産するコードと、人間レビューでは見つからないバグ

エージェント型 AI による開発は、すでに無くてはならないものになっています。

以下のように、GoogleやAnthropicでもすでに大部分のコードがAIによって生成されているようです。

  • Google: 新規コードに占める AI 生成の割合が 2024年Q3で 25%2025年秋で 50%2026年Q2で 75% と急増(Sundar Pichai 発言、Gemini + 内製エージェント開発基盤 Antigravity を使用)(businessinsider)
  • Anthropic: 全社の 70〜90% が AI 生成コード、Claude Code 自体の約 90% は Claude Code 自身が書いている(Anthropic 公式コメント)(Fortune)

一方、第三者調査が示すのは「速度と引き換えに、見つけにくいバグが紛れ込みやすい」という現実です。GitClear が累計 211M 行のコミット履歴を解析した 2025 年版レポートでは:

  • 書いてから 2週間以内にリバート/修正される短期チャーン率: 2020年 5.5% → 2024年 7.9%
  • リファクタリング相当の行: 2021年 25% → 2024年 10% 未満
  • 重複コード(clone)の出現率: 4倍 に膨張 (GitClear 2025レポート)

要するに「コミット時点では動く・型もテストも通る」一方で、統合の境界や運用時にだけ顔を出すバグが混入しやすくなっています。 ここが、AI が量産時代に入ったコードベースで急速に膨らんでいる問題領域です。

/ultrareview は、このような気づきにくい問題に対して有効的な機能です。複数の AI エージェントが並列に変更を読み解き、検出した不具合を独立に再現・検証してから報告することで、人間レビュアー1人 × 単一視点では落ちる種類の指摘を、マージ前にあぶり出します。本記事では仕様・料金・制約・実際の出力を整理します。

本記事の情報は 2026年5月時点の公式ドキュメントに基づきます。/ultrareviewリサーチプレビュー機能(Claude Code v2.1.86以降)であり、仕様・料金は変更される可能性があります。


/ultrareview とは

/ultrareview は、Claude Code の クラウドサンドボックス上で動作するマルチエージェント型のディープコードレビューです。ユーザーが CLI で /ultrareview と入力すると、リポジトリ状態がリモートにアップロードされ、複数のレビュアーエージェントが並列に変更を読み解き、検出した不具合を独立に再現・検証してから報告します。

ローカル実行の /review との違いを公式ドキュメントは次のように整理しています。

/review /ultrareview
実行場所 ローカルセッション クラウドサンドボックス
深さ シングルパス 複数エージェントが並列探索+独立検証
所要時間 数秒〜数分 おおむね5〜10分
課金 通常の利用枠 無料枠後は1回 \$5〜\$20(追加利用枠)
向いている場面 反復作業中の即時フィードバック マージ前の最終確認

ポイントは以下の3点です。

  1. High signal: 全ての指摘が独立に再現・検証される。スタイル指摘ではなく実バグに絞られる
  2. Broad coverage: 複数エージェントが別視点で並列探索するため、単一パスでは見落とすケースを拾う
  3. No local resource: ローカルマシンを占有しない。ターミナルを閉じても進行する

プラン・料金

/ultrareview は通常プランの利用枠とは別の 「追加利用枠(extra usage)」で課金されます。

プラン 無料枠 無料枠後
Pro 3回(2026年5月5日まで) 追加利用枠で課金
Max 3回(2026年5月5日まで) 追加利用枠で課金
Team / Enterprise なし 追加利用枠で課金

重要: Pro / Max の無料枠は 2026年5月5日で終了しています。本記事公開時点で新規ユーザーは初回から有料です。

  • 1回あたりの課金額は変更規模に依存し おおむね \$5〜\$20
  • リモートセッションが起動した時点で消費されるため、途中停止・失敗でも無料枠は1回消費される
  • 有料枠は実行された分のみ課金される
  • アカウント/組織で 追加利用枠が有効化されている必要があり、未設定の場合は起動がブロックされる(/extra-usage で確認・変更可能)

認証要件

  • Claude.ai アカウントでのログインが必須。API キー認証のみの環境では /login で Claude.ai に切り替える必要がある
  • Amazon Bedrock / Google Cloud Vertex AI / Microsoft Foundry 経由では利用不可
  • Zero Data Retention(ZDR)が有効な組織では利用不可

ユースケース

公式ドキュメントが推奨するのは「マージ前の最終確認」です。具体的には次のような場面に向きます。

  • 大きめの PR をマージする直前: 複数エージェントが独立に検証してくれるため、レビュワー1人の見落としを補完できる
  • セキュリティ・運用観点の最終チェック: 後述の使用例にあるように、レート制限の不備・URL エンコーディング欠落・IaC のドリフトなど、動作はしてしまうが本番でハマる類のバグを拾う
  • CI 連携での自動化: claude ultrareview サブコマンドにより非対話実行が可能。--json で生の bugs.json を取得、--timeout <分>(既定30分)でタイムアウト制御できる
# 現在のブランチ(既定ブランチ差分)をレビュー
claude ultrareview

# PR番号を指定
claude ultrareview 1234

# 任意のベースとの差分
claude ultrareview origin/main

GitHub PR への自動コメント投稿が目的なら、/ultrareview ではなく Code Review のリポジトリ統合がよさそう。


制約

導入前に押さえておきたいポイントです。

  1. リサーチプレビュー段階: v2.1.86 以降。仕様・料金・提供範囲は変わり得る
  2. クラウド送信が前提: ローカル作業ツリーがリモートサンドボックスに送られる。機密性の高いコードを扱う場合はポリシー確認が必要
  3. PR モードは GitHub 限定: PR 番号指定モードは github.com リモートが必要。GitLab/Bitbucket/オンプレ Git サーバーは対象外
  4. 巨大リポジトリはバンドル不可: その場合は draft PR を立てて PR モードを使うよう案内される
  5. 部分結果は返らない: /tasks で停止したレビューはアーカイブされ、途中までの検出結果は得られない
  6. 無料枠の使い切り判定は厳しめ: リモートセッション起動時点で1回カウント。失敗・早期停止でも消費される
  7. Bedrock / Vertex AI / Foundry / ZDR では使えない

使用例

簡単な EC サイトを Claude Code 3.7 を用いてワンショットで生成したものを利用します。そのままのコードを /ultrareview にかけたあと、ローカルの Claude Code セッションがそのまま修正・コミット・プッシュまで完了した直後の画面がこちらです。

注意: これは /ultrareview の出力ではなく、findings を受け取ったローカルセッションが修正・コミット・プッシュまで進めた結果です。公式仕様は findings の通知までで、修正以降は ローカル側(auto mode 等)の挙動です。

特徴的なのは、「動作はしているが運用で必ず壊れる」種類の指摘が多いことです。

  • /auth/*/* のレート制限 Map 共有による2重カウント
  • :latest プッシュ × IMMUTABLE ECR の2回目以降失敗
  • engine_version のマイナーバージョン自動更新ドリフト

このような実装の問題は、自身で実装していれば気づきそうですが、大量の生成されたコードの中では埋もれ、事前に発見するのは難しそうです。

次セクションでは、今回のレビューで発覚した内容をもとに、 AI コードレビューが構造的に強い/弱い領域を分類してみます。


AI コードレビューの観点 ── 何が拾え、何が拾えないか

検出された 10件を分類してみると、AI(特にマルチエージェント並列型)レビューが構造的に強い領域とそうでない領域がはっきり出ます。

AI が強い: 「横断不変条件」と「仕様準拠」

  • bug_001 (rate limit Map 共有): factory() で生成される rateLimit インスタンスが、内部の Mapプロセス共通の参照として共有してしまう古典的なクロージャ事故。コードを 1 ファイルだけ読むと正しく見えるが、呼び出し側の生成回数とインスタンスのライフサイクルを同時に追わないと検出できない。エージェントが「factory の利用箇所」と「Map のスコープ」を別々に並列追跡することで初めて落とし穴が浮き上がる
  • bug_002 (XFF 偽装): X-Forwarded-For の信頼ポリシーは ALB / CloudFront / Cloudflare で正しい挙動が異なる。RFC・各クラウドの公式ドキュメントを横断的に当てる作業は、AI が網羅的に得意な領域
  • bug_004 (URL エスケープ漏れ): DATABASE_URL のパスワード部に @ / 等が混じった瞬間に接続が壊れる。「動くケースが圧倒的多数で、たまに壊れる」境界条件は人間レビュアーが流しやすく、AI が網羅探索しやすい

これらは「単一ファイル単位では正しい」「仕様書を全件突き合わせれば必ず見つかる」種類で、並列エージェント × 検証ループという /ultrareview のアーキテクチャがそのまま効きます。

AI が強い: 「副作用と時間軸」

  • bug_003 (ECR latest × IMMUTABLE): タグの不変性ポリシーと CD パイプラインの整合は、現実に push が走って初めて壊れる典型。ローカルテストでは確認できない。
  • bug_009 (ECS force-new-deployment 順序): タスク定義の登録 → サービス更新の順序が逆転すると「古いタスクで強制再デプロイ」という挙動になる。実行順という時間軸の不変条件は、構文チェックでは拾えない
  • bug_026 (WAF へのレート制限移譲): コード側のプロセス内 Map によるレート制限はタスク数だけ実効上限が乗算される。単体の rateLimit.ts は正しく動くが、ECS のタスク数 × CDN 構成 × WAF 設定を組み合わせて初めて「実上限」が見える ── 単一視点では気づきにくい

/ultrareview がここを拾えるのは、bugs.json の各 finding を独立に再現・検証する設計(Higher signal の根拠)のおかげです。これがないと、AI レビューは「それっぽいが偽陽性」を量産します。

AI が拾いにくい: 「業務意図」と「組織知」

一方、Nit に分類された 3件 (bug_032 / bug_034 / bug_039) は AI レビューの限界を示します。

  • bug_039engine_version メジャー固定は「メンテナの方針次第」で、「自動マイナー更新を許容するか/許容しないか」は組織の運用ポリシー。AI は両論併記しかできない
  • bug_034migrate.sh dead codeは、本当に dead なのか「まだ使っていないだけで来週使う」のかをコードからは判断できない
  • bug_032final_snapshot_identifierは「再作成時に衝突する」ところまでは仕様で判定できるが、「そもそも再作成を許容する設計か(本番 RDS なら通常 NG)」は組織の運用次第
  • ボーナスの tags.Name 命名整合も同様で、組織内の命名規約を知らないと過剰に修正提案しがち

ここは Nit に落としてくれたから良いものの、AI が Normal severity に格上げした時こそ人間がブレーキを踏むべき領域です。

実運用での示唆

  • AI レビューは「多視点 × 仕様照合 × 副作用シミュレーション」で人間を超えるが、「業務文脈・組織慣習・将来計画」では人間に及ばない
  • /ultrareview の Severity 分類(Normal / Nit)は鵜呑みにせず、Nit の中の重要指摘・Normal の中の過剰指摘を人間がリラベルする運用が現実的
  • マルチエージェント検証は 偽陽性を減らす設計(≠ ゼロにする設計)。10 件中 1〜2 件はコンテキスト不足の指摘が混ざる前提でレビューすること
  • 上記の特性を踏まえると、マージ前ゲートよりも「PR 作成時の壁打ち」として使うほうが、人間と AI の役割分担として健全な場面も多い

まとめ

  • /ultrareview は Claude Code on the web 基盤上で動く マルチエージェント・クラウドレビュー
  • ローカル /review との差別化点は 独立検証 × 並列探索 × 非占有実行 の3点
  • Pro / Max の無料枠は 2026年5月5日に終了済み、以降は 1回 \$5〜\$20 の追加利用枠課金
  • マージ前の最終ゲートとして位置付けるのが王道。CI からは claude ultrareview --json で組み込める
  • 公式仕様で保証されるのは「verified findings をセッションに通知として返す」ところまで。修正・コミットの自動化はローカルセッション側の挙動なので、auto mode 利用時は push 前に人間レビューを挟む運用にすること
  • リモートサンドボックスへのコード送信を伴うため、機密リポジトリでの利用はポリシー要確認
  • Bedrock / Vertex AI / Foundry / ZDR 環境では現状利用不可
  • AI レビューが構造的に強いのは「横断不変条件 × 仕様準拠 × 副作用シミュレーション」、弱いのは「業務意図 × 組織知」。Severity ラベルは鵜呑みにせず、人間が再ラベルする運用が現実的

Google で 75%、Anthropic 社内で 70〜90% が AI 生成コードという時代に、人間レビュアー1人 × 単一視点だけでマージ判断を下し続けるのは現実的ではありません。/ultrareview は、その「AI が量産する量と速度」と「人間レビューの帯域」のギャップを、同じ AI 並列エージェント側から埋めにきた一手です。コミット前は通った、テストも通った、レビューも通った ── それでも本番で壊れるバグが急に増えたチームには、まず 1 度試す価値があります。


参考資料

AIデーを半年運用して出てきた成果物の紹介

こんにちは!fumiyaki です。

私たちのチームでは半年ほど前から「AIデー」というAIを活用する日を作り、運用しています。1スプリント2週間のうち、スプリント初日をまるごとAIデーにあてて、各メンバーが自由にAIを触る日です。

この半年で、AIデーからはいろいろな成果物が生まれました。本記事ではその中から、私が個人的に「これは紹介したい」と思ったものを3つピックアップして紹介します。

  • Slackスレッドでの議論反映 — スレッドでの議論を Devin が Issue やドキュメントに反映してくれる仕組み
  • エラー自動調査 — Slackへのエラー通知をトリガーに Devin が自動で調査して Issue まで起票する仕組み
  • kaigi — 会議後のTodoをまるごと自動化する常駐Claude Code

どれもメニューマネージャー(飲食店のメニューをフードデリバリープラットフォームへ配信するシステム)を作っているチームの中で生まれたものです。

AIデーについて

AIデーは、2週間スプリントの初日をまるごとAIを触る時間にあてるという日です。 以下のような形で運営されています。

  • テーマ縛りはなし: 業務と関係ない実験でも構わない
  • 成果物は必須ではない: 動くものが出来上がらなくてもOK
  • 共有会: その日の終わりに何をやったのか、知見を共有

導入の背景は、「AIを皆がどうやって使っているのかがわからない」という素朴な課題感でした。毎日の業務をこなしていると、他のメンバーが普段どんなプロンプトを書いているのか、どんなツールをどう組み合わせているのかはなかなか見えません。各自の工夫が個人の中に閉じてしまっていて、チームとして「AIの使い方」を蓄積する場が無い状態でした。

スプリントの中でAIデーは1日しか無いので「成果物を出す」という縛りを意図的にかけていません。手を動かすこと、そしてその日の終わりに「こういうことを試しました」を話すこと。この2点だけを重要視していて、結果や成果物は二の次、という設計にしています。

とは言え半年もやって成果物が0だったわけではないので、いくつかの成果物をピックアップして紹介するのがこの記事となります。

① Slackスレッドの議論を Issue に反映する Devin Playbook

最初に紹介するのは、Slack のスレッドで Devin を呼び出して一言依頼するだけで、そのスレッドの内容を解析して GitHub Issue やドキュメントの PR を自動で作ってくれる Playbook です。

きっかけは、開発チームあるあるの悩みでした。Slack で決まったことが Issue に反映されない、というやつです。

仕様管理には GitHub Issue を使っているのですが、日々の議論は Slack で進むので、「Slack で『B ではなく A で行こう』と決まったのに Issue には古い情報のまま残っている」「スレッドで『これもやらないとだね』と出たタスクが誰の TODO にもなっていない」「数週間後に『あの話どうなったっけ?』と聞かれて Slack を遡る羽目になる」といったことはあるあるですよね。

こうなる原因はシンプルで、Slack の議論を Issue に書き移す作業が手動で面倒くさくて、忙しい開発の中ではどうしても後回しになっていた、という話です。結果として、Issue が最新の状態を反映していない状況が生まれます。

この Playbook は、現在の運用を変えずに問題を解決することを狙っています。普段通り Slack のスレッド内で議論する。最後に Devin に一言依頼するだけで、Devin がスレッドを読み、内容を自動で分類して、適切な場所に情報を落としに行く、というのが大まかな流れです。

分類は「知識系」と「タスク系」の2つで行っています。

  • 知識系(技術仕様の議論、手順やワークフローの説明、ポストモーテムなど)→ GitHub にドキュメントの PR を作成
  • タスク系(バグ報告、改善要望)→ GitHub Issue を作成し、GitHub Projects にも追加、Type フィールド(Bug / Feature / Task)まで設定

両方に該当する場合はドキュメントと Issue の両方を作りますし、「知識」「タスク」のどちらかを明示して分類を上書きすることもできます。既存の Issue に議論の続きを追記したい場合は、Issue の URL を添えて依頼すれば、そのスレッドで出た新しい内容だけが追記されます。

設計のちょっとした工夫として、Devin にはドキュメントや Issue を書かせる前に必ずコードベースを調査させるフェーズを入れています。そうすると「○○画面の △△ コンポーネント(src/components/...)で、こういう条件のときに〜」のように、ファイルパスや関数名を含んだ具体的な記述になってくれて、後から読み返したときの情報量がぐっと上がります。Devin が Slack のスレッドだけを頼りに書くと、どうしても抽象度の高いふわっとした文章になりがちなので、この「まずコードを読んでから書く」の強制はかなり効いています。

もう1つの工夫は少し背景説明が必要なのですが、tacomsという会社はmobile order lab(以降はmolと表記)との合併しており GitHub Organization が2つあります。今回作った仕組みは tacoms 側と mol 側の Devin を 2段構成 で繋いでいます。

Slack 連携している Devin は tacoms 側に紐付いているのですが、対象のリポジトリは mol 側にあるため、tacoms 側の Devin が Slack スレッドを解析して、その結果を mol 側の Devin API に curl で渡してセッションを立て、mol 側が実際の GitHub 操作を実行する、という構成です。

制約自体は面倒なのですが、結果として「解析・分類」と「GitHub 操作」の責務が自然に分かれて、見通しの良い設計にはなりました!…多くの課題がありますが早く合体して欲しいです(泣)。

この Playbook は「Slack スレッドでの議論を、運用を変えずに Issue へ集約する」ための仕組みです。Single Source of Truth は AI 時代にとても大事だと考えています。

② エラー自動調査 — 属人化を溶かす

2つ目は、エラーの自動調査を Devin にまるごと任せる Playbook です。

メニューマネージャーでは、UberEats、Menu Inc. など複数のフードデリバリープラットフォームへメニューを配信しています。エラーはどうしても発生するものなので、Slack にエラー通知が届くたびに、誰かが DB・Google Cloud のログ・コードを辿って原因を特定する、という作業が発生するものです。

調査の流れは毎回ほぼ同じで、「エラーコードを確認 → データベースでジョブやスケジュールの状態を調べる → トレース ID で Google Cloud のログを検索 → 配信基盤システムのコードを読む → 原因を特定する」というステップでした。

問題は、この調査ができる人が限られていたことです。アカウントの権限の問題やデータベースのクエリ、Google Cloud のログの検索方法、配信基盤システムのコード構造を知っていないといけません。特定の人しかエラーに対応できないという属人化状態になっていました。

これを Devin Playbook にまるごと覚えさせたのが、この仕組みです。エラー通知をきっかけに Devin のセッションが起動し、以下を自動で実行してくれます。

  • 対応不要ブランド(テスト店舗など)のスキップ
  • CSV データからのエラーパターン分類
  • データベースのスキーマに基づく状態判定
  • トレース ID を使った Google Cloud のログの横断検索
  • コードパスの追跡による該当配信基盤システムの特定
  • 外部 APIでの現在の状態を確認
  • 調査結果の Slack スレッド投稿
  • バグ疑いの場合は GitHub Issue を起票(既存 Issue との重複チェックも!)

人がやっていた調査の流れを、そのまま Devin に実行させている形です。以下、設計で気を使ったポイントをいくつか紹介します。

調査を方法論に落とし込む

8 つのステップは Observe → Trace → Analyze → Report という調査メソドロジーに沿って構造化しています。データベース調査や Google Cloud のログ調査が Observe、コードパス追跡が Trace、結果統合が Analyze、Slack 投稿と Issue 起票が Report、という対応です。

わざわざ方法論に落としているのは、Devin に「次に何をすべきか」を明確に指示するためです。自由度が高すぎると調査が発散するリスクがあって、方法論に沿って順に進める構造が調査品質の安定に効いています。

データベース調査を Google Cloud のログより先に行う

一般的にはログから調べ始めることが多いかもしれませんが、この Playbook ではデータベース調査を先に行う順番にしています。データベースで判明した trace_id やタイムスタンプを Google Cloud のログの検索条件に使うことで、ログ検索の精度を上げるためです。人間が調査するときもデータベースの状態を先に確認してからログを絞り込む方が効率的なので、その順序を明示的に Playbook に組み込んでいます。

READ-ONLY 原則

Playbook には「Forbidden Actions」として以下を明示的に書いています。

  • コードの変更・ファイルの作成
  • データベースへの書き込み系操作全般
  • Google Cloud リソースの変更

自動で動くものだからこそ、安全性を最優先にしました。調査の目的は原因の特定であって、修正ではありません。READ-ONLY に徹することで、自動実行による意図しない副作用を排除しています。

Playbook と Knowledge を分離する

個人的に一番気に入っているのが、Devin の Playbook と Knowledge を分離していることです。

エラーパターン表、対応不要ブランドリスト、データベースクエリのテンプレート、Google Cloud のログの検索パターン、各配信プラットフォームの認証手順 — こういった「データ」に相当するものは全部 Knowledge 側に寄せていて、Playbook 側は「何をどの順番でやるか」だけに集中させています。

こうしておくと何が嬉しいかというと、新しいエラーパターンが見つかったときにコードや Playbook を触らずに、Devin の WebUI から 1 行追記するだけで次回から自動で判定してくれるようになります。運用で「このエラーコードは毎回こういう原因だった」という知見が溜まったら、Knowledge に追記するだけ。コード変更もデプロイも不要です。調査の知見がそのまま仕組みの精度に変わっていく感覚は、運用していて気持ちがいいですね。

もうひとつ、Knowledge の編集は WebUI 上の操作で完結するため、エラーパターンの追記や連絡先の変更くらいであればエンジニアでなくても触れる、というのも地味に大きいポイントです。

Issue の重複チェック

バグ疑いと判定された場合は GitHub Issue を自動で起票しますが、同じエラーが繰り返し起きたときに Issue が乱立しないよう、起票前に既存 Issue との重複チェックを入れています。

具体的には、Issue を作成するときに body の末尾に識別キーを HTML コメントで埋め込んでいます。

<!-- auto-investigation-key: {"error_code":"...","platform":"...","function":"..."} -->

次回の調査で同じエラーコード・プラットフォーム・関数の組み合わせが出てきたら、この識別キーで既存 Issue を検出して、新規起票の代わりに既存 Issue のリンクを Slack に返す、という作りにしています。

③ kaigi — 会議後のTodoを全自動化する常駐 Claude Code

3つ目は kaigi です。会議が終わるたびに発生する「議事録を書く」「GitHub Issue を起票する」「カレンダーを更新する」「ドキュメントを直す」という一連の作業を、Claude Code にまるごと任せてしまう仕組みです。

どのチームでも発生するこの地味な作業を消し去るために、Claude Code をローカルに常駐させ、Google Drive と Slack の変化をバックグラウンドで監視する構成を組みました。

技術的な肝は、Claude Code の2つの機能を組み合わせていることです。

1つ目は、バックグラウンドで監視用のプロセス(hookやポーリングなど)を動かしておき、そのプロセスが標準出力(log)に書き出したタイミングで反応する、というイベント駆動の仕組みです。Monitor tool と呼ばれています。 ログの出力がなければClaude Codeは何もしないので、待機中のコンテキスト消費をゼロに保てます。

kaigi ではこの Monitor を2つ走らせていて、片方は Google Drive を90秒間隔でポーリングして新しいトランスクリプトを見つけたら TRANSCRIPT: {...} を吐き出し、もう1つは Slack の Socket Mode で WebSocket を張って #fb を含むメッセージが投稿された時に NEW_FB: {...} を吐き出す、という分担になっています。

2つ目は、議事録のスレッドごとに独立したエージェントを立ち上げる仕組みで、こちらは Agent Teams を使っています。スレッド内で #fb のメッセージが検知されると、そのスレッド専用のClaudeインスタンスがCreateTeamで作られ、そのインスタンスが Monitor を使ってそのスレッドの返信を監視します。

FBの内容をエージェントが解釈し、 必要があれば kaigi システムを worktree で複製してPRの作成まで行います。Slackのスレッドごとに独立したインスタンスなので、仮に複数人が別々のスレッドで同時にFBしても、それぞれの文脈に集中して正確に動いてくれます。

会議後のたいくつな作業を解消するだけでなく、Slack でフィードバックを投げるとClaude Codeがこのシステムを進化させてくれます。

AIデーを回してみて

半年AIデーを続けてみて、一番変わったのはチームの AI に対する解像度だと思います。共有会で「こんなツールを試した」「このプロンプトはこう組むとうまくいく」という話をしているうちに、自然とチーム全員の AI への解像度が上がってきていると思います。

AIデー導入前に感じていた「皆がどう使っているかわからない」というモヤモヤは、今はあまり感じません。

一方で、正直に言うとまだまだ「一気に景色が変わった!」というフェーズには辿り着いていないというのが率直なところです。今回紹介した3つの仕組みも、それぞれ単体では便利なのですが、まだバラバラの点として存在している状態です。これらの点がどこかで線として繋がったとき、初めて「開発フローが変わった」と言える気がしていて、そこを目指しながらAIデーを続けています。

まとめ

AIデーの説明とそこから生まれた3つの成果物を紹介しました。

  • Slackスレッドでの議論反映: Devin を使って Slack の議論を Issue・ドキュメントに自動変換する
  • エラー自動調査: Devin Playbook で調査を方法論に落とし込み、属人化を剥がす
  • kaigi: Claude Code の Monitor × Team で、会議後のTodoを常駐エージェントに任せる

どれも「普段の業務を少し楽にする」ための仕組みですが、AIデーというまとまった時間がなかったら、おそらくどれも着手できていなかったと思います。「成果物は必須ではない」という緩めのルールが、結果的にチームにはちょうどよかったのかもしれません。

同じような悩み(AI をどう使うかチームの中で見えない、試す時間がない、知見が個人に閉じる)を持っているチームがあれば、2週間に1日だけでもAIデーを試してみると、半年後に何かしら見える景色が変わっているかもしれません。

Rorkを触ってみて感じたことと、AIエージェント時代の開発で思ったこと

お疲れさまです。株式会社tacomsのdaikiです!
今年から、毎月新しいことにチャレンジするという抱負があり 今月はRork というサービスを使って、日常のちょっとした不便を解消するアプリを試しに作ってます。

この記事は Rork の機能紹介をするものではありません。
すでにわかりやすい紹介記事はいくつかありますし、たとえば以下の記事すごくわかりやすいです。

https://zenn.dev/nogu66/articles/rork-introduction

この記事では、Rork の説明そのものではなく、実際に最上位グレードのProMaxプランまで課金してみて自分がどう感じたかを書いてみます。


きっかけ

(こんなアプリあったら便利なのに...)と思うことがたまにあります。

たとえば、

  • 犬の予防接種、前回いつ行ったっけ?
  • 雨予報の日でも、途中で止んでる時間があれば犬の散歩したいから通知して欲しい
  • コーヒーのレシピで、粉が○gならお湯の投下比率はどれくらいだっけ?

みたいな、日常の小さな不便です。

ただ、こういうものって、アイデアはメモしても途中で作る欲が薄れていきます。

理由はシンプルで、特に iPhone 向けのアプリを作ろうとすると、

  • Xcode を入れるのが重い
  • Mac 前提の空気がある
  • 実機確認までの距離が遠い

このあたりが普通に面倒です。

「ちょっと作ってみたい」くらいの温度感だと、そこを乗り越える前に止まってしまうことが多いと思います。 自分もまさにそうで、そんな時に出会ったのがRorkという**ブラウザ上でスマホアプリが開発できるAIエージェント"でした。

Rork — create a mobile app using AI in minutes

RorkのTOP画面


Rorkを触って最初に感じた良さ

Rork を触って、最初に「これはいいな」と思ったのは、実機で確認するまでがかなり近いことでした。

よかった点を素直に書くとこんな感じです。

  • Xcode が不要
  • ブラウザ上で開発できる
  • Windows でも触れる
  • 実機で動かしやすい
  • 最終的に Apple Developer 側にアプリを飛ばすところまで持っていける

特に印象的だったのは、思いついたものをすぐ実機で触れる体験です。

体感としては、

従来

設計 → 実装 → 起動 → QR → 実機確認

Rork

設計 → QR → 実機確認

くらいの短さがあります。

もちろん裏では色々動いているのですが、使っている側の感覚としてはかなり近いです。

この「思考から実機までの距離の短さ」は想像以上に強くて、
アイデアが熱いうちにそのまま触れる形にできるのは、かなり気持ちいい体験でした。


実際に作ってみたもの

試しに作ってみたのは、ペットの予防接種記録アプリです。

犬と猫の予防接種を記録して、次回予定日を忘れないようにする、かなりシンプルなものです。

ペットの予防接種管理アプリ
ペットの予防接種管理アプリ

要件としては、

  • 犬・猫のみ
  • ログイン不要
  • ローカル保存
  • オフライン対応
  • 接種日と次回予定日の管理
  • 期限切れ時の通知
  • 初回チュートリアルあり

といった内容で、やりたいことはそこそこ明確でした。

機能追加や画面の形を整えるフェーズは特に強く、
手戻りも少なく、「ちゃんと開発が前に進んでいる感覚」がありました。

実際に初回プロンプトで生成されたもの↓

初回プロンプトから生成されたアプリ


使ってみてよかったところ

1. まず動くものを作るまでが速い

これはやはり一番大きいです。

アプリ開発って、「作る前の準備」が億劫になっていたのですが、Rork だとその部分がなくなります。

「このアイデア、実際どうなんだろう」を試すまでが近く、
わずか小一時間ほどで触れる形にできるのは、個人開発との相性がかなりいいと感じました。


2. 実機確認の心理的ハードルが低い

コードを書いて終わりではなく、
実際に iPhone で触って確かめるところまで持っていきやすいのは大きいです。

UI の違和感や入力体験は、やっぱり実機で見ないと分からないので、
この距離の近さはかなり価値がありました。


3. iOS開発への苦手意識を弱めてくれる

「iOS アプリ開発はちょっと重い」という気持ちがある人にとって、
最初の一歩としてかなりいいと思います。

少なくとも自分は、Xcode が必要ない時点でかなり気楽でした。


一方で、使っていて困ったところ

ただ、いいことばかりではありませんでした。

1. 詰まるのは意外と「軽そうなエラー」

印象としては、

👉 機能開発は強いが、局所的なエラーでハマることがある

という感じでした。

特にハマったのは、フォーマッターやlint系のエラーです。

人間が見れば「ここ直せば終わりだよね」という内容でも、
これをFixさせると、なぜか何往復もすることがある。

修正を投げる → 直ったように見える → 別のエラーになる
→ また投げる → 少し変わる → でも完全には直らない

このループに入ると、抜け出しづらいです。

しかも、毎回ちょっとずつ前進しているように見えるので、
つい続けてしまう。


2. そういう時は、結局人間が見ることになる

途中で気づきます。

「これはコード見た方が早いな」

実際にコードを見て直す。

この方が速い場面がたまにあります。

この瞬間が、個人的には一番「現実に戻る」ポイントでした。

それまでかなり気持ちよく進んでいた分、全部を任せ切れるわけではないと理解するタイミングになります。(GitHubとの連携はすごく簡単だった)


3. リリース周りは普通に手間がある

これは Rork に限った話ではありませんが、

  • スクリーンショット
  • プライバシーポリシー
  • ストア情報入力

このあたりはやはり残ります。

実装コストは下がっても、
アプリ公開のための作業まで完全に消えるわけではありませんでした。


使ってみて感じたこと

Rork はたしかに便利です。

特に、

👉 アイデアをすぐ実機で試せる

という点はかなり価値があります。

ただ、使っていて感じたのは、

AI は「とりあえず前に進める」のは本当に速いけど、 ここまで進めたけど、そもそもこれやるべきなのか?と立ち止まる判断はあまり得意じゃない

ということでした。


AIエージェント開発で大事だと思ったこと

最終的に一番重要だと感じたのは、

「どこまで任せるか」ではなく「どこで切り替えるか」

でした。

例えば、

  • 仕様を形にする → AIに任せる
  • 同じエラーが続く → 人間が見る
  • リリース前の詰め → 最後は人間が握る

この切り分けだと、かなり楽になりました。

本音を言えば、コードを一切見ずにそのままリリースまでいきたいですが、 その手前で一度人間に戻ってくる感覚があります。


まとめ

Rork は、個人開発のハードルをかなり下げてくれるサービスでした。

特に、

👉 「作ってみたい」を、その日のうちに触れる形にできる

これはかなり大きい価値だと思います。

一方で、

  • 局所的なエラーでハマることがある
  • リリース周りの作業は残る

という現実もあります。

作るところはかなり楽になる。でも、その分それ以外の仕事が前に出てくる。

ただ、それでも
「作ってみようかな」と思える距離まで持ってきてくれるのは間違いないです。

日常の小さなアイデアを形にしたい人は、一度触ってみるとかなり感覚が変わると思います。