1 行渡すと Claude Code が 1 時間自走する ─ E2E テスト駆動で新機能を作らせた話
はじめに
私たちのチームは Slack 上で動く社内向け AI エージェントを開発・運用しています。新機能追加のたびに「Claude Code が実装したと言うが実際に Slack で動かない」という事象にあたっていたので、Claude Code に E2E テストケース 1 行を渡せば計画から実装・デプロイ・検証まで自走する仕組み を /e2e-dev というスラッシュコマンドとして作りました。1 回の依頼で 1 時間自走することもあり、その間 人間は別作業に集中できます(最後の Slack 目視確認は残ります)。
何を作っているか
Slack で @bot にメンションして自然言語で話しかけると、Bedrock Converse が意図を解析して該当のツールを実行し、結果を Slack に返します。

図: システム構成
構成は Slack Bot 用 Lambda + Amazon Bedrock AgentCore Gateway(OpenAPI target)+ 既存の社内 REST API です。
「新しいツールを 1 つ足す」作業が頻繁に発生する ので、安全に・速く回すためのワークフローを /e2e-dev として作った、というのが本記事の話です。
どんな課題を解きたかったか
Claude Code に Slack Bot 用 Lambda の新機能を作ってもらうと、こんなことが起きます。
- 「実装しました」と返ってくる
- ローカルの unit テストは PASS している
- でも Slack で実際に話しかけると、Bot は期待通り動かない
原因は下記のようなことがありました。
- LLM のツール選択精度(ツール description / 必須パラメータ設計)
- Bedrock の inputSchema 制約に引っかかったまま気付かない
- Gateway 側の OpenAPI spec 更新を忘れている
unit テストでは検出できない層なので、「Slack に話しかけたらこう返ってくる」までを完了条件にしたかったのです。
スラッシュコマンドの中身
.claude/commands/e2e-dev.md を作って、Claude Code のスラッシュコマンド /e2e-dev から呼び出します。引数は1行で、形式は <Slack発話> → <期待応答> です。
/e2e-dev 企業Aの招待URLを発行して → https:// で始まる招待URLが含まれた成功メッセージが返る
中身は12ステップのフローです。
フロー図(クリックで展開)

| Step | 内容 |
|---|---|
| 1 | 初期化(ループカウンタ N = 0) |
| 2 | 必要な MCP ツールのロード |
| 3 | ベースライン確認: 同じ発話を Bot に投げて現状の応答を観測。Botから応答自体が返ってこないなら 中止、期待通りなら早期成功 |
| 4 |
ギャップ分析: N >= 5 で 中止(ループ上限超過)。セーフならループカウンタ Nに+1 → API 状態確認 → APIのレスポンスに応じて分岐 → Lambda 側ギャップ確認 → 実装計画出力 |
| 5 | API 未実装なら API リポで先に実装(前提チェック → 設計 → 実装 → 品質チェック → デプロイ)。DBスキーマ変更が必要なら 中止 |
| 6 | Slack Bot 用 Lambda 側の実装(ツール定義 / 判定基準 / フォーマッタ / 確認フロー / テスト追加) |
| 7 | 品質チェック(テスト実行 → 全テスト PASS) |
| 8 | dev デプロイ: Gateway → Lambda の順。各失敗で 中止(Gateway デプロイ失敗 / ビルド失敗 / Lambda デプロイ失敗) |
| 9 | E2E 検証: 発話を再投入し期待応答と突き合わせ。Botから応答自体が返ってこないなら 中止 |
| 10 | 原因切り分け: Lambda 側→Step 4 / API 側→Step 11 →Step 9 / OpenAPI specの不整合→Step 8 / インフラ→中止(インフラ到達不可) |
| 11 | API 修正サブフロー(不一致特定 → 修正 → テスト → push → dev 再デプロイ → Step 9 に戻る) |
| 12 | 結果レポート(テストケース / ベースライン / 実装内容 / 観察ログ / 検証結果 N/5) |
フロー全体は上記の流れで、E2E が通るまでを「完了」 と定義しています。
肝はベースライン確認とE2E検証です。同じ発話を「実装前」と「実装後」に Slack に投げて差分を取る ことで、unit テストの PASS では分からない「実際に意図通り動いたか」を客観的に確認できます。
そして結果レポートが返ってきた後、最後に 開発者が Slack スレッドを目視で確認 します。パターンマッチの自動判定だけでなく、実際の応答テキストが意図通りかを人間が見て最終 OK を出します。実装が終わった瞬間ではなく、E2E検証の自動判定 + 開発者の目視確認 が揃った時点で初めて「完了」とする扱いです。「Claude Code が実装したと主張するが動かない」が事実上ほぼ起きませんし、起きても最後の目視確認で気付けます。
なお Lambda 側修正のループは 5 回まで で、超えたら自走を止めて中止レポートを出します。無限ループや、壊れたコードが dev に出続けることを防ぐ安全装置として入れています。
学び
3 ヶ月ほど運用して見えたこと。
-
「Claude Code が実装した」と「実際に動いた」は別物。E2E PASS を完了条件に組み込むと、この間にあった責任の曖昧さが消えました
-
テストケースを先に書く強制力は AI に対しても効きました。「期待応答」を1行書くだけで、LLM と人間のゴールが揃います
-
テストケースの曖昧さは結果の曖昧さに直結します。「成功する」「うまく動く」のような書き方では、Claude Code は何を満たせば PASS なのかを自分で解釈してしまいます。「何の状態が、どう変わるか」を1行で精度高く言語化することに時間を使った方が、最終的な手戻りは大きく減りました
-
悪い例:
企業Aの招待URLを発行して → 成功する -
良い例:
企業Aの招待URLを発行して → https:// で始まる招待URLが含まれた成功メッセージが返る
悪い例だと「成功」の定義が LLM 任せになります。たとえば「Slack に何か応答が返ってきた」だけで PASS と判定されることもあり、人間が想定した「URL が含まれる成功メッセージ」とは別の基準で動く可能性があります。良い例は「URLが含まれる」「メッセージが返る」という具体的な完了条件があり、機械的に判定できます。
-
悪い例:
-
API 側変更のサブフロー必須: 新機能のほとんどは API 側の追加が必要で、Slack Bot だけ直しても動きません。API 開発・修正のサブフローを設けないと結局手動になります
-
ベースライン確認は意外と効きます: 実装前に同じ発話を投げるベースライン確認を入れたら、「そもそも何ができていないか」が明文化されて、その後のギャップ分析の計画精度が上がりました
副次効果: AI へのマイクロマネジメントから解放された
完了条件が <発話> → <期待応答> という形で合否が機械的に判定できるので、人間が途中経過に介入する必要が無くなりました。
これまでは Claude Code に作業を任せても、途中経過の確認や軌道修正の指示を入れるために画面に張り付いている時間が長くありました。
/e2e-dev 化してからは、1 行渡したら別プロジェクトに頭を切り替えて並行作業できます。E2E PASS の結果レポートが戻ってきたら、最後に Slack スレッドを目視で確認して OK を出します。1 時間自走するということは、その間 別プロジェクトを進められる 1 時間 を獲得したのと同じ意味になります。
適用範囲
- Slack Bot 用 Lambda の 発話 → 応答 が観測可能な機能に限ります
- E2E 検証は dev 環境で完結する設計です(prod デプロイは別フローに分けています)
- 1 回の依頼で 5 分〜1 時間 ほど自走します。新規ツール追加で API 側の実装も伴うと、検証〜修正で数往復するので 1 時間に届くことがあります
おわりに
Claude Code に新機能を作らせる仕組みは、プロダクトごとに合った設計がありそうです。私たちのチームのケースでは 「テストケースを最初に渡し、E2E PASS を完了条件にする」 という形に落ち着きました。同じ条件のプロジェクト(Slack Bot など)の方は試してみてもいいかもしれません。
株式会社カンリーは「店舗経営を支える、世界的なインフラを創る」をミッションに、店舗アカウントの一括管理・分析SaaS「カンリー店舗集客」の開発・提供、他複数のサービスを提供しております。 技術系以外のnoteはこちらから note.com/canly
Discussion