Your first RAG app in five lines

LlamaIndex · Essentials · 10 min

Seeing the whole pipeline work end to end first makes every later component easier to place.

The smallest useful LlamaIndex program answers questions about a folder of files:

documents = SimpleDirectoryReader("data").load_data()
index = VectorStoreIndex.from_documents(documents)
query_engine = index.as_query_engine()
response = query_engine.query("What is our refund policy?")
print(response)

What happens behind these lines:

1. SimpleDirectoryReader reads every supported file in data/ (text, Markdown, PDF, Word and more) into Document objects. 2. VectorStoreIndex.from_documents splits the documents into chunks, sends each chunk to an embedding model and keeps the vectors in memory. 3. as_query_engine() builds an object that, for each question, embeds the question, finds the most similar chunks (2 by default), puts them into a prompt, and asks the LLM to answer from them. 4. query returns a Response. Printing it shows the answer; response.source_nodes lists the chunks that were used, with similarity scores.

By default LlamaIndex uses OpenAI for both the LLM and the embeddings, so set the OPENAI_API_KEY environment variable first. The next lesson shows how to choose other models, including local ones.

Always look at source_nodes when an answer seems wrong. If the right chunk isn't there, the problem is retrieval, not the LLM, and no prompt change will fix it.

Example

# pip install llama-index ; export OPENAI_API_KEY=sk-...
from llama_index.core import SimpleDirectoryReader, VectorStoreIndex

documents = SimpleDirectoryReader("data").load_data()   # every file in ./data
index = VectorStoreIndex.from_documents(documents)     # chunk + embed + store
query_engine = index.as_query_engine()

response = query_engine.query("How long do refunds take?")
print(response)                    # Refunds are processed within 5 business days.

for src in response.source_nodes:  # the chunks the answer was based on
    print(round(src.score, 2), src.node.metadata["file_name"])
# 0.83 refunds.md
# 0.71 faq.md

Remember

  • Reader, then VectorStoreIndex.from_documents, then as_query_engine().query()
  • The default LLM and embeddings are OpenAI's (needs OPENAI_API_KEY)
  • response.source_nodes shows which chunks the answer used

Watch out for

  • Judging a RAG app only by its answers without checking source_nodes, so retrieval problems look like model problems.

Check yourself

  1. A query answer is wrong and source_nodes shows unrelated chunks. Where is the problem most likely?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: developers.llamaindex.ai/python/framework/getting_started/starter_example/