●ENTERPRISE — Claude Enterprise adds richer admin analytics, model-level entitlements, and spend alerts●DEVICES — Trusted Devices arrives for Team and Enterprise, verifying devices before remote Claude Code sessions●CODE — Claude Code adds org default models, readable session names, and clickable file attachments●MODEL — Claude Sonnet 5 is the default across all plans at $2/$10 per million tokens through August 31●FABLE 5 — Claude Fable 5 returns worldwide from July 1 after export controls lift, with a new cybersecurity classifier●LIMITS — Claude Code weekly usage limits are up 50% through July 13; Claude Science applications close July 15●ENTERPRISE — Claude Enterprise adds richer admin analytics, model-level entitlements, and spend alerts●DEVICES — Trusted Devices arrives for Team and Enterprise, verifying devices before remote Claude Code sessions●CODE — Claude Code adds org default models, readable session names, and clickable file attachments●MODEL — Claude Sonnet 5 is the default across all plans at $2/$10 per million tokens through August 31●FABLE 5 — Claude Fable 5 returns worldwide from July 1 after export controls lift, with a new cybersecurity classifier●LIMITS — Claude Code weekly usage limits are up 50% through July 13; Claude Science applications close July 15
When Instructions Fade in Long Conversations: Measuring Adherence and Pulling It Back
System-prompt instructions quietly lose their grip as a conversation grows. This piece turns that drift into a number you can track, then fixes it with prompt structure and mid-conversation re-anchoring, backed by runnable code and measured results.
One evening I was batch-generating drafts for four sites at once.
The first several came back with exactly the heading structure I had asked for. But somewhere around the twentieth, a "summary" section I had never requested began quietly slipping in. No errors. The model was writing with full confidence, and writing something slightly different each time.
I only noticed the next morning, looking at the diffs. It was unsettling. Nothing had broken. The instructions had simply faded.
The longer a conversation runs, the more quietly a system prompt loses its grip. This piece is about catching that fade as a number rather than a hunch, and then pulling behavior back with prompt structure and a mid-conversation fix, all traced through runnable code and measured results.
Why instructions fade as conversations grow
Several independent forces stack up behind fading instructions.
One is position. The system prompt is pinned to the front of the conversation, but as turns accumulate, the model leans harder on recent context. The rules up front become relatively "far away."
Another is dilution. Once twenty turns of exchange are in the history, the ten lines of constraints you placed at the start are a tiny fraction of the whole. The absolute amount of rule text hasn't changed, but its weight has dropped.
Then there is competition. When you slip a new request or an exception into the middle of a conversation, it acts as an implicit override and quietly collides with the original rules.
None of this is the simple story of "the model forgot." It's the priority of adherence sliding along with the center of gravity of the context. That's exactly why we start by measuring.
Turning adherence into a number
As long as you're saying "it feels like it's drifting," you can't verify whether any fix actually worked. So we define the rules as a set of checks that can be judged mechanically, and produce an adherence score for each turn of the conversation.
For a concrete target, imagine we want the model to obey three rules: "always start headings with H2," "never use bullet points," and "don't append a sources section." The judging is done with deterministic checks such as regular expressions, never relying on the model's own self-report.
import osimport refrom anthropic import Anthropicclient = Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])SYSTEM_PROMPT = """You are an assistant that drafts technical articles.Always obey these rules.1. Headings must start with ##.2. Do not use bullet points (lines beginning with - or *).3. Do not append a "Sources" or "References" section at the end."""# Judge each rule with a deterministic function (True = obeyed)def rule_heading(text: str) -> bool: return bool(re.search(r"^##\s", text, re.MULTILINE))def rule_no_bullets(text: str) -> bool: return not re.search(r"^\s*[-*]\s", text, re.MULTILINE)def rule_no_sources(text: str) -> bool: return not re.search(r"(Sources|References)", text)CHECKS = { "heading": rule_heading, "no_bullets": rule_no_bullets, "no_sources": rule_no_sources,}def adherence(text: str) -> float: passed = sum(1 for fn in CHECKS.values() if fn(text)) return passed / len(CHECKS)
Next, we send nearly the same "probe" request on every turn and record the adherence score each time. The history keeps growing, so the context gets longer as the turns advance. Keeping the probe text almost identical isolates the change as coming from prompt length rather than from what we asked.
PROBE = "Write about 60 words of body text under this heading. Any topic is fine."def run_session(turns: int, reanchor_every: int = 0): history = [] curve = [] digest = "Strict: (1) headings start with ## (2) no bullets (3) no trailing Sources section" for t in range(1, turns + 1): # Re-inject the rule digest at a fixed interval (0 disables it) if reanchor_every and t % reanchor_every == 0: history.append({"role": "user", "content": digest}) history.append({"role": "assistant", "content": "Understood. I will strictly comply."}) history.append({"role": "user", "content": PROBE}) resp = client.messages.create( model="claude-sonnet-5", max_tokens=400, system=SYSTEM_PROMPT, messages=history, ) out = resp.content[0].text history.append({"role": "assistant", "content": out}) curve.append((t, adherence(out))) return curve
The point of this harness is that judgment never depends on human eyes or on the model grading itself. An adherence of 1.0 means every rule was obeyed; 0.66 means one has slipped, at a glance. Run run_session(50) in the bare state first, and watch the shape of the decay.
✦
Thank you for reading this far.
Continue Reading
What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.
WHAT YOU'LL LEARN
✦A small harness that scores instruction adherence turn by turn (Anthropic SDK, runnable as written)
✦Locating the turn band where rules break, then restoring adherence by restructuring the system prompt (before/after)
✦A re-anchoring implementation that re-injects a rule digest mid-conversation, with measured cadence tuning
Secure payment via Stripe · Cancel anytime
✦
Unlock This Article
Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.
Here is how adherence moved on my end when I ran fifty turns against claude-sonnet-5 (averaged over three trials and rounded). The numbers shift with your environment and with model updates, so read them as material for spotting a trend rather than as fixed truth.
Turn band
Mean adherence
Rule that broke first
1–10
1.00
none
11–20
0.94
no bullets
21–35
0.79
no bullets, sources section
36–50
0.67
all three, sporadically
The reading is clear. The breakdown doesn't happen suddenly at the tail; it creeps in from around turn twenty. And the first to fold were the negative rules ("do not …"). The positive one, "headings start with ##," held up comparatively well to the end.
That's telling. Prohibitions are harder for the model to hold, and they loosen first as the context stretches. The response is to act before this onset band, and to rewrite the negative instructions into a form that is easier to keep.
Restructuring the system prompt to slow the decay
The same rules yield different adherence depending on how they're written and where they're placed. I restructured the bare prompt in three ways.
First, translate the negatives into positives. "Do not use bullet points" is hard to hold, so I write the behavior I actually want: "express lists as running prose joined by commas." I specify the substitute action rather than the prohibition.
Second, consolidate the rules into a short "charter" pinned to the end of the system prompt. Instead of scattering them through long prose, gathering the minimal set of checkable clauses at the very end makes them easier to reference from a position closer to recent context.
Third, attach a one-line reason to each rule. A rule with a reason helps the model judge priority when a competing request arrives.
SYSTEM_PROMPT_V2 = """You are an assistant that drafts technical articles.--- OUTPUT CHARTER (self-check in this order before you start writing) ---A. Start headings with ## (to preserve the article's hierarchy)B. Write lists as running prose joined by commas (bullets break the layout)C. Return only the body; do not create a Sources/References section (added in a separate step)--------------------------------------------------------------------------"""
Swapping in SYSTEM_PROMPT_V2 and running fifty turns again, adherence improved like this.
Turn band
Bare prompt
Charter (V2)
1–10
1.00
1.00
11–20
0.94
0.99
21–35
0.79
0.92
36–50
0.67
0.85
Structure alone pushed the onset of decay later and made it shallower. Even so, in the back half of fifty turns, about fifteen percent is still breaking. Beyond this point a static prompt won't reach; you have to intervene inside the conversation.
I've written more about assembling the system prompt itself in Claude system prompt design patterns, and reading it alongside this will firm up the foundation.
Dropping an anchor again mid-conversation
Re-anchoring means inserting a short rule digest partway through the conversation to pull the center of gravity of recent context back toward the rules. The reanchor_every argument in the harness above is that implementation: at a fixed interval it inserts the digest and a short acknowledgment into the history.
The crux is frequency. Anchor too often and the history swells and cost rises; anchor too rarely and you miss the decay. Varying the interval and measuring adherence in the back half (turns 36–50) of a fifty-turn run gives this.
Re-anchor interval
Back-half mean adherence
Approx. added tokens
none
0.85
0
every 15 turns
0.90
~ +2%
every 10 turns
0.96
~ +3%
every 5 turns
0.97
~ +6%
Anchoring every ten turns hit the best cost trade-off for this target. Going to every five barely moved adherence while adding tokens. That lines up with the earlier observation that decay begins around turn twenty: pick an interval one step ahead of where the breakdown starts, as a practical rule of thumb.
Keep the digest short. Re-pasting the entire system prompt makes the history heavy and invites more dilution. Fold only the minimal, judgment-relevant clauses into a single line and drop that. An anchor doesn't need to be heavy; it just needs to pull in the right direction.
Field notes the docs don't spell out
Running this for real surfaced a few things that were hard to read off the documentation.
Negative instructions loosen first as context stretches. Wherever possible, translate the constraints you care about into positive "do this instead" behaviors, and the back-half breakdown drops visibly.
Because adherence falls continuously, threshold monitoring works well. I run generated output through the same judging functions and route only the batches that dip below 0.9 to a human review queue. Catching just the turns that broke keeps quality up with far less effort than eyeballing everything.
The effect of re-anchoring changes with model updates. When you switch to a new model, assume you'll re-tune the interval once. The ten-turn interval that was optimal on the previous model can be either excessive or insufficient on the next.
And measuring turn by turn with a fixed probe doubles as a regression test for system-prompt changes. When you tweak a single line of the prompt, you can mechanically confirm the back-half adherence hasn't dropped. That quietly pays off over long-term operation.
The next step
Start by writing out two or three of the rules you want obeyed as functions that can be judged deterministically. That alone turns "it feels like it's drifting" into a measurable fact: "it fell to 0.7 by turn thirty."
Once you can measure, three moves start to work in sequence: translate negatives into positives, consolidate the rules into an end-of-prompt charter, and drop an anchor one step ahead of where the decay begins. Static prompt edits and mid-conversation re-anchoring aren't either/or; you layer them.
For my part, running the four sites of Dolice Labs as an indie developer, every time I try to keep the output of several products consistent this "quiet fade" has tripped me up again and again. If it spares you a stumble at the same spot, I'll be glad. Thank you for reading.
Share
Thank You for Reading
Claude Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.