Files changed (1) hide show
  1. README.md +477 -475
README.md CHANGED
@@ -1,475 +1,477 @@
1
- ---
2
- title: RAG Optimizer
3
- emoji: 🔧
4
- colorFrom: blue
5
- colorTo: green
6
- sdk: docker
7
- sdk_version: "3.11"
8
- app_port: 8000
9
- base_path: /web
10
- ---
11
- ## RAG Optimizer Environment
12
-
13
- A reinforcement learning environment for optimizing Retrieval-Augmented
14
- Generation (RAG) parameters. Agents learn to select optimal `chunk_size` and
15
- `top_k` values to maximize retrieval performance.
16
-
17
- ## Overview
18
-
19
- This environment simulates a RAG parameter optimization task where agents must
20
- discover the optimal configuration:
21
-
22
- - **Optimal chunk_size**: 300
23
- - **Optimal top_k**: 5
24
-
25
- The environment scores actions based on how close the selected parameters are
26
- to these optimal values.
27
-
28
- ## Key Features
29
-
30
- - RL-style environment for parameter optimization
31
- - Deterministic reward function based on distance from optimal configuration
32
- - Multi-task setup with increasing difficulty
33
- - LLM proxy integration for OpenEnv validation
34
- - FastAPI + OpenEnv server for scalable interaction
35
- - Docker-ready and deployable on Hugging Face Spaces
36
-
37
- ## Problem Formulation
38
-
39
- We define RAG tuning as:
40
-
41
- - **State** : Current retrieval configuration
42
- - **Action** : Adjust `(chunk_size, top_k)`
43
- - **Reward** : Retrieval quality score
44
- - **Goal** : Maximize reward to reach task-specific thresholds
45
-
46
- ## Tasks
47
-
48
- Three tasks of varying difficulty:
49
-
50
- | Task | Target Score | Description |
51
- | ---------------------- | ------------ | ----------------------------------- |
52
- | `baseline_retrieval` | 0.5 | Easy - suboptimal parameters work |
53
- | `parameter_tuning` | 0.7 | Medium - requires good parameters |
54
- | `optimal_rag` | 0.85 | Hard - requires near-optimal params |
55
-
56
- ## Action Space
57
-
58
- ```python
59
- chunk_size: int # Size of document chunks
60
- top_k: int # Number of retrieved documents
61
- ```
62
-
63
- ## Reward Function
64
-
65
- Optimal configuration:
66
-
67
- - chunk_size = 300
68
- - top_k = 5
69
-
70
- ```python
71
- size_err = abs(chunk_size - 300) / 700.0
72
- k_err = abs(top_k - 5) / 5.0
73
- raw_score = 1.0 - (size_err + k_err) / 2.0
74
- ```
75
-
76
- Scores are clamped to `(0.01, 0.99)` to satisfy strict validator constraints.
77
-
78
- ## Installation
79
-
80
- ### Prerequisites
81
-
82
- - Python 3.11+
83
- - Docker (for containerized deployment)
84
- - UV package manager (recommended)
85
-
86
- ### Setup
87
-
88
- ```bash
89
- ### Clone repository
90
- git clone https://github.com/AyushGupta16/RAG_Optimizer.git
91
- cd RAG_Optimizer
92
-
93
- ### Install dependencies
94
- uv sync
95
- ```
96
-
97
- ### For local testing only
98
-
99
- ```python
100
- #### Or with pip
101
- pip install -r requirements.txt
102
-
103
- #### Set up environment variables
104
- cp .env.example .env
105
- #### Edit .env with your API credentials
106
- ```
107
-
108
- ### Environment Variables
109
-
110
- ```bash
111
- #### Required for LLM proxy (validator checks this)
112
- API_BASE_URL=https://your-llm-proxy.com/v1
113
- API_KEY=your_api_key_here
114
- MODEL_NAME=gpt-4o-mini
115
-
116
- # Local development
117
- ENV_BASE=http://127.0.0.1:8000
118
- ```
119
-
120
- ## Usage
121
-
122
- ### Running Locally
123
-
124
- ```bash
125
- # Terminal 1: Start environment server
126
- python server/app.py --host 127.0.0.1 --port 8000
127
-
128
- # Terminal 2: Run inference
129
- ```bash
130
- python inference.py
131
- ```
132
-
133
- ### Expected Output
134
-
135
- ```bash
136
- [DEBUG] LLM proxy call succeeded for task=baseline_retrieval
137
- [START] task=baseline_retrieval env=rag_optimizer model=gpt-4o-mini
138
- [STEP] step=1 action={"chunk_size": 500, "top_k": 3} reward=0.657143 done=true error=none
139
- [END] success=true steps=1 score=0.657143 rewards=0.657143
140
-
141
- [DEBUG] LLM proxy call succeeded for task=parameter_tuning
142
- [START] task=parameter_tuning env=rag_optimizer model=gpt-4o-mini
143
- [STEP] step=1 action={"chunk_size": 350, "top_k": 4} reward=0.864286 done=true error=none
144
- [END] success=true steps=1 score=0.864286 rewards=0.864286
145
-
146
- [DEBUG] LLM proxy call succeeded for task=optimal_rag
147
- [START] task=optimal_rag env=rag_optimizer model=gpt-4o-mini
148
- [STEP] step=1 action={"chunk_size": 300, "top_k": 5} reward=0.990000 done=true error=none
149
- [END] success=true steps=1 score=0.990000 rewards=0.990000
150
- ```
151
-
152
- ## Validation
153
-
154
- Run local validation before submitting:
155
-
156
- ```bash
157
- # Check environment setup
158
- openenv validate
159
-
160
- # Expected output:
161
- # [OK] RAG_Optimizer: Ready for multi-mode deployment
162
- ```
163
-
164
- ## Architecture and Integration
165
-
166
- ### System Architecture
167
-
168
- ```text
169
- inference.py
170
- |
171
- | 1. LLM proxy call using API_BASE_URL + API_KEY
172
- | 2. POST /reset and POST /step
173
- v
174
- server/app.py
175
- |
176
- | OpenEnv create_app(...)
177
- v
178
- server/rag_optimizer_environment.py
179
- |
180
- | - restore persistent state
181
- | - evaluate (chunk_size, top_k)
182
- | - call LLM proxy for validator compliance
183
- | - compute score and done flag
184
- v
185
- models.py
186
- |
187
- | - RagOptimizerAction
188
- | - RagOptimizerObservation
189
- | - RagOptimizerState
190
- v
191
- Reward + Observation returned to inference.py
192
- ```
193
-
194
- ### Repository Architecture
195
-
196
- ```text
197
- RAG_Optimizer/
198
- ├── server/
199
- │ ├── __init__.py
200
- ��� ├── app.py
201
- │ ├── Dockerfile
202
- │ ├── rag_optimizer_environment.py
203
- │ └── requirements.txt
204
- ├── outputs/
205
- ├── .venv/
206
- ├── __init__.py
207
- ├── .env
208
- ├── .gitignore
209
- ├── client.py
210
- ├── inference.py
211
- ├── models.py
212
- ├── openenv.yaml
213
- ├── pyproject.toml
214
- ├── README.md
215
- └── uv.lock
216
- ```
217
-
218
- ### Role of Each File
219
-
220
- - `server/app.py` creates the FastAPI/OpenEnv server.
221
- - `server/rag_optimizer_environment.py` contains the environment logic, task
222
- targets, scoring, and state persistence.
223
- - `server/Dockerfile` packages the environment for Hugging Face Spaces and
224
- validator execution.
225
- - `server/requirements.txt` lists runtime dependencies for server builds.
226
- - `inference.py` runs the benchmark tasks, calls the LLM proxy, and prints
227
- validator-compatible logs.
228
- - `models.py` defines action, observation, and state schemas.
229
- - `client.py` provides a reusable client wrapper for interacting with the
230
- environment.
231
- - `openenv.yaml` registers the environment and task metadata.
232
- - `pyproject.toml` defines package metadata and dependencies.
233
- - `uv.lock` locks dependency versions for reproducible builds.
234
- - `.env` is for local development only and should not be committed with secrets.
235
- - `outputs/` stores local run artifacts if generated.
236
-
237
- ### State Persistence
238
-
239
- The environment uses class-level variables to persist state across HTTP requests:
240
-
241
- ```py
242
- class RagOptimizerEnvironment(Environment):
243
- _current_target: float = 0.85
244
- _current_episode_id: Optional[str] = None
245
- _current_step_count: int = 0
246
- ```
247
-
248
- This ensures that episode state survives server framework instance recreation
249
- between `/reset` and `/step`.
250
-
251
- ### Project Structure
252
-
253
- ```text
254
- RAG_Optimizer/
255
- ├── server/
256
- │ ├── app.py
257
- │ ├── __init__.py
258
- │ └── rag_optimizer_environment.py
259
- ├── client.py
260
- ├── inference.py
261
- ├── models.py
262
- ├── openenv.yaml
263
- ├── pyproject.toml
264
- ├── README.md
265
- └── server/requirements.txt
266
- ```
267
-
268
- ### Environment Logic
269
-
270
- The environment computes scores based on normalized distance from optimal parameters:
271
-
272
- ```python
273
- size_error = abs(chunk_size - 300) / 700
274
- k_error = abs(top_k - 5) / 5
275
- raw_score = 1.0 - (size_error + k_error) / 2
276
- ```
277
-
278
- Scores are clamped to `(0.01, 0.99)` to satisfy validator requirements
279
- (strictly between 0 and 1).
280
-
281
- ## API Endpoints
282
-
283
- ### POST /reset
284
-
285
- Reset environment for a new episode.
286
-
287
- **Request:**
288
-
289
- ```json
290
- {
291
- "task_id": "optimal_rag",
292
- "episode_id": "optional-uuid"
293
- }
294
- ```
295
-
296
- **Response:**
297
-
298
- ```json
299
- {
300
- "observation": {
301
- "retrieval_score": 0.01,
302
- "message": "Environment reset. Task: optimal_rag | target=0.85"
303
- },
304
- "reward": 0.01,
305
- "done": false
306
- }
307
- ```
308
-
309
- ### POST /step
310
-
311
- Execute an action in the environment.
312
-
313
- **Request:**
314
-
315
- ```json
316
- {
317
- "action": {
318
- "chunk_size": 300,
319
- "top_k": 5
320
- }
321
- }
322
- ```
323
-
324
- **Response:**
325
-
326
- ```json
327
- {
328
- "observation": {
329
- "retrieval_score": 0.99,
330
- "message": "Step 1: Score 0.990000"
331
- },
332
- "reward": 0.99,
333
- "done": true
334
- }
335
- ```
336
-
337
- ## LLM Proxy Integration
338
-
339
- The project uses the injected validator credentials:
340
-
341
- - `API_BASE_URL`
342
- - `API_KEY`
343
- - `MODEL_NAME`
344
-
345
- The proxy is called from:
346
-
347
- - `inference.py` once per task
348
- - `server/rag_optimizer_environment.py` during `step()`
349
-
350
- This satisfies the LLM criteria checks while keeping the environment deterministic.
351
-
352
- ## Development
353
-
354
- ### Running Tests
355
-
356
- ```bash
357
- # Lint code
358
- ruff check .
359
-
360
- # Format code
361
- ruff format .
362
-
363
- # Type check
364
- mypy .
365
- ```
366
-
367
- ### Adding New Tasks
368
-
369
- To add a new difficulty level:
370
-
371
- 1. Update `TASK_TARGETS` in `rag_optimizer_environment.py`:
372
-
373
- ```python
374
- TASK_TARGETS = {
375
- "baseline_retrieval": 0.5,
376
- "parameter_tuning": 0.7,
377
- "optimal_rag": 0.85,
378
- "expert_rag": 0.95, # New task
379
- }
380
- ```
381
- 2. Update `TASK_TARGETS` in `inference.py`
382
- 3. Add test case to `inference.py`:
383
-
384
- ```python
385
- tasks = [
386
- # ... existing tasks ...
387
- ("expert_rag", {"chunk_size": 300, "top_k": 5}),
388
- ]
389
- ```
390
-
391
- ## Troubleshooting
392
-
393
- ### Common Issues
394
-
395
- #### LLM proxy call failed
396
-
397
- - Check `API_BASE_URL` and `API_KEY` in `.env`
398
- - Verify proxy endpoint is accessible
399
- - Check API quota/rate limits
400
-
401
- #### Scores out of range
402
-
403
- - Ensure environment clamps scores to `(0.01, 0.99)`
404
- - Check `grader_safe_score()` function
405
- - Verify no exact 0.0 or 1.0 values in logs
406
-
407
- #### State not persisting
408
-
409
- - Verify class variables are used (not instance variables)
410
- - Check `_current_*` variables are updated in `reset()`
411
- - Ensure `step()` restores state from class variables
412
-
413
- ## Tech Stack
414
-
415
- - Python
416
- - FastAPI
417
- - OpenEnv
418
- - OpenAI Python SDK
419
- - Docker
420
- - Hugging Face Spaces
421
-
422
- ## What Makes This Stand Out
423
-
424
- - ML Systems + RL environment design
425
- - Backend engineering with FastAPI + OpenEnv
426
- - Validator-compliant LLM proxy integration
427
- - Stateful environment handling across HTTP requests
428
- - Reproducible deployment through Docker and Hugging Face Spaces
429
-
430
- ## Future Improvements
431
-
432
- - Let the LLM suggest actions dynamically instead of fixed task actions
433
- - Integrate real vector databases (FAISS, Pinecone)
434
- - Replace synthetic reward with retrieval metrics (Recall@k, MRR)
435
- - Multi-step RL optimization (instead of single-step)
436
- - Learnable policies via PPO / DQN
437
-
438
- ## Contributing
439
-
440
- Contributions welcome! Please:
441
-
442
- 1. Fork the repository
443
- 2. Create a feature branch
444
- 3. Add tests for new functionality
445
- 4. Submit a pull request
446
-
447
- ## License
448
-
449
- MIT License - see LICENSE file for details
450
-
451
- ## Acknowledgments
452
-
453
- - Built with [OpenEnv](https://github.com/meta-llama/openenv)
454
- - Part of the OpenEnv Hackathon 2026
455
- - Environment design inspired by RAG optimization research
456
-
457
- ## Contact
458
-
459
- - **Author**: Ayush Gupta
460
- - **GitHub**: [@AyushGupta16](https://github.com/AyushGupta16)
461
- - **Email**: <ayushgupta0616@gmail.com>
462
-
463
- ## Citation
464
-
465
- If you use this environment in your research, please cite:
466
-
467
- ```bibtex
468
- @misc{rag-optimizer-2026,
469
- author = {Gupta, Ayush},
470
- title = {RAG Optimizer Environment},
471
- year = {2026},
472
- publisher = {GitHub},
473
- url = {<https://github.com/AyushGupta16/RAG_Optimizer>}
474
- }
475
- ```
 
 
 
1
+ ---
2
+ title: RAG Optimizer
3
+ emoji: 📈
4
+ colorFrom: blue
5
+ colorTo: green
6
+ sdk: docker
7
+ sdk_version: '3.11'
8
+ app_port: 8000
9
+ base_path: /web
10
+ license: mit
11
+ pinned: false
12
+ ---
13
+ ## RAG Optimizer Environment
14
+
15
+ A reinforcement learning environment for optimizing Retrieval-Augmented
16
+ Generation (RAG) parameters. Agents learn to select optimal `chunk_size` and
17
+ `top_k` values to maximize retrieval performance.
18
+
19
+ ## Overview
20
+
21
+ This environment simulates a RAG parameter optimization task where agents must
22
+ discover the optimal configuration:
23
+
24
+ - **Optimal chunk_size**: 300
25
+ - **Optimal top_k**: 5
26
+
27
+ The environment scores actions based on how close the selected parameters are
28
+ to these optimal values.
29
+
30
+ ## Key Features
31
+
32
+ - RL-style environment for parameter optimization
33
+ - Deterministic reward function based on distance from optimal configuration
34
+ - Multi-task setup with increasing difficulty
35
+ - LLM proxy integration for OpenEnv validation
36
+ - FastAPI + OpenEnv server for scalable interaction
37
+ - Docker-ready and deployable on Hugging Face Spaces
38
+
39
+ ## Problem Formulation
40
+
41
+ We define RAG tuning as:
42
+
43
+ - **State** : Current retrieval configuration
44
+ - **Action** : Adjust `(chunk_size, top_k)`
45
+ - **Reward** : Retrieval quality score
46
+ - **Goal** : Maximize reward to reach task-specific thresholds
47
+
48
+ ## Tasks
49
+
50
+ Three tasks of varying difficulty:
51
+
52
+ | Task | Target Score | Description |
53
+ | ---------------------- | ------------ | ----------------------------------- |
54
+ | `baseline_retrieval` | 0.5 | Easy - suboptimal parameters work |
55
+ | `parameter_tuning` | 0.7 | Medium - requires good parameters |
56
+ | `optimal_rag` | 0.85 | Hard - requires near-optimal params |
57
+
58
+ ## Action Space
59
+
60
+ ```python
61
+ chunk_size: int # Size of document chunks
62
+ top_k: int # Number of retrieved documents
63
+ ```
64
+
65
+ ## Reward Function
66
+
67
+ Optimal configuration:
68
+
69
+ - chunk_size = 300
70
+ - top_k = 5
71
+
72
+ ```python
73
+ size_err = abs(chunk_size - 300) / 700.0
74
+ k_err = abs(top_k - 5) / 5.0
75
+ raw_score = 1.0 - (size_err + k_err) / 2.0
76
+ ```
77
+
78
+ Scores are clamped to `(0.01, 0.99)` to satisfy strict validator constraints.
79
+
80
+ ## Installation
81
+
82
+ ### Prerequisites
83
+
84
+ - Python 3.11+
85
+ - Docker (for containerized deployment)
86
+ - UV package manager (recommended)
87
+
88
+ ### Setup
89
+
90
+ ```bash
91
+ ### Clone repository
92
+ git clone https://github.com/AyushGupta16/RAG_Optimizer.git
93
+ cd RAG_Optimizer
94
+
95
+ ### Install dependencies
96
+ uv sync
97
+ ```
98
+
99
+ ### For local testing only
100
+
101
+ ```python
102
+ #### Or with pip
103
+ pip install -r requirements.txt
104
+
105
+ #### Set up environment variables
106
+ cp .env.example .env
107
+ #### Edit .env with your API credentials
108
+ ```
109
+
110
+ ### Environment Variables
111
+
112
+ ```bash
113
+ #### Required for LLM proxy (validator checks this)
114
+ API_BASE_URL=https://your-llm-proxy.com/v1
115
+ API_KEY=your_api_key_here
116
+ MODEL_NAME=gpt-4o-mini
117
+
118
+ # Local development
119
+ ENV_BASE=http://127.0.0.1:8000
120
+ ```
121
+
122
+ ## Usage
123
+
124
+ ### Running Locally
125
+
126
+ ```bash
127
+ # Terminal 1: Start environment server
128
+ python server/app.py --host 127.0.0.1 --port 8000
129
+
130
+ # Terminal 2: Run inference
131
+ ```bash
132
+ python inference.py
133
+ ```
134
+
135
+ ### Expected Output
136
+
137
+ ```bash
138
+ [DEBUG] LLM proxy call succeeded for task=baseline_retrieval
139
+ [START] task=baseline_retrieval env=rag_optimizer model=gpt-4o-mini
140
+ [STEP] step=1 action={"chunk_size": 500, "top_k": 3} reward=0.657143 done=true error=none
141
+ [END] success=true steps=1 score=0.657143 rewards=0.657143
142
+
143
+ [DEBUG] LLM proxy call succeeded for task=parameter_tuning
144
+ [START] task=parameter_tuning env=rag_optimizer model=gpt-4o-mini
145
+ [STEP] step=1 action={"chunk_size": 350, "top_k": 4} reward=0.864286 done=true error=none
146
+ [END] success=true steps=1 score=0.864286 rewards=0.864286
147
+
148
+ [DEBUG] LLM proxy call succeeded for task=optimal_rag
149
+ [START] task=optimal_rag env=rag_optimizer model=gpt-4o-mini
150
+ [STEP] step=1 action={"chunk_size": 300, "top_k": 5} reward=0.990000 done=true error=none
151
+ [END] success=true steps=1 score=0.990000 rewards=0.990000
152
+ ```
153
+
154
+ ## Validation
155
+
156
+ Run local validation before submitting:
157
+
158
+ ```bash
159
+ # Check environment setup
160
+ openenv validate
161
+
162
+ # Expected output:
163
+ # [OK] RAG_Optimizer: Ready for multi-mode deployment
164
+ ```
165
+
166
+ ## Architecture and Integration
167
+
168
+ ### System Architecture
169
+
170
+ ```text
171
+ inference.py
172
+ |
173
+ | 1. LLM proxy call using API_BASE_URL + API_KEY
174
+ | 2. POST /reset and POST /step
175
+ v
176
+ server/app.py
177
+ |
178
+ | OpenEnv create_app(...)
179
+ v
180
+ server/rag_optimizer_environment.py
181
+ |
182
+ | - restore persistent state
183
+ | - evaluate (chunk_size, top_k)
184
+ | - call LLM proxy for validator compliance
185
+ | - compute score and done flag
186
+ v
187
+ models.py
188
+ |
189
+ | - RagOptimizerAction
190
+ | - RagOptimizerObservation
191
+ | - RagOptimizerState
192
+ v
193
+ Reward + Observation returned to inference.py
194
+ ```
195
+
196
+ ### Repository Architecture
197
+
198
+ ```text
199
+ RAG_Optimizer/
200
+ ├── server/
201
+ │ ├── __init__.py
202
+ │ ├── app.py
203
+ │ ├── Dockerfile
204
+ │ ├── rag_optimizer_environment.py
205
+ │ └── requirements.txt
206
+ ├── outputs/
207
+ ├── .venv/
208
+ ├── __init__.py
209
+ ├── .env
210
+ ├── .gitignore
211
+ ├── client.py
212
+ ├── inference.py
213
+ ├── models.py
214
+ ├── openenv.yaml
215
+ ├── pyproject.toml
216
+ ├── README.md
217
+ └── uv.lock
218
+ ```
219
+
220
+ ### Role of Each File
221
+
222
+ - `server/app.py` creates the FastAPI/OpenEnv server.
223
+ - `server/rag_optimizer_environment.py` contains the environment logic, task
224
+ targets, scoring, and state persistence.
225
+ - `server/Dockerfile` packages the environment for Hugging Face Spaces and
226
+ validator execution.
227
+ - `server/requirements.txt` lists runtime dependencies for server builds.
228
+ - `inference.py` runs the benchmark tasks, calls the LLM proxy, and prints
229
+ validator-compatible logs.
230
+ - `models.py` defines action, observation, and state schemas.
231
+ - `client.py` provides a reusable client wrapper for interacting with the
232
+ environment.
233
+ - `openenv.yaml` registers the environment and task metadata.
234
+ - `pyproject.toml` defines package metadata and dependencies.
235
+ - `uv.lock` locks dependency versions for reproducible builds.
236
+ - `.env` is for local development only and should not be committed with secrets.
237
+ - `outputs/` stores local run artifacts if generated.
238
+
239
+ ### State Persistence
240
+
241
+ The environment uses class-level variables to persist state across HTTP requests:
242
+
243
+ ```py
244
+ class RagOptimizerEnvironment(Environment):
245
+ _current_target: float = 0.85
246
+ _current_episode_id: Optional[str] = None
247
+ _current_step_count: int = 0
248
+ ```
249
+
250
+ This ensures that episode state survives server framework instance recreation
251
+ between `/reset` and `/step`.
252
+
253
+ ### Project Structure
254
+
255
+ ```text
256
+ RAG_Optimizer/
257
+ ├── server/
258
+ │ ├── app.py
259
+ │ ├── __init__.py
260
+ │ └── rag_optimizer_environment.py
261
+ ├── client.py
262
+ ├── inference.py
263
+ ├── models.py
264
+ ├── openenv.yaml
265
+ ├── pyproject.toml
266
+ ├── README.md
267
+ └── server/requirements.txt
268
+ ```
269
+
270
+ ### Environment Logic
271
+
272
+ The environment computes scores based on normalized distance from optimal parameters:
273
+
274
+ ```python
275
+ size_error = abs(chunk_size - 300) / 700
276
+ k_error = abs(top_k - 5) / 5
277
+ raw_score = 1.0 - (size_error + k_error) / 2
278
+ ```
279
+
280
+ Scores are clamped to `(0.01, 0.99)` to satisfy validator requirements
281
+ (strictly between 0 and 1).
282
+
283
+ ## API Endpoints
284
+
285
+ ### POST /reset
286
+
287
+ Reset environment for a new episode.
288
+
289
+ **Request:**
290
+
291
+ ```json
292
+ {
293
+ "task_id": "optimal_rag",
294
+ "episode_id": "optional-uuid"
295
+ }
296
+ ```
297
+
298
+ **Response:**
299
+
300
+ ```json
301
+ {
302
+ "observation": {
303
+ "retrieval_score": 0.01,
304
+ "message": "Environment reset. Task: optimal_rag | target=0.85"
305
+ },
306
+ "reward": 0.01,
307
+ "done": false
308
+ }
309
+ ```
310
+
311
+ ### POST /step
312
+
313
+ Execute an action in the environment.
314
+
315
+ **Request:**
316
+
317
+ ```json
318
+ {
319
+ "action": {
320
+ "chunk_size": 300,
321
+ "top_k": 5
322
+ }
323
+ }
324
+ ```
325
+
326
+ **Response:**
327
+
328
+ ```json
329
+ {
330
+ "observation": {
331
+ "retrieval_score": 0.99,
332
+ "message": "Step 1: Score 0.990000"
333
+ },
334
+ "reward": 0.99,
335
+ "done": true
336
+ }
337
+ ```
338
+
339
+ ## LLM Proxy Integration
340
+
341
+ The project uses the injected validator credentials:
342
+
343
+ - `API_BASE_URL`
344
+ - `API_KEY`
345
+ - `MODEL_NAME`
346
+
347
+ The proxy is called from:
348
+
349
+ - `inference.py` once per task
350
+ - `server/rag_optimizer_environment.py` during `step()`
351
+
352
+ This satisfies the LLM criteria checks while keeping the environment deterministic.
353
+
354
+ ## Development
355
+
356
+ ### Running Tests
357
+
358
+ ```bash
359
+ # Lint code
360
+ ruff check .
361
+
362
+ # Format code
363
+ ruff format .
364
+
365
+ # Type check
366
+ mypy .
367
+ ```
368
+
369
+ ### Adding New Tasks
370
+
371
+ To add a new difficulty level:
372
+
373
+ 1. Update `TASK_TARGETS` in `rag_optimizer_environment.py`:
374
+
375
+ ```python
376
+ TASK_TARGETS = {
377
+ "baseline_retrieval": 0.5,
378
+ "parameter_tuning": 0.7,
379
+ "optimal_rag": 0.85,
380
+ "expert_rag": 0.95, # New task
381
+ }
382
+ ```
383
+ 2. Update `TASK_TARGETS` in `inference.py`
384
+ 3. Add test case to `inference.py`:
385
+
386
+ ```python
387
+ tasks = [
388
+ # ... existing tasks ...
389
+ ("expert_rag", {"chunk_size": 300, "top_k": 5}),
390
+ ]
391
+ ```
392
+
393
+ ## Troubleshooting
394
+
395
+ ### Common Issues
396
+
397
+ #### LLM proxy call failed
398
+
399
+ - Check `API_BASE_URL` and `API_KEY` in `.env`
400
+ - Verify proxy endpoint is accessible
401
+ - Check API quota/rate limits
402
+
403
+ #### Scores out of range
404
+
405
+ - Ensure environment clamps scores to `(0.01, 0.99)`
406
+ - Check `grader_safe_score()` function
407
+ - Verify no exact 0.0 or 1.0 values in logs
408
+
409
+ #### State not persisting
410
+
411
+ - Verify class variables are used (not instance variables)
412
+ - Check `_current_*` variables are updated in `reset()`
413
+ - Ensure `step()` restores state from class variables
414
+
415
+ ## Tech Stack
416
+
417
+ - Python
418
+ - FastAPI
419
+ - OpenEnv
420
+ - OpenAI Python SDK
421
+ - Docker
422
+ - Hugging Face Spaces
423
+
424
+ ## What Makes This Stand Out
425
+
426
+ - ML Systems + RL environment design
427
+ - Backend engineering with FastAPI + OpenEnv
428
+ - Validator-compliant LLM proxy integration
429
+ - Stateful environment handling across HTTP requests
430
+ - Reproducible deployment through Docker and Hugging Face Spaces
431
+
432
+ ## Future Improvements
433
+
434
+ - Let the LLM suggest actions dynamically instead of fixed task actions
435
+ - Integrate real vector databases (FAISS, Pinecone)
436
+ - Replace synthetic reward with retrieval metrics (Recall@k, MRR)
437
+ - Multi-step RL optimization (instead of single-step)
438
+ - Learnable policies via PPO / DQN
439
+
440
+ ## Contributing
441
+
442
+ Contributions welcome! Please:
443
+
444
+ 1. Fork the repository
445
+ 2. Create a feature branch
446
+ 3. Add tests for new functionality
447
+ 4. Submit a pull request
448
+
449
+ ## License
450
+
451
+ MIT License - see LICENSE file for details
452
+
453
+ ## Acknowledgments
454
+
455
+ - Built with [OpenEnv](https://github.com/meta-llama/openenv)
456
+ - Part of the OpenEnv Hackathon 2026
457
+ - Environment design inspired by RAG optimization research
458
+
459
+ ## Contact
460
+
461
+ - **Author**: Ayush Gupta
462
+ - **GitHub**: [@AyushGupta16](https://github.com/AyushGupta16)
463
+ - **Email**: <ayushgupta0616@gmail.com>
464
+
465
+ ## Citation
466
+
467
+ If you use this environment in your research, please cite:
468
+
469
+ ```bibtex
470
+ @misc{rag-optimizer-2026,
471
+ author = {Gupta, Ayush},
472
+ title = {RAG Optimizer Environment},
473
+ year = {2026},
474
+ publisher = {GitHub},
475
+ url = {<https://github.com/AyushGupta16/RAG_Optimizer>}
476
+ }
477
+ ```