<?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: Nitish kumar</title>
    <description>The latest articles on DEV Community by Nitish kumar (@nitish-builds).</description>
    <link>https://dev.to/nitish-builds</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%2F4059254%2F0cee8545-4ef1-42cc-b217-7b6fbf4b230d.png</url>
      <title>DEV Community: Nitish kumar</title>
      <link>https://dev.to/nitish-builds</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nitish-builds"/>
    <language>en</language>
    <item>
      <title>Your AI employees can now work as a team: introducing Agent Orchestration</title>
      <dc:creator>Nitish kumar</dc:creator>
      <pubDate>Wed, 02 Sep 2026 18:29:32 +0000</pubDate>
      <link>https://dev.to/deskferry/your-ai-employees-can-now-work-as-a-team-introducing-agent-orchestration-gfo</link>
      <guid>https://dev.to/deskferry/your-ai-employees-can-now-work-as-a-team-introducing-agent-orchestration-gfo</guid>
      <description>&lt;p&gt;Until now, a DeskFerry agent was a very good solo employee. You described a job in plain English, it connected to your tools, and it ran that job on a schedule or trigger. That worked well for one job at a time.&lt;/p&gt;

&lt;p&gt;But real work isn't one job. Qualifying a lead is research, then scoring, then CRM hygiene, then outreach, then follow-up. Each of those is a different skill, with different tools and different failure modes. Cramming all of it into a single agent meant one giant prompt, one giant blast radius, and a lot of "why did it do that?"&lt;/p&gt;

&lt;p&gt;As of September 1, that changes. Agent Orchestration is live in DeskFerry.&lt;/p&gt;

&lt;p&gt;What it does&lt;/p&gt;

&lt;p&gt;Orchestration lets one agent coordinate others. You give a brief to a lead agent, and it breaks the work down and delegates each piece to a specialist agent you've already built (or lets DeskFerry build the missing ones for you).&lt;/p&gt;

&lt;p&gt;Concretely, agents can now:&lt;/p&gt;

&lt;p&gt;Delegate. A lead agent hands a sub-task to another agent and waits for the result, the same way a manager assigns work.&lt;br&gt;
Share context. The research agent's findings are available to the outreach agent without you copying anything between them. Memory is scoped to the workflow, not trapped in one agent.&lt;br&gt;
Hand off mid-flight. A support triage agent can escalate a ticket to a billing agent with the full thread attached, then step back in when billing is done.&lt;br&gt;
Run in parallel. Independent steps (enrich five leads, check three inboxes) fan out and come back together.&lt;br&gt;
Pause for humans where it matters. Approvals work exactly as before, but now you can put the checkpoint at the team level — approve the final email, not every intermediate step.&lt;br&gt;
What it looks like&lt;/p&gt;

&lt;p&gt;You still describe the outcome, not the plumbing:&lt;/p&gt;

&lt;p&gt;Every weekday at 8am, pull new HubSpot leads, research each company, score them against our ICP, draft a first-touch email for anything above 70, and post the drafts to #sales for approval before sending.&lt;/p&gt;

&lt;p&gt;DeskFerry turns that into a small team: a coordinator, a researcher, a scorer, and a writer. Each one is a normal DeskFerry agent — you can open it, edit its instructions, swap its model, or reuse it in a different workflow. The scorer you built for inbound leads can be the same scorer your partnerships agent calls next month.&lt;/p&gt;

&lt;p&gt;Why we built it this way&lt;/p&gt;

&lt;p&gt;We looked at two approaches. One was a visual canvas where you draw boxes and arrows between agents. The other was letting you describe the team the way you'd describe it to a new hire. We chose the second, because the whole point of DeskFerry is that you shouldn't need to become a workflow architect to get work done.&lt;/p&gt;

&lt;p&gt;Under the hood, the coordinator is doing the planning, but everything it decides is visible. Every delegation, every handoff, and every intermediate result shows up in the run log, so when something goes sideways you can see exactly which agent made which call.&lt;/p&gt;

&lt;p&gt;What it means in practice&lt;br&gt;
Smaller, more reliable agents. A specialist with one job and three tools is much harder to confuse than a generalist with fifteen.&lt;br&gt;
Reuse. Build a skill once, call it from anywhere.&lt;br&gt;
Less babysitting. The coordinator handles retries and routing so you don't get paged for a single flaky step.&lt;br&gt;
&lt;a href="https://deskferry.app" rel="noopener noreferrer"&gt;Try it&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Orchestration is available now. Open any existing agent, and you'll see a new option to let it delegate to other agents, or start fresh with a multi-step brief and let DeskFerry assemble the team.&lt;/p&gt;

&lt;p&gt;If you're on a trial, this is included. If you're not, the trial is free and doesn't auto-convert.&lt;/p&gt;

&lt;p&gt;We'd love to hear what you build. Drop your workflows in the comments, or tell us where orchestration falls short — that's the feedback that shapes what ships next.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>automation</category>
      <category>agents</category>
      <category>nocode</category>
    </item>
    <item>
      <title>Your agent doesn't need more tools, it needs better tool descriptions</title>
      <dc:creator>Nitish kumar</dc:creator>
      <pubDate>Sun, 02 Aug 2026 16:31:35 +0000</pubDate>
      <link>https://dev.to/nitish-builds/your-agent-doesnt-need-more-tools-it-needs-better-tool-descriptions-4d28</link>
      <guid>https://dev.to/nitish-builds/your-agent-doesnt-need-more-tools-it-needs-better-tool-descriptions-4d28</guid>
      <description>&lt;p&gt;Most agent failures I've debugged weren't reasoning failures. The model reasoned fine. It just picked the wrong tool, because the tool description didn't tell it what it needed to know.&lt;/p&gt;

&lt;p&gt;This is an under-discussed problem, and it gets worse the more integrations you add. Here's what we've learned.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The setup&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Say your agent has four calendar-ish tools available:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"calendar_create_event"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Creates a calendar event"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"calendar_quick_add"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Adds an event from text"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"scheduling_book_slot"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Books a scheduling slot"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"meeting_schedule"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Schedules a meeting"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Now: "Book me 30 minutes with Sarah on Thursday."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Which one? You don't know either, and you have context the model doesn't. The model will pick one, it'll probably work about 60% of the time, and when it's wrong the failure will be silent — an event created in the wrong system that nobody notices for a week.&lt;/p&gt;

&lt;p&gt;Roughly 40% of our agent failures traced back to tool selection, not reasoning. That was surprising and it changed where we spent engineering time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why OpenAPI schemas aren't enough&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A schema tells you what a tool accepts. It doesn't tell you:&lt;/p&gt;

&lt;p&gt;What the tool is for — the use case, not the signature&lt;br&gt;
When it's appropriate versus the four adjacent tools that look identical&lt;br&gt;
Whether it's reversible — can you undo it, and how&lt;br&gt;
What it costs — a rate-limited call and a free one shouldn't be equally attractive&lt;br&gt;
What it assumes — does it require the user's calendar to be connected first?&lt;/p&gt;

&lt;p&gt;Documentation doesn't have this either, because docs are written for humans who already know which product they're integrating with. The model is choosing between products.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What a description for an agent looks like&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here's the template we converged on:&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;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;calendar_create_event&lt;/span&gt;
&lt;span class="na"&gt;purpose&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="s"&gt;Create an event on the user's primary Google Calendar when you already&lt;/span&gt;
  &lt;span class="s"&gt;know the exact date, time, and duration.&lt;/span&gt;
&lt;span class="na"&gt;use_when&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;The time is fully specified ("Thursday 2pm for 30 minutes")&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;The user owns the calendar being written to&lt;/span&gt;
&lt;span class="na"&gt;do_not_use_when&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;The time is approximate or needs negotiation → use scheduling_book_slot&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Inviting external participants who need to pick → use scheduling_book_slot&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;The user said "find a time" rather than naming one&lt;/span&gt;
&lt;span class="na"&gt;reversible&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yes — event can be deleted via calendar_delete_event&lt;/span&gt;
&lt;span class="na"&gt;side_effects&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;sends invitations to all attendees immediately&lt;/span&gt;
&lt;span class="na"&gt;cost&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;low&lt;/span&gt;
&lt;span class="na"&gt;requires&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;google_calendar connection active&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The do_not_use_when block with explicit redirects is doing most of the work. It's not describing this tool — it's describing the boundary between this tool and its neighbours, which is exactly what the model is uncertain about.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Generating these at scale&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Writing these by hand doesn't scale past a few dozen tools. Our loop:&lt;/p&gt;

&lt;p&gt;Generate a first draft from the schema and whatever docs exist, using a model.&lt;br&gt;
Ship it. It'll be mediocre.&lt;br&gt;
Log every selection, along with what the agent was asked and what it picked.&lt;br&gt;
When a selection is wrong, don't patch the prompt — patch the description of the tool that should have been chosen and the one that was.&lt;br&gt;
Over time the descriptions become a record of every mistake the system has made.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;record_misselection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;chosen_tool&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;correct_tool&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# The fix goes in the tool metadata, not the system prompt.
&lt;/span&gt;    &lt;span class="c1"&gt;# System prompt fixes don't generalize; description fixes do.
&lt;/span&gt;    &lt;span class="n"&gt;boundary_note&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;infer_distinguishing_feature&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;chosen_tool&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;correct_tool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;correct_tool&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;use_when&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;boundary_note&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;chosen_tool&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;do_not_use_when&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;boundary_note&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; → use &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;correct_tool&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That step 5 is the important one. Every instinct says to fix selection errors by adding rules to the system prompt. Resist it. Prompt fixes are global, they collide with each other, and they don't survive a model upgrade. Description fixes are local to the tools involved and they compose.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A cheap win: prune before you send&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Related, and it saves real money: don't send every tool schema on every step of the loop. Schemas can be a large share of your token spend, because they're re-sent on every iteration, not once per run.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;relevant_tools&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;all_tools&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# Cheap pre-filter — embedding similarity between the current
&lt;/span&gt;    &lt;span class="c1"&gt;# goal and each tool's `purpose` field
&lt;/span&gt;    &lt;span class="n"&gt;scored&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;rank_by_similarity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;goal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;all_tools&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;purpose&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;scored&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nf"&gt;always_include&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;all_tools&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Fewer tools in context also means better selection accuracy, so this helps twice. Most frameworks encourage handing the agent everything up front; that's the wrong default past about a dozen tools.&lt;/p&gt;

&lt;p&gt;The bigger point&lt;/p&gt;

&lt;p&gt;The industry is competing on model quality and integration count. Neither is where agent reliability actually comes from right now.&lt;/p&gt;

&lt;p&gt;The semantic layer — what each tool means, when it applies, how it differs from its neighbours — is unglamorous curation work that nobody ships as a feature. It's also, in our experience, the difference between an agent that demos well and one that runs unattended.&lt;/p&gt;

&lt;p&gt;If I were starting again I'd treat it as core product from day one instead of infrastructure to get through.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Building DeskFerry — agents across 1,500+ integrations, which is how we ended up caring about this. Questions welcome below.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>architecture</category>
      <category>python</category>
    </item>
  </channel>
</rss>
