Context-Faithful Trajectory Processing
Branching agent runs create overlapping, changing histories that are hard to train faithfully; QwenGyre preserves exact request contexts in shared-prefix trees, scores assessable work, and admits deduplicated targets per execution.
Read the paper ↗What it is
- Shared-prefix trajectory trees Keep exact model requests and outputs in a tree, so branching runs can share earlier context without pretending they all followed one transcript.
- Assessable partial work A run that times out can still receive a score when its completed work can be checked; an unresolved score is different from a valid zero.
- One target, one contribution Choose a bounded set of important paths, train only on tokens the policy actually produced, and prevent shared prefixes from being counted twice.
Why it matters
Long-running agents branch, compact histories, and may stop before finishing. Preserving the actual inputs and carefully assigning trainable tokens lets learning use assessable work without inventing context or overweighting shared prefixes.
Before we get into the mechanics, here is the short version: QwenGyre keeps a record of what the model actually received and produced, even when a long agent run later branches or compacts its history. It scores whatever completed work can still be assessed, then chooses a limited set of useful paths without training twice on a shared prefix. That matters because a reconstructed transcript can quietly change what an output appears to have been conditioned on.
-
Context fidelity: A long agent run is not one tidy chat log. The canonical example is a model call made after the harness has compacted history: the output was conditioned on an input that may no longer appear in the current transcript. QwenGyre records the exact input and output tokens and keeps the output tied to its original context. The tree shares matching prefixes and branches when contexts diverge. It is like keeping a notebook with shared pages before two people split onto different routes; the limit is that a token tree does not itself explain the task meaning of those pages.
-
Partial scoring: A timeout is not the same thing as having no useful work. Imagine an agent has produced a repository that can be tested before its run expires: the completed artifact can be assessed under the task’s scoring rule. The score is about the preserved work, not elapsed time or how long the transcript is. If evaluation cannot produce a valid reward before the execution budget ends, those trajectories are excluded; a valid zero is still a real score. So the real question was never just whether the run finished — it was whether its state can be judged.
-
Selective, non-duplicating training: First ask which tokens the policy actually generated. Prompts, tool results, and harness-injected assistant content can help condition a response without becoming targets themselves. Then consider candidate paths through the tree. The canonical example is two leaves that share an early policy-generated prefix: if both are trained as full transcripts, that prefix gets counted twice. QwenGyre admits a bounded, role-prioritized set and masks a selected path’s targets before drawing again. Think of marking notebook pages you have already learned from; it avoids repeating the same page, though it does not guarantee every branch is admitted.
For a selected path, only the policy-produced tokens still unmasked become targets. The sampler favors the highest-priority role class that still has eligible tokens, then draws within that class in proportion to its remaining eligible-token count. The ordering favors main-agent task-driving work over delegated sub-agent work, and task-driving turns over summaries. I like that the selection rule makes the tradeoff explicit: it spends a per-execution budget on expected importance rather than pretending all leaves are equally useful. What should happen when one execution contributes several selected paths carrying different pieces of its target set?
The answer is to keep the execution as the unit of normalization. The selected paths contribute disjoint target sets because shared path tokens are masked after selection; their union is the execution’s admitted targets. Each target gets the same normalization coefficient, based on the total admitted targets for that execution, and an execution with no targets contributes zero loss. In words, adding another path does not automatically give the execution more aggregate weight. This is the important bookkeeping distinction: sampling paths decides which targets exist, while normalization decides how those fixed targets share the execution’s contribution. But the cap still means some candidate paths may never train — how much coverage is worth the cost of admitting more?
Read the deep dive
Why People Wanted It
A long-horizon agent does not produce one neat transcript. It can call tools, delegate work, revise artifacts, compact its history, and branch into different contexts. If training reconstructs those histories afterward, the reconstructed input may not be the one that actually conditioned an output. If every branch is expanded and trained independently, shared tokens can be counted repeatedly.
So the real question was never just how to store a conversation. It was how to preserve what the policy actually saw and generated, assess the work that remains when an execution ends, and turn branching records into training targets without duplicating shared prefixes.
The Core Move
Record each request and response as it happened, organize records into a shared-prefix tree, then select provenance-valid targets while keeping their execution identity. The paper gives no single formula for this processing pipeline; its core is a sequence of explicit record, score, mask, and admission operations.
Why Exact Request Records Matter
Here is the deeper machinery behind the intuition: each model-call record preserves exact input and output token IDs, output behavior log-probabilities, and associated metadata. Tool-call payloads are cached by call ID and restored before matching later histories, while incoming IDs remain available to associate tool responses. This lets the harness retain its message interface while training uses the recorded tokens.
The key constraint is that an output keeps its original conditioning context even if later history compaction removes that context from the harness’s current view. For a new request, the serialized context is matched against existing paths; matched nodes are reused, only new input content is encoded, and the request becomes a new node. Divergent contexts become branches, while a request with no matching prefix attaches to the root. Outputs generated independently remain separate nodes.
Why Scoring Can Survive an Incomplete Run
Now the scoring layer goes beyond the basics: at execution closure, the committed policy-generation request record is fixed and available artifact state is assessed under the task’s scoring rule. A timeout does not automatically make work unusable. Completed work can receive a valid score if it is assessable; the score is not derived from elapsed time, trajectory length, or termination status.
An assessment carries its execution, artifact version, and available branch reference, so a later assessment does not overwrite the state associated with an earlier one. A critique used as later input remains context, but evaluator provenance excludes it from policy targets. If evaluation fails, it can be retried against the same preserved state within the execution’s time budget. No valid reward by the budget’s end means those trajectories are excluded; a valid zero remains trainable. A complete failure with no assessable work can instead receive a zero-reward dummy trajectory.
Why Admission Uses Provenance and Shared-Target Masks
Here is the part that gets technical: first mask tokens that were not sampled from the policy. Policy-produced tokens are eligible targets; system and user prompts, tool results, and assistant-role content injected by the harness remain conditioning context only.
Candidate paths are leaves plus their root-to-leaf prefixes. Since executions can yield widely varying numbers of candidates, admission caps the number selected per execution at the stated maximum, . Within a role class, a leaf is drawn with probability proportional to its count of currently unmasked trainable tokens. Role priority puts main-agent task-driving turns ahead of delegated sub-agent work, and task-driving turns ahead of context-managing summaries within an agent.
When a path is drawn, its targets are fixed to the still-unmasked tokens on that path, then the entire path is masked for subsequent draws. This is the deduplication rule: a shared prefix contributes targets once, without changing targets already fixed by an earlier draw. Admission stops when no eligible tokens remain or the cap is reached. The excerpt names the maximum but does not provide the role-priority equation, so the priority is described here in words rather than reconstructed as a formula.
Why the Loss Is Normalized Per Execution
The expert-level constraint is that an execution’s admitted targets form one deduplicated set, even if those targets are distributed across several selected paths. For execution , each trajectory receives its fixed target set ; on-tree masking makes those sets disjoint. The execution target set is their union, , and its length is .
In words, the denominator is the number of admitted, deduplicated trainable tokens for that execution. Each target therefore has coefficient in the execution’s normalized loss; importance weighting and clipping do not change that denominator. An execution with no admitted targets contributes zero loss. The batch then averages over the original rollout executions, so splitting one execution across more selected trajectories does not give it extra aggregate normalization weight. Reassigning a fixed target set among paths leaves its execution ratio, clipping decision, and loss unchanged; changing which targets are admitted can still change the result.
Minimal Causal Code
This plain loop shows the target-mask invariant: each newly admitted path claims only targets not already claimed. It is a minimal illustration of that rule, not a full implementation of role ranking or probabilistic sampling.
# Each leaf_path is a root-to-leaf sequence of node IDs.
# policy_targets[node] is the set of token positions emitted by the policy.
claimed = {node: set() for node in policy_targets}
admitted = []
for leaf_path in selected_leaf_paths:
targets = {}
for node in leaf_path:
fresh = policy_targets[node] - claimed[node]
if fresh:
targets[node] = fresh
if not targets:
continue
admitted.append((leaf_path, targets))
# Fix this trajectory's targets, then mask its whole path for later draws.
for node in leaf_path:
claimed[node].update(policy_targets[node])
What You Gain, and What You Lose
You gain faithful conditioning contexts despite later compaction, shared-prefix storage instead of immediate full-history expansion, and a way to learn from assessable partial work. Provenance masks keep injected context out of policy targets; path masking prevents shared targets from contributing twice; execution-level normalization keeps an execution’s aggregate weight from depending on how many paths carry its targets.
The costs are real: request recording and payload restoration add bookkeeping; tree matching and deferred materialization make admission more involved than treating every transcript as an independent sample; and unresolved scoring can exclude otherwise recorded trajectories. A role-prioritized cap also deliberately leaves some candidate paths out. This is a data-integrity design, not a guarantee that every branch or every unfinished run becomes training signal.
Preserve the exact context, score what can be assessed, and let each policy-generated token belong to one admitted execution target set.