1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Deserialize, Serialize)]
7#[serde(default)]
8pub struct RAGVectorConfig {
9 pub enabled: bool,
11 #[serde(default = "default_embedding_model")]
14 pub embedding_model: String,
15 #[serde(default)]
17 pub sparse_embeddings: bool,
18 #[serde(default = "default_sparse_model")]
20 pub sparse_model: String,
21 #[serde(default = "default_vector_path")]
23 pub vector_path: String,
24}
25
26#[derive(Debug, Clone, Deserialize, Serialize)]
28#[serde(default)]
29pub struct RagChunkingConfig {
30 #[serde(default = "default_chunking_strategy")]
32 pub chunking_strategy: String,
33 #[serde(default = "default_chunk_size")]
35 pub chunk_size: usize,
36 #[serde(default = "default_chunk_overlap")]
38 pub chunk_overlap: usize,
39 #[serde(default = "default_min_chunk_size")]
41 pub min_chunk_size: usize,
42}
43
44#[derive(Debug, Clone, Deserialize, Serialize)]
46#[serde(default)]
47pub struct RagSearchConfig {
48 #[serde(default = "default_search_strategy")]
50 pub search_strategy: String,
51 #[serde(default = "default_search_limit")]
53 pub search_limit: usize,
54 #[serde(default)]
56 pub search_threshold: f32,
57 #[serde(default)]
59 pub hybrid_weights: Option<HybridWeightsConfig>,
60}
61
62#[derive(Debug, Clone, Deserialize, Serialize)]
64#[serde(default)]
65pub struct RagRerankingConfig {
66 #[serde(default)]
68 pub rerank_enabled: bool,
69 #[serde(default = "default_reranker_model")]
72 pub reranker_model: String,
73 #[serde(default = "default_rerank_weight")]
75 pub rerank_weight: f32,
76}
77#[derive(Debug, Clone, Default, Serialize, Deserialize)]
79#[serde(default)]
80pub struct RagConfig {
81 pub vector: RAGVectorConfig,
83 pub chunking: RagChunkingConfig,
85 pub search: RagSearchConfig,
87 pub rerank: RagRerankingConfig,
89}
90#[derive(Debug, Clone, Deserialize, Serialize)]
91
92pub struct HybridWeightsConfig {
93 #[serde(default = "default_semantic_weight")]
95 pub semantic: f32,
96 #[serde(default = "default_bm25_weight")]
98 pub bm25: f32,
99 #[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}