From Code Writing To Work Design

I think back to when I first joined the company in early 2024. If I remember correctly, it was right before GPT-4o came out. Even then, LLMs were quite helpful for writing code. But the nature of that help was very different from what it is now.

For example, suppose I had to build an API in Spring Boot. I would first complete one example API myself, flowing from controller to facade, service, and repository. Then I would copy the entire code and ask the model to create another API with the same convention and the same logic. In other words, the LLM was closer to a replication tool than a designer. If a human had already laid the path, it could follow that path to some extent.

Of course, I sometimes asked questions when I got stuck. But hallucinations were severe, and once the complexity of the task increased even slightly, syntax errors and logical flaws appeared throughout the code. At the time, the natural procedure in development was still to search through official documentation, inspect library code, read error logs, and debug directly. The LLM was an auxiliary tool, not something one could entrust work to.

After that, model performance continued to rise. At some point, the amount of time I spent relying on answers slowly began to exceed the time I spent looking things up myself. Then coding agents appeared. The first one I properly used was from the Gemini line, and to be honest, its performance was terrible. The fact that it could directly modify local files was interesting, but it was much slower than when I worked by hand, and the results were not stable. From that point on, I tried my own kind of harness engineering. I split tasks into smaller units, specified rules, forced tests, and limited the scope of modification. Even so, it could not match the quality of code written directly by a human.

The same problems repeated even in repositories where the conventions had already been established. It modified files without understanding the structure, forced together pieces of code that merely looked similar, and almost always caused problems during compilation. In the end, a developer still had to read and fix the code again. The agent may have written the code, but the responsibility still belonged entirely to the developer.

Then, around the time I left the company in early 2026, I started using newer Codex-line models, and the difference became completely tangible. The code became more precise. It performed compilation checks after the work. It began to handle not only simple implementation, but also revision and verification as a single flow. Now I could leave one task to an agent and work on something else myself. With some exaggeration, I could produce two or three times my previous productivity.

After returning to school and working on several projects, this change accelerated even further. New agents and models were released roughly once every month or two, and their performance and speed visibly improved. The parts that developers had to fix after a task was completed decreased, and the code became increasingly refined. It reached the point where, on a monthly basis, or even weekly, I felt that I would fall behind if I did not keep up. Now writing code without a coding agent feels strange.

The way I work has also changed completely. I specify branch conventions and Git flow, then run several tasks in parallel. Even PR reviews are no longer something I read entirely by hand. I built a custom dashboard to help review other people’s code, or more precisely, code written by other people’s agents. With the rise of MCP, I can connect Notion, Figma, browsers, and various other connectors, compressing into a single flow tasks that previously required moving back and forth between windows.

Where Developer Judgment Still Matters

Server incident response is the same. In the past, when a problem occurred, I directly wrote Prometheus queries, checked Grafana dashboards, dug through CloudWatch metrics, and followed JVM flame graphs or API traces in Datadog APM to find the cause. When a database issue occurred, I would spend the whole day attached to the query console, checking processes, finding expensive queries, reading execution plans, and fixing indexes and query structures. Now, a significant portion of this process can be delegated to an agent. Through an MCP server, I can have it read metrics, open a tunnel into an infrastructure server, perform Java profile capture, and assist with analyzing the result. A large portion of the repetitive exploration and text analysis humans had to perform can now be completed in an overwhelmingly shorter amount of time.

This progress was astonishing. But at the same time, it felt hollow.

It seemed as though the tasks I had been good at could now be done by anyone. The time I spent reading code, digging into libraries, spending entire days debugging, and accumulating knowledge through official documentation felt almost meaningless. In the past, that was competitiveness. The ability to understand problems faster than others, fix them more accurately, and implement them in a more stable structure. But AI began to imitate that ability rapidly. It felt as though the scarcity of the skills I had built was disappearing.

But while collaborating with several developers, my thinking slowly changed. AI was not reducing the gap between developers. It was revealing that gap even more clearly.

Many people talk about the importance of prompts. I feel it painfully as well. But the prompt I am talking about here is not the ability to write pretty sentences. It is the ability to understand the essence of a task, know the points that must be decided, understand the context of the system in which the code will live, and set conditions so that the agent cannot make careless assumptions. In the end, a good prompt comes from good development knowledge.

Suppose we are making a simple login page. If you ask for “a login page view and backend logic,” including both frontend and backend, today’s AI can produce a working login feature in under five minutes. The problem is precisely that it works. It works so convincingly that, unless you know what is missing, you simply move on.

But login is not merely a feature where a user enters an email and password, sends a POST request to the server, and is redirected to the main page on success. One must decide how sessions will be managed, how the lifecycle of access tokens and refresh tokens will be handled if JWT is used, how HttpOnly, Secure, and SameSite policies will be configured if cookies are used, how passwords will be hashed and stored, where server-side authentication and authorization checks will be performed, how to respond to credential stuffing and brute force attacks, how login failure counts and rate limits will be handled, how access privileges will be separated by user role, how logout and token invalidation will be guaranteed, and how much error information will be exposed between security and usability.

Working With Agents Without Losing Thought

These are not things that easily come to mind if one has never built a login page directly. AI can produce an answer. But the developer must know what to ask. A person who does not know what must be decided will accept the assumptions filled in by AI as they are. At that moment, the code has not been “completed.” It has entered the repository carrying invisible debt.

That is why I find it strange to treat “AI contribution” as an independent value. If we assume the contribution to code quality is 100, some people say that in the past, developer ability accounted for 90 and LLM assistance added 10, while now AI accounts for 90 and the developer handles only 10. But I do not think so. The quality of the 90 that AI produces still stands on top of the developer’s ability. Without prior knowledge, without understanding the system, and without the ability to use AI well, one cannot draw out that 90.

In fact, the gap may grow even wider. In the past, the difference between an excellent developer and an average developer appeared in coding speed and debugging ability. Now that difference appears in the way they handle agents. One person tells AI, “Make a login.” Another person organizes authentication policy, security requirements, error handling, test scope, and integration with the existing architecture before assigning the task. Both use AI. But the results are completely different.

The hiring market is similar. These days, people often say that the productivity of existing developers has increased, so new developers are no longer needed, and that is why the market has become difficult. Of course, there is some truth to that. If a skilled developer uses agents well, one person can handle far more work than before. The need for people who only perform simple implementation is bound to decrease.

But from what I hear from people in the field, the issue does not seem to be simply that companies are hiring fewer juniors. It also feels strongly as though there are fewer people worth hiring. Development looks too easy now. Output appears even without digging deeply into code. One can complete a project without having implemented things directly. But if engineering thinking is not properly trained in that process, one does not understand why the code was written that way. When an error occurs, one cannot narrow down the cause. When structures collide, one does not know where to begin unraveling them. The problem is not that one cannot write code without AI. The problem is being unable to properly read even the code AI has written.

Of course, studying code itself has also become much harder. One can say that the ideal approach is to write code without AI and understand logic from the bottom up, as people did before. I also believe that is important. But when there is a tool right in front of me that can perform a task I cannot do at ten times the speed, how could I ignore it? Saying we should not use AI is not realistic. What matters now is not whether we use AI, but how we use AI without losing thought.

There is one method I at least try to practice. Before assigning a task, I write the requirements in as much detail as possible. Then, at the end, I always add this question.

“What do I need to decide in advance in order to perform this task? Do not assume any workflow or logic. Have me review every process in detail.”

Responsibility Moves Upstream

Just adding this one question changes the result significantly. No matter how detailed I think the prompt is, something I had forgotten always comes out. Sometimes, an entire procedure I had never considered returns as a question. I must then study those questions again and make decisions. Only then do I avoid making the agent redo the same work twice, three times, or ten times.

Understanding the written code is also important. Code written by an agent is not code one can skip reading. Rather, it is code one must read even more carefully. The first task always starts off looking plausible. The first feature in a new repository is clean. But if one continues assigning follow-up tasks without understanding that structure, spaghetti code eventually accumulates. Logic collides, responsibilities blur, exception handling is duplicated, and the same concept spreads under multiple names. At first, it seems fast. Later, it collapses beyond control.

In the age of AI, developers may write less code. But that does not mean they can think less. If anything, they must think more. The time spent typing directly decreases, but one must judge what to build, what structure is appropriate, which decisions must not be deferred, and which assumptions must be prevented. Implementation labor decreases, but design, review, and responsibility become more distinct.

That is why the difference between a developer and a coder now seems even clearer.

A coder receives code written by AI. A developer decides what kind of code AI should write. A coder thinks it is over when it works. A developer looks at why it works, where it can break, and what kind of structure can survive when the next feature is added. A coder writes prompts as commands. A developer writes prompts like design documents.

The age in which AI writes code has arrived. This does not mean developers are no longer needed. It means, rather, that what a developer knows has become more important. In the past, we learned what we did not know by struggling through it ourselves. Now AI covers up what we do not know too quickly. That is why we must dig into it more consciously. We should not merely look at the answer AI filled in. We must check what AI assumed.

In the end, competitiveness has not disappeared. Its position has merely changed. It has moved from how much code one can type to how accurately one can define what kind of code should be written. And this change is colder than it first appears. AI is open to everyone, but not everyone obtains the same result.