Top
Best
New

Posted by rzk 17 hours ago

Ask HN: How to deal with shipping AI-written code you don't understand?

I saw this LinkedIn post from a Meta engineer and it resonated with me:

https://www.linkedin.com/posts/ali-hamie_im-an-engineer-at-m...

> I'm an engineer at Meta and I never felt this uncomfortable doing my job. I'm writing code these days and it all feels like a black box. This new standard of shipping with AI is moving so fast that if we're going to spend our time checking each line of code, it's going to take forever. That means you can end up with systems you've built where you don't truly understand how all the code works. You understand the high level, but not every detail. And maybe this is becoming the new standard. It goes against every instinct of being a software engineer. I'm used to understanding what I'm building. Now I'm trying to figure out how much I need to understand before I'm comfortable moving forward. Are other engineers feeling this too?

How are you handling this?

315 points | 461 commentspage 11
ex-aws-dude 12 hours ago||
We just don't do that, I don't know why people talk like that is a given

Is it a company culture thing or a domain specific thing?

mattbrewsbytes 15 hours ago||
It feels like another layer of "conceptual compression". I'm not sure who/when that phrase came around but in context of Rails is where I heard it and its things like ActiveRecord or really any ORM. You aren't writing the SQL directly, something else is and for the most part it works. Then it doesn't work or your database grows too much and you need to optimize table structures with indexes, etc.

My point is if you don't understand the fundamentals of the underlying code (SQL in the example above), you're more likely to have issues in the future. Or maybe not if that app doesn't reach a usage pattern or complexity where the nuances under the hood matter.

It really depends on what you're shipping. Meta ships social media apps where in the grand scheme of things if something is broken software wise it largely doesn't matter. What's the worst case? lost ad revenue? Users can't do things? If that were software for MRI machines or aerospace where software issues/bugs can result in lives lost then it matters much more in understanding what is going on at all levels of the software and potentially hardware.

dansitu 7 hours ago||
If you are a senior engineer then there is no need for you to be shipping code that you don't understand. People can definitely generate code a lot faster than before, but you also have a magic genie that can help you critique and improve the code that you're reviewing, including when that code was written by agents.

An experienced senior engineer with access to a coding agent is the most powerful code-understanding system that has ever existed. There's no excuse for shipping or approving anything you don't fully grok.

batshit_beaver 5 hours ago|
Time. The limit is time. With or without agents there’s an X number of lines of code my brain can digest per work day. But rate of production of code is effectively unlimited or heavily influenced by people who let go of at least some percentage of understanding. This forces the rest of the team to also let go to keep up. Without guardrails around the rate of code production, _teams_ tend toward 0% code understanding. Individuals working on solo projects or in tiny teams that can enforce social contracts are not affected.
keithnz 7 hours ago||
the guidance / guardrails, agent roles, etc are the critical thing now, it's kind of like meta programming AI to get the outcomes you want. Any problems need addressing at this level. You don't need to understand all the code, but you should understand how the system is building up and adjust as needed. This would be an architectural review process you go through with AI. Features to code that should plug into existing architectural structures are generally no problem. It's just boilerplate code AI is generating. But architecture is only one aspect, you should have lots of guidance for all kinds of thing. There's security, performance, correctness, QA, Ux, Deployment, Process, Monitoring etc and having feedback systems for everything. You keep refining and reviewing your guidance and the impact it is having. As well as this you are molding the product for the things you want via feature development. What I'm not sure of is if you are some cog somewhere in a company like Meta whether whatever slice you become responsible for becomes a bit meh if you are mostly just prompting a feature and not much more. As a developer in a smaller company (we are global with a smallish tech team) I get to do a lot of things from interacting with our customers through to the entire backend and get to make critical decisions about nearly everything. Nearly everything in the company is starting to be driven via guidance and feedback loops (including on the guidance itself).
archagon 8 hours ago||
Don't.

By doing so, you debase your own profession.

meindnoch 5 hours ago||
I don't.
mooreds 9 hours ago||
You are accountable.

You're going to have to understand it one way or another, either at writing or at debugging. Even if you delegate all debugging to AI, you'll still need to determine what is "right".

If you don't understand the code at writing or debugging, you'll pay the architectural price (where it degrades). That price may be worth paying, but that depends on the system you are building.

cyberax 5 hours ago||
Don't.
iamwil 6 hours ago|
Peter Naur in 1985 wrote that programming is the act of building a working theory of the system in our minds, and this often takes form as tacit knowledge in the head of programmers. Even if you handed the complete codebase and perfect documentation to a completely new team, they would often need to go back to the old team and ask questions.

And before agents, we often built this working theory of the system by writing the code by hand. It helps us figure out the "grain" of the codebase so we have a better idea of how to extend it.

So what happens when agents are writing the code? The main avenue with which we built the working theory of the system in our mind is now taken away, and we're left feeling like our understanding of the system is blinded.

I ended up more or less changing my entire workflow. Four main principles:

1. Interrogation/interview-based design and specification

2. Make the decisions that matter and leave the rest to the agent.

3. Use agent to generate explainers, quizzes, and simulations.

4. Use verifiers and guardrails in the coding loop.

Interview-based design and spec

When I tell the agent what I want to build or extend, there's naturally ambiguity. But the agent knows what is ambiguous to it, so it can ask me. /grill-me is one way to do this. You'd think this would be commonplace now, but it's actually not. Some people are still wondering why they're getting bad results. It's because they're not resolving the ambiguity.

Making the decisions that matter

Not every decision matters in a product. Agents are fast at writing code and pretty good at some of the nitty gritty details, so I let it make those decisions. Also, if a particular subsystem is commonplace and undifferentiating, such as login, then I also let it make architectural decisions for that subsystem.

For decisions that are product differentiators, where that differentiation is supported by technology, I make decisions on the stack, the architecture, and the approach. This is the design phase. Because agents tend to make the mainstream decisions, they almost always take a midwit approach which doesn't leverage the technology in a way that makes a difference for the customer.

Some try to build this understanding from code reviews. I personally don't think it's the way to go, because it's not motivating. I find that I'm more motivated to learn how the system works today, because I want to change how it works tomorrow--and it sticks in my head better too (no different than pre-agents).

Generating explainers, quizzes, and simulations

As I'm doing design for an improvement and I don't know how a part of the system works, I can ask questions of the agent in chat. If I still don't get it, I can ask for diagrams (either ASCII or mermaid). But if it's an entire subsystem, I have a skill in which I can ask for visual and interactive explainers. It'll generate a markdown page (or html) that has these interactive components that help demonstrate a concept.

To help make the concept stick, there are quizzes after each section and at the end.

With the computational simulations, I generate a throwaway tool in which I can explore the state space. This doesn't happen as often, as I try to keep state spaces small, and for those explainers tend to work well.

With the design simulations, a same-model agent and a cross-model agent and I will talk about an explainer, and we'll name things that we understand or notice about the design and the intended direction we want to extend it. Then, we'll use subagents to generate options and then discuss the pros and cons. I find this is a good way for me to understand the dead-ends of a design.

Using Verifiers and Guardrails

I define guardrails as mechanistic checks that doesn't change with the feature. such as linters, typecheckers, and pre-commit hooks are all guardrails. Verifiers are mechanistic checks that will be different with each feature, such as unit/integration tests.

For more complicated states or concurrent parts, I'll ask the agent to use formal methods to write a proof. Then use the proof to generate a trace (a series of steps that demonstrate a happy or unhappy path). Then I run that trace in unit tests (kinda like property-based testing--so I guess this can be called trace-based testing), and the code has to adhere to the trace.

I also wrote a design verifier, where the requirements in the spec can be converted into a series of mechanically checkable rules. Then during testing, the verifier fires up the headless browser and uses the DOM measurements of the page to see if it matches up to the rules. This was completely impractical before agents.

All of this so a) I can be sure that the agent is doing what it's supposed to with the decisions that it's making b) I can be out of the coding loop, so that I'm not up at 2am begging, "you fixed this, but you broke that. pls fix." The agent can check for itself.

---

If any of this sounds helpful, lemme know. I've been wondering if other engineers care about understanding the code that's being written, or if people just don't care anymore. I've spoken to a few, and it seems to be split. And it may just be a matter of degree and detail. Some like it at a higher level. Some like it nitty gritty.

i2km 8 minutes ago|
I agree in that code is a byproduct of the tacit understanding which arises circularly when you write the code.

But if you're trying to gain the same level of tacit understanding by writing quizzes and simulations, are you actually gaining anything from using a LLM? Isn't it just better, faster and quicker to write the code yourself? Not to mention more enjoyable?

More comments...