<?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: Sumit V</title>
    <description>The latest articles on DEV Community by Sumit V (@sumit_v_0a2447f3bcb4fd18f).</description>
    <link>https://dev.to/sumit_v_0a2447f3bcb4fd18f</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%2F1682285%2F1f33061a-cf1e-4878-be40-b347e4c598c7.jpg</url>
      <title>DEV Community: Sumit V</title>
      <link>https://dev.to/sumit_v_0a2447f3bcb4fd18f</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sumit_v_0a2447f3bcb4fd18f"/>
    <language>en</language>
    <item>
      <title>Building an AI Agent from Scratch: A Step-by-Step Journey</title>
      <dc:creator>Sumit V</dc:creator>
      <pubDate>Wed, 25 Mar 2026 10:52:30 +0000</pubDate>
      <link>https://dev.to/sumit_v_0a2447f3bcb4fd18f/building-an-ai-agent-from-scratch-a-step-by-step-journey-7dd</link>
      <guid>https://dev.to/sumit_v_0a2447f3bcb4fd18f/building-an-ai-agent-from-scratch-a-step-by-step-journey-7dd</guid>
      <description>&lt;p&gt;AI agents aren't magic. They're just a loop. This workshop breaks down how to build a real Todo Agent in 11 commits, teaching you the core pattern behind every AI agent system.&lt;/p&gt;

&lt;p&gt;Everyone's talking about AI agents, but most explanations are either too abstract ("agents can reason and act!") or too complex (production systems with 50 dependencies). &lt;/p&gt;

&lt;p&gt;This workshop takes a different approach: build one from scratch, one commit at a time. By the end, you'll understand the fundamental loop that powers everything from ChatGPT plugins to autonomous coding assistants.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub Repository:&lt;/strong&gt; &lt;a href="https://github.com/sumitvairagar/simple-agent-workshop" rel="noopener noreferrer"&gt;https://github.com/sumitvairagar/simple-agent-workshop&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Journey: 11 Commits to Understanding
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: Set Up the Project Skeleton
&lt;/h3&gt;

&lt;p&gt;Every project starts somewhere. We begin with just a &lt;code&gt;.gitignore&lt;/code&gt; and a &lt;code&gt;README&lt;/code&gt;. Nothing runs yet, but we know what we're building: a Todo Assistant that can add tasks, list them, mark them done, and even prioritize using AI.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Learning:&lt;/strong&gt; Start simple. Define the goal before writing code.&lt;/p&gt;




&lt;h3&gt;
  
  
  Step 2: Add Dependencies and TypeScript Config
&lt;/h3&gt;

&lt;p&gt;We install the essentials:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;openai&lt;/code&gt; → Official SDK to talk to GPT&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;dotenv&lt;/code&gt; → Load API keys securely&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;tsx&lt;/code&gt; → Run TypeScript without compilation&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;typescript&lt;/code&gt; → Type safety and autocomplete&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Key Learning:&lt;/strong&gt; Modern AI development needs surprisingly few dependencies.&lt;/p&gt;




&lt;h3&gt;
  
  
  Step 3: Say Hello to GPT 👋
&lt;/h3&gt;

&lt;p&gt;Our first message to GPT and back!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&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;openai&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;completions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&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;gpt-4o&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello!&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;choices&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;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&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 to Notice:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We send a &lt;code&gt;messages&lt;/code&gt; array with a role and content&lt;/li&gt;
&lt;li&gt;GPT replies in &lt;code&gt;choices[0].message.content&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;finish_reason&lt;/code&gt; tells us WHY GPT stopped (&lt;code&gt;"stop"&lt;/code&gt; = it's done)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Key Learning:&lt;/strong&gt; The OpenAI API is just HTTP requests. No magic.&lt;/p&gt;




&lt;h3&gt;
  
  
  Step 4: Give GPT a Memory with Conversation History
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;The Problem:&lt;/strong&gt; GPT has NO memory between calls. Every request starts fresh.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Solution:&lt;/strong&gt; Keep a &lt;code&gt;messages&lt;/code&gt; array and send the full conversation every time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Golden Rule:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Push the user message into history&lt;/li&gt;
&lt;li&gt;Call the API with the full history array&lt;/li&gt;
&lt;li&gt;Push GPT's reply into history too — never skip this!
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;messages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
&lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;My name is Alice&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="c1"&gt;// ... call API ...&lt;/span&gt;
&lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;choices&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;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;What's my name?&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="c1"&gt;// GPT correctly remembers: "Your name is Alice"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Key Learning:&lt;/strong&gt; Conversation memory is just an array. You manage it, not GPT.&lt;/p&gt;




&lt;h3&gt;
  
  
  Step 5: Stream GPT's Reply Word by Word ✨
&lt;/h3&gt;

&lt;p&gt;Instead of waiting for the full response, tokens appear as GPT writes them. This makes everything feel alive and instant.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;stream&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;openai&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;completions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&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;gpt-4o&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="k"&gt;await &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;chunk&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;stream&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;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;chunk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;choices&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;delta&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stdout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;content&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;Key Learning:&lt;/strong&gt; Streaming is the difference between "loading..." and feeling like you're talking to something intelligent.&lt;/p&gt;




&lt;h3&gt;
  
  
  Step 6: Give GPT Tools to Work With 🔧
&lt;/h3&gt;

&lt;p&gt;Tools give GPT superpowers beyond just chatting. Each tool is a description that tells GPT:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What it's called (&lt;code&gt;add_todo&lt;/code&gt;, &lt;code&gt;list_todos&lt;/code&gt;, &lt;code&gt;mark_done&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;When to use it (the description)&lt;/li&gt;
&lt;li&gt;What inputs to pass
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tools&lt;/span&gt; &lt;span class="o"&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;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;function&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;function&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;add_todo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Add a new task to the todo list&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;parameters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;object&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;task&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;The task to add&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;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; GPT does NOT run tools itself. It just tells us "please run &lt;code&gt;add_todo&lt;/code&gt; with this input" and we do the actual work.&lt;/p&gt;

&lt;p&gt;When GPT wants a tool, &lt;code&gt;finish_reason&lt;/code&gt; changes to &lt;code&gt;"tool_calls"&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Learning:&lt;/strong&gt; Tools are just JSON schemas. GPT reads them and decides when to use them.&lt;/p&gt;




&lt;h3&gt;
  
  
  Step 7: Actually Run the Tools GPT Asks For 🏃
&lt;/h3&gt;

&lt;p&gt;Now we close the loop — when GPT says "call this tool", we do it!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Flow:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Find all &lt;code&gt;tool_calls&lt;/code&gt; in the response&lt;/li&gt;
&lt;li&gt;Run the matching function (&lt;code&gt;add_todo&lt;/code&gt;, &lt;code&gt;list_todos&lt;/code&gt;, &lt;code&gt;mark_done&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Push each result back as a &lt;code&gt;"tool"&lt;/code&gt; role message&lt;/li&gt;
&lt;li&gt;Include the &lt;code&gt;tool_call_id&lt;/code&gt; so GPT knows which result matches which request
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;for &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;toolCall&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;choices&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;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tool_calls&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;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;executeTool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;toolCall&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;function&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="nx"&gt;toolCall&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tool&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;tool_call_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;toolCall&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;content&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;result&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;p&gt;&lt;strong&gt;Key Learning:&lt;/strong&gt; Tool execution is just function calls. You write the functions, GPT decides when to call them.&lt;/p&gt;




&lt;h3&gt;
  
  
  Step 8: The Agent Loop — This Is Where the Magic Happens 🤖
&lt;/h3&gt;

&lt;p&gt;This is THE commit. Everything before was setup. This is the agent.&lt;/p&gt;

&lt;p&gt;The whole idea in plain English:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Keep asking GPT what to do next.&lt;br&gt;&lt;br&gt;
If it wants a tool → run it, hand GPT the result, ask again.&lt;br&gt;&lt;br&gt;
If it says it's done → stop and show the answer.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&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;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;callGPT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;messages&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;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;finish_reason&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tool_calls&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="c1"&gt;// Run the tools and add results to messages&lt;/span&gt;
    &lt;span class="nf"&gt;executeTools&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tool_calls&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Ask GPT again&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;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;finish_reason&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;stop&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="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// GPT is done&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;That loop is what makes this an "agent" instead of a chatbot.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;GPT decides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which tools to call&lt;/li&gt;
&lt;li&gt;How many times&lt;/li&gt;
&lt;li&gt;When to stop&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We just follow its lead.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Learning:&lt;/strong&gt; The agent loop is the heart of every AI agent system. Master this pattern, and you understand 90% of AI agents.&lt;/p&gt;




&lt;h3&gt;
  
  
  Step 9: Add a System Prompt to Guide the Agent's Behaviour
&lt;/h3&gt;

&lt;p&gt;Without instructions, GPT will do &lt;em&gt;something&lt;/em&gt;... but inconsistently.&lt;/p&gt;

&lt;p&gt;The system prompt is like a job description — it tells GPT:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What role it's playing (todo list assistant)&lt;/li&gt;
&lt;li&gt;The rules to follow (add, list, mark done)&lt;/li&gt;
&lt;li&gt;How to behave (brief and friendly)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;system&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`You are a helpful todo list assistant.

Rules:
- Use add_todo to add tasks
- Use list_todos to show all tasks
- Use mark_done to complete tasks
- Be brief and friendly`&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;Try This:&lt;/strong&gt; Comment out the system prompt and run again. The difference is night and day.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Learning:&lt;/strong&gt; System prompts are how you control agent behavior. They're more important than you think.&lt;/p&gt;




&lt;h3&gt;
  
  
  Step 10: Stream the Final Answer to the User in Real Time
&lt;/h3&gt;

&lt;p&gt;After all the tools are done, we do one final call to GPT and stream the summary token by token to the terminal.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why Two Separate Calls?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;During the loop we need the complete response to see tool requests&lt;/li&gt;
&lt;li&gt;Streaming and tool use can't be combined cleanly — pick one&lt;/li&gt;
&lt;li&gt;So: tool use in the loop, streaming for the final pretty answer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Key Learning:&lt;/strong&gt; Production systems often separate "thinking" (tool use) from "presentation" (streaming).&lt;/p&gt;




&lt;h3&gt;
  
  
  Step 11: Add a Prioritize Tool That Calls GPT Under the Hood 🪆
&lt;/h3&gt;

&lt;p&gt;One GPT call using another GPT call as a tool.&lt;/p&gt;

&lt;p&gt;The main agent manages the todo workflow. When the user asks to prioritize, it hands off the thinking to a smaller focused GPT call (&lt;code&gt;gpt-4o-mini&lt;/code&gt;) that reorders tasks.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Main agent → calls prioritize → GPT sub-call → reordered list → back to main agent
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Key Learning:&lt;/strong&gt; This "agent inside an agent" pattern is how real production systems handle tasks that are too big or specialized for one model to do alone.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Big Picture
&lt;/h2&gt;

&lt;p&gt;After these 11 steps, you've built a real AI agent. Not a toy, not a demo — a working system that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Maintains conversation memory&lt;/li&gt;
&lt;li&gt;Uses tools to interact with the world&lt;/li&gt;
&lt;li&gt;Makes decisions autonomously&lt;/li&gt;
&lt;li&gt;Streams responses for great UX&lt;/li&gt;
&lt;li&gt;Can even delegate to other AI calls&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;And the core pattern?&lt;/strong&gt; It's just a loop:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. User sends message
2. GPT decides which tool to use
3. Execute the tool
4. Send result back to GPT
5. GPT responds to user
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. That's the pattern behind ChatGPT plugins, GitHub Copilot, autonomous coding agents, and every other AI agent system.&lt;/p&gt;




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

&lt;p&gt;The workshop is designed to be hands-on. Clone the repo and use the demo script to navigate through each commit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/sumitvairagar/simple-agent-workshop.git
&lt;span class="nb"&gt;cd &lt;/span&gt;simple-agent-workshop
./simple-agent-workshop-demo.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Commands:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;n&lt;/code&gt; — Next step&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;p&lt;/code&gt; — Previous step&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;l&lt;/code&gt; — List all steps&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;g 5&lt;/code&gt; — Jump to step 5&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;q&lt;/code&gt; — Quit&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At each step, read the code, run &lt;code&gt;npm start&lt;/code&gt;, and see how it works.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Software Engineers Need to Understand This
&lt;/h2&gt;

&lt;p&gt;AI agents aren't replacing software engineers. They're becoming a core tool in our toolkit.&lt;/p&gt;

&lt;p&gt;Understanding how they work means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can build AI features into your products&lt;/li&gt;
&lt;li&gt;You can debug when they fail (and they will)&lt;/li&gt;
&lt;li&gt;You can architect systems that use AI effectively&lt;/li&gt;
&lt;li&gt;You can evaluate which problems AI can actually solve&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;This isn't optional knowledge anymore. It's foundational.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Just like every engineer should understand HTTP, databases, and async programming — understanding the agent loop is becoming a core skill.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's Next?
&lt;/h2&gt;

&lt;p&gt;This workshop teaches the fundamentals. Real production systems add:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Error handling and retries&lt;/li&gt;
&lt;li&gt;Rate limiting and cost controls&lt;/li&gt;
&lt;li&gt;Observability and logging&lt;/li&gt;
&lt;li&gt;Multi-agent orchestration&lt;/li&gt;
&lt;li&gt;Memory systems beyond conversation history&lt;/li&gt;
&lt;li&gt;Security and sandboxing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But they all build on this same core loop.&lt;/p&gt;

&lt;p&gt;Master the basics first. Then level up.&lt;/p&gt;




&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;GitHub Repo: &lt;a href="https://github.com/sumitvairagar/simple-agent-workshop" rel="noopener noreferrer"&gt;https://github.com/sumitvairagar/simple-agent-workshop&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;OpenAI API Docs: &lt;a href="https://platform.openai.com/docs" rel="noopener noreferrer"&gt;https://platform.openai.com/docs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;TypeScript: &lt;a href="https://www.typescriptlang.org" rel="noopener noreferrer"&gt;https://www.typescriptlang.org&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Built something cool with this? Share it in the comments! I'd love to see what you create.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>programming</category>
      <category>openai</category>
    </item>
  </channel>
</rss>
