LLM (Large Language Model)의 Function Calling 또는 Tool Calling을 사용할 때, 함수에서 예외가 발생하면 Python 프로세스가 중단되는 경우가 있습니다. 이를 방지하고, 프로세스를 안전하게 유지하며 예외를 LLM에게 전달하기 위해 재시도(retry) 정책을 설정하는 방법을 알아보겠습니다. 특히 LangChain 프레임워크에서는 Tenacity 라이브러리를 활용하여 재시도 메커니즘을 내장하고 있습니다. 이번 포스팅에서는 tenacity.retry 장식자(Decorator)를 사용해 함수 재시도를 구현하고, 실패 시 커스터마이징된 응답을 반환하는 방법을 설명합니다.
LLM/랭체인을 통한 Function/Tool Calling에서 호출된 함수에서 예외가 발생하면 다음과 같은 문제가 발생합니다:
이를 해결하기 위해 함수 레벨에서 재시도 정책을 설정하고, 마지막 실패 시에도 안정적인 응답을 반환할 수 있어야 합니다.
Tenacity는 Python의 강력한 재시도(retry) 라이브러리입니다. tenacity.retry
장식자를 사용하면 다양한 재시도 조건과 정책을 설정할 수 있습니다. 주요 기능은 다음과 같습니다:
LangChain 내부에서도 Tenacity
를 활용하여, 다양한 재시도 기능을 제공하고 있습니다.
다음은 LangChain의 Tool에 사용할 함수를 tenacity.retry
로 래핑하는 예제입니다.
from tenacity import retry, stop_after_attempt, wait_fixed, RetryCallState
def retry_error_callback(retry_state: RetryCallState) -> str:
exc = retry_state.outcome.exception()
return f"Exception: {exc.__class__.__name__}: {exc}"
# 재시도 정책 설정: 최대 3번 재시도, 2초 간격
@retry(
stop=stop_after_attempt(3),
wait=wait_fixed(2),
retry_error_callback=retry_error_callback,
)
def get_yes24_book_detail(url: str) -> str:
# 크롤링 코드이기에 네트워크 오류나 HTML 파싱 에러가 발생할 수 있습니다.
return ...
# 함수를 호출했을 때, 예외가 발생하더라도 프로세스 중단없이 안정적으로 값을 반환하게 됩니다.
book_detail = get_yes24_book_detail("https://www.yes24.com/Product/Goods/139709711")
# Function Calling에서 이렇게 활용합니다.
tools = [
get_yes24_book_detail,
]
stop_after_attempt(3)
: 최대 3번 재시도wait_fixed(2)
: 재시도 사이에 2초 대기retry_error_callback
: 마지막 재시도 후 실패 시 반환할 값을 설정RetryError
예외를 발생시키지 않고, retry_error_callback
을 통해 문자열 형태의 실패 결과를 반환합니다.랭체인의 langchain.tools.Tool
을 사용할 때에도 retry
장식자로 래핑한 함수를 적용하시면, 예외가 발생하더라도 안정적으로 함수 호출을 하실 수 있습니다.
파이썬 장식자도 하나의 함수이므로, 이렇게 먼저 재시도 정책을 생성하신 후에
from tenacity import retry, stop_after_attempt, RetryCallState, wait_random
def retry_error_callback(retry_state: RetryCallState) -> str:
exc = retry_state.outcome.exception()
return f"Exception: {exc.__class__.__name__}: {exc}"
# 장식자가 아니라, 이렇게 함수처럼 활용 가능
retry_strategy = retry(
# 모든 예외에 대해서 재시도. 특정 예외 클래스만 지정하고 싶다면?
# retry=retry_if_exception_type(Value),
stop=stop_after_attempt(3), # 재시도 횟수
wait=wait_random(1, 3), # 재시도 대기 시간
retry_error_callback=retry_error_callback,
)
아래와 같이 일관되게 재시도 전략을 지정하실 수 있습니다.
tools = [
retry_strategy(get_yes24_book_detail),
retry_strategy(other_function1),
retry_strategy(other_function2),
]
LangChain을 사용해 LLM과 Function/Tool Calling을 구현할 때는 재시도 정책을 설정하여 안정성을 높이는 것이 중요합니다. Tenacity를 통해 쉽고 유연하게 재시도 로직을 구현해보세요! 🚀
댓글