<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Tanzil Ahmed</title>
    <description>The latest articles on Forem by Tanzil Ahmed (@tanzilahmed).</description>
    <link>https://forem.com/tanzilahmed</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%2F1242920%2F680149c4-92a2-4680-a977-6f8c8f8b4a4a.png</url>
      <title>Forem: Tanzil Ahmed</title>
      <link>https://forem.com/tanzilahmed</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/tanzilahmed"/>
    <language>en</language>
    <item>
      <title>I Built My Developer Portfolio with Zero Frameworks — Pure Vanilla JS</title>
      <dc:creator>Tanzil Ahmed</dc:creator>
      <pubDate>Tue, 07 Apr 2026 09:53:55 +0000</pubDate>
      <link>https://forem.com/tanzilahmed/i-built-my-developer-portfolio-with-zero-frameworks-pure-vanilla-js-n49</link>
      <guid>https://forem.com/tanzilahmed/i-built-my-developer-portfolio-with-zero-frameworks-pure-vanilla-js-n49</guid>
      <description>&lt;h2&gt;
  
  
  The Challenge
&lt;/h2&gt;

&lt;p&gt;Every developer portfolio looks the same — React, Next.js, Tailwind, same template. I wanted mine to stand out and actually demonstrate that I can write clean code without leaning on frameworks.&lt;/p&gt;

&lt;p&gt;Live: &lt;a href="https://tanzil-portfolio-sigma.vercel.app" rel="noopener noreferrer"&gt;https://tanzil-portfolio-sigma.vercel.app&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;A cyberpunk-themed developer portfolio with a terminal aesthetic. Boot sequence animation, typewriter effects, glitch animations — all in pure vanilla JS and CSS. Zero dependencies. Zero frameworks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Technical Decisions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Why no frameworks?&lt;/strong&gt;&lt;br&gt;
A portfolio is a static page. React adds 40KB+ of JavaScript for what is essentially a landing page. Vanilla JS is faster, lighter, and honestly more impressive to technical hiring managers who see through the abstraction.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The terminal boot sequence&lt;/strong&gt;&lt;br&gt;
The page opens with a simulated system boot — text lines appear one by one like a terminal initializing. Built with a simple JS array of strings and setTimeout chains. No library needed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Typewriter effect&lt;/strong&gt;&lt;br&gt;
Classic character-by-character reveal using requestAnimationFrame for smooth performance. Cancels and restarts cleanly when the user navigates.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Glitch animation&lt;/strong&gt;&lt;br&gt;
Pure CSS — a combination of clip-path and transform animations with staggered timing creates the glitch effect on the name header.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;HTML5&lt;/li&gt;
&lt;li&gt;CSS3 (custom properties, keyframe animations)&lt;/li&gt;
&lt;li&gt;Vanilla JavaScript (ES6+)&lt;/li&gt;
&lt;li&gt;Three.js (particle background)&lt;/li&gt;
&lt;li&gt;Deployed on Vercel&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What's Inside
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Boot sequence intro animation&lt;/li&gt;
&lt;li&gt;Terminal-style navigation&lt;/li&gt;
&lt;li&gt;Project showcase with live links&lt;/li&gt;
&lt;li&gt;Skills matrix&lt;/li&gt;
&lt;li&gt;Experience timeline&lt;/li&gt;
&lt;li&gt;Contact section&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Writing vanilla JS forces you to understand what frameworks actually do. No useEffect, no useState — just the DOM, events, and your own logic. Every developer should build at least one project without a framework.&lt;/p&gt;

&lt;p&gt;Check it out: &lt;a href="https://tanzil-portfolio-sigma.vercel.app" rel="noopener noreferrer"&gt;https://tanzil-portfolio-sigma.vercel.app&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;GitHub: &lt;a href="https://github.com/Tanzil-Ahmed" rel="noopener noreferrer"&gt;https://github.com/Tanzil-Ahmed&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>portfolio</category>
      <category>showdev</category>
    </item>
    <item>
      <title>I Built an AI Audio Mastering Engineer with Claude — It Analyzes 13 Acoustic Measurements</title>
      <dc:creator>Tanzil Ahmed</dc:creator>
      <pubDate>Tue, 07 Apr 2026 09:39:22 +0000</pubDate>
      <link>https://forem.com/tanzilahmed/i-built-an-ai-audio-mastering-engineer-with-claude-it-analyzes-13-acoustic-measurements-47cm</link>
      <guid>https://forem.com/tanzilahmed/i-built-an-ai-audio-mastering-engineer-with-claude-it-analyzes-13-acoustic-measurements-47cm</guid>
      <description>&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;MixMaster AI is an AI-powered audio mastering system. You upload a raw audio file, describe what you want in plain English, and Claude handles the entire mastering chain automatically.&lt;/p&gt;

&lt;p&gt;GitHub: &lt;a href="https://github.com/Tanzil-Ahmed/mixmaster-ai" rel="noopener noreferrer"&gt;https://github.com/Tanzil-Ahmed/mixmaster-ai&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;Audio mastering requires deep technical knowledge — EQ curves, compression ratios, loudness targets, stereo imaging. Most musicians and indie creators can't afford a mastering engineer for every track.&lt;/p&gt;

&lt;p&gt;I built one with Claude.&lt;/p&gt;

&lt;h2&gt;
  
  
  How It Works
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Audio Analysis&lt;/strong&gt;&lt;br&gt;
Claude analyzes 13 acoustic measurements from the uploaded file — loudness (LUFS), dynamic range, crest factor, spectral balance, stereo width, true peak, and more using librosa and pyloudnorm.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. AI Decision Making (Claude tool_use)&lt;/strong&gt;&lt;br&gt;
Claude reads the measurements + your creative brief and sets every DSP parameter — EQ frequencies and gains, compression ratio and threshold, saturation amount, stereo width, limiter ceiling.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Signal Processing Chain&lt;/strong&gt;&lt;br&gt;
The full mastering chain runs using Spotify's pedalboard library:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Corrective EQ (high-pass, surgical cuts)&lt;/li&gt;
&lt;li&gt;Compression (ratio, threshold, attack, release)&lt;/li&gt;
&lt;li&gt;Saturation (harmonic enhancement)&lt;/li&gt;
&lt;li&gt;Stereo imaging (mid-side processing)&lt;/li&gt;
&lt;li&gt;Limiting (true peak control, TPDF dither)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;4. Output&lt;/strong&gt;&lt;br&gt;
Streaming-ready WAV at -14 LUFS with true peak control. Professional quality, zero manual knob-turning.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Python&lt;/li&gt;
&lt;li&gt;Anthropic Claude API (tool_use)&lt;/li&gt;
&lt;li&gt;Spotify pedalboard (DSP chain)&lt;/li&gt;
&lt;li&gt;librosa + pyloudnorm (audio analysis)&lt;/li&gt;
&lt;li&gt;FastAPI (REST endpoint)&lt;/li&gt;
&lt;li&gt;Gradio (UI)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Three Interfaces
&lt;/h2&gt;

&lt;p&gt;The same mastering engine is exposed three ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Gradio UI (drag and drop)&lt;/li&gt;
&lt;li&gt;REST API (/master endpoint)&lt;/li&gt;
&lt;li&gt;CLI (command line)&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;Stem mastering (separate vocal, drums, instruments)&lt;/li&gt;
&lt;li&gt;Genre-aware presets&lt;/li&gt;
&lt;li&gt;Batch processing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Star the repo if you find it useful.&lt;/p&gt;

&lt;p&gt;GitHub: &lt;a href="https://github.com/Tanzil-Ahmed/mixmaster-ai" rel="noopener noreferrer"&gt;https://github.com/Tanzil-Ahmed/mixmaster-ai&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>ai</category>
      <category>audio</category>
      <category>opensource</category>
    </item>
    <item>
      <title>I Built an Autonomous Job Application Agent with Claude AI — Here's How It Works</title>
      <dc:creator>Tanzil Ahmed</dc:creator>
      <pubDate>Mon, 06 Apr 2026 23:35:27 +0000</pubDate>
      <link>https://forem.com/tanzilahmed/i-built-an-autonomous-job-application-agent-with-claude-ai-heres-how-it-works-31d9</link>
      <guid>https://forem.com/tanzilahmed/i-built-an-autonomous-job-application-agent-with-claude-ai-heres-how-it-works-31d9</guid>
      <description>&lt;p&gt;Job hunting today is broken.&lt;/p&gt;

&lt;p&gt;You’re expected to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Search across multiple job boards&lt;/li&gt;
&lt;li&gt;Tailor resumes for every role&lt;/li&gt;
&lt;li&gt;Research each company&lt;/li&gt;
&lt;li&gt;Write custom cover letters&lt;/li&gt;
&lt;li&gt;Track applications manually&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s repetitive, time-consuming, and mentally draining — especially when you’re applying to dozens (or hundreds) of roles.&lt;/p&gt;

&lt;p&gt;So I built &lt;strong&gt;Job Hunter AI&lt;/strong&gt; — an autonomous job application agent that does this end-to-end:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Find jobs → Research companies → Generate tailored applications → Track everything&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This post breaks down exactly how I built it using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Claude API (tool use)&lt;/li&gt;
&lt;li&gt;FastAPI&lt;/li&gt;
&lt;li&gt;WebSockets&lt;/li&gt;
&lt;li&gt;Tavily + Exa (search + data enrichment)&lt;/li&gt;
&lt;li&gt;PostgreSQL&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  The Problem: Job Hunting is High Friction
&lt;/h1&gt;

&lt;p&gt;The core issue isn’t lack of jobs — it’s &lt;strong&gt;friction&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Every application requires:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Context switching (LinkedIn → company site → resume editor)&lt;/li&gt;
&lt;li&gt;Repeated research&lt;/li&gt;
&lt;li&gt;Manual writing&lt;/li&gt;
&lt;li&gt;No feedback loop&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Even worse:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You lose track of where you applied&lt;/li&gt;
&lt;li&gt;You don’t know which strategy works&lt;/li&gt;
&lt;li&gt;You burn out before you optimize&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I didn’t want a “job tracker.”&lt;/p&gt;

&lt;p&gt;I wanted an &lt;strong&gt;agent&lt;/strong&gt; that behaves like a smart assistant:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Find relevant roles, understand the company, and apply better than I would manually.”&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  System Architecture (High-Level)
&lt;/h1&gt;

&lt;p&gt;Here’s how the system is structured:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                ┌──────────────────────┐
                │   Frontend (HTML)    │
                │  + WebSocket Client  │
                └─────────┬────────────┘
                          │
                          ▼
                ┌──────────────────────┐
                │      FastAPI         │
                │  (API + WebSockets)  │
                └─────────┬────────────┘
                          │
        ┌─────────────────┼─────────────────┐
        ▼                 ▼                 ▼
┌──────────────┐  ┌──────────────┐  ┌──────────────┐
│ Claude API   │  │ Tavily API   │  │ Exa API      │
│ (Agent Brain)│  │ (Search)     │  │ (Deep Data)  │
└──────────────┘  └──────────────┘  └──────────────┘
                          │
                          ▼
                ┌──────────────────────┐
                │   PostgreSQL DB      │
                │ (Jobs + Tracking)    │
                └──────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;Claude is not just generating text — it is &lt;strong&gt;orchestrating actions via tools&lt;/strong&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  Claude Tool Use: Turning LLM into an Agent
&lt;/h1&gt;

&lt;p&gt;This is where things get interesting.&lt;/p&gt;

&lt;p&gt;Instead of prompting Claude to “write a cover letter,” I gave it tools like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;search_jobs&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;research_company&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;generate_application&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Claude decides &lt;strong&gt;when to call which tool&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example: Company Research Tool
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;tools&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;research_company&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;description&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;Fetch detailed company insights&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;input_schema&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;object&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;properties&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;company_name&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;string&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;required&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;company_name&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="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;
  
  
  Claude Call
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;messages&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="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;claude-3-opus-20240229&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;max_tokens&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;messages&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&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;content&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;Apply to backend roles at Stripe&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="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Tool Execution Layer
&lt;/h3&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;research_company&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;company_name&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;tavily_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tavily&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;company_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;exa_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;exa&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_company_info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;company_name&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;summary&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;tavily_data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;summary&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;culture&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;exa_data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;culture&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;tech_stack&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;exa_data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tech&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;h3&gt;
  
  
  What’s powerful here?
&lt;/h3&gt;

&lt;p&gt;Claude:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Decides &lt;em&gt;when&lt;/em&gt; to research&lt;/li&gt;
&lt;li&gt;Uses the data to &lt;em&gt;adapt the application&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Maintains context across steps&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This turns it from a chatbot into a &lt;strong&gt;decision-making system&lt;/strong&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  FastAPI + WebSocket Pipeline
&lt;/h1&gt;

&lt;p&gt;I didn’t want a “click → wait → response” UX.&lt;/p&gt;

&lt;p&gt;This is a &lt;strong&gt;streaming system&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why WebSockets?
&lt;/h3&gt;

&lt;p&gt;Because the agent:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Finds jobs&lt;/li&gt;
&lt;li&gt;Researches companies&lt;/li&gt;
&lt;li&gt;Generates applications&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;…and I want the user to see that &lt;em&gt;live&lt;/em&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  Backend Flow
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@app.websocket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/ws&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;websocket_endpoint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;WebSocket&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;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;accept&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;query&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;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;receive_text&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="c1"&gt;# Step 1: Find jobs
&lt;/span&gt;        &lt;span class="n"&gt;jobs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;search_jobs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send_json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;stage&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;jobs_found&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;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;jobs&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;job&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;jobs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="c1"&gt;# Step 2: Research
&lt;/span&gt;            &lt;span class="n"&gt;company_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;research_company&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;job&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;company&lt;/span&gt;&lt;span class="sh"&gt;"&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;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send_json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;stage&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;research_done&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;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;company_data&lt;/span&gt;
            &lt;span class="p"&gt;})&lt;/span&gt;

            &lt;span class="c1"&gt;# Step 3: Generate application
&lt;/span&gt;            &lt;span class="n"&gt;application&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;generate_application&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;job&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;company_data&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;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send_json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;stage&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;application_ready&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;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;
            &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Frontend Behavior
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Connects via WebSocket&lt;/li&gt;
&lt;li&gt;Listens for &lt;code&gt;stage&lt;/code&gt; updates&lt;/li&gt;
&lt;li&gt;Renders results progressively&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This creates a &lt;strong&gt;real-time agent experience&lt;/strong&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  What Surprised Me While Building This
&lt;/h1&gt;

&lt;h3&gt;
  
  
  1. Tool Use &amp;gt; Prompt Engineering
&lt;/h3&gt;

&lt;p&gt;Initially, I tried:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Write better prompts”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That plateaued quickly.&lt;/p&gt;

&lt;p&gt;The real unlock was:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Giving the model structured tools and letting it &lt;em&gt;act&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  2. Data Quality &amp;gt; Model Quality
&lt;/h3&gt;

&lt;p&gt;Even with Claude:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Bad company data = bad applications&lt;/li&gt;
&lt;li&gt;Weak search results = irrelevant jobs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your system is only as good as:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The data pipeline feeding the model&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  3. State Management is Hard
&lt;/h3&gt;

&lt;p&gt;When your agent:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Searches&lt;/li&gt;
&lt;li&gt;Branches&lt;/li&gt;
&lt;li&gt;Calls tools&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You need to track:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Context&lt;/li&gt;
&lt;li&gt;Progress&lt;/li&gt;
&lt;li&gt;Failures&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This becomes a &lt;strong&gt;mini orchestration engine&lt;/strong&gt;, not just an API call.&lt;/p&gt;




&lt;h3&gt;
  
  
  4. Real-Time UX Changes Everything
&lt;/h3&gt;

&lt;p&gt;Without WebSockets:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It feels slow&lt;/li&gt;
&lt;li&gt;Feels like a black box&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With streaming:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Feels alive&lt;/li&gt;
&lt;li&gt;Feels intelligent&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  How to Run It Yourself
&lt;/h1&gt;

&lt;ol&gt;
&lt;li&gt;Clone the repo:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/Tanzil-Ahmed/job-hunter-agent

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

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Set environment variables:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="n"&gt;ANTHROPIC_API_KEY&lt;/span&gt;=
&lt;span class="n"&gt;TAVILY_API_KEY&lt;/span&gt;=
&lt;span class="n"&gt;EXA_API_KEY&lt;/span&gt;=
&lt;span class="n"&gt;DATABASE_URL&lt;/span&gt;=&lt;span class="n"&gt;postgresql&lt;/span&gt;://...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Install dependencies:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Run FastAPI server:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;uvicorn api:app &lt;span class="nt"&gt;--reload&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Open frontend:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;index.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  What’s Next
&lt;/h1&gt;

&lt;p&gt;Planned improvements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Resume auto-optimization per job&lt;/li&gt;
&lt;li&gt;Feedback loop (track response rates)&lt;/li&gt;
&lt;li&gt;Auto-apply integrations&lt;/li&gt;
&lt;li&gt;Multi-agent workflow (research agent + writing agent)&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  Final Thoughts
&lt;/h1&gt;

&lt;p&gt;This project changed how I think about building with AI.&lt;/p&gt;

&lt;p&gt;The shift is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;From “generate text” → to “build systems that act”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you’re building AI apps today:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Don’t just prompt&lt;/li&gt;
&lt;li&gt;Design agents&lt;/li&gt;
&lt;li&gt;Build pipelines&lt;/li&gt;
&lt;/ul&gt;




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

&lt;p&gt;If this was useful or interesting:&lt;/p&gt;

&lt;p&gt;👉 Star the repo&lt;br&gt;
👉 Run it locally&lt;br&gt;
👉 Break it, improve it, build on top of it&lt;/p&gt;

&lt;p&gt;This is just the beginning of what autonomous systems can do.&lt;/p&gt;

&lt;p&gt;Let’s build smarter tools.&lt;/p&gt;

</description>
      <category>python</category>
      <category>ai</category>
      <category>claudeapi</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
