Skip to content

feat: 修正失敗時のリトライを追加#10

Merged
yu-sugimoto merged 2 commits into
mainfrom
feat/retry-agent
Mar 4, 2026
Merged

feat: 修正失敗時のリトライを追加#10
yu-sugimoto merged 2 commits into
mainfrom
feat/retry-agent

Conversation

@yu-sugimoto

Copy link
Copy Markdown
Collaborator

自己修復アプローチ

  • 方法としては、①LangGraph リトライ、②Worker 内 Claude 修正があったが、それぞれ以下のメリデメがあった
評価軸 LangGraph リトライ) Worker 内 Claude 修正
修正の精度 エラーログのみで判断、コンテキスト少ない 自分の実装+エラーから的確に修正
レイテンシ Pod 再起動で 30〜60秒 / リトライ 修正のみで数秒
API コスト 各リトライが最小プロンプト 会話が肥大化
リソース効率 失敗時に Pod を即解放 Pod 長時間占有でやや悪め
障害分離 各リトライが独立 Pod OOM / タイムアウトリスク
スケーラビリティ K8s スケジューラに委任 Pod 占有時間増大
可観測性 Job 単位で追跡 ログでしか追跡不可

今回 → Worker 内 Claude 修正を採用

理由

修正精度が圧倒的に高いためWorker 内 Claude 修正を採用する。dev server 起動失敗の原因は実装ミス(ポート指定、依存関係、ビルドエラー等)が大半で、Claude が「自分の実装コンテキスト」を保持したまま修正できる ので精度がいいはずと判断した。ただ、コンテナを起動&並列処理が10を超えてくると、jobを再度渡すのがいいかもしれない


一時的な緩和策

  • タイムアウト対策
    • WORKER_DEADLINE_SECONDS を 900 → 1200 に引き上げ
  • OOM 対策
    • リトライ前に kill で 前回の dev server プロセスを確実に停止
  • API コスト対策
    • リトライ回数を最大2回に制限

Copilot AI review requested due to automatic review settings March 4, 2026 05:55

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Worker の dev server 起動失敗時に、同一 Pod 内で Claude に自己修復させてリトライすることで、失敗率低減と再実行コスト削減を狙う PR です(LangGraph 側の Job リトライではなく Worker 内リトライを採用)。

Changes:

  • dev server 起動〜スクリーンショット取得をリトライするループを追加(最大2回リトライ)
  • 失敗時に dev server プロセスを停止する kill_dev_servers() と、Claude に修正させる fix_with_claude() を追加
  • .dockerignore を新規追加し、Docker build コンテキストを抑制

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
docker/worker-implement.py スクリーンショット取得の検証強化と、失敗時の自己修復リトライ導入
.dockerignore node_modules 等を除外してビルドコンテキストを削減

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +379 to +388
except Exception as e:
last_error = str(e)
if attempt < max_retries:
emit_log(
"implementing",
f"Dev server launch failed (attempt {attempt + 1}/{max_retries + 1}), attempting fix...",
detail=last_error,
)
await kill_dev_servers(repo_dir)
await fix_with_claude(repo_dir, last_error)

Copilot AI Mar 4, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On failure you pass str(e) into fix_with_claude(), but the most common exception here is the synthetic “Screenshot was not created...” error, which doesn’t include the actual dev server/stdout/stderr that Claude needs to fix the root cause. Consider capturing and surfacing the relevant launch/screenshot command outputs (or writing them to a file and including that content) so the retry/fix prompt contains actionable error details.

Copilot uses AI. Check for mistakes.
Comment on lines +189 to +195
async def kill_dev_servers(repo_dir: str) -> None:
"""Kill any lingering dev server processes (node, vite, next, etc.)."""
for pattern in ["node", "vite", "next"]:
subprocess.run(
["pkill", "-f", pattern],
capture_output=True,
)

Copilot AI Mar 4, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kill_dev_servers() relies on calling pkill, but the current worker image build (docker/worker.Dockerfile) does not install procps, so pkill is likely missing and this will raise FileNotFoundError, breaking the retry flow. Either install the needed OS package in the worker image or handle the absence of pkill (e.g., fallback to another mechanism) so retries don’t fail immediately.

Copilot uses AI. Check for mistakes.
Comment on lines +189 to +195
async def kill_dev_servers(repo_dir: str) -> None:
"""Kill any lingering dev server processes (node, vite, next, etc.)."""
for pattern in ["node", "vite", "next"]:
subprocess.run(
["pkill", "-f", pattern],
capture_output=True,
)

Copilot AI Mar 4, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kill_dev_servers(repo_dir) doesn’t use repo_dir and runs pkill -f on very broad patterns (node, vite, next). That can terminate unrelated processes in the container (and makes the parameter misleading). Prefer scoping the kill to processes launched for this repo (e.g., match repo_dir in the command line, or better: capture and store the dev server PID when starting it and kill that PID/process group).

Copilot uses AI. Check for mistakes.
@yu-sugimoto yu-sugimoto merged commit 17d70f0 into main Mar 4, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants