Chapter 22

OpenAI Agents SDK: When a Ready Harness Pays Off

The Agents SDK adds a small set of primitives for agents, tools, sessions, handoffs, guardrails, tracing, and human in the loop. It saves loop code but doesn't cancel the main thing: business rules still live in your handlers, not in the SDK.

Bash
npm install @openai/agents zod

An agent is assembled from tools and an instruction, and run spins the loop for you.

TypeScript
import { Agent, run, tool } from "@openai/agents";
import { z } from "zod";

export function makeSupportAgent(context: TrustedToolContext) {
  const orderTool = tool({
    name: "order_read",
    description: "Read a verified public view of the current user's order.",
    parameters: z.object({ order_id: z.string() }),
    async execute(input) {
      return JSON.stringify(await orderRead(input, context));
    }
  });

  return new Agent({
    name: "Commerce Support",
    instructions: buildPrompt(context.locale),
    tools: [orderTool]
  });
}

const result = await run(makeSupportAgent(context), userMessage, {
  maxTurns: 6,
  context
});

console.log(result.finalOutput);

When a ready harness really pays off is visible from the needs.

Need · SDK capability

  • A long multi-turn - Sessions and provider-backed conversation sessions
  • Handing off to a specialist - Handoffs or agent as tool
  • Action confirmation - Human in the loop with pause and resume state
  • Diagnostics - Tracing on by default in server runtimes
  • Checking input and result - Guardrails and output schemas

A long multi-turn is covered by sessions, handing off to a specialist by handoffs, action confirmation by human in the loop with pause and resume, diagnostics by tracing on by default. And the multi-agent fork, which you should decide by result ownership, not by fashion.

Manager or handoff. Agent-as-tool keeps control with the manager and suits a shared final wording well. A handoff passes the active conversation to a specialist. Choose by result ownership, not by the multi-agent fashion.

OpenAI is covered. Anthropic is built differently - its Messages API is stateless, and that changes the adapter.

Links