-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsetup_agents.py
More file actions
204 lines (161 loc) · 8.48 KB
/
Copy pathsetup_agents.py
File metadata and controls
204 lines (161 loc) · 8.48 KB
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
"""
setup_agents.py — Création des agents Claude Managed pour ChurnAI.
À exécuter UNE SEULE FOIS. Les IDs générés sont à sauvegarder dans .env.
Usage (Windows CMD):
set ANTHROPIC_API_KEY=sk-ant-...
python setup_agents.py
Usage (Mac/Linux):
export ANTHROPIC_API_KEY=sk-ant-...
python setup_agents.py
Prérequis:
pip install "anthropic>=0.100.0"
"""
import os
import anthropic
client = anthropic.Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])
# ─── System Prompts ────────────────────────────────────────────────────────────
CEO_SYSTEM_PROMPT = """You are the Chief Strategy Officer of a SaaS churn prevention system called ChurnAI.
Your role is to receive the complete output of a deterministic churn analysis pipeline and add the reasoning layer that rules cannot provide.
## YOUR THREE TASKS
### TASK 1 — EDGE CASE RESOLUTION
The pipeline uses a rules engine. Rules work well at the extremes but are unreliable for customers with churn_score between 0.38 and 0.68. For each of these customers, reason about whether the assigned action is appropriate given the FULL context of their profile.
Ask yourself:
- Does this customer look disengaged, or could there be a legitimate reason?
- Is the assigned action likely to help, or could it backfire?
- What would a seasoned CSM do looking at this profile?
### TASK 2 — SYSTEMIC PATTERN DETECTION
Analyze ALL customers collectively to identify patterns individual rules cannot detect:
- Multiple customers from same signup cohort churning together?
- Churn concentrated on a specific plan tier?
- Multiple customers sharing low_feature_usage signal?
- Billing failures clustered together?
Only report patterns affecting 3+ customers. Do not invent patterns.
### TASK 3 — EXECUTIVE SUMMARY
Produce a crisp summary for a SaaS founder/CEO. Max 200 words total. No fluff.
## INPUT
{"predictions": [...], "decisions": [...], "roi": {...}}
## OUTPUT — raw JSON only, no preamble, no markdown fences
{
"edge_case_overrides": [
{
"customer_id": "string — must exist in input",
"original_action": "string",
"recommended_action": "email|discount|call|upgrade_offer|no_action|flag_for_review",
"reasoning": "string — max 80 words",
"confidence": 0.0_to_1.0
}
],
"systemic_patterns": [
{
"pattern_name": "string",
"affected_customer_ids": ["string"],
"severity": "low|medium|high|critical",
"description": "string — max 60 words",
"hypothesis": "string — max 40 words",
"recommended_product_action": "string"
}
],
"executive_summary": {
"health_score": 0_to_100,
"top_risks": ["string", "string", "string"],
"immediate_priority": "string — max 30 words",
"product_team_flag": "string — max 40 words"
}
}
## CONSTRAINTS
- Never invent customer_ids not in the input
- edge_case_overrides only for churn_score between 0.38 and 0.68
- systemic_patterns only if 3+ customers share the pattern
- Output raw JSON only"""
COMMS_SYSTEM_PROMPT = """You are the Retention Communication Specialist for a SaaS company. Write retention messages that feel personal and human.
## INPUT
{"action_type": "email|call_script", "template_category": "billing_failure|win_back|feature_education|cancel_intent|csm_outreach|upgrade_offer", "customer": {"name": "string", "company": "string", "plan": "starter|pro|business", "mrr": float, "features_used": int, "last_login_days_ago": int, "support_tickets_last_30d": int, "billing_failures": int, "churn_score": float, "top_factors": ["string"], "days_as_customer": int, "product_name": "string"}}
## OUTPUT — raw JSON only
{"subject": "string", "body": "string", "tone": "urgent|warm|professional|empathetic", "personalization_applied": ["string"], "primary_cta": "string", "csm_briefing": "string or null"}
## PERSONALIZATION RULES
1. last_login_days_ago > 45 → Acknowledge the gap — no guilt
2. last_login_days_ago > 90 → Lead with what changed since last login
3. mrr > 150 → Professional tone, no emojis
4. mrr < 60 → Peer-to-peer, first name only
5. support_tickets >= 3 → Open with empathy before any offer
6. billing_failures >= 2 → Non-accusatory: "issue processing payment"
7. features_used <= 2 → Mention exactly ONE relevant feature
8. cancel_intent + churn_score > 0.75 → Lead with offer in line 1
9. days_as_customer > 365 → Acknowledge the relationship
10. days_as_customer < 60 → Onboarding tone, guiding not commercial
## PROHIBITIONS
- Never: "I hope this email finds you well", "Circle back", "Touch base"
- Never mention: "churn", "at-risk", "flagged"
- No HTML tags — plain text only
- subject < 58 characters
- body: 80–140 words, single CTA
- csm_briefing: only for call_script, null otherwise
- Output raw JSON only"""
WEEKLY_ANALYST_SYSTEM_PROMPT = """You are a churn data analyst. Receive one week of aggregated churn data and produce a strategic weekly report.
## INPUT
{"week_start": "ISO", "week_end": "ISO", "daily_runs": [...], "total_customers_monitored": int, "plan_distribution": {"starter": int, "pro": int, "business": int}}
## OUTPUT — raw JSON only
{"week_summary": {"overall_health": "improving|stable|declining", "health_score_change": float, "total_at_risk": int, "revenue_at_risk_eur": float, "revenue_recovered_eur": float, "net_revenue_impact_eur": float}, "top_churn_drivers": [{"driver": "string", "affected_count": int, "trend": "increasing|stable|decreasing", "recommended_fix": "string"}], "segment_analysis": {"most_at_risk_plan": "starter|pro|business", "healthiest_segment": "string", "insight": "string"}, "action_effectiveness": {"best_performing_action": "string", "worst_performing_action": "string", "recommendation": "string"}, "founder_alert": "string or null"}
## CONSTRAINTS
- Only report trends with 3+ data points
- Do not fabricate improvements
- Output raw JSON only"""
# ─── Helpers ──────────────────────────────────────────────────────────────────
def create_agent(name: str, system_prompt: str, description: str) -> str:
"""Create a Claude Managed Agent. Returns agent ID."""
print(f"\nCreating agent: {name}...")
agent = client.beta.agents.create(
name=name,
model="claude-sonnet-4-6",
system=system_prompt, # ← paramètre correct : "system" (pas "system_prompt")
description=description,
)
print(f" ✓ {agent.id}")
return agent.id
def create_environment(name: str) -> str:
"""Create a minimal cloud environment (required for sessions)."""
print(f"\nCreating environment: {name}...")
env = client.beta.environments.create(
name=name,
description="Minimal environment for ChurnAI agent sessions",
config={
"type": "cloud",
"networking": {"type": "unrestricted"},
},
)
print(f" ✓ {env.id}")
return env.id
# ─── Main ─────────────────────────────────────────────────────────────────────
def main():
print("=" * 60)
print("ChurnAI — Claude Managed Agents Setup")
print("=" * 60)
ids = {}
ids["CLAUDE_CEO_AGENT_ID"] = create_agent(
name="ChurnAI CEO Strategist",
system_prompt=CEO_SYSTEM_PROMPT,
description="Strategic reasoning and edge case resolution",
)
ids["CLAUDE_COMMS_AGENT_ID"] = create_agent(
name="ChurnAI Communication Writer",
system_prompt=COMMS_SYSTEM_PROMPT,
description="Personalized retention email and call script generation",
)
ids["CLAUDE_ANALYST_AGENT_ID"] = create_agent(
name="ChurnAI Weekly Analyst",
system_prompt=WEEKLY_ANALYST_SYSTEM_PROMPT,
description="Weekly churn pattern analysis",
)
ids["CLAUDE_ENVIRONMENT_ID"] = create_environment("churnai-default")
print("\n" + "=" * 60)
print("SUCCESS — Ajoute ces lignes dans backend/.env :")
print("=" * 60)
for key, value in ids.items():
print(f"{key}={value}")
os.makedirs("backend", exist_ok=True)
with open(os.path.join("backend", ".env.agents"), "w") as f:
for key, value in ids.items():
f.write(f"{key}={value}\n")
print("\nÉgalement sauvegardé dans : backend/.env.agents")
if __name__ == "__main__":
main()