Show HN: SafeAgent – exactly-once execution guard for AI agent side effects

I built a small Python library called SafeAgent that protects real-world side effects when AI agents retry tool calls.

One issue we ran into while experimenting with agent workflows is that retries can trigger irreversible actions multiple times:

agent calls tool ↓ network timeout ↓ agent retries ↓ side effect happens twice

Examples:

• duplicate payment • duplicate email • duplicate ticket • duplicate trade

Most systems solve this ad-hoc using idempotency keys scattered around different services.

SafeAgent centralizes this into a small execution guard.

The idea is simple:

1. every tool execution gets a request_id 2. SafeAgent records the execution receipt 3. retries return the original receipt instead of running the side effect again

Example:

FIRST CALL REAL SIDE EFFECT: sending email

SECOND CALL WITH SAME request_id SafeAgent returns the original execution receipt (no second side effect)

The project is early but includes examples for:

• OpenAI tool calls • LangChain style tools • CrewAI actions

PyPI: https://pypi.org/project/safeagent-exec-guard/

GitHub: https://github.com/azender1/SafeAgent

Curious how other people are handling retry safety for agent side effects.

3 points | by Lions2026 4 hours ago

2 comments

  • guerython 2 hours ago
    We hit the same failure mode while running agents through n8n. Every tool call writes (request_id, tool, input_hash, response) into Postgres with a unique constraint. The guard query grabs that row first; if it already exists with a success flag we return the stored receipt instead of re-running the side effect. That way retries from the agent loop, HTTP transport, or queue worker may replay the cached payload and skip the duplicate action. Storing the error state alongside the success payload was the hardest bit so we don’t swallow a real failure while pretending it succeeded.
  • Lions2026 4 hours ago
    A bit more context on why I built this.

    While experimenting with LLM agents calling tools, I ran into a reliability problem: retries can easily trigger irreversible actions more than once.

    For example:

    agent → call tool network timeout → retry agent retries tool call side effect runs twice

    That can mean:

    duplicate payment

    duplicate email

    duplicate ticket

    duplicate trade

    Most systems solve this locally with idempotency keys, but in agent workflows the retries can come from multiple layers (agent loops, orchestration frameworks, API retries, etc.).

    SafeAgent is a small execution guard that sits between the agent and the side effect. Every tool call gets a request_id, and SafeAgent records a durable execution receipt. If the same request is replayed, it returns the original receipt instead of executing again.