Crawler Reads URLs, Search Finds URLs
guide2026-06-029 min read
Keep search, crawling, extraction, ranking, and citations as separate responsibilities so a research agent stays debuggable.
searchcrawlerragcitations
Summary
The most useful rule for building Perplexity-like or Deep Research-style systems is simple: search finds candidate URLs, crawlers read URLs, rerankers choose evidence, and citation builders preserve traceability. Mixing these responsibilities makes the system hard to debug and weakens answer quality. This note explains the boundary between SearXNG-style search, Firecrawl-style extraction, Exa-style semantic discovery, Onyx-style crawling, and LangFlow orchestration.What This Solves
When building web research flows, it is tempting to call everything “web search.” That creates confused systems:- A crawler is asked to discover pages even though it only knows how to read pages.
- A search provider is treated as evidence even though it only returns snippets.
- An LLM is asked to cite sources it never actually opened.
- Reranking happens after the answer instead of before evidence selection.
- Failed page reads silently become empty context.
The boundary is not academic. It directly controls whether a research agent can explain why it trusted a source and where an answer came from.
Who This Is For
This is for anyone building search, RAG, Deep Research, or Perplexity-like flows in LangFlow. It assumes you already have a search provider or crawler and want the pipeline to become reliable enough for cited answers. It is also useful when choosing between SearXNG, Firecrawl, Exa, Onyx-style crawler logic, Playwright, or a custom reader.Prerequisites
- A LangFlow or similar orchestration layer.
- At least one search provider.
- At least one content reader or crawler.
- A place to store source metadata and chunks.
- An LLM that answers from labeled context.
- Optional reranker or embedding model.
The Workflow
Make search responsible only for discovery
A search provider answers this question:The normalized output should look like:Search snippets are not enough for final citations. They are hints for which pages to open.
Apply filters before opening pages
Domain allowlists, denylists, recency filters, language filters, and location filters should shape the candidate set before crawler work starts.Example filter object:This prevents the crawler from spending time on pages the system already knows it should not trust.
Use reranking before crawling deeply
Search rank is useful but not final. Before opening many pages, deduplicate and score candidate URLs.A simple first-pass scoring model:Open a small diverse set of URLs instead of every result.
Make the crawler responsible for reading URLs
A crawler answers this question:A useful reader output:If a page fails, preserve the failure reason. Do not feed empty or challenge-page text into the LLM.
Handle HTML, PDF, and JavaScript pages separately
Different page types need different readers:
- HTML can usually use HTTP fetch plus cleanup.
- PDF needs PDF text extraction and metadata handling.
- JavaScript-heavy pages may need Playwright fallback.
- Bot-challenge pages should usually be marked as failed, not treated as evidence.
Convert content into source chunks
The answer model should not receive an unstructured blob of pages. Convert content into chunks with source IDs:Stable chunk IDs are the bridge between evidence and citations.
Make citations a validator, not decoration
Citations should be checked after generation. The formatter should detect:
- Known chunk citations, such as
[1.1]. - Unknown citations, such as
[9.4]when no source 9 exists. - Raw URLs that were never opened.
- Claims that have no nearby citation.
Tool Roles
| Tool or Layer | Best Use | Do Not Use It For |
|---|---|---|
| SearXNG-style metasearch | Open search recall and candidate URLs | Deep page extraction or final evidence |
| Brave / Serper / Google PSE | Search recall with provider ranking | Claim-level citation support |
| Exa-style semantic search | Semantic discovery and content retrieval | Full replacement for all crawling needs |
| Firecrawl-style extraction | LLM-ready page reading and crawl jobs | Search ranking unless paired with discovery |
| Onyx-style crawler | Controlled URL reading with safety and fallback | Discovering the web from scratch |
| Playwright | JavaScript rendering fallback | Bypassing every bot challenge |
| Reranker | Evidence selection before answer generation | Fixing unsupported final answers after the fact |
| Citation validator | Checking source traceability | Inventing citations |
LangFlow Node Map
In LangFlow, keep the pipeline visible:Decision Rules
Use these rules when designing or debugging the pipeline:- If the problem is “no good sources found,” improve search or filters.
- If the problem is “source pages are empty,” improve crawler or fallback handling.
- If the problem is “answer uses weak sources,” improve reranking.
- If the problem is “answer has no citations,” improve prompt and formatter.
- If the problem is “citations point to nonexistent sources,” improve validator.
- If the problem is “system is too slow,” reduce URLs opened before reducing answer quality.
Common Failure Modes
Final Checklist
- Search provider returns candidate URLs with title, URL, snippet, provider, and rank.
- Domain and recency filters run before crawling.
- URL deduplication happens before page reading.
- Reranker selects a small, diverse set of URLs.
- Crawler returns
scrape_successfulandfailure_reason. - HTML, PDF, and JavaScript fallback paths are handled separately.
- Source chunks have stable IDs.
- Final answer cites known chunks.
- Citation formatter reports invalid citations.
- Failed pages are visible in diagnostics.
What To Remember
The durable rule is:Metadata
Quick Reference
Typeguide
Statuspublished
Date2026-06-02
Retrieval Tags
searchcrawlerragcitationslangflow
Related
Recreate Perplexity Search With LangFlowDeep Research Is An Orchestration LoopLangFlow Debugging Playbook