Skip to main content

ares_rag/
config.rs

1use serde::{Deserialize, Serialize};
2
3// ============= RAG Configuration =============
4// RAG (Retrieval Augmented Generation) configuration.
5// =========== Vector Store ===========
6#[derive(Debug, Clone, Deserialize, Serialize)]
7#[serde(default)]
8pub struct RAGVectorConfig {
9    /// Enable RAG feature flag (disabled by default for safety)
10    pub enabled: bool,
11    /// Available models: bge-small-en-v1.5, bge-base-en-v1.5, bge-large-en-v1.5,
12    /// all-minilm-l6-v2, all-minilm-l12-v2, nomic-embed-text-v1.5, etc.
13    #[serde(default = "default_embedding_model")]
14    pub embedding_model: String,
15    /// Enable sparse embeddings for hybrid search (default: false)
16    #[serde(default)]
17    pub sparse_embeddings: bool,
18    /// Sparse embedding model (default: "splade-pp-en-v1")
19    #[serde(default = "default_sparse_model")]
20    pub sparse_model: String,
21    /// Path to store vector data (default: "./data/vectors")
22    #[serde(default = "default_vector_path")]
23    pub vector_path: String,
24}
25
26// =========== Chunking ===========
27#[derive(Debug, Clone, Deserialize, Serialize)]
28#[serde(default)]
29pub struct RagChunkingConfig {
30    /// Chunking strategy: "word" (default), "semantic", "character"
31    #[serde(default = "default_chunking_strategy")]
32    pub chunking_strategy: String,
33    /// Size of text chunks for indexing (default: 200 words or 500 chars for semantic).
34    #[serde(default = "default_chunk_size")]
35    pub chunk_size: usize,
36    /// Overlap between consecutive chunks (default: 50).
37    #[serde(default = "default_chunk_overlap")]
38    pub chunk_overlap: usize,
39    /// Minimum chunk size to keep (default: 20 chars).
40    #[serde(default = "default_min_chunk_size")]
41    pub min_chunk_size: usize,
42}
43
44// =========== Search ===========
45#[derive(Debug, Clone, Deserialize, Serialize)]
46#[serde(default)]
47pub struct RagSearchConfig {
48    /// Default search strategy: "semantic" (default), "bm25", "fuzzy", "hybrid"
49    #[serde(default = "default_search_strategy")]
50    pub search_strategy: String,
51    /// Default number of results to return (default: 10)
52    #[serde(default = "default_search_limit")]
53    pub search_limit: usize,
54    /// Default similarity threshold (default: 0.0)
55    #[serde(default)]
56    pub search_threshold: f32,
57    /// Hybrid search weights (semantic, bm25, fuzzy) - sum should be 1.0
58    #[serde(default)]
59    pub hybrid_weights: Option<HybridWeightsConfig>,
60}
61
62// =========== Reranking ===========
63#[derive(Debug, Clone, Deserialize, Serialize)]
64#[serde(default)]
65pub struct RagRerankingConfig {
66    /// Enable reranking by default (default: false)
67    #[serde(default)]
68    pub rerank_enabled: bool,
69    /// Reranker model: "bge-reranker-base" (default), "bge-reranker-v2-m3",
70    /// "jina-reranker-v1-turbo-en", "jina-reranker-v2-base-multilingual"
71    #[serde(default = "default_reranker_model")]
72    pub reranker_model: String,
73    /// Weight for combining rerank and retrieval scores (default: 0.6)
74    #[serde(default = "default_rerank_weight")]
75    pub rerank_weight: f32,
76}
77/// RAG Configuration Wrapper
78#[derive(Debug, Clone, Default, Serialize, Deserialize)]
79#[serde(default)]
80pub struct RagConfig {
81    /// Vector store configuration for vector embeddings and retrieval
82    pub vector: RAGVectorConfig,
83    /// Text chunking strategy for document indexing
84    pub chunking: RagChunkingConfig,
85    /// Search strategy and configuration
86    pub search: RagSearchConfig,
87    /// Reranking configuration
88    pub rerank: RagRerankingConfig,
89}
90#[derive(Debug, Clone, Deserialize, Serialize)]
91
92pub struct HybridWeightsConfig {
93    /// Weight for semantic search (default: 0.5)
94    #[serde(default = "default_semantic_weight")]
95    pub semantic: f32,
96    /// Weight for BM25 search (default: 0.3)
97    #[serde(default = "default_bm25_weight")]
98    pub bm25: f32,
99    /// Weight for fuzzy search (default: 0.2)
100    #[serde(default = "default_fuzzy_weight")]
101    pub fuzzy: f32,
102}
103
104impl Default for HybridWeightsConfig {
105    fn default() -> Self {
106        Self {
107            semantic: 0.5,
108            bm25: 0.3,
109            fuzzy: 0.2,
110        }
111    }
112}
113
114impl Default for RAGVectorConfig {
115    fn default() -> Self {
116        Self {
117            enabled: false,
118            embedding_model: default_embedding_model(),
119            sparse_embeddings: false,
120            sparse_model: default_sparse_model(),
121            vector_path: default_vector_path(),
122        }
123    }
124}
125
126impl Default for RagChunkingConfig {
127    fn default() -> Self {
128        Self {
129            chunking_strategy: default_chunking_strategy(),
130            chunk_size: default_chunk_size(),
131            chunk_overlap: default_chunk_overlap(),
132            min_chunk_size: default_min_chunk_size(),
133        }
134    }
135}
136
137impl Default for RagSearchConfig {
138    fn default() -> Self {
139        Self {
140            search_strategy: default_search_strategy(),
141            search_limit: default_search_limit(),
142            search_threshold: 0.0,
143            hybrid_weights: None,
144        }
145    }
146}
147
148impl Default for RagRerankingConfig {
149    fn default() -> Self {
150        Self {
151            rerank_enabled: false,
152            reranker_model: default_reranker_model(),
153            rerank_weight: default_rerank_weight(),
154        }
155    }
156}
157
158fn default_semantic_weight() -> f32 {
159    0.5
160}
161
162fn default_bm25_weight() -> f32 {
163    0.3
164}
165
166fn default_fuzzy_weight() -> f32 {
167    0.2
168}
169
170fn default_vector_path() -> String {
171    "./data/vectors".to_string()
172}
173
174fn default_embedding_model() -> String {
175    "bge-small-en-v1.5".to_string()
176}
177
178fn default_sparse_model() -> String {
179    "splade-pp-en-v1".to_string()
180}
181
182fn default_chunking_strategy() -> String {
183    "word".to_string()
184}
185
186fn default_chunk_size() -> usize {
187    200
188}
189
190fn default_chunk_overlap() -> usize {
191    50
192}
193
194fn default_min_chunk_size() -> usize {
195    20
196}
197
198fn default_search_strategy() -> String {
199    "semantic".to_string()
200}
201
202fn default_search_limit() -> usize {
203    10
204}
205
206fn default_reranker_model() -> String {
207    "bge-reranker-base".to_string()
208}
209
210fn default_rerank_weight() -> f32 {
211    0.6
212}