R2RBuilder
Learn how to build and customize R2R
Introduction
R2R uses two key components for assembling and customizing applications: the R2RBuilder
and a set of factory classes, R2RFactory*
. These components work together to provide a flexible and intuitive way to construct R2R instances with custom configurations, providers, pipes, and pipelines.
R2RBuilder
The R2RBuilder
is the central component for assembling R2R applications. It employs the Builder pattern for simple application customization.
Key Features
- Flexible Configuration: Supports loading configurations from TOML files or using predefined configurations.
- Component Overrides: Allows overriding default providers, pipes, and pipelines with custom implementations.
- Factory Customization: Supports custom factory implementations for providers, pipes, and pipelines.
- Fluent Interface: Provides a chainable API for easy and readable setup.
Basic Usage
Here’s a simple example of how to use the R2RBuilder:
from r2r import R2RBuilder, R2RConfig
# Create an R2R instance with default configuration
r2r = R2RBuilder().build()
# Create an R2R instance with a custom configuration file
r2r = R2RBuilder(config=R2RConfig.from_toml("path/to/config.toml")).build()
# Create an R2R instance with a predefined configuration
r2r = R2RBuilder(config_name="full").build()
Factories
R2R uses a set of factory classes to create various components of the system. These factories allow for easy customization and extension of R2R’s functionality.
Main Factory Classes
- R2RProviderFactory: Creates provider instances (e.g., DatabaseProvider, EmbeddingProvider).
- R2RPipeFactory: Creates individual pipes used in pipelines.
- R2RPipelineFactory: Creates complete pipelines by assembling pipes.
Factory Methods
Each factory class contains methods for creating specific components. For example, the R2RPipeFactory
includes methods like:
create_parsing_pipe()
create_embedding_pipe()
create_vector_search_pipe()
create_rag_pipe()
Customizing Factories
You can customize the behavior of R2R by extending these factory classes. Here’s a simplified example of extending the R2RPipeFactory
:
from r2r import R2RPipeFactory
from r2r.pipes import MultiSearchPipe, QueryTransformPipe
class R2RPipeFactoryWithMultiSearch(R2RPipeFactory):
def create_vector_search_pipe(self, *args, **kwargs):
# Create a custom multi-search pipe
query_transform_pipe = QueryTransformPipe(
llm_provider=self.providers.llm,
prompt_provider=self.providers.prompt,
config=QueryTransformPipe.QueryTransformConfig(
name="multi_search",
task_prompt="multi_search_task_prompt",
),
)
inner_search_pipe = super().create_vector_search_pipe(*args, **kwargs)
return MultiSearchPipe(
query_transform_pipe=query_transform_pipe,
inner_search_pipe=inner_search_pipe,
config=MultiSearchPipe.PipeConfig(),
)
Builder + Factory in action
The R2RBuilder provides methods to override various components of the R2R system:
Provider Overrides
from r2r.providers import CustomAuthProvider, CustomDatabaseProvider
builder = R2RBuilder()
builder.with_auth_provider(CustomAuthProvider())
builder.with_database_provider(CustomDatabaseProvider())
r2r = builder.build()
Available provider override methods:
with_auth_provider
with_database_provider
with_embedding_provider
with_eval_provider
with_llm_provider
with_prompt_provider
with_kg_provider
with_crypto_provider
Pipe Overrides
from r2r.pipes import CustomParsingPipe, CustomEmbeddingPipe
builder = R2RBuilder()
builder.with_parsing_pipe(CustomParsingPipe())
builder.with_embedding_pipe(CustomEmbeddingPipe())
r2r = builder.build()
Available pipe override methods:
with_parsing_pipe
with_embedding_pipe
with_vector_storage_pipe
with_vector_search_pipe
with_rag_pipe
with_streaming_rag_pipe
with_eval_pipe
with_kg_pipe
with_kg_storage_pipe
with_kg_search_pipe
Pipeline Overrides
from r2r.pipelines import CustomIngestionPipeline, CustomSearchPipeline
builder = R2RBuilder()
builder.with_ingestion_pipeline(CustomIngestionPipeline())
builder.with_search_pipeline(CustomSearchPipeline())
r2r = builder.build()
Available pipeline override methods:
with_ingestion_pipeline
with_search_pipeline
with_rag_pipeline
with_streaming_rag_pipeline
with_eval_pipeline
Factory Overrides
from r2r.factory import CustomProviderFactory, CustomPipeFactory, CustomPipelineFactory
builder = R2RBuilder()
builder.with_provider_factory(CustomProviderFactory)
builder.with_pipe_factory(CustomPipeFactory)
builder.with_pipeline_factory(CustomPipelineFactory)
r2r = builder.build()
Advanced Usage
For more complex scenarios, you can chain multiple customizations:
from r2r import R2RBuilder, R2RConfig
from r2r.pipes import CustomRAGPipe
class MyCustomAuthProvider:
...
class MyCustomLLMProvider
...
class MyCustomRAGPipe
config = R2RConfig.from_toml("path/to/config.toml")
r2r = (
R2RBuilder(config=config)
.with_auth_provider(MyCustomAuthProvider())
.with_llm_provider(MyCustomLLMProvider())
.with_rag_pipe(MyCustomRAGPipe())
.build()
)
This approach allows you to create highly customized R2R instances tailored to your specific needs.
Best Practices
- Configuration Management: Use separate configuration files for different environments (development, staging, production).
- Custom Components: When creating custom providers, pipes, or pipelines, ensure they adhere to the respective interfaces defined in the R2R framework.
- Testability: Create factory methods or builder configurations specifically for testing to easily mock or stub components.
- Logging: Enable appropriate logging in your custom components to aid in debugging and monitoring.
- Error Handling: Implement proper error handling in custom components and provide meaningful error messages.
By leveraging the R2RBuilder and customizing factories, you can create flexible, customized, and powerful R2R applications tailored to your specific use cases and requirements.
Was this page helpful?