<?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: juvet manga</title>
    <description>The latest articles on DEV Community by juvet manga (@juvet_manga).</description>
    <link>https://dev.to/juvet_manga</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%2F2191408%2F675c63f6-42f6-4237-ac5b-945f3d5b3d14.jpeg</url>
      <title>DEV Community: juvet manga</title>
      <link>https://dev.to/juvet_manga</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/juvet_manga"/>
    <language>en</language>
    <item>
      <title>I Built a Notion MCP Job Alert Bot to Help My Designer Brother Find Work online from a developing country</title>
      <dc:creator>juvet manga</dc:creator>
      <pubDate>Tue, 31 Mar 2026 06:29:14 +0000</pubDate>
      <link>https://dev.to/juvet_manga/i-built-a-notion-mcp-job-alert-bot-to-help-my-designer-brother-find-work-online-from-a-developing-24h2</link>
      <guid>https://dev.to/juvet_manga/i-built-a-notion-mcp-job-alert-bot-to-help-my-designer-brother-find-work-online-from-a-developing-24h2</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;(I made this post intially for the Notion MCP challenge but since it is more storydriven I prepared another version to submit and use this one to share to the community, with my back story for building my tool Nancy. Sorry in advance if at some point it sounds like an ad for Notion MCP)  - &lt;a href="https://dev.to/juvet_manga/nancy-a-notion-powered-job-intelligence-bot-built-out-of-necessity-2hhe"&gt;Read the short version here&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There's a version of this story where I talk about architecture patterns and API design. I'll get there. But first, let me tell you why this project exists.&lt;/p&gt;

&lt;p&gt;My brother is one of the most talented designers I know. We live in Cameroon, work together at a startup that doesn't pay enough yet, and needed side gigs to survive. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We tried Upwork but payments aren't supported in our country, so your earnings just sit there, locked, visible but untouchable.&lt;/li&gt;
&lt;li&gt;We tried Fiverr but my brother's account got blocked immediately after we landed our first client, no warning, no reason given. He tried to verify his identity with his national ID card and couldn't, because Fiverr only accepted passports at the time (even though they'd accepted ID cards before). Support never replied by the way.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We spent over two months living on less than $100. Combined.&lt;/p&gt;

&lt;p&gt;I decided to stop waiting for platforms to decide our fate. I built &lt;strong&gt;Nancy&lt;/strong&gt; (named after my niece),  a service that scrapes Dribbble for new design job postings and sends us a Telegram alert the moment one appears. &lt;/p&gt;

&lt;p&gt;The idea was simple: my brother would see job postings before almost anyone else in the world. An edge, however small.&lt;/p&gt;

&lt;p&gt;Sad part though, It didn't land us a job (despite being very useful). Most positions required US (or Europe) residency or full-time availability, which we couldn't offer. Hopefully we had a gig with a local company that paid enough for a while.&lt;/p&gt;

&lt;p&gt;Anyway it was worth every line of code. I enjoyed fighting fate alongside my brother.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; I built a Python bot called Nancy that scrapes Dribbble &lt;br&gt;
job listings and sends Telegram alerts. After adding Notion MCP, &lt;br&gt;
Notion became both the config layer (live settings) and the data &lt;br&gt;
layer (job pipeline tracking). Full source on GitHub.&lt;/p&gt;


&lt;h2&gt;
  
  
  What Is Nancy? (A Notion MCP-Powered Job Alert Bot)
&lt;/h2&gt;
&lt;h3&gt;
  
  
  How It Scrapes and Alerts in Real Time
&lt;/h3&gt;

&lt;p&gt;Nancy is a Python bot that:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Scrapes Dribbble job listings on a schedule&lt;/li&gt;
&lt;li&gt;Summarizes each job description using HuggingFace's &lt;code&gt;facebook/bart-large-cnn&lt;/code&gt; model&lt;/li&gt;
&lt;li&gt;Sends a formatted alert to a Telegram channel with one-tap apply buttons&lt;/li&gt;
&lt;li&gt;Tracks everything so the same job is never sent twice&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The stack is intentionally lean: Python, FastAPI, BeautifulSoup, and Notion MCP for state management and configuration.&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%2Fqfjfrd9tjar1uwq93rxd.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%2Fqfjfrd9tjar1uwq93rxd.png" alt="Telegram channel with Nancy job alert bot" width="800" height="509"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before Notion, Nancy stored state in flat JSON files and had zero configuration — to change anything you had to redeploy. It worked, but it was not practical.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Hacker note:&lt;/strong&gt; I used a very interesting tip to get my service working live without ever paying anything. What I did was to use Render.com hosting service to host my app as a web app (Not background or CRON jobs!! These are billed services) and deploy it with an endpoint allowing me to trigger scraping. Then I created an account on the tool Uptime Robot, where I set it to hit my endpoint after every 15 minutes, this way it makes the service stay alive and always act like a live monitoring service.&lt;br&gt;
It is also possible to create a background task service on Render but it's paid, I opted for this free workaround instead (it's got its limitations too but works pretty fine for personal usage). Share me your reviews if you try this tip! 🤓&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Video Demo
&lt;/h2&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/8dpzKR2p3aQ"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Using Notion MCP as a Control Plane (Not Just a Destination)
&lt;/h2&gt;

&lt;p&gt;The Notion MCP integration transforms Nancy from a one-trick scraper into a &lt;strong&gt;bidirectional job intelligence system&lt;/strong&gt;. Notion is now both the control plane (Nancy reads its instructions from Notion) and the data layer (every job Nancy finds lives in Notion with full status tracking).&lt;/p&gt;

&lt;h3&gt;
  
  
  The Config Database: Live Settings Without Redeployment
&lt;/h3&gt;

&lt;p&gt;Most tutorials on Notion MCP show it as an output layer. Nancy flips that.&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%2Fuc2rrzk737ikt0c53n7l.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%2Fuc2rrzk737ikt0c53n7l.png" alt="Notion dashboard with config settings" width="800" height="386"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nancy reads a live config from a Notion database on every single run:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Setting&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Example Value&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Effect&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;keywords&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;designer, UX, product&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Only alert on jobs matching these terms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;job_types&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Full-time, Contract&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Filter by employment type&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;max_pages&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;3&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;How many Dribbble pages to scrape per run&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;active&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;true&lt;/code&gt; / &lt;code&gt;false&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Kill switch — pause Nancy without touching code&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Want to focus only on freelance roles this week? Edit one cell in Notion. Want to pause Nancy while you're away? Flip &lt;code&gt;active&lt;/code&gt; to &lt;code&gt;false&lt;/code&gt;. No redeployment, no code changes, no terminal.&lt;/p&gt;

&lt;p&gt;`# Nancy reads this on every trigger&lt;br&gt;
config = notion_tracker.get_config()&lt;/p&gt;

&lt;p&gt;if config.get("active", "true").lower() == "false":&lt;br&gt;
    return {"status": "paused", "detail": "Nancy is paused via Notion config."}&lt;/p&gt;

&lt;p&gt;max_pages = int(config.get("max_pages", 2))&lt;br&gt;
keywords = [k.strip().lower() for k in config.get("keywords", "").split(",") if k.strip()]`&lt;/p&gt;

&lt;h3&gt;
  
  
  The Jobs Database: A Full Application Pipeline in Notion
&lt;/h3&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%2F5se4nh1hiu1nhv9oefrm.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%2F5se4nh1hiu1nhv9oefrm.png" alt="Notion table with job postings" width="800" height="385"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Every new job Nancy finds is saved to a Notion database with full metadata:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Job Title, Company, Location, Job Type&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Status&lt;/strong&gt; — &lt;code&gt;New → Notified → Reviewing → Applied → Archived&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;URL&lt;/strong&gt; — used for deduplication (no more duplicate alerts)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Summary&lt;/strong&gt; — the HuggingFace-generated summary&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Date Found&lt;/strong&gt; — when Nancy discovered it&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Telegram Sent&lt;/strong&gt; — checkbox confirming the alert was delivered&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Pipeline Board view turns Notion into a job application tracker. You see every opportunity at a glance, and you move cards as you progress. Nancy handles discovery; you handle decisions.&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%2Frd91zctb1ajm9tqdwn9i.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%2Frd91zctb1ajm9tqdwn9i.png" alt="Notion Kanban view with job posts scraped by Nancy" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Full Flow: From Scrape to Telegram Alert
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;/trigger-scraper called&lt;br&gt;
  → read config FROM Notion (active? max_pages? keywords? job_types?)&lt;br&gt;
  → if active=false → return "paused"&lt;br&gt;
  → load existing job URLs from Notion (deduplication)&lt;br&gt;
  → scrape Dribbble up to max_pages&lt;br&gt;
  → for each new job matching filters:&lt;br&gt;
      → summarize via HuggingFace API&lt;br&gt;
      → send Telegram notification&lt;br&gt;
      → save to Notion (Status=New)&lt;br&gt;
      → mark Telegram Sent → Status=Notified&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  New API Endpoints: /config and /jobs
&lt;/h2&gt;

&lt;p&gt;Two new endpoints complete the picture:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;GET /config&lt;/code&gt;&lt;/strong&gt; — returns the live Notion config so you can verify what Nancy is running with:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;{&lt;br&gt;
  "source": "notion",&lt;br&gt;
  "config": {&lt;br&gt;
    "keywords": "designer, UX, product",&lt;br&gt;
    "job_types": "Full-time, Contract",&lt;br&gt;
    "max_pages": "3",&lt;br&gt;
    "active": "true"&lt;br&gt;
  }&lt;br&gt;
}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;GET /jobs&lt;/code&gt;&lt;/strong&gt; — returns all jobs stored in Notion, filterable by status. Falls back to local JSON if Notion isn't configured.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Python 3.11&lt;/strong&gt; + &lt;strong&gt;FastAPI&lt;/strong&gt; — web service and API&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;BeautifulSoup4&lt;/strong&gt; — Dribbble scraping&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HuggingFace&lt;/strong&gt; (&lt;code&gt;facebook/bart-large-cnn&lt;/code&gt;) — job description summarization&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;python-telegram-bot&lt;/strong&gt; — Telegram channel notifications&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;notion-client&lt;/strong&gt; — official Notion Python SDK&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Render&lt;/strong&gt; — cloud deployment&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Notion MCP&lt;/strong&gt; — control plane + data layer&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why This Architecture Actually Matters
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Notion as Source, Not Just Output
&lt;/h3&gt;

&lt;p&gt;Most Notion integrations treat Notion as a destination — a place to dump output. What makes this different is that Notion is also the &lt;em&gt;source&lt;/em&gt;. Nancy checks Notion before it does anything. That's the MCP model: your workspace becomes an operating surface, not just a display.&lt;/p&gt;

&lt;p&gt;For us, concretely, this means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;My brother can adjust what kinds of jobs Nancy watches for without asking me to redeploy anything&lt;/li&gt;
&lt;li&gt;Every lead is tracked in one place, not scattered across Telegram history&lt;/li&gt;
&lt;li&gt;The pipeline view makes it obvious which opportunities are worth pursuing&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Source Code&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The full project is open source: &lt;a href="https://github.com/juv85/Nancy-v2-alt" rel="noopener noreferrer"&gt;&lt;strong&gt;github.com/juv85/Nancy-v2-alt&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To run your own instance, clone the repo and set these environment variables:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;TELEGRAM_BOT_TOKEN=&lt;br&gt;
TELEGRAM_CHANNEL_ID=&lt;br&gt;
HF_TOKEN=&lt;br&gt;
NOTION_TOKEN=&lt;br&gt;
NOTION_JOBS_DB_ID=&lt;br&gt;
NOTION_CONFIG_DB_ID=&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;A &lt;code&gt;.env.example&lt;/code&gt; is included as a template.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next: Toward an Autonomous Job Application Agent
&lt;/h2&gt;

&lt;p&gt;I want to be honest: what Nancy does today with Notion is not yet even close to the full power of what MCP makes possible.&lt;/p&gt;

&lt;p&gt;Anyway the vision is to build an autonomous job application agent.&lt;/p&gt;

&lt;p&gt;With Notion MCP, the agent gains long-term memory. Not just a database of &lt;br&gt;
scraped jobs, but a living context store with an overview of the user's &lt;br&gt;
identity and metadata on jobs that matter to the user.&lt;/p&gt;

&lt;p&gt;The agent this way will know what is relevant to highlight when drafting assets to apply, and also what to apply.&lt;/p&gt;

&lt;p&gt;Thanks for reading&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Juvet Manga&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Extras:
&lt;/h2&gt;

&lt;p&gt;Thanks for reading this far.&lt;br&gt;
The story I shared is actually true and you can find my brother's portfolio, website and LinkedIn profile here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Portfolio&lt;/strong&gt;: &lt;a href="http://www.dribbble.com/lePerfectionniste" rel="noopener noreferrer"&gt;www.dribbble.com/lePerfectionniste&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LinkedIn&lt;/strong&gt;: &lt;a href="http://www.linkedin.com/in/paul-nana-manga/" rel="noopener noreferrer"&gt;www.linkedin.com/in/paul-nana-manga/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Website&lt;/strong&gt;: &lt;a href="https://leperfectionniste1.wixsite.com/home/new-home" rel="noopener noreferrer"&gt;leperfectionniste-site&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want high quality work related to design especially in tech (UI/UX for mobile and web apps, Dashboards designs, Pitch-deck slides, brand design etc.) feel free to reach out - &lt;a href="mailto:leperfectionniste123@gmail.com"&gt;leperfectionniste123@gmail.com&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  📣 Need help with AI for your mobile app ?
&lt;/h3&gt;

&lt;p&gt;As someone who's solved these challenges I offer technical consulting specifically for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Building Custom Text classification and QA models for mobile apps&lt;/li&gt;
&lt;li&gt;NLP model integration in React Native apps&lt;/li&gt;
&lt;li&gt;Mobile-optimized AI architecture&lt;/li&gt;
&lt;li&gt;AI project ideation and conception&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I am also available for freelance gigs related to :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mobile app development with React Native&lt;/li&gt;
&lt;li&gt;Backend development with Django&lt;/li&gt;
&lt;li&gt;Web apps development with React&lt;/li&gt;
&lt;li&gt;CI/CD setup using Github Actions&lt;/li&gt;
&lt;li&gt;n8n setup&lt;/li&gt;
&lt;li&gt;AI automation
Reach out here - &lt;a href="mailto:mangajuvet87@gmail.com"&gt;mangajuvet87@gmail.com&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Let’s connect:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;LinkedIn&lt;/strong&gt;: &lt;a href="https://www.linkedin.com/in/juvet-manga/" rel="noopener noreferrer"&gt;https://www.linkedin.com/in/juvet-manga/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;X&lt;/strong&gt;: &lt;a href="https://x.com/manga_juvet" rel="noopener noreferrer"&gt;https://x.com/manga_juvet&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Book a free call&lt;/strong&gt;: &lt;a href="https://zcal.co/juvet/30min" rel="noopener noreferrer"&gt;https://zcal.co/juvet/30min&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>python</category>
      <category>tutorial</category>
      <category>ai</category>
    </item>
    <item>
      <title>Nancy: A Notion-Powered Job Intelligence Bot Built Out of Necessity</title>
      <dc:creator>juvet manga</dc:creator>
      <pubDate>Sun, 29 Mar 2026 07:06:58 +0000</pubDate>
      <link>https://dev.to/juvet_manga/nancy-a-notion-powered-job-intelligence-bot-built-out-of-necessity-2hhe</link>
      <guid>https://dev.to/juvet_manga/nancy-a-notion-powered-job-intelligence-bot-built-out-of-necessity-2hhe</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/notion-2026-03-04"&gt;Notion MCP Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;Nancy is an automated Dribbble job intelligence system. It monitors Dribbble for new design job postings, summarizes them using AI, fires real-time alerts to a Telegram channel, and now, powered by Notion MCP, stores every opportunity in a structured Notion workspace with full application pipeline tracking.&lt;/p&gt;

&lt;p&gt;The idea was to give my brother an edge: see a new job posting before almost anyone else in the world, apply immediately, and track the whole pipeline in one place.&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%2Fju81t04kjaeow8cw3oed.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%2Fju81t04kjaeow8cw3oed.png" alt=" " width="800" height="509"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Core capabilities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Scrapes Dribbble job listings on demand via a REST API trigger&lt;/li&gt;
&lt;li&gt;Summarizes job descriptions using HuggingFace (facebook/bart-large-cnn)&lt;/li&gt;
&lt;li&gt;Sends formatted Telegram alerts with one-tap apply buttons&lt;/li&gt;
&lt;li&gt;Stores all jobs in a Notion database with status tracking&lt;/li&gt;
&lt;li&gt;Reads its own configuration live from Notion — no redeployment needed to change behavior&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Tech stack: Python 3.11, FastAPI, BeautifulSoup4, HuggingFace Inference API, python-telegram-bot, notion-client, deployed on Render.&lt;/p&gt;

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

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/8dpzKR2p3aQ"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Show us the code
&lt;/h2&gt;

&lt;p&gt;GitHub: &lt;a href="https://github.com/juv85/Nancy-v2-alt" rel="noopener noreferrer"&gt;github.com/juv85/Nancy-v2-alt&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Notion integration lives in notion/notion_integration.py. The key entry points:&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;# scraper/scraper.py — reads live config from Notion on every run
&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;notion_tracker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_config&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;config&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;active&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;true&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;false&lt;/span&gt;&lt;span class="sh"&gt;"&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;status&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;paused&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;detail&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;Nancy is paused via Notion config.&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_pages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&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;max_pages&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="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;keywords&lt;/span&gt; &lt;span class="o"&gt;=&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="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;config&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;keywords&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="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# After scraping, each new job is saved to Notion and marked notified
&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;notion_tracker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;page_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;notion_tracker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_job&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;notion_tracker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mark_telegram_sent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;page_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To run your own instance, clone the repo and set the environment variables required in the .env.example&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Used Notion MCP
&lt;/h2&gt;

&lt;p&gt;Most Notion integrations use Notion as a destination — a place to dump output. Nancy uses it as both &lt;strong&gt;input and output&lt;/strong&gt;: Notion is the control plane Nancy reads from, and the data layer Nancy writes to.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Notion as control plane (input)&lt;/strong&gt;
&lt;/h3&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%2Fm60g47kx9d42lyoekbr4.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%2Fm60g47kx9d42lyoekbr4.png" alt=" " width="800" height="385"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nancy reads a &lt;strong&gt;Config database&lt;/strong&gt; in Notion before every single run:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Setting&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Example&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;What it does&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;active&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;true&lt;/code&gt; / &lt;code&gt;false&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Kill switch — pause Nancy without touching code&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;keywords&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;designer, UX, product&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Only alert on jobs matching these terms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;job_types&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Full-time, Contract&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Filter by employment type&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;max_pages&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;3&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;How many Dribbble pages to scrape per run&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Want Nancy to focus on freelance roles this week? Edit one cell in Notion. Want to pause it while you're traveling? Flip &lt;code&gt;active&lt;/code&gt; to &lt;code&gt;false&lt;/code&gt;. No terminal, no redeployment.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Notion as data layer (output)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;[SCREENSHOT: Nancy Jobs database — Pipeline Board (Kanban) with columns New / Notified / Reviewing / Applied / Archived]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Every job Nancy finds is saved to a &lt;strong&gt;Jobs database&lt;/strong&gt; with full metadata and a status workflow:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;New → Notified → Reviewing → Applied → Archived&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This turns Notion into an actual application tracker. Nancy handles discovery; you handle decisions. The Pipeline Board makes it immediately obvious where each opportunity stands.&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%2Fz2e2sfkspcp82uyn6tm5.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%2Fz2e2sfkspcp82uyn6tm5.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The full flow&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;/trigger-scraper&lt;br&gt;
  → read config FROM Notion (active? max_pages? keywords? job_types?)&lt;br&gt;
  → if active=false → return "paused"&lt;br&gt;
  → fetch existing job URLs from Notion (deduplication)&lt;br&gt;
  → scrape Dribbble up to max_pages&lt;br&gt;
  → for each new job matching filters:&lt;br&gt;
      → summarize via HuggingFace&lt;br&gt;
      → send Telegram alert&lt;br&gt;
      → save to Notion Jobs DB (Status = New)&lt;br&gt;
      → update Status → Notified, tick Telegram Sent&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Two new API endpoints complete the picture:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;GET /config&lt;/code&gt; — returns the live Notion config on demand&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;GET /jobs&lt;/code&gt; — returns all jobs from Notion, filterable by status&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;I want to be honest: what Nancy does today with Notion is not yet even close to the full power of what MCP makes possible.&lt;/p&gt;

&lt;p&gt;Anyway the vision is to build an autonomous job application agent.&lt;/p&gt;

&lt;p&gt;Notion becomes the agent's long-term memory. Not just a database of scraped jobs, but a living context store with an overview of the user's identity and metadata on jobs that matter to the user. &lt;br&gt;
The agent this way will know what is relevant to highlight when drafting assets to apply, and also what to apply.&lt;/p&gt;

&lt;p&gt;Thanks for reading&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Juvet Manga&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>notionchallenge</category>
      <category>mcp</category>
      <category>ai</category>
    </item>
    <item>
      <title>What are attention masks in the context of transformers (GPT, BERT, T5)</title>
      <dc:creator>juvet manga</dc:creator>
      <pubDate>Sun, 03 Nov 2024 07:25:39 +0000</pubDate>
      <link>https://dev.to/juvet_manga/what-are-attention-masks-in-the-context-of-transformers-gpt-bert-t5-jb4</link>
      <guid>https://dev.to/juvet_manga/what-are-attention-masks-in-the-context-of-transformers-gpt-bert-t5-jb4</guid>
      <description>&lt;p&gt;Imagine your brain as a supercomputer, constantly flooded with data—sights, sounds, thoughts. Every second, new information bombards us, yet somehow, we avoid being overwhelmed. Our brains don’t process every detail; they focus on what matters and filter the rest. Deep learning models, especially transformer-based ones like GPT and BERT, try to mimic this focus. But in a digital world, how do they know what’s important and what to ignore?&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Do Transformers Need an Attention Mask?
&lt;/h3&gt;

&lt;p&gt;Imagine sitting in a bar, talking with a friend while other people chat loudly around you. You won’t listen to every conversation. You focus only on the words said by your friend despite the fact that your ears capture the surrounding chats. Your brain creates an ‘attention mask,’ filtering out everything irrelevant.&lt;/p&gt;

&lt;p&gt;Transformers have a similar challenge and this is where attention masks step in. An attention mask is a tool that tells the model which parts of the input are relevant (ones to “pay attention to”) and which parts should be ignored (masked out). It’s like a set of invisible markers that highlight where to focus and what to skip.&lt;/p&gt;

&lt;p&gt;💁🏾 Can you show a clear example that highlights how attention works in a sentence ? &lt;/p&gt;

&lt;p&gt;🧏🏾‍♂️ Sure, check this out &lt;/p&gt;

&lt;h3&gt;
  
  
  How Attention Masks Work in Practice
&lt;/h3&gt;

&lt;p&gt;Consider the following sentence&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"The cat sat&lt;/strong&gt; q1230jiqowe &lt;strong&gt;on&lt;/strong&gt; 3rk30k1 &lt;strong&gt;the mat&lt;/strong&gt; 1231"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;here is how our model will represent the data&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sentence&lt;/strong&gt;: [The, cat, sat, q1230jiqowe, on, 3rk30k1, the, mat, 1231]&lt;br&gt;
&lt;strong&gt;Attention Mask:&lt;/strong&gt;     [1,   1,   1,       0,       1,     0,    1,    1,     0]&lt;/p&gt;

&lt;p&gt;In this mask:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;1s indicate the model should focus on these tokens&lt;/strong&gt; because they form the actual sentence.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;0s indicate noise or irrelevant tokens&lt;/strong&gt; that the model should ignore.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I guess you automatically removed the irrelevant characters when reading and focused on the valuable information. That’s it.&lt;/p&gt;

&lt;p&gt;In transformers, data is fed into the model in the form of a sequence (like a sentence split into tokens). Not all tokens in the sequence are useful; some may be padding tokens added to create equal-length inputs for batch processing. Attention masks act as a filter to block out these irrelevant tokens.&lt;/p&gt;

&lt;p&gt;💁🏾 Pad… &lt;/p&gt;

&lt;p&gt;🧏🏾‍♂️ Yes I know, let me explain&lt;/p&gt;

&lt;p&gt;Well, models have a particular way of processing data. The model needs all the inputs to have the same length before they can be treated, and this length is set when the model is being trained, it’s called the token length.&lt;/p&gt;

&lt;p&gt;In practice, if a model has a token length of 10 for example, it looks like this&lt;/p&gt;

&lt;p&gt;Sentence 1: The cat sat on the mat&lt;/p&gt;

&lt;p&gt;→ [The, cat, sat, on, the, mat, [PAD], [PAD], [PAD], [PAD]]&lt;/p&gt;

&lt;p&gt;Sentence 2: The dog ate the fish and ran to the room before I could realize&lt;/p&gt;

&lt;p&gt;→ [The, dog, ate, the, fish, and, ran, to, the, room, before]&lt;/p&gt;

&lt;p&gt;This helps the model expect a certain amount of information at a given time, so as to avoid excessive data intake, a bit like a speed limiter. This might be the idea of another article but for now let’s stick to attention masks.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Attention Masks Matter
&lt;/h3&gt;

&lt;p&gt;Without attention masks, transformers would process all parts of an input indiscriminately. In practice, this would make the model prone to errors, focusing on irrelevant data and potentially "hallucinating" patterns that don’t exist. &lt;/p&gt;

&lt;p&gt;By focusing on key information and ignoring unnecessary parts, attention masks keep models efficient, accurate, and grounded in relevant data.&lt;/p&gt;

&lt;p&gt;🤷🏾 I think I got the point now, but how does this help anyone in real-world scenarios ? &lt;/p&gt;

&lt;p&gt;💁🏾‍♂️ Well there are many applications but take this one…&lt;/p&gt;

&lt;h3&gt;
  
  
  Practical Impact of Attention Masks
&lt;/h3&gt;

&lt;p&gt;Think of a voice-controlled virtual assistant that responds to commands like, "Play my favorite song." Often, the audio data is noisy, with background sounds, pauses, or even other conversations nearby. Without an attention mask, the assistant might focus on everything in the audio stream, including background noises and other voices. This could lead to misinterpreting the command or even responding to unrelated words.&lt;/p&gt;

&lt;p&gt;For example, if someone says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Uh, Alexa, can you uhmm play my favorite song? (kids talking in the background)"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Without an attention mask, the assistant might process every single word, including "uh," “uhmm,” "kids talking in the background," and other irrelevant sounds. This can make it slower to respond or even trigger the wrong action.&lt;/p&gt;

&lt;p&gt;With an attention mask, the assistant zeros in on the actual command ("can you play my favorite song?") and filters out the rest. This helps it respond quickly, accurately, and without being thrown off by background noise, providing a much smoother user experience.&lt;/p&gt;

&lt;p&gt;iPhone users should be able to relate from the way Siri acts most of the time&lt;/p&gt;

&lt;h3&gt;
  
  
  Brief Note on Other Mask Types
&lt;/h3&gt;

&lt;p&gt;In addition to attention masks, there are several other types of masks that play important roles in transformer models:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Padding Masks&lt;/strong&gt;: These masks indicate which tokens in a sequence are padding tokens (usually represented as 0 or a special token). Padding is used to ensure all input sequences in a batch are of equal length. Padding masks help the model ignore these irrelevant tokens during processing, much like attention masks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Segment Masks&lt;/strong&gt;: In tasks like question-answering or sentence-pair classification, segment masks distinguish between different segments of input. For instance, in a question-answer pair, one segment might represent the question while the other represents the context. This helps the model understand how to treat different parts of the input relative to one another.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Subword Masks&lt;/strong&gt;: In models that utilize subword tokenization (like BERT), these masks help identify which parts of the input correspond to actual subwords and which are merely padding or irrelevant. This ensures that the model focuses on meaningful linguistic units.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Future Masks&lt;/strong&gt;: In autoregressive models like GPT, future masks prevent the model from attending to future tokens in the sequence during training. This ensures that predictions for the next token are based solely on past tokens, maintaining the causal nature of the model.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Token Type IDs&lt;/strong&gt;: While not a mask in the strict sense, token type IDs indicate the type of token in a sequence. They can be useful for differentiating between multiple sentences or parts of text in tasks that require understanding of context. This is sometimes used interchangeably with segment mask ids, I realized this one when working on with a BERT question-answering model.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Closing Recap
&lt;/h3&gt;

&lt;p&gt;In summary, attention masks are a crucial component of transformer models, enabling them to focus on relevant information while filtering out distractions. Just as our brains prioritize significant data amidst a flood of sensory input, attention masks guide models to pay attention to important tokens and ignore irrelevant ones.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Information Filtering&lt;/strong&gt;: Just like you filter out background noise when having a conversation, attention masks help models zero in on relevant input, ensuring accurate processing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Practical Applications&lt;/strong&gt;: The impact of attention masks is clear in real-world scenarios, such as voice-controlled assistants, where the ability to focus on user commands amidst background chatter is vital for delivering a seamless user experience.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Integration with Other Masks&lt;/strong&gt;: Attention masks work in harmony with other types of masks, such as padding masks, segment masks, and future masks, all of which contribute to the overall effectiveness of transformer architectures.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;By understanding how attention masks function, we can appreciate the sophistication behind models like GPT and BERT, which mimic human cognitive abilities to process and prioritize information. As the field of deep learning continues to evolve, mastering these concepts will empower developers and researchers to build more efficient and accurate AI systems.&lt;/p&gt;

&lt;p&gt;🙆🏾‍♀️ Is it finished already ? I still wanted to know some stuffs and ask questions 🙁&lt;/p&gt;

&lt;p&gt;🙋🏾‍♂️ Don’t bother, ask your concerns in the comment section or even DM, I’ll do my best to answer&lt;/p&gt;

&lt;h3&gt;
  
  
  Further Reading
&lt;/h3&gt;

&lt;p&gt;If you’re interested in exploring more about attention masks and transformer models, consider the following resources:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;“Attention is All You Need” Paper&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;The seminal paper by Vaswani et al. that introduced the transformer architecture. It provides a deep dive into the mechanism of attention and its applications in natural language processing.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://arxiv.org/abs/1706.03762" rel="noopener noreferrer"&gt;Read the paper here&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Illustrated Transformer&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;A visually engaging explanation of how transformers work, including attention mechanisms, by Jay Alammar. This is a fantastic resource for beginners looking to grasp the foundational concepts.&lt;/li&gt;
&lt;li&gt;Check it out here.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;The original BERT paper by Devlin et al. explains how attention masks are utilized in the BERT model and their role in pre-training and fine-tuning.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://arxiv.org/abs/1810.04805" rel="noopener noreferrer"&gt;Read the paper here&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A Beginner’s Guide to Understanding Transformers in NLP&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;An accessible article that breaks down transformer architecture and its components, including attention masks, in a clear and concise manner.&lt;/li&gt;
&lt;li&gt;Explore the guide here.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Understanding the Attention Mechanism in Transformers&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;A detailed blog post that delves into the different types of attention mechanisms used in transformers, providing examples and practical insights.&lt;/li&gt;
&lt;li&gt;Read more here.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These resources will help you deepen your understanding of attention masks and transformer architectures, enhancing your knowledge and skills in deep learning and natural language processing.&lt;/p&gt;

&lt;h3&gt;
  
  
  About Me
&lt;/h3&gt;

&lt;p&gt;Hi there! I'm Juvet Manga, a young passionate machine learning engineer specializing in developing cutting-edge AI models for mobile applications. With a focus on deep learning and natural language processing, I strive to bridge the gap between complex technology and everyday understanding.&lt;/p&gt;

&lt;p&gt;Currently, I’m working on an exciting project as a member of the startup Mapossa involving transformer models. My goal is to make AI accessible and comprehensible for everyone, whether you're a seasoned developer, a curious business exec or just starting your journey in tech.&lt;/p&gt;

&lt;p&gt;In addition to my technical work, I love sharing knowledge through writing and presentations, aiming to simplify advanced concepts for a broader audience. When I'm not coding, you can find me playing games (Legend of Zelda is my favorite😍) or exploring the latest AI research. Let’s connect and explore the fascinating world of AI together !&lt;br&gt;
-&amp;gt; LinkedIn: Juvet Manga&lt;br&gt;
-&amp;gt; X: juvet_manga&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>ai</category>
      <category>deeplearning</category>
      <category>learning</category>
    </item>
    <item>
      <title>Text Classification vs. Token Classification in NLP: Key Differences, Use Cases, and Performance Optimization</title>
      <dc:creator>juvet manga</dc:creator>
      <pubDate>Sun, 13 Oct 2024 07:38:28 +0000</pubDate>
      <link>https://dev.to/juvet_manga/text-classification-vs-token-classification-in-nlp-key-differences-use-cases-and-performance-optimization-70n</link>
      <guid>https://dev.to/juvet_manga/text-classification-vs-token-classification-in-nlp-key-differences-use-cases-and-performance-optimization-70n</guid>
      <description>&lt;p&gt;With the explosion of &lt;strong&gt;Large Language Models (LLMs)&lt;/strong&gt; like ChatGPT, Gemini, and Claude AI, Natural Language Processing (NLP) has permeated virtually every field. But when building AI models for real-world applications, we often face critical decisions about which NLP tasks best suit our goals. Among these, &lt;strong&gt;text classification&lt;/strong&gt; and &lt;strong&gt;token classification&lt;/strong&gt; stand out as essential tools in the machine learning toolkit, but &lt;strong&gt;choosing the right one&lt;/strong&gt; can dramatically impact model performance and practicality.&lt;/p&gt;

&lt;p&gt;While at first glance they may seem similar, these two tasks present &lt;strong&gt;very different technical challenges&lt;/strong&gt; and serve distinct purposes. In this article, we’ll explore their &lt;strong&gt;key differences&lt;/strong&gt;, when to use each, and the technical considerations that can make or break your model in production.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Text Classification: The Straightforward Class Labeling Task&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Text classification involves assigning an overall label to a chunk of text, whether it’s a sentence, paragraph, or document. For many, this task is the first step into NLP and one of the more straightforward implementations in machine learning.&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%2Fd65yfw8xufgwqianc9mj.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%2Fd65yfw8xufgwqianc9mj.png" alt="Text classification spam classifier example" width="800" height="399"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There exist 2 types of text classification &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Multi-class text classification&lt;/strong&gt;: Which assigns a unique category to a piece of text. An example is a spam detector model, &lt;em&gt;a message can either be a spam or not a spam but not both at the same time&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-label text classification&lt;/strong&gt;: Which makes it possible to overlap categories for a specific piece of text. An example of multi-label text classification is a movie genre classifier. A single movie can belong to multiple genres simultaneously, such as "Action", "Sci-Fi", and "Thriller"&lt;em&gt;. For instance, the movie "The Matrix" could be classified under all three of these categories at once, demonstrating how categories can overlap in multi-label classification&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, text classification can become deceptively complex as you scale your models or expand to domain-specific tasks. Let’s take &lt;strong&gt;sentiment analysis&lt;/strong&gt; as an example. While basic models can perform sentiment analysis with high accuracy, challenges arise when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The text contains &lt;strong&gt;ambiguity or sarcasm&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;You need the model to handle &lt;strong&gt;multilingual data&lt;/strong&gt; or domain-specific jargon.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;An experienced developer or data scientist understands that &lt;strong&gt;building a robust text classification model&lt;/strong&gt; isn’t just about using off-the-shelf architectures. It’s about understanding the &lt;strong&gt;trade-offs in choosing architectures&lt;/strong&gt; like logistic regression, LSTMs, or transformers (like BERT), and optimizing for &lt;strong&gt;speed and accuracy&lt;/strong&gt; depending on the use case.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Example:&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Text: "Your service was amazing!"
Model output: Positive sentiment
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But what about more complex sentences with multiple meanings, or long-form text where sentiment may shift midway through? This is where text classification can hit its limitations. &lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Token Classification: Contextual Labeling at the Token Level&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Token classification&lt;/strong&gt;, on the other hand is actually a specialized variation of text classification . It requires labeling each token (word or sub-word) in a sentence, making it more intricate. &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%2Fejtfwvflayjeegig89i5.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%2Fejtfwvflayjeegig89i5.png" alt="Token classification - Named Entity Recognition example" width="703" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is essential for tasks like &lt;strong&gt;Named Entity Recognition (NER)&lt;/strong&gt;, &lt;strong&gt;part-of-speech tagging&lt;/strong&gt;, or even &lt;strong&gt;question-answering&lt;/strong&gt; tasks, where the model needs to &lt;strong&gt;understand context at a granular level&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Unlike text classification, where you only care about the overall sentiment or category of the text, token classification requires the model to consider the &lt;strong&gt;relationships between words&lt;/strong&gt; and the &lt;strong&gt;semantic dependencies&lt;/strong&gt; across the entire input.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Example:&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Sentence: "Elon Musk founded SpaceX."
Model output: 
- [Elon Musk]: PERSON
- [SpaceX]: ORGANIZATION
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For the model to be able to identify SpaceX as an organization, it needs to understand how it relates to the rest of the words in the sentence and this is where the transformer architecture excels (but this concept is for another day).&lt;/p&gt;

&lt;p&gt;Token classification tasks become particularly challenging when dealing with &lt;strong&gt;domain-specific entities&lt;/strong&gt; (legal, medical), or when attempting to optimize for both &lt;strong&gt;speed and accuracy&lt;/strong&gt; in production environments.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;The Challenges: Data Labeling, Model Complexity, and Performance Trade-offs&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;For text classification, &lt;strong&gt;data labeling&lt;/strong&gt; is often more straightforward because you’re working at the document or sentence level. But in token classification, data labeling is a far more complex and time-consuming process. Every token in your dataset needs to be carefully labeled, which can quickly escalate the cost and effort involved in preparing your dataset.&lt;/p&gt;

&lt;p&gt;Additionally, from an architectural standpoint, token classification models are typically more complex. Transformers like BERT have become the go-to architectures for these tasks due to their ability to handle &lt;strong&gt;contextual relationships&lt;/strong&gt;, but this comes with &lt;strong&gt;trade-offs&lt;/strong&gt; in terms of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Inference time&lt;/strong&gt; (especially in real-time applications).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Model size&lt;/strong&gt; (which can be prohibitive in low-resource environments like mobile).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;When to Choose One Over the Other&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;In reality these tasks are not exactly substitutes, each one solves a very specific problem. Anyway here is what to remember when going for one of these models&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Text classification&lt;/strong&gt; is ideal when you’re analyzing an entire body of text and care about its overall label. Think about tasks like &lt;strong&gt;document classification&lt;/strong&gt; (e.g., spam detection or sentiment analysis).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Token classification&lt;/strong&gt; should be your choice when you need a more &lt;strong&gt;granular understanding&lt;/strong&gt; of the text, such as in NER, &lt;strong&gt;information extraction&lt;/strong&gt;, or &lt;strong&gt;question-answering&lt;/strong&gt; systems.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Performance Considerations: Scaling and Optimization&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;When moving models into production, experienced developers will encounter performance bottlenecks, especially with token classification models. For example, &lt;strong&gt;token classification&lt;/strong&gt; tasks often require &lt;strong&gt;significant computational resources&lt;/strong&gt;, making them slower in inference compared to text classification tasks.&lt;/p&gt;

&lt;p&gt;In &lt;strong&gt;low-latency environments&lt;/strong&gt;, where speed is crucial (e.g., mobile applications), you might need to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Quantize your models&lt;/strong&gt; (especially BERT-based ones) for faster inference.&lt;/li&gt;
&lt;li&gt;Employ &lt;strong&gt;model distillation&lt;/strong&gt; to shrink large models without sacrificing too much accuracy.&lt;/li&gt;
&lt;li&gt;Consider &lt;strong&gt;hybrid models&lt;/strong&gt; that combine the best aspects of both tasks.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Conclusion: Mastering the Right Tool for the Job&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Understanding the key differences between text classification and token classification helps you choose the right approach for your project. Whether you're building a &lt;strong&gt;sentiment analysis model&lt;/strong&gt; to understand customer feedback or implementing &lt;strong&gt;NER&lt;/strong&gt; for contract analysis, your task requires a clear understanding of the technical and architectural trade-offs. By carefully selecting the appropriate model, optimizing for performance, and keeping your end-use case in mind, you can significantly improve the effectiveness and efficiency of your NLP projects.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Final Thought&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;As machine learning advances, the boundary between text and token classification may continue to blur, but understanding these foundational differences will keep you ahead of the curve—whether you’re optimizing for speed, scalability, or accuracy in real-world applications.&lt;/p&gt;




&lt;p&gt;If you found this helpful please let me know in the comments or by leaving a reaction, that motivates me really much to continue.&lt;/p&gt;

&lt;p&gt;You can find me on LinkedIn if you want to connect or to collaborate: &lt;a href="https://www.linkedin.com/in/juvet-manga" rel="noopener noreferrer"&gt;Here's my profile&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>machinelearning</category>
    </item>
  </channel>
</rss>
