OpenAI Client Retries

Turn on the OpenAI SDK's built-in Retry-After + backoff for the native client path

OpenAI client retries turn on the OpenAI SDK’s built-in retry engine so transient 429s and network blips on the native client path are retried automatically.

The same “native OpenAI client path” referenced here is where the Responses API routing lives — see OpenAI → Transparent Responses API routing.

Diagram

OpenAI Client Retries

429 / 5xx / blip

200

🤖 Agent

🧰 OpenAIClient

🌐 OpenAI API

⏳ Retry-After + backoff

✅ Response

Quick Start

  1. Turn it on with one env var (zero code change)
    python
    # export OPENAI_MAX_RETRIES=5
    
    from praisonaiagents import Agent
    
    agent = Agent(
        name="Assistant",
        instructions="You are a helpful assistant.",
    )
    agent.start("Summarise today's news.")
    # Transient 429s and network blips are now retried automatically.

    The user runs an agent; transient rate limits and network blips retry automatically on the native OpenAI client path.

  2. Pass max_retries through the client factory
    python
    from praisonaiagents.llm import get_openai_client
    
    client = get_openai_client(max_retries=5)
  3. Construct the client directly
    python
    from praisonaiagents.llm import OpenAIClient
    
    client = OpenAIClient(max_retries=5)

How It Works

The value is forwarded into the underlying openai SDK, which honours Retry-After on 429s and applies exponential backoff for transient errors.

Diagram
OpenAI APIopenai SDKOpenAIClientYour codeOpenAI APIopenai SDKOpenAIClientYour codeget_openai_client(max_retries=5)OpenAI(…, max_retries=5)chat.completions.create(…)POST /v1/chat/completions429 Too Many Requests (Retry-After: 2)sleep(2s) + exponential backoffretry200 OKresponse
BehaviourDetail
Applies toThe native OpenAIClient / get_openai_client path (used internally by AutoAgents and, since PR for #2963, by the OpenAI fallback leg of praisonai --auto / AutoGenerator), plus any direct callers.
Not affectedThe LiteLLM leg of praisonai --auto (LiteLLM runs first; OPENAI_MAX_RETRIES only kicks in when the OpenAI fallback runs). The LiteLLM-backed LLM class and agent-loop resilience engine also live in a separate layer — see Agent Retry. Since the fix for #3135, that agent-loop layer is on by default; pass Agent(..., retry=False) to opt out of it.
When unsetBehaviour is byte-identical to before — max_retries is only forwarded when it is not None.
Cacheget_openai_client() caches on max_retries, so changing it mid-process rebuilds the SDK client.

Configuration Options

OptionTypeDefaultDescription
max_retries (arg on OpenAIClient / get_openai_client)Optional[int]NoneNumber of automatic retries for transient errors on the native OpenAI client path.
OPENAI_MAX_RETRIES (env var)int (string)unsetFallback used when max_retries is not passed. Non-integer values silently fall back to the SDK default.

Precedence: explicit arg > OPENAI_MAX_RETRIES env var > SDK default.


Which Approach to Use

Match the retry surface to how broadly you want the policy to apply.

Diagram

Every native call
in the process

One client / hot path

No

Yes

Local server
LM Studio / vLLM

Where should retries apply?

OPENAI_MAX_RETRIES env var
(zero code change)

Need to tweak
other client options?

get_openai_client(max_retries=5)

OpenAIClient(max_retries=5)

Leave off
(no Retry-After to honour)


Common Patterns

Turn it on globally with one env var — for production deployments where every call should retry the same way.

python
# export OPENAI_MAX_RETRIES=5
from praisonaiagents import Agent

agent = Agent(name="Assistant", instructions="You are a helpful assistant.")
agent.start("Draft a weekly status report.")

Scope it to one call site — pass max_retries explicitly when you build the client for a hot path.

python
from praisonaiagents.llm import get_openai_client

# Only this client retries; the rest of the process is unaffected.
client = get_openai_client(max_retries=5)

Local server (LM Studio / vLLM) — leave it off — local endpoints rarely emit Retry-After, so retries are wasted latency.

python
from praisonaiagents.llm import get_openai_client

# No max_retries: keep local calls fast and fail fast.
client = get_openai_client(base_url="http://localhost:1234/v1")

Best Practices

Prefer the env var for cluster-wide policy

One place, no code change, easy to bump per environment. Set OPENAI_MAX_RETRIES once and every native call inherits it.

Start with 3–5

This matches the SDK’s typical rate-limit budget without inflating tail latency.

Don't stack with agent-level retry unless you mean to

As of the fix for #3135, a default Agent() retries transient errors (RetryBackoffConfig(), up to 3 retries) even without retry=True. If you also set OPENAI_MAX_RETRIES=5, both layers fire — 5 × 3 = 15 attempts on a rate limit. Pass Agent(..., retry=False) to disable the agent-loop layer if you only want the SDK-level policy.

Not a substitute for failover

Retries help transient blips; for provider outages use LLMConfig(fallbacks=[...]) — see Model Fallback.



Related