<?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>Forem: Noble Ackerson</title>
    <description>The latest articles on Forem by Noble Ackerson (@stigsfoot).</description>
    <link>https://forem.com/stigsfoot</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F121422%2Fe8f033ee-e179-46cf-9c6a-cec0b8fa92d1.jpeg</url>
      <title>Forem: Noble Ackerson</title>
      <link>https://forem.com/stigsfoot</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/stigsfoot"/>
    <language>en</language>
    <item>
      <title>Your multi-agent system is probably slower than it needs to be</title>
      <dc:creator>Noble Ackerson</dc:creator>
      <pubDate>Sat, 19 Jul 2025 18:24:30 +0000</pubDate>
      <link>https://forem.com/stigsfoot/your-multi-agent-system-is-probably-slower-than-it-needs-to-be-2efi</link>
      <guid>https://forem.com/stigsfoot/your-multi-agent-system-is-probably-slower-than-it-needs-to-be-2efi</guid>
      <description>&lt;h1&gt;
  
  
  From Sequential to Dynamic: Evolving a Generative UI Multi-Agent Architecture
&lt;/h1&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.amazonaws.com%2Fuploads%2Farticles%2Fo2g6detk6z2ywjbzd0gz.png" 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.amazonaws.com%2Fuploads%2Farticles%2Fo2g6detk6z2ywjbzd0gz.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem I Started With
&lt;/h2&gt;

&lt;p&gt;Building dashboards sucks. You spend hours configuring charts, mapping data, and making sure everything works together. I thought: what if I could just ask for what I want in plain English and get back a working React dashboard?&lt;/p&gt;

&lt;p&gt;So back to the drawing board, I built a system that does exactly that. Natural language in, interactive React components out. The magic happens through AI agents that specialize in different parts of dashboard creation.&lt;/p&gt;

&lt;p&gt;But here's the thing - my first version was painfully slow. Users would ask for a dashboard and then... wait. And wait some more. Everything happened one step at a time, like being stuck behind someone counting exact change at the grocery store.&lt;/p&gt;

&lt;p&gt;This post is essentially a part two of my Agentic Component Recognition and GenerativeUI applied research (see part one below) fixed that using Google's Agent Development Kit (ADK) and went from "please wait 30 seconds" to "here's your dashboard streaming in real-time."&lt;/p&gt;

&lt;h2&gt;
  
  
  Version 1: The Slow Sequential Approach
&lt;/h2&gt;

&lt;p&gt;Our original system worked like an assembly line from the 1950s. One agent would finish, pass the work to the next agent, who would finish, pass it on, and so on.&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="c1"&gt;# What I started with - everything in sequence
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;google.adk.agents&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;SequentialAgent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;LlmAgent&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create_dashboard_the_slow_way&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;chart_agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;LlmAgent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;chart_maker&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;chart_tools&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="n"&gt;map_agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;LlmAgent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;map_maker&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;map_tools&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;  
    &lt;span class="n"&gt;layout_agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;LlmAgent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;layout_maker&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;layout_tools&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

    &lt;span class="c1"&gt;# This runs one agent at a time, in order
&lt;/span&gt;    &lt;span class="c1"&gt;# Chart agent finishes -&amp;gt; Map agent starts -&amp;gt; Layout agent starts
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;SequentialAgent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;slow_dashboard_maker&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;sub_agents&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;chart_agent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;map_agent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;layout_agent&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The math was brutal:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Chart agent: 5 seconds&lt;/li&gt;
&lt;li&gt;Map agent: 5 seconds
&lt;/li&gt;
&lt;li&gt;Layout agent: 5 seconds&lt;/li&gt;
&lt;li&gt;Total: 15+ seconds of staring at loading spinners&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Users would request a dashboard and then go make coffee. That's not the experience I wanted.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Fix: Three Phases of Getting Faster
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Phase 1: Parallel Tools Within Agents
&lt;/h3&gt;

&lt;p&gt;First fix was obvious once I saw it. Individual agents were doing multiple things sequentially too. Our chart agent would create a bar chart, wait for it to finish, then create a line chart, then create a pie chart.&lt;/p&gt;

&lt;p&gt;Why not do all three at the same time?&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="c1"&gt;# Let agents do multiple things at once
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;make_charts_parallel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chart_types&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;tasks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;chart_type&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;chart_types&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;tasks&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="nf"&gt;create_chart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chart_type&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="c1"&gt;# All charts get created simultaneously
&lt;/span&gt;    &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;gather&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;tasks&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;results&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This was like going from dial-up to broadband for individual agents. Our chart agent went from 10 seconds to 2 seconds when it needed multiple charts.&lt;/p&gt;

&lt;h3&gt;
  
  
  Phase 2: Parallel Agents
&lt;/h3&gt;

&lt;p&gt;Next problem: independent agents were still waiting in line. Chart generation and map generation have nothing to do with each other, so why does the map agent wait for the chart agent to finish?&lt;/p&gt;

&lt;p&gt;ADK has a &lt;code&gt;ParallelAgent&lt;/code&gt; that handles this perfectly:&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="c1"&gt;# Multiple agents working simultaneously
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;google.adk.agents&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ParallelAgent&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create_dashboard_faster&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# Figure out what we actually need
&lt;/span&gt;    &lt;span class="n"&gt;agents_needed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;chart&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="n"&gt;agents_needed&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;chart_agent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;map&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="n"&gt;agents_needed&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;map_agent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;accessible&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="n"&gt;agents_needed&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;accessibility_agent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Run only what we need, all at the same time
&lt;/span&gt;    &lt;span class="n"&gt;parallel_maker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ParallelAgent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;fast_dashboard_maker&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;sub_agents&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;agents_needed&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;parallel_maker&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now instead of 15 seconds sequential, we're looking at 5-7 seconds with results streaming in as each agent finishes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Phase 3: Dynamic Agent Creation
&lt;/h3&gt;

&lt;p&gt;The real breakthrough was realizing I didn't need to keep all these agents sitting around doing nothing. Why have a map agent loaded in memory if someone just wants a simple chart?&lt;/p&gt;

&lt;p&gt;I built an agent factory that creates exactly what each query needs:&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="c1"&gt;# Create agents on demand
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AgentFactory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="c1"&gt;# Templates for different types of agents
&lt;/span&gt;        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;templates&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;chart_basic&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;ChartTemplate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gemini-flash&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;complexity&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;basic&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;chart_advanced&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;ChartTemplate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gemini-pro&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;complexity&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;advanced&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;map_basic&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;MapTemplate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gemini-flash&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;complexity&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;basic&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="c1"&gt;# etc...
&lt;/span&gt;        &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;make_dashboard&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;requirements&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="c1"&gt;# What do I actually need for this query?
&lt;/span&gt;        &lt;span class="n"&gt;needed_capabilities&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;analyze_query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;# Create only those agents
&lt;/span&gt;        &lt;span class="n"&gt;agents&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;capability&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;needed_capabilities&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;template&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;templates&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;capability&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_agent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="n"&gt;agents&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;agent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;# Run them in parallel
&lt;/span&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;agents&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;orchestrator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ParallelAgent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sub_agents&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;agents&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;orchestrator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;agents&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

        &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;orchestrator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;finally&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="c1"&gt;# Clean up when done
&lt;/span&gt;            &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cleanup_agents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;agents&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is where things got interesting. I could:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Spin up exactly the right agents for each query&lt;/li&gt;
&lt;li&gt;Use lightweight agents for simple requests&lt;/li&gt;
&lt;li&gt;Use heavyweight agents for complex analysis&lt;/li&gt;
&lt;li&gt;Clean up everything when done&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Real-World Examples
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Simple query&lt;/strong&gt;: "Show me Q4 sales trends"&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Factory creates: 1 basic chart agent&lt;/li&gt;
&lt;li&gt;Time: ~3 seconds&lt;/li&gt;
&lt;li&gt;Memory: Minimal&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Complex query&lt;/strong&gt;: "Show regional sales with accessible high-contrast visualization and executive summary"&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Factory creates: Chart agent + Map agent + Accessibility agent + Summary agent&lt;/li&gt;
&lt;li&gt;Time: ~6 seconds (all running in parallel)&lt;/li&gt;
&lt;li&gt;Memory: Only what's needed, cleaned up after&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Follow-up query&lt;/strong&gt;: "Make that chart bigger"&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Factory creates: 1 lightweight chart modifier agent&lt;/li&gt;
&lt;li&gt;Time: ~1 second&lt;/li&gt;
&lt;li&gt;Memory: Almost nothing&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  ADK Made This Possible
&lt;/h2&gt;

&lt;p&gt;None of this would have worked without ADK's built-in features:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Session Management&lt;/strong&gt;: Agents automatically share data through ADK's session state. Chart agent puts data in session, map agent reads it out. No complicated message passing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Streaming&lt;/strong&gt;: Results show up in the UI as soon as each agent finishes, not when everything is done.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Callbacks&lt;/strong&gt;: We can monitor performance, catch errors, and log everything without cluttering our agent code.&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="c1"&gt;# ADK handles the hard parts
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;google.adk.core.callbacks&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;before_agent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;after_agent&lt;/span&gt;

&lt;span class="nd"&gt;@before_agent&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;log_start&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;agent_name&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="nf"&gt;print&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="s"&gt;Starting &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;agent_name&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;span class="nd"&gt;@after_agent&lt;/span&gt;  
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;log_finish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;agent_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&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="nf"&gt;print&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;agent_name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; finished in &lt;/span&gt;&lt;span class="si"&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;duration&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;ms&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;h2&gt;
  
  
  The Results
&lt;/h2&gt;

&lt;p&gt;Before: "Please wait 20-30 seconds for your dashboard"&lt;br&gt;
After: "Here's your chart... here's your map... here's your final dashboard" (streaming in real-time)&lt;/p&gt;

&lt;p&gt;Numbers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;70% faster for complex dashboards&lt;/li&gt;
&lt;li&gt;60% less memory usage (only create what you need)&lt;/li&gt;
&lt;li&gt;90% fewer timeout errors (parallel execution is more resilient)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But the real win was user experience. Instead of staring at loading spinners, users watch their dashboard come together piece by piece.&lt;/p&gt;
&lt;h2&gt;
  
  
  What I Learned
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Start simple&lt;/strong&gt;: I began with SequentialAgent, figured out what worked, then made it faster.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use ADK's built-ins&lt;/strong&gt;: Don't reinvent session management, streaming, or callbacks. ADK already solved these problems.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Parallel isn't always better&lt;/strong&gt;: For dependencies (like layout composition), you still need sequential steps.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Clean up your mess&lt;/strong&gt;: Dynamic agent creation means dynamic cleanup. Don't leave agents sitting around eating memory.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Monitor everything&lt;/strong&gt;: You can't optimize what you don't measure. ADK's callback system makes this easy.&lt;/p&gt;
&lt;h2&gt;
  
  
  Future Plans
&lt;/h2&gt;

&lt;p&gt;What's next? I'm working on:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Smart agent sizing&lt;/strong&gt;: Use small models for simple queries, big models for complex analysis.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Learning from history&lt;/strong&gt;: Track which agent combinations work best for different types of queries.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cost optimization&lt;/strong&gt;: Balance speed vs. cost by choosing the right models for each task.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cross-query caching&lt;/strong&gt;: If two users ask for similar dashboards, reuse what we can.&lt;/p&gt;

&lt;p&gt;If you're interested in contributing to this create an issue or for the repo (link below)&lt;/p&gt;
&lt;h2&gt;
  
  
  Try It Yourself
&lt;/h2&gt;

&lt;p&gt;The complete code is available in our GenUI repo. You can run the ADK web interface locally:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install ADK&lt;/span&gt;
pip &lt;span class="nb"&gt;install &lt;/span&gt;google-adk

&lt;span class="c"&gt;# Run the web UI&lt;/span&gt;
adk web genui_agent/ &lt;span class="nt"&gt;--port&lt;/span&gt; 8080

&lt;span class="c"&gt;# Visit http://localhost:8080&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The ADK documentation has everything you need to build your own multi-agent systems. Start with their quickstart guides and work your way up to parallel orchestration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bottom Line
&lt;/h2&gt;

&lt;p&gt;Building responsive AI systems isn't about having the biggest models or the most complex architecture. It's about using the right tools efficiently and not making users wait when they don't have to.&lt;/p&gt;

&lt;p&gt;ADK gave us the building blocks. I just had to stop thinking sequentially and start thinking in parallel.&lt;/p&gt;




&lt;p&gt;Code examples and implementation details are available at &lt;a href="https://github.com/stigsfoot/google-ai-sprint" rel="noopener noreferrer"&gt;github.com/stigsfoot/google-ai-sprint&lt;/a&gt;. Questions? Find me on LinkedIn &lt;a href="https://linkedin.com/in/noblea" rel="noopener noreferrer"&gt;@noblea&lt;/a&gt; or check out the &lt;a href="https://google.github.io/adk-docs/" rel="noopener noreferrer"&gt;ADK documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resources&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://medium.com/google-cloud/agentic-component-recognition-770c3c7f59ac" rel="noopener noreferrer"&gt;Part 1 of this series&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://youtu.be/mwEmzlbENk8?si=qI1HHxrM5pWmIy9G" rel="noopener noreferrer"&gt; Accompanying video - part 1&lt;/a&gt; - old version&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://youtube.com/@stigsfoot?si=YgeURkksLxGpZU5m" rel="noopener noreferrer"&gt;Subscribe to my YouTube&lt;/a&gt; - Subscribers should reach out for access to colab, and notebookLM to learn about ACR.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://google.github.io/adk-docs/" rel="noopener noreferrer"&gt;Google ADK Docs&lt;/a&gt; - Start here&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/google/adk-python" rel="noopener noreferrer"&gt;ADK GitHub&lt;/a&gt; - Source code&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>multiagent</category>
      <category>generativeui</category>
      <category>agentdevelopmentkit</category>
      <category>agentorchestration</category>
    </item>
    <item>
      <title>Creating VR games by learning from step 1 with Noble Ackerson</title>
      <dc:creator>Noble Ackerson</dc:creator>
      <pubDate>Wed, 24 Mar 2021 18:44:55 +0000</pubDate>
      <link>https://forem.com/stigsfoot/creating-vr-games-by-learning-from-step-1-with-noble-ackerson-19ea</link>
      <guid>https://forem.com/stigsfoot/creating-vr-games-by-learning-from-step-1-with-noble-ackerson-19ea</guid>
      <description>&lt;p&gt;In in episode 30 of the Friends That Code podcast, Mike and I talk VR/AR, Data Privacy &amp;amp; Trust, Continuing education and more &lt;a href="https://anchor.fm/friendsthatcode/episodes/30---Creating-VR-games-by-learning-from-step-1-with-Noble-Ackerson-esaie7/a-a51cipm" rel="noopener noreferrer"&gt;Listen here&lt;/a&gt;&lt;/p&gt;

</description>
      <category>vr</category>
      <category>ar</category>
      <category>privacy</category>
    </item>
    <item>
      <title>The Inputs, Outputs, and Outcomes of Product Strategy</title>
      <dc:creator>Noble Ackerson</dc:creator>
      <pubDate>Mon, 09 Mar 2020 03:44:08 +0000</pubDate>
      <link>https://forem.com/stigsfoot/the-inputs-outputs-and-outcomes-of-product-strategy-39gm</link>
      <guid>https://forem.com/stigsfoot/the-inputs-outputs-and-outcomes-of-product-strategy-39gm</guid>
      <description>&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.amazonaws.com%2Fi%2F424p28a3rqzzmay8e0mr.jpeg" 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.amazonaws.com%2Fi%2F424p28a3rqzzmay8e0mr.jpeg" alt="Photo by me #throughGlass at Google HQ Mountainview, CA" width="800" height="587"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://nobles.page/blog/the-inputs-outputs-outcomes-of-product-strategy/" rel="noopener noreferrer"&gt;Originally posted on my site&lt;/a&gt; and my &lt;a href="https://medium.com/@nobleackerson/the-inputs-outputs-and-outcomes-of-product-strategy-78eef52fbf0c" rel="noopener noreferrer"&gt;Medium page&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  In coaching a few startups I noticed that if your product’s inputs are garbage, the resulting outcomes are garbage, even if the outputs are polished. In this article, I’ll lay out a case for the path to a successful product:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;inputs, stewarded by an awesome research team;&lt;/li&gt;
&lt;li&gt;outputs, governed by a disciplined Agile team; and&lt;/li&gt;
&lt;li&gt;outcomes, lead by a mature product team&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;No, it’s not about outcomes over outputs dear product managers, it’s all three.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A healthy balance of all three means harmonized team behind a sustainable, repeatable, and successful product that consistently achieves its purpose.&lt;br&gt;
Recently I was carpooling with a colleague and she asked if I needed the “butt warmer” turned on. Not sure why that question stuck with me but I’ve always heard the temperature-controlled seats in some cars referred to as seat warmers.&lt;/p&gt;

&lt;p&gt;My mind wondering as my butt toasted: “There are two types of people in this world, people who refer to temperature-controlled seats as butt warmers and those who call it seat warmers”?&lt;/p&gt;

&lt;p&gt;That is, people who look at the feature as an output; I tweaked a knob and the seat got warm. vs people who look at the feature as an outcome; I pushed a button and the seat made my butt warm.&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.amazonaws.com%2Fi%2Fj77ug5bwxmpl32nkm3zj.jpeg" 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.amazonaws.com%2Fi%2Fj77ug5bwxmpl32nkm3zj.jpeg" alt="Image Credit: https://hackernoon.com/personal-experiences-with-agile-16-comments-pictures-and-a-video-about-practically-applying-agile-8bd710b0f6c3" width="600" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As your Startup or product gets mature, you may notice that the agile process starts breaking down. The knee jerk is to start optimizing for your development team's outputs. Your features keep missing deadlines, quality degrades, backlog grows. Naturally, you consider hiring specialists or a consultant to help optimize your outputs. These output focused specialists or “Agilists” as they call themselves are often well certified. They preach the gospel on how to improve your agile processes to fix the issues.&lt;/p&gt;

&lt;p&gt;Agilists are important to any growing organization. After all, these constants and Agile coaches are wired to help you optimize software development processes and outputs.&lt;/p&gt;

&lt;p&gt;All sorted, right?&lt;/p&gt;

&lt;p&gt;Wrong.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The resulting outputs-heavy focused organization, tend to miss that building a successful product is ⅓ of a balanced formula. A balanced formula harmonizes a collaborative, and iterative environment where the Business, Research, Development, and Product teams work hard together to repeat, review, and refine each stage of a product until you believe it will consistently achieve its purpose.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;While well-intentioned, the work of an Agilist, left unchecked, tends to overcorrect on team outputs and as I’ve seen over and over again in my career, the business steers away from its value engine by measuring the wrong metrics.&lt;/p&gt;

&lt;p&gt;Agile is now mainstream, and Agilists the bad ones, are a product of dark agile, a profit-driven agile industrial complex of project management experts who pivoted after product-driven companies deemed them redundant.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/G_y2pNj0zZg"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Caption: one of the original signers of the Agile Manifesto, Martin Fowler, talking about dogmatic Agilists force-feeding processes directly from the Agile Bible.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;When considering a shot of Agilists into your culture, remember, your organization doesn’t do Agile, you are agile, or perhaps, you never were.&lt;br&gt;
Should you hire a congregant of the “Church of Agile”, look for ones who have actually shipped a successful product. Ones with strong Product foundations that spend time to understand the culture, market, business, and technology.&lt;/p&gt;

&lt;p&gt;Outputs are important but do not overcorrect or else you miss the other two key principles of building a great product, Inputs, and Outcomes.&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.amazonaws.com%2Fi%2Fx5rq0qtml94wz1s217um.png" 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.amazonaws.com%2Fi%2Fx5rq0qtml94wz1s217um.png" alt="Image credit: https://medium.com/yoursproductly/5-what-jobs-to-be-done-jtbd-teaches-us-about-our-users-part-1-3-81b16d554e05" width="754" height="294"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What do I mean when I say Outcomes? Yes, Product Managers, I’m coming after you too. If you’re in the product leadership world, you’ve probably heard product experts proclaim &lt;a href="https://medium.com/@jefago/outcomes-over-outputs-the-long-term-challenge-b9366ffbc77f" rel="noopener noreferrer"&gt;Outcomes over Outputs!&lt;/a&gt; for many years.&lt;/p&gt;

&lt;p&gt;Yeah…um, no.&lt;/p&gt;

&lt;p&gt;Not entirely if you want to scale your business and product to sustain success. The reason over-optimizing for outcomes sucks is that over-optimizing your product Strategy skewed to changes in your Users’ behavior may drive a culture of User-centeredness however, if your developer practices (outputs) suck, you successfully ship to the right customer, but you risk missing the right product at the right time. Spoiler alert if you haven’t seen &lt;a href="https://www.ted.com/talks/bill_gross_the_single_biggest_reason_why_start_ups_succeed?language=en" rel="noopener noreferrer"&gt;Bill Gross’s TED talk on his successful portfolios&lt;/a&gt;: Timing, after all, is “the single reason why businesses/products succeed or fail.” So focus on Outcomes over Outputs all you want but if your team can’t ship, you fail.&lt;/p&gt;

&lt;p&gt;Your Inputs are also key. During my Startup days a few years ago, I published a post called &lt;a href="https://medium.com/founder-in-the-trenches/what-came-first-the-product-or-the-user-6e839b86fcb4" rel="noopener noreferrer"&gt;“What came first, the product or the user? Defining the User”&lt;/a&gt; in which I wrote: “a technology startup, without ongoing user research principles from its onset, is a hobby.”&lt;/p&gt;

&lt;p&gt;If your business leaders don’t think hard about prioritizing the market research, refining the intake of customer feedback, prioritizing and road mapping said feedback part of a holistic product strategy, you fail.&lt;br&gt;
Let me underscore this again if you don’t have a continuously refined set of inputs like a good roadmap, yeah, sure, the over-certified consultants can create a super-efficient scrum team but guess what, no one uses your product, and your marketing and sales apparatus underperforms because the market moved on.&lt;/p&gt;

&lt;p&gt;To my fellow product leaders, digital product strategy is hard. You don’t do agile and agile breaks down because of people, and processes that may not be for you. Products that consistently matter for your users have a balance of well-refined Inputs, well-timed Outputs, and measured and tuned Outcomes.&lt;/p&gt;

&lt;p&gt;Again:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Inputs are shepherded by a strong UX team, a mature research apparatus with constant outreach to Users/customers;&lt;/li&gt;
&lt;li&gt;Consistent outputs are governed through a disciplined engineering team that drives building the right product.&lt;/li&gt;
&lt;li&gt;Great outcomes are governed by mature product and business minds to feed the architectural runway to reduce technical debt and to guide a focus on the right inputs.
&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.amazonaws.com%2Fi%2F441eylb3ww6xinld2dm5.jpg" alt="Photo by me, Maui HI" width="800" height="534"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A good balance of all three, tempering each at the right moment in your product lifecycle. If your product’s inputs are garbage, the resulting outcomes are garbage, even if the outputs are polished. This is the confluence of a product your customers want and a healthy, happy, and productive business.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You have to stay close to your customers and understanding what and why.&lt;/li&gt;
&lt;li&gt;You have to be diligent with refining your roadmap&lt;/li&gt;
&lt;li&gt;Measure all the things. KPI’s FTW…against your goals, initiatives, and your outcomes.&lt;/li&gt;
&lt;li&gt;Focus on delivering solutions for real problems.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Doing all this helps you tweak the right knobs for your outcomes. This brings me back to the car seat thing. Are you a “butt-warmer” or a “seat-warmer” kind of person?&lt;/p&gt;

&lt;p&gt;Before you answer, know that the temperature-controlled seats in your vehicle work by controlling the input voltage you need and the output temperature to the seat and the outcome is what you, the User really care about so you don’t freeze your ass off at the right time of year.&lt;br&gt;
See also: &lt;a href="https://www.sciencedirect.com/science/article/abs/pii/S1359431106003073" rel="noopener noreferrer"&gt;How butt-seat-warmers-a-bobber’s work&lt;/a&gt; ~by Science Direct.&lt;/p&gt;

</description>
      <category>agile</category>
      <category>productmanagement</category>
      <category>ux</category>
      <category>agilemethodology</category>
    </item>
  </channel>
</rss>
