cryogenic22 commited on
Commit
e2eb9f2
·
verified ·
1 Parent(s): 9d9292e

Create simplified_planning_agent.py

Browse files
Files changed (1) hide show
  1. simplified_planning_agent.py +153 -0
simplified_planning_agent.py ADDED
@@ -0,0 +1,153 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Simplified Planning Agent for Pharmaceutical Analytics
3
+ This version uses direct API calls instead of LangChain components
4
+ """
5
+
6
+ import os
7
+ import json
8
+ import re
9
+ from typing import Dict, List, Any, Tuple
10
+ from pydantic import BaseModel, Field
11
+
12
+ # Define analysis plan schema
13
+ class AnalysisPlan(BaseModel):
14
+ """Planning agent output with analysis plan details"""
15
+ problem_statement: str = Field(description="Refined problem statement based on the alert")
16
+ required_data_sources: List[Dict[str, str]] = Field(
17
+ description="List of data sources needed with table name and purpose")
18
+ analysis_approaches: List[Dict[str, str]] = Field(
19
+ description="List of analytical approaches to be used with type and purpose")
20
+ tasks: List[Dict[str, Any]] = Field(
21
+ description="Ordered list of tasks to execute with dependencies")
22
+ expected_insights: List[str] = Field(
23
+ description="List of expected insights that would answer the problem")
24
+
25
+ class PlanningAgent:
26
+ """Agent responsible for planning the analysis workflow"""
27
+
28
+ def __init__(self):
29
+ """Initialize the planning agent"""
30
+ api_key = os.getenv("ANTHROPIC_API_KEY")
31
+ if not api_key:
32
+ raise ValueError("ANTHROPIC_API_KEY not found in environment variables")
33
+
34
+ self.api_key = api_key
35
+ print("Planning Agent initialized successfully")
36
+
37
+ def create_analysis_plan(self, alert_description: str) -> Tuple[AnalysisPlan, Dict]:
38
+ """Generate an analysis plan based on the alert description"""
39
+ print("Planning Agent: Creating analysis plan...")
40
+
41
+ # Create the system and user messages
42
+ system_message = """You are an expert pharmaceutical analytics planning agent.
43
+ Your task is to create a detailed analysis plan to investigate sales anomalies.
44
+
45
+ For pharmaceutical sales analysis:
46
+ - Consider product performance, competitor activities, prescriber behavior
47
+ - Include geographic, temporal, and demographic dimensions in your analysis
48
+ - Consider both internal factors (supply, marketing) and external factors (market events, seasonality)
49
+
50
+ Your output should be a complete JSON-formatted analysis plan following this structure:
51
+ {
52
+ "problem_statement": "Clear definition of the problem to solve",
53
+ "required_data_sources": [
54
+ {"table": "sales", "purpose": "Core sales metrics analysis"},
55
+ {"table": "regions", "purpose": "Geographic segmentation"}
56
+ ],
57
+ "analysis_approaches": [
58
+ {"type": "time_series_decomposition", "purpose": "Separate trend from seasonality"},
59
+ {"type": "comparative_analysis", "purpose": "Compare performance across regions"}
60
+ ],
61
+ "tasks": [
62
+ {
63
+ "id": 1,
64
+ "name": "Data acquisition",
65
+ "description": "Pull relevant data from sources",
66
+ "agent": "data_agent",
67
+ "dependencies": [],
68
+ "expected_output": "Cleaned datasets for analysis"
69
+ },
70
+ {
71
+ "id": 2,
72
+ "name": "Analysis execution",
73
+ "description": "Perform statistical analysis",
74
+ "agent": "analytics_agent",
75
+ "dependencies": [1],
76
+ "expected_output": "Analysis results"
77
+ }
78
+ ],
79
+ "expected_insights": [
80
+ "Primary factors contributing to sales decline",
81
+ "Regional variations in performance"
82
+ ]
83
+ }
84
+
85
+ Be thorough but focus on creating a practical analysis workflow.
86
+ """
87
+
88
+ user_message = f"Create an analysis plan for the following alert: {alert_description}"
89
+
90
+ # Make direct API call to Claude
91
+ try:
92
+ import anthropic
93
+ client = anthropic.Anthropic(api_key=self.api_key)
94
+
95
+ response = client.messages.create(
96
+ model="claude-3-haiku-20240307",
97
+ max_tokens=2000,
98
+ temperature=0.2,
99
+ messages=[
100
+ {"role": "system", "content": system_message},
101
+ {"role": "user", "content": user_message}
102
+ ]
103
+ )
104
+
105
+ # Extract response content
106
+ response_text = response.content[0].text
107
+
108
+ # Extract JSON from the response
109
+ plan_dict = self.extract_json_from_text(response_text)
110
+
111
+ # Convert to Pydantic model for validation
112
+ analysis_plan = AnalysisPlan.model_validate(plan_dict)
113
+
114
+ return analysis_plan, plan_dict
115
+
116
+ except Exception as e:
117
+ print(f"Error creating analysis plan: {e}")
118
+ raise
119
+
120
+ def extract_json_from_text(self, text: str) -> Dict:
121
+ """Extract JSON from text that might contain additional content"""
122
+ try:
123
+ # First try to parse the entire text as JSON
124
+ return json.loads(text)
125
+ except json.JSONDecodeError:
126
+ # Try to find JSON block with regex
127
+ json_pattern = r'```json\s*([\s\S]*?)\s*```'
128
+ match = re.search(json_pattern, text)
129
+ if match:
130
+ try:
131
+ return json.loads(match.group(1))
132
+ except json.JSONDecodeError:
133
+ pass
134
+
135
+ # Try to find anything that looks like JSON
136
+ json_pattern = r'({[\s\S]*})'
137
+ match = re.search(json_pattern, text)
138
+ if match:
139
+ try:
140
+ return json.loads(match.group(1))
141
+ except json.JSONDecodeError:
142
+ pass
143
+
144
+ # If all extraction attempts fail
145
+ raise ValueError(f"Could not extract JSON from response: {text}")
146
+
147
+ # For testing
148
+ if __name__ == "__main__":
149
+ # Get API key from environment
150
+ agent = PlanningAgent()
151
+ alert = "Sales of DrugX down 15% in Northeast region over past 30 days compared to forecast."
152
+ plan, plan_dict = agent.create_analysis_plan(alert)
153
+ print(json.dumps(plan_dict, indent=2))