Day 34: EventBridge as the Agent’s Async Backbone

Day 34: EventBridge as the Agent's Async Backbone

If a tool takes three minutes (terraform plan, warehouse query, image build), do not hold the Bedrock turn open. Emit an event, return a correlation id, and let the agent poll get_job — or resume via Step Functions callback. Day 34 makes EventBridge the async backbone.

⚡ TL;DR: Sync tools for <2s work; async via EventBridge for longer. Persist job state in DynamoDB with idempotency. Teach the model the start/get contract; cap polls in the graph.

Pattern

start_job(args, idempotencyKey)
  → DynamoDB PENDING (conditional)
  → PutEvents JobRequested
  → return {jobId}

Worker rule → run → SUCCEEDED|FAILED + result pointer
get_job(jobId) → status for next agent turn
import uuid, time, json, boto3
ddb = boto3.resource("dynamodb").Table("AgentJobs")
eb = boto3.client("events")

def start_job(tenant: str, tool: str, args: dict, idem: str) -> dict:
    job_id = str(uuid.uuid4())
    try:
        ddb.put_item(
            Item={
                "pk": f"tenant#{tenant}",
                "sk": f"idem#{idem}",
                "jobId": job_id,
                "status": "PENDING",
                "tool": tool,
                "createdAt": int(time.time()),
            },
            ConditionExpression="attribute_not_exists(sk)",
        )
    except ddb.meta.client.exceptions.ConditionalCheckFailedException:
        prev = ddb.get_item(Key={"pk": f"tenant#{tenant}", "sk": f"idem#{idem}"})["Item"]
        return {"jobId": prev["jobId"], "deduped": True}
    eb.put_events(Entries=[{
        "Source": "agent.tools",
        "DetailType": "JobRequested",
        "Detail": json.dumps({"jobId": job_id, "tenant": tenant, "tool": tool, "args": args}),
        "EventBusName": "agents",
    }])
    return {"jobId": job_id, "deduped": False}

Why EventBridge

Rules fan out to workers, metrics, and security audit without hard-coding consumers. You can still target SQS for buffering. Schema discipline prevents silent payload drift.

Production checklist

  • [ ] Job table with status enum + TTL
  • [ ] Idempotency on start_job
  • [ ] DLQ on worker failures
  • [ ] Prompt/tool docs describe async contract
  • [ ] Trace jobId across EventBridge → worker
  • [ ] Poll cap in Step Functions / agent loop

Series navigation

← Day 33 · Day 35 →

Last updated September 11, 2026


Discover more from CheatCoders

Subscribe to get the latest posts sent to your email.

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply