← All AI Engineer talks

AI Engineer World's Fair 2026

Loop Engineering from first principles

Read the talk

Loop Engineering from First Principles

Build coding-agent loops around measured errors, small changes and human review, using an incremental RPC-to-Effect migration to connect control theory with practical CI workflows.

From a talk by Kyle Mistele

Before you start: Familiarity with pull requests, CI workflows and coding agents is helpful; no prior knowledge of control theory or Effect is required.

What happens when nobody can review the PR?

A coding agent can keep working, verifiers can keep checking, and review agents can keep reviewing—yet the result can still be a pull request nobody wants to read. Kyle Mistele opens with an illustrative failure: six review agents surrounding a 40,000-line PR. More automated scrutiny does not, by itself, make that change understandable to the team responsible for shipping it.

Geoff Huntley’s Ralph is a useful tool for some workloads. Mistele sees its appeal especially in solo work and noncritical systems. The harder problem is using loops in a team maintaining software with customers, regulatory obligations and service-level agreements. Those constraints make the size and comprehensibility of each change part of correctness.

Slide with a cartoon character at an oven and a diagram connecting Prompt to Agent to done, with a return arrow labeled while (true).
Ralph Wiggum as a “software engineer,” alongside a repeating prompt-to-agent loop.
0:270:41
Suggest correction

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

0:27 · section reference included

Loops should make code easier to read

The enthusiasm for loops began with a simple shift: instead of repeatedly prompting a coding agent yourself, design a loop that prompts it. Mistele traces the discussion from Ralph’s original post to Peter Steinberger’s advocacy of loop design. In his description of OpenClaw, loops build, review, merge and release code; other loops find bugs, including bugs in the loops themselves. He also cites Boris Cherny describing his engineering work as writing loops to prompt Claude.

Push that logic further and the volume of generated code becomes a reason to stop reading it. Verification and automated review take over, and code becomes effectively write-only. Mistele treats the accompanying claims of tenfold speed as an unsettled promise, not an established result.

His counterexamples concern both reliability and cost. Mistele says Claude Code’s terminal flicker took six months to fix, while OpenCode built a renderer in a fraction of that time; this is his historical anecdote, not a controlled development-speed comparison. The terminal-flickering issue documents the reported problem. He also points to OpenClaw stability problems and the expense of running these systems without a frontier lab’s token budget. Drawing on Matt Pocock’s argument, he adds that bad code becomes especially expensive when agents keep building on it.

Design loops that improve the code while humans continue reading it. A loop can remove bad patterns, make changes easier to review and solve difficult problems in a complex repository. The software factory can emerge incrementally, with engineering discipline applied to the loop itself.

1:552:03
Suggest correction

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

1:55 · section reference included

Measure, correct and measure again

Control theory asks how to drive a changing system toward a desired state. For a coding loop, the system is the codebase. A sensor measures its current state, and a set point specifies the desired state. The difference is the measured error. A controller converts that error into an incremental correction, and an actuator applies the correction while other changes continue to disturb the system. Measuring again closes the loop.

Control Theory diagram showing a set point entering an error junction, followed by Controller, Actuator and System, with a disturbance input and a Sensor feeding measured output back.
A control loop connects measured error, controller, actuator, system and sensor.

The same basic structure appears in a thermostat: measure temperature, compare it with the setting, act, then measure again. Software engineers already encounter related mechanisms in Kubernetes autoscaling and infrastructure-as-code reconciliation. Mistele also describes PostgreSQL autovacuum and React’s virtual DOM as using or approximating control loops. The common requirements are a system you can change, a problem you can measure and feedback about the result.

Incremental corrections reduce the chance of oversteering. Instead of attempting the entire desired end state in one change, the controller makes a bounded move and checks its effect. That is the useful distinction between a feedback loop and a blind loop. It is not a categorical rejection of Ralph: Mistele explicitly recognizes that the best Ralph implementations already apply control principles and that Ralph is a teaching device, not an instruction to abandon judgment.

4:334:43
Suggest correction

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

4:33 · section reference included

Separate the responsibilities, even when one agent performs them

Start an agentic control loop by defining a property the codebase should satisfy, then choose how to detect deviations. Simply repeating a Bash command does not guarantee incremental progress; the sensing and selection policy must supply that discipline.

Sensor approachSuitable ingredients
DeterministicESLint rules, ast-grep, Packwerk
AgenticAn agent, a skill and natural-language rules
HybridA pipeline combining deterministic checks and agent judgment

These are alternatives for measuring the discrepancy, not requirements to make every part of the loop agentic.

The implementation boundaries can overlap. Mistele uses Aiden Bai’s React Doctor as an example of a hybrid sensor and controller: it identifies React problems, prioritizes fixes and explains how to make them. Likewise, one agent can select a change and implement it in the same context window. Combining components does not remove the controller’s responsibility to limit the size of a change and choose the right direction. Repeated oversized or incorrect corrections can quickly destabilize the codebase.

6:597:15
Suggest correction

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

6:59 · section reference included

Choose a measurable maintenance workload

Pattern cleanup is only one application. A loop could check an API against someone else’s OpenAPI specification, maintain compliance with the particular MCP specification version a server targets, mirror a project between Python and TypeScript, or keep a Vite-based Next.js fork aligned with upstream. Each candidate needs the same three properties: a measurable discrepancy, incremental corrections and feedback on their quality.

HumanLayer’s example is an incremental migration of its RPC API to Effect. The team first adopted Effect for race-prone code, liked the result and began extending it across the codebase. In the recording, Mistele places a small procedure beside its Effect rewrite to establish the transformation the loop will perform. The syntax is incidental to the loop design; this is a migration chosen for the team’s needs, not a recommendation that every codebase adopt Effect.

8:298:40
Suggest correction

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

8:29 · section reference included

Find old procedures—and stop adding new ones

The first implementation task is a sensor that finds unmigrated RPC procedures. An agent or a text search could do this, but Mistele chooses ast-grep for structural matching. Its scanning rules can live outside the ordinary TypeScript and ESLint configuration, avoiding reliance on checks an agent might suppress with inline comments. Additional rules can target other unwanted patterns, with granular include and exclude paths across supported languages in a monorepo.

The raw results need normalization before they become a useful control input. In Mistele’s workflow, ast-grep produced roughly 50 keys per violation; the team retained four fields and sorted the results deterministically. That count describes this workflow, not a fixed output contract. The practical purpose of processing ast-grep’s JSON output is to turn a verbose scan into a stable list that can be compared between revisions.

Before migrating the backlog, prevent it from growing:

  1. Run a full scan on main.
  2. Sort the violations deterministically and commit the baseline to version control.
  3. Scan each pull request and check whether it introduces any new unmigrated procedures.
  4. Require new procedures to use Effect while existing procedures are migrated incrementally.

This lets the repository carry known migration debt without treating new debt as acceptable.

Other developers are still changing the system while the loop works. Without the regression check, their changes could undo its progress. Mistele loosely calls the baseline check a disturbance dampener: it is a practical safeguard around the control loop rather than a perfect one-to-one mapping to a control-theory component.

9:409:52
Suggest correction

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

9:40 · section reference included

Choose a small correction with a useful purpose

A minimal controller can use Bash and jq to select the first violation from the sorted list. A more selective controller can use structural analysis to choose the smallest unmigrated procedure, limiting the scope of the next change. An agent could make the selection, or select and implement together, but Mistele recommends keeping deterministic decisions in deterministic code.

The migration also has an operational purpose: better error handling and instrumentation. A more ambitious controller could use telemetry to prioritize procedures with frequent errors, weak instrumentation or gaps in application performance monitoring. The control signal would then contain both the selected procedure and the evidence explaining what should improve. That gives the actuator a reason to improve the implementation rather than mechanically translate its syntax. The accompanying diagram makes the handoff concrete: Sentry traces and errors inform selection, and sample trace data travels with the chosen procedure to the agent.

Data-Driven Controller diagram with AST-Grep Rules, steps to fetch Sentry traces and errors by procedure and pick the most errors or worst performance, and an Actuator (Agent) receiving the selected procedure and sample trace data.
A data-driven controller selects a procedure using Sentry traces and errors, then passes trace data to the actuator.
11:2111:38
Suggest correction

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

11:21 · section reference included

Give the actuator local patterns to follow

The actuator is a CLI coding agent plus a skill. The skill deserves substantial attention, but it should evolve through observed results rather than being treated as a specification that must be perfected before the first run. HumanLayer writes golden patterns by hand: idiomatic examples that show the agent how this repository expects a change to look. Without those examples, the agent falls back on documentation and patterns learned elsewhere.

Pass the skill and the controller’s selected target into the actuator together. Include a response template in the skill so the agent’s final message can serve as the pull-request description. Once the agent finishes, deterministic workflow steps commit the change, push the branch and create the PR. The agent handles implementation; ordinary automation handles publication of its proposed change.

12:2612:41
Suggest correction

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

12:26 · section reference included

Use existing CI, then fix the correction friction

Existing CI is a practical place to run the loop. GitHub Actions, GitLab or CircleCI already provides repository access, secrets, dispatch and scheduling. A workflow can perform one sense–control–actuate iteration, create a PR and run on a daily schedule. There is no need for a separate cluster merely to orchestrate this sequence. The intended result is a small change waiting for review each morning.

That initial design was frustrating enough that HumanLayer turned it off. Correcting an output meant checking out the branch, changing the skill, changing the code, committing and pushing again. The migration itself might be small, but steering the automation demanded too much manual work. A useful loop therefore needs a low-friction way for a human to correct both the current proposal and the instructions that will shape future proposals.

13:2213:36
Suggest correction

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

13:22 · section reference included

Turn review comments into persistent steering

Add a Markdown feedback file to version control and load it deterministically into the actuator’s context on every run, after the controller has selected the work. Then label every generated PR with an identifier for its loop. The label matters when several workflows operate in the same repository: each must recognize its own PRs and respond only to feedback intended for it.

The correction path starts with a reviewer leaving an /iterate comment:

  1. The corresponding loop workflow receives the comment trigger.
  2. It loads the PR diff, comments, review comments and description into the agent’s context alongside the skill.
  3. It instructs the agent to fix the proposed code and update the feedback file.

The review now produces both a repair to the current PR and reusable guidance for subsequent actuator runs.

Keeping that guidance in version control makes changes to the loop’s behavior inspectable. The team can see how its instructions evolved and revert them when necessary. Human steering becomes part of the repository’s reviewable history rather than a series of manual skill edits that are difficult to reconstruct.

14:1314:24
Suggest correction

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

14:13 · section reference included

Stop producing changes when review is blocked

A scheduled loop can outpace its reviewers even when each individual change is small. HumanLayer encountered this during travel, customer visits and other work: PRs accumulated, duplicated effort and conflicted. Useful maintenance became another backlog demanding attention.

The existing PR label supplies a simple backpressure mechanism. Before checking out code, installing dependencies or invoking an agent, query for open PRs carrying the loop’s label. If one exists, stop the new run. The gate permits at most one open PR per loop.

An outstanding PR is a conservative signal that the previous output has not cleared the human-review boundary. Producing another change does not resolve that bottleneck. Waiting prevents a stack of new proposals from building up behind it, reduces duplicate work and, as Mistele qualifies it, hopefully avoids conflicts.

15:1015:25
Suggest correction

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

15:10 · section reference included

Increase throughput as confidence and review capacity grow

Once the loop produces changes the team trusts, the next question is how to accelerate it. Mistele cites a backlog of 150 RPC procedures and estimates roughly six months at the preceding pace of one procedure per daily run. That is a planning estimate, not a measured completion rate; review delays also affect how quickly the backlog clears.

He proposes two ways to increase the work selected in an iteration:

  • Larger batches: Have the controller select three or five procedures instead of one.
  • Separate implementation contexts: Select a batch, then migrate each procedure in its own implementation phase and context window. Mistele expects this separation to be cheaper and more reliable; he presents no measured comparison.

The distinction is between how much work the controller chooses and how much context each implementation receives.

Another proposed extension distributes review ownership: run the workflow four times and give one PR to each of four teammates. This would require adjusting the earlier single-open-PR policy; the talk does not specify that concurrency design. The underlying constraint remains human capacity to read the resulting changes.

The resulting operating model improves the code incrementally, slows down when review cannot keep up and accepts corrections through the same PR interface the team already uses. Mistele closes by inviting viewers to try the offered skill and share what they build. The useful endpoint is a loop whose output remains readable and whose behavior the team can steer as it learns.

Closing slide with a skill installation command above five bullets: Build control loops; Read the code; Make the code better; Manage risk with incremental change; Use adaptive flow control & steering.
Closing recommendations pair control loops and code review with incremental change, adaptive flow control and steering.
16:1716:27
Suggest correction

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

16:17 · section reference included

Resources

From the talk

Read the complete timestamped transcript
  1. 0:00

    [upbeat music]

  2. 0:27

    Hey, everybody. My name's Kyle. I'm co-founder of a company called HumanLayer, and I'm here to talk about loops. I think we've all been building loops lately, and I've realized recently I think we're all doing it wrong.

  3. 0:41

    Loops are really powerful, don't get me wrong. But so much of the discourse around them is hype driven and just really not helpful, right? We, I think we have this idea, just kind of as an industry somehow, that we can, like, pipe a prompt in a loop to a coding agent and that we can build software this

  4. 0:57

    way, right? Maybe we're investing a lot of time in verifiers. Maybe you have six different code review agents. But at the end of the day, if we're doing this, we're still building forty thousand line PRs that just nobody wants to read, right?

  5. 1:12

    And this isn't to throw shade to Jeff Huntley, right? This is... Ralph is an innovative, uh, it's a sharp tool that works very well for certain types of problems.

  6. 1:22

    It works very well if you're not building on a team, and it works very well if you're not working on critical systems. But most of us are working on teams, and we don't fit in that box.

  7. 1:33

    So today I wanna talk about how to build loops that work in large, complex code bases for systems that have real customers, real users, real regulatory obligations and service level agreements, and everything else that keeps us from shipping yellow forty thousand line PRs straight to production.

  8. 1:51

    In other words, I wanna talk about how to build loops for the real world.

  9. 1:55

    If you're not aware, uh, this post actually dates back to July. It went viral this past January, which is when a lot of us, I think, started building loops.

  10. 2:03

    And of course, much more recently, I'm sure y'all are gonna see this slide a lot this week. Uh, but Peter Steinberger said that we shouldn't be prompting coding agents anymore, right?

  11. 2:12

    We should just be designing loops that prompt our agents. Of course, OpenClaus notoriously built on loops. Loops build the code. Loops review the code. They merge and release the code.

  12. 2:22

    They find and fix the bugs. There's even loops for finding and fixing bugs in the loops that are merging the things, right? It's loops all the way down. It's, uh, Boris Turney, also the creator of Claude Code, recently said that this is his entire job as an engineer now is just writing loops to prompt Claude.

  13. 2:41

    And eventually, we might not even need loops, right? We're just gonna have, like, swarms of agents designing loops to prompt agents building swarms for loops and, like, I don't know, somewhere we're, like, writing production code, I assume.

  14. 2:56

    And in fact, all of our loops that we're building are producing so much code that we can't possibly read all of it, right? So we might as well just not read any of it, right?

  15. 3:06

    We're, we're investing in verification and in code review, but all this code is read-only. This was the thesis of a conference that, uh, was here in town last month.

  16. 3:14

    So a lot of smart people at the frontier labs think that this is the future of software development, and if you're doing this, you're moving ten X faster and everybody else is getting left behind.

  17. 3:26

    Now, it's not clear how well this works yet. Uh, took six months to fix the Claude Code terminal flicker. The OpenCode team wrote a renderer in a fraction of that time.

  18. 3:36

    And OpenClau, of course, also notoriously has stability issues. What is abundantly clear, however, is that this shit is really expensive if you don't work at a frontier lab and have an unlimited token budget.

  19. 3:50

    And all this code that we're writing is actually really expensive, right? Matt Pocock talked about this recently. Uh, bad code is much more expensive in the age of agents than it, it has ever been at any point in the past.

  20. 4:03

    So today I wanna talk about what I think works in the real world and what we've started doing at HumanLayer, which, to be clear, is still building loops, right?

  21. 4:12

    I think loops are super powerful, but we can design loops and still read the code. In fact, we can design loops that make it easier to read the code because the loops are making the code better.

  22. 4:23

    We can solve hard problems in complex code bases with loops, and we can build our software factory incrementally. But, uh, to do this is gonna take some real engineering, y'all.

  23. 4:33

    So let's talk about control theory. Control theory is all about how we drive a dynamic system, which would be your code base, towards some desired, stable or optimal end state, right?

  24. 4:43

    You have a sensor that measures the current state of the world. You have your set point, right? The desired state of the world. And the difference between those two things is your measured error.

  25. 4:53

    You have a controller that reads that measured error and turns it into a control signal about an incremental change to apply to the system. We have an actuator that applies that change to the system, which is undergoing disturbances in the meantime.

  26. 5:07

    And then we re-measure, recompute our measured error, and we're back where we started. Now, this sounds really complicated, and it can be. I have a twin brother, actually, who's an aerospace engineer.

  27. 5:18

    This is how they keep fighter jets from falling out of the sky. Uh, but, uh, it's probably a little bit simpler than most of y'all think. Does anyone have one of these?

  28. 5:28

    Uh, a thermostat uses a control loop, right? Uh, for, for any of our European friends in the audience, it's part of something we have, uh, here in the States.

  29. 5:37

    It's called air conditioning. [audience applauding] And, uh, most of us probably actually use control loops on a daily basis, right? Kubernetes auto-scaling systems are built on control loops. Infrastructure as code uses a desired state, current state, iterative change, like control loop pattern.

  30. 5:58

    PostgreSQL's, uh, autovacuum and React's virtual DOM both use or approximate control loops. Control loops are ideal when we have a system that we wanna change, a problem we can measure, and a way to get feedback on the result of that change.

  31. 6:12

    Like good software engineers have always been taught to do, control loops change a system incrementally instead of just trying to get straight to the end state immediately all at once and risk blowing everything up, right?

  32. 6:23

    They help us to avoid oversteering and destabilizing the system, and it minimizes risk.

  33. 6:30

    So, control loops are the opposite of what I'm gonna call a blind RLHF loop. They're how we avoid PRs that look like this, 'cause nobody wants to review this, right?

  34. 6:39

    Which is not to say that all RLHF loops are blind loops. The best RLHFs are actually applying control theory. I know Jeff Huntley is out in the hall somewhere wandering around.

  35. 6:47

    If you go talk to him, he's gonna tell you the same thing, right? That RLHF is a- a teaching device, and I think some of us read it a little too literally, but this is how we should have always been building loops.

  36. 6:59

    But the other issue with RLHF loops is they're not incremental, right? It's just a bash loop. So we have to build agentic control loops. And to do that, we start by defining a set point, which is the desired end state of our code base with respect to some property of it, and we add a sensor.

  37. 7:15

    There's a lot of ways to build a sensor. It can be strictly deterministic, your ESLint rules, your AST grep, your pack work, or it can be non-deterministic. You can have an agent and a skill and a bunch of natural language rules, and you could also just have a pipeline, like a combination of the two.

  38. 7:33

    So how do we build agentic con- whoops. There we go. Now, uh, this is all theory, right? Practically speaking, and because we're using agents, we can blur the lines a little bit between system components.

  39. 7:45

    So Aiden Bye's React Doctor, for example, is fantastic. It is, uh, it's a great way to catch all of the React slop that Claude snuck into your code base last week.

  40. 7:56

    But, uh, it's a hybrid sensor and controller. It tells you what are all the problems with your React code, and also, by the way, what are the top three things you should fix and how do you fix them?

  41. 8:06

    Similarly, our controller and actuator might actually just be a single agent deciding on an incremental change to make and then applying it in the same context window. But I wanna zoom in on the controller a little bit because without one, or without a well-tuned one, we might make too large of a change all at once, or we

  42. 8:23

    might make the wrong change entirely. And if you put that in a loop, you're in trouble pretty quickly.

  43. 8:29

    So we can use control loops to root out bad patterns and to clean up our code, but we can actually use them for all sorts of things, right? We could make sure that our API is compliant with someone else's OpenAPI spec.

  44. 8:40

    We can make sure that our MCP server is compliant with whatever version of the, uh, the MCP specification that we're currently on. Haven't checked. You could mirror a project from Python into TypeScript or vice versa.

  45. 8:54

    You could even maintain your, uh, Vite-based slop fork of Next.js against the upstream. The key questions are, can we find something we can measure? Can we apply changes incrementally?

  46. 9:05

    And can we get feedback on the quality of those changes? To illustrate that, I'm gonna walk through a control loop that we use internally at HumanLayer. Uh, for our loop, we are incrementally migrating our RPC API to Effect.

  47. 9:18

    We adopted it for some of our race-prone code. We like it, so we're adopting it across the rest of our code base. If you've never seen Effect code before, the code on the right is just the kind of trivial procedure on the left rewritten in Effect.

  48. 9:29

    Uh, the syntax is really weird. We're psychos. We really like it. It's not for everybody. That's okay. Uh, this isn't a talk about Effect, so we'll keep moving. Ooh, clicker's not working.

  49. 9:40

    Cool. So step one, we have to build our sensor to find unmigrated procedures. We can have an agent do this, or we could use grep or ripgrep. But instead, we're gonna use ast-grep 'cause it's really powerful.

  50. 9:52

    It's a great tool to have in your toolbox for building loops. It's language agnostic. It's out of band from your TypeScript config or ESLint rules, which if you're a TypeScript developer, you have watched Claude disable those with inline comments.

  51. 10:05

    Uh, but so we can just write a simple rule that finds unmigrated procedures, uh, based on the pattern above. And we, over time, we can even layer on more rules that describe other patterns we wanna get rid of with granular include and exclude paths.

  52. 10:17

    If you have a multilingual monorepo like we do, uh, it'll work for any language you could possibly imagine. And we can just scan our code base, and it'll produce a long list of violations.

  53. 10:27

    Uh, way too long, in fact. It'll give you about 50 keys per violation, so we're just gonna filter it down to four, and we're gonna sort it deterministically. Why are we doing that?

  54. 10:36

    At the beginning, I said this was gonna be practical, and so we're gonna step outside of our control loop paradigm for a second because before we start incrementally migrating procedures one at a time, we need to enforce that all new procedures are using Effect, right?

  55. 10:48

    So we're gonna run a full scan once on main, sort all the violations deterministically, and track it in our version control. And then on every new PR, we can see if a- the branch added any unmigrated procedures, right?

  56. 11:01

    So this is our control loop, and our system is undergoing disturbances. In this case, uh, all of our teammates shipping Claude slop, and this is how we make sure that they're not undoing our loop's work.

  57. 11:11

    This doesn't map directly to a part of the control loop, but we can kind of, like, squint at it a little bit and call it a disturbance dampener. So now that we've stopped the bleeding, we can actually design our controller.

  58. 11:21

    For a simple controller, we could just deterministically pick the first violation from the list. You can use Bash and jq. Or we could get a little cleverer and use ast-grep to find the smallest unmigrated procedure and always pick the smallest one to reduce the risk.

  59. 11:38

    Uh, we could have an agent make the decision if we really want to. I don't think you should ever send an agent to do deterministic code's job, but you certainly can.

  60. 11:45

    In fact, depending on the complexity, we could have the agent pick the procedure to migrate and just do it at the same time, like we just talked about. But we can make this even more powerful, right?

  61. 11:54

    Because we're not just migrating to Effect for the sake of it. We're doing it because it's helpful for handling errors and for helping us instrument our code better. And so what we could do if we wanna get really clever is we can look at our telemetry and figure out which procedures have the most errors or the least

  62. 12:08

    instrumentation or has a gap in our APM, right? And when we send a control signal to our actuator agent, we can include not just the procedure to migrate, but also all the data about the things that we're trying to fix with this migration so that the actuator agent can actually make the code better instead of just doing

  63. 12:26

    a one-to-one migration. Oh, man. There we go. So next is building our actuator. Our actuator is just an agent plus a skill. Um, bring your CLI coding agent of choice.

  64. 12:41

    You should spend a lot of time on the skill. Not all of that should be up front. You'll want to iterate on it over time based on what works.

  65. 12:47

    At HumanLayer, we like to build out what we call golden patterns by hand before setting the agent loose. These are just, like, idiomatic handwritten examples for the agent to follow because they're just pattern replicators, and otherwise you're getting what's in the docs or what the agent knows from the internet.

  66. 13:00

    And so we pipe the skill plus our control signal into our actuator agent. And the skill, of course, should include a response template, and the agent's gonna work, and work, and work, and it'll produce a final response.

  67. 13:13

    And then we're going to deterministically commit, and push, and create a PR using the final message as our PR description. Now all we have to do is actually run the loop, right?

  68. 13:22

    Uh, my recommendation is to use GitHub Actions, or your GitLab, or your CircleCI, or whatever else you're using because it has access to your code, it has access to your secrets, and it has great dispatch and scheduling primitives, right?

  69. 13:36

    We don't need a new cluster for this. So we can write a workflow that runs a single iteration of the loop, sense, control, actuate, and creates a PR. And then we can schedule this to run once a day.

  70. 13:46

    And every morning, we walk into the office to a small incremental PR that's low risk. And when we first did this, it was actually really frustrating, and we turned the loop off, and it, uh ...

  71. 13:57

    'Cause we had to constantly update the skill. We had to constantly check out the branch, change the skill, change the code, commit and push, and our loop was actually really high friction, right?

  72. 14:06

    But there's a better way to do this, uh, where we can put a human on the loop in a really low friction way to resteer it when it goes wrong.

  73. 14:13

    And the way to do this is to just create a feedback file that's tracked in version control, just as a markdown file, right? We can deterministically load it into our actuator agent's context every time that it runs after we run the controller.

  74. 14:24

    Then we can add a label to the PR, right? Each workflow needs to be able to identify PRs that it created since there might be a bunch of different loops running, and we only want workflows to respond to feedback from, uh, comments on their PRs.

  75. 14:36

    And we're going to add a comment trigger to each loop workflow, so that when a user leaves a /iterate comment on the PR, uh, the loop workflow is gonna pick that up.

  76. 14:44

    It's going to deterministically load all of the PR context, the diff, the comments, the review comments, the description into the agent's context along with the skill, and it's going to instruct the agent to fix the code, but also to update that feedback file, right?

  77. 14:58

    It looks kind of like this. And the benefit of doing this way is that now that feedback file with instructions is tracked in your version control. You can see how you've changed it over time.

  78. 15:07

    You can revert it if you need to.

  79. 15:10

    So the next thing we're gonna do is add flow control because the other problem that we had when we did this was that if we were at a customer site for a week, or if we were traveling, or spent six days working on slides instead of writing code, uh, the PRs from all of our loops would just

  80. 15:25

    stack up. They'd duplicate work, they'd conflict, and we wouldn't get around to doing it. And, like, the loop's work is important, but it's not that important. And so now we just had all this, like, junk we had to deal with that wasn't important.

  81. 15:37

    So this is actually a really easy problem to fix, uh, because each loop and its workflow has a label that gets attached to PRs. When the workflow first runs, uh, before we check out the code, and install the dependencies, and run our sense actu- or sense, control, actuate steps, we can just check and see if the last

  82. 15:54

    PR that we created or any PR with the loop's label on it is open. And if so, we just shut down, right? Because this means that the last time that a human, uh, reviewed the code from this loop was before the loop ran, right?

  83. 16:08

    No human reviewed the last output, so there's no reason to stack up even more work for humans to review. This way we have exactly one PR at most open per loop at a time.

  84. 16:17

    No stacking, no duplication, hopefully no conflicts. And of course, once you're feeling confident in the loop, we're gonna wanna speed it up, right? I have 150 RPC procedures to migrate.

  85. 16:27

    If I do one at a time, it's gonna take six months, which is way longer than I wanna wait. Fortunately, there's a lot of ways to pick up the, the velocity of our loop.

  86. 16:34

    Uh, we could have our controller pick three procedures to migrate instead of one at a time or five. Uh, we could have our controller pick three or five and then do each of those in a separate implementation phase, which will be both cheaper and more reliable since each migration gets its own context window.

  87. 16:50

    Or we could just run the workflow four times and give one PR to each of four people on the team. So let's put it all together. We built a control loop that improves our code incrementally, and we're actually reading the code.

  88. 17:03

    It has adaptive flow control, so we're not creating a bunch of loo- or a bunch of work that nobody wants to review, and we can resteer it on the fly in a super low friction way.

  89. 17:12

    If you want to try this yourself, uh, we built a skill. Please try it out. My Twitter handle is down there on the bottom. Please share it. I would love to see what you build.

  90. 17:20

    And if you get excited by this, uh, at HumanLayer, we're hiring here in San Francisco. And if you're working on mission critical systems and want to figure out how to get more out of AI, we'd love to chat.

  91. 17:31

    Thank you so much. [audience applauding] [upbeat music]