Large language models reward fluent, high-probability answers. That works within a single domain, where knowledge is bounded. Across domains, an LLM tends to flatten the different meanings a concept carries into one generic meaning. A semantic failure occurs when an agent uses a technically valid fact or definition in the wrong business context, or fails to preserve a relationship between concepts that changes what the answer should mean. For an enterprise, almost every important data inquiry is cross-domain and the risk of confident mistakes is what's holding back AI adoption.
This article looks at the problem, then proposes a two-part harnessing system: a harness that works ahead of time and a harness that responds to real failures.
An example: Latency means two different things
A site reliability engineer asks an agent to set an alert threshold for a payment service's API latency. The agent retrieves a generic internal guideline suggesting p95 under 300ms and p99 under 500ms.. Reasonable on its own.
But this endpoint calls external banking and fraud detection systems on every request, adding 150 to 250ms of overhead it doesn't control. A 300ms target barely covers one healthy fraud check, let alone the full chain.
"Latency" means two things here: a generic convention in the service agreement domain and the unavoidable cost of downstream calls in the infrastructure domain. The threshold needs to tolerate that overhead while staying tight enough to catch real problems, tacit knowledge a senior engineer holds but nobody wrote down.
Adopt the generic baseline and every healthy request touching the banking network trips the alert. On-call drowns in false pages, the team mutes it and the one real outage goes unnoticed.
The goal is not to make the model remember every enterprise nuance. It is to turn the relationships experts carry in their heads into context the agent can retrieve and constraints the system can verify.
The real failure is flattening meaning
The root cause sits in how a typical RAG pipeline turns the question into a retrieval query. The entity simply becomes "latency," stripped of domain:
// Basic RAG slot extraction
{"intent": "set_alert_threshold", "entity": "latency", "service": "payment-api"}
With no domain field to filter on, the retriever returns whatever scores highest for "latency" plus "alert" plus "API," generic SRE guidance. The service's downstream dependencies never enter the query, because the slot never asked for them.
Nobody specified which "latency" was meant, because the question was cross-domain (Figure 1.) from the start. The concept means a user commitment in one domain and a measured system cost in the other; and without deliberate controls the model can't hold both apart.
The LLM then flattens them into one slot, and the tacit rule that would have caught the gap, that a commitment must respect the constraints underneath it, exists nowhere the agent can learn it. The recommendation looks reasonable, the mistake is hard to spot and the resulting alert fatigue buries real outages.
This is a byproduct of how the model reasons, through co-occurrence in training data, optimizing for fluency rather than checking a value against the specific system it's applied to. Nothing in the answer looks obviously nonsensical. The failure becomes visible only when you compare the recommendation with knowledge from another domain.
In this example, the failure occurs before generation: the retrieval representation collapses two domains into one entity. Enterprise data spans dozens of systems with their own vocabularies, so this collapse is the default wherever domains intersect.
A fix at the query level and where it stops working
A fix at the query level may work by preserving domain in the query instead and the conflict becomes visible:
// Domain-aware slot extraction
{
"generic_latency": {"domain": "service_agreement", "p95_ms": 300},
"service_latency": {"domain": "infrastructure", "downstream_overhead_ms": [150, 250]},
"relation": "threshold >= generic_latency.p95_ms + downstream_overhead_ms",
"conflict": true
}
This works because someone already knew "latency" needed splitting here. That knowledge doesn't generalize, the next term on the next service needs the same manual insight and enterprise systems generate far more terms than any team can hand-check.
Fixing the query solves the instance, not how an agent recognizes, unprompted, when any term needs this treatment. That's the harnessing problem: getting this correction to happen at scale, on terms nobody has flagged yet.
Guide & sensor and the loop between them
A bigger model, a cleverer prompt, a self-reflecting loop, none of these close this gap. Better reasoning alone cannot close this gap. If the relevant relationship never enters the agent's context, asking the model to reason harder does not reliably recreate institutional knowledge that was never provided. But domains change faster than any team can encode them and even an encoded rule can fail to reach the agent, lost in retrieval or ignored outright. So closing the gap means two things: encode as much tacit knowledge as possible ahead of time and catch it whenever that knowledge, known or not, fails to show up in what the agent does.
This is harness engineering: feedforward controls that steer the agent before it acts, feedback controls that catch what steering missed or failed to enforce and a loop connecting them so each catch sharpens the next round of steering. Guide and sensor are our names for those two halves.
Guide
Guide, as a feedforward control, surfaces tacit knowledge ahead of time for the domain intersections that matter most. In the latency case, that means encoding as an ontology with explicit relations that any generic latency baseline must be validated against known downstream dependencies.
Producing that ontology manually does not scale. An extraction engine can identify concepts that appear across domains, compare how each domain defines them and surface relationships that may affect agent decisions. Domain experts then decide which relationships are important enough to encode. In our earlier latency case, that means recognizing latency as a service target in one domain and a system cost in another and encoding the tacit relationship.
The engine can produce both inferential and deterministic knowledge. A relation the engine surfaces but hasn't confirmed stays inferential, an open judgment call, until a domain expert reviews it. Once approved, the ontology, the relation rules and the ownership record behind each one all become computational, deterministic structures an agent queries through a context-as-a-service layer, a third source of knowledge alongside training data and the vector database.
Served this way, guide gives an agent the cross-domain knowledge it needs to get the answer right the first time.
Sensor
Sensor, as a feedback control, catches semantic failure after an agent produces an answer, whether that's a relation guide never encoded, or one it did encode that got lost before generation.
Generic output evals may not catch this unless the cross-domain constraint is explicitly represented in the evaluation criteria. A trace can show what context and tools the agent used, but it does not by itself tell you whether the resulting value respected the relevant business relationship.
To scale that feedback mechanism, we introduced an approach called the reliability ladder, so each risk gets tested where it actually lives, not at the finish line.
At each layer, a truth contract states what must hold there, testable rather than documented. A contract test makes each contract executable. A failure taxonomy routes the result, here to platform reliability rather than filed as a model error, since the model produced a defensible baseline competently. Triggers decide when to recheck, on a component change, a definition update, or a muted alert that turns one caught conflict into a permanent regression test across every similar endpoint.
Five roles, kept separate on purpose: the ladder locates, the contract states, the test verifies, the taxonomy routes, triggers decide when.
Loop
Guide puts pre-made context in front of the agent, so the initial answer gets the cross-domain relation right the first time. Sensor is where the system meets reality: it runs after generation and every conflict it catches, a reconciliation flag with nowhere yet to resolve, a threshold that ignored a known constraint, feeds back into what guide encodes, expanding the ontology, the contracts, the glossary, ahead of the next request.
Computational and inferential controls sit inside both, but guide and sensor themselves don't run side by side as separate safeguards. Steered by a human, they form one closed loop (Figure 3) that gets better at cross-domain reasoning every time it's used.
What this means for building enterprise-ready agents
Semantic failure is one of the most dangerous risks in an agent, precisely because a confident, well-formed wrong answer isn't something an eval or a trace will surface on its own.
Enterprise context is inherently complex and no agent at scale can stay inside one domain. The model's core reward mechanism works against it here: optimizing for fluent, high-probability answers means flattening a concept to its most common meaning unless something forces the distinction to stay visible.
The tacit rules practitioners hold about how one domain's terms map onto another's constraints could stop this. Nobody ever wrote them down anywhere an agent can retrieve them.
Building that layer around the model, one that constructs and validates context instead of expecting the model to know what it was never taught, is a harness engineering problem.
The answer is a feedforward system, guide: that gets ahead of the highest-value gaps and a feedback system, sensor, that catches what guide misses. A loop between the two keeps expanding what the agent can reliably access.
Model capability, tracing and evals raise what an agent can do. None of them close this particular gap on their own. Harness engineering, guide and sensor working as one loop, is what makes that capability trustworthy enough for enterprises to adopt.
Disclaimer: The statements and opinions expressed in this article are those of the author(s) and do not necessarily reflect the positions of Thoughtworks.