# How we run customer support with an AI agent

Our support agent on Machine plugs into Plain, our code and Stripe. It sorts and answers incoming threads on its own, and pauses for a person whenever something sensitive comes up.

Canonical page: https://themachine.myapps.ai/use-cases/customer-support

Our own customer support runs on Machine. An AI agent sits on top of Plain, our
support tool, and can also see our code and our Stripe account. A real support
question usually needs product knowledge, engineering context and billing data
all at once. A help-centre chatbot can recite the docs. It cannot open the code
behind a bug, check that a subscription renewed, or take a carefully limited
action on someone's account.

Below we explain how it fits together: what it connects to, how each conversation
gets its own workspace, and where the limits sit.

- **Team:** Machine, the company that builds this platform
- **Support stack:** Plain.com
- **Connected systems:** Codebase · Stripe · Plain
- **Mode:** Starts on each new message · a person approves anything sensitive

## The problem

Tickets multiply faster than headcount. The tickets that count are the ones no
saved reply can handle: "Why did you bill me twice?", "Nothing happens when I
click this button", "Can your API do X?" Each one takes someone who knows the
product, reads code and can open the customer's account: usually a senior
engineer.

A help-desk bot copes with the simple stuff and gives up on these. Hiring more
people grows cost one-for-one with ticket volume. And handing a general-purpose AI
assistant real keys to production is a tough sell in any security review.

## What we built

We wired our **Plain** inbox to an agent on Machine. Each incoming thread gets a
sealed-off session of its own, with narrow access to the places a support problem
can lead: what the product knows, the code and Stripe. The agent digs in, fixes
what it is allowed to fix, and hands sensitive steps to a person.

## How it works

### Let Plain start each run

Plain sends a signed webhook to the project. A new thread or a fresh customer reply
sets it off, and each time a brand-new **session** is created: a fresh cloud
computer (sandbox) just for that conversation. Nothing is shared between threads,
and a busy day simply means more sessions working side by side.

### Teach the agent the product

What the agent knows about the product sits in **skills** and **memory**, the
playbook it loads at the start of every session. That includes how the product
behaves, our support playbook, the voice we reply in, and fixes that solved
similar problems before. Each time a thread is closed, the playbook can learn
something new.

### Plug in everything a ticket might need

**Connectors** are scoped connections to your tools, with the keys held on our
servers so the model never sees them. Through them the agent can:

- **Search the code:** when a bug comes in, find the code behind it, look at what
changed lately, and check whether it is a known issue.
- **Check Stripe:** the customer's plan, invoices and subscription status, so
billing answers come from real account data.
- **Read and reply in Plain:** take in the whole thread, then send back an answer.

### Draw the lines

Out of the box the agent **mostly reads**: it can look around freely, but its
writes are tightly limited. Refunds, plan changes and anything else
that touches a customer's money or account halt at a **human approval gate**.
Credentials are stored encrypted in the **Secrets Manager** and only handed to the
agents you grant them to, at the moment a run starts.

### Let each thread play out

When a thread arrives, the agent sorts it, digs through all three systems, and then
either solves it outright or passes it to a person with the legwork done and the
context attached. "Why did you bill me twice?" turns into a Stripe check and a
clear answer. "Nothing happens when I click this button" turns into a code search
that either explains what is going on or files a bug for engineering.

> **Summary**
> Hook your support tool up as a **trigger**. Give the agent narrow
> **connectors** into every system a ticket could reach. Store what it knows about
> the product as **skills** and **memory**, and put a person in front of anything
> sensitive. From then on, every incoming thread gets a session of its own.

## Guardrails

Letting an agent into your code, your Stripe account and your support inbox is as
much a security decision as a product one. Here is what keeps it safe on Machine:

- **Isolation.** Every thread runs in a sandbox and on a branch of its own. Inside,
  the session can install tools, run code and try things out to reproduce a bug,
  and only what it is explicitly allowed to send ever leaves.
- **Scoped secrets.** The Plain, Stripe and GitHub credentials are stored encrypted
  in the Secrets Manager and only handed to the agents you grant them to, injected
  into the sandbox when the run starts.
- **Human approval gates.** Anything that cannot be undone, such as moving money
  or changing an account, needs a person to approve it.
- **Everything is code.** The agent's persona, skills and permissions are files in
  the repo. They keep a version history and change through a reviewed **change
  request**, not a setting in a dashboard.

## The outcome

- **24/7:** Round-the-clock answers with nobody on night duty
- **First-touch:** Plenty of threads are solved before a person even opens them
- **3 systems:** Product knowledge, Stripe and the code, all in one agent

The detective-work tickets that once pulled a senior engineer off their work now
go to the agent first, and when it passes one along, the diagnosis comes with it.
Customers get a real answer at any hour.

Four building blocks make it work: a sandbox that keeps every session contained,
a Secrets Manager that handles the keys, approval gates in front of anything that
cannot be undone, and memory that gets smarter each time a thread is closed.
