Building a Customer Service AI Agent That Executes Workflows (Not Just Answers Questions) - Full Architecture A developer detailed the architecture behind a production customer service AI agent that executes workflows rather than merely answering questions, emphasizing the tool-use layer and intent classification. The agent loop includes classifying intent, retrieving context, planning actions, executing tools, and generating grounded responses, with escalation conditions built in. The post provides code examples using Anthropic's Claude model and highlights the difference from retrieval-only chatbots. Most customer service AI implementations answer questions. They retrieve relevant information from a knowledge base, synthesize a response, and hand the conversation back to the customer. That's a chatbot. A good one, in 2026, but still a chatbot. A customer service agent that executes workflows does something different. It processes the refund. It updates the account. It triggers the return label. It does what the customer asked, inside the systems that matter, and sends confirmation when it's done. The difference isn't the model, it's the architecture around the model, specifically the tool-use layer and how everything connecting to it is designed. This is the architecture we use for production customer service agents. It's the part that most tutorials skip. A Q&A agent has one primary operation: retrieve context, generate response. The loop is simple. A workflow-execution agent has three: classify intent, execute tools, generate response. The middle step is where production complexity lives. Here's the agent loop that governs everything: python from anthropic import AsyncAnthropic from typing import Optional import asyncio client = AsyncAnthropic async def agent loop conversation: Conversation - AgentResponse: Step 1: Classify customer intent intent = await classify intent message=conversation.latest message, history=conversation.history Step 2: Retrieve customer context from backend systems context = await retrieve context customer id=conversation.customer id, intent=intent Step 3: Plan actions based on intent + context action plan = await plan actions intent=intent, context=context, policy=load policy intent.type Step 4: Execute tools if the intent requires action tool results = {} if action plan.requires tools: tool results = await execute tools action plan.tools Check escalation conditions before proceeding if should escalate tool results, intent, context : return await escalate to human conversation=conversation, context=context, tool results=tool results, reason=determine escalation reason intent, tool results Step 5: Generate grounded response from results response = await generate response intent=intent, context=context, tool results=tool results Step 6: Persist updated conversation state await persist context conversation, response, tool results return response The key difference from a retrieval-only agent: step 4 executes real operations against real systems. The agent isn't describing what should happen. It's making it happen. Before any tool call happens, the agent needs to know what category of request it's dealing with. Intent classification determines which tools get considered and which policy rules apply. INTENT CATEGORIES = "order status", "return request", "refund request", "account update", "billing dispute", "product question", "complaint", "explicit escalation" async def classify intent message: str, history: list - Intent: response = await client.messages.create model="claude-sonnet-4-5", max tokens=256, system="""Classify the customer message into exactly one intent category. Return JSON: {"type":