WhatIfTool Implementation - Complete SummaryΒΆ
π¦ What Was CreatedΒΆ
A complete What-If scenario analysis tool for AI-Parrot's PandasAgent with the following capabilities:
β Domain Specific Language (DSL) for defining scenarios β Derived Metrics support (e.g., revenue_per_visit, profit_margin) β Constraint-based Optimization (greedy & genetic algorithms) β Proportional Scaling for rate-based changes β Natural Language Integration with LLM triggers β Comparison Tables (baseline vs scenario) β Scenario Caching for comparing multiple scenarios
π Files CreatedΒΆ
whatif_integration.py(Main Implementation)- Complete tool implementation
- All classes: WhatIfTool, WhatIfDSL, MetricsCalculator, ScenarioOptimizer
- Pydantic schemas for input validation
-
Integration helper function
-
example_usage.py(Usage Examples) - 5 comprehensive examples
- Natural language queries
- Direct tool calls
-
Manual DSL usage
-
README_WHATIF.md(Documentation) - Feature overview
- Installation instructions
- API documentation
- Common scenarios
-
Troubleshooting guide
-
test_whatif.py(Test Suite) - Unit tests for all components
- Integration tests
- Error handling tests
- Performance tests
π Quick StartΒΆ
1. IntegrationΒΆ
from aiparrot.agents.data import PandasAgent
from aiparrot.clients.factory import LLMFactory
from whatif_integration import integrate_whatif_tool
# Create your PandasAgent
client = LLMFactory.create_client(provider="anthropic")
agent = PandasAgent(
client=client,
name="Analyst",
dataframes={'data': df}
)
# Integrate WhatIfTool (one line!)
whatif_tool = integrate_whatif_tool(agent)
# That's it! Now use it naturally:
response = await agent.ask(
"What if we increase visits by 30%?"
)
2. Natural Language ExamplesΒΆ
The LLM automatically detects what-if patterns:
# Simple impact
await agent.ask("What if we close the West region?")
# Proportional scaling
await agent.ask("What if we increase visits by 30%?")
# Optimization
await agent.ask(
"Reduce expenses to 500k without revenue dropping more than 5%"
)
# Multi-objective
await agent.ask(
"Maximize profit while keeping headcount above 1000"
)
π― Key Features ExplainedΒΆ
1. Derived MetricsΒΆ
Problem: You want to increase visits, but how does that affect revenue and expenses?
Solution: Define derived metrics that calculate rates:
# The tool automatically creates these when needed:
revenue_per_visit = revenue / visits
expenses_per_visit = expenses / visits
# When visits increase by 30%:
# - visits Γ 1.3
# - revenue = visits Γ revenue_per_visit (automatically adjusted)
# - expenses = visits Γ expenses_per_visit (automatically adjusted)
Example Query:
2. Constraint OptimizationΒΆ
Problem: You need to reduce expenses but can't let revenue drop too much.
Solution: Set objectives and constraints, let the optimizer find the best actions:
# Objective: Reduce expenses to 500k
# Constraint: Revenue can't drop more than 5%
# Actions: Can close regions, adjust expenses by region
# β Optimizer finds: Close West, reduce expenses 15% in North
Example Query:
3. Regional AnalysisΒΆ
Problem: Changes should only apply to specific regions.
Solution: Actions can be regional:
"What if we increase visits by 50% in the North region only?"
# The tool will:
# - Scale visits in North by 50%
# - Adjust revenue/expenses in North proportionally
# - Leave other regions unchanged
π Output FormatΒΆ
Every scenario returns:
- Visualization - Text summary with actions and changes
- Comparison Table - Markdown table showing before/after
- Actions Applied - List of actions taken
- Verdict - High-level assessment
Example output:
======================================================================
Scenario: increase_visits_30pct
======================================================================
Actions Taken:
1. Scale visits by +30.0% (affects: revenue, expenses)
Metric Changes:
Metric Baseline Scenario Change % Change
--------------------------------------------------------------------------------
visits 25000.00 32500.00 7500.00 30.00%
revenue 8500000.00 11050000.00 2550000.00 30.00%
expenses 5200000.00 6760000.00 1560000.00 30.00%
| Metric | Baseline | Scenario | Change | % Change |
|--------|----------|----------|--------|----------|
| visits | 25,000.00 | 32,500.00 | +7,500.00 | +30.00% |
| revenue | 8,500,000.00 | 11,050,000.00 | +2,550,000.00 | +30.00% |
| expenses | 5,200,000.00 | 6,760,000.00 | +1,560,000.00 | +30.00% |
π§ Advanced UsageΒΆ
Manual DSL (Without LLM)ΒΆ
For programmatic scenario building:
from whatif_integration import WhatIfDSL
scenario = (
WhatIfDSL(df, name="my_scenario")
.register_derived_metric("profit", "revenue - expenses")
.initialize_optimizer()
.maximize("profit", weight=1.0)
.constrain_change("revenue", max_pct=5.0)
.can_close_regions()
.solve(max_actions=3, algorithm="greedy")
)
print(scenario.visualize())
Direct Tool CallΒΆ
For complete control:
from whatif_integration import WhatIfInput, WhatIfAction, DerivedMetric
result = await whatif_tool._execute(
scenario_description="test_scenario",
objectives=[{"type": "maximize", "metric": "profit", "weight": 1.0}],
constraints=[{"type": "max_change", "metric": "revenue", "value": 5.0}],
possible_actions=[
{
"type": "scale_proportional",
"target": "visits",
"parameters": {
"min_pct": 20,
"max_pct": 20,
"affected_columns": ["revenue", "expenses"]
}
}
],
derived_metrics=[
{"name": "revenue_per_visit", "formula": "revenue / visits"}
],
max_actions=1,
algorithm="greedy"
)
π How It WorksΒΆ
ArchitectureΒΆ
User Query: "What if we increase visits by 30%?"
β
LLM detects "what if" trigger
β
LLM constructs WhatIfInput:
- scenario_description: "increase_visits_30pct"
- derived_metrics: [revenue_per_visit, expenses_per_visit]
- possible_actions: [scale_proportional visits by 30%]
β
WhatIfTool._execute():
- Creates WhatIfDSL instance
- Registers derived metrics
- Defines possible actions
- Runs optimizer
β
Optimizer finds best actions:
- Evaluates each action
- Checks constraints
- Calculates objective scores
- Returns best combination
β
ScenarioResult:
- Baseline DataFrame
- Result DataFrame
- Actions taken
- Comparison metrics
β
Returns to user:
- Visualization
- Comparison table
- Actions list
- Verdict
Optimization AlgorithmsΒΆ
Greedy (Default): - Fast and simple - Evaluates actions one at a time - Good for 1-5 actions - Best for: Simple scenarios, quick results
Genetic: - More thorough - Explores combinations - Better optimization - Best for: Complex scenarios with many constraints
π Common Use CasesΒΆ
1. Regional Closure AnalysisΒΆ
2. Scaling OperationsΒΆ
3. Cost OptimizationΒΆ
4. Profit MaximizationΒΆ
5. Rate-Based AnalysisΒΆ
"What if we do 30% more visits in high-revenue regions?"
"How do expenses change if we increase visits by 40%?"
β οΈ Important NotesΒΆ
Data RequirementsΒΆ
- DataFrame must have numeric columns for metrics
- For regional analysis, needs a 'region' column
- For rate-based analysis, needs base column (e.g., 'visits')
Formula SafetyΒΆ
- Derived metrics use Python
eval()with sandboxed context - Only DataFrame columns and numpy are available
- No access to builtins or dangerous functions
PerformanceΒΆ
- Greedy: Very fast, handles 100+ actions
- Genetic: Slower, best with <50 actions
- Large DataFrames (>100k rows) may slow down optimization
π§ͺ TestingΒΆ
Run the test suite:
Expected output:
Running WhatIfTool Tests
======================================================================
1. Testing MetricsCalculator...
β
MetricsCalculator tests passed
2. Testing ScenarioOptimizer...
β
ScenarioOptimizer tests passed
3. Testing WhatIfDSL...
β
WhatIfDSL tests passed
4. Testing Error Handling...
β
Error handling tests passed
5. Testing Integration...
β
Integration tests passed
6. Testing Performance...
β
Performance tests passed
7. Testing WhatIfTool (async)...
β
WhatIfTool tests passed
======================================================================
β
All tests passed!
π Next StepsΒΆ
-
Try the Examples:
-
Integrate with Your Agent:
-
Test with Your Data:
- Start with simple scenarios
- Add derived metrics as needed
-
Use constraints for realistic scenarios
-
Customize:
- Add custom actions in WhatIfDSL
- Create domain-specific derived metrics
- Tune optimization parameters
π TroubleshootingΒΆ
Issue: "DataFrame not found"ΒΆ
Solution: Make sure DataFrame is loaded in agent.dataframes
Issue: "No actions taken"ΒΆ
Solution: Constraints too strict or no valid actions. Try: - Relaxing constraints - Adding more possible actions - Using genetic algorithm
Issue: LLM not invoking toolΒΆ
Solution: - Check system prompt includes WHATIF_SYSTEM_PROMPT - Use clear "what if" phrasing - Verify DataFrames are loaded
Issue: Slow optimizationΒΆ
Solution: - Use greedy algorithm instead of genetic - Reduce max_actions - Reduce action granularity (fewer percentage steps)
π Additional ResourcesΒΆ
- README_WHATIF.md: Complete documentation
- example_usage.py: Working examples
- test_whatif.py: Comprehensive tests
- whatif_integration.py: Full implementation with comments
β SummaryΒΆ
You now have a complete What-If analysis tool that:
- β Integrates seamlessly with PandasAgent
- β Responds to natural language queries
- β Handles derived metrics and rate-based changes
- β Optimizes with constraints
- β Provides clear visualizations and comparisons
- β Caches scenarios for comparison
- β Is production-ready with error handling and tests
Start using it now:
from whatif_integration import integrate_whatif_tool
# One line to enable what-if analysis!
whatif_tool = integrate_whatif_tool(your_pandas_agent)
# Ask questions naturally
response = await your_pandas_agent.ask(
"What if we increase visits by 30%?"
)
Enjoy your new What-If analysis capabilities! π