I joined UiPath in July 2026 after 7+ years as a Developer Advocate at AWS. Just over a month in, and I've had to unlearn something I've depended on when building automations most of my career: that some of my steps in my code now have opinions. This is where non-deterministic has been creeping into the way I build things.
First, a confession: I spent the better part of a decade building systems whose entire appeal was that they did exactly what I told them to. Terraform plans. Lambda functions. Pipelines that either went green or red and produced the same output every single time given the same input. Determinism was the whole product. Enter stage-left: non-determinism.
TL;DR: the word "agent" has been stretched so thin it's basically transparent, and the most useful thing I've learnt isn't a product, it's a line: Work is now split into steps for known work (deterministic) and ones that benefit from judgement (non-deterministic). Almost everything in the UiPath agentic stack makes sense the moment you know which side of that line a given piece is standing on. These are my notes from figuring that out.
The line
Here's the trap I walked straight into: I assumed "agentic" meant "put an LLM in the middle and let it sort things out". So my first instinct was to reach for an agent for everything, including the parts that were an if statement wearing a very expensive hat.
Non-determinism is a cost, not a feature. You pay for it in latency, in tokens, and in the thing that actually matters at enterprise scale: explainability. When the finance team asks "why invoice #4471 got rejected", "it worked on my computer" "the model felt strongly about it" is not an answer anyone accepts. So the question for every step in a process becomes: does this step genuinely need judgement, or do I just not want to write the rules down?
This the the decision tree I ended up with:
Does this step need judgement?
β
βββββββββββββββββββ΄ββββββββββββββββββ
NO YES
β β
Is there an API? Can it be wrong?
β β
ββββββββββ΄βββββββββ ββββββββββ΄ββββββββββ
YES NO low stakes high stakes
β β β β
Coded Function RPA process Coded Agent Coded Agent
Python, typed, .xaml - drives LLM + tools, + human approval
no LLM the UI of that fully traced (Action Center)
1997 ERP
If you noticed the right-most branch for "Can it be wrong?" doesn't have the usual "Yes" / "No" branching, there is no option for "No", LLMs will always have a non-zero change of getting it wrong, this is the non-deterministic nature again. I keep coming back to this: "Agentic" in an enterprise doesn't mean "no humans." It means the human moves from doing the work to approving the interesting 4% of it where an incorrect decision has a high stakes impact, and the platform's job is to make that handoff a first-class node rather than a Slack message someone forgets to read.
The map
Now that we've covered the mental model, here's roughly how I've mapped out the different UiPath products. This is my mental version, not an org chart:
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Studio Web Β· Agent Builder Β· your own editor + the uip CLI β build
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β M A E S T R O F L O W β orchestrate
β the conductor - what runs, when, in what order, β
β and what happens when it goes wrong β
β β
β βββββββββββββ ββββββββββββββ ββββββββββββ βββββββββββββ β
β β Coded β β Coded β β Human β β RPA β β do the
β β Agents β β Functions β β approval β β processes β β work
β β (LLM) β β (no LLM) β β (HITL) β β (.xaml) β β
β βββββββββββββ ββββββββββββββ ββββββββββββ βββββββββββββ β
β β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Orchestrator Β· Integration Service Β· Data Fabric Β· IXP β ground
β jobs, queues, assets Β· SaaS connectors Β· entities Β· docs β floor
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β AI Trust Layer + Governance - policies, guardrails, audit β the adults
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
The part that surprised me is the bottom two layers. I came in expecting the agent frameworks to be the interesting bit, and they're genuinely good, but they're also the bit anyone can pip install. What you can't pip install is twenty years of "this connector handles the fact that integration Z's session tokens expire weirdly on Tuesdays". The ground floor is the moat, and the agentic layer is what finally makes it addressable by something other than a human clicking.
Coded Functions: the code you mostly know
A Coded Function is a deterministic unit of Python. Typed input, typed output, no LLM, no agent loop. You scaffold it with uip functions new <name> -l py, and it looks like this:
from pydantic import BaseModel
from uipath.tracing import traced
class Input(BaseModel):
invoice_id: str = ""
class Output(BaseModel):
is_valid: bool = False
error_type: str = "" # populated on failure, empty on success
error_message: str = ""
@traced(name="validate_invoice", run_type="uipath")
def validate_invoice(input: Input) -> Output:
out = Output()
try:
out.is_valid = matches_purchase_order(input.invoice_id)
except Exception as exc:
out.error_type = "FAILED"
out.error_message = str(exc)
return out
Two things to notice, because I used them incorrectly on my first attempts. First, errors are returned, not raised, you populate those error_* fields rather than letting the exception escape, because the caller might be a flow that needs to route on the failure rather than just die. Second, the @traced decorator: it makes the function show up in the platform's trace view alongside the LLM calls.
Similar to how you specify function name as the entrypoint for a Lambda function, set the filename + function name in uipath.json. This is used when deploying the solution to indicate it is a Function:
{
"functions": {
"main": "main.py:validate_invoice"
}
}
What is so special about a function: a Python Coded Function gets real job semantics: an Orchestrator job ID, retries, scheduling, an audit trail. It's not a helper buried inside an agent's context window where nobody can see it fail. It's a first-class citizen that a flow, an agent, a BPMN process, or a plain API call can all invoke. Every time I've been tempted to give an agent "just one more tool," the better answer has usually been a function.
Coded Agents: your framework, someone else's ops problem
When the step does need judgement, you write an actual coded agent in Python with the framework you'd have picked anyway: LangGraph, LlamaIndex, or OpenAI Agents. There's no proprietary DSL to learn. Your LangGraph graph is a LangGraph graph.
The interesting part is what your agent reaches for at runtime:
your Python agent (e.g. a LangGraph graph)
β
ββββββββββββββββ¬ββββββββ΄βββββββββ¬βββββββββββββββββ
βΌ βΌ βΌ βΌ
LLM Gateway Coded Function IS connector Context
model access, deterministic Salesforce, Grounding
keys, policy, helper you NetSuite, SAP, your indexed
BYO models already trust Workday, β¦ documents
β β β β
ββββββββββββββββ΄ββββββββ¬βββββββββ΄βββββββββββββββββ
βΌ
every hop traced, every call governed
You never put a model key in your code, you go through the gateway, which is also where BYO-model configs and policies live. Tools come from the same catalogue the rest of the platform uses, so create_process_tool lets an agent kick off an existing RPA process, and create_escalation_tool lets it hand a decision to a human in Action Center without you hand-rolling a task queue.
And then there's the part that made me genuinely happy, because it's the part everyone skips: uip codedagent eval runs your agent against an eval set with real evaluators before you ship it. The workflow assumes you'll write a smoke set. Tests for the non-deterministic parts, treated as table stakes rather than a blog post someone means to write. Coming from infrastructure, where "did the plan apply cleanly" was the whole test suite, I find this a healthy amount of paranoia.
Flow: where it stops being a demo
An agent on its own is a demo. A process is a sequence of steps with branching, retries, humans, deadlines, and a nasty legacy system at the end of it. That's Maestro Flow: a .flow project (JSON on disk, visual in Studio Web, either way it's a real artifact you can diff) that wires everything above into something a business will actually run on a Tuesday.
βββββββββββ
β Trigger β new mail lands in invoices@
ββββββ¬βββββ
βΌ
ββββββββββββββββββββ
β IXP extraction β pull the fields out of the attached PDF
ββββββ¬ββββββββββββββ
βΌ
ββββββββββββββββββββ
β Coded Function β validate + normalise
β validate_invoice β no LLM - same input, same answer, always
ββββββ¬ββββββββββββββ
βΌ
β amount > 10k or PO mismatch?
β
yes β no
ββββββΌββββββββββββ β
β Human approval β β
β (Action Center)β β
ββββββ¬ββββββββββββ β
ββββββββββββ¬βββββββββββββββββ
βΌ
ββββββββββββββββββββββββββββββββββββββββ
β Coded Agent: reconcile_discrepancies β
β LangGraph - reasons about the messy β
β cases, escalates when unsure β
ββββββ¬ββββββββββββββββββββββββββββββββββ
βΌ
ββββββββββββββββββββ
β RPA process β keys it into the ERP that has no API
β (.xaml) β and, let's be honest, never will
ββββββββββββββββββββ
Look at the mix in that diagram: exactly one node has an LLM in it. That's not me being conservative, that's the shape most real processes take. The agent earns its place on the messy branch, and everything else stays boring on purpose.
The bit that isn't visible in a diagram is what happens when it breaks. A running flow is an instance you can pause, resume, cancel or retry. Failures land as incidents with traces attached. The whole thing packages into a solution (.uipx) so the flow, its functions, its agents and their resource bindings are versioned and deployed together, instead of the alternative I know far too well, which is six repos, a Confluence page, and hope driven development.
What I'm poking at next
I'm just over one month in, so treat all of the above as field notes rather than doctrine, I'm still finding the sharp edges (and cheerfully filing feedback about them). Next on my list: pushing much harder on evals, because "how do you know your agent still works after you changed the prompt" is the question I think the whole industry is currently ignoring getting to, and MCP servers via AgentHub, where the tool-catalogue story gets a lot more interesting.
If you're a cloud/DevOps person eyeing this space and wondering whether the "agentic" hype is real: it is, but not in the way the marketing implies. It's not that everything becomes an agent. It's that you finally get to put judgement in a process without giving up the determinism of everything around it, and the interesting engineering is in drawing that line well.
Come tell me where I've got it wrong. I'll be in the comments.
Top comments (2)
The retry boundary is the part I would watch closest. A deterministic pipeline usually fails in a way you can replay. An agent can fix the input, call another tool, then leave a plausible transcript instead of a reproducible state transition. Iβd want the orchestration layer to treat each agent step like an external system call, with idempotency keys and a replay log. Did you end up drawing that boundary inside Maestro, or closer to each tool?
If You feel, that the whole industry does not have the answer, then that might be a very tough question