relai 0.3.2__tar.gz → 0.3.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of relai might be problematic. Click here for more details.
- {relai-0.3.2/relai.egg-info → relai-0.3.3}/PKG-INFO +186 -8
- relai-0.3.3/README.md +217 -0
- {relai-0.3.2 → relai-0.3.3}/pyproject.toml +4 -3
- {relai-0.3.2 → relai-0.3.3}/relai/logger.py +5 -2
- {relai-0.3.2 → relai-0.3.3}/relai/maestro/optimizer.py +109 -79
- {relai-0.3.2 → relai-0.3.3}/relai/mocker/persona.py +6 -2
- {relai-0.3.2 → relai-0.3.3}/relai/simulator.py +16 -8
- {relai-0.3.2 → relai-0.3.3}/relai/utils.py +37 -0
- {relai-0.3.2 → relai-0.3.3/relai.egg-info}/PKG-INFO +186 -8
- relai-0.3.2/README.md +0 -38
- {relai-0.3.2 → relai-0.3.3}/LICENSE.md +0 -0
- {relai-0.3.2 → relai-0.3.3}/relai/__init__.py +0 -0
- {relai-0.3.2 → relai-0.3.3}/relai/_client.py +0 -0
- {relai-0.3.2 → relai-0.3.3}/relai/_exceptions.py +0 -0
- {relai-0.3.2 → relai-0.3.3}/relai/benchmark.py +0 -0
- {relai-0.3.2 → relai-0.3.3}/relai/critico/__init__.py +0 -0
- {relai-0.3.2 → relai-0.3.3}/relai/critico/critico.py +0 -0
- {relai-0.3.2 → relai-0.3.3}/relai/critico/evaluate.py +0 -0
- {relai-0.3.2 → relai-0.3.3}/relai/data.py +0 -0
- {relai-0.3.2 → relai-0.3.3}/relai/exporter.py +0 -0
- {relai-0.3.2 → relai-0.3.3}/relai/flags.py +0 -0
- {relai-0.3.2 → relai-0.3.3}/relai/maestro/__init__.py +0 -0
- {relai-0.3.2 → relai-0.3.3}/relai/maestro/graph.py +0 -0
- {relai-0.3.2 → relai-0.3.3}/relai/maestro/params.py +0 -0
- {relai-0.3.2 → relai-0.3.3}/relai/maestro/utils.py +0 -0
- {relai-0.3.2 → relai-0.3.3}/relai/mocker/__init__.py +0 -0
- {relai-0.3.2 → relai-0.3.3}/relai/mocker/base_mocker.py +0 -0
- {relai-0.3.2 → relai-0.3.3}/relai/mocker/tool.py +0 -0
- {relai-0.3.2 → relai-0.3.3}/relai/schema/visual.py +0 -0
- {relai-0.3.2 → relai-0.3.3}/relai.egg-info/SOURCES.txt +0 -0
- {relai-0.3.2 → relai-0.3.3}/relai.egg-info/dependency_links.txt +0 -0
- {relai-0.3.2 → relai-0.3.3}/relai.egg-info/requires.txt +0 -0
- {relai-0.3.2 → relai-0.3.3}/relai.egg-info/top_level.txt +0 -0
- {relai-0.3.2 → relai-0.3.3}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: relai
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.3
|
|
4
4
|
Summary: An SDK for building reliable AI agents
|
|
5
5
|
Author-email: RELAI <priyatham@relai.ai>, RELAI <wwx@relai.ai>
|
|
6
6
|
License: Apache License
|
|
@@ -205,12 +205,11 @@ License: Apache License
|
|
|
205
205
|
See the License for the specific language governing permissions and
|
|
206
206
|
limitations under the License.
|
|
207
207
|
Classifier: License :: OSI Approved :: Apache Software License
|
|
208
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
209
208
|
Classifier: Programming Language :: Python :: 3.10
|
|
210
209
|
Classifier: Programming Language :: Python :: 3.11
|
|
211
210
|
Classifier: Programming Language :: Python :: 3.12
|
|
212
211
|
Classifier: Programming Language :: Python :: 3.13
|
|
213
|
-
Requires-Python: >=3.
|
|
212
|
+
Requires-Python: >=3.10
|
|
214
213
|
Description-Content-Type: text/markdown
|
|
215
214
|
License-File: LICENSE.md
|
|
216
215
|
Requires-Dist: pydantic>=2.11.5
|
|
@@ -226,14 +225,22 @@ Dynamic: license-file
|
|
|
226
225
|
<img align="center" src="docs/assets/relai-logo.png" width="460px" />
|
|
227
226
|
</p>
|
|
228
227
|
<p align="left">
|
|
229
|
-
<h1 align="center">
|
|
228
|
+
<h1 align="center">Simulate → Evaluate → Optimize AI Agents</h1>
|
|
229
|
+
<p align="center">
|
|
230
|
+
<a href="https://pypi.org/project/relai/"><img alt="PyPI" src="https://img.shields.io/pypi/v/relai.svg"></a>
|
|
231
|
+
<img alt="Python" src="https://img.shields.io/pypi/pyversions/relai.svg">
|
|
232
|
+
<a href="LICENSE.md"><img alt="License" src="https://img.shields.io/badge/license-Apache--2.0-blue.svg"></a>
|
|
233
|
+
<a href="http://docs.relai.ai"><img alt="Docs" src="https://img.shields.io/badge/docs-online-brightgreen.svg"></a>
|
|
234
|
+
<a href="https://github.com/relai-ai/relai-sdk/actions/workflows/upload-to-package-index.yml"><img alt="CI" src="https://img.shields.io/github/actions/workflow/status/relai-ai/relai-sdk/upload-to-package-index.yml?branch=main"></a>
|
|
235
|
+
</p>
|
|
236
|
+
|
|
230
237
|
|
|
231
238
|
**RELAI** is an SDK for building **reliable AI agents**. It streamlines the hardest parts of agent development—**simulation**, **evaluation**, and **optimization**—so you can iterate quickly with confidence.
|
|
232
239
|
|
|
233
240
|
**What you get**
|
|
234
|
-
- **Agent Simulation** — Create full/partial environments, define
|
|
235
|
-
- **Agent Evaluation** — Mix
|
|
236
|
-
- **Agent Optimization (Maestro)** — Holistic optimizer that uses evaluator signals & feedback to improve prompts/configs
|
|
241
|
+
- **Agent Simulation** — Create full/partial environments, define LLM personas, mock MCP servers & tools, and generate synthetic data. Optionally condition simulation on real samples to better match production.
|
|
242
|
+
- **Agent Evaluation** — Mix code-based and LLM-based custom evaluators or use RELAI platform evaluators. Turn human reviews into benchmarks you can re-run.
|
|
243
|
+
- **Agent Optimization (Maestro)** — Holistic optimizer that uses evaluator signals & feedback to improve **prompts/configs** and suggest **graph-level** changes. Maestro selects best model/tool/graph based on observed performance.
|
|
237
244
|
|
|
238
245
|
## Quickstart
|
|
239
246
|
|
|
@@ -249,9 +256,153 @@ uv add relai
|
|
|
249
256
|
export RELAI_API_KEY="<RELAI_API_KEY>"
|
|
250
257
|
```
|
|
251
258
|
|
|
259
|
+
### Example: A simple Stock Assistant Agent (Simulate → Evaluate → Optimize)
|
|
260
|
+
Prerequisites: Needs an OpenAI API key and `openai-agents` installed to run the base agent.
|
|
261
|
+
To use Maestro graph optimizer, save the following in a file called `stock-assistant.py` (or change the `code_paths` argument to `maestro.optimize_structure`).
|
|
262
|
+
```python
|
|
263
|
+
# ============================================================================
|
|
264
|
+
# STEP 0 — Prerequisites
|
|
265
|
+
# ============================================================================
|
|
266
|
+
# export OPENAI_API_KEY="sk-..."
|
|
267
|
+
# `uv add openai-agents`
|
|
268
|
+
# export RELAI_API_KEY="relai-..."
|
|
269
|
+
# Save as `stock-assistant.py`
|
|
270
|
+
|
|
271
|
+
import asyncio
|
|
272
|
+
|
|
273
|
+
from agents import Agent, Runner
|
|
274
|
+
|
|
275
|
+
from relai import (
|
|
276
|
+
AgentOutputs,
|
|
277
|
+
AsyncRELAI,
|
|
278
|
+
AsyncSimulator,
|
|
279
|
+
SimulationTape,
|
|
280
|
+
random_env_generator,
|
|
281
|
+
)
|
|
282
|
+
from relai.critico import Critico
|
|
283
|
+
from relai.critico.evaluate import RELAIFormatEvaluator
|
|
284
|
+
from relai.maestro import Maestro, params, register_param
|
|
285
|
+
from relai.mocker import Persona
|
|
286
|
+
from relai.simulator import simulated
|
|
287
|
+
|
|
288
|
+
# ============================================================================
|
|
289
|
+
# STEP 1.1 — Decorate inputs/tools that will be simulated
|
|
290
|
+
# ============================================================================
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
@simulated
|
|
294
|
+
async def get_user_query() -> str:
|
|
295
|
+
"""Get user's query about stock prices."""
|
|
296
|
+
# In a real agent, this function might get input from a chat interface.
|
|
297
|
+
return input("Enter you stock query: ")
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
# ============================================================================
|
|
301
|
+
# STEP 1.2 — Register parameters for optimization
|
|
302
|
+
# ============================================================================
|
|
303
|
+
|
|
304
|
+
register_param(
|
|
305
|
+
"prompt",
|
|
306
|
+
type="prompt",
|
|
307
|
+
init_value="You are a helpful assistant for stock price questions.",
|
|
308
|
+
desc="system prompt for the agent",
|
|
309
|
+
)
|
|
310
|
+
|
|
311
|
+
# ============================================================================
|
|
312
|
+
# STEP 2 — Your agent core
|
|
313
|
+
# ============================================================================
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
async def agent_fn(tape: SimulationTape) -> AgentOutputs:
|
|
317
|
+
question = await get_user_query()
|
|
318
|
+
agent = Agent(
|
|
319
|
+
name="Stock assistant",
|
|
320
|
+
instructions=params.prompt, # access registered parameter
|
|
321
|
+
model="gpt-5-mini",
|
|
322
|
+
)
|
|
323
|
+
result = await Runner.run(agent, question)
|
|
324
|
+
tape.extras["format_rubrics"] = {"Prices must include cents (eg: $XXX.XX)": 1.0}
|
|
325
|
+
tape.agent_inputs["question"] = question # trace inputs for later auditing
|
|
326
|
+
return {"summary": result.final_output}
|
|
327
|
+
|
|
328
|
+
|
|
329
|
+
async def main() -> None:
|
|
330
|
+
# Set up your simulation environment
|
|
331
|
+
# Bind Personas/MockTools to fully-qualified function names
|
|
332
|
+
env_generator = random_env_generator(
|
|
333
|
+
config_set={
|
|
334
|
+
"__main__.get_user_query": [Persona(user_persona="A polite and curious user.")],
|
|
335
|
+
}
|
|
336
|
+
)
|
|
337
|
+
|
|
338
|
+
async with AsyncRELAI() as client:
|
|
339
|
+
# ============================================================================
|
|
340
|
+
# STEP 3 — Simulate
|
|
341
|
+
# ============================================================================
|
|
342
|
+
simulator = AsyncSimulator(agent_fn=agent_fn, env_generator=env_generator, client=client)
|
|
343
|
+
agent_logs = await simulator.run(num_runs=1)
|
|
344
|
+
|
|
345
|
+
# ============================================================================
|
|
346
|
+
# STEP 4 — Evaluate with Critico
|
|
347
|
+
# ============================================================================
|
|
348
|
+
critico = Critico(client=client)
|
|
349
|
+
format_evaluator = RELAIFormatEvaluator(client=client)
|
|
350
|
+
critico.add_evaluators({format_evaluator: 1.0})
|
|
351
|
+
critico_logs = await critico.evaluate(agent_logs)
|
|
352
|
+
|
|
353
|
+
# Publish evaluation report to the RELAI platform
|
|
354
|
+
await critico.report(critico_logs)
|
|
355
|
+
|
|
356
|
+
maestro = Maestro(client=client, agent_fn=agent_fn, log_to_platform=True, name="Stock assistant")
|
|
357
|
+
maestro.add_setup(simulator=simulator, critico=critico)
|
|
358
|
+
|
|
359
|
+
# ============================================================================
|
|
360
|
+
# STEP 5.1 — Optimize configs with Maestro (the parameters registered earlier in STEP 2)
|
|
361
|
+
# ============================================================================
|
|
362
|
+
|
|
363
|
+
# params.load("saved_config.json") # load previous params if available
|
|
364
|
+
await maestro.optimize_config(
|
|
365
|
+
total_rollouts=20, # Total number of rollouts to use for optimization.
|
|
366
|
+
batch_size=1, # Base batch size to use for individual optimization steps. Defaults to 4.
|
|
367
|
+
explore_radius=1, # A positive integer controlling the aggressiveness of exploration during optimization.
|
|
368
|
+
explore_factor=0.5, # A float between 0 to 1 controlling the exploration-exploitation trade-off.
|
|
369
|
+
verbose=True, # If True, related information will be printed during the optimization step.
|
|
370
|
+
)
|
|
371
|
+
params.save("saved_config.json") # save optimized params for future usage
|
|
372
|
+
|
|
373
|
+
# ============================================================================
|
|
374
|
+
# STEP 5.2 — Optimize agent structure with Maestro (changes that cannot be achieved by setting parameters alone)
|
|
375
|
+
# ============================================================================
|
|
376
|
+
|
|
377
|
+
await maestro.optimize_structure(
|
|
378
|
+
total_rollouts=10, # Total number of rollouts to use for optimization.
|
|
379
|
+
code_paths=["stock-assistant.py"], # A list of paths corresponding to code implementations of the agent.
|
|
380
|
+
verbose=True, # If True, related information will be printed during the optimization step.
|
|
381
|
+
)
|
|
382
|
+
|
|
383
|
+
|
|
384
|
+
if __name__ == "__main__":
|
|
385
|
+
asyncio.run(main())
|
|
386
|
+
|
|
387
|
+
```
|
|
388
|
+
## Simulation
|
|
389
|
+
Create controlled environments where agents interact and generate traces. Compose LLM personas, mock MCP tools/servers, and synthetic data; optionally condition on real events to align simulation ⇄ production.
|
|
390
|
+
|
|
391
|
+
➡️ Learn more: [Simulator](https://docs.relai.ai/simulator.html)
|
|
392
|
+
|
|
393
|
+
## Evaluation (Critico)
|
|
394
|
+
Use code-based or LLM-based evaluators—or RELAI platform evaluators—and convert human reviews into benchmarks you can re-run in Simuation/CI pipeline.
|
|
395
|
+
|
|
396
|
+
➡️ Learn more: [Evaluator](https://docs.relai.ai/evaluator.html)
|
|
397
|
+
|
|
398
|
+
## Optimization (Maestro)
|
|
399
|
+
Maestro is a holistic agent optimizer. It consumes evaluator/user feedback to improve prompts, configs, and even graph structure when prompt tuning isn’t enough. It can also select the best model, best tool, and best graph based on observed performance.
|
|
400
|
+
|
|
401
|
+
➡️ Learn more: [Maestro](https://docs.relai.ai/maestro.html)
|
|
402
|
+
|
|
252
403
|
## Links
|
|
253
404
|
|
|
254
|
-
- 📘 **Documentation:** [docs.relai.ai](
|
|
405
|
+
- 📘 **Documentation:** [docs.relai.ai](http://docs.relai.ai)
|
|
255
406
|
- 🧪 **Examples:** [relai-sdk/examples](examples)
|
|
256
407
|
- 🌐 **Website:** [relai.ai](https://relai.ai)
|
|
257
408
|
- 📰 **Maestro Technical Report:** [ArXiV](https://arxiv.org/abs/2509.04642)
|
|
@@ -260,3 +411,30 @@ export RELAI_API_KEY="<RELAI_API_KEY>"
|
|
|
260
411
|
## License
|
|
261
412
|
|
|
262
413
|
Apache 2.0
|
|
414
|
+
|
|
415
|
+
## Citation
|
|
416
|
+
If you use the SDK in your research, please consider citing our work:
|
|
417
|
+
|
|
418
|
+
```
|
|
419
|
+
@misc{relai_sdk,
|
|
420
|
+
author = {RELAI, Inc.,},
|
|
421
|
+
title = {relai-sdk},
|
|
422
|
+
year = {2025},
|
|
423
|
+
howpublished = {\url{https://github.com/relai-ai/relai-sdk}},
|
|
424
|
+
note = {GitHub repository},
|
|
425
|
+
urldate = {2025-10-20}
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
@misc{wang2025maestrojointgraph,
|
|
429
|
+
title={Maestro: Joint Graph & Config Optimization for Reliable AI Agents},
|
|
430
|
+
author={Wenxiao Wang and Priyatham Kattakinda and Soheil Feizi},
|
|
431
|
+
year={2025},
|
|
432
|
+
eprint={2509.04642},
|
|
433
|
+
archivePrefix={arXiv},
|
|
434
|
+
primaryClass={cs.AI},
|
|
435
|
+
url={https://arxiv.org/abs/2509.04642},
|
|
436
|
+
}
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
<p align="center"> <sub>Made with ❤️ by the RELAI team — <a href="https://relai.ai">relai.ai</a> • <a href="https://discord.gg/sjaHJ34YYE">Community</a></sub> </p>
|
|
440
|
+
|
relai-0.3.3/README.md
ADDED
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img align="center" src="docs/assets/relai-logo.png" width="460px" />
|
|
3
|
+
</p>
|
|
4
|
+
<p align="left">
|
|
5
|
+
<h1 align="center">Simulate → Evaluate → Optimize AI Agents</h1>
|
|
6
|
+
<p align="center">
|
|
7
|
+
<a href="https://pypi.org/project/relai/"><img alt="PyPI" src="https://img.shields.io/pypi/v/relai.svg"></a>
|
|
8
|
+
<img alt="Python" src="https://img.shields.io/pypi/pyversions/relai.svg">
|
|
9
|
+
<a href="LICENSE.md"><img alt="License" src="https://img.shields.io/badge/license-Apache--2.0-blue.svg"></a>
|
|
10
|
+
<a href="http://docs.relai.ai"><img alt="Docs" src="https://img.shields.io/badge/docs-online-brightgreen.svg"></a>
|
|
11
|
+
<a href="https://github.com/relai-ai/relai-sdk/actions/workflows/upload-to-package-index.yml"><img alt="CI" src="https://img.shields.io/github/actions/workflow/status/relai-ai/relai-sdk/upload-to-package-index.yml?branch=main"></a>
|
|
12
|
+
</p>
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
**RELAI** is an SDK for building **reliable AI agents**. It streamlines the hardest parts of agent development—**simulation**, **evaluation**, and **optimization**—so you can iterate quickly with confidence.
|
|
16
|
+
|
|
17
|
+
**What you get**
|
|
18
|
+
- **Agent Simulation** — Create full/partial environments, define LLM personas, mock MCP servers & tools, and generate synthetic data. Optionally condition simulation on real samples to better match production.
|
|
19
|
+
- **Agent Evaluation** — Mix code-based and LLM-based custom evaluators or use RELAI platform evaluators. Turn human reviews into benchmarks you can re-run.
|
|
20
|
+
- **Agent Optimization (Maestro)** — Holistic optimizer that uses evaluator signals & feedback to improve **prompts/configs** and suggest **graph-level** changes. Maestro selects best model/tool/graph based on observed performance.
|
|
21
|
+
|
|
22
|
+
## Quickstart
|
|
23
|
+
|
|
24
|
+
Create a free account and get a RELAI API key: [platform.relai.ai/settings/access/api-keys](https://platform.relai.ai/settings/access/api-keys)
|
|
25
|
+
|
|
26
|
+
### Installation and Setup
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
pip install relai
|
|
30
|
+
# or
|
|
31
|
+
uv add relai
|
|
32
|
+
|
|
33
|
+
export RELAI_API_KEY="<RELAI_API_KEY>"
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Example: A simple Stock Assistant Agent (Simulate → Evaluate → Optimize)
|
|
37
|
+
Prerequisites: Needs an OpenAI API key and `openai-agents` installed to run the base agent.
|
|
38
|
+
To use Maestro graph optimizer, save the following in a file called `stock-assistant.py` (or change the `code_paths` argument to `maestro.optimize_structure`).
|
|
39
|
+
```python
|
|
40
|
+
# ============================================================================
|
|
41
|
+
# STEP 0 — Prerequisites
|
|
42
|
+
# ============================================================================
|
|
43
|
+
# export OPENAI_API_KEY="sk-..."
|
|
44
|
+
# `uv add openai-agents`
|
|
45
|
+
# export RELAI_API_KEY="relai-..."
|
|
46
|
+
# Save as `stock-assistant.py`
|
|
47
|
+
|
|
48
|
+
import asyncio
|
|
49
|
+
|
|
50
|
+
from agents import Agent, Runner
|
|
51
|
+
|
|
52
|
+
from relai import (
|
|
53
|
+
AgentOutputs,
|
|
54
|
+
AsyncRELAI,
|
|
55
|
+
AsyncSimulator,
|
|
56
|
+
SimulationTape,
|
|
57
|
+
random_env_generator,
|
|
58
|
+
)
|
|
59
|
+
from relai.critico import Critico
|
|
60
|
+
from relai.critico.evaluate import RELAIFormatEvaluator
|
|
61
|
+
from relai.maestro import Maestro, params, register_param
|
|
62
|
+
from relai.mocker import Persona
|
|
63
|
+
from relai.simulator import simulated
|
|
64
|
+
|
|
65
|
+
# ============================================================================
|
|
66
|
+
# STEP 1.1 — Decorate inputs/tools that will be simulated
|
|
67
|
+
# ============================================================================
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
@simulated
|
|
71
|
+
async def get_user_query() -> str:
|
|
72
|
+
"""Get user's query about stock prices."""
|
|
73
|
+
# In a real agent, this function might get input from a chat interface.
|
|
74
|
+
return input("Enter you stock query: ")
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
# ============================================================================
|
|
78
|
+
# STEP 1.2 — Register parameters for optimization
|
|
79
|
+
# ============================================================================
|
|
80
|
+
|
|
81
|
+
register_param(
|
|
82
|
+
"prompt",
|
|
83
|
+
type="prompt",
|
|
84
|
+
init_value="You are a helpful assistant for stock price questions.",
|
|
85
|
+
desc="system prompt for the agent",
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
# ============================================================================
|
|
89
|
+
# STEP 2 — Your agent core
|
|
90
|
+
# ============================================================================
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
async def agent_fn(tape: SimulationTape) -> AgentOutputs:
|
|
94
|
+
question = await get_user_query()
|
|
95
|
+
agent = Agent(
|
|
96
|
+
name="Stock assistant",
|
|
97
|
+
instructions=params.prompt, # access registered parameter
|
|
98
|
+
model="gpt-5-mini",
|
|
99
|
+
)
|
|
100
|
+
result = await Runner.run(agent, question)
|
|
101
|
+
tape.extras["format_rubrics"] = {"Prices must include cents (eg: $XXX.XX)": 1.0}
|
|
102
|
+
tape.agent_inputs["question"] = question # trace inputs for later auditing
|
|
103
|
+
return {"summary": result.final_output}
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
async def main() -> None:
|
|
107
|
+
# Set up your simulation environment
|
|
108
|
+
# Bind Personas/MockTools to fully-qualified function names
|
|
109
|
+
env_generator = random_env_generator(
|
|
110
|
+
config_set={
|
|
111
|
+
"__main__.get_user_query": [Persona(user_persona="A polite and curious user.")],
|
|
112
|
+
}
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
async with AsyncRELAI() as client:
|
|
116
|
+
# ============================================================================
|
|
117
|
+
# STEP 3 — Simulate
|
|
118
|
+
# ============================================================================
|
|
119
|
+
simulator = AsyncSimulator(agent_fn=agent_fn, env_generator=env_generator, client=client)
|
|
120
|
+
agent_logs = await simulator.run(num_runs=1)
|
|
121
|
+
|
|
122
|
+
# ============================================================================
|
|
123
|
+
# STEP 4 — Evaluate with Critico
|
|
124
|
+
# ============================================================================
|
|
125
|
+
critico = Critico(client=client)
|
|
126
|
+
format_evaluator = RELAIFormatEvaluator(client=client)
|
|
127
|
+
critico.add_evaluators({format_evaluator: 1.0})
|
|
128
|
+
critico_logs = await critico.evaluate(agent_logs)
|
|
129
|
+
|
|
130
|
+
# Publish evaluation report to the RELAI platform
|
|
131
|
+
await critico.report(critico_logs)
|
|
132
|
+
|
|
133
|
+
maestro = Maestro(client=client, agent_fn=agent_fn, log_to_platform=True, name="Stock assistant")
|
|
134
|
+
maestro.add_setup(simulator=simulator, critico=critico)
|
|
135
|
+
|
|
136
|
+
# ============================================================================
|
|
137
|
+
# STEP 5.1 — Optimize configs with Maestro (the parameters registered earlier in STEP 2)
|
|
138
|
+
# ============================================================================
|
|
139
|
+
|
|
140
|
+
# params.load("saved_config.json") # load previous params if available
|
|
141
|
+
await maestro.optimize_config(
|
|
142
|
+
total_rollouts=20, # Total number of rollouts to use for optimization.
|
|
143
|
+
batch_size=1, # Base batch size to use for individual optimization steps. Defaults to 4.
|
|
144
|
+
explore_radius=1, # A positive integer controlling the aggressiveness of exploration during optimization.
|
|
145
|
+
explore_factor=0.5, # A float between 0 to 1 controlling the exploration-exploitation trade-off.
|
|
146
|
+
verbose=True, # If True, related information will be printed during the optimization step.
|
|
147
|
+
)
|
|
148
|
+
params.save("saved_config.json") # save optimized params for future usage
|
|
149
|
+
|
|
150
|
+
# ============================================================================
|
|
151
|
+
# STEP 5.2 — Optimize agent structure with Maestro (changes that cannot be achieved by setting parameters alone)
|
|
152
|
+
# ============================================================================
|
|
153
|
+
|
|
154
|
+
await maestro.optimize_structure(
|
|
155
|
+
total_rollouts=10, # Total number of rollouts to use for optimization.
|
|
156
|
+
code_paths=["stock-assistant.py"], # A list of paths corresponding to code implementations of the agent.
|
|
157
|
+
verbose=True, # If True, related information will be printed during the optimization step.
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
if __name__ == "__main__":
|
|
162
|
+
asyncio.run(main())
|
|
163
|
+
|
|
164
|
+
```
|
|
165
|
+
## Simulation
|
|
166
|
+
Create controlled environments where agents interact and generate traces. Compose LLM personas, mock MCP tools/servers, and synthetic data; optionally condition on real events to align simulation ⇄ production.
|
|
167
|
+
|
|
168
|
+
➡️ Learn more: [Simulator](https://docs.relai.ai/simulator.html)
|
|
169
|
+
|
|
170
|
+
## Evaluation (Critico)
|
|
171
|
+
Use code-based or LLM-based evaluators—or RELAI platform evaluators—and convert human reviews into benchmarks you can re-run in Simuation/CI pipeline.
|
|
172
|
+
|
|
173
|
+
➡️ Learn more: [Evaluator](https://docs.relai.ai/evaluator.html)
|
|
174
|
+
|
|
175
|
+
## Optimization (Maestro)
|
|
176
|
+
Maestro is a holistic agent optimizer. It consumes evaluator/user feedback to improve prompts, configs, and even graph structure when prompt tuning isn’t enough. It can also select the best model, best tool, and best graph based on observed performance.
|
|
177
|
+
|
|
178
|
+
➡️ Learn more: [Maestro](https://docs.relai.ai/maestro.html)
|
|
179
|
+
|
|
180
|
+
## Links
|
|
181
|
+
|
|
182
|
+
- 📘 **Documentation:** [docs.relai.ai](http://docs.relai.ai)
|
|
183
|
+
- 🧪 **Examples:** [relai-sdk/examples](examples)
|
|
184
|
+
- 🌐 **Website:** [relai.ai](https://relai.ai)
|
|
185
|
+
- 📰 **Maestro Technical Report:** [ArXiV](https://arxiv.org/abs/2509.04642)
|
|
186
|
+
- 🌐 **Join the Community:** [Discord](https://discord.gg/sjaHJ34YYE)
|
|
187
|
+
|
|
188
|
+
## License
|
|
189
|
+
|
|
190
|
+
Apache 2.0
|
|
191
|
+
|
|
192
|
+
## Citation
|
|
193
|
+
If you use the SDK in your research, please consider citing our work:
|
|
194
|
+
|
|
195
|
+
```
|
|
196
|
+
@misc{relai_sdk,
|
|
197
|
+
author = {RELAI, Inc.,},
|
|
198
|
+
title = {relai-sdk},
|
|
199
|
+
year = {2025},
|
|
200
|
+
howpublished = {\url{https://github.com/relai-ai/relai-sdk}},
|
|
201
|
+
note = {GitHub repository},
|
|
202
|
+
urldate = {2025-10-20}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
@misc{wang2025maestrojointgraph,
|
|
206
|
+
title={Maestro: Joint Graph & Config Optimization for Reliable AI Agents},
|
|
207
|
+
author={Wenxiao Wang and Priyatham Kattakinda and Soheil Feizi},
|
|
208
|
+
year={2025},
|
|
209
|
+
eprint={2509.04642},
|
|
210
|
+
archivePrefix={arXiv},
|
|
211
|
+
primaryClass={cs.AI},
|
|
212
|
+
url={https://arxiv.org/abs/2509.04642},
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
<p align="center"> <sub>Made with ❤️ by the RELAI team — <a href="https://relai.ai">relai.ai</a> • <a href="https://discord.gg/sjaHJ34YYE">Community</a></sub> </p>
|
|
217
|
+
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "relai"
|
|
7
|
-
requires-python = ">=3.
|
|
7
|
+
requires-python = ">=3.10"
|
|
8
8
|
authors = [
|
|
9
9
|
{name = "RELAI", email = "priyatham@relai.ai"},
|
|
10
10
|
{name = "RELAI", email = "wwx@relai.ai"},
|
|
@@ -14,7 +14,6 @@ readme = "README.md"
|
|
|
14
14
|
license = {file = "LICENSE.md" }
|
|
15
15
|
classifiers = [
|
|
16
16
|
"License :: OSI Approved :: Apache Software License",
|
|
17
|
-
"Programming Language :: Python :: 3.9",
|
|
18
17
|
"Programming Language :: Python :: 3.10",
|
|
19
18
|
"Programming Language :: Python :: 3.11",
|
|
20
19
|
"Programming Language :: Python :: 3.12",
|
|
@@ -30,7 +29,7 @@ dependencies = [
|
|
|
30
29
|
"opentelemetry-instrumentation>=0.58b0",
|
|
31
30
|
"openinference-instrumentation>=0.1.38",
|
|
32
31
|
]
|
|
33
|
-
version = "0.3.
|
|
32
|
+
version = "0.3.3"
|
|
34
33
|
|
|
35
34
|
[tool.setuptools.packages.find]
|
|
36
35
|
where = ["."]
|
|
@@ -40,6 +39,8 @@ include = ["relai*"]
|
|
|
40
39
|
dev = [
|
|
41
40
|
"build>=1.3.0",
|
|
42
41
|
"google-genai>=1.45.0",
|
|
42
|
+
"langchain>=1.0.1",
|
|
43
|
+
"langgraph>=1.0.1",
|
|
43
44
|
"mkdocs>=1.6.1",
|
|
44
45
|
"mkdocs-material>=9.6.14",
|
|
45
46
|
"mkdocstrings[python]>=0.29.1",
|
|
@@ -31,8 +31,11 @@ def flatten(mapping: Mapping[str, Any]) -> Iterator[tuple[str, AttributeValue]]:
|
|
|
31
31
|
yield f"{key}.{sub_key}", sub_value
|
|
32
32
|
elif isinstance(value, list) and any(isinstance(item, Mapping) for item in value):
|
|
33
33
|
for index, sub_mapping in enumerate(value):
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
if isinstance(sub_mapping, Mapping):
|
|
35
|
+
for sub_key, sub_value in flatten(sub_mapping):
|
|
36
|
+
yield f"{key}.{index}.{sub_key}", sub_value
|
|
37
|
+
else:
|
|
38
|
+
yield f"{key}.{index}", sub_mapping
|
|
36
39
|
else:
|
|
37
40
|
if isinstance(value, Enum):
|
|
38
41
|
value = value.value
|