When Users Change Their Minds: Measuring and Repairing Intent Drift in LLM Agents
Yanjie Zhang, Bowen Cao, Zixin Chen, Yushi Sun
cs.CL, cs.AI
2026-09-26
Mid-dialogue requirement changes cut 8 agents from 0.60 to 0.22 full credit; explicit state tracking lifts mean score from 0.367 to 0.467, still below the 0.778 single-turn score.
Anyone who has shipped a multi-turn agent has seen this failure: a user states a task, revises a parameter a few turns later, withdraws a constraint, and says 'go'. The delivered result still honors the dead constraint. The paper names this intent drift: superseded parts of the user's intent keep shaping the final answer or tool action.
Existing evaluations each prove half the problem. Sharded-instruction settings show models lose the task when information arrives gradually; evolving-intent benchmarks add revisions and task switching. Both only check whether the agent ends up following the evolved task, so they cannot tell obsolete-intent failures from other multi-turn errors. Isolating the failure needs a known final intent plus stale information whose erroneous use flips the task verdict. IntentFlux is built to that spec.
On the benchmark side, each task is a finite set of atomic goals. A user simulator walks from an initial intent through ADD, DELETE, and REPLACE edits to a final active intent, and scoring always uses the source task's native grader (SQL execution, code tests, AST checks on tool calls). The dialogue changes; the grading standard does not. Stale information enters in two forms:
Difficulty is controlled by a construction budget of 1, 3, or 5 variants and decoys per goal (easy, medium, hard); average dialogue length grows from 13.2 to 37.1 turns. The closing turn is a neutral request for the final answer with no restatement of the final intent, forcing the agent to recover the current requirements from the dialogue itself. Source tasks span seven families (LiveCodeBench, GSM8K, HumanEval, Spider, ToTTo, SummHay, BFCL) plus a VitaBench interactive track; human annotation with downstream audit recovers the annotated final intent for 95% of General-Test cases.
The repair starts from an observation: history compression cannot fix this. After summarization, the superseded value and its replacement often both survive, and deciding which is active remains the generator's job; conclusions derived from a deleted goal look locally consistent and get kept too. StateForge upgrades 'what to retain' to 'what is still valid'. After each user turn, a tracker folds edits into an explicit active state; when a goal is deleted or replaced, conclusions derived from it are invalidated as well. The updated state is inserted between the cached history and the current input, so history stays cacheable while active information sits closest to generation. The harness is train-free, and two transfer paths build on it: on-policy distillation (OPD) trains a small tracker, and thinking distillation internalizes state folding into a standalone agent.
On the 627-task calibration pool (gemini-3.5-flash tested), mean score falls from 0.476 (easy) to 0.384 (hard), a 19.3% relative drop. On the fixed 125-task General-Test, full-credit rates (CAR) for four of the eight models:
| Model | Clean CAR | Hard drift CAR | Hard IDG [95% CI] |
| Claude Opus 4.7 | 0.592 | 0.184 | 0.408 [0.304, 0.512] |
| GPT-5.4 | 0.608 | 0.224 | 0.384 [0.304, 0.472] |
| Qwen3.6 Plus | 0.640 | 0.192 | 0.448 [0.360, 0.536] |
| GLM 5.2 | 0.576 | 0.232 | 0.344 [0.264, 0.432] |
All eight models show a positive clean-versus-drift gap at every difficulty stratum; averaged across models, CAR goes from roughly 0.60 to 0.22. Turn count alone does not explain the loss: a turn-matched control with no intent changes scores 0.734, close to the 0.778 single-turn condition, while drift trajectories score 0.469.
| Condition (Qwen3.5-122B) | Mean score |
| Single-turn, final intent given directly | 0.778 |
| Turn-matched, no intent changes | 0.734 |
| Multi-turn drift | 0.469 |
| Deep Agents (rolling summary) | 0.354 |
| OpenHarness (two-phase compaction) | 0.392 |
| Bare multi-turn (medium) | 0.367 |
| StateForge | 0.467 |
| Ground-truth final state injected | 0.549 |
Deep Agents lands below bare execution and OpenHarness only marginally above it; neither approaches the clean condition. StateForge reaches 0.467, a +0.100 gain over bare execution (95% CI [0.030, 0.171]); injecting the ground-truth final state reaches 0.549, still 0.229 short of clean, so state-estimation error explains only part of the gap. Responses differ sharply by family: LiveCodeBench drops 0.309 from easy to hard, GSM8K drops 0.184, SummHay barely moves, and BFCL actually rises 0.048. On the VitaBench interactive track (100 tasks), withholding a final-intent restatement in the closing turns costs 0.103 rubric score against clean (0.594 vs 0.697); the default restating close masks the gap entirely, a reminder that a benchmark can accidentally hand the model the very state it means to test. On transfer: a 9B tracker is statistically indistinguishable from the 122B reference (0.399 vs 0.428); one OPD iteration lifts a 2B tracker from 0.266 to 0.445, with the 122B tracker at 0.428 under the same protocol; thinking distillation lifts a standalone 35B agent on the drift condition from 0.296 to 0.461, while its clean score dips from 0.745 to 0.718.
For benchmark builders, this isolates a failure that aggregate multi-turn scores hide: making stale information grader-consequential is what separates 'old intent still at work' from generic multi-turn degradation, and the decoy retention rule is the design worth copying. For agent engineers, the takeaway is direct: history compression does not repair intent drift, an explicit active-requirement state does, and the tracker needs no base-agent scale (9B suffices, 2B is trainable), so it can ship as a cheap module in front of an existing agent. The honest framing: 0.467 against 0.778. StateForge is a partial repair, and most of the gap remains.