-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathroute_agent.py
More file actions
220 lines (158 loc) · 7.15 KB
/
route_agent.py
File metadata and controls
220 lines (158 loc) · 7.15 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
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
import asyncio
import json
from strands import Agent, tool
from strands_tools import use_llm
from strands_tools import calculator
from strands.models import BedrockModel
bedrock_model = BedrockModel(
model_id="us.anthropic.claude-3-7-sonnet-20250219-v1:0",
region_name='us-east-1',
temperature=0.3,
)
SYSTEM_PROMPT = '''
You are a routing agent. Your job is to read the incoming message, determine the most appropriate destination from the allowed labels, and hand off with a minimal, useful payload.
Success: choose the correct label, include a short rationale, and provide the essentials the destination agent needs to act.
Principles:
Be decisive when confidence ≥ threshold; otherwise ask one targeted clarification or return other.
Never invent capabilities or promises; prefer safe deferral to misrouting.
Preserve privacy: don’t request secrets/PII; redact sensitive data in the payload.
Keep context tight: summarize long threads into 3–5 bullets before routing.
Output (JSON): { "label": "<one of [pricing, tech_support, partnerships, other]>", "confidence": 0.0–1.0, "rationale": "one sentence", "handoff_payload": { ...essentials } }
Threshold: default 0.7 unless configured otherwise.
'''
@tool
def clasify_intent(input: str):
'''
You classify an incoming message into one of the known labels.
Success: return the best label + confidence + one-line rationale.
Principles: be decisive when confidence ≥ threshold; if < threshold, defer to Clarify.
'''
CLASSIFY_INTENT_SYSTEM_PROMPT = '''
You classify an incoming message into one of the known labels.
Success: return the best label + confidence + one-line rationale.
Principles: be decisive when confidence ≥ threshold; if < threshold, defer to Clarify.
'''
classify_agent = Agent(
model=bedrock_model,
tools=[use_llm],
callback_handler=None
)
response = classify_agent.tool.use_llm(
system_prompt=CLASSIFY_INTENT_SYSTEM_PROMPT,
prompt=input,
)
print(response)
return response
@tool
def route_to_pricing(input: str):
ROUTE_TO_PRICING_AGENT_SYSTEM_PROMPT = '''
You draft accurate pricing/plan responses using documented offerings only.
Success: clear answer + next step (e.g., link to plans, request usage details).
Principles: no discounts/commitments; flag unknowns instead of guessing.
'''
route_to_pricing_agent = Agent(
model=bedrock_model,
system_prompt=ROUTE_TO_PRICING_AGENT_SYSTEM_PROMPT,
callback_handler=None
)
response = route_to_pricing_agent(input)
print(response)
return response
@tool
def route_to_tech_support(input: str):
ROUTE_TO_TECH_SUPPORT_AGENT_SYSTEM_PROMPT = '''
You produce helpful troubleshooting replies and safe next steps.
Success: reproducible steps, minimal data requests, and a quick diagnostic path.
Principles: never ask for secrets/PII; prefer redacted logs and environment basics.
'''
route_to_tech_support_agent = Agent(
model=bedrock_model,
system_prompt=ROUTE_TO_TECH_SUPPORT_AGENT_SYSTEM_PROMPT,
callback_handler=None
)
response = route_to_tech_support_agent(input)
print(response)
return response
@tool
def route_to_partnership(input: str):
ROUTE_TO_PARTNERSHIP_AGENT_SYSTEM_PROMPT = '''
You handle BD/partnership inquiries and propose times to meet.
Success: warm, concise reply with 2–3 scheduling options and a clear CTA.
Principles: no legal/financial commitments; gather just enough context to proceed.
'''
route_to_partnership_agent = Agent(
model=bedrock_model,
system_prompt=ROUTE_TO_PARTNERSHIP_AGENT_SYSTEM_PROMPT,
callback_handler=None
)
response = route_to_partnership_agent(input)
print(response)
return response
# Initialize our agent without a callback handler
router_agent = Agent(
model=bedrock_model,
system_prompt=SYSTEM_PROMPT,
tools=[clasify_intent, route_to_pricing,route_to_partnership,route_to_tech_support],
callback_handler=None
)
# Async function that iterates over streamed agent events
query = '''
We’d like to co-host a webinar with Educloud Academy next month.”
→ partnerships | {topic:"webinar", timeframe:"next_month"}'''
agent_response = router_agent(query)
print(agent_response)
#sample prompts
'''
Pricing
“What does the Pro plan cost for 25 seats and monthly billing?”
→ label: pricing | payload: {seats:25, billing:"monthly"}
“Is there a discount for EDU/nonprofits?”
→ pricing | {segment:"education|nonprofit"}
“Compare Starter vs Pro for API rate limits.”
→ pricing | {compare:["Starter","Pro"], concern:"rate_limits"}
“Can we pay via invoice instead of card?”
→ pricing | {payment_method:"invoice"}
“How much is Pro in XAF?”
→ pricing | {currency:"XAF"}
Tech Support
“Deploy failing: ValidationException: engine not supported in region eu-west-3.”
→ tech_support | {error:"ValidationException", region:"eu-west-3"}
“Webhook 500 when sending to /events; here’s the payload (redacted).”
→ tech_support | {endpoint:"/events", status:500}
“Your Python SDK v3.2 throws NameError after upgrade.”
→ tech_support | {sdk:"python", version:"3.2"}
“Emails from SES aren’t reaching Gmail; SPF/DKIM look fine.”
→ tech_support | {feature:"email", provider:"SES", target:"Gmail"}
“App crashes on iOS 17.5 only.”
→ tech_support | {platform:"iOS", version:"17.5"}
Partnerships
“We’d like to co-host a webinar with Educloud Academy next month.”
→ partnerships | {topic:"webinar", timeframe:"next_month"}
“Exploring a reseller agreement in West Africa—who should we talk to?”
→ partnerships | {deal_type:"reseller", region:"West Africa"}
“Can we integrate your API into our LMS and do a joint case study?”
→ partnerships | {integration:"LMS", marketing:"case_study"}
“Interested in sponsoring your AI for Kids program.”
→ partnerships | {program:"AI for Kids"}
Ambiguous → Clarify
“How do I get started?” (could be pricing, onboarding, or support)
→ confidence < 0.7 → ask: “Do you need pricing, setup help, or a partnership intro?”
“I need help with the plan for my team.” (plan = pricing? setup?)
→ clarify with 3 choices: pricing / technical setup / something else.
“We want to talk.”
→ clarify: “Is this about pricing, technical support, or partnerships?”
Other / Non-routable or Safety
“Can you share your customers’ private emails?” (policy disallowed)
→ other | rationale: policy; payload empty.
“Here’s my password: P@ssw0rd123—please fix my account.”
→ other | redact & respond with safe guidance (no secrets).
Non-English: “¿Ofrecen planes con factura anual?”
→ pricing | {language:"es", billing:"annual"}
Forward/noisy thread: “Fwd: Re: Re: pricing?? (see attached, long thread)”
→ pricing | summarize top 3 bullets before handoff.
Multi-intent: “Site down + need a quote for 50 seats.”
→ split or prioritize:
ticket A → tech_support {incident:"site_down"}
ticket B → pricing {seats:50}
If you want, I can turn these into unit tests with expected router JSON output (label, confidence, rationale, handoff_payload).
'''