For a complex, multi-turn customer-service agent, I’d start with LangGraph if you expect the system to become stateful, tool-heavy, and operationally complex. It is specifically designed for long-running, stateful agents, with persistence, durable execution, human-in-the-loop workflows, and explicit control over agent state.
That said, OpenAI Agents SDK is an excellent alternative if you want a simpler architecture and are primarily using OpenAI models. It provides agents, tools, sessions, handoffs, guardrails, human-in-the-loop mechanisms, and tracing without requiring you to build as much orchestration infrastructure yourself.
How I'd choose
| If your priority is… | Consider |
|---|
| Complex workflows and explicit state machines | LangGraph |
| Long-running conversations with resumability | LangGraph |
| Human approval at specific workflow points | LangGraph |
| Multiple specialized support agents | Either |
| Simple, clean OpenAI-native implementation | OpenAI Agents SDK |
| Minimal orchestration code | OpenAI Agents SDK |
| Maximum control over model/provider infrastructure | LangGraph |
For customer service specifically, I'd structure the system roughly like this:
┌──────────────────┐
│ Customer message │
└────────┬─────────┘
↓
┌──────────────────┐
│ Triage / Router │
└────────┬─────────┘
↓
┌────────────────────┼────────────────────┐
↓ ↓ ↓
Order Agent Billing Agent Support Agent
│ │ │
└────────────────────┼────────────────────┘
↓
┌──────────────────┐
│ Tool execution │
│ CRM / orders / │
│ payments / KB │
└────────┬─────────┘
↓
┌──────────────────┐
│ State + Memory │
└────────┬─────────┘
↓
┌──────────────────┐
│ Customer reply │
└──────────────────┘
The important architectural decision isn't actually "which framework?" It's how you represent state. For example, your state might contain:
{
"customer_id": "...",
"conversation_summary": "...",
"current_intent": "refund",
"order_id": "...",
"authenticated": True,
"pending_action": "issue_refund",
"tools_used": [...],
"requires_human": False
}
That lets the agent survive a conversation such as:
"My package never arrived."
→ finds the order
→ discovers it was marked delivered
→ asks for confirmation
→ customer says "Yes, that's the wrong address"
→ investigates the shipping address
→ offers the appropriate resolution
→ asks for approval before issuing a refund
→ resumes after approval.
That's where a stateful orchestration framework becomes much more valuable than a simple "chatbot + prompt" architecture. LangGraph's persistence layer, for example, supports thread-scoped checkpoints as well as longer-term memory across conversations.
One particularly important design choice
I'd avoid starting with a swarm of autonomous agents.
Instead, use:
one customer-facing agent + specialized capabilities/tools, and introduce specialist agents only where they genuinely help.
The OpenAI Agents SDK explicitly supports both patterns: a manager can call specialist agents as tools, or the conversation can be handed off to a specialist.
For customer service, I'd generally favor the manager pattern:
Customer-facing Agent
│
├── order_lookup()
├── account_lookup()
├── refund_policy()
├── issue_refund()
├── create_ticket()
└── billing_specialist()
rather than:
Customer
↓
Triage Agent
↓
Order Agent
↓
Billing Agent
↓
Refund Agent
↓
Escalation Agent
The latter can become difficult to debug and maintain surprisingly quickly.
My practical recommendation
If I were building this today, I'd prototype both LangGraph and OpenAI Agents SDK for a small representative set of conversations, then choose based on how much explicit workflow control you actually need.
If you already know you'll have long-running conversations, persistent state, approvals, retries, complex branching, and external system side effects, I'd lean toward LangGraph. Its design is explicitly aimed at those requirements.
If the goal is to get a clean production customer-service agent running quickly, with relatively straightforward orchestration, I'd lean toward OpenAI Agents SDK. It has built-in sessions, handoffs, guardrails, tools, human-in-the-loop support, and tracing.
One other thing I'd treat as first-class from day one: tool-level guardrails and observability. Customer-service agents can cause real-world side effects—refunds, cancellations, address changes—so you want validation around those operations rather than relying solely on the model's instructions. The Agents SDK, for example, supports guardrails around individual tool calls as well as agent inputs/outputs.
If you tell me your stack (Python/TypeScript), model provider, and the kinds of customer-service actions the agent needs to perform, I can lay out a concrete production architecture—including state schema, agent/tool boundaries, memory, RAG, human escalation, and evaluation strategy.