# Getting Started

## Installation

=== "pip"

    ```bash
    pip install vector-graph-rag
    ```

=== "uv"

    ```bash
    uv add vector-graph-rag
    ```

=== "With document loaders"

    ```bash
    pip install "vector-graph-rag[loaders]"
    ```

=== "With local embeddings"

    ```bash
    pip install "vector-graph-rag[hf]"
    ```

=== "With all embedding providers"

    ```bash
    pip install "vector-graph-rag[all]"
    ```

=== "With observability"

    ```bash
    pip install "vector-graph-rag[observability]"
    ```

!!! note "Prerequisites"
    - Python 3.9+
    - An OpenAI API key (set `OPENAI_API_KEY` environment variable)

## Quick Start

```python
from vector_graph_rag import VectorGraphRAG

rag = VectorGraphRAG()  # reads OPENAI_API_KEY from environment

rag.rebuild_texts([
    "Albert Einstein developed the theory of relativity.",
    "The theory of relativity revolutionized our understanding of space and time.",
])

result = rag.query("What did Einstein develop?")
print(result.answer)
```

!!! tip "Zero configuration"
    By default, Vector Graph RAG uses Milvus Lite — a local file-based vector database that requires no server setup. Your data is stored in `./vector_graph_rag.db`.

## Configuration

### Basic Configuration

```python
rag = VectorGraphRAG(
    milvus_uri="./my_data.db",                    # local file (Milvus Lite)
    llm_model="gpt-4o",                           # LLM for extraction and reranking
    embedding_provider="openai",                  # embedding provider
    embedding_model="text-embedding-3-large",      # embedding model
)
```

### With Remote Milvus

```python
rag = VectorGraphRAG(
    milvus_uri="http://localhost:19530",
    milvus_db="my_database",           # optional: specify database
    collection_prefix="my_project",    # optional: isolate collections
)
```

### With Zilliz Cloud

```python
rag = VectorGraphRAG(
    milvus_uri="https://in03-xxx.api.gcp-us-west1.zillizcloud.com",
    milvus_token="your-api-key",
)
```

!!! tip "Free tier available"
    [Sign up for Zilliz Cloud](https://cloud.zilliz.com/signup?utm_source=github&utm_medium=referral&utm_campaign=vector-graph-rag-docs) to get a free cluster. Use the cluster endpoint as `milvus_uri` and your API key as `milvus_token`.

### Milvus Deployment Modes

| Mode | `milvus_uri` | `milvus_token` | Best for |
|------|-------------|----------------|----------|
| **Milvus Lite** (default) | `./vector_graph_rag.db` | — | Personal use, dev — zero config |
| **Milvus Server** | `http://localhost:19530` | Optional | Multi-dataset, team environments |
| ⭐ **Zilliz Cloud** | `https://in03-xxx.api.gcp-us-west1.zillizcloud.com` | API key | Production, fully managed |

!!! info "Collection naming"
    With `collection_prefix="my_project"`, collections are named `my_project_vgrag_entities`, `my_project_vgrag_relations`, `my_project_vgrag_passages`.

### Environment Variables

All settings can be configured via environment variables with the `VGRAG_` prefix:

```bash
export OPENAI_API_KEY="sk-..."
export VGRAG_MILVUS_URI="http://localhost:19530"
export VGRAG_LLM_MODEL="gpt-4o"
export VGRAG_EMBEDDING_MODEL="text-embedding-3-large"
export VGRAG_COLLECTION_PREFIX="my_project"
```

Or use a `.env` file in your project root:

```ini
OPENAI_API_KEY=sk-...
VGRAG_MILVUS_URI=http://localhost:19530
VGRAG_LLM_MODEL=gpt-4o
```

### Multiple Knowledge Bases

Use `collection_prefix` to maintain separate graphs in the same Milvus instance:

```python
# Different documents → different prefixes
legal_rag = VectorGraphRAG(milvus_uri="./data.db", collection_prefix="legal")
finance_rag = VectorGraphRAG(milvus_uri="./data.db", collection_prefix="finance")
```

## Adding Documents

!!! warning "Full rebuild vs incremental updates"
    `add_texts()`, `add_documents()`, and `add_documents_with_triplets()` rebuild the full knowledge base for the current collection prefix. These legacy convenience APIs are planned for removal in v1.0.0. Use `rebuild_texts()`, `rebuild_documents()`, or `rebuild_documents_with_triplets()` for full refreshes. For source create/update/delete flows, use `upsert_documents_by_source()` and `delete_documents_by_source()`.

### From Text Strings

```python
rag.rebuild_texts([
    "Einstein developed relativity at Princeton.",
    "The theory changed modern physics.",
])
```

### With Pre-extracted Triplets

Skip LLM extraction if you already have knowledge graph triplets:

```python
rag.rebuild_documents_with_triplets([
    {
        "passage": "Einstein developed relativity at Princeton.",
        "triplets": [
            ["Einstein", "developed", "relativity"],
            ["Einstein", "worked at", "Princeton"],
        ],
    },
])
```

### From URLs and Files

Import web pages, PDFs, and other documents with automatic chunking:

```python
from vector_graph_rag.loaders import DocumentImporter

importer = DocumentImporter(chunk_size=1000, chunk_overlap=200)
result = importer.import_sources([
    "https://en.wikipedia.org/wiki/Albert_Einstein",
    "/path/to/document.pdf",
    "/path/to/report.docx",
])

rag = VectorGraphRAG(milvus_uri="./my_graph.db")
rag.rebuild_documents(result.documents, extract_triplets=True)
```

!!! warning "Loader dependencies"
    Install with `uv add "vector-graph-rag[loaders]"` to enable URL fetching and document conversion.

To use a different local parser, pass a converter into `DocumentImporter`:

```python
from vector_graph_rag.loaders import DoclingConverter, DocumentImporter

importer = DocumentImporter(
    converter=DoclingConverter(),
    chunk_size=1000,
    chunk_overlap=200,
)
result = importer.import_sources(["/path/to/document.pdf"])
```

Install Docling support with `uv add "vector-graph-rag[docling]"`.

### Incremental Updates

Use `upsert_documents_by_source()` when a source file, page, or message is created or modified. In Vector Graph RAG, a `Document` is a passage/chunk, and `metadata["source"]` identifies the source object whose chunks should be replaced.

For parser and loader workflows, attach the same stable source value to every
chunk produced from one file, page, or message. See
[Incremental Updates](incremental-updates.md) for the full source-level CUD and
retry pattern.

```python
from langchain_core.documents import Document

rag.upsert_documents_by_source(
    documents=[
        Document(
            page_content="Einstein developed relativity at Princeton.",
            metadata={
                "source": "file:file-123",
                "triplets": [
                    ["Einstein", "developed", "relativity"],
                    ["Einstein", "worked at", "Princeton"],
                ],
            },
        )
    ],
    extract_triplets=False,
)

rag.delete_documents_by_source("file:file-123")
```

!!! warning "v0.2.0 migration"
    `upsert_documents(document_id=...)` and `delete_documents(document_id)` were removed because `Document` means passage/chunk in this project. Use `upsert_documents_by_source()` and `delete_documents_by_source()` with a stable `metadata["source"]` value instead.

!!! note "Consistency model"
    Incremental updates perform a source-level cascade across passages, entities, and relations. They are not transactionally atomic, and queries may observe intermediate state if a write is interrupted. If an upsert or delete fails, rerun the same operation for the same source to converge the source back to a consistent state. Avoid concurrently mutating the same collection prefix during an update.

## Observability

Install `vector-graph-rag[observability]` to enable OpenTelemetry trace instrumentation. The library creates spans for ingestion, loading, embeddings, Milvus operations, retrieval, and generation, while your application configures the OpenTelemetry SDK and exporter.

```python
from vector_graph_rag import VectorGraphRAG, observability_context

rag = VectorGraphRAG(collection_prefix="my_project")

with observability_context(
    request_id="req-123",
    tenant_id="tenant-a",
    graph_name="my_project",
    source="file-123",
):
    rag.upsert_documents_by_source(chunks, source="file-123")
```

See [Observability](observability.md) for setup, span coverage, and data-safety notes.

## Querying

### Full Query Result

```python
result = rag.query("What did Einstein develop?")
print(result.answer)           # Generated answer
print(result.query_entities)   # Extracted entities from question
print(result.passages)         # Retrieved passages used for answer
```

### Simple String Answer

```python
answer = rag.query_simple("What did Einstein develop?")
print(answer)  # Just the answer string
```

### Custom Retrieval Parameters

```python
result = rag.query(
    "What did Einstein develop?",
    entity_top_k=30,           # more entity candidates
    relation_top_k=30,         # more relation candidates
    expansion_degree=2,        # 2-hop expansion
)
```

## REST API

Run the API server for programmatic access or to power the frontend:

```bash
uv run uvicorn vector_graph_rag.api.app:app --host 0.0.0.0 --port 8000
```

Interactive docs available at `http://localhost:8000/docs`.

See the [REST API Reference](rest-api.md) for full endpoint documentation.

## Next Steps

- **[How It Works](how-it-works.md)** — Understand the indexing and query pipelines
- **[Design Philosophy](design-philosophy.md)** — Why pure vector search instead of graph databases
- **[Python API](python-api.md)** — Complete API reference with all parameters
- **[Use Cases](use-cases.md)** — Domain-specific examples and best practices
- **[Frontend](frontend.md)** — Interactive graph visualization
