C.W.K.
Stream
Lesson 03 of 06 · published

Tool 에러 · retry · 모델한테 알려주기

~14 min · errors, retries, tool-result

Level 0Observer
0 XP0/64 lessons0/13 achievements
0/150 XP to next level150 XP to go0% complete

에러는 tool_result 콘텐츠

도구 실패 시 루프 밖으로 exception raise X — 에러 페이로드 가진 tool_result 반환. Claude가 'database query failed: timeout' 읽고 retry, user한테 묻기, 또는 pivot 결정. 에러 숨기면 모델 눈멀음.

is_error 플래그

Tool result 블록이 is_error: True 지원. Programmatic 에러 플래그해서 모델이 'no rows' 반환한 성공 쿼리와 실패한 쿼리 차이 알게. 둘 다 콘텐츠 있어; 하나만 에러.

Tool당 retry 예산

일부 도구(HTTP fetch, DB 쿼리)는 모델한테 보고 전에 transient 에러에 retry 가치. 다른 거(side effect 가진 write)는 fail fast 해야. 정책을 핸들러에 박아, 루프 X — 루프는 tool-agnostic.

원칙: 에러는 도구 계약의 일부. Surface — 모델이 너 코드 경로보다 더 나은 recovery 에이전트.

Code

에러를 tool_result 콘텐츠로 반환·python
import json

def invoke_tool(name: str, arguments: dict, tool_use_id: str) -> dict:
    handler = HANDLERS.get(name)
    if not handler:
        return {
            "type": "tool_result",
            "tool_use_id": tool_use_id,
            "is_error": True,
            "content": f"unknown tool: {name}",
        }
    try:
        out = handler(**arguments)
        return {
            "type": "tool_result",
            "tool_use_id": tool_use_id,
            "content": json.dumps(out),
        }
    except TransientError as e:
        return {
            "type": "tool_result",
            "tool_use_id": tool_use_id,
            "is_error": True,
            "content": f"transient: {e}; safe to retry",
        }
    except Exception as e:
        return {
            "type": "tool_result",
            "tool_use_id": tool_use_id,
            "is_error": True,
            "content": f"permanent: {e}; consider asking the user for clarification",
        }
핸들러에 per-tool retry 정책·python
import time

def http_fetch(url: str, attempts: int = 3) -> dict:
    last = None
    for i in range(attempts):
        try:
            r = httpx.get(url, timeout=10.0)
            r.raise_for_status()
            return r.json()
        except (httpx.TimeoutException, httpx.HTTPStatusError) as e:
            last = e
            time.sleep(2 ** i)
    raise TransientError(f"http_fetch failed after {attempts} attempts: {last}")

External links

Exercise

Tool 핸들러 하나를 에러 패턴으로 wrap. Transient failure 강제하고 모델이 어떻게 다루는지 봐. Permanent failure 강제하고 차이 봐.
Hint
모델이 transient엔 retry, permanent엔 user한테 묻는 경우 많아. 너가 주는 신호가 recovery 모양.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.