How Software Development Changes in the AI Era

From prompt engineering to harness engineering, and what I make of it

L
Seungjae Lee · NHN AD
Platform Service Lab · June 2026 · ~7 min

Introduction

Hello. I'm Seungjae Lee, from the Platform Service Lab at NHN AD. In this piece I want to share how things have shifted from traditional development to harness engineering, and what I think about it.

Laying Bricks by Hand

My first coding began at university in 2018. As a student in the College of Software Convergence, C and Python were required courses, and until I ran into nested for-loop star patterns and pointers, I even fooled myself into thinking, "Am I maybe a coding genius?" Coding back then meant learning bit by bit through Google searches and seniors — laying program on top of program one brick at a time.

Search java nested for-loop star pattern Main.java 12345 typing… Learn by searching, type line by line — brick by brick
The days of finding the how-to by Googling and typing the code out by hand

But what about now? Developers no longer Google, nor do they write code line by line. AI sits at the start and end of every task, and the developer's role has shifted from "the person who writes code" to "the person who defines and solves problems." In fact, since joining NHN AD I have not written a single line of code by hand.

If you don't write the code yourself, what is a developer supposed to do?

Learning to Lay Bricks Better

My use of AI began around 2023, while I was studying at NHN Academy. It was a time when just opening YouTube or Instagram flooded you with resume prompts, writing prompts, coding prompts. Following that current, I too always started by writing instructions like this.

ChatGPT You are a senior Java developer with 10 years of experience. An expert with deep knowledge of SQL and clean code, write code and give me feedback… Sure. What code shall I look at?
Prompt Engineering — what "words" you said to the model was everything

This methodology is called Prompt Engineering. The sole concern was one thing: "what should I say to the model?" You assign a role and describe the situation and what you want in as much detail as possible. It is intuitive and effective, so Few-Shot and ReAct prompting are applied in NHN AD's services as well.

Instruction role · rules · examples OpenAPI Schema tool definitions Agent interpret → pick tool tool call response
The Instruction and the schema define the agent's behavior · a general structure with service-specific details omitted

I stayed with this approach for a long time. I wrote most of the code by hand, and only when I got stuck or hit a hard concept did I turn to AI to ask.

The End of the Brick-Laying Age

Then, in 2025, came an event that changed me: Claude Code. It was a shift from GUI to CLI, and from Prompt Engineering to Context Engineering.

Before, I would fill in the code and files myself and control the model through prompts. But after Claude Code, the AI accesses the filesystem and tools directly — reading files, fixing code, and running tests on its own. My concern moved from "what should I say" to "what information should I feed in."

claude code — CLI read docs/spec.md and map out the structure Read docs/spec.md fix the validate() function in src/UserService.java Edit src/UserService.java validate() Bash ./gradlew test ✓ passed
Just point to the path, the file, and the function — and the agent reads, fixes, and verifies on its own

I split the key points, constraints, and memory across files and connected tools via MCP, so the agent pulls in only what it needs, when it needs it. Around that time, two thoughts circled in my head at once: "Developers won't be needed — what do I do about getting a job?" and "I can really build fast now, can't I?" It was around then that I typed code by hand less and less, and interviews started asking about Claude Code, agents and skills, and the context window — the age of Context Engineering.

Interviewer Q Have you used Claude Code? Q How do you use sub-agents and skills? Q How do you manage the context window? Well, um…
Claude Code, agents and skills, the context window

Dead Bricks, Living Design

As of 2026, it looks like the age of harness engineering. The skeleton resembles Context Engineering, but it designs the system itself in a more refined way. You define the system prompt, use sub-agents, and manage the deterministic and the non-deterministic parts separately. You keep the agent from going astray with Rules, and you make it so that even if the agent ignores the guide, lint, type-check, and compile catch it mechanically.

Below is the structure I use in my work. Work is split across role-specific agents, and mistakes surfaced in verification are not just patched on the spot but fed back into skills, memory, and Rules so they don't happen again.

Plan PM agent task.md · spec Implement backend · frontend · infra agents Verify QA · reviewer lint · test · CI Integrate Git agent commit · PR Clean up GC agent archive legacy Feed mistakes back into the system update skills · memory · Rules · agent roles mistake found feed back
Role-specific agents split plan→implement→verify→integrate→clean-up, and mistakes are fed back into skills, memory, and Rules · a general structure with in-house implementation omitted
repo/
├─ .claude/
│   ├─ commands/   new-feature · new-bugfix · new-hotfix …
│   ├─ agents/     pm · backend · frontend · infra · qa · reviewer · git · cleanup
│   └─ skills/     capture repetitive tasks and know-how
├─ ai/          agents · lambdas · batches
├─ app/
├─ domains/     domain logic
├─ modules/     api-client · db-client · storage-client
├─ infra/       IaC · deploy
├─ docs/        spec · design records
├─ scripts/
└─ .legacy/     archive of old artifacts
An example layout — commands, agents, and skills live alongside work artifacts in one repository · a general structure with in-house details omitted

Now I no longer write code line by line, nor do I draft a long new prompt each time. Once I define what needs doing, the agent reads the files it needs on its own, fixes the code, runs the tests, and checks the result. My role has narrowed to defining what to build and verifying the result.

The Journey Ahead

Right now I'm running an experiment that drives a contest entry automatically. At a set time each day, a LaunchAgent on my laptop wakes a headless Claude, which organizes the day's tasks on its own, carries out the work, reviews its own results, leaves a daily report, and goes back to sleep. Even when I don't touch it, the same thing repeats the next day.

LaunchAgent set time each day headless Claude organize tasks do the work read · edit · run self-review recheck results report · sleep leave a daily log Next day, the same thing repeats untouched
A daily automated loop that wakes on its own to organize, perform, review, and leave a report
The contest automation repository — each day generating, running, self-verifying, and accumulating reports
Each day it generates and runs a task, then verifies itself and accumulates reports

As a result, even on days I didn't commit myself, the repository steadily piles up a record of work by date.

Daily accumulated commits by date — the human and the agent are both recorded as authors
Commits accumulated by date, with the human and the agent both left as authors

Going forward, I want to refine this structure and build a system that contributes to the Korean government standard framework (eGovFrame). With a well-designed system, I believe it could go as far as leaving contributions of its own on a real codebase built by others. I'll carry on that journey at the eGovFrame open community.

Thank you.

References