00:00:00[MUSIC]
00:00:21>> Hey everyone, good afternoon.
00:00:22I'm going to start my talk with a bit of a confession.
00:00:26Ship code, I didn't quite understand.
00:00:29Generated it, tested it, deployed it, couldn't explain how it worked.
00:00:33And here's the thing though, I'm willing to bet every one of you have too.
00:00:37>> [LAUGH]
00:00:40>> So now we can all admit that we all ship
00:00:41code that we don't understand anymore, I want to take a bit of a journey,
00:00:44see how this kind of has come to be.
00:00:46First, look back in history, we see that history tends to repeat itself.
00:00:50Second, we've fallen into a bit of a trap.
00:00:52We've confused easy with simple.
00:00:55Lastly, there is a fix, but it requires us not to outsource our thinking.
00:01:00So, I spent the last few years at Netflix helping drive adoption of AI tools.
00:01:05And I have to say the acceleration is absolutely real.
00:01:07Back log items that used to take days now take hours.
00:01:10And large refactors that have been on the books for years are finally being done.
00:01:15Here's the thing though.
00:01:16Large production systems always fail in unexpected ways.
00:01:19Like look what happened with Cloud Fair recently.
00:01:21When they do, you better understand the code you're debugging.
00:01:23And the problem is now we're generating code at such speed and such volume.
00:01:28Our understanding is having a hard time keeping up.
00:01:29Hell, I know, I've done it myself.
00:01:34I've generated a bunch of code, looked at it, thought, I have no idea what this does.
00:01:39But the test passed, it worked, so I shipped it.
00:01:41The thing here is this isn't really new.
00:01:44Every generation of software engineers has eventually hit a wall where software
00:01:48complexity has exceeded their ability to manage it.
00:01:50We're not the first to face a software crisis,
00:01:52we're the first to face it at this infinite scale of generation.
00:01:56So let's take a step back to see where this all started.
00:01:58In the late 60s, early 70s, a bunch of smart computer scientists at the time came
00:02:03together and said, hey, we're in a software crisis.
00:02:06We have this huge demand for software, and yet we're not really able to keep up.
00:02:11And projects are taking too long, and it's just really slow.
00:02:15We're not doing a good job.
00:02:16So Dijkstra came up with a really great quote.
00:02:20And he said, when we had a few weak computers, I mean to paraphrase a longer
00:02:23quote, when we had a few weak computers, programming was a mild problem.
00:02:26And now that we have gigantic computers, programming has become a gigantic problem.
00:02:31He was explaining as hardware power grew by a factor of 1,000,
00:02:34society's wants of software grew in proportion.
00:02:37And so it left us, the programmers, to figure out between the ways and the means,
00:02:41how do we support this much more software?
00:02:43So this kind of keeps happening in a cycle.
00:02:47In the 70s we get the C programming language, so we could write bigger systems.
00:02:50In the 80s we have personal computers now, everyone can write software.
00:02:53In the 90s we get object-oriented programming.
00:02:56Inherent hierarchies from hell, thanks Java for that.
00:03:00In the 2000s we get agile, and we have sprints and
00:03:03scrum masters telling us what to do, there's no more waterfall.
00:03:06In the 2010s we had cloud, mobile, DevOps, everything,
00:03:09the software truly ate the world.
00:03:10And today now we have AI, Co-Pilot, Cursor, Clod, Codex, Gemini, you name it.
00:03:17We could generate code as fast as we can describe it.
00:03:19The pattern continues, but the stale has really changed, it's infinite now.
00:03:23So Fred Brooks, you might know him from writing the Mythical Man month.
00:03:29He also wrote a paper in 1986 called No Silver Bullet.
00:03:32And in this he argued that there would be no single innovation that would give us
00:03:36an order of magnitude improvement in software productivity.
00:03:38Why?
00:03:40Because he said the hard part wasn't the mechanics of coding, the syntax,
00:03:44the typing, the boilerplate.
00:03:45It was about understanding the actual problem and designing the solution.
00:03:49No tool can eliminate that fundamental difficulty.
00:03:52Every tool and technique we've created up to this point makes the mechanics easier.
00:03:55The core challenge though,
00:03:57understanding what to build, how it should work, remains just as hard.
00:04:00So if the problem isn't in the mechanics, why do we keep optimizing for it?
00:04:06How do experienced engineers end up with code they don't understand now?
00:04:09The answer, I think, comes down to two words we tend to confuse, simple and easy.
00:04:14We tend to use them interchangeably, but
00:04:16they really mean completely different things.
00:04:18I was outed at the speaker dinner as being a Clojure guy, so
00:04:21this is kind of clear here.
00:04:23But Rich Hickey, the creator of the Clojure programming language,
00:04:25explained this in his talk from 2011 called Simple Made Easy.
00:04:29He defined simple meaning one fold, one braid, and no entanglement.
00:04:33Each piece does one thing and doesn't intertwine with others.
00:04:36He defines easy as meaning adjacent, what's within reach.
00:04:39What can you access without effort?
00:04:41Copy, paste, ship.
00:04:43Simple is about structure.
00:04:45Easy is about proximity.
00:04:48The thing is, we can't make something simple by wishing it so.
00:04:51Simplicity requires thought, design, and untangling.
00:04:54But we can always make something easier.
00:04:56You just put it closer.
00:04:57Install a package, generate it with AI, copy a solution off of Stack Overflow.
00:05:03It's human nature to take the easy path.
00:05:06We're wired for it.
00:05:07As I said, copy something from Stack Overflow, it's right there.
00:05:10Framework that handles everything for you with magic, install and go.
00:05:14But easy doesn't mean simple.
00:05:15Easy means you can add to your system quickly.
00:05:18Simple means you can understand the work that you've done.
00:05:20Every time we choose easy, we're choosing speed now, complexity later.
00:05:24And honestly, that trade-off really used to work.
00:05:27The complexity accumulated in our code base is slowly enough that we can
00:05:31refactor, rethink, and rebuild when needed.
00:05:34I think AI has destroyed that balance.
00:05:36Cuz it's the ultimate easy button.
00:05:37It makes the easy path so
00:05:38frictionless that we don't even consider the simple one anymore.
00:05:41Why think about architecture when code appears instantly?
00:05:44So let me show you how this happens.
00:05:47Now a simple task evolves into a mess of complexity
00:05:50through a conversational interface that we've all come to love.
00:05:52This is a contrived example, but say we have our app,
00:05:55we wanna add some authentication to it.
00:05:57Say add auth, so we get a nice clean auth.js file.
00:06:01Iterate it on a few times, it gives a message five.
00:06:02You're like, okay, cool, we're gonna add OAuth now too,
00:06:04because now we've got an auth.js and OAuth.js.
00:06:07We keep iterating, we find ourselves that sessions are broken.
00:06:11And we got a bunch of conflicts.
00:06:12And by the time we get to turn 20, you're not really having a discussion anymore.
00:06:15You're managing contexts that become so complex that even you don't remember
00:06:18all the constraints that you've added to it.
00:06:20Dead code from abandoned approaches.
00:06:22Tests that got fixed by just making them work.
00:06:25Fragments of three different solutions because you end up saying, wait, actually.
00:06:28Each new instruction is overwriting architectural patterns.
00:06:31We said make the auth work here, it did.
00:06:33When we said fix this error, it did.
00:06:35There's no resistance to bad architectural decisions.
00:06:38The code just morphs to satisfy your latest request.
00:06:40Each interaction is choosing easy over simple.
00:06:43And easy always means more complexity.
00:06:46We know better, but when the easy path is just this easy, we take it.
00:06:50And complexity is going to compound until it's too late.
00:06:52AI really takes easy to its logical extreme.
00:06:58Decide what you want, get code instantly.
00:07:00But here's the danger in that.
00:07:02The generated code treats every pattern in your code base the same.
00:07:06When an agent analyzes your code base, every line becomes a pattern to preserve.
00:07:10The authentication check on line 47, that's a pattern.
00:07:13That weird GRPC code that's acting like GraphQL that I may have added in 2019,
00:07:18that's also a pattern.
00:07:19Technical debt doesn't register as debt, it's just more code.
00:07:22The real problem here is complexity.
00:07:25I know I've been saying that word a bunch in this talk without really defining it.
00:07:29But the best way to think about it is it's the opposite of simplicity.
00:07:31It just means intertwined.
00:07:33And when things are complex, everything touches everything else.
00:07:36You can't change one thing without affecting ten others.
00:07:41So back to Fred Brooks' No Sober Bullet paper.
00:07:43In it, he identified that there's two main types of complexity in every system.
00:07:47There's the essential complexity, which is really the fundamental difficulty
00:07:51of the actual problem you're trying to solve.
00:07:53Users need to pay for things, orders must be fulfilled.
00:07:56This is the complexity of why your software system exists in the first place.
00:08:00And then second, there's this idea of accidental complexity.
00:08:03Everything else we've added along the way, workarounds, defensive code,
00:08:06frameworks, abstractions that made sense a while ago.
00:08:09It's all the stuff that we put together to make the code itself work.
00:08:11In a real code base, these two types of complexity are everywhere.
00:08:16And they get so tangled together that separating them requires context,
00:08:19history, and experience.
00:08:20The generated output makes no such distinction.
00:08:24And so every pattern keeps us getting preserved.
00:08:26So here's a real example from some work we're doing at Netflix.
00:08:32I have a system that has an abstraction layer sitting between our old
00:08:35authorization code we wrote, say five or so years ago, in a new centralized auth system.
00:08:41We didn't have time to rebuild our whole app, so
00:08:42we just kind of put a shim in between.
00:08:44So now we have AI, this is a great opportunity to refactor our code to use
00:08:47the new system directly, seems like a simple request, right?
00:08:50And no, it's like the old code was just so tightly coupled to its authorization
00:08:56patterns, like we had permission checks woven through business logic,
00:08:59role assumptions baked into data models, and auth calls scattered across hundreds of
00:09:03files, the agent would start refactoring, get a few files in, and
00:09:07hit a dependency it couldn't untangle, and just spiral out of control and give up.
00:09:10Or worse, it would try and preserve some existing logic from the old system and
00:09:16recreating it using the new system, which I think is not great too.
00:09:19The thing is, it couldn't see the scenes.
00:09:23It couldn't identify where the business logic ended and the auth logic began.
00:09:26Everything was so tangled together that even with perfect information,
00:09:30the AI couldn't find a clean path through.
00:09:33When your accidental complexity gets this tangled,
00:09:35AI is not the best help to actually make it any better.
00:09:38I found it only adds more layers on top.
00:09:40We can tell the difference, or at least we can when we slow down enough to think.
00:09:45We know which patterns are essential and
00:09:47which are just how someone solved it a few years ago.
00:09:50We carry the context that the AI can't infer, but
00:09:53only if we take time to make these distinctions before we start.
00:09:56So how do you actually do it?
00:10:01How do you separate the accidental and essential complexity, and
00:10:04you're staring at a huge code base?
00:10:07Code base I work on Netflix has around a million lines of Java, and
00:10:10the main service in it is about five million tokens last time I checked.
00:10:13No context window I have access to can hold it.
00:10:17So when I wanted to work with it, I first thought, hey,
00:10:19maybe I can just copy large swaths of this code base into the context and
00:10:23see if the patterns were merged,
00:10:24see if it would just be able to figure out what's happening.
00:10:26And just like the authorization refactor from previously,
00:10:29the output just got lost in its own complexity.
00:10:31So with this I was forced to do something different.
00:10:34I had to select what to include, design docs, architecture, diagrams,
00:10:37key interfaces, you name it.
00:10:39And take time writing out the requirements of how components should interact and
00:10:42what patterns to follow.
00:10:43See, I was writing a spec.
00:10:45Five million tokens became 2,000 words of specification.
00:10:49And then to take it even further, take that spec and
00:10:52create an exact set of steps of code to execute.
00:10:55No vague instructions, just a precise sequence of operations.
00:10:58I found this produced much cleaner and more focused code that I could understand.
00:11:02So I defined it first, and planned its own execution.
00:11:05This became the approach which I called context compression a while ago.
00:11:11But you call it context engineering, your spectra of in development,
00:11:13whatever you want.
00:11:15The name doesn't matter.
00:11:16What only matters here is that thinking and planning become a majority of the work.
00:11:20So let me walk you through how this works in practice.
00:11:22So you have step one, phase one, research.
00:11:26You know, I go and feed everything to it up front.
00:11:28Architecture diagrams, documentation, slack threads.
00:11:31I mean, we've been over this a bunch.
00:11:32But really just bring as much context as you can that's gonna be relevant to
00:11:35the changes you're making.
00:11:36And then use the agent to analyze the code base and
00:11:39map out the components and dependencies.
00:11:42This shouldn't be a one shot process.
00:11:43I like to probe, say like, what about the caching?
00:11:46How does this handle failures?
00:11:47And when its analysis is wrong, I'll correct it.
00:11:49And if it's missing context, I provide it.
00:11:51Each iteration refines its analysis.
00:11:55The output here is a single research document.
00:11:57Here's what exists, here's what connects to what, and
00:11:59here's what your change will affect.
00:12:01Hours of expiration are compressed into minutes of reading.
00:12:03I know Dex mentioned it this morning, but the human checkpoint here is critical.
00:12:09This is where you validate the analysis against reality,
00:12:12the highest leverage moment in the entire process.
00:12:15Catch errors here, prevent disasters later.
00:12:17On to phase two.
00:12:20Now that you have some valid research in hand,
00:12:22we create a detailed implementation plan, real code structure,
00:12:25function signatures, type definitions, data flow.
00:12:28You want this to be so any developer can follow it.
00:12:30I kind of liken it to paint by numbers.
00:12:32You should be able to hand it to your most junior engineer and say, go do this.
00:12:35And if they copy it line by line, it should just work.
00:12:38This step is where we make a lot of the important architectural decisions.
00:12:43Make sure complex logic is correct.
00:12:45Make sure business requirements are following good practice.
00:12:50Make sure there's good service boundaries, clean separation, and
00:12:52preventing any unnecessary coupling.
00:12:54We spot the problems before they happen because we've lived through them.
00:12:57AI doesn't have that option.
00:12:59It treats every pattern as a requirement.
00:13:01The real magic in this step is the review speed.
00:13:05We can validate this plan in minutes and know exactly what's going to be built.
00:13:10And in order to keep up with the speed at which we want to generate code,
00:13:13we need to be able to comprehend what we're doing just as fast.
00:13:18Lastly, we have implementation, and now that we have a clear plan and
00:13:22backed by clear research, this phase should be pretty simple.
00:13:26And that's the point.
00:13:28When AI has a clear specification to follow, the context remains clean and
00:13:31focused.
00:13:32We've prevented the complexity spiral of long conversations.
00:13:36And instead of 50 messages of evolutionary code,
00:13:38we have three focused outputs, each validated before proceeding.
00:13:41No abandoned approaches, no conflicting patterns,
00:13:44no wait actually moments that leave dead code everywhere.
00:13:48To me, what I see as a real payoff of this is that you can use a background agent to
00:13:52do a lot of this work, cuz you've done all the thinking and hard work ahead of time.
00:13:56It can just start the implementation, you can go work on something else, and
00:13:59come back to review.
00:14:01And you can review this quickly because you're just verifying that it's conforming
00:14:04to your plan, not trying to understand if anything got invented.
00:14:07The thing here is we're not using AI to think for us.
00:14:12We're using it to accelerate the mechanical parts
00:14:15while maintaining our ability to understand it.
00:14:17Research is faster, planning is more thorough, and the implementation is cleaner.
00:14:21The thinking, the synthesis, and the judgement, though, that remains with us.
00:14:26So, remember that authorization refactor I said that AI couldn't handle?
00:14:34The thing is now we're actually working on it now and
00:14:37starting to make some good progress on it.
00:14:39The thing is it's not because we found better prompts.
00:14:42We found we couldn't even jump into doing any sort of research planning and
00:14:45implementation.
00:14:46We actually had to go make this change ourself by hand.
00:14:49No AI, just reading the code, understanding the dependencies, and
00:14:52making changes to see what broke.
00:14:53That manual migration was, I'll be honest, was a pain, but it was crucial.
00:14:59It revealed all the hidden constraints, which invariance had to hold true, and
00:15:02which services would break if the auth changed.
00:15:05Things no amount of code analysis would have surfaced for us.
00:15:09And then we fed that pull request of the actual manual migration into our research
00:15:14process and had it use that as the seed for any sort of research going forward.
00:15:19The AI could then see what a clean migration looks like.
00:15:23The thing is, each of these entities are slightly different, so we have to go and
00:15:27interrogate it and say, hey, what do we do about this?
00:15:29Some things are encrypted, some things are not.
00:15:32We had to provide that extra context each time through a bunch of iteration.
00:15:35Then, and only then, we could generate a plan that might work in one shot.
00:15:41And the key word, and might's the key word here, is we're still validating,
00:15:45still adjusting, and still discovering edge cases.
00:15:47The three phase approach is not magic.
00:15:55It only works because we did this one migration by hand.
00:15:57We had to earn the understanding before we can encode into our process.
00:16:01I still think there's no silver bullet.
00:16:02I don't think there's better prompts, better models, or even writing better specs.
00:16:06Just the work of understanding your system deeply enough that you can make changes to
00:16:09it safely.
00:16:11So why go through with all this?
00:16:15Why not just iterate with AI until it works?
00:16:18Eventually, models get strong enough and it just works.
00:16:21The thing to me is, it works isn't enough.
00:16:24There's a difference between code that passes test and code that survives in
00:16:27production.
00:16:28Between systems that function today and
00:16:31systems that can be changed by someone else in the future.
00:16:34The real problem here is a knowledge gap.
00:16:38When AI can generate thousands of lines of code in seconds,
00:16:41understanding it could take you hours, maybe days if it's complex.
00:16:45Who knows, maybe never if it's really that tangled.
00:16:48Here's something that I don't think many people are even talking about at this
00:16:52point. Every time we skip thinking to keep up with generation speed,
00:16:56we're not just adding code that we don't understand.
00:16:58We're losing our ability to recognize problems.
00:17:00That instinct that says, hey, this is getting complex,
00:17:03it atrophies when you don't understand your own system.
00:17:09Pattern recognition comes from experience.
00:17:11When I spot a dangerous architecture,
00:17:12it's because I'm the one up at three in the morning dealing with it.
00:17:16When I push for simpler solutions,
00:17:17it's because I've had to maintain the alternative from someone else.
00:17:21AI generates what you ask it for.
00:17:23It doesn't encode lessons from past failures.
00:17:25The three phase approach bridges this gap.
00:17:29It compresses understanding into artifacts we can review at the speed of generation.
00:17:33Without it, we're just accumulating complexity faster than we can comprehend
00:17:37it.
00:17:39AI changes everything about how we write code, but honestly,
00:17:44I don't think it changes anything about why software itself fails.
00:17:47Every generation has faced their own software crisis.
00:17:50Dijkstra's generation faced it by creating the discipline of software engineering, and
00:17:54now we face ours with infinite code generation.
00:17:56I don't think the solution is another tool in methodology.
00:18:01It's remembering what we've always known, that software is a human endeavor.
00:18:05The hard part was never typing the code.
00:18:06It was knowing what to type in the first place.
00:18:09The developers who thrive won't just be the ones who generate the most code.
00:18:13They'll be the ones who understand what they're building,
00:18:15who can still see the seams, who can recognize that they're solving the wrong
00:18:18problem.
00:18:19That's still us.
00:18:20That will only be us.
00:18:21I want to leave on a question, and I don't think the question is whether or
00:18:25not we will use AI.
00:18:26That's a foregone conclusion.
00:18:28The ship has already sailed.
00:18:30To me, the question's going to be whether we will still understand our own systems
00:18:33when AI is writing most of our code.
00:18:35Thank you.
00:18:37>> [APPLAUSE]
00:18:39[MUSIC]