惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

L
LangChain Blog
C
Check Point Blog
博客园 - Franky
V
Visual Studio Blog
云风的 BLOG
云风的 BLOG
aimingoo的专栏
aimingoo的专栏
Microsoft Security Blog
Microsoft Security Blog
V2EX - 技术
V2EX - 技术
AI
AI
Hacker News - Newest:
Hacker News - Newest: "LLM"
Jina AI
Jina AI
S
Security @ Cisco Blogs
Security Archives - TechRepublic
Security Archives - TechRepublic
H
Hacker News: Front Page
H
Hackread – Cybersecurity News, Data Breaches, AI and More
O
OpenAI News
Attack and Defense Labs
Attack and Defense Labs
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
爱范儿
爱范儿
H
Heimdal Security Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
G
Google Developers Blog
G
GRAHAM CLULEY
V
V2EX
The Register - Security
The Register - Security
人人都是产品经理
人人都是产品经理
B
Blog RSS Feed
Schneier on Security
Schneier on Security
M
MIT News - Artificial intelligence
Stack Overflow Blog
Stack Overflow Blog
Help Net Security
Help Net Security
大猫的无限游戏
大猫的无限游戏
C
CERT Recently Published Vulnerability Notes
The GitHub Blog
The GitHub Blog
V
Vulnerabilities – Threatpost
The Last Watchdog
The Last Watchdog
J
Java Code Geeks
S
Secure Thoughts
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
量子位
NISL@THU
NISL@THU
K
Kaspersky official blog
Engineering at Meta
Engineering at Meta
T
Threatpost
Recent Commits to openclaw:main
Recent Commits to openclaw:main
宝玉的分享
宝玉的分享
Security Latest
Security Latest
T
The Exploit Database - CXSecurity.com
博客园_首页
A
Arctic Wolf

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python) The Hidden Cost of AI Systems Nobody Talks About. undefined vs undeclared, and how typeof behaves Switching from file-based jobs to NATS/Kafka in Rust without changing code io_uring Adventures: Rust Servers That Love Syscalls Why Agentic AI is Killing the Traditional Database The POUR principles of web accessibility for developers and designers Quantum Neural Network 3D — A Deep Dive into Interactive WebGL Visualization How To Install Caveman In Codex On macOS And Windows Automation Pipeline Reliability: Why Your Workflow Breaks When Nobody Is Watching I Built an 'Open World' AI Coding Agent — It Works From ANY Folder From Freelancing to Product: A Tech Service Company's SaaS Transformation China's AI Giants: Adding Tencent Hunyuan & ByteDance Doubao to AI University (74 Providers) On the Vibe Coders and Their Lies clerk: Auto-Summarize Your Claude Code Sessions AI Weekly — 2026/04/10–04/17 | The Model Lockdown Is Here, but the Toolchain Is the Real Battleground AI 週報 — 2026/04/10–2026/04/17 模型封鎖潮來了,但工具鏈才是真戰場 Maybe this is how Open-Source apps are born... 🚀 Fine-Tune LLMs with LoRA and QLoRA: 2026 Guide tRPC v11 + Next.js App Router: End-to-End Type Safety Without the Boilerplate ShadCN UI in 2026: Why I Stopped Installing Component Libraries and Started Owning My Components SaaS Billing in React Server Components: Stripe + Supabase Without a Single `useEffect` Join our DEV Weekend Challenge — $1,000 in Prizes Across TEN winners! Submissions Due April 20 at 6:59 AM UTC. Implementing FSRS Spaced Repetition in Flutter + Supabase — Adding Memory Science to an AI Learning App "I Texted My Localhost From the Train — Claude Code Fixed the Bug Before I Got Home" I Built a Sales Prep AI and It Went Deeper Than Expected Design to Code #2: One JSON, Eleven Outputs Solving the 100M-Row Problem: A Summary Table Pattern for High-Volume Push Notification Logs Flutter Web With Wasm: What Actually Changes For Developers I Built 50 Royalty-Free Soundtracks for My Side Project in a Weekend Using AI Music Generation The Vibe Coding Security Checklist: 7 Things to Check Before You Ship Stop Letting Googlebot Guess Fix Your React App's SEO Right Desconstruindo o Streaming do LinkedIn: Como Criar um Engine de Extração de Vídeo de Alta Performance com HLS e FFmpeg (EDA Part-1) EDA (Exploratory Data Analysis) Explained With Real Life — Why Looking at Your Data Is the Most Important Step in Machine Learning Brand Relationship Management at Scale: Our 4-Touch Outreach System for 200+ Brands Why String.fromEnvironment() Might Return an Empty String in Dart JGuardrails 1.0.0 — Hardening Java LLM Apps Against Jailbreaks, Toxicity, and Prompt Injection Plan and Schedule a Full Week of Threads Content From One Claude Conversation Coding Cat Oran Ep3, Five Tables Changed Everything Updated: BFF Pattern I'm done watching freelancers get buried by 200 proposals. So I'm building the alternative. This is my first post BFS Algorithm in Java Step by Step Tutorial with Examples Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models How We Measure Content ROI on a Comparison Site: Revenue Attribution Without Perfect Data Introducing Nova AI Ops: The AI-Native Operating System for SRE Teams I built a free desktop video downloader for Windows — Grabbit How Talkie OCR Helps Vision-Impaired & Dyslexic Users Read the World Around Them VRCFaceTracking安装和iPhone面捕配置教程,有bug Even CrowdStrike Can't See Your Agents The Automation Gold Rush: What n8n Workflows and Claude Are Opening Up for Developers Right Now
From "I Understood Nothing" to Building a RAG App
Sabi Mantock · 2026-06-16 · via DEV Community

Yesterday, I took the time to go through 31 pages of my own notes on NLP, notes I had carefully created during an AI engineering course. However, I found that I understood very little of it.

It felt odd and disheartening to have written something down yet not grasp it. I initially thought the issue was with me. But that wasn't the case. The real issue was that simply reading notes does not equate to true learning. My notes were packed with information intended for a version of me that already had some understanding, and you can't develop comprehension just by rereading a summary. So, I decided to change my approach. Instead of reading, I had the concepts explained to me one question at a time, starting from the basics, using only simple examples. No technical terms were permitted until I had proven I could understand them.

By the end of the day, I had reconstructed the four main concepts of practical NLP from the ground up, and I used them to create a functioning app that answers questions based on my own notes. Here's the complete journey, with the same examples that finally helped me understand, along with the code for each step so you can follow along.

Start with the dumbest possible question

Imagine you want a computer to sort emails into "spam" and "not spam." Here's the catch: the computer has never read a word in its life. The only thing it can do, the only thing it has ever been able to do, is math on numbers.

So before it can sort a single email, one problem comes first: the words have to become numbers. That sentence turned out to be the foundation of everything. All of this branch of NLP is just one job: turn text into numbers without losing the meaning that matters.

My first instinct was to turn each letter into a number. It's a reasonable guess, and it's actually how computers store text underneath. But it captures spelling, not meaning. "win" and "bin" look almost identical as numbers, yet mean totally different things. The meaning of an email lives in its words, not its letters.

Bag of Words: count, don't spell

So we work with whole words. Take three emails:

  • "win money now"
  • "money money money"
  • "see you tomorrow"

List every distinct word (that's the vocabulary), give each a column, and for each email count how many times each word appears. "win money now" becomes 1, 1, 1, 0, 0, 0. "money money money" becomes 0, 3, 0, 0, 0, 0. Suddenly every email is a row of pure numbers, and a computer can compare them.

scikit-learn does exactly this in three lines:

from sklearn.feature_extraction.text import CountVectorizer

emails = ["win money now", "money money money", "see you tomorrow"]

vectorizer = CountVectorizer()
X = vectorizer.fit_transform(emails)

print(vectorizer.get_feature_names_out())  # the vocabulary (the columns)
print(X.toarray())                         # each row = one email as word-counts

That's it. That's the intimidating-sounding "Bag of Words." I had read about it and bounced off it; here I did it by hand in two minutes, then in three lines of code.

It's called a bag for a reason, and the reason is also its flaw. Imagine tossing a sentence's words into a paper bag and shaking it. You still know which words are inside and how many, but the order is gone. "win money now" and "now win money" produce the identical row. Usually harmless. But consider "dog bites man" versus "man bites dog": same three words, one is a boring Tuesday and the other is front-page news. To Bag of Words they're identical. That weakness is exactly why fancier methods had to be invented later.

TF-IDF: not all words deserve equal weight

Bag of Words has a second problem: it treats every word as equally important. The word "the" is in nearly every email, so knowing an email contains "the" tells you nothing. Meanwhile a rare word like "viagra" is a screaming signal. Yet Bag of Words counts them the same.

TF-IDF fixes this with two dials multiplied together:

  • TF (term frequency): how often a word appears in this one email. If a message says "money money money money," it's clearly about money. Repetition means importance.
  • IDF (inverse document frequency): how rare the word is across the whole pile, measured by how many separate emails contain it. Common word → tiny score. Rare word → big score. ("Inverse" just means flipped: more documents, smaller score.)

Multiply them, and something beautiful happens. Take "the": it appears a lot (high TF) but it's everywhere (near-zero IDF), so high × almost-zero ≈ zero. The word silences itself. Nobody handed the computer a list of words to ignore. The math removed the filler on its own. Meanwhile "viagra" in a spam email is repeated (high TF) and rare (high IDF), so it lights up bright.

Same API, one word swapped:

from sklearn.feature_extraction.text import TfidfVectorizer

vectorizer = TfidfVectorizer()
X = vectorizer.fit_transform(emails)

print(X.toarray().round(2))  # same shape, but now weighted by rarity

I tested the idea on "win win win money the the" and correctly predicted "win" would score highest, repeated and rare, while "the" collapsed to nothing. The method had taught me to think the way it thinks.

Embeddings: giving words a place on a map

Both methods above share a blindness: to them, "money" and "cash" are as unrelated as "money" and "banana." Each word is just its own separate column, with nothing connecting them. They have no concept that two different words can mean nearly the same thing.

Embeddings fix this with one gorgeous idea: put every word on a map of meaning. Picture a giant map where each word is a dot. We place words that mean similar things near each other, and unrelated words far apart. "cash" sits right next to "money"; "banana" is way over by "apple." A word's coordinates on that map, written as numbers, are its embedding. "king" lands closer to "queen" than to "bicycle," because the map is organized by meaning.

But how does a computer that can't read decide where to put each word? Through the company a word keeps. It reads millions of sentences and notices that "money" and "cash" are both surrounded by the same neighbors: borrow, pay, bank, withdraw. Same company, same neighborhood. "banana" keeps different company (eat, peel, ripe, fruit), so it lands far away. The computer never knows what any word means; it just matches patterns of context. (The real map isn't flat with two directions; it has hundreds, which is why an embedding is a long list of numbers. The idea is identical: close = similar, far = different.)

A pre-trained model hands you those coordinates directly:

from sentence_transformers import SentenceTransformer

model = SentenceTransformer("all-MiniLM-L6-v2")
vecs = model.encode(["money", "cash", "banana"])

print(vecs.shape)  # (3, 384) → three words, each a dot with 384 coordinates

The kicker: it's not only single words. A whole sentence, or a whole note, can become a dot too, and that's the hinge the entire next step swings on.

RAG: I accidentally invented it

Here's where it all paid off. Imagine every note in my wiki is a dot on the meaning map. Then I type a question, and that question becomes a dot on the same map. To find the note that answers it, I just grab the nearest dots.

That's the entire idea behind RAG (Retrieval-Augmented Generation):

  1. Turn the question into a dot (embed it).
  2. Find the nearest note-dots on the map (retrieval).
  3. Hand those notes to a language model and say "answer using only these."
  4. The model writes an answer grounded in my actual notes instead of guessing.

Most people learn RAG by copying a tutorial and have no idea what's happening underneath. I arrived at it by reasoning, which meant I understood every layer before I wrote a line of code.

Synapse: making it real

So I built it, in a Jupyter notebook, and named it Synapse, because a synapse is the connection between two neurons, which is exactly what embeddings do: connect related notes by meaning.

The pipeline is just the four ideas above, in order.

1. Load every note:

from pathlib import Path

WIKI = Path("path/to/my/wiki")
notes = [{"path": str(f), "text": f.read_text(encoding="utf-8")}
         for f in WIKI.rglob("*.md")]

print(f"Loaded {len(notes)} notes")

2. Embed each note into a dot on the map:

from sentence_transformers import SentenceTransformer

model = SentenceTransformer("all-MiniLM-L6-v2")
embeddings = model.encode([n["text"] for n in notes])  # shape (N, 384)

3. Retrieve the nearest notes to a question:

from sklearn.metrics.pairwise import cosine_similarity
import numpy as np

question = "what is the difference between stemming and lemmatization?"
q_emb = model.encode([question])

scores = cosine_similarity(q_emb, embeddings)[0]  # "near = similar", as a number
top = np.argsort(scores)[::-1][:3]                # the 3 closest notes

4. Generate a grounded answer from those notes:

import anthropic

client = anthropic.Anthropic()  # reads ANTHROPIC_API_KEY from your environment

context = "\n\n---\n\n".join(notes[i]["text"] for i in top)
prompt = f"""Answer the question using ONLY the notes below.
If the answer isn't in the notes, say you don't know.

NOTES:
{context}

QUESTION: {question}"""

resp = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=500,
    messages=[{"role": "user", "content": prompt}],
)
print(resp.content[0].text)

That last instruction ("if the answer isn't in the notes, say you don't know") is the anti-hallucination guard. It's the difference between a toy and something you can trust.

I asked it: "What's the difference between stemming and lemmatization?" It pulled up exactly the right notes and wrote an answer that reproduced my own comparison table: the tools, the "studies → studi" example, all of it. Not from the model's training. From my brain, retrieved and read back to me.

What actually made it click

An hour into all this, I'd gone from "I understand nothing" to deriving RAG on my own. The lesson wasn't really about NLP. It was about how to learn:

Reading is not understanding. I'd mistaken having notes for having knowledge. The fix was active discovery: being asked a question and having to reach for the answer, one small step at a time, every abstract idea anchored to something concrete (a paper bag, a map, a spam email). And then building, because nothing reveals what you don't understand faster than making it run.

If you're staring at material that won't stick, try this: stop reading it. Have it asked of you instead. Start from the dumbest possible question and refuse to move on until each piece genuinely makes sense. You can get further in a day than you'd believe.

Next up for Synapse: chunking notes for sharper retrieval, citing its sources, a real frontend, and a local-model version. The journey continues. I'll write that one up too.