# How I keep small agents from falling over

Source: https://aaronmakelky.com/reliability
Last updated: 2026-06-16

A note on the habits Aaron uses to keep small AI agent jobs from failing quietly, including fixed output, separate data fetches, logging, health checks, and shorter briefings.

Free note

Seven habits I use so one bad API call does not wreck the whole morning briefing.

Why I wrote this: my Raspberry Pi setup has broken in enough boring ways that the fixes started repeating. These are the patterns I keep reaching for when a small agent job needs to survive normal life.

## Pattern 1: fixed output shape

### Fixed structure, variable content

If I let a briefing invent its own format every morning, the next step has to guess what it is reading.

Instead of `"Write a morning briefing"`, use a template with fill-in sections:

```
## Morning Briefing: {{date}}

### Weather
{{weather_summary}}

### Schedule
{{calendar_events}}

### AI News
{{news_summary_3_items}}

### Markets
{{market_snapshot}}
```

The agent fills in `{{variables}}` instead of deciding the structure from scratch.

## Pattern 2: separate data fetches

### One API failure should mean one missing section

If the news API returns a 503, the whole briefing should not die. The failed section should say it is unavailable and the rest should still arrive.

Wrap each data fetch in its own error handler:

```
def fetch_weather():
    try:
        return get_weather_data()
    except Exception as e:
        return "Weather unavailable"

def fetch_news():
    try:
        return get_news_data()
    except Exception as e:
        return "News unavailable"
```

The briefing still delivers with one section marked unavailable instead of the whole thing failing.

## Pattern 3: backup check for missed runs

### A second check for missed runs

Your 6:40 AM cron fires the briefing. But what if the server was restarting at 6:40? You get nothing.

Add a heartbeat check. It asks, "did the daily briefing run today?" If not, it runs the briefing. One missed cron should not cost you the whole day's briefing.

The main job runs at 6:40 AM. A second check looks for a missing briefing and only runs it if the first one did not.

The exact interval matters less than the habit: one scheduled job checks whether the other one did its job.

## Pattern 4: keep going, log the failure

### Do not hide the miss

When one step fails, the agent should keep going when it can. It should also leave enough of a note that you can find the problem later.

- Each tool failure gets logged with timestamp, tool name, and error
- The daily output includes a brief "issues" section if anything failed
- A daily cron health check surfaces consecutive failures

That is how a broken API key becomes a fixable note instead of two days of missing output.

## Pattern 5: label the API keys

### One .env file, isolated keys

When you have 12 API keys and one expires, which one broke the workflow?

Structure your config so each integration has its own labeled section:

```
# .env
# Weather
OPENWEATHER_API_KEY=...

# News
BRAVE_API_KEY=...
GNEWS_API_KEY=...

# Calendar
GOOGLE_CALENDAR_CREDENTIALS=/path/to/creds.json
```

When something breaks, the labels tell you where to look first.

## Pattern 6: hard limits on output size

### Briefings should be brief

Your agent will happily produce 5,000 words if you let it. Telegram has message limits. Your attention has limits.

Hard constraints in the skill definition:

```
## Output Rules
- Total output: under 800 words
- Each section: 3-5 bullet points max
- Weather: 2 sentences
- News: 3 headlines, 1 sentence each
- Markets: numbers only, no commentary
```

The constraint is deliberate: if the briefing is too long to read, the workflow did not work.

## Pattern 7: one health check job

### One check for the scheduled jobs

You may not notice the agent is broken until you wonder, "why didn't I get my briefing today?"

Set up a health check cron that runs independently and reports:

- Which crons ran today
- Which ones failed
- Consecutive failure count
- Recommended action ("API key may need rotation")

This runs as its own job, separate from the automations it monitors.

## What this looks like in my setup

My current Raspberry Pi 5 setup uses:

- OpenClaw for the agent runtime
- Telegram for the daily delivery surface
- Scheduled jobs for briefings, intake, and health checks
- Separate data fetches so one broken API does not wreck the whole run

Every pattern above came from something breaking and then showing up again later.

## If you want an example setup

The OpenClaw bundle includes the morning briefing folder, setup notes, and related scripts. Use it as a reference setup before building your own.

- Morning briefing skill folder
- Setup notes for the required keys and services
- Related scripts where the workflow uses them
- Other skill folders you can compare against

[See the OpenClaw skills bundle](/shop) [Use the checklist first](/checklist)

Built by [Aaron Makelky](https://aaronmakelky.com). Small AI agent workflows that have to survive normal life.

## Related pages

- [OpenClaw kits](/shop)
- [AI workflow checklist](/checklist)
- [Tools](/tools)

## Sources and references

- [Cloudflare Workers](https://developers.cloudflare.com/workers/)
- [Raspberry Pi 5](https://www.raspberrypi.com/products/raspberry-pi-5/)
