OpenAI Agents SDK
The OpenAI Agents SDK can be pointed at any OpenAI-compatible endpoint by configuring a custom provider.
Install
pip install openai-agentsConfigure
Create an OpenAIProvider that points at the Doubleword API and pass it via RunConfig:
from openai import AsyncOpenAI
from agents import Agent, Runner, RunConfig
from agents.models.openai_provider import OpenAIProvider
provider = OpenAIProvider(
openai_client=AsyncOpenAI(
base_url="https://api.doubleword.ai/v1",
api_key="{{apiKey}}",
),
)
agent = Agent(
name="my-agent",
model="{{selectedModel.id}}",
instructions="You are a helpful assistant.",
)
import asyncio
result = asyncio.run(
Runner.run(
agent,
"Say hello.",
run_config=RunConfig(model_provider=provider),
)
)
print(result.final_output)The Doubleword API supports both the Responses API and the Chat Completions API, so the SDK works with its default settings.
Prompt caching
Caching needs the Chat Completions path. The SDK also drops cache_control from any input you pass. Therefore, you need to attach the marker at the client instead:
import asyncio
from openai import AsyncOpenAI
from agents import Agent, Runner, OpenAIChatCompletionsModel
client = AsyncOpenAI(
base_url="https://api.doubleword.ai/v1",
api_key="{{apiKey}}",
)
_create = client.chat.completions.create
async def create(**kwargs):
messages = kwargs.get("messages")
if messages and messages[0]["role"] == "system" and isinstance(messages[0]["content"], str):
messages[0] = {"role": "system", "content": [{
"type": "text",
"text": messages[0]["content"],
"cache_control": {"type": "ephemeral", "ttl": "1h"},
}]}
return await _create(**kwargs)
client.chat.completions.create = create
agent = Agent(
name="my-agent",
instructions="…large, stable instructions (~1024-token floor)…",
model=OpenAIChatCompletionsModel(model="{{selectedModel.id}}", openai_client=client),
)
async def main():
result = await Runner.run(agent, "What is 2 + 2?")
print(result.context_wrapper.usage.input_tokens_details.cached_tokens)
asyncio.run(main())OpenAIChatCompletionsModel is required because the default Responses path does not cache. The instructions sit at index 0 on every turn, so the marker will hold across a multi-turn runs. See the prompt caching guide for more information about prompt caching.
Batch pricing with Autobatcher
For background tasks where latency is not critical, use Autobatcher to transparently route requests through the Batch API at reduced cost:
pip install openai-agents autobatcherfrom autobatcher import BatchOpenAI
from agents import Agent, Runner, RunConfig
from agents.models.openai_provider import OpenAIProvider
client = BatchOpenAI(
api_key="{{apiKey}}",
base_url="https://api.doubleword.ai/v1",
)
provider = OpenAIProvider(
openai_client=client,
use_responses=False,
)
agent = Agent(
name="my-agent",
model="{{selectedModel.id}}",
instructions="You are a helpful assistant.",
)
import asyncio
result = asyncio.run(
Runner.run(
agent,
"Say hello.",
run_config=RunConfig(model_provider=provider),
)
)
print(result.final_output)BatchOpenAI is a drop-in AsyncOpenAI subclass that collects requests and submits them as batch jobs automatically, cutting inference costs by up to 90%.
Why OpenAIProvider instead of set_default_openai_client
The Agents SDK also offers set_default_openai_client as a simpler global configuration. However, it will fail for model names that contain a / that doesn't match a known provider prefix, for example Qwen/Qwen3-30B or meta-llama/Llama-3.1-8B. The OpenAIProvider approach bypasses the SDK's built-in provider routing and sends the model name directly to your endpoint.