Inspiration
US shippers lose an estimated $15.4 billion a year to improper freight detention and demurrage (D&D) charges — fees carriers bill when containers or trucks "sit too long," often in violation of the FMC's own 2024 billing-requirements rewrite (46 CFR Part 541). Disputing these charges is tedious, manual, and inconsistent: someone has to read the invoice, check it against the regulation, gather evidence, and decide whether it's worth fighting — invoice by invoice.
We wanted to know: could an agentic system do the judgment work — not just extract data, but actually reason about whether a charge violates federal regulation — and only pull in a human when the call genuinely needs one? That question became DisputeOps.
What it does
DisputeOps is a UiPath Maestro Case that takes a freight invoice from "just arrived" to "resolved," autonomously:
- Intake — extracts the invoice (IXP) and classifies the charge type (Agent Builder).
- Evidence — gathers the supporting facts (gate timestamps, tariff terms, force-majeure events).
- Analysis — three coded agents run in sequence: ComplianceAuditor audits the invoice against 12 FMC Part 541 rules, RecoveryOracle scores the probability of a successful recovery and recommends auto-filing, human review, or write-off, and DemandSmith drafts the demand letter.
- Approval — only when the case is genuinely uncertain, a human reviewer sees the verdict and the draft letter in an Action Center app and approves or rejects.
- Filing — the dispute is submitted; the carrier's response decides the outcome.
- Escalation — if the carrier denies the dispute or stays silent past a 7-day SLA, the case escalates to the FMC as a last resort, or loops back to Analysis for another look.
The result: routine, clear-cut disputes get filed automatically; only the judgment calls reach a person.
How we built it
We deliberately used UiPath's full agentic stack rather than one tool for everything:
- Coded agents (Python) for the reasoning layer — LangGraph for the 12-rule compliance engine (mixing deterministic checks like date math with LLM-assisted reads of free-text BOL terms and force-majeure language), Pydantic AI for the recovery scorer, LangChain for letter generation.
- UiPath IXP for document extraction, wrapped in a Maestro Flow with a native IXP node.
- Agent Builder for the charge-type classifier — including a deliberate
otherfallback so the agent surfaces uncertainty instead of guessing. - A Coded Action App (React, deployed via CLI) for the human-in-the-loop approval step.
- UiPath for Coding Agents (Claude Code) — we authored a solution-design spec and used Claude Code with UiPath's CLI skills to scaffold the entire Maestro case plan from that spec: the stages, the 12+ case variables, and the branching/rework logic. The coding agent even caught a real case-completion bug in our original design (three mutually exclusive terminal stages that, as originally modeled, could never all be satisfied) and fixed it.
The case itself models genuine non-linear case management, not a disguised flowchart: a rework loop sends denied disputes back to Analysis for re-evaluation, and Escalation to the FMC is modeled as an interrupting secondary stage that can break in from Filing on an SLA breach — the same pattern UiPath's own reference architecture uses for true exceptions.
Challenges we ran into
- Getting a document into a live case, properly. We initially assumed we'd need to seed invoice data to make the demo "just work" — but that felt like cheating the case-management story. We worked through several real options (Storage Buckets, SharePoint connectors, job attachments) before landing on the right pattern: wrap IXP in a Maestro Flow and trigger the case directly from a Google Drive file-created event, so a real invoice genuinely drives the case end to end.
- Threading data cleanly between agents. Our coded agents emit flattened, individually-typed outputs rather than one bundled object — which meant being deliberate about which case variables are scalars (the ones that drive routing) versus full JSON payloads (the ones that carry context), and writing defensive case-plan expressions so a missing upstream field never silently breaks a downstream agent's input.
- Knowing where to stop. Not every component could be a real production integration in the time available — we don't have a live TMS or carrier API to connect to. We made a deliberate choice: the agentic reasoning layer is fully real (the rules engine, the recovery scorer, the letter generator, the IXP extraction all do genuine work), while the surrounding RPA/API tasks for gate logs and carrier filing are built as clearly-labeled stand-ins for systems we don't have access to — an honest scope boundary rather than a hidden one.
- Internalizing what the coding agent built. Using coding agents to scaffold the case plan was a huge accelerator, but it meant deliberately spending time afterward making sure we could explain every design decision ourselves — not just that it worked, but why it's modeled this way.
Built With
- ixp
- langchain
- maestro
- python
- uipath
Log in or sign up for Devpost to join the conversation.