HomeVideos

Dark Factories: Verification-First Agentic Engineering | Shardul Vaidya

Now Playing

Dark Factories: Verification-First Agentic Engineering | Shardul Vaidya

Transcript

515 segments

0:06

Hi everyone. My name is Shardul Vaidya,

0:08

and today we're going to be talking

0:09

about dark factories, the step beyond

0:11

agentic engineering.

0:14

The term dark factories itself comes

0:15

from manufacturing, essentially a

0:17

factory

0:18

that has absolutely no humans at all.

0:21

Requirements go in, or essentially raw

0:23

materials go in, and a finished product

0:25

comes out, no humans involved at all.

0:28

And the intention is, well, if humans

0:30

are not needed, then why keep the lights

0:32

on? Let's look at agentic engineering by

0:35

the numbers.

0:36

When an engineer presses trust all

0:39

tools, or YOLO, or non-interactive as I

0:42

like to use it,

0:43

um you see very often a 53% accuracy

0:46

decline. That's essentially where an AI

0:49

has no feedback loop. They It has no way

0:52

to know that it's gone wrong.

0:54

On the other side, we have this 91%

0:57

versus 25%, where 91% of engineering

1:00

leaders claim that AI has improved

1:02

velocity, but only 25% have the data to

1:05

prove it. And one of the fundamental

1:07

reasons for that is the prevailing

1:09

approach.

1:11

You get the standard enterprise

1:12

rollouts, buy seats, try for acceptance

1:15

rates, declare that you're done. Or you

1:17

look at developer productivity

1:19

metrics. These are lines of code, PRs

1:21

per sprint, essentially just looking for

1:24

higher velocity, but not necessarily

1:26

improved product quality.

1:28

The next thing you see most often is

1:30

prompt engineering training. This is

1:32

essentially teaching developers how to

1:34

talk to models.

1:35

This has a very short shelf life, 12

1:37

months at the time of recording, but

1:40

honestly coming lower with models being

1:43

released every other week or every four

1:45

weeks even. And the last thing is the AI

1:48

center of excellence. These are

1:49

committees that meet every month,

1:51

discuss what shipped, and then see if

1:53

they want to make any decisions to move

1:55

the enterprise forward.

1:57

This, I don't think is the way.

2:00

The gap fundamentally isn't

2:01

productivity. It's an architectural

2:04

imbalance.

2:06

One approach assumes that humans stay in

2:09

the loop and AI helps make them faster.

2:11

The other assumes that humans are

2:13

responsible for the verification and a

2:16

system design. Essentially, instilling

2:19

organizational best practices into code.

2:24

Um verification systems replace their

2:26

judgment. These aren't even same points

2:29

on the agentic engineering spectrum.

2:32

One scales with head count where humans

2:34

essentially still are the bottleneck,

2:36

code review remains the bottleneck. And

2:38

the other scales with just a raw amount

2:40

of compute.

2:42

We're seeing the frontier move. A

2:45

handful of companies are already

2:46

operating at this dark factory scale,

2:49

but

2:50

let's talk about it a little more.

2:53

Same idea as the SAE levels for

2:55

self-driving. Each level is

2:57

fundamentally defined by what a

2:59

verification system is trusted to do.

3:03

Can you fundamentally remove the human?

3:06

Level two needs something like lane keep

3:08

cameras. You know, level four needs

3:10

lidar and redundant compute. In the case

3:13

of code, level two we're mostly focusing

3:15

on unit tests and lint and automated and

3:18

automated test writing and automated

3:20

test execution.

3:21

But to truly get to level four or level

3:23

five, we need the agents to have an

3:27

incredible amount of trust in the system

3:29

that's providing back pressure to them.

3:32

And that essentially means that when the

3:35

reviewer says, "Hey, this is wrong."

3:39

the agent is forced to listen.

3:45

Every major model can write solid code

3:46

for a well-specified task. That's been

3:48

true for over a year.

3:50

The gap between level two and level four

3:51

isn't model access, it's what you

3:54

trust the model to write without a human

3:57

reading every diff.

3:59

So, let's talk about who's actually

4:00

there. The Coinbase or Ramp convergence

4:03

is the strongest evidence for the

4:05

architecture that we're going to talk

4:06

about soon.

4:08

These are two independent companies that

4:09

essentially don't talk to each other,

4:11

but independently arrived at the same

4:13

pattern. This is constraint-driven

4:15

design at its finest. And StrongDM

4:18

essentially came up with this full

4:20

digital twin universe that simulates

4:22

everything surrounding their prod

4:24

environment.

4:26

They have end-to-end scenario testing

4:27

already built in with LLMs, and they

4:30

approach it with the fundamental idea

4:32

that zero humans write code, zero humans

4:35

review code.

4:40

Coinbase, Ramp, Stripe, Anthropic, and

4:42

StrongDM all came to the same pattern.

4:46

Isolated sandboxes, curated tool sets,

4:49

sub-agent orchestration, and most

4:51

importantly, verification gates that

4:54

provide immense back pressure to the

4:55

coding agents to write this

4:58

the correct code. This is the same way

5:01

that we've seen web-scale data

5:02

constraints produce MapReduce.

5:05

And let me show you what that looks

5:07

like.

5:08

This is what I think the

5:12

the the baseline dark factory

5:14

architecture looks like. You have some

5:16

kind of orchestrator whose sole

5:18

responsibility is to decompose, convert

5:21

it into a DAG, and then dispatch into

5:24

coding agents, right? The decomposition

5:26

happens with a planning pattern. It

5:28

doesn't matter where it gets the

5:30

requirements from. It can be from Slack,

5:31

it can be from Linear, it can be from

5:32

GitHub, or it can even be by just typing

5:35

into a web UI.

5:37

But once you get that, you decompose it

5:40

into a list of tasks while the planner

5:42

has access and ability to research the

5:45

codebase. This is exactly what you would

5:47

do in a planning sprint

5:49

or a planning meeting. And then

5:52

each agent each coding agent is given

5:54

its own sandbox it's given its own work

5:56

tree

5:57

and in the case of like hyper scale you

5:59

would probably give it its own container

6:02

to live in

6:03

and then once it thinks it's done we go

6:06

through some kind of a verification

6:08

gate.

6:09

We're going to talk about verification

6:10

gates in a minute but it goes through

6:12

some kind of verification gate. If it

6:14

fails it goes through rework goes back

6:16

to the orchestrator and gets dispatched

6:18

back into an agent saying hey

6:21

this is what the previous agent did this

6:22

is what it did wrong please fix it. If

6:25

it gets past it just goes on to a merge

6:27

state where it goes and gets deployed.

6:31

Let's talk about these runtimes for a

6:32

second. The key part here is isolation

6:35

right these

6:36

are essentially highly untrusted

6:38

systems. They get their own sandboxed

6:40

done through a container or micro VM

6:42

whatever your enterprise has expertise

6:45

in.

6:46

Then the most important thing after that

6:48

is context boundaries. There are no

6:50

shared state between agents running at

6:53

any given time.

6:55

This means that these agents are

6:57

completely stateless. They can crash we

6:59

can reboot them and they will just keep

7:01

running.

7:02

The tool registry is what lets us

7:04

essentially evolve the factory over

7:06

time.

7:08

These can be internal tools that maybe

7:10

abstract away testing or can be external

7:12

tools that give access to documentation.

7:15

But these are essentially standardized.

7:18

And finally crashing is a feature.

7:21

You never run into situations where an

7:24

agent essentially dies and then is left

7:28

there

7:29

to to just sort of be orphaned but if if

7:31

an agent dies we clean up essentially

7:34

leave the state that it was in and boot

7:36

up another agent to launch in its place.

7:39

Spin up execute produce some artifacts,

7:41

and terminate.

7:46

Then let's talk about

7:49

how this multi-agent orchestration is

7:51

possible.

7:52

First things first, decomposition, the

7:54

planning stage, so to speak, is what

7:57

lets is what lets us parallelize our

8:00

processes to the fullest.

8:03

Bad decomposition can produce merge

8:05

conflicts because more than one agent

8:07

will try to do the same thing. And this

8:11

is where we get our first back pressure.

8:14

Second, the rework loop is the biggest

8:16

key. When a task fails, the full context

8:18

of why it failed is fed forward into the

8:21

next attempt. That's not a retry, that's

8:22

essentially just a full rework.

8:25

Um cost-optimized routing essentially

8:27

lets the planner delegate to the correct

8:31

agent downstream. That essentially, this

8:33

is a trivial task, you can use a

8:34

low-cost model to do it. This is a

8:36

difficult task, use the high-quality

8:38

model. And concurrent dispatch is what

8:41

lets us essentially leverage the DAG to

8:43

say, "These, these, these tasks are

8:45

unblocked. You can execute them."

8:50

Then, there's the verification

8:52

architecture, as we said earlier.

8:55

Traditionally, even as humans work, uh

8:58

we've relied on unit tests, on property

8:59

tests, on mutation tests to

9:02

make sure that

9:05

the code we're writing is is accurate,

9:07

is trustworthy, is going in the right

9:09

direction.

9:11

These are all excellent because LLMs

9:13

have learned from them, right? They know

9:14

how unit tests work. They know how like

9:16

uh test coverage works. So, we use them.

9:19

We continue to use them. Then, we come

9:21

to the AI-native level. Now, I know

9:24

these are shown as separate streams, but

9:26

they all happen parallelly, right? That

9:28

there's no one without the other.

9:30

Um the the most the most amazing thing

9:33

that we can do with AI-native testing is

9:35

scenario testing. You can essentially

9:37

describe this end user journey

9:40

to your agent and see how long it takes

9:43

to get to that journey. This is kind of

9:45

built-in

9:47

user acceptance tests that we previously

9:49

did not really have access to.

9:51

And then the last here is the formal and

9:53

the aspirational side. It's a it's the

9:55

idea that

9:57

instead of just

9:59

making a plan and and making tasks, we

10:02

make a plan and then we make these

10:05

system invariants that define and

10:08

declare

10:09

mathematically what states the system

10:12

can live in.

10:13

This is mostly unexplored and I believe

10:15

this is aspirational for me, too, but

10:18

this is something that can really

10:19

formalize

10:20

how a system is going to behave and it

10:22

lets you have immense levels of trust on

10:26

your Dark Factory generated code.

10:30

So, let's see it run. This is my factory

10:33

and it essentially is a giant monolith

10:36

that goes from requirements to plan to

10:38

tasks to execution to merging. And I'll

10:41

just show off every step of that

10:43

process.

10:46

This is my factory dashboard.

10:48

It essentially has everything that has

10:50

that that the factory has ever done

10:52

including all the projects that it

10:53

manages.

10:54

So, we can go out here. We we can see a

10:56

health check. We can see if something is

10:58

broken.

10:59

But the most important thing in how we

11:01

essentially give the factory a task is

11:04

through the submit requirement thing. We

11:06

select which project this is about, type

11:08

in our requirements,

11:10

and hit plan down here. Once that

11:12

happens, we go into the plan stage.

11:16

We go into the requirement stage because

11:18

a plan generates requirements and we

11:20

have these

11:21

these essentially

11:23

uh

11:24

context-aware

11:26

well-researched tasks, right? So, we can

11:29

click here, which is one of my code

11:31

review tasks. And we can go down to the

11:34

actual design. And you can see here that

11:36

the the the prompt I provided was was

11:39

very trivial. It was like, "Hey, we've

11:40

done a bunch of code review. Um solve

11:42

all of the requests from the code

11:44

review."

11:45

And you can see that it's generated, I

11:48

don't know, about 20-something tasks.

11:50

Yeah, about 23 tasks. And we get this

11:53

beautiful DAG that defines

11:56

what needs to be done in what order. And

11:59

you can see here, we've got some

12:00

independent lines. We've got some deeply

12:03

dependent lines. And then we've got some

12:05

like one-off things that just needed to

12:06

be sorted. And this essentially allows

12:09

high level of parallelism in things that

12:13

have no blockers, just like how human

12:14

teams are designed. Just like how

12:16

sprints are designed. We're not ripping

12:18

out the conventional SDLC. We're saying

12:21

a factory can augment it

12:23

basically infinitely. And once we go

12:25

from there, once a a plan is triggered,

12:29

we go into this state, where essentially

12:31

a a

12:33

the orchestrator is now treating this as

12:35

an an assembly line. And you can see

12:38

here, we get this like merge status and

12:41

these like stable change IDs. These are

12:43

derived from the underlying Git

12:45

substrate we use, which is Jujutsu. Um

12:48

and those stable change IDs let us

12:50

essentially refer to these tasks uh

12:52

stably through throughout the history of

12:54

the project. And

12:56

then you can see a whole bunch of these

12:58

are merged, and then we have some

12:59

failures that say, "Hey, we've we've

13:01

exceeded max rework count." And that's

13:03

essentially uh a an escalation to me

13:06

saying, "Hey, you should probably look

13:07

at this yourself as a human, because

13:09

you're responsible for the code that it

13:10

generates."

13:11

But you can see, a vast majority of

13:13

these are already merged and already

13:15

ready to go.

13:16

Um and this actually, as a matter of

13:18

fact, this whole UI that you're seeing

13:20

right now was built entirely by the

13:21

factory. And we can go look at the code

13:24

for a minute. Uh we can go down to the

13:28

factory.

13:30

And you can see here there's over 300

13:31

commits that are essentially very tight

13:34

requirements down to right, "Oh, hey,

13:37

it's it's just it's just three

13:38

additions, six deletions, net reduction

13:40

in entropy."

13:42

And we can force the factory to behave

13:44

that way.

13:45

And we can also see this, 27 additions,

13:48

30 deletions, very tight, very clean

13:50

refactor on exactly what's going on.

13:53

This is what this kind of task

13:56

decomposition planning into design

13:59

into execution lets us do.

14:04

And the reason it works is due to back

14:08

pressure.

14:09

Back pressure in our factory comes in

14:12

two specific ways, the planned reviewer

14:15

and then the code reviewer. And then

14:17

there's a deterministic back pressure

14:18

from the test executor.

14:22

So, in our factory, um it's essentially

14:24

six phases uh that form the pipeline.

14:28

Uh first we have uh the requirement

14:30

coming in from us as we saw, then the

14:32

plan, the plan adversary. This is

14:34

essentially something that reviews the

14:36

plan generated uh and the DAG generated

14:40

to make sure it will work fine within

14:41

the context of the code base.

14:43

Once the plan adversary approves a plan,

14:45

it gets put in the queue uh which is our

14:47

which is, you know, managed by our

14:49

orchestrator, and then once a task's

14:53

dependencies are ready,

14:55

we can schedule the task. This goes to

14:57

the coder

14:58

uh and then this works essentially in an

15:00

isolated sandbox. We're going to discuss

15:02

that in a little bit.

15:04

Um once we get through code, once the

15:07

coder thinks it's done, we essentially

15:09

run the tests that are configured for

15:12

our project.

15:13

And then we go to the code adversary.

15:16

And this is essentially a code reviewer.

15:19

Um it goes through all the code that was

15:20

written, it looks at the diffs

15:21

essentially, and then points out if

15:23

there was too much entropy, if there was

15:25

like something wasn't done right, or

15:26

some feature isn't complete. And

15:28

obviously, if the tests fail, we never

15:31

get to the code reviewer. This is

15:32

essentially how a um

15:35

a maintainer would refuse to look at a

15:37

PR if the tests are red, right? If

15:40

you're breaking something, I don't even

15:41

want to look at it.

15:43

And then once the code obviously says

15:44

it's okay,

15:46

we go into the merge. Um this is enabled

15:50

by Jujutsu's conflict detection, and we

15:52

essentially have this fine-tuned

15:55

uh deterministic merge system. And then

15:57

if that fails, if there's too many com-

15:59

conflicts,

16:00

uh we obviously go back out to the LLM,

16:03

and we actually have a merge rework

16:06

manager that runs within the merge

16:09

uh agent.

16:11

The isolation philosophy comes from two

16:13

things, right? Uh first, we obviously

16:15

want to reduce the blast radius if a

16:17

agent goes haywire. Uh that's mainly

16:20

provided by running these in isolated

16:22

sandboxes. That can obviously be uh in

16:25

in Docker or in containers. That can

16:28

also be on separate EC2 instances.

16:31

However,

16:32

um you like to manage your isolation.

16:34

The second tier of isolation comes at

16:36

the version control level. So, this is

16:38

in in my factory provided by Jujutsu

16:41

workspaces.

16:42

This is the equivalent of Git work

16:43

trees, but with a little more Jujutsu

16:46

features.

16:48

And all of that just allows clean

16:49

merging back to trunk whenever it's

16:51

ready to go.

16:55

The result of all of this is you're no

16:56

longer writing code. You're composing

16:59

the factory that writes the code for

17:00

you. You essentially go from being

17:04

uh an engineer who super focuses on code

17:07

to an engineer who focuses on how the

17:09

system

17:11

verifies and fact-checks that the code

17:13

written by the LLMs is correct.

17:17

You've essentially define these really

17:20

deep requirements, curate the agent's

17:22

tool sets, architect verification

17:23

frameworks, and fundamentally ensure

17:26

correctness.

17:28

You're responsible for it, but without

17:30

actually writing every line.

17:32

So, how would we build this on AWS?

17:34

You can obviously build it from scratch

17:36

using EC2 and and just write everything

17:39

as a single monolith like I did.

17:41

Uh but every layer of this architecture

17:44

has an AWS feature or service that can

17:46

make it easier to run.

17:49

Bedrock agent core if you want to run

17:51

long-lived agents, Lambda Fargate for

17:53

isolated agent runtimes,

17:55

CodeBuild and CodePipeline for

17:58

application verification,

18:01

Lambda for for reaching out to external

18:04

uh services through tools.

18:07

All of this can be done through Bedrock.

18:10

And actually, if you wanted to not even

18:12

write code for the orchestrator, you

18:14

could use stuff like EventBridge and

18:15

Step Functions to just define your

18:18

factory as infrastructure.

18:20

And because it's all in AWS, it gives

18:23

you access to CloudWatch and CloudTrail

18:26

along with IAM that gives you really

18:28

fine-grained control of everything and

18:30

anything your agent can do.

18:33

And

18:34

because we might want our factory to be

18:36

fundamentally stateless, we can store

18:38

all our state in DynamoDB.

18:41

Uh and that's how my factory is built.

18:43

Everything is JSON, so it can very

18:45

cleanly move into DynamoDB.

18:48

And once you've done all of this,

18:50

software writes itself

18:52

courtesy of the dark factory.

18:55

These are some of the references that

18:56

inspired me on the dark factory journey.

18:59

There's Jeffrey Huntley's article on the

19:01

Ralph loop, which essentially

19:04

allows you to stack while loops on top

19:06

of another.

19:07

There's StrongDM's

19:10

blog and live website on their factory

19:14

and Stevie Yag his article on Gastown

19:17

where he describes work as these beads

19:20

that are run through the factory until

19:22

they are finished.

19:24

A huge shout out to the background

19:26

agents summit and thank you. My name is

19:30

Shardul Vaidya. You can find me on my

19:32

email address or on LinkedIn or even on

19:35

my personal website.

Interactive Summary

This presentation explores the concept of 'dark factories'—automated software engineering environments where AI agents handle requirements, code generation, and verification with minimal human intervention. Shardul Vaidya outlines an architecture centered on task decomposition, isolated runtimes, and rigorous verification gates, arguing that the future of engineering lies in building these automated factories rather than writing individual lines of code.

Suggested questions

4 ready-made prompts