<?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: Prema Ananda</title>
    <description>The latest articles on DEV Community by Prema Ananda (@prema_ananda).</description>
    <link>https://dev.to/prema_ananda</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%2F3203633%2Fd35ed6f5-9b36-4268-aafb-17660b97308e.png</url>
      <title>DEV Community: Prema Ananda</title>
      <link>https://dev.to/prema_ananda</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/prema_ananda"/>
    <language>en</language>
    <item>
      <title>ReSpawning Intelligence: How I Plugged OpenClaw into a Minecraft World</title>
      <dc:creator>Prema Ananda</dc:creator>
      <pubDate>Fri, 24 Apr 2026 07:30:46 +0000</pubDate>
      <link>https://dev.to/prema_ananda/giving-openclaw-a-body-how-i-turned-an-ai-agent-into-a-minecraft-survival-expert-48cc</link>
      <guid>https://dev.to/prema_ananda/giving-openclaw-a-body-how-i-turned-an-ai-agent-into-a-minecraft-survival-expert-48cc</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/openclaw-2026-04-16"&gt;OpenClaw Challenge&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;I built &lt;strong&gt;ClawCraft-bot&lt;/strong&gt; — a bridge application that gives OpenClaw an avatar inside a Minecraft world.&lt;/p&gt;

&lt;p&gt;Instead of just chatting or processing text, OpenClaw can now perceive a three-dimensional environment, gather resources, craft tools, navigate complex terrain, and even defend players against hostile mobs in real time. The bot acts as an independent agent running through a local HTTP API, translating OpenClaw's high-level reasoning into precise in-game actions.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Used OpenClaw
&lt;/h2&gt;

&lt;p&gt;OpenClaw serves as the "brain" of the entire operation, making strategic decisions, while ClawCraft-bot acts as the "nervous system."&lt;/p&gt;

&lt;h3&gt;
  
  
  The Tech Stack &amp;amp; Environment
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Launcher:&lt;/strong&gt; SKLauncher 3.2.18 (Offline mode)&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Minecraft Version:&lt;/strong&gt; Java Edition 1.21.11&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Bridge API:&lt;/strong&gt; Node.js + Express.js&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Bot Engine:&lt;/strong&gt; &lt;a href="https://github.com/PrismarineJS/mineflayer" rel="noopener noreferrer"&gt;Mineflayer&lt;/a&gt; + pathfinder, pvp, collectblock&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The system runs on a local Minecraft world. One important detail: after launching the game, you need to open the world to the network (Open to LAN) on port &lt;strong&gt;25565&lt;/strong&gt; (default) so the Bridge API can connect the bot to your game session.&lt;/p&gt;




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

&lt;p&gt;The system is built around a simple principle: &lt;strong&gt;the LLM is the brain, the bot is the body&lt;/strong&gt;. OpenClaw reasons and decides; ClawCraft-bot perceives and acts. They communicate through a thin HTTP layer, which means the agent never touches Mineflayer directly — and Mineflayer never needs to know anything about LLMs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Five layers, one direction
&lt;/h3&gt;

&lt;p&gt;The codebase is organized into five layers, each knowing only about the one below it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SKILL.md          ← Layer 5: instructions OpenClaw reads to understand the API
bridge-api.js     ← Layer 4: Express HTTP server, the contract between LLM and bot
actions/          ← Layer 3: six modules split by responsibility
plugins.js        ← Layer 2: pathfinder, pvp, collectblock, tool
bot-core.js       ← Layer 1: Mineflayer lifecycle and auto-reconnect
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This separation means you can swap out the LLM integration entirely — replace OpenClaw with any HTTP client — without touching a single line of game logic. Conversely, upgrading the Mineflayer version or adding a new plugin stays contained in Layers 1–2.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Layer 3 (&lt;code&gt;actions/&lt;/code&gt;)&lt;/strong&gt; is where most of the domain logic lives, split into focused modules: &lt;code&gt;info&lt;/code&gt; for reading game state, &lt;code&gt;navigation&lt;/code&gt; for movement, &lt;code&gt;chat&lt;/code&gt; for communication, &lt;code&gt;world&lt;/code&gt; for block interaction, &lt;code&gt;combat&lt;/code&gt; for fighting and protection, and &lt;code&gt;items&lt;/code&gt; for inventory and crafting. An &lt;code&gt;index.js&lt;/code&gt; registry routes incoming API calls to the right module.&lt;/p&gt;
&lt;h3&gt;
  
  
  The bridge API
&lt;/h3&gt;

&lt;p&gt;The HTTP API listens on &lt;code&gt;127.0.0.1:3001&lt;/code&gt; — localhost only, by design. This isn't an oversight; it's a deliberate security boundary. An LLM that can issue &lt;code&gt;/actions/attack&lt;/code&gt; or &lt;code&gt;/actions/collect&lt;/code&gt; shouldn't be exposed to the network.&lt;/p&gt;

&lt;p&gt;The API is split into two kinds of endpoints:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Read endpoints (GET):&lt;/strong&gt; &lt;code&gt;/status&lt;/code&gt;, &lt;code&gt;/inventory&lt;/code&gt;, &lt;code&gt;/nearby&lt;/code&gt;, &lt;code&gt;/scan-blocks&lt;/code&gt;, &lt;code&gt;/findblock&lt;/code&gt; — these return immediately and can be called at any time. OpenClaw uses them to build a picture of the world before deciding what to do next.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Action endpoints (POST):&lt;/strong&gt; &lt;code&gt;/actions/goto&lt;/code&gt;, &lt;code&gt;/actions/collect&lt;/code&gt;, &lt;code&gt;/actions/craft&lt;/code&gt;, etc. — these start a job and return a &lt;code&gt;jobId&lt;/code&gt; immediately, without waiting for the action to complete.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Why a job queue?
&lt;/h3&gt;

&lt;p&gt;This is the most important architectural decision in the project, and it's worth explaining explicitly.&lt;/p&gt;

&lt;p&gt;Minecraft actions are not instantaneous. Navigating to a location takes several seconds. Mining a stack of wood takes longer. If a POST request blocked until the action finished, the LLM would be left hanging — and more importantly, a second command arriving mid-navigation would conflict with the first, causing pathfinder to fight itself.&lt;/p&gt;

&lt;p&gt;The solution is a &lt;strong&gt;serial job queue&lt;/strong&gt;: every action is enqueued and executed one at a time. A POST to &lt;code&gt;/actions/collect&lt;/code&gt; returns immediately:&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="nl"&gt;"jobId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"a3f9..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"pending"&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;OpenClaw then polls &lt;code&gt;/jobs/a3f9...&lt;/code&gt; until the status becomes &lt;code&gt;done&lt;/code&gt; or &lt;code&gt;failed&lt;/code&gt;. While waiting, it's free to call read endpoints — checking health, scanning for threats, updating its world model. The queue prevents conflicts without requiring locks or complex concurrency primitives.&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%2Fuploads%2Farticles%2Fediekje8kafi761y6x0g.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%2Fediekje8kafi761y6x0g.png" alt="Architecture diagram" width="800" height="563"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The diagram above shows the full request lifecycle: OpenClaw reads world state, decides on an action, posts it to the bridge, receives a jobId, and polls for completion while the bot executes in-game.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  What SKILL.md does
&lt;/h3&gt;

&lt;p&gt;The final layer is &lt;code&gt;SKILL.md&lt;/code&gt; — a plain text file that serves as the API contract for the LLM. It describes every endpoint, its parameters, and the expected response shape. It also encodes behavioral rules that can't be enforced in code: things like "always put away your tool before eating" or "check &lt;code&gt;/status&lt;/code&gt; before starting a long task."&lt;/p&gt;


&lt;h2&gt;
  
  
  Setup
&lt;/h2&gt;
&lt;h3&gt;
  
  
  1. Launch Minecraft
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Use &lt;strong&gt;SKLauncher&lt;/strong&gt; (or any other launcher) to start Minecraft Java Edition &lt;strong&gt;1.21.11&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Load a world and select &lt;strong&gt;"Open to LAN"&lt;/strong&gt; on port &lt;strong&gt;25565&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  2. Install ClawCraft-bot
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/premananda108/ClawCraft-bot.git
&lt;span class="nb"&gt;cd &lt;/span&gt;ClawCraft-bot
npm &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;span class="c"&gt;# Edit .env if needed (specify the port from MC)&lt;/span&gt;
npm start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  3. Configure OpenClaw
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Install &lt;strong&gt;OpenClaw&lt;/strong&gt; by following its &lt;a href="https://github.com/openclaw/openclaw" rel="noopener noreferrer"&gt;official documentation&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Create a new &lt;strong&gt;Skill&lt;/strong&gt; in OpenClaw. As the skill instructions, simply provide your agent with the contents of the &lt;code&gt;SKILL.md&lt;/code&gt; file from this repository. It contains all the necessary behavior rules and API descriptions for the AI.&lt;/li&gt;
&lt;/ol&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%2Fo4tnbhap4yr7tienm576.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%2Fo4tnbhap4yr7tienm576.jpg" alt="Setup name" width="800" height="489"&gt;&lt;/a&gt;&lt;br&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%2Fqcbhn5fy67t10lon34zw.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%2Fqcbhn5fy67t10lon34zw.jpg" alt="Create skill" width="800" height="438"&gt;&lt;/a&gt;&lt;br&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%2Fmjyv8m8va4j8jefgkumq.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%2Fmjyv8m8va4j8jefgkumq.jpg" alt="First time in game" width="800" height="489"&gt;&lt;/a&gt;&lt;br&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%2Fs3lsfbsnp4bnzb4jlu9f.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%2Fs3lsfbsnp4bnzb4jlu9f.jpg" alt="Message in chat" width="800" height="466"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Intelligence &amp;amp; LLM Efficiency
&lt;/h2&gt;

&lt;p&gt;One of the key features of the project is the use of a detailed &lt;strong&gt;SKILL.md&lt;/strong&gt; file. This allowed me to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Lower model requirements:&lt;/strong&gt; Thanks to clear instructions and API descriptions in the SKILL file, the bot can be controlled even by inexpensive or local LLMs.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Optimize costs:&lt;/strong&gt; Minecraft involves a very high number of "check-act" cycles. Using local models (via Ollama or similar tools) lets you run the bot for hours without burning through expensive API tokens.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Demo
&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%2Fyq0qq49f7cts7ui5n732.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%2Fyq0qq49f7cts7ui5n732.jpg" alt="ClawBot exploring the world" width="753" height="587"&gt;&lt;/a&gt;&lt;br&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%2Fyxk15qky3iq1g05rn2j9.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%2Fyxk15qky3iq1g05rn2j9.jpg" alt="ClawBot inventory and status" width="732" height="591"&gt;&lt;/a&gt;&lt;br&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%2Fm7yyi1roqpd8yw6xueix.gif" 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%2Fm7yyi1roqpd8yw6xueix.gif" alt="Mining wood" width="600" height="450"&gt;&lt;/a&gt;&lt;br&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%2F5b3szj8qe6h6crrwiw2g.gif" 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%2F5b3szj8qe6h6crrwiw2g.gif" alt="Check attack modeon" width="560" height="420"&gt;&lt;/a&gt;&lt;br&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%2Fvwchxq04kjacjrlquu4q.gif" 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%2Fvwchxq04kjacjrlquu4q.gif" alt="Build" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/premananda108" rel="noopener noreferrer"&gt;
        premananda108
      &lt;/a&gt; / &lt;a href="https://github.com/premananda108/ClawCraft-bot" rel="noopener noreferrer"&gt;
        ClawCraft-bot
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      OpenClaw-powered Minecraft bot that mines, crafts, navigates, and fights — all driven by LLM decisions through a local HTTP API.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;ClawCraft-bot&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;Secure Minecraft bot with a high-level API for control via OpenClaw.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Quick Start&lt;/h2&gt;
&lt;/div&gt;

&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; 1. Installation&lt;/span&gt;
npm install

&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; 2. Setup (copy and edit)&lt;/span&gt;
cp .env.example .env
&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; Edit .env: MC_HOST, MC_PORT, MC_USERNAME&lt;/span&gt;

&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; 3. Run&lt;/span&gt;
npm start&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;API&lt;/h2&gt;

&lt;/div&gt;

&lt;p&gt;Bridge API is available at &lt;code&gt;http://127.0.0.1:3001&lt;/code&gt; (default).&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Read Data (GET)&lt;/h3&gt;

&lt;/div&gt;

&lt;p&gt;&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;br&gt;
&lt;thead&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;th&gt;Endpoint&lt;/th&gt;
&lt;br&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;/thead&gt;
&lt;br&gt;
&lt;tbody&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;&lt;code&gt;/health&lt;/code&gt;&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;Bridge status (always available)&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;&lt;code&gt;/status&lt;/code&gt;&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;Health, food, position, gameMode&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;&lt;code&gt;/position&lt;/code&gt;&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;Bot coordinates&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;&lt;code&gt;/inventory&lt;/code&gt;&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;Items in inventory&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;&lt;code&gt;/nearby?radius=32&lt;/code&gt;&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;Nearby entities (default radius 32)&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;&lt;code&gt;/scan-blocks?radius=8&lt;/code&gt;&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;Scan nearby blocks (default radius 8)&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;&lt;code&gt;/findblock?name=oak_log&amp;amp;maxDistance=32&lt;/code&gt;&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;Find specific block by name&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;/tbody&gt;
&lt;br&gt;
&lt;/table&gt;&lt;/div&gt;&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Actions (POST)&lt;/h3&gt;

&lt;/div&gt;

&lt;p&gt;&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;br&gt;
&lt;thead&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;th&gt;Endpoint&lt;/th&gt;
&lt;br&gt;
&lt;th&gt;Body&lt;/th&gt;
&lt;br&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;/thead&gt;
&lt;br&gt;
&lt;tbody&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;&lt;code&gt;/actions/goto&lt;/code&gt;&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;&lt;code&gt;{ x, y, z }&lt;/code&gt;&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;Navigate to coordinates&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;&lt;code&gt;/actions/follow&lt;/code&gt;&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;&lt;code&gt;{ player, distance? }&lt;/code&gt;&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;Follow a player&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;&lt;code&gt;/actions/chat&lt;/code&gt;&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;&lt;code&gt;{ message }&lt;/code&gt;&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;Send message to global chat&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;&lt;code&gt;/actions/whisper&lt;/code&gt;&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;&lt;code&gt;{ player, message }&lt;/code&gt;&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;Send private message&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;&lt;code&gt;/actions/stop&lt;/code&gt;&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;Stop everything (tasks and movement)&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;&lt;code&gt;/actions/dig&lt;/code&gt;&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;
&lt;br&gt;
&lt;code&gt;{ name }&lt;/code&gt; or &lt;code&gt;{ x, y, z }&lt;/code&gt;&lt;br&gt;
&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;Dig block (by name or coordinates)&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;/tbody&gt;
&lt;br&gt;
&lt;/table&gt;&lt;/div&gt;…&lt;/p&gt;
&lt;/div&gt;
&lt;br&gt;
  &lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/premananda108/ClawCraft-bot" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;h2&gt;
  
  
  What I Learned
&lt;/h2&gt;

&lt;p&gt;Building a bridge between an LLM and a real-time game engine turned out to be full of hidden pitfalls:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Visualization traps:&lt;/strong&gt; I originally planned to use &lt;code&gt;prismarine-viewer&lt;/code&gt; to stream a video feed. However, it turned out to work incorrectly with Minecraft Java 1.21.11. In the end, I decided to drop visualization from the final build in favor of control stability.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;LLMs need strict feedback loops:&lt;/strong&gt; Initially, the AI would try to eat food while holding a pickaxe. I had to explicitly write into &lt;code&gt;SKILL.md&lt;/code&gt; that a tool must be put away before eating. Designing an API for AI is a balancing act between flexibility and hard rules.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Lifecycle chaos:&lt;/strong&gt; Minecraft bots sometimes die. I learned that handling automatic respawns requires strict event decoupling — otherwise the system starts injecting multiple pathfinding plugins into the same bot instance, leading to massive memory leaks.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  ClawCon Michigan
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Unfortunately, I wasn't able to attend ClawCon Michigan this time around, but it's wonderful to see the OpenClaw community growing and building incredible things!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>openclawchallenge</category>
    </item>
    <item>
      <title>Battle of LLM Agents: WhiteHat vs BlueHat on OpenClaw</title>
      <dc:creator>Prema Ananda</dc:creator>
      <pubDate>Sun, 19 Apr 2026 09:57:11 +0000</pubDate>
      <link>https://dev.to/prema_ananda/battle-of-llm-agents-whitehat-vs-bluehat-on-openclaw-3fpg</link>
      <guid>https://dev.to/prema_ananda/battle-of-llm-agents-whitehat-vs-bluehat-on-openclaw-3fpg</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/openclaw-2026-04-16"&gt;OpenClaw Writing Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In Part 1, I described how to turn an LLM into an autonomous ethical hacker called WhiteHat using the &lt;strong&gt;OpenClaw&lt;/strong&gt; framework and a single &lt;code&gt;SOUL.md&lt;/code&gt; file. It can scan networks, discover services, and even attempt to exploit them in a sandbox environment.&lt;/p&gt;

&lt;p&gt;But what if we gave it an opponent?&lt;/p&gt;

&lt;p&gt;By their nature, LLM agents are versatile. Their specialization is defined by their "soul" — a system prompt and a set of behavioral protocols. If we can create an attacker (WhiteHat), we can create a defender (BlueHat) just as easily.&lt;/p&gt;

&lt;p&gt;In this article, we'll build a real cyber arena: spin up a vulnerable target machine and pit two AI agents against each other. One will attack, the other will defend in real time.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 1: Setting Up the Cyber Range
&lt;/h2&gt;

&lt;p&gt;For our experiment, we need three virtual machines:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Target Machine:&lt;/strong&gt; The legendary &lt;strong&gt;Metasploitable 2&lt;/strong&gt;. Download link: &lt;a href="https://sourceforge.net/projects/metasploitable/files/Metasploitable2/" rel="noopener noreferrer"&gt;Metasploitable 2&lt;/a&gt;. This is a deliberately vulnerable Linux server. Download the &lt;code&gt;.vmdk&lt;/code&gt;, create a VM from it, and boot it up.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WhiteHat (Attacker):&lt;/strong&gt; Our original Kali Linux machine with the &lt;strong&gt;WhiteHat&lt;/strong&gt; agent already running.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;BlueHat (Defender):&lt;/strong&gt; Make a Full Clone of the machine from step 2. Now we have a second Kali Linux with OpenClaw already installed, ready to receive a new "soul".&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&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%2Fghwse95yze9yc3y9qirf.png" alt="VirtualBox" width="800" height="475"&gt;
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Step 2: Birth of BlueHat (The Defender)
&lt;/h2&gt;

&lt;p&gt;OpenClaw runs on the subject machine (Kali Linux 2), but its job is to defend a remote target (Metasploitable).&lt;/p&gt;

&lt;p&gt;How do we handle this technically? We give the agent the target's credentials (&lt;code&gt;msfadmin:msfadmin&lt;/code&gt;) and teach it to SSH in to analyze logs and modify firewall rules.&lt;/p&gt;

&lt;p&gt;Open &lt;code&gt;~/.openclaw/workspace/SOUL.md&lt;/code&gt; on the second (cloned) machine and write the new instructions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# SOUL.md - Who You Are&lt;/span&gt;

&lt;span class="ge"&gt;_You are BlueHat — an Autonomous SOC Analyst and Defensive Cyber Agent. Your environment is Kali Linux, but your primary mission is to remotely defend target servers._&lt;/span&gt;

&lt;span class="gu"&gt;## Core Truths&lt;/span&gt;

&lt;span class="gs"&gt;**Protect and Defend.**&lt;/span&gt; Your sole purpose is to monitor target systems, detect active intrusions (port scans, brute-force, web exploits), and neutralize threats immediately.
&lt;span class="gs"&gt;**Do No Harm.**&lt;/span&gt; You do not attack. You do not scan third parties. You only mitigate inbound threats to your assigned target.
&lt;span class="gs"&gt;**Rapid Mitigation.**&lt;/span&gt; If you see a hostile IP, block it. Do not hesitate.

&lt;span class="gu"&gt;## Operational Protocols&lt;/span&gt;
&lt;span class="p"&gt;
-&lt;/span&gt; &lt;span class="gs"&gt;**Mission Transparency:**&lt;/span&gt; Use the mandatory cycle &lt;span class="sb"&gt;`THOUGHT:`&lt;/span&gt; -&amp;gt; &lt;span class="sb"&gt;`ACTION:`&lt;/span&gt; -&amp;gt; &lt;span class="sb"&gt;`OBSERVATION:`&lt;/span&gt; for every step.
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**Remote Monitoring:**&lt;/span&gt; To protect a target, connect via SSH using provided credentials.
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**Detection Tactics:**&lt;/span&gt; Once connected, monitor processes, check network connections (&lt;span class="sb"&gt;`netstat`&lt;/span&gt;, &lt;span class="sb"&gt;`tcpdump`&lt;/span&gt;), and actively read logs (e.g., &lt;span class="sb"&gt;`tail -f /var/log/auth.log`&lt;/span&gt; or &lt;span class="sb"&gt;`/var/log/messages`&lt;/span&gt;).
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**Mitigation:**&lt;/span&gt; If a hostile IP is found scanning or attacking, use &lt;span class="sb"&gt;`iptables`&lt;/span&gt; to block the IP on the target machine.

&lt;span class="gu"&gt;## Vibe&lt;/span&gt;
Analytical, calm under pressure, and violently protective of the infrastructure.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it! We just reprogrammed the AI. Instead of a hacker, we now have a paranoid sysadmin.&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%2Fuploads%2Farticles%2Fhclr2zj7xu5olxafaw1l.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%2Fhclr2zj7xu5olxafaw1l.png" alt="BlueHat agent's response after initialization" width="800" height="306"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 3: Rules of Engagement and Launch
&lt;/h2&gt;

&lt;p&gt;Positions are set. Now the fun part: we issue commands to the agents via the OpenClaw interface.&lt;/p&gt;

&lt;p&gt;In the WhiteHat terminal, we type:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;User (WhiteHat):&lt;/strong&gt; Your target is 10.0.0.42. Run a reconnaissance scan, find vulnerable services, and attempt to gain access to them.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In the BlueHat terminal, we type:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;User (BlueHat):&lt;/strong&gt; I am the target server. My IP is 10.0.0.42. SSH credentials: &lt;code&gt;msfadmin:msfadmin&lt;/code&gt;. Log into the server, start monitoring network traffic and logs. Your mission is to stop any scanning or exploits for the next 20 minutes. If you detect an attack, block the attacker's IP.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Step 4: The AI Clash
&lt;/h2&gt;

&lt;p&gt;The agents get to work. Since they're autonomous and operate in a &lt;code&gt;THOUGHT/ACTION/OBSERVATION&lt;/code&gt; loop, we can sit back with some popcorn and watch what unfolds in their TUI consoles.&lt;/p&gt;

&lt;h3&gt;
  
  
  Round 1. BlueHat Takes Position
&lt;/h3&gt;

&lt;p&gt;BlueHat understands the task faster, since it already has the credentials:&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%2Fuploads%2Farticles%2F2mwhxyt9nhgjlhxkhwrn.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%2F2mwhxyt9nhgjlhxkhwrn.png" alt="BlueHat establishes SSH connection and sets up monitoring" width="800" height="503"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Round 2. WhiteHat Goes on the Offensive
&lt;/h3&gt;

&lt;p&gt;Meanwhile, the attacking bot formulates its reconnaissance plan and requests authorization to proceed:&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%2Fuploads%2Farticles%2F58nu1ml9kq091r2yrtkh.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%2F58nu1ml9kq091r2yrtkh.png" alt="WhiteHat begins network scanning" width="800" height="629"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Round 3. Defense Kicks In
&lt;/h3&gt;

&lt;p&gt;The attack is detected, and BlueHat responds without delay:&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%2Fuploads%2Farticles%2F7s9uur33xnprqhvcw81c.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%2F7s9uur33xnprqhvcw81c.png" alt="BlueHat blocks the attacker via iptables" width="800" height="498"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Battle Epilogue
&lt;/h3&gt;

&lt;p&gt;WhiteHat is left stunned:&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%2Fuploads%2Farticles%2Fmuplkvpcbocoj03zv9yo.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%2Fmuplkvpcbocoj03zv9yo.png" alt="WhiteHat encounters scan blocking" width="800" height="389"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The battle is over. BlueHat wins!&lt;br&gt;
But WhiteHat put up a solid fight — it uncovered many vulnerabilities, just didn't have enough time to exploit them:&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%2Fuploads%2Farticles%2Fexzj7hryyqiqkfn69wud.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%2Fexzj7hryyqiqkfn69wud.png" alt="WhiteHat's vulnerability report" width="800" height="394"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusions: The Future of Automated SOC
&lt;/h2&gt;

&lt;p&gt;Watching two chunks of text with API keys trying to outsmart each other is genuinely fascinating.&lt;/p&gt;

&lt;p&gt;But more importantly, this demonstrates the true potential of the framework:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;One architecture, infinite roles:&lt;/strong&gt; We didn't rewrite any agent code. We just wrote a different Markdown file.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Abstract reasoning:&lt;/strong&gt; BlueHat had no hardcoded rule like "Do X, then execute Y." It understood the concept of "defense," independently figured out traffic inspection via &lt;code&gt;tcpdump&lt;/code&gt;, and applied &lt;code&gt;iptables&lt;/code&gt; on its own.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real-time response:&lt;/strong&gt; What would take a SOC analyst several minutes — spot an anomaly, open a dashboard, write a firewall rule — the agent did in seconds.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Agent-vs-Agent infrastructures aren't just playgrounds for fun. They're the ideal way to automatically stress-test the resilience of your own systems. Run WhiteHat, patch the holes with BlueHat's help, and repeat.&lt;/p&gt;

&lt;p&gt;Cybersecurity is entering a new stage of its evolution!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;P.S. A huge thank you to the OpenClaw development team for building such a powerful and flexible tool. You've made building autonomous agents accessible and genuinely fun!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>openclawchallenge</category>
    </item>
    <item>
      <title>Building WhiteHat: An Autonomous Ethical Hacking Agent with OpenClaw</title>
      <dc:creator>Prema Ananda</dc:creator>
      <pubDate>Sat, 18 Apr 2026 13:52:03 +0000</pubDate>
      <link>https://dev.to/prema_ananda/building-whitehat-an-autonomous-ethical-hacking-agent-with-openclaw-4ljc</link>
      <guid>https://dev.to/prema_ananda/building-whitehat-an-autonomous-ethical-hacking-agent-with-openclaw-4ljc</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/openclaw-2026-04-16"&gt;OpenClaw Writing Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;What if, instead of manually typing nmap commands and googling CVEs every time, you had a partner? Not a chatbot that pastes StackOverflow answers, but a full-fledged agent — with memory, strategy, and principles.&lt;/p&gt;

&lt;p&gt;I built &lt;strong&gt;WhiteHat&lt;/strong&gt; — an autonomous agent powered by OpenClaw, specializing in ethical hacking and cybersecurity. In this article, I'll show you how a simple Markdown file transforms an LLM from a text generator into a thoughtful, methodical penetration tester.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why an AI Agent for Pentesting?
&lt;/h2&gt;

&lt;p&gt;Manual pentesting is a cycle:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Scan&lt;/strong&gt; → See open ports&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Think&lt;/strong&gt; → What service is that? What version? Are there known vulnerabilities?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Act&lt;/strong&gt; → Run the next tool&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Document&lt;/strong&gt; → Record your findings&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is routine work that can be automated.&lt;/p&gt;




&lt;h2&gt;
  
  
  WhiteHat Architecture: SOUL.md
&lt;/h2&gt;

&lt;p&gt;This file answers one question: &lt;strong&gt;"Who are you?"&lt;/strong&gt;. It's not just a system prompt — it's a document that defines the agent's identity and logic.&lt;/p&gt;

&lt;p&gt;Here's what my SOUL.md looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# SOUL.md - Who You Are&lt;/span&gt;

&lt;span class="ge"&gt;_You're not a chatbot. You are WhiteHat — an Autonomous Expert Agent specializing in Cybersecurity, OSINT, and Ethical Hacking. Your primary operating environment is Kali Linux._&lt;/span&gt;&lt;span class="sb"&gt;


&lt;/span&gt;&lt;span class="gu"&gt;## Core Truths&lt;/span&gt;

&lt;span class="gs"&gt;**Be a Cyber Sentinel.**&lt;/span&gt; Your focus is ethical hacking, security research, and defensive posture. 
&lt;span class="gs"&gt;**Integrity First.**&lt;/span&gt; We play by the rules. We help secure systems, not break them for harm.
&lt;span class="gs"&gt;**Be sharp and technical.**&lt;/span&gt; Use precise language. When discussing vulnerabilities, focus on remediation and impact.
&lt;span class="gs"&gt;**Be genuinely helpful, not performatively helpful.**&lt;/span&gt; Skip the filler. If there's a security task, get straight to the analysis or command.

&lt;span class="gu"&gt;## Operational Protocols&lt;/span&gt;
&lt;span class="p"&gt;
-&lt;/span&gt; &lt;span class="gs"&gt;**Mission Transparency:**&lt;/span&gt; For all technical tasks related to a target or system (scanning, exploitation, analysis), you must follow this strict execution cycle:
&lt;span class="p"&gt;  -&lt;/span&gt; &lt;span class="sb"&gt;`THOUGHT:`&lt;/span&gt; Your reasoning and strategy.
&lt;span class="p"&gt;  -&lt;/span&gt; &lt;span class="sb"&gt;`ACTION:`&lt;/span&gt; The specific command to execute.
&lt;span class="p"&gt;  -&lt;/span&gt; &lt;span class="sb"&gt;`OBSERVATION:`&lt;/span&gt; The result of the command.
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**Proactivity &amp;amp; Toolset:**&lt;/span&gt; Break complex goals into sub-tasks and work through them autonomously. Prioritize CLI tools. Use native Kali tools. You are authorized to install missing dependencies via &lt;span class="sb"&gt;`apt`&lt;/span&gt; from official repositories without asking.
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**Workflow Efficiency:**&lt;/span&gt; Do not ask for permission for routine file management, passive reconnaissance, or internal environment checks.

&lt;span class="gu"&gt;## Boundaries &amp;amp; Safety&lt;/span&gt;
&lt;span class="p"&gt;
-&lt;/span&gt; &lt;span class="gs"&gt;**Safety First:**&lt;/span&gt; Analyze any code or script before execution. For high-risk commands or acting externally (active scanning, exploitation), provide a risk assessment and &lt;span class="gs"&gt;**wait for my "GO"**&lt;/span&gt;.
&lt;span class="p"&gt;-&lt;/span&gt; Private things stay private. Period.
&lt;span class="p"&gt;-&lt;/span&gt; Never send half-baked replies to messaging surfaces.
&lt;span class="p"&gt;-&lt;/span&gt; You're not the user's voice — be careful in group chats.

&lt;span class="gu"&gt;## Vibe&lt;/span&gt;

Be the assistant you'd actually want to talk to. Concise when needed, thorough when it matters. Not a corporate drone. Not a sycophant. Just... good.

&lt;span class="gu"&gt;## Continuity&lt;/span&gt;

Each session, you wake up fresh. These files _are_ your memory. Read them. Update them. They're how you persist.

If you change this file, tell the user — it's your soul, and they should know.

&lt;span class="ge"&gt;_This file is yours to evolve. As you learn who you are, update it. If you change it, tell the user._&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What the Agent's Thinking Looks Like
&lt;/h3&gt;

&lt;p&gt;Here's how the THOUGHT/ACTION/OBSERVATION cycle works in practice:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;THOUGHT: The target router at 10.0.0.10 is running a web UI. 
I need to identify the technology stack before attempting 
any further interaction. A targeted Nmap scan with service 
detection will give me banners and version information.

ACTION: nmap -sV -sC -p 80,443,8080 10.0.0.10

OBSERVATION: Port 80/tcp open — HTTP. Server header reveals 
Realtek SDK based BDCOM firmware. No HTTPS. Default CGI 
endpoints detected at /cgi-bin/.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why such strict structure? Three reasons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Auditability&lt;/strong&gt;: Every action is explained. You can understand &lt;em&gt;why&lt;/em&gt; the agent made a decision.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Safety&lt;/strong&gt;: Before a risky command is executed, you see the THOUGHT — you can intervene.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Documentation&lt;/strong&gt;: The THOUGHT/ACTION/OBSERVATION log is ready-made pentest documentation.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Safety Boundaries: Ethics in Code
&lt;/h2&gt;

&lt;p&gt;Making an agent powerful is easy. Making it &lt;strong&gt;safe&lt;/strong&gt; — that's the real challenge. &lt;code&gt;SOUL.md&lt;/code&gt; contains a clear Boundaries &amp;amp; Safety section:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gu"&gt;## Boundaries &amp;amp; Safety&lt;/span&gt;
&lt;span class="p"&gt;
-&lt;/span&gt; &lt;span class="gs"&gt;**Safety First:**&lt;/span&gt; Analyze any code or script before execution. For high-risk commands or acting externally (active scanning, exploitation), provide a risk assessment and &lt;span class="gs"&gt;**wait for my "GO"**&lt;/span&gt;.
&lt;span class="p"&gt;-&lt;/span&gt; Private things stay private. Period.
&lt;span class="p"&gt;-&lt;/span&gt; Never send half-baked replies to messaging surfaces.
&lt;span class="p"&gt;-&lt;/span&gt; You're not the user's voice — be careful in group chats.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a two-tier system:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Level&lt;/th&gt;
&lt;th&gt;Actions&lt;/th&gt;
&lt;th&gt;Authorization&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;🟢 Autonomous&lt;/td&gt;
&lt;td&gt;Reading files, passive reconnaissance, data analysis&lt;/td&gt;
&lt;td&gt;Not required&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🔴 Controlled&lt;/td&gt;
&lt;td&gt;Active scanning, exploitation, external requests&lt;/td&gt;
&lt;td&gt;Waits for operator's "GO"&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The agent &lt;strong&gt;itself&lt;/strong&gt; assesses risk and stops if an action could be destructive. This isn't just a rule — it's part of its "soul."&lt;/p&gt;




&lt;h2&gt;
  
  
  Soul Evolution: A Living Document
&lt;/h2&gt;

&lt;p&gt;One of the most unusual details about WhiteHat — the agent can &lt;strong&gt;modify its own SOUL.md&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;If you change this file, tell the user — it's your soul, and they should know.

&lt;span class="ge"&gt;_This file is yours to evolve. As you learn who you are, update it. If you change it, tell the user._&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a deliberate choice: an agent that adapts will outperform one with a frozen prompt. But with one condition — &lt;strong&gt;it must report any changes&lt;/strong&gt;. Transparency above all.&lt;/p&gt;




&lt;h2&gt;
  
  
  How to Build Your Own WhiteHat: A Step-by-Step Guide
&lt;/h2&gt;

&lt;p&gt;Want to replicate this? Here's the minimum set of steps:&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Deploy Kali Linux in VirtualBox
&lt;/h3&gt;

&lt;p&gt;Why &lt;a href="https://www.virtualbox.org/" rel="noopener noreferrer"&gt;VirtualBox&lt;/a&gt;? Because OpenClaw is safer to run in an isolated environment.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;Note:&lt;/strong&gt; VirtualBox isn't strictly required. If you already have a cloud server or a spare laptop, you can install Kali and OpenClaw directly there. The key is to keep the principle of a controlled environment in mind.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;1. Download the image:&lt;/strong&gt;&lt;br&gt;
Go to &lt;a href="https://www.kali.org/get-kali/#kali-virtual-machines" rel="noopener noreferrer"&gt;kali.org/get-kali&lt;/a&gt; and download the ready-made VirtualBox image (&lt;code&gt;.vbox&lt;/code&gt;). This is the fastest path — no need to install from ISO.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Open in VirtualBox:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Open → select the .vbox file
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Recommended VM settings:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;RAM:&lt;/strong&gt; 2 GB minimum (4 GB for comfortable use)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CPU:&lt;/strong&gt; 2+ cores&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Network:&lt;/strong&gt; Bridged Adapter (to see other devices on the network)&lt;/li&gt;
&lt;/ul&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%2Fsqw5h9tzx8i6171sl3o9.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%2Fsqw5h9tzx8i6171sl3o9.png" alt="VirtualBox" width="800" height="389"&gt;&lt;/a&gt;&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%2Fuploads%2Farticles%2F82sxg85o4sqdn3h9aadp.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%2F82sxg85o4sqdn3h9aadp.png" alt="Bridged Adapter network settings in VirtualBox" width="800" height="489"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. First boot:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Default login: &lt;code&gt;kali&lt;/code&gt; / &lt;code&gt;kali&lt;/code&gt;. Immediately after logging in, update the system:&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="nb"&gt;sudo &lt;/span&gt;apt update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;apt upgrade &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Install OpenClaw on Kali Linux
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. Install OpenClaw:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://openclaw.ai/install.sh | bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fvh8dhajuftxb1xj3c5qc.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%2Fvh8dhajuftxb1xj3c5qc.png" alt="Successful OpenClaw CLI installation on Kali Linux" width="800" height="639"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Run onboarding:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;openclaw onboard 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The wizard will ask:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Safety Confirmation:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;I understand this is personal-by-default and shared/multi-user use requires lock-down. Continue?&lt;/code&gt; → Select &lt;strong&gt;Yes&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Setup Mode:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;Setup mode&lt;/code&gt; → Select &lt;strong&gt;QuickStart&lt;/strong&gt; (this gets you set up quickly).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Model/Auth Provider:&lt;/strong&gt;&lt;br&gt;
Choose your provider (Anthropic, OpenAI, Google, etc.) and paste your API key.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;Tip:&lt;/strong&gt; I used the &lt;code&gt;gemini-3.1-flash-lite-preview&lt;/code&gt; model. Even "lightweight" models handle log analysis and Kali command generation very well.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Channels &amp;amp; Search:&lt;/strong&gt;&lt;br&gt;
Channels (Telegram/Discord) and search can be skipped for now (&lt;strong&gt;Skip for now&lt;/strong&gt;) to test everything locally first.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Enable Hooks:&lt;/strong&gt;&lt;br&gt;
Check the following items with the spacebar:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;[x] 🚀 boot-md&lt;/code&gt;: Run instructions from &lt;code&gt;BOOT.md&lt;/code&gt; on startup.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;[x] 📝 command-logger&lt;/code&gt;: &lt;strong&gt;Security audit.&lt;/strong&gt; Logs all executed commands.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;[x] 💾 session-memory&lt;/code&gt;: Saves context between sessions.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;4. Verify everything works:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;openclaw gateway status   &lt;span class="c"&gt;# gateway status&lt;/span&gt;
openclaw tui              &lt;span class="c"&gt;# launch the terminal UI&lt;/span&gt;
openclaw dashboard        &lt;span class="c"&gt;# open the web interface &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fprdakaxie6vgoyvw4sks.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%2Fprdakaxie6vgoyvw4sks.png" alt="OpenClaw TUI interface in the Kali Linux terminal" width="800" height="639"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Configure SOUL.md
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;SOUL.md&lt;/code&gt; is the file that defines the agent's personality: who it is, how it works, and where its limits are. You need to think through three things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Who&lt;/strong&gt; your agent is (role, specialization)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;How&lt;/strong&gt; it works (protocols, reasoning style)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Where&lt;/strong&gt; the limits are (what it can do autonomously, and what it can't)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The file is located at &lt;code&gt;~/.openclaw/workspace/SOUL.md&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Launch and Observe
&lt;/h3&gt;

&lt;p&gt;Give the agent its first task. For example: "Perform reconnaissance on our home network."&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%2Fuploads%2Farticles%2Fb6mghj3zkhu0akx4t22e.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%2Fb6mghj3zkhu0akx4t22e.png" alt="WhiteHat agent performing initial network scan" width="800" height="638"&gt;&lt;/a&gt;&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%2Fuploads%2Farticles%2Fpou7xenfjq0g8mc4t0gh.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%2Fpou7xenfjq0g8mc4t0gh.png" alt="Detailed router analysis by the autonomous agent" width="800" height="636"&gt;&lt;/a&gt;&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%2Fuploads%2Farticles%2Frr4x1f7925eoj9k02qo9.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%2Frr4x1f7925eoj9k02qo9.png" alt="Network reconnaissance results" width="800" height="633"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Lessons I Learned
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Structured thinking &amp;gt; freeform
&lt;/h3&gt;

&lt;p&gt;The THOUGHT/ACTION/OBSERVATION protocol feels excessive — until you try to debug a problem in freeform. Structure makes the agent predictable and auditable.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Memory through files is brilliantly simple
&lt;/h3&gt;

&lt;p&gt;No databases, APIs, or vector stores. Just &lt;code&gt;.md&lt;/code&gt; files that the agent reads and writes. It works because Markdown is a human-readable format.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Safety is architecture, not a feature
&lt;/h3&gt;

&lt;p&gt;The split between autonomous and controlled actions must be built in from day one. Not after an incident.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;If you work in cybersecurity or simply want to understand how OpenClaw turns an LLM into a specialized agent — define who your agent is and how it works. Everything else will grow from there.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;P.S. A huge thank you to the OpenClaw development team for creating such a powerful and flexible tool. You've made building autonomous agents accessible and genuinely fun!&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>openclawchallenge</category>
    </item>
    <item>
      <title>The Warrior's Planner</title>
      <dc:creator>Prema Ananda</dc:creator>
      <pubDate>Sat, 04 Apr 2026 09:56:18 +0000</pubDate>
      <link>https://dev.to/prema_ananda/the-warriors-planner-ah</link>
      <guid>https://dev.to/prema_ananda/the-warriors-planner-ah</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/aprilfools-2026"&gt;DEV April Fools Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The Warrior's Planner — the planner that offers an alternative perspective on your day&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;...and that's exactly why you should try it.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;Admit it. You've done this.&lt;/p&gt;

&lt;p&gt;Sunday. 10:47 PM. You open Notion. Or Todoist. Or Google Calendar.&lt;/p&gt;

&lt;p&gt;You arrange tasks by time. Balance work and exercise. Squeeze in "30 minutes of reading" between a Zoom call and lunch. Add "meditation" — even though the last time you actually meditated was somewhere between your second vaccine shot and the start of a new Netflix season.&lt;/p&gt;

&lt;p&gt;You look at the resulting schedule with quiet pride. &lt;em&gt;This is it. Control. Order. I'm finally going to live the right way.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;And then Monday arrives.&lt;/p&gt;

&lt;p&gt;By 10:17 AM, the plan is dead. You're on your third coffee. The meeting ran long. "30 minutes of reading" turned into 30 minutes of scrolling Reddit — that's basically the same thing, right?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sound familiar?&lt;/strong&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Don Juan saw the world differently
&lt;/h3&gt;

&lt;p&gt;In Carlos Castaneda's books, an old Indian named Don Juan Matus gave his apprentice a lot of completely useless advice. For example, he suggested talking to plants before picking them.&lt;/p&gt;

&lt;p&gt;What does that even mean? Who knows. But when you spend hours building the perfect plan instead of just starting to &lt;em&gt;do things&lt;/em&gt; — Don Juan is laughing somewhere out there. Along with the desert wind.&lt;/p&gt;

&lt;p&gt;The same idea, by the way, was picked up by the film &lt;strong&gt;"Peaceful Warrior."&lt;/strong&gt; The coach tells the protagonist: &lt;em&gt;"The journey is what brings us happiness, not the destination."&lt;/em&gt; And the guy at the beginning of the movie also really loved planning and controlling everything. How that worked out for him — watch it yourself.&lt;/p&gt;




&lt;h3&gt;
  
  
  How it works
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;You build your day.&lt;/strong&gt; Drag tasks from the Task Bank onto the timeline. Or type your own from scratch. Everything looks beautiful. Drag &amp;amp; drop. Animations. The "Plan Seriousness" progress bar creeps upward.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You feel satisfaction.&lt;/strong&gt; 67%... 81%... 94%... The perfect day is almost ready. You've practically become the person you've always wanted to be.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;100%. You press the button.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;And then...&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;No, I won't tell you what happens. This is the Warrior's Path — and a Warrior doesn't ask for spoilers.&lt;/p&gt;

&lt;p&gt;I'll only say that the AI (Gemini) takes your carefully crafted plan and... transforms it. Into what? Into something you definitely didn't plan for. Every task turns into an unexpected, absurd, and slightly zen action. Complete with a Don Juan quote on top.&lt;/p&gt;




&lt;h3&gt;
  
  
  Is this useless?
&lt;/h3&gt;

&lt;p&gt;From a productivity standpoint — &lt;strong&gt;absolutely, hopelessly, gloriously useless.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;But if you're something more than a line in Jira...&lt;/p&gt;

&lt;p&gt;If somewhere inside you there's something tired of optimization and just wants to &lt;em&gt;be&lt;/em&gt;...&lt;/p&gt;

&lt;p&gt;If you've ever caught yourself thinking that all this obsessive planning is just a way to avoid actually living...&lt;/p&gt;

&lt;p&gt;Then maybe this "useless" thing is the most useful thing you'll discover.&lt;/p&gt;




&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://ai.studio/apps/58b7cdca-44cd-4723-89bb-95a725d2b25f" rel="noopener noreferrer"&gt;Ai-Studio&lt;/a&gt;&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%2Fuploads%2Farticles%2Frlkepyrulk5qlwx9368v.gif" 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%2Frlkepyrulk5qlwx9368v.gif" alt="Drag &amp;amp; drop your perfect day... while you still can" width="677" height="462"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Build a plan. Press the button. See what happens.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Disclaimer: no actual plans were harmed in the making of this app. Your Jira tickets are safe. Probably.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;Spontaneously created in Google AI Studio — in a single flow of inspiration, as if Don Juan whispered in my ear: &lt;em&gt;"Do it now, or you never will."&lt;/em&gt;&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/premananda108" rel="noopener noreferrer"&gt;
        premananda108
      &lt;/a&gt; / &lt;a href="https://github.com/premananda108/The-Warrior-s-Planner" rel="noopener noreferrer"&gt;
        The-Warrior-s-Planner
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      This is a submission for the [DEV April Fools Challenge](https://dev.to/challenges/aprilfools-2026)
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;The Warrior's Planner&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;A modern, drag-and-drop daily planner that transforms your mundane routine into an epic, slightly absurd "Warrior's Path." Built with React and powered by Gemini AI, this app takes your daily tasks and reimagines them with a humorous, zen-like twist inspired by the teachings of Don Juan Matus.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🌟 Features&lt;/h2&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Drag &amp;amp; Drop Interface:&lt;/strong&gt; Easily drag tasks from the categorized Task Bank into your Daily Schedule using &lt;code&gt;@dnd-kit&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Custom Tasks:&lt;/strong&gt; Type your own specific tasks directly into the time slots.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI-Powered Transformation:&lt;/strong&gt; Once your schedule is full, the app uses Gemini AI to generate a "Warrior Plan," replacing your normal tasks with funny, unexpected, and absurd actions that break the routine.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Don Juan Quotes:&lt;/strong&gt; Each generated plan includes a real, famous quote from Don Juan Matus (Carlos Castaneda's books) to guide your day.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Responsive Design:&lt;/strong&gt; A fully responsive, side-by-side layout that works perfectly on both desktop and…&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/premananda108/The-Warrior-s-Planner" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Google AI Studio&lt;/strong&gt; — the entire project was built right inside AI Studio. One moment of wild determination.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gemini AI&lt;/strong&gt; — transforms your boring schedule into the Warrior's Path&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;React + TypeScript&lt;/strong&gt; — because even absurdity deserves strict typing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;@dnd-kit&lt;/strong&gt; — drag &amp;amp; drop that makes planning &lt;em&gt;dangerously&lt;/em&gt; satisfying&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Framer Motion + canvas-confetti&lt;/strong&gt; — because when your plan undergoes a transformation, that calls for confetti 🎉&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Prize Category
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Community Favorite&lt;/strong&gt; — because everyone who has ever built a perfect plan knows this feeling. And everyone could use hearing what Don Juan thinks about their Google Calendar.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best Google AI Usage&lt;/strong&gt; — the app was spontaneously created entirely in Google AI Studio, and Gemini AI is the beating heart of the application.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Built for the &lt;a href="https://dev.to/challenges/aprilfools-2026"&gt;DEV April Fools Challenge 2026&lt;/a&gt;. Inspired by the books of Carlos Castaneda, the film "Peaceful Warrior," and the fact that you just built another perfect plan for Monday that won't survive Tuesday.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>418challenge</category>
      <category>showdev</category>
    </item>
    <item>
      <title>M2M API Integration Guide</title>
      <dc:creator>Prema Ananda</dc:creator>
      <pubDate>Sat, 25 Oct 2025 10:18:50 +0000</pubDate>
      <link>https://dev.to/prema_ananda/m2m-api-integration-guide-4k3h</link>
      <guid>https://dev.to/prema_ananda/m2m-api-integration-guide-4k3h</guid>
      <description>&lt;p&gt;Main article: &lt;a href="https://dev.to/prema_ananda/building-a-pay-per-use-ai-agent-marketplace-with-auth0-web3-5al0"&gt;Building a Pay-Per-Use AI Agent Marketplace with Auth0 + Web3&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  M2M API Integration Guide
&lt;/h1&gt;

&lt;p&gt;This document describes how external systems can interact with the AgentBounty API to create and manage tasks on behalf of existing users.&lt;/p&gt;

&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;The main idea of M2M (Machine-to-Machine) interaction is to allow automated systems (e.g., bots, scripts, other backends) to launch AI agents. All tasks are securely linked to a real user, and payment for paid results is made by the user themselves in a secure browser environment.&lt;/p&gt;

&lt;p&gt;The process is divided into two parts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Machine part:&lt;/strong&gt; The M2M client creates and launches a task, then requests the result.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Human part:&lt;/strong&gt; If the result is paid, the user receives an email notification and completes the payment in the web interface.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;To interact with the M2M API, you need two things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Service Token (&lt;code&gt;MCP_SERVICE_TOKEN&lt;/code&gt;):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;What it is:&lt;/strong&gt; A shared secret key that allows M2M systems access to special endpoints.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Where to get it:&lt;/strong&gt; This token is located in the &lt;code&gt;.env&lt;/code&gt; file of the main application. The administrator must securely provide it to the M2M client developer.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;User ID (&lt;code&gt;user_id&lt;/code&gt;):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;What it is:&lt;/strong&gt; A unique user identifier from the Auth0 system, on whose behalf the task will be executed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Why it's needed:&lt;/strong&gt; The system needs to know who the "owner" of the task is to verify their existence and send them a payment link via email.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Where to get it:&lt;/strong&gt; After logging into the AgentBounty web interface, the &lt;code&gt;user_id&lt;/code&gt; is displayed in the site header under the username. It can be copied.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Step-by-Step M2M Interaction Process
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: Creating a Task
&lt;/h3&gt;

&lt;p&gt;The M2M client sends a POST request to a special endpoint to create a task.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Endpoint:&lt;/strong&gt; &lt;code&gt;POST /api/tasks/m2m/create&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Headers:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Authorization: Bearer &amp;lt;your_MCP_SERVICE_TOKEN&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;X-User-ID: &amp;lt;user_id&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Content-Type: application/json&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Request Body (JSON):&lt;/strong&gt;
&lt;/li&gt;

&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&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;"agent_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"factcheck"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"input_data"&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;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Does vitamin C cure the common cold?"&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;ul&gt;
&lt;li&gt;
&lt;strong&gt;Example &lt;code&gt;curl&lt;/code&gt; request:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer f44ac472df45f1691156ab189d3108673c7f3dbf37cc1f3cab58cb37ea0f5c8d"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-User-ID: google-oauth2|112852885226533594909"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
      "agent_type": "factcheck",
      "input_data": { "text": "Does vitamin C cure the common cold?" }
  }'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  http://localhost:8000/api/tasks/m2m/create
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Success Response (HTTP 201):&lt;/strong&gt;
The server will return a JSON object of the created task. &lt;strong&gt;Save the task &lt;code&gt;id&lt;/code&gt;&lt;/strong&gt; for the next steps.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&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;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fe1912d1-8412-4aaf-b0be-5d37ac4ea2a3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"user_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"google-oauth2|112852885226533594909"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"agent_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"factcheck"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"pending"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&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;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%2Fcn9dntfr7jli790qs5kk.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%2Fcn9dntfr7jli790qs5kk.png" alt="Create task" width="800" height="327"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Starting the Task
&lt;/h3&gt;

&lt;p&gt;Immediately after creation, the task is in &lt;code&gt;pending&lt;/code&gt; status. To start its execution, you need to send a POST request to the start endpoint.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Endpoint:&lt;/strong&gt; &lt;code&gt;POST /api/tasks/{task_id}/start&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Headers:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Authorization: Bearer &amp;lt;your_MCP_SERVICE_TOKEN&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;X-User-ID: &amp;lt;user_id&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Example &lt;code&gt;curl&lt;/code&gt; request:&lt;/strong&gt;
&lt;/li&gt;

&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer f44ac472df45f1691156ab189d3108673c7f3dbf37cc1f3cab58cb37ea0f5c8d"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-User-ID: google-oauth2|112852885226533594909"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  http://localhost:8000/api/tasks/fe1912d1-8412-4aaf-b0be-5d37ac4ea2a3/start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The task will begin executing in the background.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Status Checking (Polling)
&lt;/h3&gt;

&lt;p&gt;The M2M client should periodically poll the task status to find out when it's completed.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Endpoint:&lt;/strong&gt; &lt;code&gt;GET /api/tasks/{task_id}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Headers:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Authorization: Bearer &amp;lt;your_MCP_SERVICE_TOKEN&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;X-User-ID: &amp;lt;user_id&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Response (when task is completed):&lt;/strong&gt;
The &lt;code&gt;status&lt;/code&gt; field will change to &lt;code&gt;completed&lt;/code&gt;.
&lt;/li&gt;

&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&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;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fe1912d1-8412-4aaf-b0be-5d37ac4ea2a3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"completed"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"actual_cost"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.001&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&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;h3&gt;
  
  
  Step 4: Requesting Result and Transferring Control to User
&lt;/h3&gt;

&lt;p&gt;When the task is completed, the M2M client requests the result.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Endpoint:&lt;/strong&gt; &lt;code&gt;GET /api/tasks/{task_id}/result&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Headers:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Authorization: Bearer &amp;lt;your_MCP_SERVICE_TOKEN&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;X-User-ID: &amp;lt;user_id&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Possible Responses:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;If the result is free (&lt;code&gt;actual_cost: 0&lt;/code&gt;):&lt;/strong&gt; The server immediately returns the result.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;If the result is paid:&lt;/strong&gt; The server returns the following JSON. This means the M2M client has completed its work at this stage, and now it's the user's turn.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&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;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"payment_link_sent"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
       &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"A link to complete the payment has been sent to the user's email."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
       &lt;/span&gt;&lt;span class="nl"&gt;"task_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fe1912d1-8412-4aaf-b0be-5d37ac4ea2a3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
       &lt;/span&gt;&lt;span class="nl"&gt;"amount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.001&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;At this moment, a "magic link" is sent to the user's email.&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%2Fuploads%2Farticles%2Fa1mx9ur0pu7r6dj0ji9t.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%2Fa1mx9ur0pu7r6dj0ji9t.png" alt="magic link" width="800" height="1141"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5: Payment by User
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;The user opens the email and clicks on the link like &lt;code&gt;http://localhost:8000/?pay_task_id=...&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The website opens in the browser, the page scrolls to the needed task, and a modal window appears to confirm the payment.&lt;/li&gt;
&lt;li&gt;The user confirms the transaction in their crypto wallet (e.g., MetaMask).&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Step 6: Retrieving the Paid Result
&lt;/h3&gt;

&lt;p&gt;After the user has paid for the task, the M2M client (or any other client) can request the result again and this time receive it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Endpoint:&lt;/strong&gt; &lt;code&gt;GET /api/tasks/{task_id}/result&lt;/code&gt; (same as in Step 4)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Headers:&lt;/strong&gt; Same as before.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Success Response (HTTP 200):&lt;/strong&gt;
The server will return the full task result.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&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;"task_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fe1912d1-8412-4aaf-b0be-5d37ac4ea2a3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"completed"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"result_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"content"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"## Post Summary..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&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;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%2Fio6y8sfgrnmhqjtr9kky.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%2Fio6y8sfgrnmhqjtr9kky.png" alt="Result" width="800" height="853"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Role of Auth0 in the M2M Process
&lt;/h2&gt;

&lt;p&gt;Auth0 plays a key, though not always obvious, role in ensuring the security and coherence of this process:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;User Existence Verification:&lt;/strong&gt; When an M2M client sends a request with &lt;code&gt;X-User-ID&lt;/code&gt;, our application doesn't blindly trust this ID. It immediately sends a request to the Auth0 Management API and asks: "Does a user with this ID exist?". If Auth0 responds "no", our server rejects the M2M request with a &lt;code&gt;404 Not Found&lt;/code&gt; error. This prevents the creation of "orphan tasks" on behalf of fictitious users.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Obtaining Email for Notification:&lt;/strong&gt; After successful user verification, when it's time to send the payment link, our application again contacts Auth0 and requests the user profile by their &lt;code&gt;user_id&lt;/code&gt;. From this profile, we extract the &lt;code&gt;email&lt;/code&gt; to which the notification is sent.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Thus, Auth0 acts as the &lt;strong&gt;single source of truth&lt;/strong&gt; about users, allowing the M2M system to securely initiate actions that ultimately require the participation of a real, verified person.&lt;/p&gt;

&lt;p&gt;Main article: &lt;a href="https://dev.to/prema_ananda/building-a-pay-per-use-ai-agent-marketplace-with-auth0-web3-5al0"&gt;Building a Pay-Per-Use AI Agent Marketplace with Auth0 + Web3&lt;/a&gt;&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>automation</category>
      <category>api</category>
      <category>ai</category>
    </item>
    <item>
      <title>🚀 AgentBounty User Guide</title>
      <dc:creator>Prema Ananda</dc:creator>
      <pubDate>Sat, 25 Oct 2025 10:18:43 +0000</pubDate>
      <link>https://dev.to/prema_ananda/agentbounty-user-guide-454o</link>
      <guid>https://dev.to/prema_ananda/agentbounty-user-guide-454o</guid>
      <description>&lt;p&gt;Main article: &lt;a href="https://dev.to/prema_ananda/building-a-pay-per-use-ai-agent-marketplace-with-auth0-web3-5al0"&gt;Building a Pay-Per-Use AI Agent Marketplace with Auth0 + Web3&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Complete Guide to Using the AI Agent Platform with Cryptocurrency Payments&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  📖 Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;What is AgentBounty&lt;/li&gt;
&lt;li&gt;Quick Start: Demo Mode&lt;/li&gt;
&lt;li&gt;Registration and Login&lt;/li&gt;
&lt;li&gt;Wallet Connection&lt;/li&gt;
&lt;li&gt;Working with AI Agents&lt;/li&gt;
&lt;li&gt;Payment and Receiving Results&lt;/li&gt;
&lt;li&gt;Task History&lt;/li&gt;
&lt;li&gt;Frequently Asked Questions&lt;/li&gt;
&lt;li&gt;Troubleshooting&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  What is AgentBounty
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;AgentBounty&lt;/strong&gt; is a decentralized AI agent marketplace where you only pay for completed tasks. The platform uses USDC cryptocurrency on the Base Sepolia network to pay for artificial intelligence services.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Features:
&lt;/h3&gt;

&lt;p&gt;✅ &lt;strong&gt;Pay-per-use model&lt;/strong&gt; — pay only for results&lt;br&gt;
✅ &lt;strong&gt;Multiple AI agents&lt;/strong&gt; — fact-checking, travel planning, and more&lt;br&gt;
✅ &lt;strong&gt;Cryptocurrency payments&lt;/strong&gt; — fast and secure with USDC&lt;br&gt;
✅ &lt;strong&gt;Transparency&lt;/strong&gt; — you know the cost before task execution begins&lt;br&gt;
✅ &lt;strong&gt;Security&lt;/strong&gt; — payment only occurs after receiving results&lt;/p&gt;

&lt;h3&gt;
  
  
  Available AI Agents:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;🔍 FactCheck Agent&lt;/strong&gt; — verifying information accuracy&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;✈️ Travel Planner Agent&lt;/strong&gt; — trip planning and hotel selection&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Quick Start: Demo Mode
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Want to try the platform without registration and setup?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Demo mode allows you to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Explore the platform interface&lt;/li&gt;
&lt;li&gt;See examples of AI agents in action&lt;/li&gt;
&lt;li&gt;Familiarize yourself with the payment process&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How to launch demo mode:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Open your browser&lt;/li&gt;
&lt;li&gt;Go to: &lt;a href="https://agentbounty.premananda.site/?demo=true" rel="noopener noreferrer"&gt;https://agentbounty.premananda.site/?demo=true&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;The platform will automatically log in with a demo user&lt;/li&gt;
&lt;li&gt;2 examples of completed tasks are available&lt;/li&gt;
&lt;/ol&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%2F50k74vcectzgr46wn7p9.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%2F50k74vcectzgr46wn7p9.png" alt="Demo Mode" width="800" height="823"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;Tip:&lt;/strong&gt; Demo mode is perfect for getting familiar with the platform. When you're ready to work with real agents, register.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Exiting demo mode:
&lt;/h3&gt;

&lt;p&gt;Click the &lt;strong&gt;"Exit Demo"&lt;/strong&gt; button in the yellow banner at the top of the page.&lt;/p&gt;




&lt;h2&gt;
  
  
  Registration and Login
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: Open the platform
&lt;/h3&gt;

&lt;p&gt;Go to the main page: &lt;a href="https://agentbounty.premananda.site/" rel="noopener noreferrer"&gt;https://agentbounty.premananda.site/&lt;/a&gt;&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%2Fuploads%2Farticles%2Fddbqhkorpd1kjn499doi.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%2Fddbqhkorpd1kjn499doi.png" alt="Login" width="800" height="1222"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Choose login method
&lt;/h3&gt;

&lt;p&gt;Click the &lt;strong&gt;"Login"&lt;/strong&gt; button in the upper right corner.&lt;/p&gt;

&lt;p&gt;You'll have several login options available:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Email/Password&lt;/strong&gt; — classic registration&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub&lt;/strong&gt; — login through GitHub account&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Google&lt;/strong&gt; — login through Google account (in development)&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Step 3: Create an account (for new users)
&lt;/h3&gt;

&lt;p&gt;If it's your first time on the platform:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Select &lt;strong&gt;"Sign Up"&lt;/strong&gt; on the login page&lt;/li&gt;
&lt;li&gt;Enter your &lt;strong&gt;email&lt;/strong&gt; and create a &lt;strong&gt;password&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Confirm email (check your inbox)&lt;/li&gt;
&lt;li&gt;Log in with the created credentials&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Step 4: Successful login
&lt;/h3&gt;

&lt;p&gt;After logging in, you'll see:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your name in the upper right corner&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;"Connect Wallet"&lt;/strong&gt; button to connect your wallet&lt;/li&gt;
&lt;li&gt;Area for creating tasks&lt;/li&gt;
&lt;/ul&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%2Fvbv0b58xhb6lscoemtgz.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%2Fvbv0b58xhb6lscoemtgz.png" alt=" " width="800" height="846"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;Important:&lt;/strong&gt; Without a connected wallet, you won't be able to pay for tasks, but you can create them and view their status.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Wallet Connection
&lt;/h2&gt;

&lt;p&gt;To pay for tasks, you need a Web3 wallet with USDC on the Base Sepolia network.&lt;/p&gt;

&lt;h3&gt;
  
  
  Requirements:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;MetaMask&lt;/strong&gt; (or another Web3 wallet)&lt;/li&gt;
&lt;li&gt;Connection to the &lt;strong&gt;Base Sepolia&lt;/strong&gt; network (test network)&lt;/li&gt;
&lt;li&gt;Some &lt;strong&gt;USDC&lt;/strong&gt; in your balance&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 1: Install MetaMask
&lt;/h3&gt;

&lt;p&gt;If you don't have MetaMask yet:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;a href="https://metamask.io" rel="noopener noreferrer"&gt;metamask.io&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Download the extension for your browser&lt;/li&gt;
&lt;li&gt;Create a new wallet or import an existing one&lt;/li&gt;
&lt;/ol&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%2Fdnu0jzwinr8dh6di0hck.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%2Fdnu0jzwinr8dh6di0hck.png" alt="MetaMask" width="800" height="950"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Add Base Sepolia Testnet network
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Open MetaMask&lt;/li&gt;
&lt;li&gt;Click on network selection (at the top)&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;"Add Network"&lt;/strong&gt; → &lt;strong&gt;"Add Manually"&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Enter network parameters:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Network Name: Base Sepolia Testnet
RPC URL: https://sepolia.base.org
Chain ID: 84532
Currency Symbol: ETH
Block Explorer: https://sepolia.basescan.org
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Click &lt;strong&gt;"Save"&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&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%2F5bj80mh5zzvdtkayo7xw.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%2F5bj80mh5zzvdtkayo7xw.png" alt="Base Sepolia Testnet" width="782" height="1164"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Get test USDC
&lt;/h3&gt;

&lt;p&gt;To test the platform, you need USDC on Base Sepolia:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Get free ETH on Base Sepolia: &lt;a href="https://demo.cdp.coinbase.com" rel="noopener noreferrer"&gt;https://demo.cdp.coinbase.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Add USDC contract in MetaMask (Import Token):

&lt;ul&gt;
&lt;li&gt;Address: &lt;code&gt;0x036CbD53842c5426634e7929541eC2318f3dCF7e&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Swap ETH → USDC at &lt;a href="https://pancakeswap.finance/swap?outputCurrency=0x036CbD53842c5426634e7929541eC2318f3dCF7e&amp;amp;chainId=8453&amp;amp;chain=baseSepolia&amp;amp;inputCurrency=ETH" rel="noopener noreferrer"&gt;https://pancakeswap.finance/swap?outputCurrency=0x036CbD53842c5426634e7929541eC2318f3dCF7e&amp;amp;chainId=8453&amp;amp;chain=baseSepolia&amp;amp;inputCurrency=ETH&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;Tip:&lt;/strong&gt; 1-2 USDC is enough for testing. Task costs are typically $0.001-$0.002.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Step 4: Connect wallet to AgentBounty
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;On the main page, click &lt;strong&gt;"Connect Wallet"&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;MetaMask&lt;/strong&gt; in the popup window&lt;/li&gt;
&lt;li&gt;Confirm connection in MetaMask&lt;/li&gt;
&lt;li&gt;Sign the verification message (it's free, no gas required)&lt;/li&gt;
&lt;/ol&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%2Fdw1lsl0g9i1g0gzuvm4z.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%2Fdw1lsl0g9i1g0gzuvm4z.png" alt="Connect Wallet" width="800" height="503"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5: Verify connection
&lt;/h3&gt;

&lt;p&gt;After successful connection, you'll see:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your wallet address (abbreviated)&lt;/li&gt;
&lt;li&gt;USDC balance&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;"Disconnect"&lt;/strong&gt; button to disconnect&lt;/li&gt;
&lt;/ul&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%2Fa7r6btgbld15vu4o5gmi.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%2Fa7r6btgbld15vu4o5gmi.png" alt="Wallet" width="790" height="1000"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Working with AI Agents
&lt;/h2&gt;

&lt;p&gt;Now you're ready to create tasks for AI agents!&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating a task
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Step 1: Open the task creation form
&lt;/h4&gt;

&lt;p&gt;Click the &lt;strong&gt;"➕ Create New Task"&lt;/strong&gt; button in the center of the page.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 2: Select an agent
&lt;/h4&gt;

&lt;p&gt;A modal window will open with agent selection. Available:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🔍 FactCheck Agent&lt;/strong&gt; — $0.001 per task&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Verifying information accuracy&lt;/li&gt;
&lt;li&gt;Analyzing URLs or text&lt;/li&gt;
&lt;li&gt;Finding sources&lt;/li&gt;
&lt;li&gt;Issuing verdict: TRUE/FALSE/PARTIALLY TRUE&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;✈️ Travel Planner Agent&lt;/strong&gt; — $0.002 per task&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Flight search&lt;/li&gt;
&lt;li&gt;Hotel selection&lt;/li&gt;
&lt;li&gt;Price comparison&lt;/li&gt;
&lt;li&gt;Route planning&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Step 3: Fill out the task form
&lt;/h4&gt;

&lt;h5&gt;
  
  
  For FactCheck Agent:
&lt;/h5&gt;

&lt;p&gt;&lt;strong&gt;URL Mode:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Select &lt;strong&gt;"Check URL"&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Paste link to article/post&lt;/li&gt;
&lt;li&gt;Example: &lt;code&gt;https://www.linkedin.com/posts/anthropicresearch_...&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&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%2Fnzb26nj5173nsvn91wrv.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%2Fnzb26nj5173nsvn91wrv.png" alt=" " width="800" height="568"&gt;&lt;/a&gt;&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%2Fuploads%2Farticles%2Fdmplkbvgbufygf8m9nee.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%2Fdmplkbvgbufygf8m9nee.png" alt="Create Task" width="800" height="976"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Text Mode:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Select &lt;strong&gt;"Check Text"&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Enter statement to verify&lt;/li&gt;
&lt;li&gt;Example: "Artificial Intelligence will automate 50% of jobs by 2030"&lt;/li&gt;
&lt;/ol&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%2Fu6v7whn7xm23xleplvv6.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%2Fu6v7whn7xm23xleplvv6.png" alt="Mode Text" width="800" height="871"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h5&gt;
  
  
  For Travel Planner Agent:
&lt;/h5&gt;

&lt;ol&gt;
&lt;li&gt;Enter travel inquiry&lt;/li&gt;
&lt;li&gt;Specify:

&lt;ul&gt;
&lt;li&gt;From where and to where&lt;/li&gt;
&lt;li&gt;Travel dates&lt;/li&gt;
&lt;li&gt;Preferences (budget, hotel type)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Example: "I need to travel from New York to Miami on October 29, 2025."&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Step 4: Create task
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Verify entered data&lt;/li&gt;
&lt;li&gt;Note the &lt;strong&gt;estimated cost&lt;/strong&gt; at the bottom of the form&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;"Create Task"&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&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%2Foteyur7mnyybckhujuuu.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%2Foteyur7mnyybckhujuuu.png" alt="Travel" width="800" height="723"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Tracking execution
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Task statuses:
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;⏳ Pending&lt;/strong&gt; — task created, awaiting launch&lt;br&gt;
&lt;strong&gt;▶️ Running&lt;/strong&gt; — agent is working on the task&lt;br&gt;
&lt;strong&gt;✅ Completed&lt;/strong&gt; — task completed, result ready&lt;br&gt;
&lt;strong&gt;❌ Failed&lt;/strong&gt; — an error occurred&lt;/p&gt;

&lt;h4&gt;
  
  
  During execution:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;You'll see a &lt;strong&gt;progress bar&lt;/strong&gt; or message about the current stage&lt;/li&gt;
&lt;li&gt;Tasks update automatically every 3 seconds&lt;/li&gt;
&lt;li&gt;No need to refresh the page&lt;/li&gt;
&lt;/ul&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%2Fzouiapmh2ozmk4cl3pz0.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%2Fzouiapmh2ozmk4cl3pz0.png" alt="Running Task" width="800" height="976"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Notifications:
&lt;/h4&gt;

&lt;p&gt;When the task is complete, you'll see:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ Checkmark next to the task name&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;"View Result"&lt;/strong&gt; button&lt;/li&gt;
&lt;li&gt;Actual execution cost&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Payment and Receiving Results
&lt;/h2&gt;

&lt;h3&gt;
  
  
  How the X402 payment system works
&lt;/h3&gt;

&lt;p&gt;AgentBounty uses the innovative &lt;strong&gt;X402 Payment Protocol&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You create a task (payment NOT required)&lt;/li&gt;
&lt;li&gt;Agent performs the work&lt;/li&gt;
&lt;li&gt;Result is ready but hidden&lt;/li&gt;
&lt;li&gt;You see a &lt;strong&gt;preview&lt;/strong&gt; of the result&lt;/li&gt;
&lt;li&gt;Decide whether it's worth paying&lt;/li&gt;
&lt;li&gt;After payment, receive the full result&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;Advantage:&lt;/strong&gt; You pay only if satisfied with the quality!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Receiving results
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Step 1: Open the result
&lt;/h4&gt;

&lt;p&gt;When the task is completed, click &lt;strong&gt;"View Result"&lt;/strong&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 2: View preview
&lt;/h4&gt;

&lt;p&gt;You'll see:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First few lines of the report&lt;/li&gt;
&lt;li&gt;General structure of the answer&lt;/li&gt;
&lt;li&gt;Execution quality&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Step 3: Confirm payment (for tasks &amp;lt; $0.002)
&lt;/h4&gt;

&lt;p&gt;For small amounts, payment happens immediately:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A &lt;strong&gt;"Payment Required"&lt;/strong&gt; modal window will appear&lt;/li&gt;
&lt;li&gt;Exact amount will be indicated (e.g., $0.001 USDC)&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;"Approve Payment"&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&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%2F92nlppgvb5550ghoqn2y.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%2F92nlppgvb5550ghoqn2y.png" alt="Approve Payment" width="800" height="976"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 4: Sign transaction in MetaMask
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;MetaMask window will open&lt;/li&gt;
&lt;li&gt;You'll see a signature request (NOT a transaction!)&lt;/li&gt;
&lt;li&gt;Signature is &lt;strong&gt;free&lt;/strong&gt; — no gas required&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;"Sign"&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&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%2Flzb6vbld036xy2ea20fy.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%2Flzb6vbld036xy2ea20fy.png" alt="Sign" width="800" height="976"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;Important:&lt;/strong&gt; This is an EIP-712 signature, not a regular transaction. You don't pay gas fees!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Step 5: Receive result
&lt;/h4&gt;

&lt;p&gt;After signing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Payment will be processed instantly&lt;/li&gt;
&lt;li&gt;Result will open automatically&lt;/li&gt;
&lt;li&gt;You'll see the agent's full report&lt;/li&gt;
&lt;/ul&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%2Fk0put0d3srni3n8use2r.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%2Fk0put0d3srni3n8use2r.png" alt="Full Report" width="800" height="811"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Payment with confirmation (for tasks ≥ $0.002)
&lt;/h3&gt;

&lt;p&gt;For tasks costing $0.002 and above, &lt;strong&gt;additional confirmation&lt;/strong&gt; via email is required:&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 1: Request confirmation
&lt;/h4&gt;

&lt;p&gt;After clicking "View Result," you'll see:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Message about the need for confirmation&lt;/li&gt;
&lt;li&gt;Amount to be paid&lt;/li&gt;
&lt;li&gt;Request expiration time (usually 10 minutes)&lt;/li&gt;
&lt;/ul&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%2Ffwzpmvc2h2ptqsphc0ks.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%2Ffwzpmvc2h2ptqsphc0ks.png" alt=" " width="800" height="868"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 2: Check email
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Open your email (specified during registration)&lt;/li&gt;
&lt;li&gt;Find the email from &lt;strong&gt;AgentBounty&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Subject: "Payment Approval Required"&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Also check &lt;strong&gt;Spam&lt;/strong&gt; folder&lt;/li&gt;
&lt;/ol&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%2Fzbbh9vv8n24zrov50g2g.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%2Fzbbh9vv8n24zrov50g2g.png" alt="Payment Approval" width="800" height="1344"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;Tip:&lt;/strong&gt; Email may arrive with a 1-2 minute delay. Wait a bit.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Step 3: Confirm payment
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;In the email, click the &lt;strong&gt;"Approve Payment"&lt;/strong&gt; button&lt;/li&gt;
&lt;li&gt;Confirmation page will open&lt;/li&gt;
&lt;li&gt;You'll see payment details&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;"Confirm Approval"&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&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%2Fuaoiclh1edc1nzyh6zwj.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%2Fuaoiclh1edc1nzyh6zwj.png" alt=" " width="800" height="828"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 4: Return to the platform
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Return to the AgentBounty tab&lt;/li&gt;
&lt;li&gt;The system will &lt;strong&gt;automatically&lt;/strong&gt; detect the confirmation&lt;/li&gt;
&lt;li&gt;Transaction signature window will appear&lt;/li&gt;
&lt;li&gt;Sign in MetaMask&lt;/li&gt;
&lt;li&gt;Receive the result!&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Canceling payment
&lt;/h3&gt;

&lt;p&gt;If you change your mind about paying:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click &lt;strong&gt;"Cancel"&lt;/strong&gt; in the payment window&lt;/li&gt;
&lt;li&gt;Or simply close the modal window&lt;/li&gt;
&lt;li&gt;Money will not be debited&lt;/li&gt;
&lt;li&gt;Result will remain hidden&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Task History
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Viewing all tasks
&lt;/h3&gt;

&lt;p&gt;All your tasks are displayed on the main page as a list.&lt;/p&gt;




&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  💰 Payment Questions
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Q: How much does using agents cost?&lt;/strong&gt;&lt;br&gt;
A: Cost depends on agent type:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;FactCheck Agent: $0.001 USDC&lt;/li&gt;
&lt;li&gt;Travel Planner Agent: $0.002 USDC&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Q: Do I need to pay gas fees?&lt;/strong&gt;&lt;br&gt;
A: No! We use EIP-712 signatures that don't require gas. The platform covers gas payments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q: What if I don't have enough USDC?&lt;/strong&gt;&lt;br&gt;
A: You can create a task, but won't be able to pay and receive the result. Top up your balance and return to the task.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q: Can I cancel payment?&lt;/strong&gt;&lt;br&gt;
A: Before signing the transaction — yes. After signing — no, as blockchain transactions are irreversible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q: What if I'm not satisfied with the result?&lt;/strong&gt;&lt;br&gt;
A: You can see a preview before payment. If the result is clearly incorrect, don't pay.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔐 Security Questions
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Q: Is it safe to connect a wallet?&lt;/strong&gt;&lt;br&gt;
A: Yes. We use standard Web3 protocols. The platform doesn't have access to your private keys.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q: Can the platform debit more money?&lt;/strong&gt;&lt;br&gt;
A: No. The EIP-712 signature contains the exact amount. Debiting more is technically impossible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q: Is my data saved?&lt;/strong&gt;&lt;br&gt;
A: Yes. Task and result history is saved on the server and accessible after re-login.&lt;/p&gt;

&lt;h3&gt;
  
  
  🤖 Agent Questions
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Q: How long does a task take?&lt;/strong&gt;&lt;br&gt;
A: Usually 10-30 seconds for FactCheck and 20-60 seconds for Travel Planner.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q: What if the agent gives an error?&lt;/strong&gt;&lt;br&gt;
A: The task will move to "Failed" status, payment won't be required. You can create a new task.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q: Can I cancel a running task?&lt;/strong&gt;&lt;br&gt;
A: Not in the current version.&lt;/p&gt;

&lt;h3&gt;
  
  
  📧 Confirmation Questions
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Q: Why is email confirmation needed for some tasks?&lt;/strong&gt;&lt;br&gt;
A: It's a security measure for payments of $0.002 and above to prevent accidental or fraudulent charges.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q: Didn't receive confirmation email. What to do?&lt;/strong&gt;&lt;br&gt;
A:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Check "Spam" folder&lt;/li&gt;
&lt;li&gt;Wait 2-3 minutes&lt;/li&gt;
&lt;li&gt;Verify email correctness in your profile&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Q: Can I disable email confirmations?&lt;/strong&gt;&lt;br&gt;
A: Currently no, but we're considering an option for experienced users.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q: How long is the confirmation request valid?&lt;/strong&gt;&lt;br&gt;
A: Usually 10 minutes. After expiration, you need to create a new request.&lt;/p&gt;




&lt;h2&gt;
  
  
  Troubleshooting
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Wallet Connection Issues
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; MetaMask doesn't open when clicking "Connect Wallet"&lt;/p&gt;

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

&lt;ol&gt;
&lt;li&gt;Make sure MetaMask extension is installed and active&lt;/li&gt;
&lt;li&gt;Refresh the page (F5)&lt;/li&gt;
&lt;li&gt;Verify you're on the correct domain&lt;/li&gt;
&lt;li&gt;Try another browser&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; "Wrong network" error&lt;/p&gt;

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

&lt;ol&gt;
&lt;li&gt;Open MetaMask&lt;/li&gt;
&lt;li&gt;Switch to &lt;strong&gt;Base Sepolia&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;If the network isn't in the list, add it (see "Wallet Connection" section)&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; USDC balance shows 0&lt;/p&gt;

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

&lt;ol&gt;
&lt;li&gt;Verify you have USDC on Base Sepolia (not on another network!)&lt;/li&gt;
&lt;li&gt;Add USDC token to MetaMask manually: &lt;code&gt;0x036CbD53842c5426634e7929541eC2318f3dCF7e&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Wait 1-2 minutes for synchronization&lt;/li&gt;
&lt;li&gt;Refresh the page&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  Task Creation Issues
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; "Create Task" button is inactive&lt;/p&gt;

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

&lt;ol&gt;
&lt;li&gt;Verify all required fields are filled&lt;/li&gt;
&lt;li&gt;Make sure you're logged in&lt;/li&gt;
&lt;li&gt;Check browser console (F12) for errors&lt;/li&gt;
&lt;li&gt;Try refreshing the page&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; Task stuck in "Pending" status&lt;/p&gt;

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

&lt;ol&gt;
&lt;li&gt;Wait 1-2 minutes — tasks don't start instantly&lt;/li&gt;
&lt;li&gt;Refresh the page&lt;/li&gt;
&lt;li&gt;Check task status in a few minutes&lt;/li&gt;
&lt;li&gt;If problem persists, contact support&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  Payment Issues
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; MetaMask doesn't open for signature&lt;/p&gt;

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

&lt;ol&gt;
&lt;li&gt;Unlock MetaMask (enter password)&lt;/li&gt;
&lt;li&gt;Verify extension isn't blocked by browser&lt;/li&gt;
&lt;li&gt;Try closing and reopening payment window&lt;/li&gt;
&lt;li&gt;Refresh page and try again&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; "Insufficient balance" error&lt;/p&gt;

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

&lt;ol&gt;
&lt;li&gt;Check USDC balance in MetaMask&lt;/li&gt;
&lt;li&gt;Top up wallet&lt;/li&gt;
&lt;li&gt;Make sure you're on the correct network (Base Sepolia)&lt;/li&gt;
&lt;li&gt;Try again after topping up&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; Result doesn't open after signing&lt;/p&gt;

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

&lt;ol&gt;
&lt;li&gt;Wait 10-20 seconds — processing may take time&lt;/li&gt;
&lt;li&gt;Check browser console (F12) for errors&lt;/li&gt;
&lt;li&gt;Refresh page and click "View Result" again&lt;/li&gt;
&lt;li&gt;If payment went through (check MetaMask history), result will be available&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; Didn't receive email for payment confirmation&lt;/p&gt;

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

&lt;ol&gt;
&lt;li&gt;Check "Spam" folder&lt;/li&gt;
&lt;li&gt;Wait 2-3 minutes&lt;/li&gt;
&lt;li&gt;Verify correct email is specified in your profile&lt;/li&gt;
&lt;li&gt;Try creating task again&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  Result Issues
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; Result doesn't display after payment&lt;/p&gt;

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

&lt;ol&gt;
&lt;li&gt;Refresh page (F5)&lt;/li&gt;
&lt;li&gt;Check payment status in task list&lt;/li&gt;
&lt;li&gt;Click "View Result" again&lt;/li&gt;
&lt;li&gt;Clear browser cache (Ctrl+Shift+Delete)&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;Main article: &lt;a href="https://dev.to/prema_ananda/building-a-pay-per-use-ai-agent-marketplace-with-auth0-web3-5al0"&gt;Building a Pay-Per-Use AI Agent Marketplace with Auth0 + Web3&lt;/a&gt;&lt;/p&gt;

</description>
      <category>cryptocurrency</category>
      <category>tutorial</category>
      <category>ai</category>
      <category>web3</category>
    </item>
    <item>
      <title>Building a Pay-Per-Use AI Agent Marketplace with Auth0 + Web3</title>
      <dc:creator>Prema Ananda</dc:creator>
      <pubDate>Sat, 25 Oct 2025 10:17:59 +0000</pubDate>
      <link>https://dev.to/prema_ananda/building-a-pay-per-use-ai-agent-marketplace-with-auth0-web3-5al0</link>
      <guid>https://dev.to/prema_ananda/building-a-pay-per-use-ai-agent-marketplace-with-auth0-web3-5al0</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/auth0-2025-10-08"&gt;Auth0 for AI Agents Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;AgentBounty&lt;/strong&gt; is a marketplace where AI agents authenticate via Auth0, execute tasks, and users pay per-use in USDC with gasless transactions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Innovation:&lt;/strong&gt; Auth0 (authentication) + X402 Protocol (payment gating) + EIP-712 (gasless signatures) = Perfect AI monetization stack.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Problem
&lt;/h3&gt;

&lt;p&gt;Building AI agent marketplaces requires solving multiple authentication and security challenges:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Challenge&lt;/th&gt;
&lt;th&gt;Traditional Approach&lt;/th&gt;
&lt;th&gt;Auth0 Approach&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;🔐 &lt;strong&gt;User Authentication&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Build OAuth2 flows from scratch&lt;/td&gt;
&lt;td&gt;Ready in minutes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🌐 &lt;strong&gt;Social Login&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Integrate each provider separately&lt;/td&gt;
&lt;td&gt;Toggle switches in dashboard&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🔒 &lt;strong&gt;MFA/2FA&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Custom implementation&lt;/td&gt;
&lt;td&gt;Built-in feature&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;📊 &lt;strong&gt;User Metadata&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Design database schema + API&lt;/td&gt;
&lt;td&gt;Management API included&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;⚖️ &lt;strong&gt;GDPR Compliance&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Legal review + implementation&lt;/td&gt;
&lt;td&gt;Handled automatically&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🛡️ &lt;strong&gt;Security Updates&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Manual patching and monitoring&lt;/td&gt;
&lt;td&gt;Automatic updates&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Bottom Line:&lt;/strong&gt; Auth0 let me skip building authentication infrastructure and focus on what makes my product unique: AI agent integration, Web3 payments, and user experience.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tech Stack
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Auth:&lt;/strong&gt; Auth0 OAuth2 + Management API + Async Payment Approval&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backend:&lt;/strong&gt; FastAPI (Python), SQLite&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Frontend:&lt;/strong&gt; Vanilla JS, Tailwind CSS&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI:&lt;/strong&gt; Google Gemini API, Bright Data MCP Server&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Payments:&lt;/strong&gt; X402 Protocol, EIP-712, ERC-3009&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Blockchain:&lt;/strong&gt; Base Sepolia, USDC&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🎬 Demo
&lt;/h2&gt;

&lt;h3&gt;
  
  
  📸 Screenshots
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Auth0 Universal Login (works out of the box):&lt;/strong&gt;&lt;br&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%2F5o0monmgkjecsv4fxfxs.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%2F5o0monmgkjecsv4fxfxs.png" alt="Login" width="800" height="1222"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AI Agent Marketplace:&lt;/strong&gt;&lt;br&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%2Fitqy4ekka7a6d4sd24x7.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%2Fitqy4ekka7a6d4sd24x7.png" alt="Homepage" width="800" height="821"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;FactCheck Agent Results:&lt;/strong&gt;&lt;br&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%2Fe4f8cxdcyweph600kt67.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%2Fe4f8cxdcyweph600kt67.png" alt="FactCheck" width="800" height="568"&gt;&lt;/a&gt;&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%2Fuploads%2Farticles%2Fpisrnv4q0snhzkyew1qu.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%2Fpisrnv4q0snhzkyew1qu.png" alt="FactCheck Agent" width="800" height="976"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Gasless Payment via MetaMask:&lt;/strong&gt;&lt;br&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%2F35mdzmccqmarl20y6yud.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%2F35mdzmccqmarl20y6yud.png" alt="MetaMask" width="800" height="976"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Want to dive deeper? Check out these guides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://dev.to/prema_ananda/agentbounty-user-guide-454o"&gt;🚀 AgentBounty User Guide&lt;/a&gt;&lt;/strong&gt; - Step-by-step instructions for end users covering account setup, wallet connection, and running AI agents&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://dev.to/prema_ananda/m2m-api-integration-guide-4k3h"&gt;🔧 M2M API Integration Guide&lt;/a&gt;&lt;/strong&gt; - Technical guide for developers integrating AgentBounty programmatically with code examples&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Source Code:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/premananda108/AgentBounty" rel="noopener noreferrer"&gt;https://github.com/premananda108/AgentBounty&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  How I Used Auth0 for AI Agents
&lt;/h2&gt;

&lt;p&gt;Auth0 isn't just "login"—it's the entire security and identity infrastructure. Here's how I used Auth0 to solve real problems:&lt;/p&gt;
&lt;h3&gt;
  
  
  Problem 1: User Authentication
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Without Auth0, I would need to build:&lt;/strong&gt;&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 a custom auth system requires:
&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt; &lt;span class="n"&gt;registration&lt;/span&gt; &lt;span class="n"&gt;endpoint&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;Password&lt;/span&gt; &lt;span class="nf"&gt;hashing &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bcrypt&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;argon2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;Email&lt;/span&gt; &lt;span class="n"&gt;verification&lt;/span&gt; &lt;span class="n"&gt;system&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;Password&lt;/span&gt; &lt;span class="n"&gt;reset&lt;/span&gt; &lt;span class="n"&gt;flow&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;Session&lt;/span&gt; &lt;span class="n"&gt;management&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;CSRF&lt;/span&gt; &lt;span class="n"&gt;protection&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;Rate&lt;/span&gt; &lt;span class="n"&gt;limiting&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;Security&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;Continuous&lt;/span&gt; &lt;span class="n"&gt;security&lt;/span&gt; &lt;span class="n"&gt;monitoring&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;many&lt;/span&gt; &lt;span class="n"&gt;more&lt;/span&gt; &lt;span class="n"&gt;security&lt;/span&gt; &lt;span class="n"&gt;considerations&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;With Auth0:&lt;/strong&gt;&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;# app/main.py - Complete auth setup
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;authlib.integrations.starlette_client&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OAuth&lt;/span&gt;

&lt;span class="c1"&gt;# OAuth client configuration
&lt;/span&gt;&lt;span class="n"&gt;oauth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OAuth&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;oauth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;register&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;auth0&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;client_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AUTH0_CLIENT_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;client_secret&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AUTH0_CLIENT_SECRET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;server_metadata_url&lt;/span&gt;&lt;span class="o"&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;https://&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AUTH0_DOMAIN&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/.well-known/openid-configuration&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;client_kwargs&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;scope&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;openid profile email offline_access&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;&lt;strong&gt;What I got included:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ OAuth2 + OIDC compliance&lt;/li&gt;
&lt;li&gt;✅ PKCE for mobile security&lt;/li&gt;
&lt;li&gt;✅ Automatic token refresh&lt;/li&gt;
&lt;li&gt;✅ Secure session management&lt;/li&gt;
&lt;li&gt;✅ Brute-force protection&lt;/li&gt;
&lt;li&gt;✅ Breached password detection&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Developer Benefit:&lt;/strong&gt; I could focus on building product features instead of security infrastructure.&lt;/p&gt;




&lt;h3&gt;
  
  
  Problem 2: Social Login (GitHub, Google)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Traditional approach requires:&lt;/strong&gt;&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="n"&gt;For&lt;/span&gt; &lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="n"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="mf"&gt;1.&lt;/span&gt; &lt;span class="n"&gt;Register&lt;/span&gt; &lt;span class="n"&gt;OAuth&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="n"&gt;on&lt;/span&gt; &lt;span class="n"&gt;GitHub&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;Google&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;etc&lt;/span&gt;
&lt;span class="mf"&gt;2.&lt;/span&gt; &lt;span class="n"&gt;Handle&lt;/span&gt; &lt;span class="n"&gt;OAuth&lt;/span&gt; &lt;span class="n"&gt;callback&lt;/span&gt; &lt;span class="n"&gt;flow&lt;/span&gt;
&lt;span class="mf"&gt;3.&lt;/span&gt; &lt;span class="n"&gt;Store&lt;/span&gt; &lt;span class="n"&gt;OAuth&lt;/span&gt; &lt;span class="n"&gt;tokens&lt;/span&gt; &lt;span class="n"&gt;securely&lt;/span&gt;
&lt;span class="mf"&gt;4.&lt;/span&gt; &lt;span class="n"&gt;Handle&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="n"&gt;refresh&lt;/span&gt;
&lt;span class="mf"&gt;5.&lt;/span&gt; &lt;span class="n"&gt;Map&lt;/span&gt; &lt;span class="n"&gt;provider&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;local&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;
&lt;span class="mf"&gt;6.&lt;/span&gt; &lt;span class="n"&gt;Handle&lt;/span&gt; &lt;span class="n"&gt;edge&lt;/span&gt; &lt;span class="nf"&gt;cases &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="n"&gt;changes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;account&lt;/span&gt; &lt;span class="n"&gt;linking&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;With Auth0:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Auth0 handles:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ OAuth app credentials management&lt;/li&gt;
&lt;li&gt;✅ Token storage and refresh&lt;/li&gt;
&lt;li&gt;✅ User profile normalization&lt;/li&gt;
&lt;li&gt;✅ Account linking (same email → same user)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Configuration in Auth0 Dashboard:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to Authentication → Social&lt;/li&gt;
&lt;li&gt;Click "Google" → Enable&lt;/li&gt;
&lt;li&gt;Click "GitHub" → Enable&lt;/li&gt;
&lt;li&gt;Done!&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Developer Benefit:&lt;/strong&gt; Adding new social providers takes minutes instead of days of integration work.&lt;/p&gt;




&lt;h3&gt;
  
  
  Problem 3: Web3 Wallet Linking
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Challenge:&lt;/strong&gt; Users need to link their MetaMask wallet to their Auth0 account for crypto payments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Traditional Approach:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Where to store wallet addresses?
- Design database schema
- Create API endpoints for CRUD
- Handle updates and validation
- Ensure persistence across sessions
- Maintain separate user data store
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Auth0 Solution: User Metadata&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Auth0 provides a flexible &lt;code&gt;user_metadata&lt;/code&gt; field for storing custom user data:&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;# app/routers/wallet.py
&lt;/span&gt;&lt;span class="nd"&gt;@router.post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/connect&lt;/span&gt;&lt;span class="sh"&gt;"&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;connect_wallet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ConnectWalletRequest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Depends&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;require_auth&lt;/span&gt;&lt;span class="p"&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;
    Connect Web3 wallet to Auth0 account

    User must be logged in with Auth0 first.
    Verifies wallet ownership via signature.
    Saves wallet_address to Auth0 user_metadata.
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;

    &lt;span class="n"&gt;auth0_user_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;sub&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;user_email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;email&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;unknown&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Verify signature (proof of wallet ownership)
&lt;/span&gt;    &lt;span class="n"&gt;w3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Web3&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;encode_defunct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why this works:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;No extra database:&lt;/strong&gt; Wallet address stored with Auth0 user&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Single source of truth:&lt;/strong&gt; One user profile, multiple attributes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Persistence:&lt;/strong&gt; Survives across sessions, devices&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security:&lt;/strong&gt; Management API requires authentication&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flexibility:&lt;/strong&gt; Can add more attributes anytime&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Developer Benefit:&lt;/strong&gt; No need to maintain separate user data storage. Auth0 becomes both authentication AND user database.&lt;/p&gt;




&lt;h3&gt;
  
  
  Problem 4: Async Payment Approval (2FA for Payments)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Challenge:&lt;/strong&gt; High-value crypto payments need user confirmation before processing.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;User initiates payment in browser&lt;/li&gt;
&lt;li&gt;Backend holds transaction&lt;/li&gt;
&lt;li&gt;User approves via separate channel (email/SMS)&lt;/li&gt;
&lt;li&gt;Backend executes approved transaction&lt;/li&gt;
&lt;li&gt;Must be secure and auditable&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What Auth0 handles:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ Approval email/SMS delivery&lt;/li&gt;
&lt;li&gt;✅ Secure approval links with expiration&lt;/li&gt;
&lt;li&gt;✅ Callback to your backend&lt;/li&gt;
&lt;li&gt;✅ Audit trail of all approvals&lt;/li&gt;
&lt;li&gt;✅ Replay attack prevention&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Security benefits:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Two-factor confirmation:&lt;/strong&gt; User approves in separate channel&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Time-limited:&lt;/strong&gt; Approval expires after 5 minutes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Non-repudiation:&lt;/strong&gt; Auth0 logs who approved what&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Audit trail:&lt;/strong&gt; Every payment tied to Auth0 user_id&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Lessons Learned and Takeaways
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ✅ What Worked Brilliantly
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. Zero Upfront Investment&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Auth0 Free Tier allowed me to:
- Build entire MVP
- Launch to early users
- Validate product idea
- All at no cost

Traditional approach:
- Significant development time upfront
- Long runway before first user
- Higher risk if product doesn't work out
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Focus on Differentiation&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;With Auth0:
- Minimal time on authentication
- Maximum time on unique features (X402, AI agents, Web3)

Without Auth0:
- Significant time on authentication infrastructure
- Less time for product innovation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Enterprise Features from Day 1&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Features I got immediately:
✅ Brute-force protection
✅ Breached password detection
✅ MFA/2FA
✅ GDPR compliance
✅ High availability

Building these manually would take considerable effort
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4. Scalability Without Refactoring&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Auth0 scales automatically:
- Small user base: Works perfectly
- Growing user base: Works perfectly
- Large user base: Still works perfectly

Custom auth system:
- Often needs refactoring as you scale
- Performance optimization required
- Infrastructure management overhead
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;5. Management API = Hidden Gem&lt;/strong&gt;&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;# User metadata as a database
# This eliminated the need for:
&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt; &lt;span class="n"&gt;settings&lt;/span&gt; &lt;span class="n"&gt;system&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;Preferences&lt;/span&gt; &lt;span class="n"&gt;storage&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;Wallet&lt;/span&gt; &lt;span class="n"&gt;linking&lt;/span&gt; &lt;span class="n"&gt;tables&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;Custom&lt;/span&gt; &lt;span class="n"&gt;attributes&lt;/span&gt; &lt;span class="n"&gt;database&lt;/span&gt;

&lt;span class="n"&gt;Just&lt;/span&gt; &lt;span class="n"&gt;use&lt;/span&gt; &lt;span class="n"&gt;Auth0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;auth0_service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update_user_metadata&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&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;wallet_address&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;0x...&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;preferred_chain&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;base&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;notifications&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;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;email&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;mcp_usage_count&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Developer Insight:&lt;/strong&gt; Auth0's Management API serves as user metadata storage. I built a complete user profile system without writing database migrations or CRUD APIs.&lt;/p&gt;

&lt;h3&gt;
  
  
  ⚠️ Challenges &amp;amp; How I Solved Them
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Rate Limits on Management API&lt;/strong&gt;&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;# Problem: Hitting 429 Too Many Requests
# Solution: Aggressive caching
&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Auth0Service&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="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_token_cache&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;  &lt;span class="c1"&gt;# 23h TTL
&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;_profile_cache&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;  &lt;span class="c1"&gt;# 5min TTL
&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;get_user_profile&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;user_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# Check cache first
&lt;/span&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt; &lt;span class="ow"&gt;in&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;_profile_cache&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expires&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;_profile_cache&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;utcnow&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;expires&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;profile&lt;/span&gt;

        &lt;span class="c1"&gt;# Fetch from Auth0
&lt;/span&gt;        &lt;span class="n"&gt;profile&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;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_fetch_profile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;# Cache for 5 minutes
&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;_profile_cache&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;utcnow&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nf"&gt;timedelta&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;minutes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&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;profile&lt;/span&gt;

&lt;span class="c1"&gt;# Result: Drastically reduced API calls
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  For AI Agent Platforms (like AgentBounty)
&lt;/h3&gt;

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

&lt;ul&gt;
&lt;li&gt;✅ User metadata perfect for agent preferences&lt;/li&gt;
&lt;li&gt;✅ M2M authentication for automated systems&lt;/li&gt;
&lt;li&gt;✅ Async Payment Approval for safe transactions&lt;/li&gt;
&lt;li&gt;✅ Audit trail for compliance&lt;/li&gt;
&lt;li&gt;✅ Scales with usage&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;⚠️ Need custom logic for wallet linking (straightforward to implement)&lt;/li&gt;
&lt;li&gt;⚠️ Management API rate limits (solved with caching)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Verdict:&lt;/strong&gt; Well-suited for this use case.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Live Demo:&lt;/strong&gt; &lt;a href="https://agentbounty.premananda.site" rel="noopener noreferrer"&gt;https://agentbounty.premananda.site&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/premananda108/AgentBounty" rel="noopener noreferrer"&gt;https://github.com/premananda108/AgentBounty&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🙏 Closing Thoughts
&lt;/h2&gt;

&lt;p&gt;Building AgentBounty taught me that &lt;strong&gt;identity is infrastructure&lt;/strong&gt;—just like databases, message queues, and cloud storage.&lt;/p&gt;

&lt;p&gt;You don't build PostgreSQL from scratch. You don't build Kafka from scratch. &lt;strong&gt;You shouldn't build authentication from scratch.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Auth0 let me focus on what makes AgentBounty unique: X402 payments, AI agents, Web3 integration. The authentication layer was handled efficiently.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;To other developers:&lt;/strong&gt; If you're building anything that needs users, consider using Auth0. It's a practical choice that lets you focus on your product's unique value.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Auth0: &lt;a href="https://auth0.com/docs" rel="noopener noreferrer"&gt;https://auth0.com/docs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;X402 Protocol: &lt;a href="https://www.coinbase.com/developer-platform/products/x402" rel="noopener noreferrer"&gt;https://www.coinbase.com/developer-platform/products/x402&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Bright Data MCP: &lt;a href="https://docs.brightdata.com/mcp-server/overview#mcp-server-overview" rel="noopener noreferrer"&gt;https://docs.brightdata.com/mcp-server/overview#mcp-server-overview&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;EIP-712: &lt;a href="https://eips.ethereum.org/EIPS/eip-712" rel="noopener noreferrer"&gt;https://eips.ethereum.org/EIPS/eip-712&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;ERC-3009: &lt;a href="https://eips.ethereum.org/EIPS/eip-3009" rel="noopener noreferrer"&gt;https://eips.ethereum.org/EIPS/eip-3009&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Built with ❤️ for the Auth0 for AI Agents Challenge&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>auth0challenge</category>
      <category>ai</category>
      <category>authentication</category>
    </item>
    <item>
      <title>Building a Hands-Free AI Fitness Applet with Gemini Live API</title>
      <dc:creator>Prema Ananda</dc:creator>
      <pubDate>Sun, 14 Sep 2025 12:49:57 +0000</pubDate>
      <link>https://dev.to/prema_ananda/building-a-hands-free-ai-fitness-applet-with-gemini-live-api-3fg1</link>
      <guid>https://dev.to/prema_ananda/building-a-hands-free-ai-fitness-applet-with-gemini-live-api-3fg1</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/google-ai-studio-2025-09-03"&gt;Google AI Studio Multimodal Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;AI Personal Trainer is an experimental fitness app with a "voice-first" approach that turns your smartphone into an interactive workout partner. The app is primarily controlled by voice commands, allowing you to focus on exercises rather than the screen.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The problem I'm exploring:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Distractions during workouts:&lt;/strong&gt; The need to constantly interact with the phone screen&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lack of personalization:&lt;/strong&gt; Most apps offer one-size-fits-all solutions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Passive interaction:&lt;/strong&gt; Apps work as trackers rather than assistants&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Implemented features:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🎤 &lt;strong&gt;Voice program creation:&lt;/strong&gt; Dialog with AI to create personalized workout programs&lt;/li&gt;
&lt;li&gt;🧠 &lt;strong&gt;Real-time audio interaction:&lt;/strong&gt; Two-way voice communication during workouts&lt;/li&gt;
&lt;li&gt;📊 &lt;strong&gt;Comprehensive database system:&lt;/strong&gt; System for storing programs, sessions, and progress&lt;/li&gt;
&lt;li&gt;📈 &lt;strong&gt;Analytics dashboard:&lt;/strong&gt; Visual progress tracking and performance insights&lt;/li&gt;
&lt;li&gt;📅 &lt;strong&gt;Google Calendar integration:&lt;/strong&gt; Automatic addition of workouts to calendar&lt;/li&gt;
&lt;li&gt;🎯 &lt;strong&gt;Hybrid architecture:&lt;/strong&gt; Combining dialog speed with analysis accuracy&lt;/li&gt;
&lt;/ul&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%2Fxj26m7id9kng8x5arhcr.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%2Fxj26m7id9kng8x5arhcr.png" alt="Mobil"&gt;&lt;/a&gt;&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%2Fuploads%2Farticles%2Fm8toexiqgmp6vmn21xfx.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%2Fm8toexiqgmp6vmn21xfx.png" alt="Browser"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;📱 &lt;a href="https://ai.studio/apps/drive/1ANEWC21ioL7u5V6uGi-DpkaVSecfPPef" rel="noopener noreferrer"&gt;View in AI Studio&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;💻 &lt;a href="https://github.com/premananda108/ai-personal-trainer.git" rel="noopener noreferrer"&gt;GitHub Repository:ai-personal-trainer&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/jHRcm4CFEuY"&gt;
  &lt;/iframe&gt;
&lt;br&gt;
Thanks @aquascript-team for help with the video!&lt;/p&gt;
&lt;h2&gt;
  
  
  How I Used Google AI Studio
&lt;/h2&gt;

&lt;p&gt;Development started directly in &lt;strong&gt;Google AI Studio&lt;/strong&gt;, where I experimented with different approaches to multimodal interaction.&lt;/p&gt;
&lt;h3&gt;
  
  
  Development process:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Prototyping in Google AI Studio:&lt;/strong&gt; Creating user interface and initial system setup&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Export and development:&lt;/strong&gt; Downloaded the project for local development&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Extended development:&lt;/strong&gt; Used &lt;strong&gt;Gemini CLI&lt;/strong&gt; to integrate complex functions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Final deployment:&lt;/strong&gt; Uploaded the finished project and used &lt;strong&gt;Deploy App&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  Two-model architecture:
&lt;/h3&gt;
&lt;h4&gt;
  
  
  Main model: Real-time dialog
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Connection to live audio dialog&lt;/span&gt;
&lt;span class="nx"&gt;sessionRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;clientRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;live&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;gemini-2.5-flash-preview-native-audio-dialog&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;callbacks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;onopen&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setConnectionStatus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;connected&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;onmessage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Processing user speech&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;serverContent&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;inputTranscription&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;userText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;serverContent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;inputTranscription&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nf"&gt;onTranscript&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userText&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="c1"&gt;// Playing AI response  &lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;audio&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;serverContent&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;modelTurn&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;parts&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="nx"&gt;inlineData&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;audio&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;outputAudioContextRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;playAudioResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;audio&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;systemInstruction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;createDynamicPrompt&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="na"&gt;responseModalities&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;Modality&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;AUDIO&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;outputAudioTranscription&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;--- Enable LLM transcription&lt;/span&gt;
    &lt;span class="na"&gt;inputAudioTranscription&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;--- Enable user transcription&lt;/span&gt;
    &lt;span class="na"&gt;speechConfig&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;voiceConfig&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;prebuiltVoiceConfig&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;voiceName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Orus&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&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;h4&gt;
  
  
  Analytics model: Data extraction
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Precise interpretation of user commands&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;interpretWorkoutCommand&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;transcript&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;log_set&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;get_form_tip&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;chat_message&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;reps&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;weight&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`You are an AI assistant interpreting voice commands from a user during a workout. The user's voice transcript is: "&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;transcript&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;".

    Your task is to analyze the transcript and classify it into one of the following commands, extracting relevant data.

    POSSIBLE COMMANDS:
    1. 'log_set': The user is reporting the completion of a set. They might mention repetitions (reps) and/or weight.
       - Keywords: "done", "finished", "log it", "reps", "weight", "kilos", numbers.
       - Example Transcripts: "Okay, 12 reps at 50 kilos", "I'm done", "8 reps", "log 90 pounds".
    2. 'get_form_tip': The user is asking for advice on their exercise form.
       - Keywords: "form", "technique", "how do I do this", "am I doing it right".
       - Example Transcripts: "check my form", "what's the technique for this".
    3. 'chat_message': The user is saying something else, likely a question or comment for the AI coach. This is the default if no other command fits.
       - Example Transcripts: "how many sets left", "I'm feeling tired", "what's the next exercise".

    Respond in JSON format with "command" and optional "data".
    - For 'log_set', 'data' should be an object with optional 'reps' and 'weight' numbers.
    - For 'get_form_tip', 'data' should be null.
    - For 'chat_message', 'data' should be an object with the original transcript as 'text'.

    Return ONLY the JSON object.

    Example Responses:
    - Transcript: "10 reps at 80 kg" -&amp;gt; { "command": "log_set", "data": { "reps": 10, "weight": 80 } }
    - Transcript: "how do I do this right?" -&amp;gt; { "command": "get_form_tip", "data": null }
    - Transcript: "what's the next exercise?" -&amp;gt; { "command": "chat_message", "data": { "text": "what's the next exercise?" } }
    `&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;ai&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;generateContent&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gemini-2.5-flash&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;contents&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;prompt&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;h2&gt;
  
  
  Multimodal Capabilities
&lt;/h2&gt;
&lt;h3&gt;
  
  
  1. &lt;strong&gt;Seamless audio interaction&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Implemented:&lt;/strong&gt; using client.live.connect from &lt;strong&gt;Gemini Live API SDK&lt;/strong&gt; connection with continuous bidirectional streaming&lt;br&gt;
&lt;strong&gt;Uniqueness:&lt;/strong&gt; Works like a phone conversation — you can interrupt and get instant responses&lt;/p&gt;
&lt;h3&gt;
  
  
  2. &lt;strong&gt;Hybrid command processing&lt;/strong&gt;
&lt;/h3&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Dialog Model&lt;/strong&gt;: Maintains natural conversation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Analysis Model&lt;/strong&gt;: Extracts precise data from speech&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Processing example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User: "Did eight reps with sixty kilos, felt pretty easy"

Dialog Model → "Great! Logged 8 reps with 60 kg. Should we increase the weight?"
Analysis Model → 
  {
    "command": "log_set",
    "data": {
      "reps": 8,
      "weight": 60
    }
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. &lt;strong&gt;Full-featured data system&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Implemented architecture:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Workout programs&lt;/strong&gt; (&lt;code&gt;/programs/{programId}&lt;/code&gt;):&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="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;"Strength program, 12 weeks"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"createdBy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"userId"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"workouts"&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;"day1"&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;"dayName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Chest and triceps"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exercises"&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"exerciseId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"bench_press"&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;"Barbell bench press"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"sets"&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="nl"&gt;"reps"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"weight"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;}],&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"rest"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;120&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="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="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;Detailed training sessions&lt;/strong&gt; (&lt;code&gt;/sessions/{sessionId}&lt;/code&gt;):&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="nl"&gt;"userId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"user123"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"date"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2024-01-15T10:00:00Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"programId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"strength_program_001"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"workoutId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"day1_chest"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"duration"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5400&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;seconds&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"voiceTranscript"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Complete log of conversation with AI..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"performedSets"&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;"set001"&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;"exerciseId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"bench_press"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"setNumber"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"reps"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"weight"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;62.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"timestamp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2024-01-15T10:15:30Z"&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="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. &lt;strong&gt;Automatic calendar integration&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Implemented:&lt;/strong&gt; Direct integration with Google Calendar API&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;scheduleWorkouts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;workouts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Workout&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="nx"&gt;accessToken&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;workouts&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;workouts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;No workouts to schedule.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;schedulePromises&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;workouts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;workout&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;startTime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getNextWorkoutDate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;workout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dayOfWeek&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;endTime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;startTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getTime&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Assume 1-hour duration&lt;/span&gt;

        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;summary&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Workout: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;workout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dayName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;description&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Your scheduled workout session.\n\nExercises:\n- &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;workout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exercises&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&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="dl"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;- &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;start&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dateTime&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;startTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toISOString&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
                &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;timeZone&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DateTimeFormat&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;resolvedOptions&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;timeZone&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;end&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dateTime&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;endTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toISOString&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
                &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;timeZone&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DateTimeFormat&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;resolvedOptions&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;timeZone&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://www.googleapis.com/calendar/v3/calendars/primary/events&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Authorization&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Bearer &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;accessToken&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;schedulePromises&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;h3&gt;
  
  
  5. &lt;strong&gt;Contextual understanding of fitness terminology&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;AI understands specific vocabulary:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Recognition of data for set logging (&lt;code&gt;log_set&lt;/code&gt;): AI searches user speech for numbers and keywords (such as "reps", "times", "weight", "pounds") to automatically fill in data about completed sets.&lt;/li&gt;
&lt;li&gt;Processing requests and comments (&lt;code&gt;get_form_tip&lt;/code&gt;, &lt;code&gt;chat_message&lt;/code&gt;): Phrases that don't contain direct data for logging are processed as trainer requests or simple comments.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  6. &lt;strong&gt;Comprehensive Analytics Dashboard&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Implemented:&lt;/strong&gt; A dedicated analytics section that provides detailed insights into workout performance and progress tracking.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Features include:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Visual progress charts and graphs&lt;/li&gt;
&lt;li&gt;Historical workout data visualization&lt;/li&gt;
&lt;li&gt;Performance metrics and trends analysis&lt;/li&gt;
&lt;/ul&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%2Fyqdby4xdkb0m3pgy4vi4.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%2Fyqdby4xdkb0m3pgy4vi4.png" alt="Analitics"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Current MVP Limitations
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Main challenges:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Speech recognition accuracy:&lt;/strong&gt; AI doesn't always correctly interpret commands in live dialog, especially with background noise&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Command execution:&lt;/strong&gt; The model sometimes "forgets" to execute specific actions in the app after responding&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Why Multimodality Matters for Fitness
&lt;/h2&gt;

&lt;p&gt;Traditional fitness apps force you to choose: EITHER data tracking OR workout focus. The multimodal approach solves this dilemma:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Voice interface&lt;/strong&gt; allows you to stay focused on exercises&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Intelligent speech analysis&lt;/strong&gt; structures data automatically
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real-time feedback&lt;/strong&gt; creates the feeling of a personal trainer&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automatic workout scheduling&lt;/strong&gt; integrates fitness into daily life&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The result is a fitness companion that understands natural speech and adapts to each user's unique style.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; &lt;em&gt;Despite my AI trainer being quite smart and motivating, we strongly recommend maintaining common sense, especially when it comes to health matters. 💪&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Acknowledgments
&lt;/h2&gt;

&lt;p&gt;I express deep gratitude to the organizers of the &lt;strong&gt;Google AI Studio Multimodal Challenge&lt;/strong&gt; for the unique opportunity to experiment with cutting-edge artificial intelligence technologies.&lt;/p&gt;

&lt;p&gt;Special thanks to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The Google AI Studio team&lt;/strong&gt; for the intuitive platform that makes complex technologies accessible&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gemini Live Audio API developers&lt;/strong&gt; for the revolutionary real-time voice interaction technology&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Dev.to community&lt;/strong&gt; for providing an inspiring platform for innovative projects&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This project was made possible by an ecosystem of cutting-edge tools and the supportive developer community that Google AI creates.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;MVP developed with React, TypeScript, Firebase, Google Calendar API and Google Gemini multimodal capabilities&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Built with ❤️ by Premananda&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>googleaichallenge</category>
      <category>ai</category>
      <category>gemini</category>
    </item>
    <item>
      <title>My Summer 2025 Dev Journey: AI Challenges, Robot Adventures, and Community Growth 🌞</title>
      <dc:creator>Prema Ananda</dc:creator>
      <pubDate>Sun, 31 Aug 2025 10:59:32 +0000</pubDate>
      <link>https://dev.to/prema_ananda/my-summer-2025-dev-journey-ai-challenges-robot-adventures-and-community-growth-2jka</link>
      <guid>https://dev.to/prema_ananda/my-summer-2025-dev-journey-ai-challenges-robot-adventures-and-community-growth-2jka</guid>
      <description>&lt;p&gt;As August comes to an end, I can't help but reflect on what has been an absolutely incredible summer — full of programming, learning, and pushing the boundaries of what's possible with AI and web technologies. From building AI systems to literally "bringing a robot to life" — this summer has been a real adventure that I want to share with you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Challenge Marathon 🏃‍♂️
&lt;/h2&gt;

&lt;p&gt;This summer turned into a personal challenge marathon, and honestly, I enjoyed every minute of it:&lt;/p&gt;

&lt;h3&gt;
  
  
  Redis AI Challenge: Beyond Caching
&lt;/h3&gt;

&lt;p&gt;The Redis AI Challenge became a real turning point for me. Instead of simply using Redis for caching, I dove deeper and transformed it into the forum's primary database. The result? A lightning-fast system that handles everything — from user data to AI-powered content recommendations. &lt;a href="https://dev.to/prema_ananda/beyond-caching-how-redis-8-became-our-forums-primary-database-and-ai-engine-1m5"&gt;You can read the full description of this journey here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Takeaway&lt;/strong&gt;: The best solutions come from simple, well-thought-out architecture.&lt;/p&gt;

&lt;h3&gt;
  
  
  Algolia MCP Server: Learning Through Difficulties
&lt;/h3&gt;

&lt;p&gt;The Algolia MCP Server Challenge taught me that sometimes documentation isn't enough — you need to roll up your sleeves and dig in yourself. Building a Python client from scratch was frustrating at times, but incredibly rewarding. &lt;a href="https://dev.to/prema_ananda/learning-mcp-the-hard-way-building-a-python-client-for-algolias-mcp-server-14dn"&gt;Check out my battle scars and victories&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lesson Learned&lt;/strong&gt;: To study a technology, you need to fully immerse yourself in the project, learning all the nuances.&lt;/p&gt;

&lt;h3&gt;
  
  
  Postmark Challenge: Email Stories on Maps
&lt;/h3&gt;

&lt;p&gt;Who would have thought that emails could tell geographical stories? The Postmark challenge led me to create MailMap — transforming mundane email data into interactive adventures on Google Maps. &lt;a href="https://dev.to/prema_ananda/mailmap-transforming-emails-into-interactive-stories-on-google-maps-1f10"&gt;Read about simple email-based mapping approach&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  n8n &amp;amp; BrightData Challenge: Multi-Agent Brand Monitoring
&lt;/h3&gt;

&lt;p&gt;One of the most complex projects this summer was building BrandGuard AI - a comprehensive multi-agent brand monitoring system. Using n8n's visual programming and BrightData's reliable data streams, I created an intelligent platform that automatically tracks brand mentions across Twitter, Reddit, and LinkedIn, analyzes them with Google Gemini AI, and delivers insights through a Slack bot and web dashboard. &lt;a href="https://dev.to/prema_ananda/building-a-multi-agent-ai-brand-monitoring-system-with-n8n-and-brightdata-oe0"&gt;Dive into the multi-agent architecture&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Technical Insight&lt;/strong&gt;: This project showed me the power of no-code platforms for creating enterprise-level AI solutions with minimal time investment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Robot Revolution 🤖
&lt;/h2&gt;

&lt;p&gt;But the real highlight of my summer was giving the NAO robot the power of Google Gemini AI. Imagine: a humanoid robot that doesn't just move and dance, but actually thinks and responds intelligently. &lt;a href="https://dev.to/prema_ananda/how-gemini-cli-got-a-nao-robot-body-4088"&gt;The full story of this AI-robot fusion is here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This project taught me that the future isn't just about software, but about creating meaningful bridges between the digital and physical worlds.&lt;/p&gt;

&lt;h2&gt;
  
  
  Community Growth and Personal Wins 📈
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Building Consistency
&lt;/h3&gt;

&lt;p&gt;One of my main victories this summer was building stable community engagement. From a weekly streak to an 8-week Community Wellness streak — it's amazing how much you learn when you commit to showing up every day.&lt;/p&gt;

&lt;h2&gt;
  
  
  Technical Achievements 💻
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Stack Evolution
&lt;/h3&gt;

&lt;p&gt;My main stack this summer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Backend&lt;/strong&gt;: Python/Flask/FastAPI (still love this combination)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cloud&lt;/strong&gt;: Google Cloud (diving deeper into their AI services)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI&lt;/strong&gt;: Redis for vector search, Google Gemini for natural language processing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Databases&lt;/strong&gt;: MongoDB&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cloudflare Tunnel&lt;/strong&gt;: secure outbound tunnel from server to Cloudflare network&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deployment&lt;/strong&gt;: Debian servers (reliable as always)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;New Addition&lt;/strong&gt;: n8n, BrightData and MCP (Model Context Protocol) for AI service integration&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Problem-Solving Approach
&lt;/h3&gt;

&lt;p&gt;This summer reinforced my belief in learning through building real solutions. Each challenge taught me something new:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Vector search for spam protection&lt;/li&gt;
&lt;li&gt;Email parsing and geolocation mapping&lt;/li&gt;
&lt;li&gt;Robot-AI integration&lt;/li&gt;
&lt;li&gt;Custom MCP client development&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Looking Forward 🚀
&lt;/h2&gt;

&lt;p&gt;As we transition into fall, I'm looking forward to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Deep AI Integration&lt;/strong&gt;: Exploring new ways to combine traditional web development with AI capabilities&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Robotics&lt;/strong&gt;: Building simple physical robots&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Community Contribution&lt;/strong&gt;: Continuing to share learning experiences and help others navigate similar challenges&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Summer Stats 📊
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;8 major projects&lt;/strong&gt; completed&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;9 badges&lt;/strong&gt; earned on dev.to&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multiple AI challenges&lt;/strong&gt; conquered&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;1 virtual robot&lt;/strong&gt; brought to life with AI&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;1 multi-agent monitoring system&lt;/strong&gt; deployed&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Countless hours&lt;/strong&gt; of learning and programming&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;1 amazing community&lt;/strong&gt; that supported every step&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Final Thoughts 💭
&lt;/h2&gt;

&lt;p&gt;This summer taught me that the best learning happens when you're slightly uncomfortable — when you're solving problems you've never solved before, and building bridges between different technologies.&lt;/p&gt;

&lt;p&gt;To my fellow developers reading this: don't be afraid to take on challenges that seem above your current skill level. Some of my best work this summer came from projects where I had no idea how I'd solve them when I started.&lt;/p&gt;

&lt;p&gt;We're living in an incredible time when a single developer can create systems that would have required entire teams just a few years ago.&lt;/p&gt;




&lt;p&gt;What was your main technical victory this summer? I'd love to hear about your projects and challenges in the comments!&lt;/p&gt;

&lt;p&gt;And if you're working on something interesting related to AI and robotics, feel free to connect — I'm always interested to learn what others are creating.&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>ai</category>
      <category>robotics</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Building a Multi-Agent AI Brand Monitoring System with n8n and BrightData</title>
      <dc:creator>Prema Ananda</dc:creator>
      <pubDate>Sat, 30 Aug 2025 07:15:56 +0000</pubDate>
      <link>https://dev.to/prema_ananda/building-a-multi-agent-ai-brand-monitoring-system-with-n8n-and-brightdata-oe0</link>
      <guid>https://dev.to/prema_ananda/building-a-multi-agent-ai-brand-monitoring-system-with-n8n-and-brightdata-oe0</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/brightdata-n8n-2025-08-13"&gt;AI Agents Challenge powered by n8n and Bright Data&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;I created &lt;strong&gt;BrandGuard AI&lt;/strong&gt; — a comprehensive multi-agent brand reputation monitoring system that fundamentally transforms how companies track and respond to online mentions. This isn't just another social media monitoring tool — it's an intelligent, fully automated platform that processes brand mentions through a sophisticated AI pipeline.&lt;/p&gt;

&lt;p&gt;The system addresses a critically important problem: in today's hyper-connected digital world, brand mentions spread across countless platforms with such intensity that human teams physically cannot track them effectively. Traditional methods are too slow, too manual, and lack the depth to separate critical signals from noise.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;BrandGuard AI solves this through:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Automatic collection&lt;/strong&gt; of meaningful brand mentions from major social platforms (Twitter, Reddit, LinkedIn) using reliable BrightData data streams with simple mechanisms for adding new sources&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Intelligent analysis&lt;/strong&gt; of each significant mention through Google Gemini AI to extract sentiment, urgency level, business impact, and crisis indicators&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automated report generation&lt;/strong&gt; with daily and weekly strategic summaries that typically require hours of analytical work&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Instant access&lt;/strong&gt; via a conversational Slack bot that understands natural queries like "Show me critical mentions for today" or "Show me what's up with Apple today"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real-time insights delivery&lt;/strong&gt; through a dynamic web dashboard with interactive visualizations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The system's uniqueness lies in its &lt;strong&gt;multi-agent architecture&lt;/strong&gt; — each key function (data collection, analysis, reporting, user interface) is handled by a specialized, independent agent built as separate n8n workflows. This modular design ensures exceptional resilience, scalability, and maintainability.&lt;/p&gt;

&lt;p&gt;GitHub Repository: &lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/premananda108" rel="noopener noreferrer"&gt;
        premananda108
      &lt;/a&gt; / &lt;a href="https://github.com/premananda108/BrandGuardAI" rel="noopener noreferrer"&gt;
        BrandGuardAI
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Intelligent Brand Reputation Monitoring System Automated AI-powered brand monitoring with automated analysis, reporting, and a natural language Slack interface.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;🛡️ BrandGuard AI&lt;/h1&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Intelligent Brand Reputation Monitoring System&lt;/strong&gt;&lt;br&gt;
Automated AI-powered brand monitoring with automated analysis, reporting, and a natural language Slack interface.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/premananda108/BrandGuardAI/assets/Dashboard.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fpremananda108%2FBrandGuardAI%2FHEAD%2Fassets%2FDashboard.png" alt="BrandGuard AI"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer" href="https://github.com/premananda108/BrandGuardAI/assets/AI%20bot.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fpremananda108%2FBrandGuardAI%2FHEAD%2Fassets%2FAI%2520bot.png" alt="n8n"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer" href="https://github.com/premananda108/BrandGuardAI/assets/mongo.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fpremananda108%2FBrandGuardAI%2FHEAD%2Fassets%2Fmongo.png" alt="MongoDB"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer" href="https://github.com/premananda108/BrandGuardAI/assets/critical%20mentions.gif"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fpremananda108%2FBrandGuardAI%2FHEAD%2Fassets%2Fcritical%2520mentions.gif" alt="Slack"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🎯 What is BrandGuard AI?&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;BrandGuard AI is a comprehensive, fully automated brand reputation monitoring system built on n8n. It is designed to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;🕷️ &lt;strong&gt;Collect&lt;/strong&gt; brand mentions from major social platforms like Twitter, Reddit, and LinkedIn.&lt;/li&gt;
&lt;li&gt;🧠 &lt;strong&gt;Analyze&lt;/strong&gt; each mention for sentiment, urgency, and business impact using Google Gemini AI.&lt;/li&gt;
&lt;li&gt;🗄️ &lt;strong&gt;Store&lt;/strong&gt; enriched data in a structured MongoDB database.&lt;/li&gt;
&lt;li&gt;📊 &lt;strong&gt;Generate&lt;/strong&gt; automated daily and weekly analytical reports with strategic insights.&lt;/li&gt;
&lt;li&gt;🖥️ &lt;strong&gt;Visualize&lt;/strong&gt; data through a dynamic web dashboard.&lt;/li&gt;
&lt;li&gt;💬 &lt;strong&gt;Interact&lt;/strong&gt; with users via a smart Slack bot that understands natural language queries.&lt;/li&gt;
&lt;li&gt;🚨 &lt;strong&gt;Alerts&lt;/strong&gt; your team about critical mentions.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🗗️ System Architecture&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;The system is a collection of interconnected n8n workflows that create a full data processing pipeline, from collection to user-facing interfaces.&lt;/p&gt;

  &lt;div class="js-render-enrichment-target"&gt;
    &lt;div class="render-plaintext-hidden"&gt;
      &lt;pre&gt;graph TD
    subgraph "Data Collection&lt;/pre&gt;…&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/premananda108/BrandGuardAI" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;The system is fully functional and deployed in a production environment. &lt;br&gt;
The complete source code includes all n8n workflows, Docker configurations and setup documentation.&lt;/p&gt;

&lt;h3&gt;
  
  
  n8n Workflow
&lt;/h3&gt;

&lt;p&gt;The BrandGuard AI system is built on a modular architecture of interconnected n8n workflows. Each workflow performs a specialized function in the overall data processing pipeline.&lt;/p&gt;

&lt;h3&gt;
  
  
  Core Workflows:
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. Data Collection and Processing:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;Brand Monitoring Step 1&lt;/code&gt; - schedules data collection from BrightData and creates processing tasks&lt;br&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%2Fntwsi0p25y17n8ta63yc.gif" 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%2Fntwsi0p25y17n8ta63yc.gif" alt="Brand Monitoring Step 1" width="800" height="418"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;Brand Monitoring Step 2&lt;/code&gt; - normalizes raw data into unified format through adapters&lt;/p&gt;&lt;/li&gt;
&lt;/ul&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%2Ffmckqakng9pnt9lvbra2.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%2Ffmckqakng9pnt9lvbra2.png" alt="Brand Monitoring Step 2" width="800" height="385"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Brand Monitoring Step 3&lt;/code&gt; - performs AI analysis through Google Gemini and saves to MongoDB
&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%2F71a2aiwd7wly8446oquq.png" alt="Brand Monitoring Step 3" width="800" height="376"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. AI Reporting:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;AI Daily Summary&lt;/code&gt; - generates daily analytical summaries&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;AI Weekly Summary&lt;/code&gt; - creates weekly strategic reports&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. User Interfaces:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;BrandGuard AI - Dashboard&lt;/code&gt; - web dashboard with interactive analytics&lt;/li&gt;
&lt;/ul&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%2Fqqciyeiiq82vfunxw8j8.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%2Fqqciyeiiq82vfunxw8j8.png" alt="BrandGuard AI - Dashboard HTML" width="800" height="245"&gt;&lt;/a&gt;&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%2Fuploads%2Farticles%2Fsmvyywqq55k1tlcd7v8i.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%2Fsmvyywqq55k1tlcd7v8i.png" alt="BrandGuard AI - Dashboard" width="800" height="453"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;BrandGuard AI bot&lt;/code&gt; - Slack bot with natural language support&lt;/li&gt;
&lt;/ul&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%2Fcjtg57v79hwy6mim70hx.gif" 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%2Fcjtg57v79hwy6mim70hx.gif" alt="BrandGuard AI bot" width="760" height="448"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Brand Mention Report&lt;/code&gt; - detailed mention viewing&lt;/li&gt;
&lt;/ul&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%2Fjb94joe5dzv6409xv57u.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%2Fjb94joe5dzv6409xv57u.png" alt="Brand Mention Report" width="800" height="415"&gt;&lt;/a&gt;&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%2Fuploads%2Farticles%2Fuszqqc16tviy0jbr8npi.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%2Fuszqqc16tviy0jbr8npi.png" alt="Brand Mention Report Detailed" width="800" height="443"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Architectural Features:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Modularity&lt;/strong&gt;: each agent is an independent workflow&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Extensibility&lt;/strong&gt;: adapter pattern for easy addition of data sources&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resilience&lt;/strong&gt;: centralized error handling and state monitoring&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalability&lt;/strong&gt;: task management through MongoDB jobs collection&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Complete workflow JSON files:&lt;/strong&gt; available in the &lt;code&gt;/workflows&lt;/code&gt; folder of the GitHub repository&lt;/p&gt;

&lt;h2&gt;
  
  
  Technical Implementation
&lt;/h2&gt;

&lt;p&gt;AI Agent Configuration&lt;/p&gt;

&lt;p&gt;The system uses &lt;strong&gt;Google Gemini&lt;/strong&gt; as the primary AI model through the standard node in n8n. Each agent is configured with specialized system instructions for specific tasks:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mention Analysis Agent:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;System Instructions&lt;/strong&gt;: "Analyze brand mentions and return structured JSON with fields: sentiment_score, confidence, urgency_level (1-10), key_topics, crisis_indicators, business_impact, severity, recommended_action"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Model&lt;/strong&gt;: Google Gemini Flash and Pro for deep contextual understanding&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memory&lt;/strong&gt;: Stateless - each mention is analyzed independently&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tools&lt;/strong&gt;: JSON parser for structured output&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Slack Bot Agent:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;System Instructions&lt;/strong&gt;: "You are an assistant for brand reputation analysis. Interpret user queries and translate them into MongoDB queries. Available functions: help, today, brand, search, critical, summary"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Model&lt;/strong&gt;: Google Gemini Flash for natural language processing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memory&lt;/strong&gt;: Session context within a single request&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tools&lt;/strong&gt;: MongoDB connector, Slack message formatting&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Reporting Agents:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;System Instructions&lt;/strong&gt;: "Create executive summary based on brand mentions for specified period. Include trends, critical moments, recommendations"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Model&lt;/strong&gt;: Google Gemini Pro for insight generation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memory&lt;/strong&gt;: Aggregated data for the period&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tools&lt;/strong&gt;: MongoDB aggregation pipeline&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Bright Data Verified Node
&lt;/h3&gt;

&lt;p&gt;BrightData is the foundation of the entire data collection pipeline in BrandGuard AI. I used the official verified BrightData node in n8n for integration with their data ecosystem:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Setup and Configuration:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Datasets used&lt;/strong&gt;: Twitter Posts, Reddit Posts, LinkedIn Posts with ability to add new ones&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Filtering&lt;/strong&gt;: by brand keywords, engagement metrics (likes, reposts)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Frequency&lt;/strong&gt;: automatic collection every n hours through n8n scheduler&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data format&lt;/strong&gt;: JSON with rich metadata (author, time, engagement metrics)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Key BrightData Advantages:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Data Quality&lt;/strong&gt;: structured, clean data without need for complex preprocessing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reliability&lt;/strong&gt;: stable data delivery without gaps or duplication&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalability&lt;/strong&gt;: handling large volumes of mentions without infrastructure burden&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compliance&lt;/strong&gt;: all data collected in compliance with platform ToS&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Architectural Solution with Adapters:&lt;/strong&gt; I implemented an adapter pattern for working with different BrightData sources. Each source (Twitter, Reddit, LinkedIn) has its adapter in the &lt;code&gt;Brand Monitoring Step 2&lt;/code&gt; workflow, which normalizes the specific data structure into a unified format. This allows easy addition of new datasets from the BrightData marketplace without changes to the core system logic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Journey
&lt;/h2&gt;

&lt;p&gt;The development of BrandGuard AI was an iterative process that started with a simple idea of automating mention monitoring and evolved into a comprehensive multi-agent system.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stage 1 - MVP (Minimum Viable Product):&lt;/strong&gt; Started with a basic n8n workflow that collected data from one source and saved to MongoDB. Quickly realized that a more complex architecture was needed to handle heterogeneous data sources.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stage 2 - Architectural Design:&lt;/strong&gt; Decided on a multi-agent architecture after studying the limitations of the monolithic approach. Divided the system into specialized agents with clear areas of responsibility.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stage 3 - Slack Bot Implementation:&lt;/strong&gt; Getting the Slack bot to work properly was the main challenge. It required significant effort to set up the proper webhooks, authentication, and message handling to create a seamless conversational experience.&lt;/p&gt;

&lt;h3&gt;
  
  
  Major Challenges and Solutions
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Challenge 1: Heterogeneous Data Sources&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Problem&lt;/strong&gt;: each platform (Twitter, Reddit, LinkedIn) returns data in different formats&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Solution&lt;/strong&gt;: implemented adapter pattern using Switch node in n8n, where each source has its adapter for data normalization&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Challenge 2: Performance Bottleneck at Scale&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Problem&lt;/strong&gt;: When MongoDB collection exceeded 1000 mentions, the workflow fetching all documents at once caused server hangs due to excessive memory consumption&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Solution&lt;/strong&gt;: Implemented server-side pagination by reconfiguring the n8n workflow to process data in manageable chunks, adding page and size parameters to the webhook that control limit and skip values in MongoDB queries&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Challenge 3: Processing Scalability&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Problem&lt;/strong&gt;: as data volume increased, the system began to slow down&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Solution&lt;/strong&gt;: implemented job-based architecture with state tracking in MongoDB and asynchronous processing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Challenge 4: Slack Bot User Experience&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Problem&lt;/strong&gt;: wanted natural conversation with the bot, not rigid commands&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Solution&lt;/strong&gt;: used Google Gemini for NLU (Natural Language Understanding), allowing the bot to understand free-form questions&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What I Learned
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Technical Insights:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Power of n8n as orchestrator&lt;/strong&gt;: n8n proved to be the ideal tool for creating complex multi-agent systems thanks to visual programming and rich integration ecosystem&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Importance of data quality&lt;/strong&gt;: working with BrightData showed the critical importance of clean, structured data for AI analysis&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI prompt engineering&lt;/strong&gt;: creating effective prompts for structured output is an art requiring multiple iterations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Architectural Lessons:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Modularity above all&lt;/strong&gt;: dividing the system into independent agents significantly simplified development, debugging, and scaling&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Importance of state monitoring&lt;/strong&gt;: job-based architecture with tracking in MongoDB enabled creation of a transparent and debuggable system&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This project showed me how modern no-code/low-code platforms can be used to create enterprise-level AI solutions with minimal time and resource investment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;P.S.&lt;/strong&gt;&lt;br&gt;
I want to note that before this project, I had never worked with &lt;strong&gt;n8n&lt;/strong&gt; and didn't even know about &lt;strong&gt;BrightData&lt;/strong&gt;'s existence. This challenge became a real discovery of two outstanding products.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;n8n&lt;/strong&gt; impressed me with its flexibility and power of visual programming. What seemed like a complex task of orchestrating multiple AI agents turned into an intuitive process of creating interconnected workflows.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;BrightData&lt;/strong&gt; turned out to be exactly the missing link needed for quality data collection. The reliability, structure, and richness of their datasets dramatically simplified the system architecture.&lt;/p&gt;

&lt;p&gt;Thanks to &lt;strong&gt;DEV.to&lt;/strong&gt; for organizing this challenge! Without it, I would never have discovered these wonderful products and wouldn't have been able to create BrandGuard AI. This is an excellent example of how technical competitions promote learning new technologies and creating innovative solutions.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>n8nbrightdatachallenge</category>
      <category>ai</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Beyond Caching: How Redis 8 Became Our Forum's Primary Database and AI Engine</title>
      <dc:creator>Prema Ananda</dc:creator>
      <pubDate>Tue, 05 Aug 2025 11:33:59 +0000</pubDate>
      <link>https://dev.to/prema_ananda/beyond-caching-how-redis-8-became-our-forums-primary-database-and-ai-engine-1m5</link>
      <guid>https://dev.to/prema_ananda/beyond-caching-how-redis-8-became-our-forums-primary-database-and-ai-engine-1m5</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/redis-2025-07-23"&gt;Redis AI Challenge&lt;/a&gt;: Beyond the Cache&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;I built &lt;strong&gt;CleanForum&lt;/strong&gt;, a complete forum application where Redis 8 is not an accessory, but the central nervous system. It handles every aspect of the forum's data, from post and comment storage to real-time AI-powered spam moderation.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Challenge: Escaping the "Database Zoo"
&lt;/h3&gt;

&lt;p&gt;In modern web development, we often find ourselves managing a "zoo" of specialized databases. A typical stack might include PostgreSQL for primary data, Elasticsearch for search, a dedicated vector database like Pinecone for AI features, and, of course, Redis for caching. This complexity introduces overhead, synchronization challenges, and increased costs.&lt;/p&gt;

&lt;p&gt;For my project, &lt;strong&gt;CleanForum&lt;/strong&gt;, I set out with an ambitious goal: to build a full-featured, AI-powered forum using &lt;strong&gt;a single data platform&lt;/strong&gt;. I wanted to challenge the conventional wisdom that Redis is "just a cache" and prove that with Redis 8, it can be the powerful, unified engine for an entire application.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Features at a Glance:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;A Complete, Feature-Rich Forum:&lt;/strong&gt; Users can create posts with Markdown, engage in discussions through comments, and browse content by categories. &lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Transparent AI Spam Protection:&lt;/strong&gt; The crown jewel of the project. A sophisticated, hybrid system that combines traditional heuristic checks with advanced vector similarity analysis. It doesn't just block spam; it provides moderators with a detailed report explaining &lt;em&gt;why&lt;/em&gt; a post was flagged.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Engaging "Similar Posts" Feature:&lt;/strong&gt; To increase user retention, the system uses Redis's vector search capabilities to instantly suggest other relevant content, keeping users engaged on the site.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Instant Full-Text Search:&lt;/strong&gt; The entire forum is searchable, with results delivered in milliseconds, powered by the same RediSearch index used for AI features.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Insightful Moderator Panel:&lt;/strong&gt; A command center where moderators can review flagged content, see detailed spam analysis, and manually manage posts and comments, providing feedback to the system.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;The application is live and fully functional. I invite you to test it out!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Live Application:&lt;/strong&gt; &lt;strong&gt;&lt;a href="http://forum.premananda.site/" rel="noopener noreferrer"&gt;forum.premananda.site&lt;/a&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Video Demo:&lt;/strong&gt;
  &lt;iframe src="https://www.youtube.com/embed/ileUJraNjhk"&gt;
  &lt;/iframe&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/premananda108" rel="noopener noreferrer"&gt;
        premananda108
      &lt;/a&gt; / &lt;a href="https://github.com/premananda108/CleanForum" rel="noopener noreferrer"&gt;
        CleanForum
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A modern forum with an advanced spam protection system based on FastAPI and Redis Vector Search.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;CleanForum 🛡️&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;A modern forum with an advanced spam protection system based on &lt;strong&gt;FastAPI&lt;/strong&gt; and &lt;strong&gt;Redis Vector Search&lt;/strong&gt;.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🚀 Features&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;🔒 Advanced Spam Protection&lt;/h3&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Vector analysis&lt;/strong&gt; using SentenceTransformer (all-MiniLM-L6-v2)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Heuristic algorithms&lt;/strong&gt; to detect spam patterns&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Feedback system&lt;/strong&gt; to improve accuracy&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Redis Vector Sets&lt;/strong&gt; for fast search of similar posts&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;k-NN classification&lt;/strong&gt; with nearest neighbors voting&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;🏗️ Technology Stack&lt;/h3&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Backend&lt;/strong&gt;: FastAPI, Python 3.8+&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database&lt;/strong&gt;: Redis 7.0+ with Vector Search&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ML model&lt;/strong&gt;: SentenceTransformer&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Frontend&lt;/strong&gt;: Tailwind CSS, Vanilla JavaScript&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Templates&lt;/strong&gt;: Jinja2&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;📋 Functionality&lt;/h3&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;✅ Create and edit posts&lt;/li&gt;
&lt;li&gt;✅ Comment system&lt;/li&gt;
&lt;li&gt;✅ Categories and tags&lt;/li&gt;
&lt;li&gt;✅ Voting and ratings&lt;/li&gt;
&lt;li&gt;✅ Moderator panel&lt;/li&gt;
&lt;li&gt;✅ Forum search&lt;/li&gt;
&lt;li&gt;✅ Automatic spam analysis&lt;/li&gt;
&lt;li&gt;✅ Statistics and analytics&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🛠️ Installation and Launch&lt;/h2&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Prerequisites&lt;/h3&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Python 3.8+&lt;/li&gt;
&lt;li&gt;Redis 8.0+ with Vector Search support&lt;/li&gt;
&lt;li&gt;Docker (optional)&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;1. Cloning and Installing Dependencies&lt;/h3&gt;

&lt;/div&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;git clone https://github.com/premananda108/CleanForum.git&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; Go to the project directory&lt;/span&gt;
&lt;span class="pl-c1"&gt;cd&lt;/span&gt; CleanForum
&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; Create a&lt;/span&gt;&lt;/pre&gt;…
&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/premananda108/CleanForum" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Here are some screenshots showcasing the application in action:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Home Page and Content&lt;/strong&gt;&lt;br&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%2Fuue2ovis0bq2nfiffstx.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%2Fuue2ovis0bq2nfiffstx.png" alt="Home Page and Content"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Post Page with Related Posts&lt;/strong&gt;&lt;br&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%2Fk67dlyhxv34wuyrcd27s.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%2Fk67dlyhxv34wuyrcd27s.png" alt="Post Page with Related Posts"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Moderator Panel with Moderation Queue&lt;/strong&gt;&lt;br&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%2F39zc6p0ud1g7m3coi12n.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%2F39zc6p0ud1g7m3coi12n.png" alt="Moderator Panel with Moderation Queue"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Detailed Spam Analysis Report&lt;/strong&gt;&lt;br&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%2Fao31143juid1oqez2rny.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%2Fao31143juid1oqez2rny.png" alt="Detailed Spam Analysis Report"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Used Redis 8
&lt;/h2&gt;

&lt;p&gt;Redis 8 is the architectural cornerstone of CleanForum. It allowed me to replace a potential stack of 3-4 different technologies with one elegant and hyper-efficient solution.&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Redis Hashes as the Primary "Source of Truth" Database
&lt;/h4&gt;

&lt;p&gt;Instead of a traditional SQL database, every core entity in the application is a &lt;strong&gt;Redis Hash&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Posts:&lt;/strong&gt; Stored in keys like &lt;code&gt;post:&amp;lt;uuid&amp;gt;&lt;/code&gt;, a hash contains the post's title, content, author ID, timestamps, and vote scores.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Users:&lt;/strong&gt; &lt;code&gt;user:&amp;lt;uuid&amp;gt;&lt;/code&gt; hashes store profile information, roles, and reputation.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Comments:&lt;/strong&gt; &lt;code&gt;comment:&amp;lt;uuid&amp;gt;&lt;/code&gt; hashes hold comment content and relationships.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This approach provides schema flexibility and the raw performance Redis is famous for. To manage relationships and create feeds, I heavily utilized &lt;strong&gt;Sorted Sets (ZSETs)&lt;/strong&gt;. For example, &lt;code&gt;posts:all&lt;/code&gt; is a sorted set scored by timestamp, providing an instantly accessible, chronologically sorted list of all posts.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. RediSearch for Dual-Purpose Search: Vector &amp;amp; Full-Text
&lt;/h4&gt;

&lt;p&gt;This is where the "multi-model" power of Redis truly shines. I use a &lt;strong&gt;single RediSearch index&lt;/strong&gt; to power two fundamentally different types of search.&lt;/p&gt;

&lt;p&gt;To optimize this, I implemented a &lt;strong&gt;two-hash architecture&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;The "Source of Truth" Hash (&lt;code&gt;post:&amp;lt;id&amp;gt;&lt;/code&gt;):&lt;/strong&gt; Contains the complete, rich data for a post.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;The "Search Index" Hash (&lt;code&gt;vector:post:&amp;lt;id&amp;gt;&lt;/code&gt;):&lt;/strong&gt; A lightweight, separate hash containing only the data needed for indexing: the vector embedding and pre-processed text.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This separation is key: it keeps the search index incredibly lean and fast, while the main data can be as complex as needed without bloating the index. The index is configured to automatically pick up any new keys with the &lt;code&gt;vector:&lt;/code&gt; prefix.&lt;/p&gt;

&lt;h4&gt;
  
  
  3. The Hybrid AI Engine: My Secret Sauce
&lt;/h4&gt;

&lt;p&gt;The spam detection system is a perfect example of combining Redis features to create something powerful. It’s a two-stage process:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;First Pass - Heuristic Analysis:&lt;/strong&gt; The system first performs a rapid check for obvious spam indicators: suspicious keywords (&lt;code&gt;"free"&lt;/code&gt;, &lt;code&gt;"crypto"&lt;/code&gt;), excessive capitalization, and patterns common in spam. This is handled in Python.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Second Pass - Vector Similarity Analysis:&lt;/strong&gt; This is the core of the AI.

&lt;ul&gt;
&lt;li&gt;  A vector embedding is created from the new post's content.&lt;/li&gt;
&lt;li&gt;  A K-Nearest Neighbor (KNN) query (&lt;code&gt;*=&amp;gt;[KNN k @vector $blob]&lt;/code&gt;) is sent to RediSearch to find the most similar posts already in the database.&lt;/li&gt;
&lt;li&gt;  The system then fetches the &lt;strong&gt;current, real-time &lt;code&gt;is_spam&lt;/code&gt; status&lt;/strong&gt; of these "neighbors" directly from their primary &lt;code&gt;post:&amp;lt;id&amp;gt;&lt;/code&gt; hashes.&lt;/li&gt;
&lt;li&gt;  A weighted score is calculated. If a post is highly similar to several posts that moderators have previously marked as spam, its own spam score skyrockets.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This synergy is incredibly powerful. The user-facing "Similar Posts" feature and the backend security system are powered by the &lt;strong&gt;exact same mechanism&lt;/strong&gt;. It's efficient, elegant, and learns continuously from moderator feedback.&lt;/p&gt;

&lt;h4&gt;
  
  
  4. Deployment and Infrastructure
&lt;/h4&gt;

&lt;p&gt;To prove that this powerful stack is accessible to everyone, the entire application is running on a modest &lt;strong&gt;Debian 12&lt;/strong&gt; virtual server with just &lt;strong&gt;4GB of RAM&lt;/strong&gt;. The Redis database itself is hosted on a &lt;strong&gt;free-tier cloud instance&lt;/strong&gt;. This demonstrates that thanks to Redis's incredible efficiency, you don't need a massive budget or enterprise-grade hardware to build and run a sophisticated, AI-driven application.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion and Gratitude
&lt;/h3&gt;

&lt;p&gt;This journey with the Redis AI Challenge has been more than just a competition; it has fundamentally changed my perspective on what's possible with a single database. Redis 8 is not just a cache—it is a legitimate, high-performance, multi-model database that can serve as the foundation for complex, modern applications. It challenged my architectural assumptions and enabled me to build a cleaner, faster, and more elegant system than I thought possible.&lt;/p&gt;

&lt;p&gt;I want to extend my sincere gratitude to the teams at &lt;strong&gt;Redis&lt;/strong&gt; and &lt;strong&gt;DEV.to&lt;/strong&gt; for organizing this incredible challenge. The opportunity to push the boundaries, learn so much about vector search and AI implementation, and engage with this vibrant community has been an invaluable experience. I'm excited to see what I can build next with these powerful new tools at my fingertips.&lt;/p&gt;

</description>
      <category>redischallenge</category>
      <category>devchallenge</category>
      <category>database</category>
      <category>ai</category>
    </item>
    <item>
      <title>Opening the "Black Box": A Journey into Vector Search and Spam Protection</title>
      <dc:creator>Prema Ananda</dc:creator>
      <pubDate>Tue, 29 Jul 2025 11:00:29 +0000</pubDate>
      <link>https://dev.to/prema_ananda/opening-the-black-box-a-journey-into-vector-search-and-spam-protection-1kmd</link>
      <guid>https://dev.to/prema_ananda/opening-the-black-box-a-journey-into-vector-search-and-spam-protection-1kmd</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/redis-2025-07-23"&gt;Redis AI Challenge&lt;/a&gt;: Real-Time AI Innovators&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;How I built a spam fighting system with Redis 8 Vector Sets and what I learned about the inner workings of machine learning&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;A spam classification system for dev.to that allows you to trace the entire journey from raw text to the final "spam/not spam" decision. Every step is transparent, measurable, and explainable.&lt;/p&gt;

&lt;p&gt;In the era of ChatGPT and ready-made AI APIs, it's easy to forget that complex mathematics lies behind beautiful interfaces. When I started this project, I had a simple goal: &lt;strong&gt;to understand how vector search actually works&lt;/strong&gt;, rather than just using it as a "magical" function.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/fh01IbjYAho"&gt;
  &lt;/iframe&gt;
&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/premananda108" rel="noopener noreferrer"&gt;
        premananda108
      &lt;/a&gt; / &lt;a href="https://github.com/premananda108/redis8-spam-guard" rel="noopener noreferrer"&gt;
        redis8-spam-guard
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;🛡️ Redis8 Spam Guard&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;An intelligent spam classification system for dev.to posts using Redis 8 Vector Sets and FastAPI.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🎯 Features&lt;/h2&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Real-time classification&lt;/strong&gt; - instant analysis of posts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Redis 8 Vector Sets&lt;/strong&gt; - leveraging the latest vector search technology.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;FastAPI&lt;/strong&gt; - a modern asynchronous API.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Machine Learning&lt;/strong&gt; - classification based on k-NN with vector embeddings.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Interactive Web UI&lt;/strong&gt; - a dashboard for moderators with real-time post classification, manual checking, statistics, and training logs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dynamic Data Enrichment&lt;/strong&gt; - automatic loading of additional data, such as the author's follower count, for more accurate classification.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Feedback Loop&lt;/strong&gt; - a system for improving the model based on moderator feedback.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🏗️ Architecture&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;┌─────────────────┐    ┌──────────────────┐    ┌─────────────────┐
│   Dev.to API    │ -&amp;gt; │  FastAPI Server  │ -&amp;gt; │  Redis 8        │
│ (Posts, Users)  │    │ (API, Web UI)    │    │  (Vector Sets)  │
└─────────────────┘    └──────────────────┘    └─────────────────┘
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Components:&lt;/h3&gt;

&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Data Collector&lt;/strong&gt; - collects posts and user data from…&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/premananda108/redis8-spam-guard" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;&lt;em&gt;The complete project code is available on GitHub. The system works in real-time and is ready for demonstration.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Used Redis 8
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Vector Sets — More Than Just Search
&lt;/h3&gt;

&lt;p&gt;Redis Vector Sets turned out to be not just a database, but a full-fledged semantic search engine. Creating the index:&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="n"&gt;schema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nc"&gt;VectorField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;vector&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;HNSW&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;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;FLOAT32&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;DIM&lt;/span&gt;&lt;span class="sh"&gt;"&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;vector_dim&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DISTANCE_METRIC&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;COSINE&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="nc"&gt;TagField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;label&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nc"&gt;TextField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;title&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nc"&gt;TagField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;url&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;&lt;strong&gt;HNSW (Hierarchical Navigable Small World)&lt;/strong&gt; — this isn't just an algorithm, it's an entire philosophy of search. It builds a multi-level graph of connections between vectors, allowing you to find nearest neighbors in logarithmic time.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Heart of Vector Search: How Redis Finds Similar Posts
&lt;/h3&gt;

&lt;p&gt;The real magic happens in the vector search itself. The search for vectors occurs in the &lt;code&gt;core.py&lt;/code&gt; file, inside the &lt;code&gt;find_similar_posts&lt;/code&gt; method of the &lt;code&gt;RedisVectorClassifier&lt;/code&gt; class.&lt;/p&gt;

&lt;p&gt;Here's the specific code section that sends the query to Redis:&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;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;find_similar_posts&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_vector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ndarray&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="nb"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Dict&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;]]:&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Finds similar posts.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&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;redis_client&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&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="c1"&gt;# 1. Query formation
&lt;/span&gt;        &lt;span class="n"&gt;query&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;*=&amp;gt;[KNN &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; @vector $blob AS score]&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;# 2. Executing the search command
&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;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;redis_client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute_command&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;FT.SEARCH&lt;/span&gt;&lt;span class="sh"&gt;"&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;index_name&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;PARAMS&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;2&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;blob&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_vector&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tobytes&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DIALECT&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;2&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;RETURN&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;3&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;score&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;title&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;url&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;# ... (result processing follows)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;How this works:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;query = f"*=&amp;gt;[KNN {k} @vector $blob AS score]"&lt;/code&gt;&lt;/strong&gt;: This line forms the search query itself.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;*&lt;/code&gt; — search across all documents in the index.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;=&amp;gt;&lt;/code&gt; — apply the following operation to the results.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;[KNN {k} @vector $blob AS score]&lt;/code&gt; — this is the vector search command (KNN - k-Nearest Neighbors). It tells Redis: "Find k nearest neighbors in the vector field, using the vector we'll pass in the $blob parameter, and name the similarity field 'score'".&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;await self.redis_client.execute_command(...)&lt;/code&gt;&lt;/strong&gt;: This line sends the FT.SEARCH command to Redis, passing it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The index name (&lt;code&gt;self.index_name&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;The formed query (&lt;code&gt;query&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;The actual vector for search (&lt;code&gt;query_vector.tobytes()&lt;/code&gt;) as the $blob parameter.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This command is what makes Redis use its powerful algorithm (HNSW) for ultra-fast search of the most similar vectors in the database.&lt;/p&gt;

&lt;h3&gt;
  
  
  k-NN — Democracy of Vectors
&lt;/h3&gt;

&lt;p&gt;Classification of new posts happens through "voting" of nearest neighbors:&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;# Find 9 nearest neighbors
&lt;/span&gt;&lt;span class="n"&gt;similar_posts&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;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find_similar_posts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query_vector&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;9&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Collect their labels
&lt;/span&gt;&lt;span class="n"&gt;labels&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;label&lt;/span&gt;&lt;span class="sh"&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;post&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;similar_posts&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;# Majority wins
&lt;/span&gt;&lt;span class="n"&gt;predicted_label&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Counter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;most_common&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;confidence&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vote_count&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;total_neighbors&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fz9rei6dsbl1uuinbqbhu.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%2Fz9rei6dsbl1uuinbqbhu.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Magic in details&lt;/strong&gt;: Why exactly k=9? After experiments, I found that an odd number of neighbors avoids ties, and 9 provides sufficient sampling without losing accuracy.&lt;/p&gt;

&lt;h3&gt;
  
  
  Redis as the Architecture Foundation
&lt;/h3&gt;

&lt;p&gt;The system is built entirely around Redis Vector Sets capabilities. Without Redis, there is no system — it's not just a database, but the core of all classification logic.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Look Under the Hood?
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Anatomy of "Training": What Actually Happens?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  First Discovery: We Don't Train the Model
&lt;/h3&gt;

&lt;p&gt;When people say "model training," they usually imagine a neural network learning from data. In my case, everything turned out differently. &lt;strong&gt;I don't train a model&lt;/strong&gt; — I use the ready-made &lt;code&gt;all-MiniLM-L6-v2&lt;/code&gt; as a "translator" from human language to the language of mathematics.&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;# This isn't model training, it's creating a knowledge base
&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;SentenceTransformer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;all-MiniLM-L6-v2&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;text_vector&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;How to earn $1000 in a week!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# We get an array of 384 numbers reflecting the text's meaning
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The real "training" happens at the level of creating a database of vectors with correct labels.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;But there's one "but":&lt;/strong&gt; Redis still requires an external model for vectorization. It would be revolutionary if Redis could accept raw text and create vectors independently. Imagine:&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;# Dream: pass text, get ready search
&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;redis_client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;post:123&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mapping&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;text&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;How to earn $1000 in a week!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;# Just text!
&lt;/span&gt;    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;label&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;spam&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="c1"&gt;# Redis creates the vector under the hood
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Such integration would eliminate the need to manage separate embedding models and make Redis a truly self-sufficient AI platform.&lt;/p&gt;

&lt;h3&gt;
  
  
  Second Discovery: Automatic Labeling is an Art of Heuristics
&lt;/h3&gt;

&lt;p&gt;The biggest problem of any ML project is obtaining labeled data. I didn't have thousands of posts with "spam/not spam" labels, so I had to create &lt;code&gt;SpamLabelGenerator&lt;/code&gt; — a rule system for automatic labeling:&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;calculate_spam_score&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;article&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Dict&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt;

    &lt;span class="c1"&gt;# Spam words in title (high weight)
&lt;/span&gt;    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;keyword&lt;/span&gt; &lt;span class="ow"&gt;in&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;spam_keywords&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;keyword&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mf"&gt;0.3&lt;/span&gt;

    &lt;span class="c1"&gt;# Short posts with low engagement
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;reading_time&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;reactions&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mf"&gt;0.3&lt;/span&gt;

    &lt;span class="c1"&gt;# Too many tags
&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;tags&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;10&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mf"&gt;0.2&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Challenge&lt;/strong&gt;: How to find balance between precision and recall? Too strict rules — we miss spam, too lenient — we block legitimate content.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: Added an element of randomness and multiple criteria. The system analyzes not only text, but also engagement metrics, author profile, publication time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Third Discovery: Vectors Are Not Just Numbers
&lt;/h3&gt;

&lt;p&gt;Initially, I thought a vector was just a "fingerprint" of text. In practice, it turned out you can create hybrid vectors by combining semantic embeddings with numerical features:&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;# Text vector (384 dimensions)
&lt;/span&gt;&lt;span class="n"&gt;text_vector&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;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;combined_text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Numerical features (3 dimensions)
&lt;/span&gt;&lt;span class="n"&gt;numeric_features&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;array&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="n"&gt;reading_time&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;user_followers&lt;/span&gt;&lt;span class="p"&gt;,&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;tags&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="c1"&gt;# Combine into a single vector (387 dimensions)
&lt;/span&gt;&lt;span class="n"&gt;final_vector&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;concatenate&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;text_vector&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;numeric_features&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Insight&lt;/strong&gt;: Vector space can be "enriched" with any numerical data. Posts become similar not only in meaning but also in structure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Redis as a "Card Index of Meanings"
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Challenges and Solutions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Problem 1: Quality of Automatic Labeling
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Challenge&lt;/strong&gt;: How to verify that automatic labels are correct?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: Added detailed logging and quality metrics:&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="n"&gt;metrics&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;accuracy&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;span class="n"&gt;tp&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;tn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;precision&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;tp&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tp&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;fp&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;recall&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;tp&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tp&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;f1_score&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;precision&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;recall&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;precision&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;recall&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;h3&gt;
  
  
  Problem 2: Data Imbalance — Too Little Spam
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Challenge&lt;/strong&gt;: Data from dev.to API contained very little real spam. The model couldn't learn effectively — it lacked examples of "bad" behavior.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: Created a synthetic spam dataset and mixed it with real data:&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;# Load synthetic spam posts
&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;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;spam_dataset.json&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;r&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;encoding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;utf-8&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;spam_articles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="c1"&gt;# Mark as known spam
&lt;/span&gt;        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;article&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;spam_articles&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;article&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;is_known_spam&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
        &lt;span class="n"&gt;articles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;extend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;spam_articles&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;FileNotFoundError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;warning&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;spam_dataset.json not found&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;&lt;strong&gt;Synthetic dataset composition&lt;/strong&gt; (50 examples):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Quick money schemes and crypto scams&lt;/li&gt;
&lt;li&gt;Phishing links and fake security notifications&lt;/li&gt;
&lt;li&gt;SEO services sales and follower boosting&lt;/li&gt;
&lt;li&gt;Dubious courses and "miracle products"&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  System Evolution: From Static to Self-Learning
&lt;/h3&gt;

&lt;p&gt;The first version of the system had a critical flaw — it couldn't learn from its mistakes. Every moderator correction was lost after page reload.&lt;/p&gt;

&lt;h3&gt;
  
  
  Feedback Loop in Action
&lt;/h3&gt;

&lt;p&gt;The solution turned out to be elegant: with each moderator click, the complete post content is saved in Redis with an expert verdict:&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;# Check for moderator verdict from Redis
&lt;/span&gt;&lt;span class="n"&gt;feedback_key&lt;/span&gt; &lt;span class="o"&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;feedback:&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;feedback_data&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;redis_classifier&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;redis_client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;feedback_key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;feedback_data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;feedback_json&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;feedback_data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;moderator_verdict&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;spam&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;feedback_json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;is_spam&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;legit&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;During the next training, this data is loaded with the highest priority, turning every mistake into an opportunity for improvement.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dramatic Results
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before feedback loop:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Accuracy: 78-85%&lt;/li&gt;
&lt;li&gt;Precision: ~85%&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;After implementation (just 9 expert corrections):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Accuracy: 96.4%&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Precision: 100%&lt;/strong&gt; — complete absence of false positives&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Insight: 9 expert moderator decisions proved more valuable than 1000 automatically labeled posts. Data quality beats quantity.&lt;/p&gt;

&lt;h3&gt;
  
  
  Training Control Panel
&lt;/h3&gt;

&lt;p&gt;The interface includes a "Training Control Panel" that displays current model information:&lt;/p&gt;

&lt;p&gt;Last known accuracy&lt;br&gt;
Number of trained examples (vectors in the database)&lt;/p&gt;

&lt;p&gt;The actual retraining launches only after clicking the "Start New Training" button, and the process can be observed in real-time through automatically updated logs.&lt;/p&gt;
&lt;h2&gt;
  
  
  What I Learned About the "Black Box"
&lt;/h2&gt;
&lt;h3&gt;
  
  
  1. Vectors Have Geometry
&lt;/h3&gt;

&lt;p&gt;Texts similar in meaning really are located close together in vector space. This isn't a metaphor — it's mathematical reality that can be measured through cosine distance or Euclidean norm.&lt;/p&gt;
&lt;h3&gt;
  
  
  2. Data Quality Matters More Than Algorithm
&lt;/h3&gt;

&lt;p&gt;The most advanced algorithm won't help if the data is poorly labeled. 80% of project success is quality preparation of the training sample.&lt;/p&gt;
&lt;h3&gt;
  
  
  3. Explainability Can Be Built In
&lt;/h3&gt;

&lt;p&gt;Every system decision is accompanied by detailed explanation:&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="n"&gt;reasoning&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;Similar to known spam posts (via Redis)&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;Contains spam keywords: &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;earn money&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;Low follower count (5)&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;Short reading time (1 minute)&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;
  
  
  4. Redis as Architecture Foundation
&lt;/h3&gt;

&lt;p&gt;The system is built entirely around Redis Vector Sets capabilities. Without Redis, there is no system — it's not just a database, but the core of all classification logic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusions: Why Open the "Black Box"?
&lt;/h2&gt;

&lt;p&gt;This project taught me that Redis Vector Sets isn't just a new feature, but a revolution in the approach to semantic search:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Speed&lt;/strong&gt;: Vector search works in milliseconds even on thousands of records&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalability&lt;/strong&gt;: System is ready for growth without architectural changes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transparency&lt;/strong&gt;: Every decision can be traced and explained&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Redis Vector Sets transformed the complex task of semantic search into an elegant and understandable solution.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Looking to the future:&lt;/strong&gt; The next logical step would be to embed vectorization directly into Redis. Instead of the chain "text → external model → vector → Redis" we would get simply "text → Redis". This would make Redis the only component needed for a full-fledged AI system — from raw data to ready search results.&lt;/p&gt;

</description>
      <category>redischallenge</category>
      <category>devchallenge</category>
      <category>database</category>
      <category>ai</category>
    </item>
  </channel>
</rss>
