← All AI Engineer talks

AI Engineer World's Fair 2024

Code Generation and Maintenance at Scale

Morgante Pell· CEO, Grit18:54

Read the talk

Code Generation and Maintenance at Scale

Maintaining large codebases requires more than generating plausible edits: agents need precise search, compiler feedback, warm environments, and checkpoints that keep failed attempts from compounding.

From a talk by Morgante Pell

Before you start: Familiarity with pull requests, TypeScript type checking, and language-model context windows will help you follow the examples.

Start with the application already running

How do you move an existing, revenue-producing business application onto Kubernetes? That was the recurring problem behind Morgante Pell’s work at Google Cloud. In his recollection, 90% of customer requests concerned existing applications; his illustrative customer had a business application generating $100 million in revenue. Kubernetes, Kustomize, and Terraform templates served that installed base: customers needed to run software they already depended on.

That experience explains Grit’s focus on maintenance. A prompt that produces a new application makes an appealing demonstration, but everyday engineering involves changing large systems whose behavior already matters—software that, for example, keeps flights running on time. The unit of work is a change to an existing system, with all its dependencies and operational constraints.

0:390:49
Suggest correction

This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.

0:39 · section reference included

One expert directs many agents

AI developer tools address different constraints:

ApproachWhat it expands
IDE assistanceA developer’s speed while writing code
Agents that lower the floorThe tasks less technical users can attempt
Agents that raise the ceilingThe scope an experienced engineer can manage

Autocomplete already fits an established development workflow. Generating an application for a less technical user extends access, but specifications and edge cases still require engineering judgment. Grit concentrates on the third category: principal engineers often know what should change, but cannot personally carry out every change across an organization.

AI Developer Tools slide with three purple columns comparing IDE developer assistants and two approaches to AI agents.
Three categories of AI developer tools: IDE assistants, lowering the floor, and raising the ceiling.

Pell describes the target as the top 1% of engineers, using agents to extend their reach. Adoption can therefore remain concentrated: he reports that roughly 95% of engineers at customer organizations do not touch Grit. His illustrative hundred-engineer team has one deeply involved operator generating hundreds of PRs. The other engineers can receive the resulting work without adopting another daily tool.

1:451:55
Suggest correction

This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.

1:45 · section reference included

From individual lines to coordinated changes

An IDE is a scalpel: precise, local, and well suited to editing individual lines. Changing hundreds of repositories or opening a thousand files calls for a different tool. Pell’s bulldozer analogy describes working at a higher level of abstraction—directing a large change rather than manually moving every piece of code.

Slide titled “Tools need to change” showing a scalpel on the left and a bulldozer on the right.
Tools need to change: a scalpel versus a bulldozer.

The demand grows as generation produces more software to maintain. Pell reports that some customers were producing 20–30% more code, accompanied by more PRs and CI activity. His scenario of AI adoption growing from 5% to 50% is a projection: wider use would increase the volume of code that needs management after it reaches production.

3:033:14
Suggest correction

This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.

3:03 · section reference included

An OpenTelemetry migration becomes an orchestration task

The concrete customer example is an organization with thousands of repositories and developers that wanted to migrate its existing logging instrumentation to OpenTelemetry. OpenTelemetry itself supports logs; this was a change to the customer’s instrumentation approach, not the elimination of logging. Traditionally, such a project requires educating hundreds of teams, explaining how to instrument their code, and getting each team to replace the relevant library usage.

The bottleneck is organizational as much as technical. A program manager tracks repositories in a spreadsheet while teams negotiate roadmap time. Pell describes conventional efforts of this kind as consuming tens of thousands of developer hours. That cost can make a useful migration stay postponed for years; the same coordination problem helps explain why old platforms and large COBOL systems persist.

With agents, one engineer directs the change while compute performs the repeated edits and repairs. For this customer migration, Pell reports under 100 developer hours plus thousands of compute hours. He says the project, postponed for years, was completed in one week through roughly 1,000 PRs, including repair iterations, merging, and migration. These are figures from his customer account, not a general productivity guarantee. The change in workflow is the consequential part: engineering effort moves from coordinating every implementation to directing and reviewing the operation.

3:554:02
Suggest correction

This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.

3:55 · section reference included

Plan, execute, and review

The workflow has three stages:

  1. Plan from a codebase index. Semantic indexing uses embeddings to represent file intent. Static analysis supplies code structure, imports, and the dependency graph. Both inform where and how to make the change.
  2. Delegate the edits. Language models assign file modifications to subagents. Those agents use GritQL, Grit’s code query and transformation language, alongside model-generated diffs to locate and modify relevant code.
  3. Review through PRs. The principal engineer directing the migration reviews the changes. Repository owners can respond with comments that inform subsequent work without ever opening Grit’s interface.

The PR remains the point where a centrally directed migration meets the developers responsible for each repository.

5:335:39
Suggest correction

This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.

5:33 · section reference included

Plausible code needs compiler feedback

Finding the right location does not make an edit correct. Pell demonstrates the distinction with Claude 3.5 Sonnet, asking it to convert linter JSON into diagnostics for Grit’s VS Code extension. He says the prompt contained about 100,000 tokens of extension context, including everything required for the task. The model produced a plausible conversion to Language Server Protocol diagnostics; neither the model’s output nor a human reading made the defect obvious.

Type checking and linting exist precisely because plausible code can still be invalid. But the first retry supplied no such evidence: Pell told Claude the code had broken in production and asked why. The response proposed an irrelevant fix. Reconsidering the same code without a concrete failure signal did not identify the underlying problem.

The TypeScript compiler, tsc, exposed incompatible Grit and LSP position and range types. Feeding that diagnostic back to the model led it to use the available range-conversion helper and correct the mismatch. The helper had already been in context; the compiler error made its relevance explicit. More context and better feedback solve different problems. Agents need access to the tools that make human developers effective, including compilers and linters, rather than relying on visual plausibility alone.

8:388:53
Suggest correction

This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.

8:38 · section reference included

Keep validation warm

A useful repair loop generates code, builds or type-checks it, and feeds the resulting diagnostics into another model call. Getting that loop to work reliably is a major part of building an agent. Its latency, however, can be dominated by ordinary developer infrastructure.

Pell’s customer example takes ten minutes for a from-scratch type-checking build, compared with roughly 30 seconds for model generation. That is not even the production build. Repeating the cold validation after every edit makes each repair expensive in elapsed time, and a sequence of attempts compounds the delay.

Slide titled “… but they are slow” showing Prompt, Build, and Fix stages labeled 30s, 10 minutes, and 30s.
A ten-minute build dominates the prompt–build–fix workflow.

An IDE avoids rebuilding everything after every keystroke. Its language server prepares an in-memory index, keeps it available, and incrementally reconciles affected code as files change. Pell illustrates a warm loop with 30 seconds of generation, one second of TS Server recomputation, and another 30 seconds for repair. These timings describe his example, not a general language-server benchmark.

For an agent that already owns a TypeScript language service, the validation step can request diagnostics from that retained service:

typescript

import ts from "typescript";

export function diagnosticsForEdit(
  service: ts.LanguageService,
  fileName: string,
): ts.Diagnostic[] {
  return [
    ...service.getSyntacticDiagnostics(fileName),
    ...service.getSemanticDiagnostics(fileName),
  ];
}

The service’s host must expose updated file versions and snapshots after an edit; recreating the service for every call would lose the intended reuse. Pell recommends the same kind of persistent tooling that supports an IDE. The distinction is retained state versus repeated cold work: the TypeScript compiler also supports incremental compilation, so a CLI is not inherently incapable of caching.

11:0711:17
Suggest correction

This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.

11:07 · section reference included

Return to a known good state

In the ideal loop, successful repairs eventually produce a commit and a migration PR. In practice, an agent can get stuck on an error, cycle through unsuccessful techniques, and then repeat them. Its context accumulates failed approaches and misleading explanations. Pell reports that Grit’s chance of producing a successful PR fell dramatically after more than ten consecutive prompts. His response is to save a known good state and return to it when a path stalls, rather than indefinitely extending the same failing chain.

Restoring source files alone would leave another cost: rebuilding the prepared environment. Grit also preserves the in-memory graph used by TS Server. Firecracker snapshots make it possible to capture the microVM’s memory and execution state. Pell describes forking that prepared state into ten isolated environments so different edits can begin with the expensive preparation already done. The checkpoint is therefore more than a Git revision; it includes the warm machinery needed to evaluate the next attempt.

13:1313:21
Suggest correction

This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.

13:13 · section reference included

Explore broadly, retain a short successful chain

Once prepared environments can be forked, the system begins to resemble distributed infrastructure more than a single assistant running on a laptop. Pell describes flows with six to ten agents working concurrently from a known good state. Each reports back with a candidate result. Evaluation combines model-based assessments with concrete signals such as remaining compiler errors and passing unit tests.

The next step is to choose which state becomes the new checkpoint. Pell uses a database voting analogy: favorable, similar candidate states inform a quorum-like choice, and the selected state becomes the starting point for another round of forks. This describes the selection strategy, not a specified formal consensus protocol.

Pell’s example spends 30–40 generations on a PR while retaining only four generations in its final selected chain. Total exploration can be large without forcing the successful path to carry every failed attempt. Checkpoint selection separates the amount of work performed from the length of the history that continues forward.

14:4314:52
Suggest correction

This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.

14:43 · section reference included

Whole-file output makes every attempt more expensive

Parallel exploration has an inference bill. Regenerating large files across repeated attempts emits the same unchanged code again and again. Whole-file generation is still the simplest initial implementation, and Pell recommends starting there. But the demonstration also shows its characteristic failure: Sonnet substitutes a comment saying the beginning of a function remains unchanged instead of reproducing the required code.

Output tokens also cost more than input tokens. Pell cites a historical $5/$15 input/output price pair for GPT-4o, and $3/$15 for Claude 3.5 Sonnet. Sonnet’s launch announcement specifies those rates per million tokens. These are talk-era price examples, not current API quotations.

A large context window does not imply an equally large response budget. Pell contrasts models accepting 1.5–2 million context tokens with outputs of roughly 4,000 tokens, without identifying the models in that example. The broader constraint is that autoregressive output remains costly and bounded. For a small modification to a large file, emitting just the edit avoids spending the response on unchanged content.

15:5216:01
Suggest correction

This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.

15:52 · section reference included

Use an edit format that preserves irrelevant code

Localized edits need a format the model can produce and the tool can apply reliably. Pell compares the alternatives this way:

FormatMain difficulty
Unified diffCorrect line numbers and diff structure
Search-and-replace through JSON function callsEscaping code inside strings
GritQL loose snippet replacementMatching a before snippet to the intended source

For unified diffs, he highlights unreliable line-number arithmetic and argues that diffs are less aligned with the full-file code models commonly encounter in training. JSON function calls avoid that particular format, but quotes, newlines, and other code characters require escaping, adding output overhead.

Grit’s loose replacement instead asks for a tutorial-like transformation: replace this snippet with that snippet. The model emits the before and after code, and the tool loosely matches the before snippet to the existing source before applying the replacement. Enough structure must remain to locate the intended code, but irrelevant contents can be omitted. In Pell’s example, that means not reproducing the existing body of makeMatch when it is unnecessary to describe the change. The edit format makes preservation the tool’s responsibility instead of asking the model to regenerate everything it should leave alone.

16:5717:03
Suggest correction

This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.

16:57 · section reference included

An interface for editing at multiple scales

The interface shown at the end still resembles CI: a conventional workflow view sitting above thousands of executing agents. Yet the engineer’s task has expanded beyond inspecting one run. It now includes understanding and directing changes across an entire codebase.

Pell’s proposed direction is closer to SimCity: zoom out to understand the whole system, zoom in to inspect a particular area, and edit at different levels of detail. This is an interface aspiration rather than a demonstrated shipped capability. It follows directly from the work the agents make possible: when one engineer can direct changes across many repositories, the interface must help that engineer see and control the system at that scale.

Slide titled “The next unsolved problem is UI” with an illustrated city labeled with classes and interfaces.
The next unsolved problem is UI: a city-like view of software structure.
18:0218:12
Suggest correction

This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.

18:02 · section reference included

Resources

From the talk

Read the complete timestamped transcript
  1. 0:00

    [on hold music] So I'm Morgante.

  2. 0:15

    I'm the founder of Grit. I'm gonna be talking about code generation and maintenance at scale, uh, or CPUs still matter and what it takes to actually make one of these agentic workflows work in production.

  3. 0:25

    Quinn was talking about how most people have not merged them. That's a hundred percent true. Uh, Grit has probably merged more PRs than any other company in the world at this point because we focused very narrowly and have done a lot of work above the model layer, and we're gonna talk about how we did that.

  4. 0:39

    Uh, it's helpful to know why I started Grit. My background is all developer tools. Uh, I've been working at Google Cloud for five years and built a lot of stuff, uh, on the DevOps layer, right?

  5. 0:49

    Thinking about Kubernetes and how do you orchestrate very large scale systems, uh, working on tools like Customize or Terraform templates. Uh, and one of the biggest things I learned from this was how rare it was for a customer to come to us and ask for a brand-new application, right?

  6. 1:04

    People didn't come and say, "I wanna build a new app on Google Cloud." It sounds cool. Ninety percent of the time customers came and said, "I have this line of business application that is doing a hundred million dollars in revenue.

  7. 1:14

    How do I run that on Kubernetes?" Right? And that's what all of our templates did. That's what everything we built, uh, in the sort of pre-AI era of automation was all on how you ran existing applications.

  8. 1:25

    And that's why we started Grit because every demo that you usually see that's hyped, you know, one of these ones on Twitter, it's usually type a prompt, get a new application from scratch, right?

  9. 1:33

    Build something brand new. It's exciting. It goes really well on Twitter. That's not what devs do day in and day out. Developers spend most of their time modifying huge applications so that flights run on time.

  10. 1:45

    And this goes into three sort of categories of developer tools, right? There's ID developer assistance. This clearly has the most product market fit today. It's really easy, right? Like Quinn was saying, you just do auto-complete, right?

  11. 1:55

    That's a very simple thing. Then there's AI agents that are focused on lowering the floor, right? They're allowing people to do tasks that they otherwise don't have the skills for, right?

  12. 2:02

    Allowing a product manager or other non-technical user to build an application that they don't have the skill set for. This is powerful, but I actually am pretty skeptical that that's how most software is being built in the future.

  13. 2:14

    It requires a real thinking of how do you actually spec things out? How do you think about edge cases? Basically, how we train as engineers that's required to build great software.

  14. 2:22

    Which is why with Grit, we focus on raising the ceiling of what great engineers can do, right? Principal engineers, the most high-level engineers that you work with, they're primarily limited by time, right?

  15. 2:32

    How-- they can't be in ten places at once. But AI agents can be in ten places at once if there's the right engineer controlling them. And that's what we focus on, is supercharging the productivity of the top one percent of engineers.

  16. 2:43

    It also helpfully gets around the problem of ninety-five percent of engineers not using AI. Uh, the great thing about Grit is ninety-five percent of our customers, ninety-five percent of their engineers don't touch it, right?

  17. 2:53

    There'll be a hundred engineers on the team. They're not l-- using Grit. There's one engineer who is deeply embedded with Grit and is generating hundreds of PRs with their agents.

  18. 3:03

    But to do this, tools need to change, right? The ID that you have today, it's a scalpel, right? It's focused on editing individual lines of code, and it's great for that, but it's not focused on editing hundreds of repos at once.

  19. 3:14

    It's not focused on how do you open a thousand files and make those changes in them, and that's why we built Grit. It's bas-- So we wanna have bulldozers for code, right?

  20. 3:20

    If you're generating huge quantities of code, how do you push that around in an effective way, uh, when you're not editing individual lines when you're working a higher level of abstraction?

  21. 3:30

    And this is super necessary, right? We've seen an explosion in how much code is being generated. A lot of our customers are seeing, uh, twenty to thirty percent more code, uh, is coming out of their teams now just because there's more PRs, there's more CI, there's everything that's running because you have code gen.

  22. 3:42

    And this is gonna accelerate, right? Once we go from five percent to maybe fifty percent of people actually using AI, there's gonna be way, way more code in the world, and we need better tools for managing that code once it's in production.

  23. 3:55

    So just to give an example of what this looks like in practice. Uh, this is a real cus-customer that we had. Uh, they are-- been around. They've got thousands of repos.

  24. 4:02

    They've got thousands of developers, and they wanted to use OpenTelemetry instead of logging, right? This is traditionally a massive effort, right? You have to coordinate across hundreds of teams to get them to understand OpenTelemetry, to understand how to instrument their code.

  25. 4:15

    You have to get them to do the actual code changes to swap out their logging library. You have to do a bunch of education efforts. And it's actually very much a people and process problem usually, right?

  26. 4:23

    Something where you have a program manager who has a massive Excel spreadsheet. That's when I say, like, Grit we compete with is actually Excel, not any other AI dev tool.

  27. 4:32

    It's that you'll go have these spreadsheets where you go and manage these changes, right? And tens of thousands of developer hours go into a change like that. So a lot of companies just say, "You know what?

  28. 4:40

    That's not worth it," right? "I'm not gonna migrate to OpenTelemetry. I'm not gonna go into the cloud. I'm gonna stay in my older ways." You know, people still have millions of lines of COBOL because it's just so much work to do this kind of coordinated change.

  29. 4:51

    Uh, with Grit, you don't have to do that coordination effort, right? Because you can have one engineer who is actually coordinating that change, is driving individual AI developer agents to do the changes.

  30. 5:00

    You don't have to have a bunch of meetings because it's just one person telling their, their little agents what to do, right? And you can do it with under a hundred developer hours because they're just doing high-level orchestration and then thousands of, uh, compute hours that the AI is doing as it's healing these changes.

  31. 5:15

    And we've seen ch-- This is literally a project that they had postponed for years because it just was not feasible. They couldn't get the-- get enough on the roadmaps.

  32. 5:22

    They got it done with Grit in a week, right? It just opened up a thousand PRs across all the repos, fixed them, uh, iterated on the changes, merged, and migrated over.

  33. 5:33

    So how do we actually do a change like that? Uh, it's sort of a three-level process. Um, planning is a big part of it, right? So we index the entire code base.

  34. 5:39

    Uh, we bui-do both semantic indexing, so understanding, uh, embeddings and understanding the intent of a file. Uh, but we also do a lot of traditional, more static analysis indexing, so we understand what's the structure of the code, what's being imported from where, what's the dependency graph, right?

  35. 5:52

    This is all the sort of thing you need to know to actually do really high quality agentic flows.

  36. 5:56

    Then once we have the plan of how we're gonna make changes, we execute the plan, right? So we use large language models that are gonna b- to take that change, delegate it to a sub-agent.

  37. 6:05

    The sub-agent is gonna make a m- modification in one file. Uh, it uses something b- called GritQL, as well as diff generation from language models. Uh, GritQL is our custom query engine that's able to actually index, uh, millions of lines of code and find the right places to modify things, and then finally push it up for PR

  38. 6:21

    review, uh, and be able to, uh, both have developers who are the director of it, right? So a typical scenario is that there'll be the principal engineer who's driving the change.

  39. 6:30

    They'll review the PRs. And then individual developers, their primary interaction with Grit is just seeing a PR land in their repo, and they m- leave like one line comment, uh, that Grit will learn from.

  40. 6:38

    But they don't actually open up the Grit UI ever because they're just responding to the changes that come from Grit.

  41. 6:44

    Cool. So a little bit more about how we find code, right? So our goal here is to find all the error logs in the codebase, 'cause we wanna migrate those over to OpenTelemetry.

  42. 6:51

    Uh, the naive approach that if you go to many of the workshops yesterday would be, all right, just chunk it, put it into RAG. Uh, you have a bunch of embeddings.

  43. 6:58

    Uh, and you know, that, you know, theoretically could work here for maybe some document use cases. I'll tell you that absolutely will not work for this problem, right? If you just go to try to find stuff that looks like, looks like a logging error, uh, it's gonna find a lot of irrelevant context, right?

  44. 7:12

    It's gonna find anything that looks like log-like. It, it-- LLM has a hard time differentiating between a user-facing log, like an alert in a UI, and an actual log that you wanna be putting into OpenTelemetry, right?

  45. 7:23

    There's also unpredictable thresholds, right? You don't actually know how much code you're looking for. You can't do, you know, retrieve the top ten, uh, closest matches. In some cases you wanna retrieve ten thousand.

  46. 7:32

    In a lot of cases, and developers don't even actually know how big of a change it is until Grit starts to propose it for them, right? So that's why we built the GritQL query engine.

  47. 7:40

    It's our own custom query system that combines the best of static analysis with the best of AI. So we've got this query here that's looking for, uh, logger, uh, with some set of args, right?

  48. 7:50

    So we're just gonna look for a function call, basically. Uh, and that's a syntactic query, so we're just looking for all of our function calls across our entire codebase.

  49. 7:57

    Uh, and then we're gonna say that our args should be like an error occurred, right? And that's just, we're giving an example of like what's an error that-- message that we might be trying to look like.

  50. 8:05

    Like there is a magical word that converts it into a semantic representation. So we wanna say, what's some code that, you know, embedding search, the cosine similarity is sufficiently above a threshold that this is an actual log message versus some other function call that we wouldn't be wanting to modify.

  51. 8:21

    And then we can finally do a imported from. We've got a built-in library that's able to understand the whole dependency graph. So we can do things like make sure this is actually imported from log4j.

  52. 8:30

    In this example, we wanted to make sure that we're only substituting our log4j logs, and that will go and traverse, uh, the import graph earlier in the program.

  53. 8:38

    So that brings us to finding the code that we wanna change. But once we've actually found the code, how do we make reliable changes? Uh, and unfortunately, really smart models, uh, still have a t- hard time doing this completely autonomously.

  54. 8:53

    Uh, just to give an example, uh, I just used Claude Sonnet today, uh, three point five. It's a really good model. Uh, and it uses, uh, we put, put the entire files, uh, so a bunch-- put a bunch of context into the context window, a hundred thousand tokens from Grit's VS Code extension on some of our linter

  55. 9:08

    outputs. Uh, and we wanted to just write a function that's gonna convert from our linter JSON output, uh, and puts it into diagnostics for the Grit VS Code extension, right?

  56. 9:16

    Pretty simple task. I promise that everything that's required was in the context window, right? It's not something where it had to go retrieve additional information. Uh, it was all there.

  57. 9:24

    Uh, ca- came back with a pretty reasonable completion, converts ESLint to LSP diagnostics. Uh, this looks reasonable to me. Like I i- imagine if you looked at this code, you wouldn't be able to tell anything that's wrong with it.

  58. 9:37

    I certainly couldn't tell anything f- that's wrong with it from eyeballing it, right? Uh, but this is wrong, right? And this is one of the main things to understand is that, uh, humans also can't look at this code and understand what's wrong with it, right?

  59. 9:47

    This is why we have systems that allow us to, uh, type check, lint things, right? It allows us to understand code that even looks kinda correct is, in fact, incorrect and will fail in production.

  60. 9:58

    But I went back and just asked, uh, Claude to fix the code for me. I said, "This broke in production. I tried to put it in my VS Code extension, it broke."

  61. 10:05

    And I just ask it why. Uh, as you can kind of imagine, doesn't do any better than I do of just looking at it, looking and eyeballing the code and understanding why it's wrong, right?

  62. 10:13

    Uh, so it just comes and spacks says some totally irrelevant answer of how to fix it because, again, it's not grounded in what the actual errors are.

  63. 10:20

    Uh, fortunately, uh, we have a great tool for TypeScript called TSC, right? We can compile this, and it's gonna go and tell me actually, uh, Grit positions and Grit ranges have a slightly different type signature, uh, than LSP ranges, right?

  64. 10:32

    And this is, you know, why compilers are great, is we can actually get that information really close in the dev, dev loop. With this information fed back into an LLM, it's able to correct that mistake, uh, no problem, right?

  65. 10:42

    That's a pretty easy change. It uses the convert LSP range to Grit range, which by the way, was in the context window. It could have used that before. It just didn't realize that it needed to use that until it had the compiler error forcing it to, right?

  66. 10:54

    So this is already how I think I-- It's important to see that IDs are already making us superhuman, and we need to make sure that all of our AI agents have access to the same tools that make them, uh, super AI.

  67. 11:07

    Uh, so compilers rock, right? This basic flow of prompt, get some code, uh, build it, type check it, and then fix that output based on the LLM. This is actually really powerful.

  68. 11:17

    This is probably, uh, half of what you need to do to build a really good agent, is make sure that you have this flow working reliably.

  69. 11:23

    Uh, but they're really slow when you're talking about enterprise codebases. Uh, so this is real numbers from, like, one of our customers. Uh, it takes them ten minutes to build their application from scratch, and that's just for type checking.

  70. 11:34

    It's not even producti- pushing a production build, right? And this is actually pretty typical if you look at very large scale enterprise codebases. Uh, that's why large companies have had to build a lot of caching, because it's hard to build a large codebase from scratch, which this is completely different than what people usually expect for AI.

  71. 11:49

    People usually think inference takes a long time, right? You're waiting for an AI. And this is actually a pretty long prompt, thirty seconds, right? We're using a huge model to cr- generate this code.

  72. 11:57

    Takes thirty seconds. But that's dwarfed by the ten minutes to build the application, right? This basically destroys our entire agentic flow if we're waiting ten minutes for every single change to validate that it's correct.

  73. 12:08

    But- This is even more compounded if we're trying to do that in a loop, right? If we're trying to do a single change, it might take a day if you're just doing this naively.

  74. 12:16

    Uh, there's some agent projects that, in fact, do take a day to make very basic changes because you don't have, haven't done this optimization level. But you might ask, like, how are you able to make changes in your IDE at a fast rate, right?

  75. 12:27

    You're not waiting 10 minutes every time you make a single keystroke to get a compiler error. Uh, it's much faster than that. It's because there's been a lot of work with language servers, uh, to solve this so that you can do a bunch of upfront prep, so you can build the index in memory, have that in-memory queryable

  76. 12:41

    index, and then only rewrite the parts or only recheck the parts that you've modified, right? On every keystroke, uh, most tools, like TS Server, for example, in TypeScript, uh, is doing live reconciliation of figuring out that specific file, right?

  77. 12:53

    And this is much, much faster. You can do the 30-second prompt, then one-second recompute from the TS Server, then 30 seconds to fix it, and this is a much more reasonable flow, right?

  78. 13:01

    So you obviously wanna be using the same kind of language server tools that you'd be using as a human, uh, not CLI-based tools, which often don't have the same heuristics in place to be able to optimize.

  79. 13:13

    And then, you know, ideally, you do this in a nice loop. You eventually get to the point where you can commit and get a gr- fresh PR to do that migration to OpenTelemetry.

  80. 13:21

    Th- but this is what it looks like in theory. In practice, at some point, it hits an error that it can't fix, right? It hits a error that gets into a loop, and it's continuously trying to fix the same error.

  81. 13:32

    It uses five different techniques, then goes back, and your context window's completely polluted with the wrong errors, right? Everyone s- often says, like, "Agents don't work." Uh, this is probably half of the reason that agents don't work, is that you just have compounding failures, right?

  82. 13:44

    We found anytime we actually have more than 10 prompts in a row, uh, our chance of having a successful PR is dramatically lower, right? Uh, so the way we work around that is instead of trying to repeatedly fix an error, uh, we should actually just save our o- original state, revert back to that, uh, and then re-

  83. 14:02

    continue to edit from there, right? So if we went down a path that was just a bad path and we got stuck in a row, we wanna go back to a known good checkpoint, uh, and then build from there.

  84. 14:11

    And this is actually how we're able to do this quickly. We don't wanna spend 10 minutes recomputing each time. Uh, we wanna actually build our in-memory graph that we talked about with TS Server.

  85. 14:19

    We wanna save that. We wanna take a snapshot of memory. Uh, so we use Firecracker. It's a VM manager, uh, that's used for AWS Lambda, but we can actually use it for dev environments too.

  86. 14:28

    Uh, and we can actually take the in-memory state, snapshot that, and then fork it into 10 different isolated environments that all have everything pre-computed. You can try 10 different changes in them and then figure out the correct change that is most likely to yield good results from there.

  87. 14:43

    And in fact, this becomes massively parallel. You can end up with an AI system that looks more like a distributed database than it does a traditional agent or something that you're running on your laptop, right?

  88. 14:52

    We actually have flows where we often have, uh, six up to 10 different agents working in parallel, all working from a known good state. They're supposed to report back once they're done.

  89. 15:02

    And then we'll actually look at the different evaluations. We look at, uh, both some LLM-based evals, but also heuristics like how many errors that are currently in the code base, uh, how many unit tests are currently passing, uh, and then actually compute, like, what of these, which is the quorum, right?

  90. 15:15

    It's actually similar to, uh, again, a database system where you would have a voting of, like, what's the new master. Uh, here it's like, what's the new good state that we wanna fork from?

  91. 15:23

    Uh, if you have these four here that have similar states that we wanna use that as our new known good state, uh, save that as our known good state, and then fork from there going forward, right?

  92. 15:32

    And this ends up being much, much more reliable because we can have an entire PR that, yes, we've done 30 or 40, uh, different generations on it, but in the final chain, there was only four different generations, right?

  93. 15:44

    Because we had one, then we got went back to a known good state. Then second one is all operating from that quorum at each checkpoint.

  94. 15:52

    But these edits get pretty expensive, right? If you're doing, uh, 40 different edits to make a single PR across very large files, uh, that's a lot of money that you're spending on inference.

  95. 16:01

    Uh, this is a common problem with making good edits. Everyone naively just asks for, "Generate the whole file again," right? It's the simplest approach. You definitely should start with that if you're building your own AI tool.

  96. 16:10

    Uh, but then you run into the classic problem of laziness. So this is actually still from, uh, Sonnet. It still said, you know, uh, the start of the function remains the same, right?

  97. 16:17

    Left this comment in because it didn't wanna output that code. And it's just because output tokens are fundamentally more expensive. And if you look at GPT-40, it's a five to $15 ratio of input tokens to output tokens.

  98. 16:28

    Uh, Claude 3.5 Sonnet is three to 15. Uh, this is pretty consistent across the board. And then response limits are not growing at the same level of context size, right?

  99. 16:36

    We've got models out there that have 1.5 million tokens, 2 million tokens in their context window, and still only outputting 4,000 tokens at a time, right? Because it's autoregressive, it gets much more expensive.

  100. 16:47

    So you really don't wanna output entire large files as you're making edits. You wanna find a good edit format. Uh, so whole edit format works well. Uh, it's very expensive though.

  101. 16:57

    Uh, you can do diffs, right? You can say, like, "Generate a unified diff for this." Try to apply that. Um, there's some problems with this. One is, like, line numbers.

  102. 17:03

    Uh, LLMs are still not very good at knowing what the right line number is, even if you give it them. They're just not that good at the math part.

  103. 17:09

    Uh, and there's also off-distribution, right? Real-world code they're trained on is largely not trained on diffs, right? It's trained on actual full files. Uh, you can do simple search and replace with function calls.

  104. 17:19

    Uh, the problem with this is function calls are underneath, for the most part, JSON. Uh, escaping code in JSON format is terrible. You end up using a lot of tokens just for, uh, just escape characters, right?

  105. 17:29

    It's just not a very good format to use. Uh, so that's why we actually developed a GritQL loose search and replace. So we can actually do something that's similar to what you would have on the model of being just a before snippet, and this is something you might have, like, in a tutorial, which is like, "Replace this

  106. 17:42

    with that," right? This is what we ... And this is actually the exact same output that comes from the LLM. We'll do a match. Like, we'll do a loose match to try to find what's the code that looks like that, and replace it with the code that looks most similar to that afterwards, right?

  107. 17:53

    And this works really, really well because we don't have to ... We can elide irrelevant details, like what's currently inside the makeMatch function, and just give enough detail to make the replacement.

  108. 18:02

    Cool. Uh, and just wanna leave you with where we're going next. This is our current UI. It still is very traditional, right? It still is, uh, building a, you know, what's a AI workflow.

  109. 18:12

    Looks kinda like your CI, even though it's thousands of agents executing. Uh, I'm really excited about where we go next with this, uh, figuring out, like, what does it look like to manage an entire code base.

  110. 18:21

    I think of, like, SimCity as, like, the ultimate where you can zoom in and out and understand, uh, different levels of granularity and edit things there. Cool. Uh, thanks so much.

  111. 18:30

    I'm Morgante, and we are hiring, so, uh, scan the QR code. [upbeat music]