mirror of
https://github.com/hwchase17/langchain.git
synced 2025-06-21 14:18:52 +00:00
Add RunnableRetry Documentation (#13074)
This commit is contained in:
parent
55aeff6777
commit
06c503f672
@ -644,6 +644,17 @@ class Runnable(Generic[Input, Output], ABC):
|
|||||||
wait_exponential_jitter: bool = True,
|
wait_exponential_jitter: bool = True,
|
||||||
stop_after_attempt: int = 3,
|
stop_after_attempt: int = 3,
|
||||||
) -> Runnable[Input, Output]:
|
) -> Runnable[Input, Output]:
|
||||||
|
"""Create a new Runnable that retries the original runnable on exceptions.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
retry_if_exception_type: A tuple of exception types to retry on
|
||||||
|
wait_exponential_jitter: Whether to add jitter to the wait time
|
||||||
|
between retries
|
||||||
|
stop_after_attempt: The maximum number of attempts to make before giving up
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A new Runnable that retries the original runnable on exceptions.
|
||||||
|
"""
|
||||||
from langchain.schema.runnable.retry import RunnableRetry
|
from langchain.schema.runnable.retry import RunnableRetry
|
||||||
|
|
||||||
return RunnableRetry(
|
return RunnableRetry(
|
||||||
|
@ -35,13 +35,84 @@ U = TypeVar("U")
|
|||||||
|
|
||||||
|
|
||||||
class RunnableRetry(RunnableBinding[Input, Output]):
|
class RunnableRetry(RunnableBinding[Input, Output]):
|
||||||
"""Retry a Runnable if it fails."""
|
"""Retry a Runnable if it fails.
|
||||||
|
|
||||||
|
A RunnableRetry helps can be used to add retry logic to any object
|
||||||
|
that subclasses the base Runnable.
|
||||||
|
|
||||||
|
Such retries are especially useful for network calls that may fail
|
||||||
|
due to transient errors.
|
||||||
|
|
||||||
|
The RunnableRetry is implemented as a RunnableBinding. The easiest
|
||||||
|
way to use it is through the `.with_retry()` method on all Runnables.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
Here's an example that uses a RunnableLambda to raise an exception
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
import time
|
||||||
|
|
||||||
|
def foo(input) -> None:
|
||||||
|
'''Fake function that raises an exception.'''
|
||||||
|
raise ValueError("Invoking foo failed. At time {time.time()}")
|
||||||
|
|
||||||
|
runnable = RunnableLambda(foo)
|
||||||
|
|
||||||
|
runnable_with_retries = runnable.with_retry(
|
||||||
|
retry_exception_types=(ValueError,), # Retry only on ValueError
|
||||||
|
wait_exponential_jitter=True, # Add jitter to the exponential backoff
|
||||||
|
max_attempt_number=2, # Try twice
|
||||||
|
)
|
||||||
|
|
||||||
|
# The method invocation above is equivalent to the longer form below:
|
||||||
|
|
||||||
|
runnable_with_retries = RunnableRetry(
|
||||||
|
bound=runnable,
|
||||||
|
retry_exception_types=(ValueError,),
|
||||||
|
max_attempt_number=2,
|
||||||
|
wait_exponential_jitter=True
|
||||||
|
)
|
||||||
|
|
||||||
|
This logic can be used to retry any Runnable, including a chain of Runnables,
|
||||||
|
but in general it's best practice to keep the scope of the retry as small as
|
||||||
|
possible. For example, if you have a chain of Runnables, you should only retry
|
||||||
|
the Runnable that is likely to fail, not the entire chain.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
from langchain.chat_models import ChatOpenAI
|
||||||
|
from langchain.prompts import PromptTemplate
|
||||||
|
|
||||||
|
template = PromptTemplate.from_template("tell me a joke about {topic}.")
|
||||||
|
model = ChatOpenAI(temperature=0.5)
|
||||||
|
|
||||||
|
# Good
|
||||||
|
chain = template | model.with_retry()
|
||||||
|
|
||||||
|
# Bad
|
||||||
|
chain = template | model
|
||||||
|
retryable_chain = chain.with_retry()
|
||||||
|
"""
|
||||||
|
|
||||||
retry_exception_types: Tuple[Type[BaseException], ...] = (Exception,)
|
retry_exception_types: Tuple[Type[BaseException], ...] = (Exception,)
|
||||||
|
"""The exception types to retry on. By default all exceptions are retried.
|
||||||
|
|
||||||
|
In general you should only retry on exceptions that are likely to be
|
||||||
|
transient, such as network errors.
|
||||||
|
|
||||||
|
Good exceptions to retry are all server errors (5xx) and selected client
|
||||||
|
errors (4xx) such as 429 Too Many Requests.
|
||||||
|
"""
|
||||||
|
|
||||||
wait_exponential_jitter: bool = True
|
wait_exponential_jitter: bool = True
|
||||||
|
"""Whether to add jitter to the exponential backoff."""
|
||||||
|
|
||||||
max_attempt_number: int = 3
|
max_attempt_number: int = 3
|
||||||
|
"""The maximum number of attempts to retry the runnable."""
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def _kwargs_retrying(self) -> Dict[str, Any]:
|
def _kwargs_retrying(self) -> Dict[str, Any]:
|
||||||
|
Loading…
Reference in New Issue
Block a user