How We Improved Our AI Agent in Slack by Making It Dumber

Our Slack agent got worse every time we made it smarter. More tools, longer prompts, broader memory — each addition felt like progress. In the channel, it felt like a colleague who had read every wiki page and still could not answer a simple question without a monologue.

The fix was not a better model. We made the main agent dumber on purpose — reduced it to a simple index. Most questions never leave that index. The rest get handed to a sub-agent that already knows how to do one job. The main agent never creates anything. It serves what exists, or it passes a packet of context to something else.

The failure mode of a helpful agent

Helpful agents fail in a specific way. They infer intent you did not state, reach for tools you did not ask for, and invent answers when the right move is to look something up or stay quiet.

In Slack that reads as noise. A thread about a broken deploy does not need a recap of your company values. It needs one of three things: an answer from the runbook, a handoff to the right specialist, or silence.

We had built the opposite — one agent that tried to be the whole company. It searched, summarized, drafted, filed tickets, and improvised policy on the fly. Every message became a reason to create something new.

Symptom Cause
Robotic ack, then long second reply Fast path and gateway both handled the same mention
No clarifying question for incomplete asks Routing defaulted to dispatch instead of intake
Wrong-thread noise Main agent improvised instead of checking ownership first

Before fixing architecture, name exactly how it fails in the channel.

The main agent is an index

We collapsed the main agent down to a single job: hold an index of what the company already knows, and know when to stop answering.

We seeded that index with our LLM — not as an open-ended brain, but as a retrieval surface. Runbooks, policies, client notes, deploy steps, who owns what. The model does not freestyle from training data. It answers from the index first, the way you would answer from an internal wiki you had actually read.

That covers most of what people ask in Slack. “How do we deploy?” “Who handles billing for X?” “What is our refund window?” — lookup, reply, done. No tools, no sub-agents, no thread takeover.

Decision matrices for everything else

Not every question is a lookup. Some need action — file a ticket, pull live data, draft a client email, run a scrape. Those do not belong in the main agent.

The index also holds decision matrices: if the request looks like this, spawn that sub-agent. Not vibes. Rows and columns we can read without opening the model weights.

deploy_incident[ incident-runner ]
client_ticket[ ticket-filer ]
weekly_report[ report-runner ]
unknown[ lookup + owner ]

The matrix is a product surface, not hidden prompt lore.

request_type: deploy_incident
  signals: ["down", "500", "prod", "rollback"]
  sub_agent: incident-runner
  main_agent_may: [lookup_runbook, pass_thread_url, pass_env]

request_type: client_ticket
  signals: ["bug report", "customer name", "broken"]
  sub_agent: ticket-filer
  main_agent_may: [lookup_client_index, pass_summary]

request_type: unknown
  main_agent_may: [lookup_index, reply_with_owner]
  sub_agent: none

Main agent permissions stay narrow: answer from index or pass context.

The main agent does not plan the work. It classifies the request, checks the matrix, and either answers from the index or spawns the sub-agent with exactly the context that agent expects. Creation happens downstream. Upstream is read and route.

What we removed from the main agent

Making it an index meant stripping everything that looked like intelligence but was really improvisation.

  • Creation. No drafts, no tickets, no generated policy. If it is not in the index and no matrix row matches, the agent says so and points to a human.
  • Open-ended tool use. The main agent does not browse Slack, query APIs, or chain five calls together. Sub-agents own that — with narrow permissions and one output shape.
  • Multi-step plans in public. The channel sees a lookup result or a single handoff line. Planning runs inside the sub-agent, not in the thread.
  • Personality. We deleted the friendly preamble and the performative empathy. Slack already has humans for that.

Each removal felt like a step backward in a demo. In production it was a step forward in trust — because the main agent stopped guessing.

Serve or send — never invent

The rule is simple enough to put on a sticky note: serve what exists, or send to someone who can act. The main agent is a librarian and a switchboard, not an author.

That constraint sounds limiting until you notice what it buys you. Answers get faster because most requests never spawn anything. Failures get clearer because when something breaks, you know whether the index was wrong, the matrix was wrong, or the sub-agent misbehaved. You are not debugging a single omniscient blob.

When the model drifts, we do not tune temperature. We update the index, add a row to a matrix, or tighten what a sub-agent is allowed to return.

Serve-or-send flow

This is the whole contract. Every turn follows one branch: serve from index, or send a context packet to a specialist.

Main agent routing contract

sequenceDiagram
    participant User
    participant Main as main_agent
    participant Index as memory_index
    participant Worker as sub_agent
    participant Slack

    User->>Slack: mention
    Slack->>Main: normalized request
    Main->>Index: lookup + classify
    alt answer exists in index
        Index-->>Main: answer + source
        Main->>Slack: short factual reply
    else matrix route exists
        Main->>Worker: context packet
        Worker->>Slack: specialist output
    else unknown
        Main->>Slack: owner handoff
    end
Serve what exists. Send what needs work. Never invent in the middle.

What changed in the channel

Fewer wrong-thread replies. Fewer “let me think about that…” messages that never land. More @mentions that actually wanted the bot — because people learned it would either quote something real or kick off a specialist, not riff.

The lesson generalizes. Your main agent does not need to be smart. It needs a good index, honest decision matrices, and sub-agents that do one thing each. Intelligence belongs at the edges — in the seeded knowledge and in the workers — not in a single Slack face trying to do everything at once.

If your agent gets worse every time you add a tool, try the opposite. Reduce the main agent to an index. Seed it with what you already know. Let everything else spawn a specialist. Make it dumber until the channel trusts it again.