バグを自動修正するAIエージェントの作り方──まず再現から始めよう

バグを自分で修正するAIエージェントを作りましょう。各報告を失敗するAPIテストとして再現し、ブランチ上で修正し、テストスイートを再実行して、グリーンになった修正だけを納品します。

Ashley Goolam

Ashley Goolam

6 11月 2026

バグを自動修正するAIエージェントの作り方──まず再現から始めよう

Apidog エンタープライズ

オンプレミスデプロイ

SSO & RBAC

SOC 2 準拠

Apidog Enterpriseを見る

バグを自律的に修正するAIエージェントが機能するのは、たった一つのルールに従うときです。「再現できないなら、修正しない」。エージェントはバグレポートを今日失敗するテストに変換し、隔離されたブランチ上でコードにパッチを当て、そのテストと全スイートを再実行し、すべてがグリーンになったときにだけ報告を返します。マージは最終的に人間が行います。バグを再現できなければ、エージェントは何も言いません。

DeepSeek Harnessチームは、2026年11月1日にスーパーエージェント設計に関するエッセイで、このアイデアを多くの読者に向けて発表しました。本ガイドでは、それを今週中に構築できるパイプラインに落とし込みます。再現は、エージェントが作成しターミナルから実行するAPIテストとして記述します。

「再現」なしで「エージェント、これを直して」が失敗する理由

コーディングエージェントにバグレポートの修正を依頼すると、たいてい自信満々のdiffが返ってきます。それが本当にあなたのバグを修正したのか、エージェントが勝手に想像したバグなのか、あるいは何も修正していないのかは、判断できません。

再現ステップがないと、次の3つの問題が起こります。

失敗するテストはこの3つすべてを解決します。バグを固定し、「完了」を定義し、リグレッションチェックとしてテストスイートに残り続けるからです。

「黙って再現して修正する」の出自

「Exploring Super-agent Design」の中で、DeepSeek Harnessチームは、自コミュニティでの運用ポリシーを紹介しています。バグが報告されると、エージェントがバックグラウンドで再現を試みる。確実かつシンプルな修正が得られたときだけ報告し、それ以外は何も言わない、というものです。

エッセイはこれを投機的実行(speculative execution)と呼び、本稿で再利用する2つの要素と組み合わせています。ワーカーはタスクごとに独立したセッションを持ち、全ツールと最も強力なモデルを使い、人間ではなくルーターに報告します。ウォッチドッグは、各ワーカーが前進しているのか迷走しているのかを監視する独立したセッションです。

注意点として、エッセイが述べているのはアーキテクチャであり、出荷済みのDeepSeek Harness機能ではありません。その一部はプロトタイププラグイン dsh-superagent-prototype として存在し、作者自身が公式のDeepSeek製品ではないと明言しています。ルーターとワーカーの構図については、スーパーエージェントの構築方法を参照してください。

バグ修正エージェントの5ステップパイプライン

自己修正エージェントは毎回同じループを回します。ゲートが2つあります。

  1. 受け入れ(Intake): レポート、失敗したリクエスト、そのレスポンスを収集します。
  2. 再現(Reproduce): 報告された理由で失敗するテストを書きます。失敗するテストがなければ修正しません。
  3. 修正(Fix): 隔離されたブランチまたはワークツリー上でコードにパッチを当てます。
  4. 再実行(Re-run): 新しいテストがパスし、既存のスイートもパスしなければなりません。
  5. 納品(Deliver): 証拠とともにプルリクエストを作成するか、黙って終了します。
5ステップのバグ修正エージェントパイプラインのフロー図:受け入れ、失敗するテストでの再現、「再現なし修正なし」ゲートから「黙ってログに記録」へルーティング、ブランチ上で修正、テストとスイートの再実行、時間枠内で修正へ戻る「グリーンか?」ゲート、そしてマージする人間への納品

ステップ1:バグレポートを受け入れる

エージェントは「またチェックアウトが壊れてる」という報告を再現できません。受け入れには固定の形式を与えましょう。

フィールド 例 重要な理由
エンドポイント POST /orders どのハンドラを読むべきか
リクエスト "coupon": null を含むボディ 不具合を引き起こした正確な入力
実際のレスポンス 500、{"error":"internal"} テストが失敗を確認すべき内容
期待されるレスポンス 注文 id 付きの 201 テストがアサートする内容
環境 staging 再現を実行する場所

フィールドに欠落があれば、エージェントは一度だけ質問するか、ログからリクエストを取得します。RFC 9457 problem details に従ったエラーボディは、エラータイプが予測可能な形式で届くため役立ちます。

ステップ2:バグを失敗するAPIテストとして再現する

ここがゲートです。エージェントは受け入れレコードをテストケースに変換します。アサーションは2つ、期待するステータスコードと、レスポンスに含まれるべきフィールドです。そしてそれを実環境に対して実行します。結果は3通りあります。

修正が許されるのは1番目だけです。これが実務上の「黙って」という意味です。残りの2つは、キューを確認する担当者のためのログエントリを生成するだけで、ユーザーのチャットにはメッセージを送りません。

再現はユニットテストではなくAPIテストとして書きましょう。エージェントはユーザーが叩いたのと同じインターフェースを叩くため、誤って別のバグを再現してしまうことがありません。

ステップ3:隔離されたブランチでコードを修正する

再現が赤になったら、ワーカーはコードの専用コピーを取得します。git worktree が最も軽量な選択肢です。新しいブランチ上に2つ目の作業ディレクトリを作るため、エージェントの編集があなたのチェックアウトに触れることはありません。そこからサービスを起動し、テスト環境をそこに向けます。

2つの制約を厳密に守ります。修正は小さくなければなりません。3ファイルまたは変更50行といった上限を設定し、それを超えるものは人間への報告対象とします。そして修正は再現を狙ったものでなければなりません。リファクタリング、リネーム、整理は禁止です。余計な変更はすべて、レビュアーの確認負担になるからです。

ステップ4:再現テストと全スイートを再実行する

2つ目のゲートは2つの部分からなります。まず、エージェントはステップ2と同じテストケースを変更せずに再実行し、パスしなければなりません。エージェントがアサーションを編集してパスさせた場合、その修正は失敗とみなされます。パイプラインはテストファイルの修正前後のdiffを取ることで、これを検出します。

次に、既存のスイートがグリーンを維持している必要があります。1つのテストをグリーンにして3つをレッドにする修正は、ステップ3に差し戻されます。ループには時間枠を設け、たとえば3回の試行または20分で停止し、試した内容をログに記録します。ここでウォッチドッグが真価を発揮します。同じ行を編集し続けるワーカーや、再現が一切触れていないファイルに迷い込んだワーカーを強制終了できるのです。

ステップ5:確認済みのシンプルな修正だけを納品する

両方のゲートがグリーンになったら、エージェントは物語ではなく証拠とともにプルリクエストを作成します。レポート、失敗した実行、diff、スイート結果付きの成功した実行です。レビューとマージは人間が行います。保護ブランチを使えば、エージェントのトークンはブランチをプッシュできても、main にマージすることは決してできません。いずれかのゲートが失敗した場合、報告者には何も届きません。エージェントはログに1行書き残して次へ進みます。

修正前の同じ POST /orders テストが期待は201だが500で失敗し、修正後に2件中2件のアサーションがパスする様子を示し、JSONレポートを証拠として添付した図

自己修正AIエージェントのガードレール

最初の無人実行の前に、これらのフェンスを設定しましょう。

ガードレール 設定 防げること
スコープ 修正あたりの最大ファイル数と行数 修正と偽った大規模書き換え
時間枠 バグあたりの最大試行回数と分数 トークンを消耗する暴走ループ
認証情報 stagingのみ、本番キーは禁止 実際の注文を書き込む再現
マージ権限 ブランチのプッシュのみ、マージは禁止 未レビューのコードが main に到達すること
テスト整合性 テストファイルの修正前後diff パスするよう書き換えたアサーション
沈黙 失敗時にユーザー向けメッセージを送らない ノイズと半分しか確認されていない主張

最も重要なのは認証情報です。再現は実際にAPIを叩くため、stagingまたはシード済みのローカルデータを使用してください。

Apidog CLIでコーディングエージェントに再現を作らせる

ステップ2がパイプラインの心臓部であり、Apidog CLI はまさにそのために作られています。コーディングエージェント(Claude Code、Codex、Cursor、OpenCode)はテストケースをJSONとして書き、Apidogプロジェクトに作成し、ターミナルから実行します。あなたが書くのはプロンプト1つだけです。

まず一度だけセットアップします。

npm install -g apidog-cli@latest
apidog auth login --with-token <YOUR_TOKEN>
npx -y skills add https://apidog.com   # pick your agent when prompted

次に、エージェントにバグレポートとこのプロンプトを渡します。

Here is a bug report for POST /orders in Apidog project <projectId>.
Turn it into an Apidog test case that fails today: assert status 201
and that $.id exists. Run it against staging and confirm it fails for
the reported reason. If it does, fix the handler on a new worktree
branch until the same test passes, run the endpoint's other cases, and
open a PR with both JSON reports. If it doesn't reproduce, stop and log why.

エージェントは記憶に頼ってペイロードを作りません。スキーマを読み、カテゴリを検索し、ファイルを検証してから、ようやくケースを作成します。

apidog cli-schema get test-case-create
apidog test-case category --project <projectId>
apidog cli-schema validate test-case-create --file repro-orders.json
apidog test-case create --project <projectId> --file repro-orders.json

エージェントが書き出すファイルは次のようになります(IDはあなたのプロジェクトのものです)。

{
  "name": "Repro: POST /orders with null coupon returns 500",
  "apiDetailId": 123456,
  "categoryId": 1,
  "method": "post",
  "path": "/orders",
  "parameters": {},
  "commonParameters": {},
  "requestBody": {
    "type": "application/json",
    "data": "{\"items\":[{\"sku\":\"A-100\",\"qty\":1}],\"coupon\":null}"
  },
  "postProcessors": [
    { "type": "assertion", "defaultEnable": true, "enable": true,
      "data": { "name": "status is 201", "subject": "httpCode", "comparison": "equal", "path": "", "value": "201" } },
    { "type": "assertion", "defaultEnable": true, "enable": true,
      "data": { "name": "order id exists", "subject": "responseJson", "comparison": "exists", "path": "$.id" } }
  ]
}

そして、バグを証明する赤い実行がこちらです。

apidog run --test-case <caseId> --project <projectId> -e <stagingEnvId> -r cli,json --out-file repro-before

CLIレポーターは500でのステータスアサーション失敗を表示し、repro-before.json が apidog-reports/ に保存されます。修正後、エージェントは --out-file repro-after を付けた同一コマンドを実行し、両アサーションがパスします。この2つのファイルがプルリクエストの証拠となります。ステップ4では、エンドポイント上の全ケースを実行し、修正が密かに隣接機能を壊さないことを保証します。

apidog test-case run --project <projectId> --endpoint <endpointId> -e <stagingEnvId> -r cli,json

--upload-report を付けると、実行結果がApidogアプリ上に表示されます。マージ後、再現ケースはリグレッションテストとしてプロジェクトに残り、同じ apidog run に -r junit を付けると、CI/CDパイプラインでのApidog CLIの実行で示されているとおりCIにそのまま組み込めます。その他のセットアップについては、Apidog CLIエージェントワークフローとClaude CodeでのApidog CLIを参照してください。Apidog Freeは最大4ユーザーまで利用できるため、有料プランなしでこのループ全体を試せます。

FAQ

AIエージェントは本当に人間なしでバグを修正できるのか?

多くのシンプルなバグについて、再現・パッチ・証明は自律的に行えます。しかしマージすべきではありません。マージには必ず人間を関与させ、ブランチ保護でそれを強制しましょう。

エージェントがバグを再現できなかった場合は?

エージェントは停止し、試した内容をログに記録します。再現できないバグは確認できない修正であり、パッチは推測にすぎません。その後、人間がレポートに詳細を追記するか、クローズします。

エージェントがテストを書き換えてパスさせないようにするには?

テストケースが最初に失敗した時点でコピーまたはハッシュを保存し、修正を受け入れる前に比較します。テストファイルは、ワーカーが編集を許可されたパスの外に置いてください。

これを構築するのにDeepSeek Harnessは必要か?

いいえ。エッセイが述べているのは設計であり、そのプロトタイププラグインは公式のDeepSeek製品ではありません。シェルコマンドを実行できるコーディングエージェントなら何でも動作します。GitHub Actions 上のClaude Codeも含まれます。実際に試してみたい場合は、DeepSeek Harnessとは何かを参照してください。

ApidogでAPIデザイン中心のアプローチを取る

APIの開発と利用をよりシンプルなことにする方法を発見できる