Special Offer

Get 3 months free of PEO*

articleIcon-icon

Article

1 min read

We Deployed an AI Agent to Parse Wage Garnishment Orders. Here's What We Learned About Making It Actually Work

Danilo Dimitrievski

Author

Danilo Dimitrievski

Last Update

September 22, 2026

We Deployed an AI Agent to Parse Wage Garnishment Orders
Table of Contents

The Problem

How It Works

Why the Plumbing Matters More Than the Model

Takeaway

When someone owes money they haven't paid, like child support or a debt, a court can order their employer to take it straight out of their pay. That order is called a wage garnishment, and it arrives as a PDF: a court document with creditors, withholding amounts, effective dates, bank details, and a dozen other fields that vary by jurisdiction. We built an AI agent to read them and extract the data in minutes instead of having someone hand-type ~30 fields.

One mistake in that data costs money. So this isn't a "cool AI thing". It's a "move real money correctly" thing. And that changes everything about how you build it.

The Problem

When a court orders that part of a contractor's pay be withheld, a client uploads the order as a scanned PDF or a photo. The document is a mess. Every jurisdiction formats it differently. Buried inside are the creditor, case number, fixed amount or percentage, cadence, effective and end dates, attorney contact, and the bank account the money must go to.

A human reads it, interprets it, and types it into our system. Around 30 fields. One wrong field and either the wrong amount gets withheld or the money gets sent to the wrong place.

We deployed an AI agent to do this in minutes. It's been running end to end in production since early September.

How It Works

The agent runs on Akai, Deel's platform for building reliable AI workflows. It's not just a prompt. It's orchestration, error handling, and async callbacks designed to let LLMs handle sensitive operations safely.
Here's the flow:

  1. A client uploads the garnishment order (PDF, scan, or photo, up to 15 MB). We validate it and hand it to the agent via a short-lived download link.

  2. The agent runs in JSON output mode against a strict schema that mirrors our garnishment domain model. It returns structured data or fails loudly. No halfway states.

  3. The call is async. Akai runs the agent and fires a callback when it finishes. Our backend fans that out over the event bus and the result lands on the record automatically.

  4. The client polls for updates. Done.

Why the Plumbing Matters More Than the Model

Most of the engineering work wasn't the prompt. It was the unreliable-dependency layer around it.

When you put an LLM into a workflow where the output moves money, you can't treat it like a web service that's always up and always correct. You have to treat it like a distributed system component that might time out, might fail, might respond late.

Three guardrails did the heavy lifting:

  1. Idempotent writes with compare-and-swap. If a callback arrives late and a timeout sweep fires at the same time, both try to finalize the record. The compare-and-swap guard ensures only one wins. No double writes, no silent failures.

  2. Explicit terminal states. The record moves through explicit states: pending, in progress, then completed or failed. A sweeper cleans up stale runs that never resolved. This forces you to define what "done" actually means instead of hoping callbacks arrive.

  3. Schema contracts over prose. The agent's output schema is the contract, not the prompt. If the model drifts, the schema catches it. Boring, but it's why we can iterate on the prompt and model without breaking what's downstream.

Most of the build time went into these three. They're not sexy. But they're why the agent is production grade instead of a demo. And because the callback plumbing and observability live in shared Akai tooling, the rough edges we hit became fixes for the next Deel team building an agent.

Takeaway

The LLM was the easy part. What made it shippable was treating the agent like any other unreliable external service, with timeout paths, explicit states, and schema contracts instead of hope.

If you've shipped an LLM in a workflow where the output moves real money, which guardrail mattered most to you? Compare-and-swap? Timeout paths? Explicit states? Or something else?

Danilo Dimitrievski

Danilo Dimitrievski is a Backend Engineer at Deel working on independent contractor contracts and invoicing. He builds the systems that turn contractor work into accurate invoices, from payment cycles and timesheets to adjustments and fees, and most recently shipped an AI agent for parsing wage garnishment orders on Deel's Akai platform.