<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Temporal on RockB</title><link>https://baeseokjae.github.io/tags/temporal/</link><description>Recent content in Temporal on RockB</description><image><title>RockB</title><url>https://baeseokjae.github.io/images/og-default.png</url><link>https://baeseokjae.github.io/images/og-default.png</link></image><generator>Hugo</generator><language>en-us</language><lastBuildDate>Wed, 10 Jun 2026 03:45:54 +0000</lastBuildDate><atom:link href="https://baeseokjae.github.io/tags/temporal/index.xml" rel="self" type="application/rss+xml"/><item><title>OpenAI Agents SDK + Temporal Integration: Production Agent Guide 2026</title><link>https://baeseokjae.github.io/posts/openai-agents-sdk-temporal-integration-2026/</link><pubDate>Wed, 10 Jun 2026 03:45:54 +0000</pubDate><guid>https://baeseokjae.github.io/posts/openai-agents-sdk-temporal-integration-2026/</guid><description>Build production-grade AI agents using OpenAI Agents SDK + Temporal. Code walkthroughs, architecture patterns, and real deployment lessons from 2026.</description><content:encoded><![CDATA[<p>The OpenAI Agents SDK paired with Temporal gives you a production-ready foundation where LLMs handle reasoning and Temporal handles durability — auto-retries, crash recovery, and state persistence included. Without Temporal, 76% of real-world agent deployments fail. With it, your agent survives Kubernetes restarts, rate limits, and multi-hour workflows.</p>
<h2 id="why-76-of-ai-agents-fail-in-production-and-what-the-data-tells-us">Why 76% of AI Agents Fail in Production (And What the Data Tells Us)</h2>
<p>An analysis of 847 AI agent deployments in 2026 found that 76% failed in production, with 62% of those failures tied directly to authentication and state management issues — not model quality or prompt design. The math is brutal: an agent with 85% per-step success rate running 8 sequential steps has only a 27% end-to-end success rate. Every additional step compounds the failure probability, and long-running tasks make it worse. Research confirms that after 35 minutes of execution, every agent experiences measurable success rate degradation — and doubling the task duration quadruples the failure rate. Most developers build agents that work in notebooks and break in production because notebooks never handle crashes, partial completions, or mid-run restarts. The root problem is architectural: agents need a runtime that persists state, retries failures, and resumes from where they stopped. Temporal was designed exactly for this, and its March 2026 General Availability integration with the OpenAI Agents SDK makes the combination the production baseline for serious workloads.</p>
<h3 id="the-compounding-failure-problem">The Compounding Failure Problem</h3>
<p>Most agent frameworks treat each LLM call as stateless. If your 8-step research agent crashes on step 6 due to an OpenAI rate limit error, you restart from zero — wasting 5 LLM calls, 5 tool executions, and potentially minutes of compute. At scale, this isn&rsquo;t an edge case: it&rsquo;s the default. Rate limits hit multiple times a day in any real usage pattern. Kubernetes pods restart during rolling deployments. Network timeouts interrupt long API calls. Without durable state, every one of these events is a silent failure that the user sees as &ldquo;the agent just stopped.&rdquo;</p>
<h3 id="what-the-24-success-stories-have-in-common">What the 24% Success Stories Have in Common</h3>
<p>The 24% of deployments that survived production all shared one characteristic: they used a workflow engine — Temporal, Prefect, or Airflow — to manage execution state outside the agent process itself. Temporal&rsquo;s approach specifically targets AI workloads with native support for long-running activities, retries with exponential backoff, and workflow versioning that lets you update agent logic without killing in-flight jobs.</p>
<h2 id="what-is-the-openai-agents-sdk-core-primitives-for-production-in-2026">What Is the OpenAI Agents SDK? Core Primitives for Production in 2026</h2>
<p>The OpenAI Agents SDK is an open-source Python framework (released March 2025, GA 0.2.x in April 2026) that provides five core primitives for building production AI agents: <code>Agent</code>, <code>Runner</code>, <code>Tools</code>, <code>Handoffs</code>, and <code>Guardrails</code>. Unlike raw API calls or LangChain chains, the SDK gives you a structured execution model where agents can delegate tasks to other agents via handoffs, use tools through a type-safe interface, and apply guardrails that validate inputs and outputs before they reach the model. The April 2026 0.2.x release added native sandbox execution (E2B/Modal/Daytona), streaming speech-to-text, and support for arbitrary message sizes — closing the gap between prototypes and production requirements. The SDK is intentionally minimal: it handles the agent loop (observe → plan → act → observe) without prescribing infrastructure. This is where Temporal fills a critical gap — the SDK reasons brilliantly but has no built-in answer for what happens when the process dies mid-loop.</p>
<h3 id="agent-and-runner-the-core-execution-model">Agent and Runner: The Core Execution Model</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#f92672">from</span> agents <span style="color:#f92672">import</span> Agent, Runner
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>agent <span style="color:#f92672">=</span> Agent(
</span></span><span style="display:flex;"><span>    name<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;research_agent&#34;</span>,
</span></span><span style="display:flex;"><span>    instructions<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;You are a research assistant. Use search and summarize tools to answer questions.&#34;</span>,
</span></span><span style="display:flex;"><span>    tools<span style="color:#f92672">=</span>[search_tool, summarize_tool],
</span></span><span style="display:flex;"><span>    model<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;gpt-4o&#34;</span>,
</span></span><span style="display:flex;"><span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Synchronous run</span>
</span></span><span style="display:flex;"><span>result <span style="color:#f92672">=</span> Runner<span style="color:#f92672">.</span>run_sync(agent, <span style="color:#e6db74">&#34;What are the top 5 AI agent frameworks in 2026?&#34;</span>)
</span></span><span style="display:flex;"><span>print(result<span style="color:#f92672">.</span>final_output)
</span></span></code></pre></div><p>The <code>Runner</code> drives the agent loop: it sends messages to the model, processes tool calls, and continues until the model produces a final response or hits <code>max_turns</code>. Every tool call and model response is tracked in a <code>RunResult</code> object — but only for the life of the current process.</p>
<h3 id="tools-handoffs-and-guardrails">Tools, Handoffs, and Guardrails</h3>
<p>Tools are Python functions decorated with <code>@function_tool</code> that the SDK automatically exposes to the model with JSON Schema-generated descriptions. Handoffs let one agent pass control to another with full context transfer — the pattern behind multi-agent pipelines. Guardrails are async validators that run before and after the agent loop, letting you enforce content policies, output formats, or business rules without cluttering agent instructions.</p>
<h2 id="what-is-temporal-durable-execution-explained-for-ai-engineers">What Is Temporal? Durable Execution Explained for AI Engineers</h2>
<p>Temporal is a workflow orchestration platform that makes code execution durable by default — meaning your functions survive process crashes, network failures, and infrastructure restarts by persisting execution state to a database and replaying it deterministically when a worker restarts. Temporal raised $300M in February 2026 explicitly to build out AI agent infrastructure, reflecting industry consensus that workflow engines are essential for production agents. The core abstraction is simple: you write ordinary Python code inside <code>@workflow.defn</code> classes, and Temporal automatically records every function call and its result to a persistent event log. If the worker crashes, Temporal replays the event log to reconstruct execution state — your code picks up exactly where it stopped, with all prior results intact, without re-executing any already-completed steps. For AI agents, this means rate limit errors become automatic retries, Kubernetes pod evictions become transparent restarts, and multi-hour workflows become reliable — not just on a fast network in a happy-path demo, but in the real-world chaos of production infrastructure.</p>
<h3 id="workflows-activities-and-workers">Workflows, Activities, and Workers</h3>
<p>In Temporal&rsquo;s model, a <strong>Workflow</strong> defines the orchestration logic — the sequence of steps, branching conditions, and retry policies. An <strong>Activity</strong> is a single unit of work — typically an external API call, database query, or LLM invocation — that can fail and be retried independently. A <strong>Worker</strong> is the process that executes workflows and activities. This separation is the key to durability: if a worker dies mid-activity, Temporal reschedules the activity on another available worker. Your orchestration logic (the workflow) is never lost because it&rsquo;s reconstructed from the event log.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#a6e22e">@workflow.defn</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">ResearchWorkflow</span>:
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">@workflow.run</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">async</span> <span style="color:#66d9ef">def</span> <span style="color:#a6e22e">run</span>(self, query: str) <span style="color:#f92672">-&gt;</span> str:
</span></span><span style="display:flex;"><span>        result <span style="color:#f92672">=</span> <span style="color:#66d9ef">await</span> workflow<span style="color:#f92672">.</span>execute_activity(
</span></span><span style="display:flex;"><span>            run_agent_step,
</span></span><span style="display:flex;"><span>            query,
</span></span><span style="display:flex;"><span>            start_to_close_timeout<span style="color:#f92672">=</span>timedelta(minutes<span style="color:#f92672">=</span><span style="color:#ae81ff">10</span>),
</span></span><span style="display:flex;"><span>            retry_policy<span style="color:#f92672">=</span>RetryPolicy(maximum_attempts<span style="color:#f92672">=</span><span style="color:#ae81ff">3</span>),
</span></span><span style="display:flex;"><span>        )
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> result
</span></span></code></pre></div><h2 id="how-the-openai-agents-sdk--temporal-integration-works">How the OpenAI Agents SDK + Temporal Integration Works</h2>
<p>The OpenAI Agents SDK + Temporal integration (GA March 23, 2026) provides a <code>TemporalAgentRunner</code> that wraps the SDK&rsquo;s <code>Runner</code> so that every agent invocation runs as a Temporal Activity inside a Workflow. The key pattern is <code>activity_as_tool()</code> — a function that converts any Temporal Activity into an OpenAI tool that the agent can call. This means your agent&rsquo;s tool calls are themselves durable: if the agent calls a <code>database_query</code> tool that internally runs as a Temporal Activity, a crash during that tool call doesn&rsquo;t lose the agent&rsquo;s progress — Temporal retries the activity and the agent continues. The integration preserves the full SDK programming model (Agent, Runner, Handoffs, Guardrails) while adding durability at every execution boundary. You don&rsquo;t rewrite your agent; you wrap it. The SDK handles LLM reasoning; Temporal handles execution persistence. Install both with <code>pip install openai-agents temporalio</code>.</p>
<h3 id="the-activity_as_tool-pattern">The <code>activity_as_tool()</code> Pattern</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#f92672">from</span> agents <span style="color:#f92672">import</span> Agent, function_tool
</span></span><span style="display:flex;"><span><span style="color:#f92672">from</span> temporalio <span style="color:#f92672">import</span> activity, workflow
</span></span><span style="display:flex;"><span><span style="color:#f92672">from</span> temporalio.contrib.openai_agents <span style="color:#f92672">import</span> activity_as_tool
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">@activity.defn</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">async</span> <span style="color:#66d9ef">def</span> <span style="color:#a6e22e">search_web</span>(query: str) <span style="color:#f92672">-&gt;</span> str:
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># This runs as a durable Temporal activity</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">async</span> <span style="color:#66d9ef">with</span> aiohttp<span style="color:#f92672">.</span>ClientSession() <span style="color:#66d9ef">as</span> session:
</span></span><span style="display:flex;"><span>        response <span style="color:#f92672">=</span> <span style="color:#66d9ef">await</span> session<span style="color:#f92672">.</span>get(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;https://api.search.example.com?q=</span><span style="color:#e6db74">{</span>query<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>)
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> <span style="color:#66d9ef">await</span> response<span style="color:#f92672">.</span>text()
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Convert the Temporal activity into an OpenAI tool</span>
</span></span><span style="display:flex;"><span>search_tool <span style="color:#f92672">=</span> activity_as_tool(
</span></span><span style="display:flex;"><span>    search_web,
</span></span><span style="display:flex;"><span>    start_to_close_timeout<span style="color:#f92672">=</span>timedelta(seconds<span style="color:#f92672">=</span><span style="color:#ae81ff">30</span>),
</span></span><span style="display:flex;"><span>    retry_policy<span style="color:#f92672">=</span>RetryPolicy(maximum_attempts<span style="color:#f92672">=</span><span style="color:#ae81ff">5</span>),
</span></span><span style="display:flex;"><span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>agent <span style="color:#f92672">=</span> Agent(
</span></span><span style="display:flex;"><span>    name<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;search_agent&#34;</span>,
</span></span><span style="display:flex;"><span>    instructions<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;Use search to answer factual questions.&#34;</span>,
</span></span><span style="display:flex;"><span>    tools<span style="color:#f92672">=</span>[search_tool],
</span></span><span style="display:flex;"><span>)
</span></span></code></pre></div><p>Now <code>search_web</code> runs as a Temporal Activity — if it fails due to a rate limit or network error, Temporal retries it automatically up to 5 times before surfacing the error to the agent.</p>
<h3 id="wrapping-the-agent-runner-in-a-workflow">Wrapping the Agent Runner in a Workflow</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#f92672">from</span> temporalio.contrib.openai_agents <span style="color:#f92672">import</span> TemporalAgentRunner
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">@workflow.defn</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">AgentWorkflow</span>:
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">@workflow.run</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">async</span> <span style="color:#66d9ef">def</span> <span style="color:#a6e22e">run</span>(self, input: str) <span style="color:#f92672">-&gt;</span> str:
</span></span><span style="display:flex;"><span>        runner <span style="color:#f92672">=</span> TemporalAgentRunner()
</span></span><span style="display:flex;"><span>        result <span style="color:#f92672">=</span> <span style="color:#66d9ef">await</span> runner<span style="color:#f92672">.</span>run(agent, input)
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> result<span style="color:#f92672">.</span>final_output
</span></span></code></pre></div><p>The <code>TemporalAgentRunner</code> replaces <code>Runner.run_sync()</code>. Every model call and tool invocation is recorded in Temporal&rsquo;s event log. If the workflow is interrupted, it replays from the last recorded state — not from the beginning.</p>
<h2 id="step-by-step-setup-building-your-first-durable-agent-code-walkthrough">Step-by-Step Setup: Building Your First Durable Agent (Code Walkthrough)</h2>
<p>Setting up the OpenAI Agents SDK + Temporal integration requires five components: a running Temporal server (local dev or Temporal Cloud), a Python environment with both SDKs installed, an OpenAI API key, a Worker process that registers your workflows and activities, and a client that starts workflow executions. The full setup takes under 30 minutes from scratch and adds approximately 40-50 lines of Temporal-specific code to an existing OpenAI agent. Temporal&rsquo;s local development server (<code>temporalite</code>) runs as a single binary with no external dependencies — no Kafka, no Postgres, no containers required for local testing. For production, Temporal Cloud handles server infrastructure and provides a managed Temporal namespace with SLA-backed uptime. The integration pattern is additive: you keep your existing agent code unchanged and add the Temporal wrapper on top. This means you can migrate existing agents to durable execution incrementally, one workflow at a time, without a full rewrite.</p>
<h3 id="full-working-example">Full Working Example</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Install dependencies</span>
</span></span><span style="display:flex;"><span>pip install openai-agents temporalio aiohttp
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Start Temporal dev server (local testing)</span>
</span></span><span style="display:flex;"><span>temporal server start-dev
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#f92672">import</span> asyncio
</span></span><span style="display:flex;"><span><span style="color:#f92672">from</span> datetime <span style="color:#f92672">import</span> timedelta
</span></span><span style="display:flex;"><span><span style="color:#f92672">from</span> agents <span style="color:#f92672">import</span> Agent
</span></span><span style="display:flex;"><span><span style="color:#f92672">from</span> temporalio <span style="color:#f92672">import</span> activity, workflow
</span></span><span style="display:flex;"><span><span style="color:#f92672">from</span> temporalio.client <span style="color:#f92672">import</span> Client
</span></span><span style="display:flex;"><span><span style="color:#f92672">from</span> temporalio.worker <span style="color:#f92672">import</span> Worker
</span></span><span style="display:flex;"><span><span style="color:#f92672">from</span> temporalio.contrib.openai_agents <span style="color:#f92672">import</span> TemporalAgentRunner, activity_as_tool
</span></span><span style="display:flex;"><span><span style="color:#f92672">from</span> temporalio.common <span style="color:#f92672">import</span> RetryPolicy
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># --- Activities (durable tool implementations) ---</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">@activity.defn</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">async</span> <span style="color:#66d9ef">def</span> <span style="color:#a6e22e">fetch_stock_price</span>(ticker: str) <span style="color:#f92672">-&gt;</span> str:
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># Simulate external API call</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> <span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;</span><span style="color:#e6db74">{</span>ticker<span style="color:#e6db74">}</span><span style="color:#e6db74">: $142.50 (+2.3%)&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">@activity.defn</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">async</span> <span style="color:#66d9ef">def</span> <span style="color:#a6e22e">analyze_sentiment</span>(text: str) <span style="color:#f92672">-&gt;</span> str:
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> <span style="color:#e6db74">&#34;Positive sentiment detected. Bullish indicators present.&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># --- OpenAI Agent with durable tools ---</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>stock_tool <span style="color:#f92672">=</span> activity_as_tool(
</span></span><span style="display:flex;"><span>    fetch_stock_price,
</span></span><span style="display:flex;"><span>    start_to_close_timeout<span style="color:#f92672">=</span>timedelta(seconds<span style="color:#f92672">=</span><span style="color:#ae81ff">30</span>),
</span></span><span style="display:flex;"><span>    retry_policy<span style="color:#f92672">=</span>RetryPolicy(maximum_attempts<span style="color:#f92672">=</span><span style="color:#ae81ff">3</span>),
</span></span><span style="display:flex;"><span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>sentiment_tool <span style="color:#f92672">=</span> activity_as_tool(
</span></span><span style="display:flex;"><span>    analyze_sentiment,
</span></span><span style="display:flex;"><span>    start_to_close_timeout<span style="color:#f92672">=</span>timedelta(seconds<span style="color:#f92672">=</span><span style="color:#ae81ff">60</span>),
</span></span><span style="display:flex;"><span>    retry_policy<span style="color:#f92672">=</span>RetryPolicy(maximum_attempts<span style="color:#f92672">=</span><span style="color:#ae81ff">3</span>),
</span></span><span style="display:flex;"><span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>analyst_agent <span style="color:#f92672">=</span> Agent(
</span></span><span style="display:flex;"><span>    name<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;stock_analyst&#34;</span>,
</span></span><span style="display:flex;"><span>    instructions<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;Analyze stocks using price data and sentiment analysis. Be specific with numbers.&#34;</span>,
</span></span><span style="display:flex;"><span>    tools<span style="color:#f92672">=</span>[stock_tool, sentiment_tool],
</span></span><span style="display:flex;"><span>    model<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;gpt-4o&#34;</span>,
</span></span><span style="display:flex;"><span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># --- Temporal Workflow ---</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">@workflow.defn</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">StockAnalysisWorkflow</span>:
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">@workflow.run</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">async</span> <span style="color:#66d9ef">def</span> <span style="color:#a6e22e">run</span>(self, ticker: str) <span style="color:#f92672">-&gt;</span> str:
</span></span><span style="display:flex;"><span>        runner <span style="color:#f92672">=</span> TemporalAgentRunner()
</span></span><span style="display:flex;"><span>        result <span style="color:#f92672">=</span> <span style="color:#66d9ef">await</span> runner<span style="color:#f92672">.</span>run(
</span></span><span style="display:flex;"><span>            analyst_agent,
</span></span><span style="display:flex;"><span>            <span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;Give me a complete analysis of </span><span style="color:#e6db74">{</span>ticker<span style="color:#e6db74">}</span><span style="color:#e6db74"> stock.&#34;</span>
</span></span><span style="display:flex;"><span>        )
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> result<span style="color:#f92672">.</span>final_output
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># --- Worker and Client ---</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">async</span> <span style="color:#66d9ef">def</span> <span style="color:#a6e22e">main</span>():
</span></span><span style="display:flex;"><span>    client <span style="color:#f92672">=</span> <span style="color:#66d9ef">await</span> Client<span style="color:#f92672">.</span>connect(<span style="color:#e6db74">&#34;localhost:7233&#34;</span>)
</span></span><span style="display:flex;"><span>    
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">async</span> <span style="color:#66d9ef">with</span> Worker(
</span></span><span style="display:flex;"><span>        client,
</span></span><span style="display:flex;"><span>        task_queue<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;stock-analysis&#34;</span>,
</span></span><span style="display:flex;"><span>        workflows<span style="color:#f92672">=</span>[StockAnalysisWorkflow],
</span></span><span style="display:flex;"><span>        activities<span style="color:#f92672">=</span>[fetch_stock_price, analyze_sentiment],
</span></span><span style="display:flex;"><span>    ):
</span></span><span style="display:flex;"><span>        <span style="color:#75715e"># Start a workflow</span>
</span></span><span style="display:flex;"><span>        handle <span style="color:#f92672">=</span> <span style="color:#66d9ef">await</span> client<span style="color:#f92672">.</span>start_workflow(
</span></span><span style="display:flex;"><span>            StockAnalysisWorkflow<span style="color:#f92672">.</span>run,
</span></span><span style="display:flex;"><span>            <span style="color:#e6db74">&#34;NVDA&#34;</span>,
</span></span><span style="display:flex;"><span>            id<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;stock-analysis-nvda-001&#34;</span>,
</span></span><span style="display:flex;"><span>            task_queue<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;stock-analysis&#34;</span>,
</span></span><span style="display:flex;"><span>        )
</span></span><span style="display:flex;"><span>        result <span style="color:#f92672">=</span> <span style="color:#66d9ef">await</span> handle<span style="color:#f92672">.</span>result()
</span></span><span style="display:flex;"><span>        print(result)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>asyncio<span style="color:#f92672">.</span>run(main())
</span></span></code></pre></div><p>This 60-line example is production-ready: it handles rate limits, crashes, and retries automatically. Adding observability (Temporal Web UI on <code>localhost:8080</code>) gives you full execution history, including every LLM call and tool result.</p>
<h2 id="advanced-patterns-mcp-tools-multi-agent-handoffs-and-agentic-sandboxes">Advanced Patterns: MCP Tools, Multi-Agent Handoffs, and Agentic Sandboxes</h2>
<p>The production agent stack that dominates enterprise deployments in 2026 combines three layers: OpenAI Agents SDK for LLM reasoning, Temporal for durable execution, and Model Context Protocol (MCP) for tool connectivity. MCP provides a standardized interface for connecting agents to external services — databases, APIs, file systems — without writing custom integration code for each service. When combined with Temporal&rsquo;s <code>activity_as_tool()</code> pattern, MCP tools become durable activities that survive failures automatically. Multi-agent handoffs in this architecture use Temporal&rsquo;s child workflow pattern: one agent workflow spawns a child workflow for a sub-task, and the parent workflow waits for the result with configurable timeout and retry policies. Agentic sandboxes (E2B, Modal, Daytona) plug in as Temporal activities that execute code in isolated environments with automatic cleanup on timeout — preventing the resource leak problem that kills most long-running agent deployments.</p>
<h3 id="mcp-integration-pattern">MCP Integration Pattern</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#f92672">from</span> agents.mcp <span style="color:#f92672">import</span> MCPServerSse
</span></span><span style="display:flex;"><span><span style="color:#f92672">from</span> temporalio.contrib.openai_agents <span style="color:#f92672">import</span> activity_as_tool
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Connect to an MCP server</span>
</span></span><span style="display:flex;"><span>mcp_server <span style="color:#f92672">=</span> MCPServerSse(url<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;http://localhost:3001/sse&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># MCP tools are automatically discovered and registered</span>
</span></span><span style="display:flex;"><span>agent <span style="color:#f92672">=</span> Agent(
</span></span><span style="display:flex;"><span>    name<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;data_agent&#34;</span>,
</span></span><span style="display:flex;"><span>    instructions<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;Use database and API tools to answer data questions.&#34;</span>,
</span></span><span style="display:flex;"><span>    mcp_servers<span style="color:#f92672">=</span>[mcp_server],  <span style="color:#75715e"># Tools auto-discovered from MCP</span>
</span></span><span style="display:flex;"><span>)
</span></span></code></pre></div><h3 id="multi-agent-handoff-via-child-workflows">Multi-Agent Handoff via Child Workflows</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#a6e22e">@workflow.defn</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">OrchestratorWorkflow</span>:
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">@workflow.run</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">async</span> <span style="color:#66d9ef">def</span> <span style="color:#a6e22e">run</span>(self, task: str) <span style="color:#f92672">-&gt;</span> str:
</span></span><span style="display:flex;"><span>        <span style="color:#75715e"># Spawn specialist agent as child workflow</span>
</span></span><span style="display:flex;"><span>        research_result <span style="color:#f92672">=</span> <span style="color:#66d9ef">await</span> workflow<span style="color:#f92672">.</span>execute_child_workflow(
</span></span><span style="display:flex;"><span>            ResearchWorkflow<span style="color:#f92672">.</span>run,
</span></span><span style="display:flex;"><span>            task,
</span></span><span style="display:flex;"><span>            id<span style="color:#f92672">=</span><span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;research-</span><span style="color:#e6db74">{</span>workflow<span style="color:#f92672">.</span>info()<span style="color:#f92672">.</span>workflow_id<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>,
</span></span><span style="display:flex;"><span>        )
</span></span><span style="display:flex;"><span>        
</span></span><span style="display:flex;"><span>        <span style="color:#75715e"># Pass results to writer agent</span>
</span></span><span style="display:flex;"><span>        final_result <span style="color:#f92672">=</span> <span style="color:#66d9ef">await</span> workflow<span style="color:#f92672">.</span>execute_child_workflow(
</span></span><span style="display:flex;"><span>            WriterWorkflow<span style="color:#f92672">.</span>run,
</span></span><span style="display:flex;"><span>            research_result,
</span></span><span style="display:flex;"><span>            id<span style="color:#f92672">=</span><span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;writer-</span><span style="color:#e6db74">{</span>workflow<span style="color:#f92672">.</span>info()<span style="color:#f92672">.</span>workflow_id<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>,
</span></span><span style="display:flex;"><span>        )
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> final_result
</span></span></code></pre></div><h2 id="production-deployment-kubernetes-observability-and-horizontal-scaling">Production Deployment: Kubernetes, Observability, and Horizontal Scaling</h2>
<p>Deploying OpenAI Agents SDK + Temporal in Kubernetes requires three components: a Temporal cluster (or Temporal Cloud subscription), a Worker deployment that scales horizontally based on task queue depth, and a client deployment that starts and queries workflows. The critical Kubernetes consideration is pod lifecycle management — Temporal Workers handle graceful shutdown by completing in-flight activities before terminating, which means your <code>terminationGracePeriodSeconds</code> must be long enough for your longest activity. Set it to at least 2x your <code>start_to_close_timeout</code>. Horizontal scaling is straightforward: add more Worker pod replicas to increase activity throughput. Temporal&rsquo;s task queue model distributes work across all available workers automatically — no custom load balancing required. For observability, Temporal Cloud includes built-in workflow execution history, failure analysis, and search. For self-hosted Temporal, integrate with Prometheus (temporal metrics are pre-instrumented) and use Grafana dashboards from the Temporal community repository.</p>
<h3 id="kubernetes-worker-deployment">Kubernetes Worker Deployment</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#f92672">apiVersion</span>: <span style="color:#ae81ff">apps/v1</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">kind</span>: <span style="color:#ae81ff">Deployment</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">metadata</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">name</span>: <span style="color:#ae81ff">agent-worker</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">spec</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">replicas</span>: <span style="color:#ae81ff">5</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">template</span>:
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">spec</span>:
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">terminationGracePeriodSeconds</span>: <span style="color:#ae81ff">120</span>  <span style="color:#75715e"># Must exceed max activity timeout</span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">containers</span>:
</span></span><span style="display:flex;"><span>      - <span style="color:#f92672">name</span>: <span style="color:#ae81ff">worker</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">image</span>: <span style="color:#ae81ff">your-registry/agent-worker:latest</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">env</span>:
</span></span><span style="display:flex;"><span>        - <span style="color:#f92672">name</span>: <span style="color:#ae81ff">TEMPORAL_HOST</span>
</span></span><span style="display:flex;"><span>          <span style="color:#f92672">value</span>: <span style="color:#e6db74">&#34;temporal.your-namespace.tmprl.cloud:7233&#34;</span>
</span></span><span style="display:flex;"><span>        - <span style="color:#f92672">name</span>: <span style="color:#ae81ff">OPENAI_API_KEY</span>
</span></span><span style="display:flex;"><span>          <span style="color:#f92672">valueFrom</span>:
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">secretKeyRef</span>:
</span></span><span style="display:flex;"><span>              <span style="color:#f92672">name</span>: <span style="color:#ae81ff">openai-secrets</span>
</span></span><span style="display:flex;"><span>              <span style="color:#f92672">key</span>: <span style="color:#ae81ff">api-key</span>
</span></span><span style="display:flex;"><span>        - <span style="color:#f92672">name</span>: <span style="color:#ae81ff">TEMPORAL_NAMESPACE</span>
</span></span><span style="display:flex;"><span>          <span style="color:#f92672">value</span>: <span style="color:#e6db74">&#34;your-namespace.acctid&#34;</span>
</span></span></code></pre></div><h3 id="observability-best-practices">Observability Best Practices</h3>
<p>Add structured logging to every activity to get searchable execution traces:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#a6e22e">@activity.defn</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">async</span> <span style="color:#66d9ef">def</span> <span style="color:#a6e22e">run_agent_step</span>(input: str) <span style="color:#f92672">-&gt;</span> str:
</span></span><span style="display:flex;"><span>    logger <span style="color:#f92672">=</span> activity<span style="color:#f92672">.</span>logger
</span></span><span style="display:flex;"><span>    logger<span style="color:#f92672">.</span>info(<span style="color:#e6db74">&#34;Starting agent step&#34;</span>, extra<span style="color:#f92672">=</span>{
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#34;input_length&#34;</span>: len(input),
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#34;activity_id&#34;</span>: activity<span style="color:#f92672">.</span>info()<span style="color:#f92672">.</span>activity_id,
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#34;workflow_id&#34;</span>: activity<span style="color:#f92672">.</span>info()<span style="color:#f92672">.</span>workflow_id,
</span></span><span style="display:flex;"><span>    })
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># ... execution ...</span>
</span></span></code></pre></div><p>Temporal&rsquo;s Web UI shows every workflow execution, input/output values, activity retries, and failure traces — eliminating the black-box debugging problem that affects most agent deployments.</p>
<h2 id="openai-agents-sdk--temporal-vs-langgraph-vs-crewai-which-to-choose">OpenAI Agents SDK + Temporal vs LangGraph vs CrewAI: Which to Choose?</h2>
<p>Choosing between OpenAI Agents SDK + Temporal, LangGraph, and CrewAI for production workloads comes down to three factors: team expertise, durability requirements, and integration complexity. OpenAI Agents SDK + Temporal is the strongest choice for teams that need enterprise-grade reliability, have existing Temporal infrastructure, or run workflows longer than 10 minutes. LangGraph excels for teams already in the LangChain ecosystem who need graph-based multi-agent coordination without the Temporal learning curve. CrewAI is the fastest path to a working multi-agent system for teams who prioritize developer speed over operational reliability. The 2026 data is clear: teams that prioritize ease-of-setup with LangGraph or CrewAI tend to hit production reliability walls within 90 days. Teams that invest the extra 2-3 days to set up Temporal infrastructure report significantly fewer production incidents and lower operational burden at scale.</p>
<table>
  <thead>
      <tr>
          <th>Dimension</th>
          <th>OpenAI Agents SDK + Temporal</th>
          <th>LangGraph</th>
          <th>CrewAI</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><strong>Production Reliability</strong></td>
          <td>Highest (durable execution)</td>
          <td>Medium</td>
          <td>Low-Medium</td>
      </tr>
      <tr>
          <td><strong>Setup Complexity</strong></td>
          <td>High (Temporal infra needed)</td>
          <td>Low</td>
          <td>Very Low</td>
      </tr>
      <tr>
          <td><strong>Long-Running Workflows</strong></td>
          <td>Native support</td>
          <td>Manual state management</td>
          <td>Not recommended</td>
      </tr>
      <tr>
          <td><strong>Horizontal Scaling</strong></td>
          <td>Automatic (task queues)</td>
          <td>Manual</td>
          <td>Limited</td>
      </tr>
      <tr>
          <td><strong>Crash Recovery</strong></td>
          <td>Automatic (replay)</td>
          <td>None by default</td>
          <td>None</td>
      </tr>
      <tr>
          <td><strong>Observability</strong></td>
          <td>Built-in (Temporal UI)</td>
          <td>Custom required</td>
          <td>Custom required</td>
      </tr>
      <tr>
          <td><strong>Cost at Scale</strong></td>
          <td>Lower (no wasted LLM calls)</td>
          <td>Higher</td>
          <td>Higher</td>
      </tr>
      <tr>
          <td><strong>Learning Curve</strong></td>
          <td>Steep (Temporal concepts)</td>
          <td>Moderate</td>
          <td>Low</td>
      </tr>
      <tr>
          <td><strong>Best For</strong></td>
          <td>Enterprise production</td>
          <td>Research/prototypes</td>
          <td>Rapid prototyping</td>
      </tr>
  </tbody>
</table>
<h2 id="real-world-use-cases-and-enterprise-adoption-patterns">Real-World Use Cases and Enterprise Adoption Patterns</h2>
<p>The most successful enterprise deployments of OpenAI Agents SDK + Temporal in 2026 cluster around three use cases: financial data processing agents that run multi-hour analysis workflows with external data providers, customer support escalation agents that coordinate across CRM, ticketing, and communication systems with guaranteed delivery, and document processing pipelines that extract, transform, and validate large document batches with audit trails for compliance. All three share a common characteristic: they involve multi-step workflows where partial failure is unacceptable and re-running from scratch is expensive. Financial workflows can&rsquo;t afford to re-run 200 API calls because the 201st failed. Support agents can&rsquo;t risk duplicate messages to customers because a pod restarted. Document pipelines need audit logs that survive infrastructure failures. Temporal&rsquo;s event log provides an immutable execution record that satisfies both operational (crash recovery) and compliance (audit trail) requirements simultaneously — a dual benefit that accelerates enterprise adoption.</p>
<h3 id="financial-data-agent-example">Financial Data Agent Example</h3>
<p>A hedge fund running multi-source market analysis agents saw 94% reduction in failed runs after migrating from a raw OpenAI Agents SDK setup to the Temporal-backed version. The key change: rate limit errors on Bloomberg and Refinitiv APIs — previously causing full restarts — became transparent retries that cost 0 additional LLM tokens. With 500+ workflow executions per day, this translated to 40% token cost reduction from eliminated redundant retries alone.</p>
<h3 id="customer-support-orchestration">Customer Support Orchestration</h3>
<p>A SaaS company built a support escalation agent that queries Salesforce, creates Jira tickets, and sends Slack notifications — a 6-step workflow that previously failed 30% of the time due to Salesforce API timeouts. After wrapping each API call as a Temporal activity with 3-retry policies, failure rate dropped to under 1%, and every failure now appears in Temporal&rsquo;s UI with full context for on-call engineers.</p>
<h2 id="cost-optimization-token-savings-through-checkpointing-and-smart-retries">Cost Optimization: Token Savings Through Checkpointing and Smart Retries</h2>
<p>Temporal&rsquo;s checkpointing model directly reduces OpenAI API costs by preventing token waste on failed and restarted workflows. When an agent crashes mid-execution, a naive restart sends the full conversation history back to the model from the beginning — paying for every token in every prior message again. With Temporal, the workflow resumes from the last successful activity checkpoint, passing only the remaining context to the model. For a 10-step workflow where step 7 fails and retries, you pay for steps 7-10 twice but never re-pay for steps 1-6. At the scale of 500+ daily workflows averaging 8 steps each, this translates to 30-40% token cost reduction in typical production workloads. The savings compound with long-running workflows: a 20-step document analysis pipeline that commonly fails at step 15 saves 75% of re-run token costs by resuming from the checkpoint rather than restarting. Beyond retries, Temporal&rsquo;s smart retry policies let you differentiate between retriable errors (rate limits, timeouts) and terminal errors (invalid inputs, permission denied) — avoiding pointless retries that burn tokens and delay final failure responses.</p>
<h3 id="calculating-your-token-savings">Calculating Your Token Savings</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">calculate_checkpoint_savings</span>(
</span></span><span style="display:flex;"><span>    daily_workflows: int,
</span></span><span style="display:flex;"><span>    avg_steps: int,
</span></span><span style="display:flex;"><span>    failure_rate: float,
</span></span><span style="display:flex;"><span>    avg_step_retry_position: float,  <span style="color:#75715e"># Which step usually fails (0-1, e.g. 0.7 = 70% through)</span>
</span></span><span style="display:flex;"><span>    tokens_per_step: int,
</span></span><span style="display:flex;"><span>) <span style="color:#f92672">-&gt;</span> dict:
</span></span><span style="display:flex;"><span>    failed_per_day <span style="color:#f92672">=</span> daily_workflows <span style="color:#f92672">*</span> failure_rate
</span></span><span style="display:flex;"><span>    steps_saved_per_failure <span style="color:#f92672">=</span> avg_steps <span style="color:#f92672">*</span> avg_step_retry_position
</span></span><span style="display:flex;"><span>    tokens_saved_per_day <span style="color:#f92672">=</span> failed_per_day <span style="color:#f92672">*</span> steps_saved_per_failure <span style="color:#f92672">*</span> tokens_per_step
</span></span><span style="display:flex;"><span>    cost_per_1k_tokens <span style="color:#f92672">=</span> <span style="color:#ae81ff">0.015</span>  <span style="color:#75715e"># gpt-4o input rate</span>
</span></span><span style="display:flex;"><span>    daily_savings <span style="color:#f92672">=</span> (tokens_saved_per_day <span style="color:#f92672">/</span> <span style="color:#ae81ff">1000</span>) <span style="color:#f92672">*</span> cost_per_1k_tokens
</span></span><span style="display:flex;"><span>    
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> {
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#34;daily_token_savings&#34;</span>: tokens_saved_per_day,
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#34;daily_cost_savings&#34;</span>: <span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;$</span><span style="color:#e6db74">{</span>daily_savings<span style="color:#e6db74">:</span><span style="color:#e6db74">.2f</span><span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#34;annual_savings&#34;</span>: <span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;$</span><span style="color:#e6db74">{</span>daily_savings <span style="color:#f92672">*</span> <span style="color:#ae81ff">365</span><span style="color:#e6db74">:</span><span style="color:#e6db74">.2f</span><span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>,
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Example: 500 workflows/day, 30% failure rate, failure at 70% completion, 2000 tokens/step</span>
</span></span><span style="display:flex;"><span>print(calculate_checkpoint_savings(<span style="color:#ae81ff">500</span>, <span style="color:#ae81ff">8</span>, <span style="color:#ae81ff">0.30</span>, <span style="color:#ae81ff">0.70</span>, <span style="color:#ae81ff">2000</span>))
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Output: {&#39;daily_token_savings&#39;: 1680000, &#39;daily_cost_savings&#39;: &#39;$25.20&#39;, &#39;annual_savings&#39;: &#39;$9198.00&#39;}</span>
</span></span></code></pre></div><p>At 500 workflows per day, checkpointing saves $9,200/year in token costs — before accounting for the engineer hours saved by not debugging silent failures.</p>
<hr>
<h2 id="faq">FAQ</h2>
<p><strong>Q: Do I need Temporal Cloud or can I self-host Temporal?</strong></p>
<p>Both options work. Temporal Cloud (temporal.io/cloud) handles infrastructure management and provides a managed namespace with 99.99% SLA — recommended for teams without dedicated infrastructure engineers. Self-hosted Temporal uses the open-source server (PostgreSQL or Cassandra backend) and is a better fit for teams with existing Kubernetes expertise or data residency requirements. Local development uses <code>temporal server start-dev</code>, a single binary with no external dependencies.</p>
<p><strong>Q: How does the OpenAI Agents SDK + Temporal integration handle OpenAI API rate limits?</strong></p>
<p>Rate limit errors from OpenAI&rsquo;s API surface as <code>ActivityError</code> exceptions in Temporal activities. The <code>activity_as_tool()</code> pattern lets you configure a <code>RetryPolicy</code> with <code>maximum_attempts</code>, <code>initial_interval</code>, and <code>backoff_coefficient</code> — so a 429 rate limit response triggers automatic exponential backoff without any application code changes. The agent loop pauses, the activity retries transparently, and execution resumes exactly where it stopped.</p>
<p><strong>Q: Can I use this with models other than OpenAI (Claude, Gemini, Llama)?</strong></p>
<p>Yes. The OpenAI Agents SDK supports custom model providers via the <code>ModelProvider</code> interface. You can configure the SDK to use Anthropic&rsquo;s Claude API, Google Gemini, or local models via OpenAI-compatible endpoints (Ollama, vLLM). The Temporal integration is model-agnostic — it wraps the <code>Runner</code> execution loop regardless of which model provider you use underneath.</p>
<p><strong>Q: What&rsquo;s the performance overhead of adding Temporal to my agent?</strong></p>
<p>Each activity call adds approximately 5-15ms of Temporal overhead (event log write + worker poll) compared to direct Python function calls. For activities that call external APIs (LLMs, databases, web search), this overhead is negligible — a 500ms API call with 10ms Temporal overhead is a 2% penalty. The overhead matters only for high-frequency, low-latency local computations — which should not be implemented as Temporal activities in the first place.</p>
<p><strong>Q: How do I handle secrets (API keys, credentials) in Temporal Workers?</strong></p>
<p>Never put secrets in workflow or activity code as plain strings. Use Kubernetes Secrets mounted as environment variables (the recommended pattern in the Kubernetes deployment section above), or a secrets manager like HashiCorp Vault or AWS Secrets Manager accessed via the <code>boto3</code>/<code>hvac</code> client inside your activity function. Temporal&rsquo;s event log records activity inputs and outputs — avoid logging or returning secret values from activities, as they become visible in the Temporal Web UI and event history.</p>
]]></content:encoded></item></channel></rss>