
# Three-Way Comparison: Tool Calling Approaches

**Query:** "SUVs with mileage >15 kmpl, available in Delhi with specs and dealer availability."

**Date:** 2026-03-01 13:45:46

## Summary Table

| Metric | Traditional | ez-ptc (no chaining) | ez-ptc (with chaining) | Best |
|--------|-------------|----------------------|------------------------|------|
| **LLM Turns** | 4 | 2 | 2 | S3 |
| **Tool Calls** | 0 | 0 | 0 | S1 |
| **Total Tokens** | 5,078 | 781 | 1,833 | S2 |
| **Input Tokens** | 4,098 | 610 | 1,219 | - |
| **Output Tokens** | 980 | 171 | 614 | - |
| **Execution Time** | 15.11s | 3.15s | 8.44s | S2 |

## Detailed Analysis

### Scenario 1: Traditional Tool Calling
**Approach:** Pydantic AI with individual tool functions

**How it works:**
- LLM calls each tool individually
- Each tool call requires a separate round-trip
- LLM must synthesize all results at the end

**Results:**
- LLM Turns: 4
- Tool Calls: 0
- Total Tokens: 5,078
- Time: 15.11s

**LLM-Generated Code:**

**Turn 1:**

```python
search_cars(body_type="SUV")
```

**Turn 2:**

```python
get_specs(car_id="suv_001")
get_specs(car_id="suv_002")
get_specs(car_id="suv_003")
get_specs(car_id="suv_004")
get_specs(car_id="suv_005")
get_specs(car_id="suv_006")
get_specs(car_id="suv_007")
get_specs(car_id="suv_008")
get_specs(car_id="suv_009")
get_specs(car_id="suv_010")
get_specs(car_id="suv_011")
get_specs(car_id="suv_012")
get_specs(car_id="suv_013")
get_specs(car_id="suv_014")
get_specs(car_id="suv_015")
```

**Turn 3:**

```python
check_availability(car_id="suv_001", city="Delhi")
check_availability(car_id="suv_002", city="Delhi")
check_availability(car_id="suv_004", city="Delhi")
check_availability(car_id="suv_005", city="Delhi")
check_availability(car_id="suv_006", city="Delhi")
check_availability(car_id="suv_007", city="Delhi")
check_availability(car_id="suv_010", city="Delhi")
check_availability(car_id="suv_011", city="Delhi")
check_availability(car_id="suv_012", city="Delhi")
check_availability(car_id="suv_015", city="Delhi")
```

### Scenario 2: ez-ptc WITHOUT Tool Chaining
**Approach:** ez-ptc with `assist_tool_chaining=False`

**How it works:**
- LLM writes Python code to orchestrate tools
- Toolkit doesn't document return types in detail
- Single execution of generated code

**Results:**
- LLM Turns: 2
- Tool Calls: 0
- Total Tokens: 781
- Time: 3.15s

**LLM-Generated Code:**

```python
cars = search_cars('SUV')
suitable_cars = [car for car in cars if car.get('mileage', 0) > 15]
results = []
for car in suitable_cars:
    specs = get_specs(car['id'])
    availability = check_availability(car['id'], 'Delhi')
    if availability['available']:
        results.append({
            'car': car,
            'specs': specs,
            'availability': availability
        })
print(results)
```

### Scenario 3: ez-ptc WITH Tool Chaining
**Approach:** ez-ptc with `assist_tool_chaining=True`

**How it works:**
- LLM writes Python code to orchestrate tools
- Toolkit documents exact return types (enables chaining)
- LLM can filter/transform data between tool calls
- Single execution of generated code

**Results:**
- LLM Turns: 2
- Tool Calls: 0
- Total Tokens: 1,833
- Time: 8.44s

**LLM-Generated Code:**

```python
suvs = search_cars('SUV')
high_mileage_suvs = [car for car in suvs if car['price'] > 0]  # First filter to get car ids

result = []
for car in high_mileage_suvs:
    specs = get_specs(car['car_id'])
    if specs['kmpl'] > 15:
        availability = check_availability(car['car_id'], 'Delhi')
        if availability['available']:
            result.append({
                'name': car['name'],
                'price': car['price'],
                'kmpl': specs['kmpl'],
                'fuel_type': specs['fuel_type'],
                'engine_cc': specs['engine_cc'],
                'transmission': specs['transmission'],
                'dealer_count': availability['dealer_count']
            })
print(result)
```

## Key Improvements

### ez-ptc (with chaining) vs Traditional:
- **50.0%** fewer LLM turns
- **63.9%** fewer tokens
- **44.1%** faster execution

### ez-ptc (with chaining) vs ez-ptc (no chaining):
- **0.0%** more LLM turns
- **134.7%** more tokens
- **168.1%** slower execution time

## Conclusion

**Winner:** Scenario 2 (ez-ptc no chaining)

The key advantage of ez-ptc with tool chaining is that it:
1. Reduces LLM round-trips significantly
2. Enables programmatic filtering between tool calls
3. Returns only relevant data (selective output)
4. Saves tokens and reduces latency

Tool chaining documentation helps the LLM understand exact return types, enabling better code generation and data manipulation.
