Prompt engineering grew up

From clever phrasing to context, skills, and harnesses.

The evolution map

The migration is not prompt engineering to no prompts. It is prompt engineering to agent engineering. Each step keeps the previous step and adds a stronger operating contract around it.

The rough history matters. Early chat models had tiny working memory, so "better prompt" mostly meant squeezing intent into a small box. Context engineering arrived when that box became the bottleneck. Tool calls, RAG, file search, MCP, and repo inspection let the agent fetch the right state instead of carrying the whole world in one conversation.

Evolution from prompt engineering to harness engineering

Prompt engineering is the wording layer. It owns the role, the task, examples, constraints, and output format. This layer is still useful. It is just too small to carry production work alone.

Context engineering is the world layer. It gives the agent the right files, schemas, screenshots, memory, docs, live data, and tools. This is where MCP fits. The agent stops guessing because it can inspect the system it is changing.

Skills engineering is the procedure layer. A repeated prompt becomes a versioned workflow: SKILL.md, scripts, examples, fixtures, and domain rules. Instead of pasting the same instruction into chat, we give the agent a maintained operating procedure.

Harness engineering is the reliability layer. It wraps the agent with evals, CI, guardrails, traces, approvals, held-out cases, and rollback. The harness decides whether the agent's work survives.

Prompt engineering is the first layer, not the whole stack.

What each layer includes

The clean way to think about this is a stack. Lower layers ask for work. Upper layers decide whether the work should be trusted.

What each agent engineering layer includes

The prompt says what we want. Context shows the agent what is true right now. Skills explain the repeatable procedure. The harness measures the result and blocks bad output.

This is the difference between a clever chat and a usable engineering system. A clever chat can answer. A harnessed agent can be checked, replayed, compared, and rolled back.

How to apply it

No special library is needed to understand the idea. The setup is a repo, a model, a tool runner, and one rule: every repeated instruction becomes a file.

If a team keeps pasting the same checklist into chat, that checklist is no longer a prompt. It is a workflow artifact. Put it under version control. Give it a name. Run it against examples. Reject changes that make the result worse.

That is the move.

Prompt engineering was the first layer

Prompt engineering sounds precise. Most of it was just asking better.

There is nothing wrong with that. Better asking saves time. The issue is repeatability. A good one-off prompt works because the hidden context is fresh in our head. The model got enough clues, the task was small, and the cost of being wrong was low.

Then the task gets larger.

We ask the agent to refactor a dbt project, review a migration, write a post, change a front-end layout, or ship a feature. Now the important things are not inside the prompt. They live around it:

  • project conventions
  • previous decisions
  • forbidden side effects
  • live files
  • tests
  • deployment rules
  • examples of our taste
  • what "done" means

When those things stay in chat, they rot. When they become files, they can be reviewed.

A prompt is a request. A skill is an operating procedure.

The serious teams are moving from clever wording to reusable context. A skill is just a folder with instructions, resources, and sometimes scripts. That sounds small, but it changes the shape of work. The agent loads the procedure when needed instead of dragging every instruction into every chat. The team stops training people to remember magic phrases and starts maintaining operating docs.

This is context engineering. Ugly name. Useful idea.

Context is the new interface

The old interface was a text box. The new interface is a repo.

For coding agents, the prompt is only one input. The agent also sees project memory, style guides, commands, tests, browser state, screenshots, files, and tool outputs. MCP pushes this further by connecting agents to external systems: databases, docs, issue trackers, search, notebooks, internal tools. The agent is no longer answering from a blank room. It is operating in an enviroment.

That is why context engineering felt like such a jump. The agent could read only the files it needed, call tools when a task needed action, and pull domain data on demand. Longer context windows helped too. Suddenly the same coding agent could attempt bigger features, not just one-shot answers.

Context window growth on a log scale, from a few thousand tokens to the million-token range

That creates leverage and danger at the same time.

Leverage: the agent can stop guessing. It can read the current schema before writing SQL. It can inspect the page before fixing CSS. It can run the failing test before proposing a patch.

Danger: a richer context surface gives the agent more ways to be wrong with confidence. Bad docs become bad decisions. Old examples become policy. A tool result can be misread. A stale metric can steer the whole loop.

The awkward failure mode is summarisation. Long tasks often depend on the agent compressing its own history so it can keep going. That sounds neat until the summary deletes the hard part. A half-built feature becomes "done". A button that was never tested becomes "verified". A messy requirement becomes a cheerful sentence. The agent continues, but the map is now wrong.

Summarising context degrades a long run; a fresh context per task does not

So the question changes from "what prompt gets the answer?" to "what system keeps the answer honest?"

Harness is the execution wrapper

Harness engineering starts when context management is no longer enough.

The useful trick is not just giving the agent more memory. It is putting the agent inside a repeatable run loop with clear start and stop rules. Create requirements. Split them into tasks. Pick one task. Give fresh context. Implement. Test. Document. Save state. Repeat.

The harness loop: a requirement file split into a JSON task list, then one task per pass with a fresh context each time until a pull request is opened

That is a different shape of work. The context does not have to remember everything forever. The harness can reopen the repo, reload the requirement file, select the next task, and check the result against evidence. Subagents and parallel agents are just another version of the same idea: each worker gets its own bounded context and a narrow job.

This is also why cloud agents and scheduled agents matter. Once the loop can run away from the laptop, take a request from chat, create a pull request, or check daily for changes, the harness becomes the operating boundary. It decides what work starts, what context is loaded, what counts as finished, and what needs a human review.

The loop is useful, then dangerous

A loop is simple:

  1. Set target.
  2. Measure gap.
  3. Act.
  4. Repeat.

That pattern works everywhere. Tests are loops. Dashboards are loops. OKRs are loops. CI is a loop. An agent that edits code, runs tests, reads failures, and edits again is also a loop.

At first it feels like magic. The agent gets a failing test, patches the code, reruns, fixes the next failure. Cheap progress.

Then the metric starts lying.

Imagine a support bot optimised for ticket resolution rate. The number climbs. Leadership relaxes. Renewal rate drops. The bot learned to close tickets, not solve problems. The loop did exactly what we built it to do.

That is the trap. A loop optimises the target it can see, not the outcome we meant.

Goodhart's law is not an academic footnote here. It is the default failure mode of metric-driven agents. Once a measure becomes the thing to maximise, the system starts changing behaviour around the measure. In AI work, that means benchmark gaming, shallow test passing, useless summaries, and code that satisfies the visible check while breaking the invisible intent.

A green dashboard can still be a broken system.

Graphs beat single loops

The fix is not "more loop". The fix is a graph of loops with checks between them.

A mature agent workflow has more than one watcher:

  • an implementation loop writes the change
  • a test loop checks the known cases
  • a held-out eval checks cases the optimiser has not seen
  • a drift loop watches production inputs
  • a rollback loop restores the last good version
  • a human loop decides what "better" means when metrics disagree

Graph of loops with validation, rollback, and human veto points

The reliability lives in the edges. Who can veto whom? Which metric is allowed to block a merge? Which file can the agent edit? Which dataset is held out? Which failures count as regressions? Which judgement stays human?

This is where the "prompt engineering grew up" line becomes practical. The useful work is not finding a better paragraph to paste into chat. The useful work is designing the graph around the agent.

Skills engineering is workflow design

The next obvious step is to stop treating skills as static markdown.

If a skill controls repeated work, it needs a lifecycle:

skills/
  dbt-review/
    SKILL.md
    examples/
    evals/
    fixtures/
    changelog.md

Run the skill on known examples. Score the output. Save failures. Change the skill only when it improves held-out cases, not just the latest annoying task. Reject ties. Keep the artifact short.

This sounds a bit too formal until the second agent starts using the same skill. Then it becomes basic hygiene.

The interesting research direction is already clear: train the skill text itself. Keep the model frozen. Let an optimiser propose bounded edits to the skill document. Accept only strict validation improvements. Ship the best skill, not the longest one.

That idea matters because it moves improvement out of vibes. We stop saying "the agent feels better this week" and start asking whether the skill improved on cases it was not allowed to memorise.

A self-improving agent without a held-out gate is just a slop amplifier.

A data team example

Take a boring data task. A model review agent checks dbt pull requests.

Prompt-only version:

Review this dbt model and tell us if anything looks wrong.

It will find some issues. It will miss others. It will depend on whatever the agent notices that day.

Skill version:

Review dbt changes using our warehouse rules.
Check grain, nullability, incremental predicates, exposures,
metric ownership, downstream breakage, and test coverage.
Run commands where possible. Do not approve on style only.

That is already better. But it is still not enough.

Loop graph version:

  • skill reads the diff and project rules
  • SQL parser checks changed models
  • dbt build runs the touched lineage
  • reconciliation query compares old and new row counts
  • eval fixture checks the review against known bad PRs
  • deployment gate blocks if critical checks fail
  • human owner decides when tradeoffs are acceptable

Now the agent is useful. Not autonomous magic. Useful.

Conclusion

We are not moving from prompts to no prompts. We are moving from prompts to systems.

The practical path is simple. Keep prompts clear, but stop treating them as the whole job. Add context, convert repeated prompts into skills, connect agents to real tools through controlled interfaces, and wrap the result in a harness. Keep held-out cases. Reject changes that do not strictly improve outcomes. Add rollback. Keep a human decision point for the definition of better.

That is the job now. Less magic sentence. More operating discipline.

Recommended read

  1. SkillOpt paper: strong evidence for treating skill text as trainable external state, with bounded edits and held-out validation gates.
  2. SkillOpt repository: practical implementation of validation-gated skill optimisation, including the best_skill.md artifact idea.
  3. Claude Skills overview: clear definition of skills as folders of instructions, scripts, and resources loaded dynamically for repeatable work.
  4. Claude Code skills docs: useful implementation detail for SKILL.md, project skills, and when skills should replace repeated pasted instructions.
  5. Model Context Protocol intro: background on connecting AI applications to external systems, tools, data sources, and workflows.
  6. OpenAI Agents SDK guardrails: concrete patterns for input, output, and tool guardrails around agent workflows.
  7. When a Measure Becomes a Target, It Ceases to be a Good Measure: compact review of Goodhart's law and why target metrics can corrupt the behaviour they were meant to measure.
blog

Mike

Mike is a Machine Learning Engineer / Python / Java Script Full stack dev / Middle shelf tequila connoisseur and accomplished napper. Stay tuned, read me on Medium https://medium.com/@mshakhomirov/membership and receive my unique content.

Comments

Leave a Comment