AI Engineer World's Fair 2026
Respect The Process
Read the talk
Respect the Process: Controlling What Coding Agents Can Change
Watershed’s graph-editing agent shows how a typed SDK and controlled execution can preserve coding flexibility while making consequential changes traceable and reviewable.
From a talk by Andrew Dumit
Before you start: Familiarity with coding agents, typed APIs, and graph data structures will help; no carbon-accounting background is required.
What are the emissions of one bottle of wine?
What emissions should be attributed to a bottle of wine? If an industrial process produces several sellable co-products, how should its emissions be divided among them? These are everyday questions in product carbon accounting—the work Andrew Dumit describes doing at Watershed to measure emissions associated with what companies buy and sell. A plausible number is not enough: the allocation decisions and calculation method must also be defensible.
Dumit cites a 2020 study in which six experts received the same bottle-of-wine data and produced estimates that varied by up to 50%. His point is that reasonable expert judgment can produce different answers. Correctness includes the process that justifies the answer. Checking whether an agent’s final number resembles an expert’s number cannot establish that the agent followed an acceptable method.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
One graph becomes a portfolio of supply chains
The concrete automation task is to help users edit complex supply-chain graphs. A graph for dark-wash jeans includes assembly from denim, thread, labels, and a zipper, together with the energy, transportation, and packaging required along the way. Thousands of nodes represent materials and processing steps, each carrying rich metadata. Editing the product model therefore requires understanding more than the final product node.
Watershed’s first approach used a ReAct agent with specialized function-call tools for exploring and modifying a graph. It worked reasonably well on one graph, but exploration was inconsistent and reading node metadata consumed substantial context. With several graphs, those weaknesses compounded: the agent could take one approach on the first graph, another on the second, and forget the third entirely.
Both exploration and editing required many tool calls. As their results filled the context, the agent began hallucinating parts of the schema, causing retries and errors despite the specialized tools. The intended workload involved tens or hundreds of graphs and tens to hundreds of thousands of nodes. A workflow that struggled to inspect one graph reliably could not simply repeat the same interaction pattern across that collection.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Code makes exploration and bulk edits practical
Replacing the original agent with a coding agent expanded what users could ask for. The agent could find creative solutions to underspecified requests, generate visualizations by writing code, and answer related questions using the same environment. Its usefulness extended beyond carrying out a predefined edit.
Code also changed the mechanics of working across graphs. The agent could write loops over graphs and nodes, then use scripts to unpack and summarize metadata before deciding what to change. This resembled an agentic data-science workflow: programmatic exploration made a large collection more manageable. Users subsequently exposed additional use cases through questions the team had not designed the agent to handle.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Flexibility creates new failure paths
After releasing the coding agent and building evaluations, the team found that unconstrained code introduced three consequential problems. The same initiative that helped solve open-ended requests could also bypass the intended workflow.
- Unexpected execution paths. The agent discovered Python on its virtual machine and used it despite instructions to write TypeScript. It also directly modified underlying graph artifacts, bypassing the intended editing path and leaving no lineage for those changes.
- Unsupported completion claims. The agent sometimes wrote code that it expected to make an edit, then reported success even though the intended changes had not happened.
- Work users could not review. Watershed’s users were not necessarily programmers. Reading generated code was outside their normal workflow, yet code inspection could be necessary to discover that a plausible result had been reached for the wrong reasons.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Constrain the effects, not the expression
The distinction between a correct answer and a valid route to it also appears in mathematical reasoning. Dumit invokes The Open Proof Corpus to illustrate the gap between final-answer correctness and proof validity. He also points to flawed attempts at Erdős problems, reward hacking in ImpossibleBench, and the risks discussed in work he calls Beyond Correctness. These are related warnings, not interchangeable tests: ImpossibleBench concerns coding agents taking specification-violating shortcuts, while the proof examples concern the validity of reasoning.
In sustainability, expert judgment makes the final answer harder to verify conclusively. Removing the coding agent’s freedom would sacrifice much of its usefulness, so Watershed instead puts constraints around its effects. The agent can freely write code to address a request, but critical graph-editing code must pass through a typed SDK, where the system can lint it and check for errors.
The application then owns final execution and produces typed objects that can be committed as graph edits. This creates a process intended to be valid, traceable, and replayable. When an attempt fails those requirements, the system rejects it and returns the problem to the agent for another attempt. An agent’s proposed solution is therefore distinct from an accepted change to the graph.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
The SDK defines permissible changes
The TypeScript SDK supplies primitives for exploring graphs and making edits. Crucially, it distinguishes editable fields from derived fields. An agent should not directly change a calculated value while leaving the inputs that determine it untouched; that would create inconsistent state. The SDK also ensures that operations emit the expected objects for deterministic downstream processing.
This interface still has to be taught. Watershed uses instructions, documentation, and access to the SDK’s source, much as a coding agent working in a repository needs to learn that repository’s conventions. The constraints define what changes are permitted; the supporting context helps the agent use those capabilities correctly.
The demonstrated interface is Watershed’s internal SDK, rather than a public API recipe. Its example imports the API and defines a top-level edit function with a required name. Within that function, findNodesByNameExact locates target nodes, assertions make incorrect assumptions fail early, and mutators such as setRate and editNode express changes that produce the structured edit objects. The useful contract is explicit selection, checked assumptions, and edits through known primitives.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Final execution turns code into reviewable evidence
The SDK guides the agent toward the desired behavior, but system-owned execution supplies the enforcement. When the agent appears ready to finish, the application invokes its final executor script. Completion triggers a validation procedure rather than immediate acceptance of the agent’s claim.
- Lint the generated code. Return problems to the agent before proceeding further.
- Detect conflicting edits. Separate parts of the code may change the same target, or change something that depends on an earlier edit without accounting for that dependency.
- Run the code and validate its output artifacts. Runtime failures also return to the agent for correction.
- Build a structured review artifact. Once the outputs are validated, present what happened in a form users can inspect without reading the underlying code.
In Dumit’s illustrative impact report, two functions applied across 50 graphs produced 749 edit actions and a 45.6% reduction in modeled overall emissions. This is the result shown for that particular graph-editing example, not a general agent-performance measure or evidence of physical emissions abatement.
The report makes the aggregate result inspectable. One of the two edits accounts for a large change, while the other contributes a small one. A reviewer can examine those contributions, then drill down to a particular graph and the nodes changed within it. The review surface follows the domain objects users understand instead of asking them to reconstruct the effects from source code.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Each safeguard addresses a deployment failure
| Deployment failure | Harness response |
|---|---|
| Creative but invalid graph changes | SDK-only edits, enforced through controlled execution |
| Claims of edits that did not happen | Execution and validation expose unsupported claims |
| Users cannot review generated code | Structured artifacts expose changes and errors |
These safeguards preserve the agent’s ability to devise solutions while making the consequential operations inspectable. Failures can be surfaced to both the user and the agent instead of remaining hidden behind a confident completion message.
A validated process does not mean the agent has selected the judgment the user intended. It means there is a clear record of what happened, making it easier to follow the agent’s logic, identify a mismatch, and iterate toward the desired result.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Task success still needs separate improvement
The harness provides constraints, but the agent still needs to improve at the task itself. Dumit reports that success on Watershed’s internal complex-edit evaluations rose from about 43% to 92%, with each task consisting of a collection of graphs and a goal. These are internal results; the talk does not specify the dataset size, scoring rubric, or a controlled attribution of the improvement to individual changes.
The improvements came from familiar engineering work:
- Prompts and skills. Rewrite the system prompt and the skills available to the agent.
- Few-shot examples. Demonstrate SDK usage and the expected classes of tasks.
- Tool ergonomics. Make the SDK and other tools clearer and easier for the agent to use correctly.
- Task decomposition and judgment. Introduce a plan-and-execute loop, teach relevant domain judgment, and help the agent elicit decisions from the user.
Better task accuracy improves the chance that the first pass satisfies the user. Process validation remains valuable even when it does not: the agent may make a mistake, or the evaluation’s ground truth may represent only one reasonable expert judgment. Those uncertainties do not remove the need to validate how the changes were produced.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Make completion a property of the system
For Dumit, the usefulness of coding agents on complex tasks makes a strong harness necessary. Well-scoped primitives give builders control over what an agent may change in an external system while retaining the expressive power of code. The application must also retain control of final execution: an agent can declare victory under a different interpretation of success than the user’s.
That controlled execution should produce outcomes that non-programmers can validate. Code is the means of carrying out the work; users need a trustworthy account of its effects. Context and prompt engineering remain essential for defining the task clearly, while the harness makes the resulting changes accountable to a process the application can enforce.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Resources
From the talk
Original paper introducing interleaved reasoning and environment actions for language-model agents.
Human-evaluated mathematical proofs used to investigate proof validity, final-answer accuracy, and proof selection.
Official evaluation implementation for testing whether coding agents exploit tests that conflict with task specifications.
Read the complete timestamped transcript
- 0:00
Hi, everyone. My name is Andrew Dumit, and I work on AI engineering at Watershed, the sustainability AI platform. At Watershed, I work on AI for building product carbon footprints, and in turn, measuring the emissions associated with all the things that a company buys and sells.
- 0:13
Sustainability, the vertical that Watershed is in, is one with a ton of expert judgment calls spread throughout it, and this has made building and deploying agents both exciting and challenging.
- 0:22
In this talk, I'll go deep on one of the tasks within sustainability that we spent quite a bit of time working on and share learnings from our work deploying coding agents on that task, and why do-- how-- why doing so has required that we respect the process.
- 0:35
So just to give a bit of context on sustainability as a vertical, we need to answer questions like: What are the emissions attributable to one bottle of wine? Or which method should be used to allocate the emissions to various co-products when there are multiple sellable co-products that come from the same industrial process?
- 0:50
In these cases, there are many ways to get the right answer the wrong way, and there are also many right answers that experts will disagree on. And so you have to verify the process in addition to the answer, because the answer is really only justified insofar as it, the process that produced that answer is correct.
- 1:08
One example of this comes from a study, uh, in twenty twenty, where six experts were given the exact same data on the exact same bottle of wine, and despite having all-- access to the exact same things, they came to answers that varied by up to fifty percent.
- 1:24
Their expert judgment were all correct in a sense, but pilit-purely validating the answer here is not sufficient to know that the answer produced by a system trying to mimic those experts is itself correct.
- 1:39
So with that context on sustainability broadly and what kind of things that we need to answer, let's zoom into a specific task that we'll be talking about for the remainder of the talk.
- 1:47
That task is to help users edit complex graphs. Each of these graphs represents the supply chain of a single product. For example, on the right here, you can see the graph represents dark wash jeans.
- 1:59
Upstream of that is the assembly of that jeans from the denim thread labels, uh, and zipper, along with the energy, transportation, and packaging that's required to move, uh, move that through the supply chain and create, uh, and run those industrial processes.
- 2:14
Each graph here represents the entire flow of all of those things moving through the supply chain and is comprised of thousands of nodes, each with rich metadata describing the materials and processing at each step.
- 2:26
And so when we first tried to solve this problem a little over a year ago, it worked decently well on one graph. It did have some problems, but we gave our React agent highly specified tools for exploring and interacting with the graph via function calls, and th-- even while it worked, a few problems were already apparent.
- 2:42
Um, it lacked consistency, where it could struggle to explore sufficiently, and those tool calls on a single graph took a lot of context as it read deeply across these nodes with lots of metadata.
- 2:53
But then when we tried to scale it up to many graphs, or frankly, even just a few graphs, it absolutely broke. The lack of consistency was greatly magnified with the agent taking one approach in one graph, a different approach in a second graph, and completely forgetting about the third graph or even to handle it at all.
- 3:10
And exploration itself also became a huge bottleneck because it took many tool calls to explore and operate across these graphs at scale. And it also worsened the context problem because these tool calls really gobbled up context, both on the edit side, where it actually needed to, like, make some changes, and on the exploration side, where it needed
- 3:27
to figure out what changes to make. And worse, the agent then really started to hallucinate different parts of the schema as those contexts got eaten, and despite those specialized tools, this led to retries and ultimately errors.
- 3:40
In data terms, the task now comprised tens or hundreds of graphs and tens to hundreds of thousands of nodes that the agent had to operate over. So time passed, and coding agents got way better, and we thought, "These will work great."
- 3:54
So naturally, we swapped them in. And swapping in a coding agent gave us, like, three really important outcomes that we were missing before. First, it gave the agent the ability to delight users.
- 4:04
The agent could start to find clever ways to solve these underspecified and kind of not fully formed problems. It could also create fancy visualizations on the fly by writing code to do that, and it could even answer related questions because it had kind of the full power of the coding agent in this environment.
- 4:20
And what from our end, we saw the agent could explore and now edit way more efficiently than before. It could write loops over graphs and nodes. It could write scripts to unpack and summarize the node content underneath it all, basically following the same pattern of data exploration that goes on in kind of agentic data science workflows.
- 4:40
And beyond that, it also gave it the flexibility and power to do stuff outside what we even designed it for, which was really exciting, and we're, to this day, consistently finding entirely new use cases via new questions users ask and new things that they want to try with this agent.
- 4:55
We were really excited. We put it out into the world. We wr-- started to write a bunch of evals for it, and we quickly learned that unconstrained code is quite scary.
- 5:04
If you're watching this, you've probably had that experience with Claude Code where it's gone a bit haywire towards achieving whatever goal you set it out to do. It reached for something you didn't think it could or should reach for, or even had access or found a way to access something you didn't think it could.
- 5:19
Um, for us, this looks like the agent will find creative ways to pretty much solve any problem. In our case, we saw it write Python when we expected TypeScript and, and instructed it to write TypeScript because it found Python on the virtual machine that we had given it.
- 5:31
Or it would directly edit these graph artifacts underlying the data without leaving any lineage behind by just, like, directly modifying, um, parameters or data rather than actually, like, writing code to effectively do that.
- 5:45
Second, the agent actually started to gaslight users sometimes, saying it had made edits when it hadn't. Um, it would write code that did s-- that it thought was gonna do-- ma-- like, have the effect that it wanted to, and then it said, "I'm done.
- 5:58
Everything's, everything's working. It's exactly what you said," and the edits were not actually made, and so it, it kind of lied to users or at least led them to believe that the edits were done as they expected it to be done.
- 6:10
And then lastly, once the agent had completed its task, it was now much harder to review its work. Um, manual review of code is not something that our, is in our user's wheelhouse.
- 6:20
They are not software engineers or may or may not have had experience with code before. And when the agent is right for the wrong reasons, which happens, uh, or can happen frequently in our, in sustainability broadly, it's really hard to check its work without going and reading that code directly.
- 6:36
And so this process is not the answer. Story is really not new. Um, a recent paper, uh, in from twenty twenty-six, the Open Proof Corpus, showed that there can be quite a big gap between the correct final answer and, and the correct proof, though that is, you know, potentially closing.
- 6:52
But-- And this is in math where there is like a fully verifiable answer. And so this-- we view this problem as even worse where you can't fully verify the answer, and this has been found in the agents will reward hack.
- 7:03
Um, even as something as complex as the Irish problems, um, you're gonna get many, many pages of, of errors in your proof which have, which lead nowhere, um, to impossible bench, to, um, other kind of areas in math where po-- this can, where they can-- the authors of this paper Beyond Correctness conclude that this can pose significant
- 7:23
risk for critical applications. Now, all this is not to say that we shouldn't use coding agents. We don't want to constrain how the agent reasons. We get so many benefits from these powerful models, but we also can't perfectly verify the answer in our case, so we don't even know when the final answer is definitely correct, uh, because
- 7:40
j-- these expert judgment calls are ever present in our space. So the main lever left is validating the process and making sure that we are following it in a way we expect.
- 7:50
And to do that, we frame it as constraining the effects, not the expression.
- 7:55
So our task, uh, begins with a user request, and from this, the agent can then go off and freely write code to execute on that user request. However, we require that all the critical code, really the stuff that edits the graph, goes through a filter of this typed SDK that we've put together where we can lint and
- 8:14
check for errors, and then we own the final execution step to guarantee that we create these typed objects that we can commit as the actual edits to the graph.
- 8:24
And these are then faithful to the process. And all of this together, um, means that the entire process is valid, traceable, and replayable. And if it's not, we can reject and retry and send it back to the agent, um, to let it know that something has gone awry.
- 8:40
So let's go a little deeper on the typed SDK and the deterministic execution. So first, our SDK is the only door. What we give to the agent, in our case, is a TypeScript SDK with all the edit primitives the agent needs to make changes to graphs, as well as explore and interact with the kind of graph objects.
- 8:57
This, for us, enforces which fields are editable versus which are derived from other fields, so the agent can't create conflicts with itself, where it edits just the target thing that it cares about, but not the thing that creates that target thing.
- 9:09
And it also guarantees that it emits objects that we expect it to so that we can actually like make use of the outputs of this in a deterministic way.
- 9:17
Now, of course, this does require teaching the agent how to actually make use of this SDK, but this is the same, uh, kind of pattern that we see with teaching an agent to like write code in your code base where you tell it how it works.
- 9:29
You can, you know, do the prompt and all of that kind of stuff. The agent also has full access to the docs and the code underlying the SDK if it really needs to go and read that as well.
- 9:38
Just for a brief example on the right here, you can see an example with a few pieces of the SDK on display. We import, um, from our API. We-- The agent has to then define kind of a top-level edit function with a well-defined name.
- 9:51
It then can use, uh, find nodes by exact name to find specific nodes that it's looking for in the graph. It can write assertions that we give it to make sure that, um, its code fails early, um, as well.
- 10:02
And then it can use, uh, specific mutator functions like set rate and edit node to actually interact with the graph in a way that will produce those kind of typed objects that we care about.
- 10:12
So that's the SDK, but the actual guarantee here is when we own the deterministic execution. So even with the typed SDK as our entry point, that really only guides the agent towards the desired end state.
- 10:26
And the real guarantee comes from the final script that we orchestrate on agent completion. This run executor script, um, i-is called when the agent has kind of completed running, and we think that we're in a like almost completed state or a ready to be completed state.
- 10:42
And what that script does is it starts by linting the agent code where we can immediately send it back to the agent if something is wrong. Better to kind of fail early rather than fail later.
- 10:53
We can also detect conflicts. This is where sometimes the agent in one part of the code edited something in another part, edited the same thing or something that depended on the first one and didn't realize that that happened.
- 11:02
Because we have these guarantees by giving the agent this well-defined structure, we can detect those conflicts for it so that we can send it back to the agent. We then run the agent edited code, and that means that we can then validate the output artifacts.
- 11:16
Of course, if the code itself fails to run, we can send that back to the agent too. And then finally, once we have the validated output artifacts, we can create a well-structured review artifact that makes it easy to review what the agent did without having to act-- ever go read the underlying code that produced it.
- 11:32
To give you a flavor of what that looks like, here's a little snippet from an emissions report where the graph edit function impact analysis ran on fifty graphs. Um, there were two functions that it applied that produced seven hundred and forty-nine edit actions, and it ultimately, in this case, reduced the overall emissions by forty-five point six percent.
- 11:49
And we can even go to, go to see there are two code... There are two edits here. Um, one kind of did a big chunk, and the other one made a very small change.
- 11:58
Maybe you'd go look at what those actually did. And then you can even go at a graph level and say, "Okay, for this graph, like, what was the option one, and which nodes did it edit within that graph?"
- 12:08
To get a sense of, um, what actually happened under the hood. So you can see all of this without actually having to go read the low-level code.
- 12:18
So to return to those three problems that, uh, we started with, now that we have these kind of two broad concepts that are part of the harness, um, when the agent will find creative ways to solve every problem, this is now a great thing, but we've limited it a little bit.
- 12:32
These invalid actions that the agent will take on its route to solve whatever problem we've presented are actually prevented with the Typed SDK as the only way to properly edit the graph, and then we can guarantee that the graph was only edited through the SDK by owning the deterministic execution and the validation of that written code.
- 12:50
The second problem about the agent saying that it made an edit when actually that the edit didn't go through in the way that it or the user expected, these false reports are caught via that deterministic execution so that we can surface those back to the agent, um, to make sure that it's doing what it claimed.
- 13:05
And finally, our users never have to look at the code because the deterministic execution system produces artifacts in an expected form, and we can build verification against those to catch both the kind of good outcomes and the errors that are now surfaced clearly to both the user, um, and the AI.
- 13:23
So even when it hasn't maybe gotten exactly the right answer or the one that the user expected, it's easy to follow its logic and kind of get to that, um, and loop back on itself.
- 13:36
Now, the harness is all well and good as it kind of adds constraints, but I also want to emphasize that even with those great guarantees, you still need to hill climb to get better at the task itself.
- 13:45
Since we started tracking how well the agent did at these complex edits, where each task here, um, in our eval set is a collection of graphs and a goal, um, we've been able to improve our outcomes from about forty-three percent to ninety-two percent on our set of internal evals.
- 14:00
And to achieve that, all the typical approaches were still effective. We did a ton of prompt improvements, like rewriting the system prompt and all the kind of skills that the agent had access to.
- 14:09
We've added few-shot examples to both teach and coach the agent how to make use of the SDK and work with these different classes of tasks that we expect.
- 14:18
We also had to make the tools, the SDK itself, and the tools the agent had access to better fit for use by improving their kind of ergonomics and how obvious they were for the agent to use.
- 14:28
We also broke the task down through doing this, breaking up the, um, overall problem to a plan and execute kind of standard loop, as well as teaching the agent some of that expert judgment that is endemic in our space, making that easier for the agent to operate on it and to ex-elicit that expert judgment from the user.
- 14:45
But the important thing here is, even though we've kind of improved the accuracy here, which is amazing, and it's great that we'll like now kind of get better at that first time a user goes through the full workflow and the task, um, even when the agent errors or even our ground truth is, you know, one of those
- 15:01
points on the possible range of expert judgments, we can still guarantee and validate the, um, process itself.
- 15:09
So to bring it all together, in a domain full of expert judgments, you must respect the process too, and for that, you really need guarantees about the process. We all know coding agents are necessary for complex tasks, and they will continue to be necessary and extremely useful, but those power-- that power comes with many risks that are,
- 15:28
like, good to go and clear-eyed about. For tasks with complex data and judgment calls, we now think that the harness should do a few important things. First, it should give the agent well-scoped primitives to interact with the kind of external system that it's actually supposed to work with.
- 15:44
Um, free, freely operating code can, you know, lead to a lot of the things that we talked about earlier, and this really allows the builders of the system to allow and disallow specific things and exercise the full power of these coding agents while still trusting the process that they're working in.
- 16:00
I think the harness should also maintain full control of the final execution. These very smart agents may declare victory in an unexpected way from what you or your user really want them to declare, and so it's important to be able to constrain and validate that the agent has actually done what it said it's done.
- 16:17
And finally, you should use that deterministic final outcome to produce outputs that are easy to validate, even for non-coders. The code is kind of just the means to an end.
- 16:26
And then, of course, the kind of standard context and prompt engineering will of course remain critical to better scoping and defining that task and making it clear what the agent needs to do.
- 16:36
That's it for me. Again, I'm Andrew Dumit at Watershed, the sustainability AI platform. Thank you again for your time and attention.