Skip to content
This repository was archived by the owner on Jul 7, 2026. It is now read-only.

Commit e3cc381

Browse files
mjptvdaptible
andauthored
docs: Add more example agents (#133)
Co-authored-by: tvdaptible <210452321+tvdaptible@users.noreply.github.com>
1 parent 40c8f11 commit e3cc381

8 files changed

Lines changed: 1048 additions & 1 deletion

File tree

docs/docs.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,11 @@
5050
"group": "Example Agents",
5151
"pages": [
5252
"examples/ssl_connection_failure",
53-
"examples/disk_space_alerts"
53+
"examples/disk_space_alerts",
54+
"examples/db_connection_pool",
55+
"examples/k8s_crash_loop_backoff",
56+
"examples/failing_gha_build",
57+
"examples/creating_new_agents"
5458
]
5559
},
5660
{
Lines changed: 382 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,382 @@
1+
---
2+
title: "Tutorial: Creating New Agents"
3+
---
4+
5+
Every team has unique infrastructure, monitoring systems, and incident response
6+
processes. The example agents in our library serve as references and starting
7+
points, but the real power of Unpage comes from understanding the agent-building
8+
process itself.
9+
10+
This tutorial walks you through the steps needed to design and implement your
11+
own agents from scratch.
12+
13+
14+
## Overview: The Agent Creation Process
15+
16+
Creating a new agent involves six key steps:
17+
18+
1. **Identify your input source** - What webhook/alert will trigger the agent?
19+
2. **Write the agent description** - How will the router know when to use this agent?
20+
3. **Design the runbook instructions** - What should the agent do step-by-step?
21+
4. **Define required tools** - What built-in and custom tools does the agent need?
22+
5. **Create custom shell tools** - Extend Unpage with your specific commands/scripts
23+
6. **Test and deploy** - Validate locally and set up production webhook handling
24+
25+
Let's walk through each step with a practical example.
26+
27+
## Example Scenario: Redis Memory Usage Alerts
28+
29+
For this tutorial, we'll create an agent that handles Redis memory usage alerts
30+
from DataDog. When Redis memory usage exceeds 85%, our agent will:
31+
32+
- Check current Redis memory statistics
33+
- Identify the largest keys consuming memory
34+
- Analyze recent memory growth patterns
35+
- Check for memory-intensive operations in Redis logs
36+
- Post actionable recommendations to the incident
37+
38+
39+
## Step 1: Identify Your Input Source
40+
41+
The first step is understanding what triggers your agent. This could be:
42+
43+
- **PagerDuty incidents** from various monitoring systems
44+
- **Direct webhooks** from DataDog, New Relic, CloudWatch, etc.
45+
- **GitHub Actions failures** or other CI/CD events
46+
- **Custom application alerts** from your own services
47+
48+
For our Redis example, we'll assume we get alerts that look like:
49+
50+
```json
51+
{
52+
"incident": {
53+
"title": "Redis Memory Usage Critical",
54+
"description": "redis-prod-cluster memory usage: 87.2% (6.1GB/7.0GB)",
55+
"service": "redis-prod-cluster",
56+
"status": "triggered"
57+
}
58+
}
59+
```
60+
61+
62+
## Step 2: Write the Agent Description
63+
64+
The agent description is used by Unpage's [Router](/concepts/router) to
65+
automatically select which agent should handle each incoming alert. Write
66+
descriptions that are:
67+
68+
- **Specific** about the alert types this agent handles
69+
- **Distinguishing** to differentiate from other agents
70+
- **Comprehensive** to cover edge cases and variations
71+
72+
Create the agent configuration:
73+
74+
```bash
75+
$ unpage agent create redis_memory_alerts
76+
```
77+
78+
Start with the description in the YAML file that opens:
79+
80+
```yaml
81+
description: >
82+
Handle Redis memory usage alerts and high memory consumption issues.
83+
Use this agent when:
84+
- The alert mentions Redis, redis-server, or Redis cluster names
85+
- Memory usage, memory consumption, or OOM (out of memory) is mentioned
86+
- Redis-specific metrics like used_memory, maxmemory, or evicted_keys are referenced
87+
- The alert comes from DataDog, CloudWatch, or other monitoring systems monitoring Redis instances
88+
```
89+
90+
## Step 3: Design the Runbook Instructions
91+
92+
The `prompt` section contains step-by-step instructions for what the agent should do.
93+
Think of this as a detailed runbook that a human SRE would follow, but written for an LLM.
94+
95+
Structure your instructions clearly:
96+
97+
- Use numbered or bulleted steps
98+
- Be specific about what information to gather
99+
- Include error handling and edge cases
100+
- Specify what actions to take based on findings
101+
- Include formatting requirements for status updates
102+
103+
```yaml
104+
prompt: >
105+
You are a Redis memory analysis specialist. When investigating Redis memory alerts:
106+
107+
1. Extract the Redis instance/cluster name from the PagerDuty alert
108+
2. Use `shell_redis_memory_info` to get current memory statistics and configuration
109+
3. Use `shell_redis_top_keys` to identify the largest keys consuming memory
110+
4. Use `shell_redis_memory_usage_history` to analyze memory growth patterns over the last 4 hours
111+
5. Use `search_datadog_logs` to find Redis logs from the last 30 minutes, looking for:
112+
- Memory-related warnings or errors
113+
- Large key operations (HSET, SADD with many members)
114+
- Client connection spikes that might indicate memory leaks
115+
6. Use `get_resource_with_neighbors` to identify applications connected to this Redis instance
116+
7. For each connected application, search logs for Redis-related errors or unusual patterns
117+
118+
Analysis and Response:
119+
- If memory usage is above 90%: Mark as CRITICAL and recommend immediate action
120+
- If memory usage is 85-90%: Mark as HIGH and suggest proactive measures
121+
- If large keys (>100MB) exist: Identify the key patterns and suggest optimization
122+
- If memory growth is rapid (>10% in 1 hour): Flag as potential memory leak
123+
124+
Create a comprehensive status update including:
125+
- Current memory usage percentage and absolute values
126+
- Top 10 memory-consuming key patterns with sizes
127+
- Memory growth rate over the last 4 hours
128+
- Any concerning log patterns or errors
129+
- Connected applications that might be causing issues
130+
- Specific recommended actions (key cleanup, configuration changes, scaling)
131+
132+
Post findings using `pagerduty_post_status_update` with priority based on severity analysis.
133+
```
134+
135+
## Step 4: Define Required Tools
136+
137+
List all the tools your agent needs in the `tools` section. These include:
138+
139+
- **Built-in tools** from Unpage plugins (DataDog, PagerDuty, AWS, etc.)
140+
- **Custom shell commands** you'll create for specific operations
141+
- **Wildcards** for groups of related tools
142+
143+
```yaml
144+
tools:
145+
- "shell_redis_memory_info"
146+
- "shell_redis_top_keys"
147+
- "shell_redis_memory_usage_history"
148+
- "search_datadog_logs"
149+
- "get_resource_with_neighbors"
150+
- "pagerduty_post_status_update"
151+
```
152+
153+
To see all available built-in tools:
154+
155+
```bash
156+
$ unpage mcp tools list
157+
```
158+
159+
Your Agent will **only** have access to the tools you explicitly give it
160+
permission to call.
161+
162+
163+
## Step 5: Create Custom Shell Tools
164+
165+
You can always extend Unpage with custom [shell commands](/plugins/shell) to
166+
interact with your specific infrastructure. These commands can:
167+
168+
- Execute Redis CLI commands against your instances
169+
- Run custom scripts or database queries
170+
- Call internal APIs or tools
171+
- Parse and format data for the agent
172+
173+
Edit your Unpage configuration (`~/.unpage/profiles/default/config.yaml`) to add the custom commands:
174+
175+
```yaml
176+
plugins:
177+
# ... existing plugins
178+
shell:
179+
enabled: true
180+
settings:
181+
commands:
182+
- handle: redis_memory_info
183+
description: Get comprehensive Redis memory statistics and configuration
184+
command: |
185+
redis-cli -h {redis_host} -p {redis_port} --raw INFO memory &&
186+
echo "---CONFIG---" &&
187+
redis-cli -h {redis_host} -p {redis_port} CONFIG GET maxmemory* &&
188+
redis-cli -h {redis_host} -p {redis_port} CONFIG GET save
189+
args:
190+
redis_host: The Redis server hostname or IP address
191+
redis_port: The Redis server port (default 6379)
192+
193+
- handle: redis_top_keys
194+
description: Identify the largest keys in Redis by memory usage
195+
command: |
196+
redis-cli -h {redis_host} -p {redis_port} --latency-history -i 1 > /dev/null 2>&1 &
197+
LATENCY_PID=$!
198+
redis-cli -h {redis_host} -p {redis_port} --bigkeys --i 0.01
199+
kill $LATENCY_PID 2>/dev/null || true
200+
args:
201+
redis_host: The Redis server hostname or IP address
202+
redis_port: The Redis server port (default 6379)
203+
204+
- handle: redis_memory_usage_history
205+
description: Get Redis memory usage metrics from the last 4 hours via DataDog API
206+
command: |
207+
curl -X GET "https://api.datadoghq.com/api/v1/query" \
208+
-H "Content-Type: application/json" \
209+
-H "DD-API-KEY: ${DATADOG_API_KEY}" \
210+
-H "DD-APPLICATION-KEY: ${DATADOG_APP_KEY}" \
211+
-G \
212+
--data-urlencode "query=avg:redis.info.memory.used_memory{host:{redis_host}}" \
213+
--data-urlencode "from=$(date -d '4 hours ago' +%s)" \
214+
--data-urlencode "to=$(date +%s)"
215+
args:
216+
redis_host: The Redis server hostname to query metrics for
217+
```
218+
219+
### Shell Command Best Practices
220+
221+
When creating shell commands:
222+
223+
- **Include error handling** with `2>/dev/null || echo "Command failed"`
224+
- **Use environment variables** for API keys and credentials
225+
- **Chain commands** with `&&` for sequential execution
226+
- **Parse output** to provide clean, structured data
227+
- **Add timeouts** for potentially long-running operations
228+
- **Document required permissions** and dependencies
229+
230+
## Step 6: Test and Deploy
231+
232+
### Local Testing
233+
234+
Test your agent with sample data before deploying:
235+
236+
```bash
237+
# Test with a sample alert payload
238+
$ echo '{"incident": {"title": "Redis Memory Usage Critical", "description": "redis-prod-cluster memory usage: 87.2%"}}' | unpage agent run redis_memory_alerts
239+
240+
# Test with a PagerDuty incident ID
241+
$ unpage agent run redis_memory_alerts --pagerduty-incident PXXXXX
242+
```
243+
244+
### Test Routing
245+
246+
Verify the router selects your agent correctly:
247+
248+
```bash
249+
# Test routing decision
250+
$ unpage agent route '{"incident": {"title": "Redis Memory Critical"}}'
251+
252+
# Debug routing with detailed explanation
253+
$ unpage agent route --debug '{"incident": {"title": "Redis Memory Critical"}}'
254+
```
255+
256+
### Production Deployment
257+
258+
Set up webhook handling for production alerts:
259+
260+
```bash
261+
# Local webhook server for testing
262+
$ unpage agent serve
263+
264+
# Public webhook with ngrok tunnel
265+
$ unpage agent serve --tunnel --ngrok-token YOUR_NGROK_TOKEN
266+
267+
# Production deployment (typically with reverse proxy)
268+
$ unpage agent serve --host 0.0.0.0 --port 8000
269+
```
270+
271+
Configure your monitoring system (PagerDuty, DataDog, etc.) to send webhooks to:
272+
- Local testing: `http://localhost:8000/webhook`
273+
- Ngrok tunnel: `https://your-tunnel.ngrok.io/webhook`
274+
- Production: `https://your-domain.com/webhook`
275+
276+
## Advanced Agent Patterns
277+
278+
### Multi-Step Analysis Agents
279+
280+
For complex scenarios, break analysis into phases:
281+
282+
```yaml
283+
prompt: >
284+
Phase 1 - Data Collection:
285+
- Gather all relevant metrics and logs
286+
- Verify the scope of the issue
287+
288+
Phase 2 - Root Cause Analysis:
289+
- Correlate data to identify potential causes
290+
- Rule out common false positives
291+
292+
Phase 3 - Impact Assessment:
293+
- Determine affected services and users
294+
- Estimate business impact
295+
296+
Phase 4 - Response and Communication:
297+
- Post detailed findings with evidence
298+
- Recommend specific remediation steps
299+
- Set appropriate incident priority
300+
```
301+
302+
### Conditional Logic Agents
303+
304+
Use conditional prompts for different scenarios:
305+
306+
```yaml
307+
prompt: >
308+
Analyze the alert and determine the scenario:
309+
310+
If memory usage > 95%:
311+
- Execute emergency memory cleanup procedures
312+
- Post CRITICAL update with immediate actions
313+
314+
If memory growth rate > 20% per hour:
315+
- Focus on identifying memory leaks
316+
- Examine recent deployments and configuration changes
317+
318+
If evicted_keys metric is increasing:
319+
- Analyze key eviction patterns
320+
- Recommend maxmemory policy adjustments
321+
322+
Otherwise:
323+
- Perform standard memory analysis
324+
- Post standard monitoring recommendations
325+
```
326+
327+
### Integration with External Systems
328+
329+
Agents can interact with any system your shell commands can reach:
330+
331+
```yaml
332+
tools:
333+
- "shell_slack_notify_team"
334+
- "shell_create_jira_ticket"
335+
- "shell_trigger_runbook_automation"
336+
- "shell_update_status_page"
337+
```
338+
339+
## Debugging and Iteration
340+
341+
### Monitoring Agent Performance
342+
343+
Use Unpage's built-in tracing to monitor agent execution:
344+
345+
```bash
346+
# Start MLflow tracking server
347+
$ unpage mlflow serve
348+
349+
# Run agent with tracing enabled
350+
$ env MLFLOW_TRACKING_URI=http://127.0.0.1:5566 unpage agent run redis_memory_alerts @test_alert.json
351+
```
352+
353+
View execution traces at `http://127.0.0.1:5566/#/experiments/1?searchFilter=&orderByKey=attributes.start_time&orderByAsc=false&startTime=ALL&lifecycleFilter=Active&modelVersionFilter=All+Runs&datasetsFilter=W10%3D&compareRunsMode=TRACES` to see:
354+
- Tool usage patterns
355+
- Execution timing
356+
- Error rates and types
357+
- Agent decision flows
358+
359+
## Best Practices Summary
360+
361+
1. **Start simple** - Begin with basic analysis, then add complexity
362+
2. **Test thoroughly** - Use various input scenarios and edge cases
363+
3. **Handle errors gracefully** - Include fallbacks for failed commands
364+
4. **Be specific in descriptions** - Help the router make correct decisions
365+
5. **Document dependencies** - Note required tools, permissions, and environment setup
366+
6. **Iterate based on results** - Refine prompts based on real incident responses
367+
7. **Monitor and improve** - Use tracing data to optimize agent performance
368+
369+
## Conclusion
370+
371+
Creating effective Unpage agents transforms reactive incident response into
372+
proactive, automated analysis. By following this systematic approach you can
373+
build agents that not only save time during incidents but also provide deeper
374+
insights into your infrastructure than manual investigation alone.
375+
376+
The key is starting with one well-defined use case, perfecting it through testing
377+
and iteration, then expanding to cover additional scenarios as you gain experience
378+
with the platform.
379+
380+
Remember: the best agents are those that encode your team's operational
381+
knowledge and decision-making processes, making your entire team more effective
382+
at infrastructure management.

0 commit comments

Comments
 (0)