<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Rushi Bhosale</title>
    <description>The latest articles on DEV Community by Rushi Bhosale (@rushibhosale84).</description>
    <link>https://dev.to/rushibhosale84</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4230647%2Fd7935d32-64d9-4629-8e0f-74520627e318.png</url>
      <title>DEV Community: Rushi Bhosale</title>
      <link>https://dev.to/rushibhosale84</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rushibhosale84"/>
    <language>en</language>
    <item>
      <title>How I put three AI agents in a Slack channel with Switch</title>
      <dc:creator>Rushi Bhosale</dc:creator>
      <pubDate>Fri, 06 Nov 2026 14:33:07 +0000</pubDate>
      <link>https://dev.to/rushibhosale84/how-i-put-three-ai-agents-in-a-slack-channel-with-switch-5chk</link>
      <guid>https://dev.to/rushibhosale84/how-i-put-three-ai-agents-in-a-slack-channel-with-switch-5chk</guid>
      <description>&lt;p&gt;Every small team has a person who gets asked the same questions all week. "Can we refund this?" "Is this okay to expense?"&lt;/p&gt;

&lt;p&gt;For the &lt;a href="https://www.wemakedevs.org/hackathons/switch" rel="noopener noreferrer"&gt;Flip the Switch hackathon&lt;/a&gt;, I built &lt;strong&gt;Precedent&lt;/strong&gt;: a Slack channel where that person answers once, and AI agents remember the answer as a tested rule. Next time, the agent brings the answer and the person just confirms it.&lt;/p&gt;

&lt;p&gt;This post shows how I built it, step by step, and what broke along the way. If you're trying Switch for the first time, I hope it saves you a few hours.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpnh55l38wh12nl3lldv4.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpnh55l38wh12nl3lldv4.jpg" alt="The Auditor agent in a Slack thread, showing a draft rule tested on 43 past cases" width="800" height="408"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Switch?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/sandbox-quantum/switch" rel="noopener noreferrer"&gt;Switch&lt;/a&gt; is open source software that puts AI agents into team chat. A Slack channel becomes a &lt;strong&gt;room&lt;/strong&gt;, and agents join it like teammates, each with its own name. People and agents all read the same conversation.&lt;/p&gt;

&lt;p&gt;You bring the agents and the chat app. I used Claude Code and Slack.&lt;/p&gt;

&lt;h2&gt;
  
  
  The plan: three agents, one room
&lt;/h2&gt;

&lt;p&gt;I split the job into three small roles:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Agent&lt;/th&gt;
&lt;th&gt;Its job&lt;/th&gt;
&lt;th&gt;Who can give it instructions&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Clerk&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Turns a request into a structured case&lt;/td&gt;
&lt;td&gt;Anyone in the room&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Judge&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Checks the case against the rules and asks the manager&lt;/td&gt;
&lt;td&gt;Only the owner and the owner's agents&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Auditor&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Turns the manager's words into a rule and tests it&lt;/td&gt;
&lt;td&gt;Only the owner and the owner's agents&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Here's how a request moves through the room:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Sam, a support agent, asks the Clerk: "Refund for order 4821, INR 64, unopened, bought 17 days ago."&lt;/li&gt;
&lt;li&gt;The Clerk makes a case and hands it to the Judge.&lt;/li&gt;
&lt;li&gt;No rule covers it, so the Judge asks Priya, the manager.&lt;/li&gt;
&lt;li&gt;Priya approves and adds: "make it a rule: unopened items up to 30 days."&lt;/li&gt;
&lt;li&gt;The Auditor tests that rule on past cases, and Priya decides whether to adopt it.&lt;/li&gt;
&lt;li&gt;The next similar request arrives with the answer and the rule, and Priya confirms in one line.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Step 1: Set up Switch
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Install &lt;a href="https://github.com/sandbox-quantum/switch/releases" rel="noopener noreferrer"&gt;Switch Console&lt;/a&gt;, the desktop app.&lt;/li&gt;
&lt;li&gt;Choose &lt;strong&gt;Add a server → Run a server on this computer&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Connect&lt;/strong&gt; and connect Slack.&lt;/li&gt;
&lt;li&gt;On the server's Home page, click &lt;strong&gt;Link&lt;/strong&gt; and choose &lt;strong&gt;This is me&lt;/strong&gt;, so Switch knows your Slack account.&lt;/li&gt;
&lt;li&gt;Under &lt;strong&gt;Your Agents&lt;/strong&gt;, turn on &lt;strong&gt;Run managed agents on this computer&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Step 2: Describe the team in one template
&lt;/h2&gt;

&lt;p&gt;This was my favourite part of Switch. One YAML file describes the agents and the room, and Console creates all of it. Here's a shortened version of mine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;agents&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{team}-clerk"&lt;/span&gt;
    &lt;span class="na"&gt;display_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Clerk&lt;/span&gt;
    &lt;span class="na"&gt;provider&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;claude&lt;/span&gt;
    &lt;span class="na"&gt;addressing&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;anyone&lt;/span&gt;
    &lt;span class="na"&gt;instructions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
      &lt;span class="s"&gt;You are the Clerk. People bring you requests; you turn each&lt;/span&gt;
      &lt;span class="s"&gt;into a case and hand it to the Judge. You never decide anything.&lt;/span&gt;

  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{team}-judge"&lt;/span&gt;
    &lt;span class="na"&gt;provider&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;claude&lt;/span&gt;
    &lt;span class="na"&gt;addressing&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;owner-agents&lt;/span&gt;
    &lt;span class="na"&gt;instructions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
      &lt;span class="s"&gt;...&lt;/span&gt;

&lt;span class="na"&gt;room&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{team}-approvals"&lt;/span&gt;
  &lt;span class="na"&gt;bridge&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{bridge}"&lt;/span&gt;
  &lt;span class="na"&gt;agents&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{team}-clerk"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{team}-judge"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{team}-auditor"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;users&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{$creator}"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look at &lt;code&gt;addressing&lt;/code&gt;. It decides who can instruct an agent. With &lt;code&gt;anyone&lt;/code&gt;, the whole room can ask the Clerk. With &lt;code&gt;owner-agents&lt;/code&gt;, only the owner and the owner's agents can instruct the Judge, so a random message can't tell it what to do.&lt;/p&gt;

&lt;p&gt;To use it, go to &lt;strong&gt;Templates → Import template&lt;/strong&gt; in Console, then click &lt;strong&gt;Create all&lt;/strong&gt;. The agents and the Slack channel appear.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Let the AI read, and let plain code decide
&lt;/h2&gt;

&lt;p&gt;I didn't want an AI deciding who gets a refund. So the agents only handle the words, and every decision goes through a small command-line tool written in plain Python, with no AI in it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;agents&lt;/strong&gt; read messages, fill in the case and write the replies.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;engine&lt;/strong&gt; checks the rules, tests new ones and saves every step as a git commit.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So the Clerk's instructions tell it to run commands like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;uv run precedent &lt;span class="nt"&gt;--home&lt;/span&gt; &amp;lt;state folder&amp;gt; &lt;span class="nt"&gt;--as&lt;/span&gt; clerk &lt;span class="k"&gt;case&lt;/span&gt; new &lt;span class="nt"&gt;--type&lt;/span&gt; refund ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 4: Check who really approved
&lt;/h2&gt;

&lt;p&gt;This is the most useful Switch trick I learned. If an agent says "Priya approved this", how do you know that's true? An agent could get it wrong, or be tricked.&lt;/p&gt;

&lt;p&gt;So the agent passes the engine only a &lt;strong&gt;message id&lt;/strong&gt;. The engine then asks Switch for that message through the agent API (&lt;code&gt;read_context&lt;/code&gt;) and reads the sender Switch recorded. An agent can't set that value for a person.&lt;/p&gt;

&lt;p&gt;The approval also has to quote a short code, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;approve C-043 #e3cf9b
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That code is a hash of this exact case and answer, so it can't be reused on a different one. When I offered an agent's own message as an approval on the live server, the engine refused it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;precedent-judge is not an approver
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 5: Test each rule on past decisions
&lt;/h2&gt;

&lt;p&gt;Before a rule is saved, the engine replays past cases with and without it. On my made-up demo data, the result was:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;43 cases, of which 41 could be checked&lt;/li&gt;
&lt;li&gt;12 newly covered by the rule&lt;/li&gt;
&lt;li&gt;0 conflicts&lt;/li&gt;
&lt;li&gt;3 past cases where the manager said no, but the rule would say yes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The manager sees those 3 before agreeing. They aren't treated as mistakes, because the manager may have had a reason.&lt;/p&gt;

&lt;h2&gt;
  
  
  What broke, and how to fix it
&lt;/h2&gt;

&lt;p&gt;I ran this on Windows with Console 0.40.1. These are the problems that cost me the most time:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;What I saw&lt;/th&gt;
&lt;th&gt;Cause&lt;/th&gt;
&lt;th&gt;Fix&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Every provider said &lt;strong&gt;Not supported here&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;A Windows bug in Console's provider picker (&lt;a href="https://github.com/sandbox-quantum/switch/issues/1511" rel="noopener noreferrer"&gt;#1511&lt;/a&gt;)&lt;/td&gt;
&lt;td&gt;Write &lt;code&gt;provider: claude&lt;/code&gt; in the template, and turn on managed agents&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;An agent reported &lt;code&gt;{engine_dir}&lt;/code&gt; in its instructions&lt;/td&gt;
&lt;td&gt;Console doesn't fill &lt;code&gt;{params}&lt;/code&gt; in managed agents' instructions (&lt;a href="https://github.com/sandbox-quantum/switch/issues/1577" rel="noopener noreferrer"&gt;#1577&lt;/a&gt;)&lt;/td&gt;
&lt;td&gt;Put the real paths into the template before importing it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;missing_scope&lt;/code&gt; when linking Slack&lt;/td&gt;
&lt;td&gt;The Slack app wasn't made from Switch's manifest&lt;/td&gt;
&lt;td&gt;Paste the manifest into &lt;strong&gt;App Manifest&lt;/strong&gt;, save, and reinstall&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;An agent said it only takes instructions from its owner&lt;/td&gt;
&lt;td&gt;My Slack account wasn't linked&lt;/td&gt;
&lt;td&gt;Click &lt;strong&gt;Link&lt;/strong&gt; on the server's Home page&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"Could not reach &lt;a href="http://localhost:.." rel="noopener noreferrer"&gt;http://localhost:..&lt;/a&gt;."&lt;/td&gt;
&lt;td&gt;The server process had stopped&lt;/td&gt;
&lt;td&gt;Quit Console fully and reopen it&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;My main lesson: test with a live agent early.&lt;/strong&gt; My template passed validation, and I only found the &lt;code&gt;{engine_dir}&lt;/code&gt; problem when an agent told me about it in the room.&lt;/p&gt;

&lt;h2&gt;
  
  
  I also found bugs in Switch
&lt;/h2&gt;

&lt;p&gt;Building this led me to report four bugs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/sandbox-quantum/switch/issues/1577" rel="noopener noreferrer"&gt;#1577&lt;/a&gt;: Console leaves &lt;code&gt;{params}&lt;/code&gt; unfilled in managed agents' instructions&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/sandbox-quantum/switch/issues/1578" rel="noopener noreferrer"&gt;#1578&lt;/a&gt;: Telegram can split a long message in the middle of &lt;code&gt;&amp;amp;lt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/sandbox-quantum/switch/issues/1579" rel="noopener noreferrer"&gt;#1579&lt;/a&gt;: Discord treats a one-line code fence as an open code block&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/sandbox-quantum/switch/issues/1580" rel="noopener noreferrer"&gt;#1580&lt;/a&gt;: Mattermost drops posts over the server's limit&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The last one taught me something. From reading the code, I reported a limit of 4,000 characters. When I tested on real servers, it was 16,383 on Mattermost 10.5 and 262,144 on 12.0, so I posted a correction. Run it before you report it!&lt;/p&gt;

&lt;h2&gt;
  
  
  What it can't do yet
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A person still confirms every case, so cases wait while the manager is away.&lt;/li&gt;
&lt;li&gt;Tampering with the saved data is detected, not prevented.&lt;/li&gt;
&lt;li&gt;The past cases and people in the demo are made up, and no real team has used it yet.&lt;/li&gt;
&lt;li&gt;The live run used one Slack account and has only been run on Windows.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;p&gt;You can try the whole flow in about two minutes, without Switch or Slack:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/rushibhosalepro/precedent.git
&lt;span class="nb"&gt;cd &lt;/span&gt;precedent
uv &lt;span class="nb"&gt;sync
&lt;/span&gt;uv run pytest &lt;span class="nt"&gt;-q&lt;/span&gt;
uv run python scripts/rehearse.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Code and full setup:&lt;/strong&gt; &lt;a href="https://github.com/rushibhosalepro/precedent" rel="noopener noreferrer"&gt;github.com/rushibhosalepro/precedent&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Demo video:&lt;/strong&gt; &lt;a href="https://youtu.be/rHvyygxSsvI" rel="noopener noreferrer"&gt;youtu.be/rHvyygxSsvI&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;I built this with Claude Code as my pair programmer. Claude Code also wrote this post, working from the project and our notes.&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  HowISwitch #FliptheSwitch
&lt;/h1&gt;

</description>
      <category>ai</category>
      <category>tutorial</category>
      <category>slack</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
