본문 바로가기
C.W.K.
Stream
Lesson 03 of 06 · published

도구 오류도 모델이 읽을 결과로 돌려줘

~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를 돌려줘. “database query failed: timeout”을 본 Claude는 다시 시도하거나 사용자에게 정보를 더 묻거나 다른 길을 택할 수 있어. 실패를 삼키면 모델은 왜 자료가 없는지 모른 채 추측해.

is_error로 실패와 빈 성공을 갈라

tool_result에는 is_error: True를 표시할 수 있어. 결과 행이 0개인 성공과 데이터베이스 연결 실패를 구분하는 신호야. 둘 다 사람이 읽을 콘텐츠를 담되, 프로그램상 상태도 함께 보내.

재시도는 각 도구의 성질에 둬

HTTP 조회나 읽기 전용 DB 질의는 일시 오류에 몇 번 재시도할 수 있어. 반면 파일 삭제나 결제처럼 부수 효과가 있는 쓰기는 곧바로 실패시키는 편이 안전해. 공통 루프가 모든 도구를 같은 횟수로 다시 부르지 않게 하고 처리기 안에 정책을 둬.

원칙: 오류도 도구 계약의 일부야. 모델이 복구 판단을 할 수 있도록 상태와 설명을 함께 드러내.

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

도구 처리기 하나를 오류 결과 패턴으로 감싸. 일시 실패와 영구 실패를 각각 강제로 만들고 모델이 재시도와 사용자 확인을 다르게 고르는지 봐.
Hint
모델의 복구 모양은 도구가 돌려준 상태와 힌트에 크게 좌우돼.

Progress

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

댓글 0

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

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