Indexes

An index organizes Nodes so queries can fetch them quickly. The workhorse is VectorStoreIndex: each Node has an embedding; queries run similarity search. Other indexes (summary, keyword, tree, property graph) serve other access patterns. Master the vector index first, then extend from the official module guides.

This site’s RAG course covers why you index. This chapter is how LlamaIndex builds, persists, and incrementally inserts.


VectorStoreIndex.from_documents

from llama_index.core import VectorStoreIndex, SimpleDirectoryReader

documents = SimpleDirectoryReader("data").load_data()
index = VectorStoreIndex.from_documents(documents)

Under the hood (overridable via Settings / transformations / storage_context):

  1. Split Documents into Nodes
  2. Embed with Settings.embed_model (starter OpenAI embeddings; historically text-embedding-ada-002)
  3. Write into the StorageContext vector store (in-memory SimpleVectorStore by default)

Pin splitter and LLM (gpt-4o-mini in examples; follow current docs):

from llama_index.core import Settings, VectorStoreIndex
from llama_index.core.node_parser import SentenceSplitter
from llama_index.llms.openai import OpenAI
from llama_index.embeddings.openai import OpenAIEmbedding

Settings.llm = OpenAI(model="gpt-4o-mini")
Settings.embed_model = OpenAIEmbedding(model="text-embedding-3-small")

index = VectorStoreIndex.from_documents(
    documents,
    transformations=[SentenceSplitter(chunk_size=512, chunk_overlap=50)],
    show_progress=True,
)

From existing Nodes: VectorStoreIndex(nodes). Vectors already in an external DB: VectorStoreIndex.from_vector_store(vector_store) (Vector Stores).


Persist to disk (default storage)

An in-memory index dies with the process. Embeddings are slow and costly, so persist:

index.storage_context.persist(persist_dir="storage")

from llama_index.core import StorageContext, load_index_from_storage

storage_context = StorageContext.from_defaults(persist_dir="storage")
index = load_index_from_storage(storage_context)

StorageContext holds docstore / index store / vector store. If you customized embeddings or transformations, restore the same Settings on load.

Incremental insert:

from llama_index.core import Document

index.insert(Document(text="New notice: maintenance next week.", metadata={"source": "notice"}))
index.storage_context.persist(persist_dir="storage")

Other index types (awareness)

TypeRetrieval intuitionConsider when
VectorStoreIndexSemantically similar top-k chunksDefault; most RAG
SummaryIndexSequential / summary pass over nodesWhole-doc summaries more than local Q&A
KeywordTableIndexKeyword → nodesMany proper nouns; weak semantic hits
TreeIndexHierarchical summariesLong docs, coarse-then-fine
PropertyGraphIndexEntity graph + vectorsMulti-hop “who relates to whom”

Do not start by composing five indexes. Stabilize vector search, then add keyword or graph based on evals. Combine at query / retrieval time with a router or fused retriever instead of copying every corpus five ways.


An index is not your system of record

Indexes optimize which context the LLM sees. They do not replace Postgres business tables. Filters, ACLs, and transactions stay in the source system; LlamaIndex picks passages. Simple tenancy: one collection / persist dir per tenant, or tenant_id in metadata plus query-time filters.


FAQ

Double bills from repeating from_documents?
If storage/ exists, load_index_from_storage—do not rebuild every boot.

Quality collapsed after changing the embedding model?
Vectors live in different spaces. Wipe storage and re-index fully.

Stuck while embedding?
Check network and keys; use show_progress=True. Large jobs: ingestion pipeline + batch writes into an external vector DB.


Next steps

评论