How to Implement Citation Functionality in LightRAG to Trace Sources with File Paths
You can trace knowledge sources in LightRAG by passing file_paths during document insertion and setting include_references=True during queries, which returns a mapping of reference_id to file_path for every cited chunk.
LightRAG is an open-source retrieval-augmented generation framework that supports built-in citation tracking. By wiring together the insertion pipeline, reference ID generation, and query response formatting, you can attribute every generated answer to its original source documents.
Pass File Paths During Document Ingestion
To enable citations, supply the file_paths parameter when calling insert (synchronous) or ainsert (asynchronous) in lightrag/lightrag.py. This argument accepts a single string or a list of strings that map to the documents being processed.
# lightrag/lightrag.py – insert signature (lines 1150-1170)
def insert(
self,
input: str | list[str],
split_by_character: str | None = None,
split_by_character_only: bool = False,
ids: str | list[str] | None = None,
file_paths: str | list[str] | None = None, # ← citation source metadata
track_id: str | None = None,
) -> str:
...
The file_paths value is forwarded to the pipeline enqueue step:
# Pipeline enqueue in lightrag/lightrag.py
await self.apipeline_enqueue_documents(input, ids, file_paths, track_id)
During ingestion, LightRAG stores these paths in the document metadata. When chunks are later generated from the documents, each chunk inherits the corresponding file path, creating a permanent link between the chunk content and its source location.
How LightRAG Generates Reference IDs
After chunking, the system builds a deterministic reference list using generate_reference_list_from_chunks in lightrag/utils.py (lines 3242-3289). This function maps each unique file path to a sequential numeric reference_id and annotates every chunk with its corresponding ID.
# lightrag/utils.py – reference list generation
def generate_reference_list_from_chunks(
chunks: list[dict],
) -> tuple[list[dict], list[dict]]:
"""
Generate reference list from chunks, prioritizing by occurrence frequency.
Returns (reference_list, updated_chunks_with_reference_ids)
"""
# 1. Count occurrences of each file_path
# 2. Sort by frequency → first appearance
# 3. Assign sequential IDs (1, 2, …)
# 4. Annotate every chunk with its reference_id
# 5. Return both the list and the enriched chunks
The algorithm prioritizes frequently occurring files by assigning them lower reference IDs, while maintaining deterministic ordering through first-appearance ties. Each chunk dictionary gains a "reference_id" field containing its assigned number, or an empty string if no path was provided.
The generated reference list structure looks like:
[
{"reference_id": "1", "file_path": "/documents/intro.pdf"},
{"reference_id": "2", "file_path": "/papers/2023-study.pdf"}
]
Retrieve Citations During Querying
When querying the knowledge base, set include_references=True to receive citation metadata. The query router in lightrag/api/routers/query_routes.py (lines 4470-4490) handles this flag and enriches the response with the reference list.
# lightrag/api/routers/query_routes.py – reference handling
if request.include_references and request.include_chunk_content:
# Build a map reference_id → list of chunk contents
for chunk in chunks:
ref_id = chunk.get("reference_id", "")
content = chunk.get("content", "")
if ref_id and content:
ref_id_to_content.setdefault(ref_id, []).append(content)
# Enrich each reference with its collected content
for ref in references:
ref_copy = ref.copy()
ref_id = ref.get("reference_id", "")
if ref_id in ref_id_to_content:
ref_copy["content"] = ref_id_to_content[ref_id]
enriched_references.append(ref_copy)
The LLM prompt template in lightrag/prompt.py (line 240) instructs the model to embed reference markers directly in the generated text:
- Track the reference_id of the document chunk which directly support the facts presented in the response.
The final JSON response contains the generated answer alongside the traceable sources:
{
"response": "Neural networks are widely used in modern AI systems [1].",
"references": [
{"reference_id": "1", "file_path": "/documents/intro.pdf"},
{"reference_id": "2", "file_path": "/papers/2023-study.pdf", "content": ["..."]}
]
}
Complete Implementation Example
Below is a runnable script demonstrating the full citation workflow from document insertion to rendered bibliography.
# example_citation.py
from lightrag.lightrag import LightRAG
# Initialize LightRAG instance
rag = LightRAG()
# Insert documents with explicit file paths
doc1 = "Artificial intelligence (AI) enables machines to mimic human cognition."
doc2 = "Deep learning is a subset of machine learning that uses neural networks."
track_id = rag.insert(
input=[doc1, doc2],
file_paths=["/docs/ai_overview.pdf", "/docs/deep_learning.pdf"],
)
print(f"Insert tracking ID: {track_id}")
# Query with citation support enabled
result = rag.query(
query="What is the relationship between AI and deep learning?",
include_references=True,
include_chunk_content=False,
)
# Render answer with inline citations
answer = result["response"]
refs = result.get("references", [])
# Build reference map for substitution
footnote_map = {
ref["reference_id"]: ref["file_path"]
for ref in refs
if ref.get("reference_id")
}
# Replace [ref_id] markers with superscript-style citations
for ref_id, path in footnote_map.items():
answer = answer.replace(f"[{ref_id}]", f"^{ref_id}")
print("\n=== Answer ===")
print(answer)
print("\n=== Bibliography ===")
for ref_id, path in sorted(footnote_map.items()):
print(f"[{ref_id}] {path}")
Expected output:
=== Answer ===
Artificial intelligence (AI) is the broader field that encompasses deep learning^2, which is a specialized technique^1.
=== Bibliography ===
[1] /docs/ai_overview.pdf
[2] /docs/deep_learning.pdf
The LLM inserts [reference_id] markers based on the prompt instructions, which your application can replace with formatted citations and map to the full bibliography entries provided in the references array.
Summary
- Supply
file_pathswhen callinginsertorainsertinlightrag/lightrag.pyto attach source metadata to documents. - Reference generation occurs via
generate_reference_list_from_chunksinlightrag/utils.py, which creates deterministic numeric IDs and annotates chunks. - Enable citations by setting
include_references=Trueduring queries, handled inlightrag/api/routers/query_routes.py, to receive a mappable list of sources. - Prompt engineering in
lightrag/prompt.pyensures the LLM embeds reference IDs in generated text for easy post-processing.
Frequently Asked Questions
How do I customize the citation format (e.g., APA style)?
Modify the prompt template in lightrag/prompt.py to instruct the LLM to emit citations in your desired format, or post-process the references array to reformat the bibliography entries before displaying them to users. The system stores raw file paths, giving you flexibility to transform them into any citation style.
Can I limit the number of citations returned in a query?
Yes. The reference list builder in lightrag/utils.py orders citations by frequency of occurrence. You can slice the resulting references array client-side (e.g., references[:5]) to limit output, or add a max_references parameter to the query logic in query_routes.py to enforce server-side limits.
What happens if I don't provide file_paths during insertion?
If file_paths is omitted or set to None, the chunks will have empty reference_id fields. The generate_reference_list_from_chunks function handles this by assigning empty strings, and the query pipeline will return an empty references array or only include chunks that have valid source paths.
How do I retrieve the actual text content of cited chunks?
Set include_chunk_content=True when calling the query method. According to the implementation in lightrag/api/routers/query_routes.py (lines 4470-4490), this attaches a "content" array to each reference object in the response, containing the raw text segments that contributed to the answer.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →