I was thinking about how to properly communicate the value of

  1. Software Engineering as a discipline, in the era of rapid LLM code generation
  2. Me as an individual, basically “why should you hire me specifically?”

In The Before Times, the answer was vaguely “I solve your business problem using code”.

This value was pretty clear to Business People, in that they would want a thing to do a thing and had two options.

  1. duct tape some SaaS functionality together using tools like fivetran, zapier, airtable, notion, sheets/excel, and Email (their favorite!)
  2. make a request that lands (usually) at the bottom of the Backlog behind all of the product features that Product People faught to be built first.

The duct taping rarely resulted in exactly what they wanted to accomplish, since you can only customize this class of SaaS so much. They did have the option for something bespoke to be built, but its at the whim of the Backlog miners having enough resources to reach that part of the mine in time. Obviously this sucks, because they don’t just want it, they want it now!

LLMs come to the scene, then Agent harnesses, and eventually we get The Inflection where they become net-useful, which leads to The Rift where some folks think Models are all we need now and Software Engineering is a dead field.

Now, pretty much anyone with the approval to burn some can spit out Something That Works in anywhere from a few minutes to a few days. If that’s the case, why do they still need software engineers?

Wide Context

Maybe this changes, maybe this is durable, but currently LLMs are kind of like race horses with blinders on. As a horse, they move very fast towards their goal. This can be a boon for productivity, and for tasks that are Not Quite Scriptable (like refactoring beyond name changes and relocations) its a whole new unlock entirely. However, given the blinders,they unaware of the totatlity of their surroundings.

The Agent’s awareness is limited to these categories:

  1. What’s provided to it by the Operator (prompting)
  2. What’s discoverable (tool usage) and what it knows it should discover (context engineering)

More often than not, things fit into neither of those categories until some failure condition is reached and the Operator makes updates. In the Agent-Operator copilot use-case, the Operator is an eagle keeping an eye on the action below, making sure that the horse is not missing a watering hole it desperately needs to keep going.

Holding a large amount of context at the same time is helpful to

  • Avoid pitfalls, mistakes already made before
  • Match problems to solutions (often laterally across domains)
  • Integrate disparate systems that are not directly connected

Aesthetic Coherence

You can tell an Agent “only use functions with no side effects” or “encapsulate all dependencies with object inheritence” and it’ll do that. Why will it do that? Well, because you told it to. Models are the modern Golem and will do what you say without much pushback (unless you tell it to pushback of course, which may or may not be pushback technically).

If you do not tell it to follow any design pattern in particular, it will often just spit out an incoherent hodge-podge. This is largely because Models are All of the Things, and the threshold between concepts is not always categorical, but rather a gradient. Which things are appropriate for which scenarios is basically just a matter of Taste.

Taste is hard to nail down, but in the context of Software Engineering I would say it’s mostly about values and how you align them to the problem at hand. Sean Goedecke covers something similar in his post on the topic [1]. My take is that its a matter of Taste only when its a choice of subjectivity.

Here’s an example of two options that are both justifiably chosen depending on the scenario

  • Tall Flat Procedures:
    • What: these mix control flow with lots of imperative code, minimizing single-caller functions, instead having everything collected into one place.
    • Why: your brain does not have to context switch in and out of functions to piece together the totatlity of whats happening. No implementation details are hidden, avoiding incorrect assumptions of how data is being transformed.
    • However: you have to “structure” with comment delineated sections, and glue code that doesnt add much value waters down your business logic.
  • Declarative Folding:
    • What: this look like a dense outer function that is mostly control flow, with imperative code nested into single purpose named functions.
    • Why: it “folds” or compresses a group of transformations into a verb-noun like fetchWebpage. Inside that function is all sorts of things, retrying, timeouts, TLS handling, but often the caller does not care about this as long as they get the data transformation of URL -> HTML they expect.
    • However: It’s not always obvious what can go wrong unless you dive in anyway to read the transformations. In order to get the full picture, you have to assemble a graph in your mind of the operations, context switching in and out of each level. Variable mutations may be more verbose since they have to be defined in the input and output for each function.

So Taste is less “which one is better?” but “when is which one better?”, and thats a question answered by a person’s entire career of experience. Humans tend to apply these based partially on principles they form, or at least discrete heuristics. When you ask a Model to code for you, it will choose purely based on some probablistic relevance to whatever code within the context window. Unless you consistently steer it towards the direction you want, you can expect the Model to drift from the larger patterns laid out towards its geometric mean.

Some of the most successful large scale software projects like the Linux kernel and the Python language are/were guided by a central visionary. It’s not so much that the decisions made by those figures were the best objectively (accuracy), but the consistency of the decisions (precision) allow for the project to grow in scale while staying coherent.

When I was more junior I heard some senior engineers say something akin to “It’s more important for new work to be consistant with old work than to be good on its own”. I think there is some truth to that. Having a narrow surface area of harmonious design concepts and a understandable architecture is what Good actually looks like. In the era where we increasingly look at code by squinting, I think having focus on the bigger picture is probably the best place for human value to be realized.