Antern / Blog
Start Walls Apply

An AI-Native Engineering Study

Structural Reasoning Is the Missing Piece of Agentic AI

The problem is not that LLMs do not know algorithms. The problem is that we keep asking them to hold algorithmic state inside language.

How to read this. We will not start with a grand agent diagram. We will start with the wall: an AI agent trying to manage an ML experiment, a Python repo, a set of constraints, and a moving state table inside its own context window.

Data structures are not trivia. They are the shape of real agent work: queues, graphs, trees, hashmaps, state machines, dependency DAGs, and metric ledgers. If those structures live only inside the model, the system becomes fluent before it becomes reliable.

SectionPlain Question
OpeningWhy does a smart agent still lose the plot?
Five wallsWhat breaks when state, graphs, constraints, execution, and review live only inside the model?
ArchitectureWhat should live outside the model so the agent can be trusted?

Opening / The Hidden Shape

The task is not just language

A serious AI agent is not answering one prompt. It is maintaining state across changing constraints. It is updating a world model. It is deciding what to execute, what to verify, and what to remember. That is structural work.

The next generation of agents will not be defined only by larger context windows. They will be defined by what they stop asking the model to remember.

The design principle of this article
0.0

A Real Research Problem

This is not a theory I arrived at by staring at diagrams. It came from using agents on real research work.

In my own research tasks, the projects are not tiny demos. Some of the codebases are three lakh to four lakh lines of code. Many tasks have already been done once. Some are half-done. Some have old checkpoints. Some experiments were run with one setting, then rerun with another setting, then compared weeks later.

In that kind of work, a normal chat starts to feel weak very quickly.

The agent may remember the current file, but forget the old decision. It may understand the current benchmark, but miss that an older checkpoint used a different dataset slice. It may write a new script, but not notice that a similar script already exists in another folder. It may say a model improved, but compare numbers that were not produced under the same rules.

what the agent has to keep straight
old task -> already attempted
checkpoint -> saved from an earlier run
metric -> produced with a specific judge
dataset split -> must match the baseline
script -> may already exist somewhere else
decision -> made two weeks ago, still important

Once the project gets that large, the problem is not whether the model can write a good paragraph. The problem is whether the agent has a reliable map of the work.

Adding structural reasoning changed the work. A run ledger made experiments easier to trust. A task graph made it clearer what was already done. A dependency graph reduced duplicate work. A proof log made it harder for the agent to say something was complete when it had not actually been checked.

The larger the project gets, the less you can afford to keep the project only in the model's head.

0.1

The Wall Before The Architecture

Answer first · from your own work

Think of the last time an AI agent helped with an ML repo. Did it lose track of which config, dataset, checkpoint, metric, or script was the source of truth?

Imagine you ask an AI agent to improve an evaluation pipeline in a messy ML repo.

You say: “Add a new benchmark, run it across three models, compare the results against the previous run, update the experiment table, and tell me if the new model is actually better.”

This sounds like one task.

It is not one task.

It quietly contains a lot of structure:

the structure hiding inside one plain-language request
models
  -> baseline
  -> candidate
  -> previous checkpoint

datasets
  -> validation split
  -> held-out split
  -> adversarial slice

runs
  -> metrics
  -> seeds
  -> configs
  -> logs

constraints
  -> same dataset
  -> same prompt
  -> same seed policy
  -> same evaluation script
The user wrote one sentence. The agent received a small world model.

A normal LLM tries to solve this by reading text, remembering what matters, and continuing the conversation. That works for a small demo.

Think of it like asking a student to do math without paper. For two numbers, fine. For a whole page of numbers, they need a notebook. The agent needs a notebook too.

It breaks when the agent has to remember which model used which config, which metric came from which run, whether the baseline used the same dataset split, whether the failed run should be retried, and whether the new score is actually comparable.

The agent is not failing because it lacks words.

It is failing because the task is not just language. It is a graph of dependencies, states, constraints, and updates.

WHAT WE ASK THE LLM TO DO TODAY Experiment Repo Long Context LLM “Looks improved” WHAT THE AGENT ACTUALLY NEEDS Experiment Repo Structured Staterun graph + metric table + config ledger Validator answer with lineage
The first system hopes the model remembers. The second makes memory inspectable.

The difference is not cosmetic. In the first setup, the state lives as a story in the model's hidden context. In the second, the state lives as an object the system can query, update, and test.

A production agent should not be trusted because it sounds coherent. It should be trusted because the important state is outside the model and every important step is checkable.

0.2

The Structural Reasoning Claim

The missing piece in most agent designs is not another prompt. It is an explicit structure the model can operate on.

When people hear “data structures,” they often think of interview problems: arrays, queues, trees, graphs, hashmaps, heaps.

That is the shallow reading.

The wrong question is:

The wrong question

Can an LLM answer a data structure quiz?

The useful question is:

The useful reading

Can an LLM maintain and manipulate structured state reliably when the answer depends on order, hierarchy, connectivity, or constraints?

That is exactly what AI agents need to do.

An ML agent managing experiments has to reason over queues of jobs. A Python coding agent has to reason over dependency graphs. A data agent has to reason over table schemas. A research agent has to reason over citation graphs. A training agent has to reason over checkpoints, datasets, configs, metrics, and failure logs.

In plain words

A paragraph is like a story. A structure is like a map. Agents need maps for the parts where being wrong is expensive.

These are not paragraphs.

They are structures.

The agent design test

If removing one structured store makes the system rely on the model's hidden memory, that part of the architecture is probably underbuilt. Serious agents need visible state: graphs for relationships, DAGs for tasks, ledgers for runs, and validators for hard constraints.

This is why many impressive demos collapse when they become products. The model can explain the plan, but the plan is not stored. It can describe the repo, but the dependency graph is not explicit. It can say the benchmark improved, but the metric lineage is not checked. It can write code, but the execution state is still imagined until a tool runs it.

The problem is not intelligence in the abstract. It is misplaced responsibility. We keep asking the model to carry state, maintain relationships, enforce constraints, simulate execution, and judge its own result.

So the design lesson is not:

not enough as an architecture
Use more chain-of-thought.
Ask the model to think harder.
Keep more of the repo in context.

The design lesson is:

Do not ask the LLM to be the data structure. Give the agent a data structure.

BAD ARCHITECTURE Task LLM holds everything plan state constraints memory + validation Answer BETTER ARCHITECTURE Task LLM extracts intent External structures graph + DAG + state machine metric table + constraint set Verified answer
The model becomes a reasoning component, not the whole state machine.

The model should not be responsible for silently maintaining all intermediate state in its hidden activations.

It should operate on explicit state that the system can inspect, update, and verify.

Part I / The First Walls

Two walls every AI engineering agent hits

We will start with two common failures in AI engineering work: experiment state drifts, and dependency graphs get flattened into local edits. Each wall gives us one design rule.

B1

The Agent Forgets The Experiment State

Answer first · from your own work

If you ask an agent to compare two model runs, what must stay identical for the comparison to be meaningful?

A model comparison is simple until the state branches.

You ask an agent to compare two runs:

two clean runs
Run A:
model       = llama-3.1-8b
dataset     = eval_v2
seed        = 42
temperature = 0.2
score       = 71.4

Run B:
model       = qwen-2.5-14b
dataset     = eval_v2
seed        = 42
temperature = 0.2
score       = 73.1

So far, easy.

Then you add: “Now rerun only the failed examples from Run A using a stricter judge, but keep the original judge score in the final report too.”

Now the state branches:

one request later, the table is no longer flat
Run A
  -> original score
  -> failed examples
  -> rerun score
  -> stricter judge score

Run B
  -> original score
  -> comparison target

Then you ask: “Actually, exclude examples where both models refused. Also compare cost per correct answer.”

Now the agent has to preserve the old metric, create a filtered metric, track a new denominator, and avoid mixing judge policies.

This is where language-only reasoning gets brittle. The model may write a fluent answer, but the hidden state can drift:

metric drift, written as questions
same dataset?          maybe
same judge?            maybe
same denominator?      maybe
same refusal policy?   maybe
same baseline lineage? maybe
In an experiment system, maybe is failure.

The fix is not a longer prompt.

The fix is a state ledger.

WITHOUT EXTERNAL STATE User asks update LLM edits mental table Metric drift confident answer WITH EXTERNAL STATE User asks update State Update Engine Experiment Ledger Metric Validator
The ledger is the memory. The validator is the guardrail.

For an AI engineering agent, that state might be a real record, not a paragraph:

experiment ledger record
{
  "run_id": "eval_2026_07_09_qwen14b",
  "model": "qwen-2.5-14b",
  "dataset": "eval_v2",
  "split": "heldout",
  "seed": 42,
  "judge": "strict_judge_v3",
  "temperature": 0.2,
  "metrics": {
    "accuracy": 0.731,
    "refusal_rate": 0.08,
    "cost_per_correct": 0.014
  },
  "parent_run": "eval_2026_07_08_baseline"
}

Now the LLM does not need to remember which score came from where. It can query the ledger.

The agent can describe state. The system must store state.

B2

The Agent Drops The Dependency Graph

Answer first · from your own work

When you change an embedding model in a Python repo, what else might silently become invalid?

The user asks for a model change. The repo hears a graph change.

Take a Python agent working inside an ML repo.

The user says: “Replace the embedding model with the new one and make sure retrieval quality improves.”

That sounds simple.

But in a real repo, the embedding model touches many things:

the obvious dependency chain
embedder.py
   -> vector_store.py
   -> retriever.py
   -> reranker.py
   -> eval_retrieval.py
   -> report.md

It may also affect the chunk size, embedding dimension, index format, cache keys, stored vectors, distance metric, and whether the new evaluation is still comparable to the baseline.

A weak agent edits embedder.py, runs one script, and says done.

A structure-aware agent first builds the dependency graph.

NAIVE AGENT Change embedding model Edit embedder.py Run one eval Done STRUCTURE-AWARE AGENT Change embedding model Repository graph Affected nodes Migration + eval plan Verified result
Changing a model is not a local text edit. It is a graph update.

If the new model changes embedding dimension from 768 to 1024, then the vector index may be invalid.

If the cache key does not include the model name, old embeddings may be silently reused.

If the evaluation compares a fresh candidate against a stale baseline, the conclusion is invalid.

So the agent needs an explicit graph:

the repo as a world model
EmbeddingModel
      -> produces
EmbeddingVector
      -> stored in
VectorIndex
      -> queried by
Retriever
      -> evaluated by
RetrievalEval
      -> summarized in
ExperimentReport

And each edge carries a rule:

EdgeRule
EmbeddingModel -> VectorIndexDimension must match.
EmbeddingModel -> CacheCache key must include model id.
Retriever -> RetrievalEvalSame dataset and top_k are required.
RetrievalEval -> ReportReport must include baseline lineage.

This is structural reasoning.

Not “thinking harder.”

Not “let's reason step by step.”

A graph the agent can inspect.

The LLM should read the map. It should not be asked to remember the map.

B3

The Agent Mixes Up Constraints

Answer first · from your own work

When an agent runs an experiment, which rules are soft wishes, and which rules must never be broken?

A constraint is a rule with teeth.

Suppose you ask an agent to fine-tune a small model:

one training request, many hidden rules
Fine-tune the classifier on the new dataset.
Keep it under 6GB VRAM.
Do not use private customer text.
Finish in under 40 minutes.
Keep latency under 120ms.
Do not reduce F1 on the safety slice.

A weak agent treats these like helpful suggestions. It may pick a larger batch size because training looks faster. It may use the full dataset because more data looks better. It may improve average F1 while hurting the safety slice.

But constraints are not decoration. They are the rails that keep the work valid.

In plain words

If the agent is cooking, constraints are not the garnish. They are the allergy list. You do not “mostly” avoid peanuts for someone with a peanut allergy.

The fix is to turn constraints into a checklist the system can read before and after every action.

CONSTRAINTS BECOME A CHECKABLE OBJECT User Requestplain language Constraint Extractorturn rules into fields Constraint SetVRAM <= 6GBlatency <= 120msno private text Agent Actiontrain / eval / edit Validatorpass or stop fail -> revise before continuing
The model can propose. The constraint set decides what is allowed.

Now the agent is not carrying the rules in its head. The rules are written down:

constraint set
{
  "max_vram_gb": 6,
  "max_latency_ms": 120,
  "forbidden_data": ["private_customer_text"],
  "must_not_regress": ["safety_slice_f1"],
  "deadline_minutes": 40
}

Before the agent trains, it checks the rules. After the agent trains, it checks the rules again. If a rule fails, the agent does not get to explain it away.

Natural language is how constraints enter. Structured validation is how constraints survive.

B4

The Agent Says Instead Of Runs

Answer first · from your own work

Which sentence do you trust more: “the tests should pass” or “pytest returned 42 passed, 0 failed”?

There is a huge gap between saying a thing worked and running the command that proves it.

An agent edits a Python evaluation script and writes:

the dangerous kind of confidence
The benchmark should now run correctly.
The JSON parser should handle missing fields.
The retrieval eval should be faster.
The tests should pass.

Every line sounds useful. None of it is proof.

In plain words

“I cleaned my room” is not the same as opening the door and seeing a clean room. For agents, the command output is the open door.

The fix is simple: important claims must become command results.

A CLAIM IS NOT A FACT UNTIL A TOOL CHECKS IT Agent Claim“tests should pass” Run Commandpytest / mypy / eval Observed Result42 passed, 0 failed Write the result into the state logfuture agents can see what was actually run
The command output is the fact. The sentence is just a claim.

For an AI engineering agent, the proof might look like this:

proof log
check: unit tests
command: pytest tests/test_eval_runner.py
result: 18 passed, 0 failed

check: type check
command: mypy src/eval_runner.py
result: success, no issues found

check: smoke benchmark
command: python scripts/run_eval.py --model tiny --limit 20
result: completed, wrote reports/eval_smoke.json

Notice the pattern. The agent does not say “should.” It runs the thing and records what happened.

If the agent cannot show the command result, the system should treat the claim as unproven.

B5

The Agent Trusts Itself

Answer first · from your own work

When you write code, why is it easier for someone else to spot your bug than for you to spot it yourself?

The same agent that made the plan is a weak judge of whether the plan was good.

This failure is subtle. The agent writes a patch, runs a test, reads its own explanation, and concludes the work is done. It is surrounded by its own story.

That is dangerous because the story may be wrong in a small way that matters.

self-review misses the important question
Agent: I changed the embedding model.
Agent: I ran the eval.
Agent: The new score is higher.
Agent: The change is good.

But a real reviewer asks different questions:

independent reviewer questions
Was the old vector index rebuilt?
Were old cache files ignored?
Was the same dataset used?
Did latency get worse?
Did safety-slice accuracy drop?
Can this be done with fewer changes?

The fix is to separate maker from checker.

WEAK SETUP One Agentmakes patch + judges patch it trusts the story it just wrote STRONG SETUP Maker Agent Independent Checker Approve / Reject / Ask the checker sees goal, patch, logs, and constraints
The checker is not there to be clever. It is there to be independent.

The checker does not need the whole chat. In fact, it should not get the whole chat. It should get the goal, the patch, the changed files, the proof logs, and the constraints at risk.

That keeps the checker focused on the object, not the story.

Maker is not checker. The agent that produced the answer should not be the only judge of the answer.

Part II / The Architecture

The structure-aware AI engineering agent

Now the walls have forced the design. We need external state, explicit graphs, hard constraints, real tool execution, and an independent checker. Put those together and the agent stops being one big prompt. It becomes a small system.

2.1

The Whole Machine

The LLM is still important. It is just not the whole machine.

The model is good at reading a messy request, proposing a plan, writing code, explaining tradeoffs, and noticing patterns. But it should not be the only place where the plan, state, constraints, and proof live.

STRUCTURE-AWARE AI ENGINEERING AGENT User Request Intent + Constraint Extractor Structured World Modelrepo graph + run ledger + task DAGconstraints + memory + tool results Plannermake task DAG Tool Executoredit / run / query State Updatewrite results back Simulatorwhat might break? Validatorhard checks Independent Checkerapprove / reject Final Response + Memory Update write back
The important swap: state moves out of the model and into the system.

Read the picture from top to bottom. The request comes in as language. The agent turns it into structured objects. The planner makes a task DAG. The executor runs tools. The state update engine writes down what changed. The simulator asks what might break. The validator checks hard rules. The independent checker judges the result.

The final answer is just the last step.

In a weak agent, the final answer is the whole product. In a strong agent, the final answer is a summary of work that already happened in visible state.

2.2

How To Build It

This does not require a magical model. It requires boring system parts around the model.

Here is the practical version:

Agent PartWhat It Can Be In Real Life
Repository graphtree-sitter, language server indexes, import graphs, call graphs.
Run ledgerSQLite, Postgres, JSONL files, MLflow, Weights & Biases-style records.
Task DAGA small JSON plan with task ids, dependencies, status, and proof commands.
Constraint setStructured fields for budget, data policy, latency, quality bars, and safety slices.
Tool executorSandboxed shell commands, Python scripts, CI jobs, eval harnesses.
ValidatorDeterministic checks: tests, typecheck, lint, schema validation, metric comparisons.
Independent checkerA separate LLM pass or fresh session that sees artifacts, not the maker's whole story.

The simplest version can live in plain files. You do not need to start with a graph database. A small folder can hold the state:

minimal agent state folder
.agent-state/
  world-model.json       # repo graph, key files, important edges
  runs.jsonl             # model runs, metrics, configs, lineage
  constraints.json       # rules that must not break
  task-dag.json          # tasks, dependencies, status
  proof-log.md           # commands run and outputs observed
  decisions.md           # human decisions and agent assumptions
ONE TASK THROUGH A PLAIN-FILE AGENT STATE Requestchange model world-modelwhat depends on it? task-dagwhat runs first? Patchedit files proof-logcommands + output constraintspass / fail Responsewith evidence
Plain files are enough to start. The point is not fancy storage. The point is visible state.

Later, the same design can grow into a database, a graph store, a scheduler, or a production orchestration system. But the shape stays the same.

Language comes in. Structure is created. Tools run. State is updated. Checks decide what counts.

2.3

The Rule To Carry

A better agent is not just a bigger model with a longer prompt.

A better agent is a system that knows which jobs belong to the model and which jobs belong outside it.

what belongs where
LLM should:
  -> understand messy requests
  -> propose plans
  -> write code
  -> explain tradeoffs
  -> ask useful questions

System should:
  -> store state
  -> maintain graphs
  -> enforce constraints
  -> execute tools
  -> validate results
  -> keep proof logs

That is the line most agent systems blur. They ask the model to remember, track, simulate, validate, and judge. Then they wonder why the output sounds right while the state is wrong.

The fix is not to remove the LLM. The fix is to stop giving it jobs that should belong to the architecture.

THE FINAL SWAP Old agent LLM holds state LLM tracks graph LLM checks constraints LLM says it worked LLM judges itself Structure-aware agent state store holds state graph holds relationships validator checks constraints tools produce facts checker reviews independently same model family, better architecture
Robustness comes from moving the right responsibilities out of the model.

The next generation of AI agents will be built from models plus maps: explicit state, explicit structure, tool execution, validation, and feedback loops.

That principle applies beyond software engineering. Travel agents need route graphs. Research agents need citation graphs. Robotics agents need world models. Workflow agents need task DAGs. Coding agents need repository graphs and proof logs.

The domains change. The shape repeats.

2.4

Citation

This article takes its own architectural stand. The research paper below is a useful reference for the structural reasoning problem.

Paper citation

He, Y., Li, Y., White, C., & Vitercik, E. Can LLMs Reason Structurally? Benchmarking via the lens of Data Structures. Proceedings of the 43rd International Conference on Machine Learning, 2026.

Use this citation for the paper that studies structural reasoning through data structures and motivates why explicit structure matters for reliable agent systems.

AI-Native Engineering Sprint

Want to truly learn AI-native engineering?

If you are a working professional and want to build the kind of proof needed for Applied AI Engineer, Forward Deployed Engineer, Agent Engineer, AI SWE, AI Product Engineer, or AI startup engineering roles, apply to work with us.

The AI-Native Engineering Sprint is for people who want to learn the systems behind agents, evaluation, retrieval, AI coding workflows, production capstones, and technical positioning.

Apply to work with us