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

推荐订阅源

让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
人人都是产品经理
人人都是产品经理
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
T
The Exploit Database - CXSecurity.com
N
News and Events Feed by Topic
Latest news
Latest news
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
C
CXSECURITY Database RSS Feed - CXSecurity.com
IT之家
IT之家
V
V2EX
WordPress大学
WordPress大学
Apple Machine Learning Research
Apple Machine Learning Research
Cisco Talos Blog
Cisco Talos Blog
K
Kaspersky official blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
S
SegmentFault 最新的问题
小众软件
小众软件
A
Arctic Wolf
酷 壳 – CoolShell
酷 壳 – CoolShell
腾讯CDC
宝玉的分享
宝玉的分享
Last Week in AI
Last Week in AI
G
GRAHAM CLULEY
罗磊的独立博客
T
Tor Project blog
C
Cisco Blogs
美团技术团队
博客园 - Franky
月光博客
月光博客
博客园 - 三生石上(FineUI控件)
T
Threat Research - Cisco Blogs
Cyberwarzone
Cyberwarzone
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
有赞技术团队
有赞技术团队
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Security Latest
Security Latest
博客园 - 司徒正美
Hugging Face - Blog
Hugging Face - Blog
Spread Privacy
Spread Privacy
J
Java Code Geeks
C
CERT Recently Published Vulnerability Notes
大猫的无限游戏
大猫的无限游戏
S
Securelist
The Cloudflare Blog
博客园 - 叶小钗
D
Darknet – Hacking Tools, Hacker News & Cyber Security
阮一峰的网络日志
阮一峰的网络日志
雷峰网
雷峰网
Project Zero
Project Zero

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
Reduce LLM Token Waste in RAG with Markdown
AlterLab · 2026-06-17 · via DEV Community

TL;DR

Feeding raw HTML to Large Language Models wastes tokens on markup, scripts, and styling. By rendering dynamic web pages in a headless browser and converting the final DOM to clean Markdown, you reduce token consumption by up to 90% while preserving semantic structure and improving retrieval accuracy in RAG pipelines.

The Problem: LLMs, Context Windows, and the HTML Tax

Building Retrieval-Augmented Generation (RAG) pipelines over web data introduces a specific data engineering problem. The web is built on HTML. Large Language Models operate on tokens.

When you pass raw HTML to an embedding model or an LLM context window, you pay a steep tax. You pay for <div class="mt-4 flex flex-col justify-center">, <script type="application/json">, SVG paths, and inline CSS. These non-semantic tokens dilute the actual content. They increase latency, exhaust context limits, and drive up API costs.

Worse, this noise degrades your embeddings. When an embedding model processes a chunk of text dominated by CSS classes and HTML attributes, the resulting vector represents the markup structure more heavily than the actual information. This leads to poor retrieval performance. When a user queries your RAG system, the vector database returns chunks based on matching HTML boilerplate rather than semantic relevance.

Why Markdown is the Ideal Intermediate Format

Markdown solves the HTML tax problem. It preserves semantic meaning without the syntactic overhead of HTML. It maintains hierarchical structure through headers, relationships through links, and tabular data through Markdown tables.

A standard product page or a long-form article converted from HTML to Markdown often drops from 50,000 tokens to roughly 3,000. This 94% reduction in token count directly translates to lower inference costs and higher context density.

When you feed clean Markdown into a context window, the LLM processes dense, high-signal information. It pays attention to the data you care about.

Consider this raw HTML snippet:

```html title="example.html" {2-3}

Specifications


  • Weight: 2.4 lbs
  • Battery Life: 12 hours



Converted to Markdown, it becomes:


```markdown title="example.md" {1-3}
## Specifications
- Weight: 2.4 lbs
- Battery Life: 12 hours

The Markdown version contains the exact same information but requires a fraction of the tokens. The LLM understands the header and the list items natively.

The Challenge of Modern Web Rendering

Converting static HTML to Markdown is straightforward using libraries like html2text or turndown. The challenge lies in modern web architecture. Most single-page applications (SPAs) ship an empty <div id="root"> and render content client-side via JavaScript.

If you fetch these pages with a standard HTTP client like requests in Python or curl in bash, your Markdown converter will output nothing. You capture the loading state, not the data.

You need a headless browser to execute the JavaScript, wait for the network to idle, and then extract the final computed DOM.

Doing this at scale introduces significant infrastructure overhead. You must manage a fleet of headless Chrome instances. You have to handle memory leaks, process crashes, and concurrent execution limits.

Beyond browser management, you face access barriers. Many web servers employ strict rate limiting and automated traffic detection, even for publicly accessible data. Fetching the fully rendered DOM requires robust proxy rotation and systems capable of sophisticated anti-bot handling. If you fail to solve a CAPTCHA or trigger a firewall block, your RAG pipeline starves for data.

Cleaning the DOM Before Conversion

Before generating the Markdown, it is crucial to sanitize the HTML. Modern web pages contain elements like <nav>, <footer>, <aside>, and hidden modals that contribute no value to the core content.

If you convert the entire page blindly, your Markdown will include navigation links, newsletter signups, and related article previews. This reintroduces noise into your RAG pipeline.

A robust extraction pipeline evaluates DOM nodes based on text density, link-to-text ratios, and semantic HTML5 tags like <main> or <article>. It prunes the DOM tree of boilerplate, ensuring the resulting Markdown represents only the primary article or data payload.

When implementing custom conversion pipelines, you must build this sanitization step yourself using tools like Mozilla's Readability.js. Offloading this eliminates the need to maintain complex DOM pruning rules across diverse web layouts.

Single-Step Markdown Extraction with AlterLab

Instead of building a complex pipeline with Puppeteer, proxy managers, HTML parsing libraries, and Markdown converters, you can request Markdown directly from the AlterLab API.

We built AlterLab to abstract this infrastructure away. Our systems handle the headless browser execution, manage the proxy rotation, sanitize the DOM, and return the data in your requested format.

You pass the target URL to the API. You specify that you want Markdown. AlterLab navigates to the page, waits for JavaScript execution to complete, parses the rendered HTML, strips navigation and footer boilerplate using heuristics, and returns a clean Markdown string.

Here is how to implement this using our Python SDK.

```python title="rag_scraper.py" {4-8}

client = alterlab.Client(api_key=os.getenv("ALTERLAB_API_KEY"))

response = client.scrape(
url="https://example-news-site.com/article",
formats=["markdown"],
wait_for="networkidle"
)

markdown_content = response.markdown
print(markdown_content)

The output is ready to be chunked and embedded




For systems where you prefer standard HTTP requests, the same configuration works via cURL. See the [API reference](https://alterlab.io/docs) for full parameter details.



```bash title="Terminal" {4-4}
curl -X POST https://api.alterlab.io/v1/scrape \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example-news-site.com/article", 
    "formats": ["markdown"], 
    "wait_for": "networkidle"
  }'

The wait_for: "networkidle" parameter ensures the headless browser waits until all client-side rendering completes before extracting the DOM. The formats: ["markdown"] parameter handles the conversion pipeline internally.

Optimizing RAG Ingestion Pipelines with Markdown

Once you have clean Markdown, your chunking strategy improves drastically. Standard text chunking methods split text arbitrarily by character count. This often breaks paragraphs in half or separates a table header from its rows, destroying the context the LLM needs to answer queries.

With Markdown, you chunk by semantic boundaries using headers (#, ##, ###).

Markdown-aware text splitters read these headers to keep related concepts together. When a section exceeds your chunk size limit, the splitter drops down to the next header level.

```python title="chunker.py" {4-10}
from langchain.text_splitter import MarkdownHeaderTextSplitter

headers_to_split_on = [
("#", "Header 1"),
("##", "Header 2"),
("###", "Header 3"),
]

markdown_splitter = MarkdownHeaderTextSplitter(headers_to_split_on=headers_to_split_on)
md_header_splits = markdown_splitter.split_text(markdown_content)

for split in md_header_splits:
print(split.metadata)
print(split.page_content)




This ensures that every chunk sent to your vector database contains complete, logically grouped information. It also preserves the header hierarchy in the metadata, allowing you to filter or weight retrieval results based on section context.

## Handling Tabular Data and Complex Structures

Tables present a notorious challenge for RAG systems. HTML tables (`<table>`, `<tr>`, `<td>`) confuse text embedding models. Flattening a table into plain text removes the row and column relationships, rendering the data incomprehensible.

Markdown tables maintain a rigid, predictable structure.



```markdown title="table.md" {1-4}
| Parameter | Type | Description |
|---|---|---|
| url | string | The target webpage URL |
| formats | array | Requested output formats |

LLMs parse Markdown tables natively. When a user asks a question requiring data aggregation across columns, the LLM correctly interprets the intersections of the Markdown table provided in the context window. Converting HTML directly to Markdown preserves this critical tabular structure without writing custom extraction logic.

Beyond text and tables, web pages contain images and complex nested structures. Raw HTML encodes images with <img> tags, srcset attributes, and lazy-loading wrappers.

When converting to Markdown, the process extracts the primary src and alt text, formatting it as ![alt text](image_url). If your RAG system incorporates multimodal LLMs, you can parse these Markdown image tags to fetch and analyze the visual content. The LLM receives the semantic description via the alt text, maintaining context even if you choose not to download the image.

For nested structures like accordions or tabbed interfaces, headless browser execution is paramount. SPAs often delay rendering the content of an inactive tab until the user clicks it. By using interaction features to simulate user clicks before triggering the Markdown extraction, you ensure all hidden content surfaces in the final DOM. This guarantees your RAG pipeline ingests the complete dataset, rather than missing critical information hidden behind UI components.

Real-world Data Engineering Considerations

Operating a RAG ingestion pipeline requires fault tolerance. When scraping dynamic websites, you must account for network timeouts, changing DOM structures, and temporary IP blocks.

By relying on an API to handle the extraction and conversion, you reduce your surface area for errors. You do not need to debug Puppeteer timeouts or update Chrome versions. Your error handling focuses entirely on your ingestion logic.

Implement exponential backoff for failed requests. Queue URLs for processing rather than executing them synchronously. Monitor the token count of the returned Markdown. If a site undergoes a major redesign, the heuristics stripping boilerplate might fail, resulting in a sudden spike in token count. Set up alerts for unexpected deviations in response size to catch these anomalies early.

Summary

Processing web data for AI requires minimizing noise. Extracting dynamically rendered pages directly as Markdown removes token bloat at the source. It simplifies your ingestion pipeline, lowers LLM API costs, and provides your embedding models with highly structured, high-signal text.

By offloading browser rendering, JavaScript execution, and Markdown conversion to an API, your engineering team can focus on improving embedding models and retrieval strategies rather than managing headless Chromium instances. Build data pipelines that scale reliably by treating web extraction as a solved infrastructure primitive.