Build the agent around where the work happens
Contents
Recently, a scheduled regression run failed on one of our staging environments. Dozens of API tests went red at once. Before any engineer looked at it, our QA agent re-ran the job and grouped the failures. Every one of them was the same 503 error from a single service, and it had been happening for about two hours. So it wasn't a test bug.
The QA agent then tagged the agent that belongs to the team owning that service and asked it to check the service health. That agent pulled logs, traces, and pod metrics, found that the service was running on a single pod that had been restarted again and again, and recommended what to do next: re-run the tests, flag the owning team, and add a second replica. From the failed run to a root cause and a recommendation took about eleven minutes. The first time a human needed to act was to read the recommendation.
Nobody opened a new tool for this. The failure was reported in Slack, the agents were in Slack, and the conversation happened in a Slack thread that anyone could read.
This is how most agent work at ShopBack looks today. Over the past year, we have moved from a few experiments to domain agents that sit in team channels and pick up work as it arrives. The lesson I keep coming back to is: build the agent around where the work happens. In this post, I want to share how we got here, what the growth looked like, and what we had to learn along the way. These are my personal views from building this with our teams, not an official ShopBack position.
Work already arrives in Slack
If you look at where work starts in most engineering teams, a lot of it doesn't start in an issue tracker. Someone posts a bug report in a team channel. A colleague from another team asks why a number looks wrong. A product manager drops a feature request with a screenshot. A monitor fires an alert into a channel. Only later, if at all, does that work become a ticket.
So when we started building agents, asking people to go somewhere else to talk to them felt like the wrong starting point. Every new console, portal, or chat window is one more place to remember. The reporter already knows how to post a message in a channel. And a Slack thread already holds most of the context an agent needs: the original report, the follow-up questions, the screenshots, and who is involved.
It is like the difference between a help desk on another floor and one next to the entrance. People use the one they walk past.
We weren't the only ones to land here. When Cognition made Devin generally available, they wrote that "Slack is the primary interface for spinning up Devin sessions". Cursor added the ability to start background agents by mentioning @Cursor in Slack. GitHub made its Copilot coding agent work from Slack conversations, and Anthropic launched Claude Code in Slack. The pattern is the same: meet people in the conversation where the request already lives.
One agent per domain, not one giant agent
The next question was whether to build one agent for everyone or many smaller ones. We chose one agent per domain. The growth team has its agent, payments has its agent, the QA team has its agent, and so on.
The reason is context. Each team has its own services, conventions, runbooks, dashboards, and history. Each team also needs different skills and tools. A payments investigation and a mobile release question need very different knowledge. If we put all of that into a single agent, its context fills up with information that is irrelevant to the task in front of it. I wrote about why this makes agents worse in tokens, context windows, and why your AI agent feels stupid sometimes. A smaller agent with the right skills and the right tools does better work than a giant one that knows a little about everything.
There is also an ownership benefit. When the growth agent gives a bad answer, the growth team knows it is their agent, and they improve its knowledge, skills, or tools. When an agent belongs to everyone, it belongs to no one. This is similar to how we handle on-call. We don't route every production question in the company to one generalist. Each team owns its own on-call rotation because they know their system best.
This also shaped the platform. Each Slack-facing agent has its own Slack app and its own configuration, so a team can add or change its agent without touching anyone else's. If you are curious how skills and tools fit together in an agent like this, MCP vs Skills explains the layers.
What a domain agent does when work arrives
The flow we aim for looks like this. Someone reports something in a team channel. The domain agent picks it up, triages it, and recommends what to do. If it is a support question, the agent often answers it directly. If it is a bug, the agent investigates with the tools it has, such as logs, traces, data queries, and the codebase, and explains what it found. In some cases, it can resolve the issue in one shot: it proposes a merge request and asks the on-duty engineer to review it.
I want to be honest about the shape of this. One-shot fixes happen, but they are not the common case. More often, the agent does the first pass, and then the on-duty engineer picks up the thread and works with the agent over a few messages until the issue is resolved. The fix might be a config change, or it might be a merge request the agent opens. That is still a big deal. Triage is the part of the job that interrupts engineers the most. When the agent has already done a good first pass with evidence, the engineer starts from a recommendation instead of a blank page, and the back-and-forth stays in the same thread where the issue was reported.
The more interesting part has been agents working with each other. The QA example at the start of this post is one. In another thread, a regression run failed a handful of tests. The growth agent grouped the failures into three causes and tagged the agent of the team that owns the affected service to ask whether anything had changed. That agent reproduced the failures and found that the problem was stale test data, not a code regression, and it provided the exact data needed to fix it. When the QA agent was mentioned twice in the same thread, it recognized the second mention as a duplicate trigger and did nothing, instead of starting the investigation again.
Team agents aren't the only ones doing this. I run my own local agent, Jarvis, on my machine. One of its jobs is to follow our agentic delivery flow. It asks a team agent in Slack for an approval verdict on a merge request, reads the reply, and then takes the next step. So Slack has also become a place where agents coordinate with each other.
How it grew
Our first version, in late 2025, was quick and pragmatic. A mention in Slack went to a workflow automation tool, which triggered a CI job. The CI job ran Claude Code inside a workspace prepared for a specific team, and the answer was posted back to the thread.
It let teams start building agents within days, which was what we needed at that stage. But over time, the CI system ended up doing jobs it was never designed for: keeping track of sessions, continuing conversations, avoiding duplicate runs, delivering replies, and showing status for long-running work.
By mid-2026, we had moved to a dedicated platform. A Slack adapter receives events and verifies them. A broker owns sessions, queues, and replies. Each Slack thread maps to one session, and each session runs in its own sandbox. Long tasks can pause and resume, and the thread shows a live status while the agent works. We ran both paths side by side for a while and moved teams over gradually.
Here is how usage grew. The chart counts agent runs each month across the old path and the new platform combined, rounded.
We went from around 100 runs in December 2025 to around 78,000 in October 2026. Growth was fastest in the spring, when more teams built their agents, and it picked up again in September and October. Two notes on how this is counted. On the old path, a run is one CI job. On the new platform, a run is one agent turn. Both include some work that didn't start in Slack, like scheduled tasks and ticket-driven runs, so read the chart as the total load on our agents, not a count of Slack messages.
Usage only tells half the story. The other half is whether the agents produce work that ships. The bars in this chart show the total number of merged merge requests each month, rounded. The line shows the share of them that were authored by the team agents people use from Slack.
In January, these agents authored less than 1% of our merged merge requests. By October, it was almost 15%. That share grew while the total was growing too, from around 4,700 merged merge requests in January to around 12,700 in October.
Slack is where work arrives, not where it gets organized
There's a misreading I want to avoid here. Using Slack as the front door does not mean everything should happen in Slack.
Collaboration happens across tools. Slack is great for reporting, asking, discussing, and triaging. It's not great for keeping track of what was decided, who owns what, and where a piece of work stands three weeks later. Scrolling back through threads to reconstruct the status of a feature is painful for humans, and it is just as painful for agents. An issue tracker like Jira keeps that information organized. GitLab is where code review happens, with diffs, pipelines, and approvals.
So in our setup, the agent picks up work in Slack, but the work itself moves into the system that fits it. A bug that needs a fix becomes a merge request in GitLab. A feature that needs planning becomes a ticket in Jira, where plans are reviewed and approved. The thread links to them, and the agent keeps the people in the thread updated.
Slack itself seems to be moving in the same direction. In August 2026, it launched Slack Code, which gives agent coding work a dedicated channel with views for the plan, the diffs, and a live preview, and it requires human sign-off on high-stakes actions like merging code to production. A plain chat message was never the right surface for reviewing a diff.
I wrote more about the foundations that make this possible, like clear ownership, governed data access, and strong verification, in agentic engineering runs on boring foundations.
What we had to learn the hard way
Putting agents in Slack is easy to start and harder to run well. These are the lessons that cost us the most.
Only a mention should start work. We tried letting agents read and react to everything in a channel. It created noise, burned money, and made agents trigger each other. Now a mention starts a session, replies in that thread continue it, and one thread is one session.
Slack proves where a message came from, not who is allowed to act. A message in Slack doesn't tell you whether the person who wrote it is allowed to trigger what the agent is about to do. Granting the right permissions to the right people and auditing what agents do on their behalf is still an ongoing problem, and one we want to solve.
Agents talking to agents needs rules. Once agents can mention each other, they can also loop. We added limits on how often an agent can be triggered by bots in the same thread, and agents that answer a bot mention once instead of continuing the conversation forever. We also learned that approvals between agents need care. In one thread, an agent gave another agent the go-ahead to change data on staging. Staging is a low-risk place for that, but it made us realize that an agent approving another agent is still an approval, and we tightened those gates afterwards. Human approval should sit at the points where judgment matters, and it should be explicit.
Isolate the blast radius. At one point, one malformed configuration entry took down every Slack agent at the same time. We changed the platform so each agent's configuration is loaded and validated on its own. One team's mistake should not stop every other team's agent.
Treat every message as untrusted input. Anyone who can post in a channel can try to steer an agent. Scope each agent's tools to what its domain needs, run it in a sandbox, and keep credentials out of the agent's reach where you can.
Respect the platform limits. An agent that was allowed to read whole channels quickly hit Slack's rate limits. Long replies got hidden behind "Show more" until we switched to Slack's native markdown blocks. Slack has also become stricter with third-party apps. In 2025, it lowered the rate limits for reading conversation history for new commercially distributed apps, citing the risk of apps exfiltrating sensitive conversation data. Internal apps that a company builds for itself were not affected.
If you are an engineering leader thinking about putting agents in Slack, these are the questions I would answer first:
- Where does work arrive for each team today?
- Which domain owns each agent, and who improves it when it is wrong?
- Where does the work move after triage, and who approves it there?
- Whose identity does an agent run carry?
- What happens to every other agent when one agent breaks?
- How will you measure whether the work is valuable, beyond how much of it there is?
What the numbers don't say
The charts above show adoption and output. They don't prove value on their own.
More runs mean more demand, which is different from more productivity. A merge request count also hides a lot. Agent merge requests may be smaller, or focused on lower-risk work. When we compared recently closed merge requests, 87% of the ones authored by agents were merged, compared to 93% of the ones authored by humans. That is close, but it is a gap, and every unmerged merge request still cost someone time to review.
Review time is also mixed. Comparing the same weeks in 2025 and 2026, the median time for a human merge request to go from open to merged went up by 37%, while the 75th percentile went down by 53%. A typical merge request waits a bit longer, but the slower ones get merged much sooner. I can't honestly say that agents saved or cost us review time overall. What I can say is that human review attention is now the main limit, which is the same thing I found when running more agents myself.
The metrics I care more about now are the ones that are harder to collect: how much agent work is accepted without rework, how many review rounds it takes, and how much on-call time triage saves per domain. We are still working on measuring these well.
Build around the work
Looking back, the most important decision was not which model to use or which framework to build on. It was putting the agent where the work already arrives, giving each domain its own agent, and moving the work into the right system once it was understood.
Slack is the front door. Jira and GitLab are where the work is organized and reviewed. The agent's job is to connect them, and the human's job is to own the decisions that matter.
If you're about to start, don't begin by asking which agent to build. Begin by looking at where work arrives in your teams, and build the agent there.
If this perspective resonates with you, subscribe to my blog. I share what I learn while building real systems with AI in the loop. You can also follow me on X or Threads for more thoughts and ongoing experiments.