Source Maps, Chunk Citations, And Citation Validation

guide2026-06-0211 min read

Treat citations as checked data, not as decorative links appended after an LLM answer.

citationsragsearchlangflow

Summary

A Perplexity-like answer is only trustworthy when every visible citation maps back to evidence the system actually opened, cleaned, chunked, and sent to the model. The source map is the contract between retrieval and writing; chunk citations are the model-facing handles; the validator is the gate that catches missing, invalid, weak, or invented references. This note focuses only on citation integrity. The broader search pipeline is covered in Recreate Perplexity Search With LangFlow, and the search-versus-crawler boundary is covered in Crawler Reads URLs, Search Finds URLs.

What This Solves

Many RAG and web-search agents look cited but are not actually grounded. Common weak patterns include:
  • The answer cites raw URLs that were never opened.
  • The model cites search snippets instead of page content.
  • A citation points to a source, but the source does not support the nearby claim.
  • The final answer has a list of links at the bottom, but individual claims are untraceable.
  • A model invents citation IDs such as [9] or [3.4] because the prompt asked for citations without giving it a strict source map.
The fix is to make citations a data pipeline:
opened sources
-> source map
-> evidence chunks
-> grounded prompt
-> answer with chunk citations
-> citation parser
-> citation validator
-> optional repair pass
-> final response
The source map is the source of truth. The final answer is allowed to cite only IDs that exist in that map.

Who This Is For

This is for builders of Perplexity-like search, Deep Research, RAG, or LangFlow systems who already have search and page-reading working, but now need citation quality to become inspectable. The reader should already understand:
  • Search providers find candidate URLs.
  • Crawlers or readers open URLs and extract content.
  • Rerankers choose which evidence reaches the model.
  • LLMs should answer from labeled context, not from memory.

Prerequisites

  • A search or retrieval flow that returns candidate URLs or documents.
  • A reader or crawler that returns clean text and metadata.
  • A chunk builder that can split source content into evidence units.
  • A final answer model that can follow citation instructions.
  • A formatter or custom component that can parse and validate the answer.
Never publish real source URLs from private work, API keys, LangFlow flow IDs, project IDs, or internal service domains. Use https://docs.example.com, $FLOW_ID, and $LANGFLOW_API_KEY in public examples.

The Workflow

1

Build a source map before generating the answer

A source map should be created only from sources the system actually opened or retrieved. Search results that were never opened can stay in debug metadata, but they should not become citeable evidence.A minimal source map looks like this:
{
  "sources": [
    {
      "source_id": 1,
      "canonical_url": "https://docs.example.com/search",
      "title": "Example Search Documentation",
      "provider": "web",
      "retrieved_at": "2026-06-02T10:00:00Z",
      "opened": true,
      "content_type": "text/html",
      "reader_status": "ok"
    }
  ]
}
The source_id is not a display detail. It is the stable key that downstream chunks and citations depend on.
2

Convert each source into citeable chunks

A source-level citation such as [1] is usually too broad. Use chunk-level citation IDs when the answer needs claim-level support.
{
  "source_id": 1,
  "chunk_id": "1.2",
  "title": "Example Search Documentation",
  "url": "https://docs.example.com/search",
  "section": "Ranking",
  "text": "The ranking endpoint scores documents by semantic similarity and freshness.",
  "char_start": 842,
  "char_end": 921,
  "token_estimate": 15
}
The chunk ID format can be simple: source_id.local_chunk_index. The important part is that IDs are stable inside one answer run and unambiguous inside the prompt.
3

Send the model labeled evidence instead of raw pages

The prompt should contain only selected chunks and clear instructions about citation syntax.
Answer the user using only the evidence below.
Cite every factual claim with chunk IDs in square brackets, such as [1.2].
If the evidence is insufficient, say so.
Do not cite URLs directly.
Do not cite IDs that are not listed below.

Source [1]: Example Search Documentation
URL: https://docs.example.com/search

Chunk [1.1]
The search API returns candidate URLs and snippets.

Chunk [1.2]
The ranking endpoint scores documents by semantic similarity and freshness.
The model should not need to invent citations because the valid citation handles are already present.
4

Parse citations from the final answer

After generation, extract chunk citations and raw URLs before returning the response to the user.
{
  "answer": "The search layer should find candidates, while ranking selects the strongest evidence [1.1][1.2].",
  "detected_chunk_citations": ["1.1", "1.2"],
  "detected_source_citations": [],
  "detected_urls": [],
  "citation_spans": [
    {
      "citation": "1.1",
      "start": 83,
      "end": 88
    }
  ]
}
Keep parser output separate from validator output. The parser says what the answer contains; the validator says whether it is acceptable.
5

Validate citation existence

The first validator pass is mechanical. Every cited ID must exist in the source map or chunk map.
{
  "valid_citations": ["1.1", "1.2"],
  "invalid_citations": [],
  "uncited_sources": [],
  "warnings": []
}
If the answer cites [9.4] and the chunk map contains only [1.1], [1.2], and [2.1], the answer should not pass silently.
6

Check whether citations are close to claims

A simple MVP can require at least one citation per paragraph or bullet. A stronger system should split the answer into claims and check each claim separately.Claim-level validation shape:
{
  "claims": [
    {
      "claim": "The ranking endpoint scores documents by semantic similarity and freshness.",
      "citations": ["1.2"],
      "status": "supported",
      "reason": "The cited chunk states the same ranking criteria."
    }
  ]
}
The validator does not need to prove truth in an absolute sense. It needs to prove that the answer is grounded in the retrieved evidence.
7

Repair only the answer, not the evidence

If citation validation fails, run a repair pass with the original answer, validation errors, and the same source chunks.
Revise the answer so every factual claim cites one of the valid chunk IDs.
Remove claims that are not supported by the provided chunks.
Do not add new sources.
Do not cite URLs directly.
The repair pass should not search again unless the orchestrator explicitly decides that evidence is insufficient.

Source Map Schema

A practical source map can stay small, but it should preserve enough state to debug bad answers later.
{
  "run_id": "example-run-001",
  "query": "Compare search providers and crawlers for a research agent",
  "sources": [
    {
      "source_id": 1,
      "title": "Example Search Documentation",
      "canonical_url": "https://docs.example.com/search",
      "original_url": "https://docs.example.com/search?ref=result",
      "provider": "web",
      "search_rank": 1,
      "reader_status": "ok",
      "content_type": "text/html",
      "retrieved_at": "2026-06-02T10:00:00Z"
    }
  ],
  "chunks": [
    {
      "chunk_id": "1.1",
      "source_id": 1,
      "section": "Overview",
      "text": "The search API returns candidate URLs and snippets.",
      "token_estimate": 11
    }
  ]
}
Useful fields:
FieldWhy It Matters
source_idStable source key for the run
canonical_urlDeduplicates URL variants
reader_statusPrevents failed reads from becoming citeable
retrieved_atHelps evaluate freshness
chunk_idGives the model a precise citation handle
sectionMakes debugging easier when a citation is weak
textStores the evidence that should support the answer

Validator Rules

Use a layered validator instead of one vague “citation check.”
RuleFailure ExampleResponse
Citation existsAnswer cites [7.2], but chunk map has no 7.2Mark invalid and repair
Source was openedAnswer cites a search result that was never readRemove citation or open source
No raw URL citationsAnswer cites https://example.com/page directlyReplace with chunk citation
Claim has nearby citationParagraph contains factual claims but no citationRepair or warn
Citation supports claimCited chunk is about pricing, claim is about securityMark weak support
No unsupported final sourcesBibliography includes unused or unopened URLsRemove from final response
Start with existence checks and raw URL checks. Add claim-level support checks after the pipeline reliably produces chunk citations.

LangFlow Node Map

In LangFlow, citation integrity is easier to debug when every step is visible:
Crawler / Retriever
-> Content Cleaner
-> Chunk Builder
-> Source Map Builder
-> Prompt Builder
-> LLM Answer
-> Citation Parser
-> Citation Validator
-> Repair Branch
-> JSON Response
The source map builder and citation validator are good candidates for custom components because they are deterministic. The LLM should write and repair prose, but deterministic code should own ID assignment, parsing, and existence checks.

Common Failure Modes

The answer has links but no claim-level citations. This usually means the prompt asked for sources in a loose way. Give the model explicit chunk IDs and require citations near factual claims.
The model cites unknown IDs. The prompt may be too long, the chunk labels may be inconsistent, or the model may be copying examples from instructions. Validate IDs mechanically and run a repair pass.
Citations exist but support the wrong claim. Existence checks are passing, but claim support is weak. Add a claim splitter and a lightweight verifier that compares each claim with the cited chunk text.
The validator rejects everything. The answer format may be too strict for the model. First require one citation per paragraph, then move toward claim-level checks once the model follows the basic syntax.

Final Checklist

  • Only opened or retrieved sources enter the source map.
  • Every source has a stable source_id.
  • Every citeable evidence unit has a stable chunk_id.
  • The answer prompt shows the exact citation IDs the model may use.
  • The model is instructed not to cite raw URLs.
  • The parser extracts chunk citations, source citations, raw URLs, and citation spans.
  • The validator rejects citations that do not exist in the chunk map.
  • The validator reports missing or weak citations instead of hiding them.
  • Repair uses the same evidence and does not invent new sources.
  • Final API output includes answer, sources, detected_chunk_citations, and citation_warnings.

What To Remember

Citations are not a presentation layer. They are a contract between retrieval, evidence selection, answer generation, and validation. If the source map is explicit and the validator is deterministic, a research agent becomes much easier to debug: weak answers can be traced to bad search recall, bad extraction, bad chunking, weak prompts, or unsupported claims.

Metadata

Quick Reference

Typeguide
Statuspublished
Date2026-06-02

Retrieval Tags

citationsragsearchlangflowvalidation
Related
recreate perplexity search with langflowcrawler reads urls search finds urlsdeep research orchestration