helios-engine 0.5.5

A powerful and flexible Rust framework for building LLM-powered agents with tool support, both locally and online
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
# ReAct (Reasoning and Acting)

ReAct is a powerful feature in Helios Engine that enables agents to reason about tasks before taking actions. This pattern leads to more thoughtful, systematic problem-solving and makes the agent's decision-making process transparent.

## What is ReAct?

ReAct (Reasoning and Acting) is a pattern where the agent follows a two-phase approach:

1. **💭 Reasoning Phase**: The agent analyzes the task, identifies what's needed, and creates a plan
2. **⚡ Action Phase**: The agent executes the plan using available tools

This separation helps agents handle complex, multi-step tasks more effectively and provides visibility into their thinking process.

## Enabling ReAct Mode

Enabling ReAct is incredibly simple - just add `.react()` to your agent builder:

```rust
use helios_engine::{Agent, Config, CalculatorTool};

#[tokio::main]
async fn main() -> helios_engine::Result<()> {
    let config = Config::from_file("config.toml")?;
    
    let mut agent = Agent::builder("ReActAgent")
        .config(config)
        .tool(Box::new(CalculatorTool))
        .react()  // ✨ Enable ReAct mode
        .build()
        .await?;
    
    let response = agent.chat("Calculate (25 * 4) + (100 / 5)").await?;
    println!("{}", response);
    
    Ok(())
}
```

## How It Works

When you send a message to a ReAct-enabled agent, here's what happens:

```
User Query: "Calculate (25 * 4) + (100 / 5)"

💭 Reasoning Phase:
   Agent thinks: "I need to:
   1. Calculate 25 * 4 = 100
   2. Calculate 100 / 5 = 20
   3. Add the results: 100 + 20 = 120"
   
⚡ Action Phase:
   - Uses calculator tool: 25 * 4 → 100
   - Uses calculator tool: 100 / 5 → 20
   - Uses calculator tool: 100 + 20 → 120
   
Response: "The result is 120"
```

The reasoning is displayed with a `💭 ReAct Reasoning:` prefix, making it easy to follow the agent's thought process.

## Custom Reasoning Prompts

For domain-specific tasks, you can customize the reasoning prompt:

```rust
use helios_engine::{Agent, Config, CalculatorTool};

#[tokio::main]
async fn main() -> helios_engine::Result<()> {
    let config = Config::from_file("config.toml")?;
    
    let math_prompt = r#"As a mathematical problem solver:
1. Identify the mathematical operations needed
2. Break down complex calculations into steps
3. Determine the order of operations (PEMDAS)
4. Plan which calculator functions to use
5. Verify the logic of your approach

Provide clear mathematical reasoning."#;
    
    let mut agent = Agent::builder("MathExpert")
        .config(config)
        .system_prompt("You are a mathematics expert.")
        .tool(Box::new(CalculatorTool))
        .react_with_prompt(math_prompt)  // 🎯 Custom reasoning
        .build()
        .await?;
    
    let response = agent.chat("Calculate ((15 * 8) + (20 * 3)) / 2").await?;
    println!("{}", response);
    
    Ok(())
}
```

## When to Use ReAct

###  Use ReAct When:

- **Complex Multi-Step Tasks**: Tasks that require planning and coordination
- **Debugging**: When you want to see how the agent approaches problems
- **Critical Operations**: When accuracy is more important than speed
- **Learning**: Understanding agent behavior and decision-making
- **Domain-Specific Tasks**: With custom prompts for specialized reasoning

### ❌ Don't Use ReAct When:

- **Simple Queries**: Straightforward tasks where reasoning adds unnecessary overhead
- **Speed Critical**: Applications where latency is paramount
- **No Tools Available**: ReAct is designed for tool-using agents
- **High-Volume Operations**: When the extra LLM call impacts throughput

## Examples

### Example 1: Basic ReAct Agent

```rust
use helios_engine::{Agent, Config, CalculatorTool, EchoTool};

#[tokio::main]
async fn main() -> helios_engine::Result<()> {
    let config = Config::from_file("config.toml")?;
    
    let mut agent = Agent::builder("Assistant")
        .config(config)
        .tools(vec![
            Box::new(CalculatorTool),
            Box::new(EchoTool),
        ])
        .react()
        .build()
        .await?;
    
    // Multi-step task
    let response = agent
        .chat("Calculate 15 * 7, then echo the result")
        .await?;
    println!("{}", response);
    
    Ok(())
}
```

### Example 2: Domain-Specific Reasoning

```rust
use helios_engine::{Agent, Config, FileReadTool, CalculatorTool};

#[tokio::main]
async fn main() -> helios_engine::Result<()> {
    let config = Config::from_file("config.toml")?;
    
    let data_analysis_prompt = r#"As a data analyst:
1. UNDERSTAND: What data am I working with?
2. EXTRACT: What information do I need?
3. PROCESS: What calculations are required?
4. TOOLS: Which tools should I use?
5. OUTPUT: How should I present the result?

Think through the data pipeline systematically."#;
    
    let mut analyst = Agent::builder("DataAnalyst")
        .config(config)
        .system_prompt("You are a data analysis expert.")
        .tools(vec![
            Box::new(FileReadTool),
            Box::new(CalculatorTool),
        ])
        .react_with_prompt(data_analysis_prompt)
        .build()
        .await?;
    
    let response = analyst
        .chat("Analyze the numbers: 10, 20, 30, 40, 50. Calculate their average.")
        .await?;
    println!("{}", response);
    
    Ok(())
}
```

### Example 3: Comparing With and Without ReAct

```rust
use helios_engine::{Agent, Config, CalculatorTool};

#[tokio::main]
async fn main() -> helios_engine::Result<()> {
    let config1 = Config::from_file("config.toml")?;
    let config2 = Config::from_file("config.toml")?;
    
    // Standard agent
    let mut standard = Agent::builder("Standard")
        .config(config1)
        .tool(Box::new(CalculatorTool))
        .build()
        .await?;
    
    // ReAct agent
    let mut react = Agent::builder("ReAct")
        .config(config2)
        .tool(Box::new(CalculatorTool))
        .react()
        .build()
        .await?;
    
    let query = "Calculate (15 * 3) + (20 * 2)";
    
    println!("Standard agent:");
    let r1 = standard.chat(query).await?;
    println!("{}\n", r1);
    
    println!("ReAct agent:");
    let r2 = react.chat(query).await?;
    println!("{}\n", r2);
    
    Ok(())
}
```

## Builder Methods

### `.react()`

Enables ReAct mode with the default reasoning prompt.

```rust
let agent = Agent::builder("MyAgent")
    .config(config)
    .react()
    .build()
    .await?;
```

### `.react_with_prompt(prompt)`

Enables ReAct mode with a custom reasoning prompt.

```rust
let custom_prompt = "Think step by step about this problem...";

let agent = Agent::builder("MyAgent")
    .config(config)
    .react_with_prompt(custom_prompt)
    .build()
    .await?;
```

Both methods can be placed anywhere in the builder chain:

```rust
// Before tools
let agent = Agent::builder("Agent")
    .config(config)
    .react()
    .tool(Box::new(CalculatorTool))
    .build()
    .await?;

// After tools
let agent = Agent::builder("Agent")
    .config(config)
    .tool(Box::new(CalculatorTool))
    .react()
    .build()
    .await?;
```

## Performance Considerations

### Latency

ReAct adds one extra LLM call for reasoning:

- **Without ReAct**: 1 LLM call + tool executions
- **With ReAct**: 2 LLM calls + tool executions

**Impact**: Approximately 1-2 seconds additional latency (varies by model)

### Token Usage

Additional tokens are consumed for:
- Reasoning prompt: ~50 tokens
- Reasoning response: ~100-300 tokens
- Context storage: ~100-300 tokens

**Impact**: ~250-650 additional tokens per query

### Optimization Tips

For applications where performance matters:

```rust
// Use ReAct selectively
if query_is_complex {
    react_agent.chat(query).await?
} else {
    standard_agent.chat(query).await?
}

// Or create specialized agents
let quick_agent = Agent::builder("Quick")
    .config(config)
    .build()
    .await?;

let thinking_agent = Agent::builder("Thinker")
    .config(config)
    .react()
    .build()
    .await?;
```

## Benefits

### 1. Better Accuracy
Thinking before acting reduces errors and improves decision quality.

### 2. Transparency
See exactly how the agent approaches problems, making debugging easier.

### 3. Complex Task Handling
Multi-step problems are handled more systematically with clear planning.

### 4. Explainability
Understand agent reasoning for compliance, auditing, or learning purposes.

### 5. Domain Adaptation
Custom prompts tailor reasoning to specific domains or tasks.

## Best Practices

### 1. Use Descriptive System Prompts

```rust
.system_prompt("You are a methodical assistant who thinks through problems carefully.")
```

### 2. Combine with Appropriate Tools

```rust
.tools(vec![
    Box::new(CalculatorTool),
    Box::new(FileReadTool),
    Box::new(JsonParserTool),
])
.react()
```

### 3. Set Reasonable Iteration Limits

```rust
.max_iterations(15)  // Allow enough steps for complex reasoning
.react()
```

### 4. Monitor Reasoning Output

Watch the `💭 ReAct Reasoning:` output to understand agent behavior and optimize prompts.

### 5. Use Custom Prompts for Specific Domains

Tailor the reasoning prompt to match your use case (mathematics, data analysis, planning, etc.).

## Troubleshooting

### Reasoning Not Showing

**Problem**: No reasoning output visible

**Solution**: 
- Ensure `.react()` or `.react_with_prompt()` is called
- Verify the agent has tools registered
- Check stdout for `💭 ReAct Reasoning:` prefix

### Too Much Overhead

**Problem**: ReAct adds too much latency

**Solution**:
- Use ReAct selectively for complex tasks only
- Consider disabling for simple queries
- Use faster models for reasoning phase

### Poor Reasoning Quality

**Problem**: Agent reasoning is unclear or unhelpful

**Solution**:
- Improve the system prompt to encourage better thinking
- Use more capable models (e.g., GPT-4 vs GPT-3.5)
- Create custom reasoning prompts with examples
- Adjust the prompt structure for your specific domain

## Next Steps

- Check out the [examples directory]../examples/overview.md for complete working examples
- See [react_agent.rs]https://github.com/Ammar-Alnagar/Helios-Engine/blob/main/examples/react_agent.rs for a basic demo
- See [react_custom_prompt.rs]https://github.com/Ammar-Alnagar/Helios-Engine/blob/main/examples/react_custom_prompt.rs for domain-specific examples
- Read the [Tools documentation]../tools/using_tools.md to learn about available tools

## Summary

ReAct mode enables agents to think before acting, leading to:
- 🎯 More accurate results
- 👁️ Transparent decision-making
- 🧩 Better handling of complex tasks
- 🔧 Easier debugging and optimization

Simply add `.react()` to your agent builder to enable this powerful feature!