The most interesting code in Alibaba Cloud's Qoder refund-agent case study is not in the agent. It is in the Spring Boot service that decides whether the agent's answer may become a fact. The worker is thin: one SDK session per case, a skill describing the review, two Python scripts against an existing application, and a queue message that starts a review on case creation. Qoder supplies the runtime; the application keeps the records. The design is readable for the separation it enforces — the model proposes, the service disposes — and the candour about where that separation stops helping.
The agent sees what the case page already assembled. For DD-1041 the detail endpoint returns an amount of 129.0, version 0, a reason code, one photograph, and two policy entries marked HARD. get_case.py fetches that payload and downloads the image; SKILL.md explains how to compare claim, evidence, and policy; submit_review.py posts a decision or patches a note. The payload is small, typed, and versioned. Note what it lacks: any field for whether the photograph actually shows a shipping label.
The commit gate is server-side and conjunctive. A decision lands only if the case version still matches, confidence is at least 0.9, the amount is no more than 250 dollars, and policy findings are complete. Approvals add four conditions: full refund, matching identity, enough photographs, no pending seller-response window. Automatic rejection is narrower — a verified expired return window and nothing else. Everything outside those bounds becomes a note for a person.
Conjunction is the substantive choice. The four clauses guard different failure modes: state freshness, evidentiary completeness, financial exposure, and the model's uncertainty. They are not commensurable, which is why they are not folded into a score. A weighted total invites compensation — confidence of 0.99 offsetting a stale read, a small amount offsetting missing findings. Requiring every clause to pass leaves each with veto power and no exchange rate between them.
A high confidence number unlocks nothing by itself. In the reported live run the agent returned 0.93 on an 89-dollar claim and the decision committed, but the conjunction committed it, not the number. Confidence is a veto, never a vote. The threshold can therefore be moved without touching model or worker, since it is a comparison inside the service. It is also the weakest clause, resting on the model's self-report rather than on externally checkable properties of the case.
Version equality does the quiet work. The payload carries version 0 and the write is conditional on it still being 0. That is optimistic concurrency borrowed from database practice, and it blocks the failure agents are prone to: reading a case, reasoning at length, then writing about a world that has moved. A seller replying inside the 48-hour window bumps the case and the late write is refused. The post also notes an idempotency key on decision writes and a trace ID reused for redelivery — freshness and duplication handled separately.
The best move is the note path. A review note is appended without changing status, version, or update timestamp. A handoff cannot corrupt the record, and because it cannot, it costs almost nothing to take. Had handing off been as expensive as deciding, pressure would have run the other way: the worker would drift toward deciding and the human fallback would become a theory.
Authority is split three ways. The worker owns transport, authentication, queueing, and notification recipients; the backend owns permission; SKILL.md owns the procedure. Because procedure lives in a file rather than in worker code, policy text can be revised without redeploying the agent. The cost is that such text is revisable but not testable: editing it changes behaviour with no compile step and no type error, and the post describes no regression corpus for skill edits.
Coverage is where the architecture stops being general. Refund review admits crisp rules because its fields are enumerable: the amount is a number, the window is a date, identity is a field, photographs are countable, policy is codes with severity. The gate is not clever; it is legible. Automatic rejection is deliberately one condition wide, the right instinct for negative authority handed to software.
Where the policy finding is itself a judgement — whether damage is consistent with shipping, whether two photographs show the same item — the pattern degrades into a human queue with extra steps. The pipeline still spends a session, an image download, a skill load, a note write, and a notification to produce a note someone must read anyway. That can be worth it if the note saves more reviewer time than the queue costs. The post does not measure the exchange, and it decides whether the handoff is assistance or overhead.
The 0.9 threshold is a configured policy number, not a measured guarantee. Calibration is per-model and per-distribution, and the session sets the model to auto while the SDK supports routing lighter models to routine cases and stronger ones to ambiguous evidence. The model behind the number can therefore differ between runs, so a threshold tuned on one does not transfer automatically. The post gives one decision at 0.93, no sample size, no evaluation method, and no false-approve estimate, and states plainly that these runs are not an accuracy score.
The point that a caption is not proof a label is visible names a mismatch the architecture cannot fix. The evidence object is structured — kind, URL — but its evidentiary value is not. A photograph is a container; whether it contains what the claim depends on has no field to record. Prompt text can instruct caution and nothing more. In the 129-dollar case the agent paused, which is caution rather than verification: what stopped it was the open seller window and its own hesitation, not a check on the artifact.
What transfers is the commit gate, the version check, the free fallback write, and policy kept in data. What does not is rule coverage, a property of the domain rather than of the pattern, and the 250-dollar cap, which is loss containment rather than competence. A cap makes a system safe by keeping it small: it bounds the damage of a wrong approval and says nothing about whether the reasoning was right. On a larger claim it routes everything to a person.
Four quantities would need measuring before the pattern can be called working: block rate per clause, which separates a concurrency problem from a reasoning problem; human-queue rate, which prices the fallback; stale-version conflict rate, which shows whether the freshness check is load-bearing; and false-approve rate, which requires sampling approved cases against ground truth and is the one nobody wants to pay for. A fifth, note-to-decision conversion, would show whether the notes are useful.
The transferable idea is an asymmetry of authority: the model may read and propose, the service may commit. The queue, the skill, and the notification are plumbing around that split. The gate itself is a few dozen lines of ordinary server code, which is the encouraging part — what is worth copying is small, boring, and auditable.
Sources: Alibaba Cloud Blog, "Stop rebuilding your app for AI — add an agent instead", https://www.alibabacloud.com/blog/stop-rebuilding-your-app-for-ai--add-an-agent-instead-_603680