
Articles · Inbox · 18 min
What is an inbox agent, and how is it different from a helpdesk chatbot?
An inbox agent is software given a mail job and a short list of tools. It searches threads, drafts, files, archives, and stops when the artifact exists or it hits a limit you set. A helpdesk chatbot answers a message and waits. A Zapier path fires a graph you already drew. The model is not the product. The loop is.
By Eric · Rome · Aug 29, 2026
Forty mixed vendor threads is a job with a finish line. The artifact is a one-page brief in a folder, junk archived, and the hard thread in a queue with evidence attached. A widget that chats about the mailbox is not that job.
Software that can search the mailbox, write the file, and stop is an inbox agent. Software that talks about the mailbox is a helpdesk chatbot, and software that fires a graph you already drew is a Zapier path.
Vendors blur the three. Search, write, archive, and stop is one loop. A reply that waits for the next message is another.
An inbox agent is given a mail job, a short tool list, and a way to know it is done. It acts in the mailbox until the artifact exists or it hits a limit you set. A chatbot replies, a Zap fires a path, and if the output is only more chat you do not have an agent.
I build operators, not windows. The same split I use in AI agent vs chatbot applies here, only the desk is mail.
If you cannot name a finish line a script can see, you still have a helpdesk widget. The construction is how to build an inbox agent. This page only names the worker, the chatbot, and the Zap.
Name the finish line for the inbox
Write done as a test a script can see: a brief in a folder, junk archived, a ticket closed with the file attached. “Handle the inbox” is not a finish line. If only a person can tell the work finished, a person will stay in every loop.
I start with the artifact, not the model. The brief PDF sits in the shared drive and the vendor thread is archived. Refund logged, customer mailed a draft, ticket moved to waiting.
Calendar hold created, original message labeled done. Each of those can be checked without reading a chat.
“Be kind to the unread” is not a job. “Summarize my morning” is not a job unless you name the file, the folder, and the labels that prove the morning is handled.
A goal you cannot test will produce a fluent recap and an untouched mailbox.
The finish line also names what must not happen: send, delete, or touching threads labeled legal. Those are not vibes in the prompt. They are grants the runtime can refuse.
I write the done condition before I pick tools. If I cannot write it, I do not have an inbox agent yet. I have a chat with extra steps.
The model will happily discuss mail all day. Discussion is not completion.
Write the goal as a test a script can see before you talk about a plan. Search, file, archive, stop. Without that, the model tours the mailbox and never produces the brief.
Name the output and the side effects that must exist, then the side effects that must not. Then you have a job. Then you can talk about tools.
Put the chatbot on conversation work
A helpdesk chatbot answers a message and waits for the next one. An inbox agent keeps going: it calls mail tools, reads what came back, and continues until the job is met. Conversation is the chatbot’s product, and the artifact is the agent’s.
I have watched teams bolt a model onto a shared inbox and call the widget an agent. A customer types and the model replies. The window got smarter and the desk did not move: a human still copies the answer, still refunds, still files the PDF.
A chatbot is the right shape when the work is a conversation: FAQ, a guided form, a status check the user is happy to read. Use it when the person on the other side is still in the thread and the next message is the product.
An inbox agent is the right shape when the person who owns the mailbox is trying to leave the thread. Vendor mail, inbound ops, founder overload, a support queue that should close tickets rather than collect replies.
The user of the agent is the operator. The mailbox is the environment.
Anthropic’s Building effective agents, published 19 December 2024, puts customer support in an appendix as a place where agents add value. The reason is not the chat UI.
Support already has conversation, tools such as order history, refunds, and tickets, and a resolution you can measure. Take the tools and the resolution away and you are back to a chatbot.
That is the tell. If success is a good reply, you built a chatbot. If success is a closed ticket, a filed brief, or an archived thread, you are in agent territory.
The same model can do both. The loop decides which one you shipped.
Do not put an unsupervised agent on first contact with a customer. Capture is a script or a tight chatbot, and completion is the agent after the lead or the ticket exists.
I wrote that split in AI agent vs chatbot. Mail does not change it.
If you still type the next instruction after every reply, you have a chatbot, even if the vendor slide says agent. Independently means the run continues without you in every click.
The inbox agent goes away, uses tools, and comes back with the file or a packet that says why it stopped.
Keep Zapier on the drawn path
A Zapier path is a workflow. You drew the branches, and the graph decides the next step. Use it when the mail job is a known sequence, and use an agent when you cannot draw the path in advance and you can still write what done looks like.
Anthropic’s 2024 essay draws the line I use on every desk. Workflows are systems where models and tools run through predefined code paths. Agents are systems where the model dynamically directs its own process and tool use.
A Zap is the first kind. An inbox agent is the second.
Workflows are systems where LLMs and tools are orchestrated through predefined code paths. Agents are systems where LLMs dynamically direct their own processes and tool usage.
New invoice from this domain, save the PDF, post a row, label the thread. That is a Zap. You can draw it on a napkin.
Putting a model in the middle adds latency and a way to wander. Write the Zap.
Forty vendor threads, some junk, some contracts, some that need a one-page brief, some that should wait for legal. You cannot draw that graph without lying.
The next tool depends on what the last search returned. That is an agent.
Anthropic’s advice in that same 2024 post is blunt: find the simplest solution, and only add complexity when it demonstrably improves outcomes. Agentic systems trade latency and cost for flexibility.
If a filter and a path would do, the path should win.
Routing can still be a workflow. Anthropic names routing as a pattern: classify the input, then dispatch to a specialist path.
Easy refunds down a Zap. Hard disputes to an agent. The classifier can be a small model, and the hard work keeps the tools and the stop rule.
The agent earns its keep when the number of steps is not known, the tool choice depends on what just came back, and you still have a finish line. Open-ended browsing of the whole company drive is not that job. It is a way to spend.
Compare the three shapes on one desk
Three shapes sit on the same desk: the chatbot is a window, the Zap is a graph, and the inbox agent is a worker with tools and a stop. Pick the shape that matches the job. Do not buy an agent for a path you already drew.
| Inbox agent | Helpdesk chatbot | Zapier path | |
|---|---|---|---|
| You give it | A job with a finish line | A message | A trigger |
| It acts | Yes, by choosing mail tools | No. It replies. | Yes, down a path you drew |
| Who decides next | The model, inside your limits | The user | The graph |
| Tools | Named functions with schemas | Optional, often none | Fixed steps and apps |
| You are done when | The artifact exists | The reply is good | The last step fires |
| The human sits | At the edge: grants and review | In every turn | When the graph breaks |
| Use it when | The path cannot be drawn ahead | The work is a conversation | The sequence is already known |
Read the table left to right on a real thread. A customer asks for store hours: chatbot. An invoice always lands from the same domain and always needs the same row in the sheet: Zapier path.
A founder inbox with mixed vendors, mixed attachments, and a brief due in a folder: inbox agent.
Vendors will keep saying agents run processes from start to finish. The mechanism is still this table: chatbot if the reply is the product, Zap if you already drew the path, inbox agent if the model must choose mail tools toward an artifact.
If the process is a drawn path, you do not need the model to steer it.
Email order processing with a decision and a close is inbox-agent work: look up the order, write the result, stop. A helpdesk widget that narrates the same order is still chat.
Do not import a vendor customer story as your score. Your number is whether the artifact exists on a frozen set of your threads.
A hybrid desk is normal. Zap on the obvious invoice, chatbot on the public FAQ, agent on the mixed pile that still has a finish line.
The failure is using one shape for all three and calling it transformation.
Arm the operator with named mail tools
Give the operator named mail tools with schemas and limits. Search is not send, read is not archive, and draft is not the list. Extra tools are how it wanders, so the description of each tool is the prompt and you write it exactly.
In the OpenAI Agents SDK docs (2026), an agent is a large language model configured with instructions, tools, and optional runtime behavior such as handoffs, guardrails, and structured outputs. Tools are not a vibe. They are functions with names, descriptions, and arguments the model can pick.
For mail I start under ten: search_mail, read_thread, get_attachment, write_file, draft_reply, apply_label, archive_thread, create_ticket. That set already covers a morning. Each one has a schema, a timeout, and a permission.
YouTube
Open originalLangGraph’s 7 May 2024 customer-support tutorial is a travel assistant with named tools and a graph, not a mailbox. The mechanism I want is still one function per grant: search is not archive, draft is not send.
search_mail returns ids and snippets, not a novel. read_thread returns the thread, not a guess. write_file returns a path.
draft_reply writes a draft and stops. apply_label does not archive. archive_thread does not delete.
The model should not have to infer those boundaries from prose.
Anthropic’s 2024 agents essay spends an appendix on this: treat the agent-computer interface with the same care as a human-computer interface. Example usage, edge cases, input format, and clear walls between similar tools.
I have watched a model archive a legal thread because archive and label shared a fuzzy description.
Send is a different grant. I do not put send_mail on the first operator, so draft is the tool. This page is draft-first, the build guide closes with send as a later grant, and triage classifies and files with send behind a scored class.
A person, or a later promotion after eval, turns draft into send. Same for delete, wire, and deploy. An inbox agent that can read the mailbox should not also be able to move money.
Return short true results: not found, denied, timeout, thread id, path. The next thought needs facts, so do not wrap tool output in marketing language.
The runtime logs the call. If you only keep the final message, you will not see the bad search.
Thirty tools is a wanderer. If the desk needs billing and legal and deploy, you do not dump thirty tools on one body.
You split specialists later, and you hand off with a packet. One operator, short list, is the default.
Put the loop in a runtime you can stop
The model should not own the loop. A runtime calls the model, runs tools, retries a dropped connection, caps turns, and stops. OpenAI Agents SDK names this as Agent plus Runner, and if you cannot kill a runaway trace you are still in demo.
The OpenAI Agents SDK docs (2026) describe an agent as an LLM with instructions and tools, plus a built-in loop that continues until the task is complete. The Runner calls the model, runs tools, switches on a handoff, and stops on a final output.
If turns exceed max_turns, the runtime raises.
That raise is the stop rule in code. Anthropic’s 2024 essay says the same: agents should gain ground truth at each step, may pause for a human, and should have stopping conditions such as a maximum number of iterations.
An unbounded mail loop is an invoice. Cap steps and spend in the runtime or the operator will keep searching.
I cap steps and spend on every inbox run. A dropped connection retries. A business failure does not, unless a rule says so.
Archiving the same thread eleven times is not a connectivity problem.
Guardrails belong in the runtime, not in a paragraph of the prompt. The Agents SDK treats input and output guardrails as checks around the run.
For mail that means the run may not mail outside the company, touch a legal label, or claim a refund it did not post.
Memory is not the chat log of the whole company. The run needs the current thread, the finish line, and the tool results so far.
If you stuff last month’s mailbox into the prompt, the operator will re-litigate old mail and miss today’s artifact.
A notebook that calls the model in a for-loop is a demo. Production is a runtime you can observe. Log every tool name, arguments, result, latency, and cost.
When the brief is missing, you read the trace. You do not argue with the final paragraph.
Retries, permissions, and stop do not live in the prompt. The prompt can remind the model of the finish line. The runtime enforces the budget, and if those two disagree the runtime wins.
Take ground truth from the mailbox
Trust the mailbox, not the recap. Anthropic’s 2024 agents essay says agents need ground truth from the environment at each step. After a search, read the result, and after a file write, check the id, because invented summaries are how junk gets archived by accident.
The model will offer to remember what it saw. Do not let it. search_mail returned three ids, so read_thread on the one that matched.
If the attachment is a scan, run the parse tool and read that output. The brief is written from ids, not from a vibe.
This is why a chatbot trained on your help center is still a chatbot. It answers from parameters and retrieved text.
An inbox agent has to touch the thread that arrived this morning. The environment changed since training, and the tool result is the update.
I fail runs that skip the check. Wrote a brief, never called write_file. Claimed the thread was archived, never called archive_thread.
Said there was no invoice, but get_attachment was never used. Pretty traces that miss the file are zeros.
Errors must be usable: not found, permission denied, timeout, duplicate. The model can recover from those if the tool tells the truth.
A stack trace is not a result. A silent success on a no-op is worse.
Idempotent writes help. archive_thread on an already archived thread should return already archived, not a second side effect.
draft_reply should take a thread id and replace the draft, not create five. Mail systems are messy, so the tool contract should be boring.
Ground truth also includes what the agent must not infer. If the thread does not contain a purchase order number, the brief says so.
Inventing a PO to look complete is a miss, even if the prose is confident.
Anthropic’s 2024 principles for this desk: keep the design simple, show the planning steps, and test the tool interface. Transparency means the trace shows the search, the read, the write.
Hand the hard thread off with a packet
When the thread is too hard or too expensive, the agent writes a packet and leaves: goal, evidence, next action, limits. The next worker continues. A chat dump is not a handoff, and escalation that restarts the job is a miss.
The OpenAI Agents SDK docs describe two common patterns for more than one agent. A manager can call specialists as tools and keep control. Or the current agent can hand off, and the specialist takes over the run.
Mail uses both, but only after one operator is boring.
Most inbox jobs never need a fleet. One worker, short tools, a stop. Split when permissions should not share a body.
The researcher who reads contracts should not send. The closer who drafts replies should not touch legal holds.
How to hand off an agent to a human is the packet spec I use here. The outgoing operator writes the original finish line, unchanged. It attaches evidence as ids, not a vibe summary, names the one next action, and reports spend left, grants, and deadline.
The incoming operator continues from that packet. It does not re-ask the whole question. If evidence is missing, it calls a tool, and it does not invent a recap.
Shared memory can hold the files. The packet holds the baton.
Helpdesk chatbots escalate by saying they will get a human, then pasting the chat. That is fine for a conversation. It is a failure for an inbox agent.
The human who picks up a legal thread should see the finish line, the attachment ids, and why the operator stopped. Not a thousand tokens of hedging.
A packet is also how you pause. Anthropic notes that agents can pause for human feedback at checkpoints or blockers.
The pause is a state: waiting on legal, draft in this id, do not send. The runtime should be able to resume without replaying the whole mailbox.
If you pass the raw thread instead of a decision, the second agent starts the job over and may double-archive, double-draft, or miss the file the first one already wrote. Force a packet with a done check or the desk will loop.
Score the artifact on frozen mail
Freeze last week’s mail, run the operator, and score the artifact. A fluent explanation of a missing brief is a zero. Log every tool call, compare against a script or a careful human, and if you cannot name the score you are grading vibes.
I do not judge an inbox agent by how the chat reads. I give it jobs I already know. Ten threads is a start, fifty is better, and you write the finish line for each.
Keep the set frozen so this week can be compared to last week.
Anthropic’s 2024 essay repeats the measurement point: add complexity only when it demonstrably improves outcomes, and optimize with comprehensive evaluation before you reach for a bigger agentic system.
Mail is a good eval surface because done is a file, a label, a closed ticket. You can see it.
Score done or not first, then tool errors, then cost per success, then steps to done. A cheap fail is still a fail. Cutting the read_thread step to save tokens is how you file the wrong PDF.
LLM-as-judge is fine for tone on a draft. It is a bad only-score. A judge that grades writing will pass an operator that never archived the junk and never wrote the brief.
The primary score is whether the artifact meets the finish line.
Keep a baseline: last week’s agent, a Zap on the easy subset, or a careful human. Live users are not a test set. If the new loop does not beat the baseline on the frozen set, it does not sit on the live mailbox.
Log the misses in a way you can read: wrong thread archived, brief missing a figure that was in the attachment, draft that invents a discount. Those miss classes become grants, tool descriptions, or a specialist. They do not become a longer system prompt that nobody tests.
Keep people at the edge of the inbox
People set the job, the grants, and the review. They do not click every tool. Draft can go unsupervised after the score holds, send stays locked until you promote it, and autonomy is a grant like a permission, because the owner is not the next token.
Human in the loop is often a way to skip eval. If a person must approve every search, you built a slow chatbot.
The point of an inbox agent is that the person is not in every loop. They are at the edge.
People set the job, the grants, and the review. They do not click archive for the model. Direction here is a finish line and a weekly score, not a training slogan.
Make done something a script can see, or the person will stay forever: a test, a webhook, a labeled thread, a file id. Review the weekly score. Intervene when the score drops, and do not sit inside the trace unless it failed.
Draft is not send, label is not delete, and a waiting queue is not the customer. Split the grants so a good morning of triage cannot become a public incident.
Unsupervised does not mean no owner. It means the owner designed the runtime, the eval, and the grants.
Promote one job at a time. Inbox triage can go unsupervised once it beats the baseline. Refunds might still need a review, and legal holds never go to the same operator that drafts marketing replies.
Autonomy is earned per job, not flipped on for the whole company.
When the operator should stop and ask, write that as a tool: request_review with a packet. The runtime pauses, a person answers, and the run resumes from the packet, not from a hallway conversation that never entered the log.
I have taken people out of the inner loop on mail jobs where the finish line was a file and a label, the tool list was short, and the frozen set held. I have not taken people out of send-the-list. The difference is the grant, not the model size.
How to build an inbox agent is the next route: finish line, tools, runtime, eval, one desk. This page is only the map.
Questions
No. Suggested replies and a helpdesk widget answer a message and wait. They become an inbox agent only if a model can call mail tools across steps and stop on a done condition you can test.
Not if the output is still only chat. Pointing a window at mail does not give it a finish line, a tool list, or a stop rule. The loop has to change, even if the widget stays in front.
No. Start with search, read, file, label, archive, and draft. Promote send after the job holds on a frozen set, and only with a grant that matches that job.
Usually no. Start with one operator and a short tool list. Split specialists when one worker would need permissions that should never sit together, such as legal holds and outbound send.
When you can draw the path in advance: same trigger, same steps, same outcome. Save the agent for mail where the next tool depends on what the last search returned, and where you can still write what done looks like.
Next

