Skip to content

Build the Seven Agents (Block 3c)

Seven checks in the process need judgement, and there are seven because different departments and business owners control them. The contract asks for seven low-code Agents, one per family of business rules, named in contracts/components.md. Nothing else is built here: the deterministic work is already deployed as the provided processes, or belongs in the downstream case as an expression.

Why low-code, and why before the case? The exercise is about a process that uses judgement where the business needs it, not about agent frameworks. And Agents are the only component testable in isolation, so building them first gives the case block one authoring pass against things that already exist and answer.

The prompt

Prompt — block 3c · Agents
# Build — the seven Agents

**Seven agents, one per `PDD.md` §7 section — `contracts/components.md` names them and what each owns.** Nothing else is built here: the deterministic work is already deployed as the six provided RPA processes, or belongs in the Maestro Case as a connector activity or an expression.

Use the **`uipath-agents`** skill (low-code Agents). All seven inside your one solution — the Maestro case binds only Agents that live alongside it.

What each one must decide is `PDD.md` §7, by rule id. Do not re-derive it and do not soften it: those rules are what the Verify block tests.

Three things decide whether these are usable:

- **One concern, one owner.** An Agent may cite another Agent's finding as evidence; it may never re-raise it as its own. A reviewer sees every finding at once, so the same problem reported three times reads as three problems.
- **A finding must be visible to whatever reports it.** Before writing any check, ask whether that data actually reaches that component at that point — not whether it is on the document somewhere. An Agent asked to confirm something absent from its own input can only report it missing, confidently and wrongly.
- §7.9 says what to leave alone and which claim should settle by itself. Agents that only implement §7.1–§7.8 flag something on every claim.

**Done when:** 
- each one runs on a real claim and returns what §7 says it should, including on a claim with nothing wrong, where the right answer is that it found nothing
- every Agent that computes a figure returns the same figures on three runs of identical inputs, and each figure agrees with its own copies — claimed against the form, net against its envelope (`cookbook.md`)
- solution is uploaded (`uip solution upload Build/ClaimCase-<seat>`), so all seven Agents open in Studio Web inside it. Everything you build is local until that upload.

Steps:

  • Check uip login status and the solution status
  • Read the low-code agent reference files from the skill
  • Build the EligibilityScreening agent (BR-01–BR-05)
  • Build the AssessmentReportValidation agent (BR-06–BR-09)
  • Build the CoverageAnalysis agent (BR-10–BR-16)
  • Build the SettlementCalculation agent (BR-20–BR-29)
  • Build the CredibilityAssessment agent (BR-30–BR-33)
  • Build the DecisionRecommendation agent (BR-40–BR-45, BR-60–BR-62)
  • Build the ClaimantCorrespondence agent (BR-50–BR-52)
  • Test each agent with uip agent debug
  • Upload the solution to Studio Web
  • Update PROGRESS.md

What the agent will review

  • A prompt governs what an agent reports, never what it concludes. Whether a claim reaches a human is a case condition over the outputs these Agents emit (a flag count, a risk level, a net payable), never a sentence in a prompt.
  • A typed output field beats a paragraph of prompt. When a payload must contain a fact, we declare it as a field in the output schema. A model fills a declared field reliably; prose asking it to be careful competes with every other sentence.
  • One concern, one owner. An Agent may cite another's finding as evidence; it may never re-raise it as its own. The reviewer sees every finding at once, and one problem reported by three Agents reads as three problems.
  • PDF documents reach an Agent as job attachments, never as extracted text. A policy's meaning lives in clause wording that flattening loses. Agents carry the built-in document reader for exactly this reason.
  • Field order is part of the prompt. A model writes its output in order, so the fields that constrain a verdict come before the verdict. Rewording rarely fixes an agent that stops at the first rule; moving the constraining field first does.
  • Never end in an error. An agent that cannot read an input still returns every field, with -1 for a figure it could not read, so the claim reaches a person instead of faulting the case.
  • Text a person reads is plain. Reasons and letters carry no field names, no JSON and no em dashes, and amounts carry thousands separators.

The gate

One real invocation per Agent, on a real claim, with uip agent debug: it must return what its §7 section says, including nothing at all on a clean claim. A grader's score is about structure and wording; only a run answers whether the agent does the thing.

Every agent that computes a figure runs three times on identical inputs and returns the same figures each time, and each figure agrees with its own copies: claimed against the form, net against its envelope. Temperature 0 does not make an agent deterministic; the repeat run is how you find out.

This workshop writes no evaluation sets for the Agents; Verify tests all seven end to end, on claims with planted problems. On a real project, give each Agent its own set: real inputs with their accepted outputs, re-run whenever its prompt or its model changes. It is Verify's baseline, one Agent at a time.

Proof

The outcome of this block, open in Studio Web, with all seven Agents inside the solution and EligibilityScreening showing what a built one looks like:

All seven Agents in the solution in Studio Web — EligibilityScreening open with its stepped system prompt, the Analyze Files tool, and typed inputs

The lesson's rules are visible in the build: the system prompt works in named steps and tells the agent to call Analyze Files on the policy exactly once, and never on the claim form ("the claim form already reaches you as structured data"); the user prompt carries typed inputs (claimData, claimFormDocument), not pasted text.

Each of the seven runs on a real claim and answers per its rules; the solution is uploaded, and all seven open in Studio Web.

What an Agent hands back

A typed output field beats a paragraph of prompt, and this is what that means in practice. Here are three real envelopes from real claims: what the case actually routes on, and what "found nothing" looks like when it is a real, populated answer.

What to notice: "found nothing" is not an absence; it is a populated, typed answer. Every rule has a verdict and the evidence it read; BR-03 even explains why a blank State field is correct for Singapore, not a data gap. A clean claim never shows a screen, so this envelope is the only place you ever see restraint working.

{
  "result": "Pass",
  "failed": [],
  "checks": [
    { "id": "BR-01", "name": "Policy status", "result": "Pass",
      "reason": "Policy quotes 'Payment Status | Current - Paid in Full' and 'Policy Period | 09/08/2025 to 09/08/2026'; loss occurred 2026-08-09, within the paid, in-force period." },
    { "id": "BR-02", "name": "Identity", "result": "Pass",
      "reason": "Claimant 'Sarah Chen Wei Ling' matches policyholder 'Sarah Chen Wei Ling' exactly." },
    { "id": "BR-03", "name": "Address", "result": "Pass",
      "reason": "Claim address 'Blk 234 Toa Payoh Lorong 1, #12-456, Singapore, 310234' matches policy's insured address exactly; missing State field reflects Singapore having none, not a data gap." },
    { "id": "BR-04", "name": "Coverage period", "result": "Pass",
      "reason": "Incident date 2026-08-09 falls within policy period 2025-08-09 to 2026-08-09 inclusive." },
    { "id": "BR-05", "name": "Filing deadline", "result": "Pass",
      "reason": "Incident 2026-08-09 to submission 2026-08-11 is 2 calendar days, well within the 60-day deadline." }
  ]
}

What to notice: the agent shows its arithmetic and names the evidence. The annual aggregate is Bound, the remainder and the prior claim that consumed it are stated, and the cap it forces is shown line by line. aggregateStatus and the capped netPayable are exactly the scalars the case routes on.

// settlementJson — the ledger
{
  "currency": "AUD",
  "basis": "replacement cost",
  "arithmetic": {
    "dwellingCapped": 28500, "otherStructuresCapped": 3200, "personalPropertyCapped": 3800,
    "base": 35500, "deductible": 5000, "afterDeductible": 30500,
    "lossOfUseCapped": 0, "netPayable": 30500
  },
  "lines": [
    { "item": "Roof - Main House", "section": "Dwelling", "claimed": 18500,
      "assessorEstimate": 19696.47, "covered": true, "capApplied": "none", "payable": 18500 },
    { "item": "Gutters - Main House", "section": "Dwelling", "claimed": 4800,
      "assessorEstimate": 5487.80, "covered": true, "capApplied": "none", "payable": 4800 }
    /* … 3 more lines */
  ]
}

// payoutChecksJson — the check that carries the evidence
{
  "aggregateStatus": "Bound",
  "aggregateRemainder": 27796,
  "priorClaimsTotal": 159704,
  "reasonablenessFlag": false,
  "claimedTotal": 35500, "assessedTotal": 37485.98, "ratio": 0.947,
  "capsApplied": [
    { "line": "Personal Property section",
      "cap": "annual aggregate (187500, prior claim CLM-2026-527352 paid 159704, remainder 27796)",
      "from": 35500, "to": 30500 }
  ],
  "notes": "Aggregate remainder (27796) is below combined base (35500), so aggregate binds: effective covered base reduced to 27796 before deductible. Claimed total is below assessed total, no reasonableness flag. Deductible 5000 applied once to base."
}

What to notice: conclusion: "Escalate" is the routing scalar, and contradictions[] carries both statements, verbatim, so the human sees exactly what conflicts without re-reading the report. The claim reaches the adjuster with the reason already assembled.

{
  "conclusion": "Escalate",
  "belongsToThisClaim": true,
  "missing": [],
  "contradictions": [
    "'The overall structural integrity of the property was not affected by the incident.' vs 'Physical damage to the property includes compromised door frames, damaged locking mechanisms, and broken window glass at the entry point.'"
  ],
  "claimedItemsPriced": true,
  "notes": "Report matches claim PCL-5662627, property, and incident date; all claimed items priced. However, an internal contradiction exists regarding whether structural integrity was affected, requiring escalation for clarification."
}