LabHub
배우기 러닝패스 코스

AI 에이전트 — 모델이 아니라 그래프 · 실패·재시도·예산 · 실습

카드 거절에도 세 번씩 다시 보냈다

LabHub 에서 이어서 보기

목표

노드에 RetryPolicy 를 붙이고, 다시 해도 되는 실패만 다시 하게 만든다. 같은 요청이 두 번 반영되지 않게 멱등 열쇠를 붙이고, 호출 예산을 세어 바닥나면 재시도 대신 포기하되 결과를 남긴다. 판정은 전부 횟수로 한다 — 시간이나 속도는 재지 않는다.

왜 중요한가

재시도는 한 줄로 켜진다. 그래서 켜 놓고 확인하지 않는다. 그런데 RetryPolicy 의 기본 retry_onValueError·TypeError·RuntimeError·OSError 같은 예외를 다시 하지 않는다(이 실습 환경의 langgraph 0.2.60 에서 확인한 사실입니다). 우리가 만드는 예외는 대개 그 계열을 물려받으므로, 정책을 붙여 놓고도 시도 기록에는 한 줄만 남는다. 오류도 경고도 나지 않는다.
반대로 retry_on 을 넓게 잡으면 영구 실패까지 상한까지 반복한다. 카드 거절 한 건에 시도가 세 줄 쌓이고, 그만큼이 정상 건이 쓸 몫을 먹는다. 그래서 "다시 해도 되는 실패" 를 가르는 기준이 필요하다 — 같은 요청을 그대로 다시 보냈을 때 다른 답이 나올 가능성이 있는가.
재시도가 안전하려면 조건이 하나 더 있다. 시간이 지나 끊긴 요청은 응답을 못 받았을 뿐 저쪽에서 이미 처리됐을 수 있다. 그대로 다시 보내면 두 번 청구된다. 요청마다 열쇠를 붙이고 받는 쪽이 그 열쇠로 "이미 한 건인가" 를 봐야 한다.
마지막으로 재시도는 그대로 호출 예산을 먹는다. 앞 건이 흔들리기만 해도 뒤 건은 시도조차 못 한다. 예산은 건수가 아니라 도구 몸통이 돈 횟수로 세고, 바닥났을 때는 예외를 올리는 대신 결과 기록의 한 줄로 남긴다.
채점기는 여러분이 적어 둔 설명을 믿지 않는다. 여러분의 모듈을 실제로 불러 매번 다른 열쇠·금액·실패 계획으로 돌리고, ATTEMPTS 에 쌓인 줄 수와 원장에 반영된 금액을 채점기가 따로 계산한 값과 대조한다.

단계

1. /root/work/agbudget/budget.pyMAX_ATTEMPTS·TransientError·PermanentError·ATTEMPTS·LEDGER·PLAN·reset()·applied_total()·charge()·State·build_plain()·run_once() 를 만드세요. 재시도가 없으므로 실패하면 시도는 한 번뿐입니다.
2. DEFAULT_RETRY·build_default_retry()·run_default() 를 더하세요. retry_on 을 적지 않은 RetryPolicy 를 노드에 붙였는데도 시도가 여전히 한 번인 것을 확인합니다.
3. RETRY_ALL·build_retry_all()·run_retry_all() 을 더하세요. retry_on=(ValueError,) 를 명시하면 일시 실패가 되살아나고, 상한을 넘기면 마지막 예외가 그대로 올라옵니다.
4. is_retryable(exc)·RETRY_SPLIT·build_split()·run_split() 을 더해 영구 실패를 다시 하지 않게 하세요. 영구 실패의 시도 횟수가 MAX_ATTEMPTS 에서 1 로 줄어야 합니다.
5. charge() 에 멱등 열쇠를 넣으세요. 같은 request_key 로 두 번 불려도 원장에는 한 줄만 남고, 두 번째 호출은 그때 그 영수증을 duplicate 표시와 함께 돌려줍니다.
6. BudgetExhausted·call_with_budget()·build_budgeted()·run_budgeted() 를 더하세요. 예산이 남지 않으면 도구를 부르지 않고, 포기하더라도 outcome"예산초과" 인 기록을 남깁니다.
7. settle_batch(orders, budget) 를 더해 여러 건이 예산 하나를 나눠 쓰게 하세요. 예산이 바닥난 뒤의 건은 skipped 로 남깁니다.
8. /root/work/agbudget/budget_report.json/root/work/agbudget/budget_report.md 에 재어 본 횟수를 기록하세요.

참고

단계 8개

  1. 재시도가 없으면 시도는 한 번뿐이다
  2. 정책을 붙였는데 왜 한 번만 하는가
  3. 다시 할 것을 직접 적는다
  4. 영구 실패를 세 번 보내지 않는다
  5. 두 번 와도 한 번만 반영한다
  6. 바닥나면 포기하되 기록을 남긴다
  7. 앞 건의 재시도가 뒤 건의 몫을 먹는다
  8. 재어 본 횟수로 기록한다