The `DocEmbedder` class provides an end-to-end pipeline for ingesting documents into Feast's online vector store. It handles chunking, embedding generation, and writing results -- all in a single step.
#### Key Components
* **`DocEmbedder`**: High-level orchestrator that runs the full pipeline: chunk → embed → schema transform → write to online store
* **`BaseChunker` / `TextChunker`**: Pluggable chunking layer. `TextChunker` splits text by word count with configurable `chunk_size`, `chunk_overlap`, `min_chunk_size`, and `max_chunk_chars`
* **`BaseEmbedder` / `MultiModalEmbedder`**: Pluggable embedding layer with modality routing. `MultiModalEmbedder` supports text (via sentence-transformers) and image (via CLIP) with lazy model loading
* **`SchemaTransformFn`**: A user-defined function that transforms the chunked + embedded DataFrame into the format expected by the FeatureView schema
print('\n'.join([c.message.content for c in response.choices]))
```
## Alternative: Using DocEmbedder for Simplified Ingestion
Instead of manually chunking, embedding, and writing documents as shown above, you can use Feast's `DocEmbedder` class to handle the entire pipeline in a single step. `DocEmbedder` automates chunking, embedding generation, FeatureView creation, and writing to the online store.
### Install Dependencies
```bash
pip install feast[milvus,rag]
```
### Set Up and Ingest with DocEmbedder
```python
from feast import DocEmbedder
import pandas as pd
# Prepare your documents as a DataFrame
df = pd.DataFrame({
"id": ["doc1", "doc2", "doc3"],
"text": [
"Aaron is a prophet, high priest, and the brother of Moses...",
"God at Sinai granted Aaron the priesthood for himself...",
"His rod turned into a snake. Then he stretched out...",
`DocEmbedder` is extensible at every stage. Below are examples of how to create custom components and wire them together.
#### Custom Chunker
Subclass `BaseChunker` to implement your own chunking strategy. The `load_parse_and_chunk` method receives each document and must return a list of chunk dictionaries.
```python
from feast.chunker import BaseChunker, ChunkingConfig
from typing import Any, Optional
class SentenceChunker(BaseChunker):
"""Chunks text by sentences instead of word count."""
def load_parse_and_chunk(
self,
source: Any,
source_id: str,
source_column: str,
source_type: Optional[str] = None,
) -> list[dict]:
import re
text = str(source)
# Split on sentence boundaries
sentences = re.split(r'(?<=[.!?])\s+', text)
chunks = []
current_chunk = []
chunk_index = 0
for sentence in sentences:
current_chunk.append(sentence)
combined = " ".join(current_chunk)
if len(combined.split()) >= self.config.chunk_size:
chunks.append({
"chunk_id": f"{source_id}_{chunk_index}",
"original_id": source_id,
source_column: combined,
"chunk_index": chunk_index,
})
# Keep overlap by retaining the last sentence
current_chunk = [sentence]
chunk_index += 1
# Don't forget the last chunk
if current_chunk and len(" ".join(current_chunk).split()) >= self.config.min_chunk_size:
chunks.append({
"chunk_id": f"{source_id}_{chunk_index}",
"original_id": source_id,
source_column: " ".join(current_chunk),
"chunk_index": chunk_index,
})
return chunks
```
Or simply configure the built-in `TextChunker`:
```python
from feast import TextChunker, ChunkingConfig
chunker = TextChunker(config=ChunkingConfig(
chunk_size=200,
chunk_overlap=50,
min_chunk_size=30,
max_chunk_chars=1000,
))
```
#### Custom Embedder
Subclass `BaseEmbedder` to use a different embedding model. Register modality handlers in `_register_default_modalities` and implement the `embed` method.
```python
from feast.embedder import BaseEmbedder, EmbeddingConfig
from typing import Any, List, Optional
import numpy as np
class OpenAIEmbedder(BaseEmbedder):
"""Embedder that uses the OpenAI API for text embeddings."""
return np.array([item.embedding for item in response.data])
```
#### Custom Logical Layer Function
The schema transform function transforms the chunked + embedded DataFrame into the exact schema your FeatureView expects. It must accept a `pd.DataFrame` and return a `pd.DataFrame`.
vector_length=1536, # Match the OpenAI embedding dimension
)
# Embed and ingest
result = embedder.embed_documents(
documents=df,
id_column="id",
source_column="text",
column_mapping=("text", "text_embedding"),
)
```
> **Note:** When using a custom `schema_transform_fn`, ensure the returned DataFrame columns match your FeatureView schema. When using a custom embedder with a different output dimension, set `vector_length` accordingly (or let it auto-detect via `get_embedding_dim`).
For a complete end-to-end example, see the [DocEmbedder notebook](https://github.com/feast-dev/feast/tree/master/examples/rag-retriever/rag_feast_docembedder.ipynb).
## Why Feast for RAG?
Feast makes it remarkably easy to set up and manage a RAG system by:
@@ -62,6 +62,59 @@ Navigate to the examples/rag-retriever directory. Here you will find the followi
Open `rag_feast.ipynb` and follow the steps in the notebook to run the example.
## Using DocEmbedder for Simplified Ingestion
As an alternative to the manual data preparation steps in the notebook above, Feast provides the `DocEmbedder` class that automates the entire document-to-embeddings pipeline: chunking, embedding generation, FeatureView creation, and writing to the online store.
1. **Generates a FeatureView**: Automatically creates a Python file with Entity and FeatureView definitions compatible with `feast apply`
2. **Applies the repo**: Registers the FeatureView in the Feast registry and deploys infrastructure (e.g., Milvus collection)
3. **Chunks documents**: Splits text into smaller passages using `TextChunker` (configurable chunk size, overlap, etc.)
4. **Generates embeddings**: Produces vector embeddings using `MultiModalEmbedder` (defaults to `all-MiniLM-L6-v2`)
5. **Writes to online store**: Stores the processed data in your configured online store (e.g., Milvus)
### Customization
* **Custom Chunker**: Subclass `BaseChunker` for your own chunking strategy
* **Custom Embedder**: Subclass `BaseEmbedder` to use a different embedding model
* **Logical Layer Function**: Provide a `SchemaTransformFn` to control how the output maps to your FeatureView schema
### Example Notebook
See **`rag_feast_docembedder.ipynb`** for a complete end-to-end example that uses DocEmbedder with the Wiki DPR dataset and then queries the results using `FeastRAGRetriever`.
from .chunker import BaseChunker, ChunkingConfig, TextChunker
from .data_source import KafkaSource, KinesisSource, PushSource, RequestSource
from .dataframe import DataFrameEngine, FeastDataFrame
from .doc_embedder import DocEmbedder, LogicalLayerFn
from .doc_embedder import DocEmbedder, SchemaTransformFn
from .embedder import BaseEmbedder, EmbeddingConfig, MultiModalEmbedder
from .entity import Entity
from .feature import Feature
Expand DownExpand Up
@@ -66,7 +66,7 @@
"Project",
"FeastVectorStore",
"DocEmbedder",
"LogicalLayerFn",
"SchemaTransformFn",
"BaseChunker",
"TextChunker",
"ChunkingConfig",
Expand Down
Loading
Oops, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Loading
Oops, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402520 — GeezerVison does not store the pages you look up. Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.