<?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: Batila Amulya</title>
    <description>The latest articles on DEV Community by Batila Amulya (@amulya631).</description>
    <link>https://dev.to/amulya631</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%2F3879897%2Fa5a21c97-ff0c-46f6-b172-25e1fb8f580c.jpeg</url>
      <title>DEV Community: Batila Amulya</title>
      <link>https://dev.to/amulya631</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/amulya631"/>
    <language>en</language>
    <item>
      <title>I built a macro tracker powered by AI + attitude</title>
      <dc:creator>Batila Amulya</dc:creator>
      <pubDate>Fri, 22 May 2026 11:10:58 +0000</pubDate>
      <link>https://dev.to/amulya631/i-built-a-macro-tracker-powered-by-ai-attitude-6j</link>
      <guid>https://dev.to/amulya631/i-built-a-macro-tracker-powered-by-ai-attitude-6j</guid>
      <description>&lt;p&gt;I built a macro tracker powered by AI + attitude. 🏋️&lt;/p&gt;

&lt;p&gt;Plan your macros in the morning. Check in once at night. Let Milo cheer you on or let Evil Vilo roast you.&lt;/p&gt;

&lt;p&gt;🚀 Live demo: &lt;a href="https://web-production-5c594.up.railway.app/" rel="noopener noreferrer"&gt;https://web-production-5c594.up.railway.app/&lt;/a&gt;&lt;br&gt;
📦 GitHub: &lt;a href="https://github.com/Amulya631/MacroDay" rel="noopener noreferrer"&gt;https://github.com/Amulya631/MacroDay&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Problem&lt;br&gt;
Most nutrition apps are reactive.&lt;br&gt;
You eat something, you log it, you feel guilty later. The friction of logging every meal throughout the day is exactly why people abandon these apps within a week — and the people who care most about macros (gym-goers chasing protein and fiber targets) are the ones who need a simple system, not a data-entry job.&lt;br&gt;
Old Way ❌MacroDay ✦ Log every meal, all daySet an intention in the morningReact to what you already ateMake smarter decisions all dayGuilt at 10pm when you're 40g short Confirm at night — no surprises&lt;/p&gt;

&lt;p&gt;The Solution: Planning-First, Not Logging-First&lt;br&gt;
Two touchpoints a day:&lt;/p&gt;

&lt;p&gt;Morning — Tell MacroDay what you're planning to eat. Get instant AI-powered macro analysis across all five macros (calories, protein, fiber, carbs, and fats). Add snacks to close gaps and watch the rings update live.&lt;br&gt;
Night. Confirm what you actually ate. Followed your plan? Quick tick-box list. Day went sideways? Enter your actual meals.&lt;/p&gt;

&lt;p&gt;You set an intention in the morning, which means better decisions all day, not just guilt at the end.&lt;/p&gt;

&lt;p&gt;Features&lt;/p&gt;

&lt;p&gt;🎯 5 animated SVG macro rings — real-time visual feedback for all five macros&lt;br&gt;
🧠 AI-powered analysis — Claude Haiku reads your meal descriptions and calculates macros, gaps, and smart snack suggestions&lt;br&gt;
⚡ Live snack updates — add a suggested snack and all five rings update instantly&lt;br&gt;
🎙️ Voice input — mic button on every meal field (Chrome, Web Speech API)&lt;br&gt;
🕐 Time-aware routing — the right screen for the time of day, automatically&lt;br&gt;
📋 Night check-in — Path A (tick-box) or Path B (full re-entry), with edge case handling&lt;br&gt;
📊 End-of-day summary — actual vs. target macro rings with celebration or encouragement&lt;br&gt;
🔄 Day rollover — history written to localStorage, today resets automatically&lt;br&gt;
😇😈 Milo vs. Evil Vilo — choose your mascot. One is warm and proud of you. The other will not be kind about your fiber intake.&lt;/p&gt;

&lt;p&gt;The Mascot System (a first-class feature)&lt;br&gt;
The mascot is not an afterthought. At profile setup, you pick your flavor. Both characters appear on every emotional moment — morning results, skipped meals, end-of-day summary, sleep screen.&lt;br&gt;
Milo (Good) 😇&lt;/p&gt;

&lt;p&gt;"Great job planning ahead your protein is solid, and you've got room for a great snack tonight!"&lt;/p&gt;

&lt;p&gt;Evil Vilo 😈&lt;/p&gt;

&lt;p&gt;"Embarrassing. You logged 'some chicken' and expect me to calculate your macros? Try again."&lt;/p&gt;

&lt;p&gt;Both are built from the same data — just radically different personalities. Vilo is a ragebait villain who will genuinely not be kind about your fiber intake.&lt;/p&gt;

&lt;p&gt;Tech Stack&lt;br&gt;
LayerTechNotesBackendPython · FastAPIServes frontend + APIFrontendVanilla HTML/CSS/JSNo framework neededAIClaude Haiku (claude-haiku-4-5-20251001)Single endpointStorageBrowser localStorageZero infraVoiceWeb Speech APIChrome onlyDeploymentRailway1 Procfile, 1 env var&lt;br&gt;
Single-service architecture — FastAPI serves both the static frontend and the /api/analyze endpoint from the same origin. No CORS complexity, no separate frontend deployment.&lt;/p&gt;

&lt;p&gt;How the AI Works&lt;br&gt;
All macro analysis runs through a single endpoint:&lt;br&gt;
POST /api/analyze&lt;br&gt;
The request includes:&lt;/p&gt;

&lt;p&gt;Meal descriptions (free text — "200g chicken breast, 150g rice")&lt;br&gt;
Daily macro targets from the user's profile&lt;br&gt;
Mode ("morning" or "night")&lt;br&gt;
Mascot preference ("milo" or "vilo")&lt;/p&gt;

&lt;p&gt;Claude returns structured JSON:&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="err"&gt;json&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"macros"&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;"calories"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1480&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"protein"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;112&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"fiber"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"carbs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;160&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"fats"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;38&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;"gaps"&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;"calories"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;520&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"protein"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;38&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"fiber"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;7&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;"feedback"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Your protein is on track but fiber is noticeably short..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"snack_suggestions"&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="s2"&gt;"Greek yogurt (200g) — +15g protein, +0g fiber"&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;"affirmation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Solid plan. Don't blow it at dinner."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"needs_clarification"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&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;Key Architecture Decisions&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;One endpoint, three modes
Rather than separate routes for morning analysis, night analysis, and snack recalculation, everything goes through POST /api/analyze with a mode field.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;One fetch wrapper on the frontend&lt;br&gt;
Prompt logic lives in one place&lt;br&gt;
Easier to tune Vilo's tone without hunting across multiple handlers&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Vague input detection at the prompt level
When a user types "some chicken", the app doesn't try to parse or validate before sending. Instead, the Claude prompt instructs the model to return needs_clarification: true if it can't calculate macros with reasonable confidence.
This is more robust than regex—Claude catches edge cases a rule-based validator would miss. "Food from the gym" is vague. "Leftover pasta" is ambiguous but probably workable.&lt;/li&gt;
&lt;li&gt;SVG rings over CSS conic gradients
stroke-dasharray / stroke-dashoffset on SVG circles gives precise control over fill percentage and animates cleanly with CSS transitions. Conic-gradient is simpler to write but harder to animate and has inconsistent cross-browser rendering for partial fills.
The SVG approach adds ~10 lines per ring but is rock-solid on every browser.&lt;/li&gt;
&lt;li&gt;localStorage over a backend database
For a personal-use demo with no auth requirement, localStorage is the right call. Zero infrastructure, zero latency, works offline, resets cleanly.
The data model is designed so that migrating to a real database later is straightforward—each key (macroday_profile, macroday_today, macroday_history) maps directly to what would be a user-scoped database record.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Project Structure&lt;br&gt;
MacroDay/&lt;br&gt;
├── main.py              # FastAPI app — serves frontend + API&lt;br&gt;
├── requirements.txt&lt;br&gt;
├── Procfile             # Railway deployment config&lt;br&gt;
├── static/&lt;br&gt;
│   ├── index.html       # Single-page app (all screens)&lt;br&gt;
│   ├── style.css        # Health/wellness UI styling&lt;br&gt;
│   ├── app.js           # Routing, profile, night check-in logic&lt;br&gt;
│   └── analyze.js       # API calls, ring rendering, snack logic&lt;br&gt;
├── assets/&lt;br&gt;
│   ├── Milo_Good.png&lt;br&gt;
│   └── Vilo_Evil.png&lt;br&gt;
└── docs/&lt;br&gt;
    ├── scope.md&lt;br&gt;
    ├── prd.md&lt;br&gt;
    └── spec.md&lt;/p&gt;

&lt;p&gt;Running Locally&lt;br&gt;
bash# 1. Clone&lt;br&gt;
git clone &lt;a href="https://github.com/Amulya631/MacroDay.git" rel="noopener noreferrer"&gt;https://github.com/Amulya631/MacroDay.git&lt;/a&gt;&lt;br&gt;
cd MacroDay&lt;/p&gt;

&lt;h1&gt;
  
  
  2. Install
&lt;/h1&gt;

&lt;p&gt;pip install -r requirements.txt&lt;/p&gt;

&lt;h1&gt;
  
  
  3. Set your API key
&lt;/h1&gt;

&lt;p&gt;echo "ANTHROPIC_API_KEY=your-key-here" &amp;gt; .env&lt;/p&gt;

&lt;h1&gt;
  
  
  4. Start
&lt;/h1&gt;

&lt;p&gt;uvicorn main:app --reload&lt;/p&gt;

&lt;h1&gt;
  
  
  5. Open &lt;a href="http://localhost:8000" rel="noopener noreferrer"&gt;http://localhost:8000&lt;/a&gt; in Chrome
&lt;/h1&gt;

&lt;p&gt;Get an Anthropic API key at console.anthropic.com.&lt;/p&gt;

&lt;p&gt;What's Next (v2 Ideas)&lt;/p&gt;

&lt;p&gt;📸 Photo macro analysis—photograph a meal, AI estimates macros from the image&lt;br&gt;
🔔 Push notifications — morning reminder at 8am, night reminder at 8pm&lt;br&gt;
📈 Multi-day insights—"You've been low on fiber all week."&lt;br&gt;
💪 Post-workout mode — dedicated high-protein suggestion flow&lt;/p&gt;

&lt;p&gt;Try It&lt;/p&gt;

&lt;p&gt;🚀 Live demo: &lt;a href="https://web-production-5c594.up.railway.app/" rel="noopener noreferrer"&gt;https://web-production-5c594.up.railway.app/&lt;/a&gt;&lt;br&gt;
⭐ GitHub: &lt;a href="https://github.com/Amulya631/MacroDay" rel="noopener noreferrer"&gt;https://github.com/Amulya631/MacroDay&lt;/a&gt;&lt;br&gt;
🛠️ Built with: Claude Code · Anthropic&lt;/p&gt;

&lt;p&gt;If you're a gym-goer who's ever abandoned a nutrition app because it felt like a second job — this one's for you. Give it a try, star the repo, or open an issue if you have ideas.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>python</category>
      <category>hackathon</category>
      <category>vibecoding</category>
    </item>
    <item>
      <title>ResearchMind — AI Research Pipeline with Cross-Session Memory | Backboard Challenges 2026</title>
      <dc:creator>Batila Amulya</dc:creator>
      <pubDate>Fri, 22 May 2026 10:43:40 +0000</pubDate>
      <link>https://dev.to/amulya631/researchmind-ai-research-pipeline-with-cross-session-memory-backboard-challenges-2026-4beh</link>
      <guid>https://dev.to/amulya631/researchmind-ai-research-pipeline-with-cross-session-memory-backboard-challenges-2026-4beh</guid>
      <description>&lt;h1&gt;
  
  
  I Built a Multi-Agent AI Research Pipeline in 2 Days — Here's Every Error I Hit
&lt;/h1&gt;

&lt;p&gt;I just submitted ResearchMind to the Backboard Challenges Hackathon. This is the honest build log — what I built, how it works, and the 11 errors that almost stopped me.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Is ResearchMind?
&lt;/h2&gt;

&lt;p&gt;Type a research topic. Three AI agents collaborate and produce a polished academic research brief with real APA citations. Download it as a PDF. Come back next week — it remembers everything you've researched.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Live:&lt;/strong&gt; &lt;a href="https://researchmind-production-04c7.up.railway.app" rel="noopener noreferrer"&gt;https://researchmind-production-04c7.up.railway.app&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/Amulya631/ResearchMind" rel="noopener noreferrer"&gt;https://github.com/Amulya631/ResearchMind&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  The Architecture
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Input Topic
    │
    ▼
┌─────────────────────────────────────┐
│  Stage 1 — Planner (Gemini Flash)   │
│  Reads memory → generates subtasks  │
└──────────────────┬──────────────────┘
                   │
    ▼
┌─────────────────────────────────────┐
│  Stage 2 — Summarizer (Gemini Flash)│
│  5–8 APA-cited facts per subtask    │
└──────────────────┬──────────────────┘
                   │
    ▼
┌─────────────────────────────────────┐
│  Stage 3 — Synthesizer (Claude Haiku│
│  Polished brief + References section│
└──────────────────┬──────────────────┘
                   │
    ▼
  Saved to Backboard Cross-Session Memory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Backboard Features Used
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Multi-assistant architecture&lt;/strong&gt; — 3 permanent assistants with distinct system prompts&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-model routing&lt;/strong&gt; — Gemini 2.5 Flash for speed, Claude Haiku for synthesis quality&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Persistent memory&lt;/strong&gt; — &lt;code&gt;client.add_memory()&lt;/code&gt; stores conclusions after every session&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cross-thread memory recall&lt;/strong&gt; — &lt;code&gt;memory="Auto"&lt;/code&gt; on &lt;code&gt;add_message()&lt;/code&gt; triggers automatic recall&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  The Tech Stack
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Backboard SDK v1.5.13
Streamlit 1.32
Google Gemini 2.5 Flash
Anthropic Claude Haiku
fpdf2 (PDF generation)
Railway (deployment)
Python 3.12
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  11 Errors I Hit (And Fixed)
&lt;/h2&gt;

&lt;p&gt;The hackathon guide was written for an older SDK version. Here's every error I encountered:&lt;/p&gt;
&lt;h3&gt;
  
  
  Error 1 — &lt;code&gt;streamlit: command not recognized&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Windows PATH issue. Fix: &lt;code&gt;python -m streamlit run app.py&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Error 2 — &lt;code&gt;'dict' object has no attribute 'role'&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;SDK v1.5.13 returns messages as dicts, not objects.&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;# Wrong
&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;role&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;
&lt;span class="c1"&gt;# Right
&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&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;h3&gt;
  
  
  Error 3 — Documents still being indexed
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;asyncio.sleep(3)&lt;/code&gt; was too short. Fixed with a polling loop.&lt;/p&gt;

&lt;h3&gt;
  
  
  Error 4 — BackboardServerError on every Synthesizer call
&lt;/h3&gt;

&lt;p&gt;6 stuck documents from test runs overloading the RAG system. &lt;code&gt;delete_assistant_document()&lt;/code&gt; doesn't exist in v1.5.13. Solution: deleted and recreated the assistant, then switched to inline content passing instead of document upload.&lt;/p&gt;

&lt;h3&gt;
  
  
  Error 5 — &lt;code&gt;NameError: tmp_path not defined&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Orphaned &lt;code&gt;os.unlink(tmp_path)&lt;/code&gt; left after removing the upload block.&lt;/p&gt;

&lt;h3&gt;
  
  
  Error 6 — Invisible input text
&lt;/h3&gt;

&lt;p&gt;CSS specificity conflict with Streamlit's internal theme. Fixed with &lt;code&gt;!important&lt;/code&gt; and solid background colors.&lt;/p&gt;

&lt;h3&gt;
  
  
  Error 7 — &lt;code&gt;SyntaxError: unterminated string literal&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Apostrophe in &lt;code&gt;you've&lt;/code&gt; inside a single-quoted Python string.&lt;/p&gt;

&lt;h3&gt;
  
  
  Error 8 — &lt;code&gt;assistants.py --update&lt;/code&gt; crash
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;force_update=True&lt;/code&gt; was applied to the Planner even though its prompt hadn't changed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Error 9 — &lt;code&gt;FPDFUnicodeEncodingException&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Em dash &lt;code&gt;—&lt;/code&gt; outside Helvetica's Latin-1 range. Fixed with a &lt;code&gt;clean()&lt;/code&gt; function that maps Unicode to ASCII equivalents.&lt;/p&gt;

&lt;h3&gt;
  
  
  Error 10 — &lt;code&gt;FPDFException: Not enough horizontal space&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;20mm margins were too wide on Railway's environment. Reduced to 10mm, added dynamic line coordinates, and a &lt;code&gt;safe_write()&lt;/code&gt; helper that catches individual line errors.&lt;/p&gt;

&lt;h3&gt;
  
  
  Error 11 — Topic chip wrapping to two lines
&lt;/h3&gt;

&lt;p&gt;Double-width emoji &lt;code&gt;⚛️&lt;/code&gt; (U+269B + U+FE0F variation selector) consuming full column width. Replaced with single-width &lt;code&gt;⚛&lt;/code&gt; and restructured to a 3+2 chip layout.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Feature That Makes It Different
&lt;/h2&gt;

&lt;p&gt;The cross-session memory is what separates this from a standard chatbot.&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;await&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_memory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;assistant_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;planner_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&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;Completed research on: &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&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;Subtasks covered: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;, &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;subtasks&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&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;Key conclusions: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;brief&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;600&lt;/span&gt;&lt;span class="p"&gt;]&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="n"&gt;metadata&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;topic&lt;/span&gt;&lt;span class="sh"&gt;"&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&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;research_session&lt;/span&gt;&lt;span class="sh"&gt;"&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;Next session, &lt;code&gt;memory="Auto"&lt;/code&gt; on &lt;code&gt;add_message()&lt;/code&gt; automatically retrieves this — and the Planner's system prompt tells it to skip already-covered subtasks. Knowledge compounds over time instead of starting from zero every run.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I'd Do Differently
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Skip document upload entirely from day one inline content passing is more reliable&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;python -m py_compile app.py&lt;/code&gt; after every change on Windows&lt;/li&gt;
&lt;li&gt;Test on the deployment environment early PDF rendering behaved differently on Railway vs local&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;

&lt;p&gt;🚀 &lt;strong&gt;Live:&lt;/strong&gt; &lt;a href="https://researchmind-production-04c7.up.railway.app" rel="noopener noreferrer"&gt;https://researchmind-production-04c7.up.railway.app&lt;/a&gt;&lt;br&gt;&lt;br&gt;
💻 &lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/Amulya631/ResearchMind" rel="noopener noreferrer"&gt;https://github.com/Amulya631/ResearchMind&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Feedback is welcome! especially if you're also building on Backboard.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Built by Batila Amulya—GCP Cloud Engineer &amp;amp; Gen AI enthusiast&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  python #ai #hackathon #buildinpublic #streamlit #llm #multiagent
&lt;/h1&gt;

</description>
      <category>ai</category>
      <category>python</category>
      <category>hackathon</category>
      <category>devjournal</category>
    </item>
    <item>
      <title>For my hackathon submission I asked: what if you never had to open a calendar, task manager, or notes app again? NEXUS is my answer. Full breakdown inside 👇</title>
      <dc:creator>Batila Amulya</dc:creator>
      <pubDate>Wed, 15 Apr 2026 07:27:15 +0000</pubDate>
      <link>https://dev.to/amulya631/for-my-hackathon-submission-i-asked-what-if-you-never-had-to-open-a-calendar-task-manager-or-24m1</link>
      <guid>https://dev.to/amulya631/for-my-hackathon-submission-i-asked-what-if-you-never-had-to-open-a-calendar-task-manager-or-24m1</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/amulya631/building-nexus-how-i-architected-a-multi-agent-ai-system-on-google-cloud-in-48-hours-13n" class="crayons-story__hidden-navigation-link"&gt;Building NEXUS: How I Architected a Multi-Agent AI System on Google Cloud in 48 Hours&lt;/a&gt;
    &lt;div class="crayons-article__cover crayons-article__cover__image__feed"&gt;
      &lt;iframe src="https://www.youtube.com/embed/WdAybc3MevM" title="Building NEXUS: How I Architected a Multi-Agent AI System on Google Cloud in 48 Hours"&gt;&lt;/iframe&gt;
    &lt;/div&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/amulya631" class="crayons-avatar  crayons-avatar--l  "&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%2Fuser%2Fprofile_image%2F3879897%2Fa5a21c97-ff0c-46f6-b172-25e1fb8f580c.jpeg" alt="amulya631 profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/amulya631" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Batila Amulya
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Batila Amulya
                
              
              &lt;div id="story-author-preview-content-3503372" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/amulya631" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&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%2Fuser%2Fprofile_image%2F3879897%2Fa5a21c97-ff0c-46f6-b172-25e1fb8f580c.jpeg" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Batila Amulya&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/amulya631/building-nexus-how-i-architected-a-multi-agent-ai-system-on-google-cloud-in-48-hours-13n" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Apr 15&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/amulya631/building-nexus-how-i-architected-a-multi-agent-ai-system-on-google-cloud-in-48-hours-13n" id="article-link-3503372"&gt;
          Building NEXUS: How I Architected a Multi-Agent AI System on Google Cloud in 48 Hours
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/ai"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;ai&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/googlecloud"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;googlecloud&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/machinelearning"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;machinelearning&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/hackathon"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;hackathon&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/amulya631/building-nexus-how-i-architected-a-multi-agent-ai-system-on-google-cloud-in-48-hours-13n" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/raised-hands-74b2099fd66a39f2d7eed9305ee0f4553df0eb7b4f11b01b6b1b499973048fe5.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;1&lt;span class="hidden s:inline"&gt; reaction&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/amulya631/building-nexus-how-i-architected-a-multi-agent-ai-system-on-google-cloud-in-48-hours-13n#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              2&lt;span class="hidden s:inline"&gt; comments&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            3 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
    </item>
    <item>
      <title>Building NEXUS: How I Architected a Multi-Agent AI System on Google Cloud in 48 Hours</title>
      <dc:creator>Batila Amulya</dc:creator>
      <pubDate>Wed, 15 Apr 2026 07:14:09 +0000</pubDate>
      <link>https://dev.to/amulya631/building-nexus-how-i-architected-a-multi-agent-ai-system-on-google-cloud-in-48-hours-13n</link>
      <guid>https://dev.to/amulya631/building-nexus-how-i-architected-a-multi-agent-ai-system-on-google-cloud-in-48-hours-13n</guid>
      <description>&lt;p&gt;`One sentence. Four AI agents. Real results — in under 4 seconds. Here's everything I learned building NEXUS for the Gen AI Academy APAC Edition hackathon.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem I wanted to solve
&lt;/h2&gt;

&lt;p&gt;How many apps do you open on a typical workday just to stay organized? Calendar. Task manager. Notes app. Each one lives in its own silo, and switching between them adds up to a surprising amount of mental overhead.&lt;/p&gt;

&lt;p&gt;I wanted to build something different — a single conversational interface where you say what you need to do, and the system figures out the rest. Not a chatbot that gives you a list of suggestions. An actual agent that &lt;em&gt;acts&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;That idea became &lt;strong&gt;NEXUS&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;NEXUS is a fully deployed multi-agent AI system on Google Cloud Platform. You send one natural language request, and NEXUS automatically coordinates specialized AI agents to complete complex workflows — simultaneously.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What NEXUS actually does
&lt;/h2&gt;

&lt;p&gt;Here's a quick example. You send:&lt;/p&gt;

&lt;p&gt;"Schedule a team meeting tomorrow and create a task to prepare the agenda."&lt;/p&gt;

&lt;p&gt;Within 4 seconds, two things happen in parallel:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ChronoBot creates event &lt;code&gt;EVT-EACD61F3&lt;/code&gt; in Firestore&lt;/li&gt;
&lt;li&gt;TaskMind creates task &lt;code&gt;TASK-462C3D6C&lt;/code&gt; in Firestore&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No manual switching. No separate apps. One message, multiple agents, real results.&lt;/p&gt;

&lt;h2&gt;
  
  
  Meet the agent network
&lt;/h2&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%2Fe92svl2pv5dgg4hy4drl.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.amazonaws.com%2Fuploads%2Farticles%2Fe92svl2pv5dgg4hy4drl.jpg" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The architecture: how it all fits together
&lt;/h2&gt;

&lt;p&gt;The core insight behind NEXUS is that routing intelligence should live in the AI, not in the code. The orchestrator sends your message to Gemini 2.5 Flash, which returns a JSON routing plan:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;json&lt;br&gt;
{"agents": ["calendar", "tasks"], "plan": "Schedule meeting using calendar agent, then create prep task."}&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The relevant agents are called in parallel — each an independent Cloud Run service. They write to Firestore and return structured results back to the orchestrator.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;plaintext&lt;br&gt;
User message&lt;br&gt;
  → NEXUS Core (Cloud Run + Gemini 2.5 Flash)&lt;br&gt;
      → Dynamic routing to ChronoBot / TaskMind / MemoryVault&lt;br&gt;
          → Firestore (5 collections)&lt;br&gt;
              → Structured response with agent IDs + execution trace&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Google Cloud Platform?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cloud Run&lt;/strong&gt; — Each agent scales to zero. No cost when idle, instant burst when needed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Firestore (Native mode)&lt;/strong&gt; — Schemaless and real-time. No schema migrations during a 48-hour build.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gemini 2.5 Flash&lt;/strong&gt; — Sub-second JSON responses at ~$0.000125 per request.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cloud Pub/Sub&lt;/strong&gt; — Async agent messaging. Decouples agents for future event-driven scaling.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Secret Manager&lt;/strong&gt; — Zero hardcoded credentials. Non-negotiable for anything touching APIs.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What made this genuinely hard
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Dynamic routing vs hardcoded logic.&lt;/strong&gt; The temptation was to write explicit routing rules. I pushed back on that—trusting Gemini to classify intent and return a structured JSON plan is far more robust and extensible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Keeping agents truly independent.&lt;/strong&gt; Strict API contracts, no shared state except through Firestore. Tedious to maintain, but it means I can add a new agent without touching existing code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;IAM and least privilege.&lt;/strong&gt; The service account uses exactly 8 roles. Getting this right during a hackathon is easy to skip; I'm glad I didn't.&lt;/p&gt;

&lt;h1&gt;
  
  
  Try it yourself
&lt;/h1&gt;

&lt;p&gt;NEXUS is fully deployed and live:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;shell&lt;br&gt;
curl -X POST "https://nexus-orchestrator-yqumqe2gtq-uc.a.run.app/query" \&lt;br&gt;
  -H "Content-Type: application/json" \&lt;br&gt;
  -d '{"message": "Remind me to follow up with the team on Friday"}'&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Live demo:&lt;/strong&gt; &lt;a href="https://nexus-frontend-yqumqe2gtq-uc.a.run.app" rel="noopener noreferrer"&gt;https://nexus-frontend-yqumqe2gtq-uc.a.run.app&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/Amulya631/Nexus_Agent" rel="noopener noreferrer"&gt;https://github.com/Amulya631/Nexus_Agent&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What I'd build next
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;An email agent—draft a follow-up and schedule a reminder in one go&lt;/li&gt;
&lt;li&gt;Agent-to-agent communication via Pub/Sub&lt;/li&gt;
&lt;li&gt;A memory-aware orchestrator that learns your preferences over time&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Closing thoughts
&lt;/h2&gt;

&lt;p&gt;Building NEXUS taught me that the hardest part of a multi-agent system isn't the individual agents — it's the orchestration layer. Getting the routing right, keeping agents independent, and building proper observability is where the real engineering lives.&lt;/p&gt;

&lt;p&gt;If you're building something similar or have questions about the GCP architecture, drop a comment or find me on GitHub!&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Built for the Gen AI Academy APAC Edition — Google Cloud × H2S. Track: Multi-Agent AI Systems.&lt;/em&gt;`&lt;/p&gt;

</description>
      <category>ai</category>
      <category>googlecloud</category>
      <category>machinelearning</category>
      <category>hackathon</category>
    </item>
  </channel>
</rss>
