Paper deep dive
CodeGrep: An RL-Trained Retrieval Agent for LLM Coding Agents
Wuya Chen, Yihao yang, Yang Cao, Yue Lin
Intelligence
Status: succeeded | Model: Gemma-4-26B-A4B | Prompt: intel-v1 | Confidence: 91%
Last extracted: 8/8/2026, 4:20:08 AM
Summary
The paper introduces CodeGrep, a 14B parameter retrieval agent trained end-to-end using GRPO to optimize multi-turn parallel tool calls (grep, glob, read) for LLM coding agents. Evaluated on SWE-Bench Verified, CodeGrep improves efficiency by reducing rounds by 15% and tokens by 19% on resolved instances while slightly increasing the resolve rate from 25.8% to 27.0%. The study highlights a precision threshold for downstream utility, where CodeGrep (precision 0.677) outperforms BM25 (0.375) and Jina (0.445). The training pipeline utilizes CATM to mine supervision from 67K open-source trajectories and employs a lightweight Git-worktree RL environment.
Entities (9)
Relation Signals (8)
CodeGrep → evaluatedon → SWE-bench Verified
confidence 95% · On all 500 SWE-Bench Verified instances, CodeGrep preserves resolve rate
CodeGrep → istrainedwith → GRPO
confidence 95% · CodeGrep, a 14B retrieval agent trained end-to-end with GRPO
CodeGrep → isbuilton → Qwen3-14B-Instruct
confidence 92% · CodeGrep is a 14B-parameter retriever built on Qwen3-14B-Instruct
CodeGrep → improvesefficiencyby → 15% fewer rounds
confidence 90% · with 15% fewer rounds and 19% fewer tokens on resolved instances
CodeGrep → outperforms → BM25
confidence 90% · BM25 with precision 0.375 degrades the agent... CodeGrep with precision 0.677 crosses the threshold
CodeGrep → outperforms → Jina
confidence 90% · Jina with precision 0.445 is neutral... CodeGrep with precision 0.677 crosses the threshold
CATM → usedtomine → supervision
confidence 90% · we mine supervision from 67K open-source agent trajectories using CATM
OpenHands → servesasdownstreamagentfor → CodeGrep
confidence 85% · return candidate files to a frozen downstream coding agent... injected into a frozen OpenHands agent
Cypher Suggestions (0)
No Cypher suggestions yet.
Abstract
Abstract:Modern LLM coding agents such as Claude Code and OpenHands share a common inefficiency: they spend much of their token budget finding the file to patch, rather than patching it. On SWE-Bench Verified, a 30B OpenHands agent averages 23 rounds and 631K tokens per resolved issue, with many calls spent on grep, glob, and view_file during repository exploration. We introduce CodeGrep, a 14B retrieval agent trained end-to-end with GRPO to issue multi-turn parallel grep, glob, and read tool calls and return candidate files to a frozen downstream coding agent. On all 500 SWE-Bench Verified instances, CodeGrep preserves resolve rate while substantially improving efficiency: 27.0% versus 25.8% for the no-retrieval baseline, with 15% fewer rounds and 19% fewer tokens on resolved instances. Across retrievers, downstream utility follows a precision threshold: BM25 with precision 0.375 degrades the agent, Jina with precision 0.445 is neutral, and CodeGrep with precision 0.677 crosses the threshold at which retrieval begins to reduce rollout cost. To enable this study, we mine supervision from 67K open-source agent trajectories using CATM and build a Git-worktree environment for multi-turn agent RL. In our setting, applying the efficiency signal at the advantage layer rather than the reward layer reduces KL drift and translates cleanly into downstream efficiency. We will release the model, training pipeline, RL environment, and evaluation harnesses.
Tags
Links
- Source: https://arxiv.org/abs/2608.05886v1
- Canonical: https://arxiv.org/abs/2608.05886v1
Trouble viewing inline? Open PDF directly →
Full Text
60,565 characters extracted from source content.
Expand or collapse full text
CodeGrep: An RL-Trained Retrieval Agent for LLM Coding Agents Wuya Chen1,∗ and Yihao Yang2 and Yang Cao2 and Yue Lin1 chenwuya@corp.netease.com, 13590078189@163.com yihao786, cy1835208239@gmail.com gzlinyue@corp.netease.com 1Netease Guangzhou AI Lab 2Independent Researcher Abstract Modern LLM coding agents—Claude Code, OpenHands—share a common inefficiency: they spend most of their token budget finding the file to patch, not patching it. On SWE-Bench Verified, a 3030B OpenHands agent averages 2323 rounds and 631631K tokens per resolved issue, dominated by grep, glob, and view_file calls. No open, systematically-studied agent-style code retriever exists at scale to shorten this phase. We introduce CodeGrep, a 1414B retrieval agent trained end-to-end with GRPO to issue multi-turn parallel grep/glob/read tool calls and return candidate files to a frozen downstream coding agent. On all 500500 SWE-Bench Verified instances, CodeGrep delivers a small but reproducibly positive resolve-rate lift (+1.2+1.2p: 25.8%→27.0%25.8\%→ 27.0\%) alongside a much larger efficiency gain (−15%-15\% rounds, −19%-19\% tokens on resolved instances). Across three retrievers, downstream utility follows a precision threshold: BM25 (precision 0.3750.375) degrades the agent, Jina (0.4450.445) is neutral, and only CodeGrep (0.6770.677) crosses the threshold at which retrieval begins to buy efficiency. To enable this study, we mine supervision from 6767K open-source agent trajectories (CATM) and build a Git-worktree environment for multi-turn agent RL. In our setting, applying the efficiency signal at the advantage layer, rather than the reward layer, holds KL drift to one-third and translates cleanly into downstream efficiency. We will release the model, training pipeline, RL environment, and evaluation harnesses. CodeGrep: An RL-Trained Retrieval Agent for LLM Coding Agents Wuya Chen1,∗ and Yihao Yang2 and Yang Cao2 and Yue Lin1 chenwuya@corp.netease.com, 13590078189@163.com yihao786, cy1835208239@gmail.com gzlinyue@corp.netease.com 1Netease Guangzhou AI Lab 2Independent Researcher 1 Introduction Modern LLM coding agents—general-purpose assistants like Claude Code Anthropic (2025) and open GitHub-issue-solving frameworks like OpenHands Wang and others (2024)—share a common inefficiency in how they allocate their token budget: much of it is spent finding the file to patch, not writing the patch itself. In this work, we ground this observation on a concrete instance: a 3030B OpenHands agent on SWE-Bench Verified Jimenez et al. (2023) averages 2323 rounds and 631631K tokens per resolved issue, with a large fraction consumed by grep, glob, and view_file calls issued in ambiguous exploration loops—often 20+20+ rounds in a wrong direction before the agent gives up. Can a specialized retrieval submodule shorten this exploration phase? Two hypotheses have not been jointly tested. H1 (effectiveness): better file-level retrieval steers the agent past dead-end explorations and raises the resolve rate. H2 (efficiency): the agent resolves roughly the same set of issues but with a shorter rollout. Distinguishing them requires evaluating a retriever both on its intrinsic quality and on its downstream effect within the same agent stack—a comparison absent from prior open code retrievers, from lexical (BM25 Robertson and Zaragoza (2009)) to static dense encoders Feng et al. (2020); Guo et al. (2021); Jina AI (2024). We train CodeGrep, a 1414B retrieval agent optimized end-to-end with GRPO Shao et al. (2024), and evaluate it against BM25 and Jina on SWE-Bench Verified. Neither H1 nor H2 holds uniformly: retrieval quality translates downstream through a precision threshold, not a linear payoff. Below the threshold, BM25 (precision 0.3750.375) degrades the agent; near it, Jina (0.4450.445) is neutral; above it, CodeGrep (0.6770.677) cuts 15%15\% rounds and 19%19\% tokens on resolved instances, while adding a small but reproducibly positive +1.2+1.2p to the resolve rate. Three engineering ingredients enable this study. First, CATM (Code Agent Trajectory Mining) mines relevance labels from 6767K open-source OpenHands trajectories without human annotation (§3.4). Second, a Docker-free Git-worktree sandbox reduces per-rollout environment setup from minutes to milliseconds, making multi-turn agent RL tractable on a single 8×8×B200 node (§3.3). Third, a systematic reward study across three trained iterations (v1→v2→v3v_1→v_2→v_3) yields two observations about GRPO reward design: in our setting, applying an efficiency signal at the advantage layer is markedly more stable than at the reward layer, and removing an auxiliary component absent from the downstream tool improves both training stability and downstream efficiency (§3.5). Contributions. • CodeGrep, an open 1414B agent-style code retriever trained end-to-end with GRPO; injected into a frozen OpenHands agent, it cuts rounds by 15%15\% and tokens by 19%19\% on resolved SWE-Bench Verified instances while lifting resolve rate by +1.2+1.2p. • A precision-threshold characterisation of retrieval–agent coupling: across three retrievers (BM25 0.3750.375, Jina 0.4450.445, CodeGrep 0.6770.677), downstream utility exhibits three regimes—hurts, neutral, buys efficiency (§5.1). • A reward-design study showing that (i) reward-layer multiplicative scaling of a tool-call penalty triples GRPO policy drift vs. advantage-layer scaling (KL 0.310.31 vs. 0.090.09); (i) in our final iteration, dropping an auxiliary line-range component from the base reward improves both training stability and downstream efficiency (§3.5). • Full open release: model, CATM pipeline, RL environment, and all evaluation harnesses. 2 Related Work Code retrieval for SWE-Bench-style agents. Static retrievers—dense code encoders Feng et al. (2020); Guo et al. (2021, 2022); Jina AI (2024) and lexical baselines such as BM25 Robertson and Zaragoza (2009)—struggle when issue vocabulary does not overlap with the target code, a common failure mode in GitHub bug reports (§4.2). Pipeline systems such as Agentless Xia et al. (2024), Moatless Örwall (2024), and SWE-Fixer Xie et al. (2025) pair lightweight retrieval with LLM-based reranking, but keep the retrieval component non-trainable. Agent-style search and tool use. Building on ReAct Yao et al. (2023) and Toolformer Schick et al. (2023), coding agents such as OpenHands Wang and others (2024) and SWE-agent Yang et al. (2024) operate over rich tool interfaces at the cost of dozens of sequential calls per issue. For search specifically, Search-R1 Jin et al. (2025) and ReasonIR Shao et al. (2025) train LLMs to use search engines with RL, but target indexed web corpora rather than repository file systems. Reinforcement learning for tool policies. GRPO Shao et al. (2024) has been adapted to multi-turn tool use in ToRL Li et al. (2025), RAGEN Wang et al. (2025), and concurrent Cognition SWE-grep Pan et al. (2025). A recurring difficulty is reward-length exploitation when the reward mixes task accuracy with efficiency signals. Our v1→v2→v3v_1→v_2→v_3 study (§3.5) traces one manifestation and its resolution: moving the efficiency signal from the reward to the advantage layer. Trajectory mining as supervision. Learning “what is relevant” from past agent reads is behavioural supervision with a long history in classical IR. LRAT Zhou et al. (2026) applied this to web-search agents with one-to-one browse-relevance pairs. CATM (§3.4) adapts the template to code retrievers that emit multiple parallel reads per turn, requiring one-to-many attribution and per-trajectory aggregation (Table 4); our source data are open-source OpenHands trajectories Nebius AI (2025). 3 Method 3.1 System Overview The system runs in two decoupled phases (Fig. 1). During training, CodeGrep is optimized with GRPO in a custom RL environment (§3.3) against relevance labels mined by CATM (§3.4). During inference, the trained CodeGrep takes the issue description, emits a short list of candidate files, and those files are injected into the prompt of a frozen OpenHands downstream agent. Only the retriever is trained; the downstream agent is untouched, so any downstream measurement (§4) is unambiguously attributable to what the retriever contributes to the prompt. Agent Trajectories(67K)GRPO Training(CodeGrep, 14B)CodeGrep CheckpointTrainingSWE-Bench IssueCodeGrep (14B)grep / glob / readSWE-Bench AgentQwen3-30B, frozenCode PatchfilesInferenceweights Figure 1: System overview. Training (blue) produces CodeGrep weights from open-source agent trajectories via GRPO. Inference (orange) uses the trained CodeGrep as a retrieval submodule whose output is injected into a frozen downstream agent’s prompt. 3.2 CodeGrep: The Retrieval Model CodeGrep is a 1414B-parameter retriever built on Qwen3-14B-Instruct Yang and others (2025). It exposes three read-only primitives—grep (regex search), glob (path matching), and read (file contents)—mirroring how a developer navigates an unfamiliar codebase. At each turn it emits up to 88 tool calls executed concurrently; observations are appended to the context, and exploration terminates on a final answer or after 44 turns (33 exploration + 11 answer, 2424 effective reads). The answer conforms to a fixed JSON schema: <answer>"files": […], "line_ranges": […]</answer> the line_ranges field is dead information downstream (the OpenHands editing tool consumes only file paths), so we drop it from the training objective in v3v_3 (§3.5). 3.3 RL Environment: A Lightweight Multi-turn Tool Sandbox An RL environment for CodeGrep must expose the target repository at a specific commit so that grep/glob/read calls can execute and their observations feed back into the rollout. The default of reusing official SWE-Bench Docker images is intractable at single-node training scale: each image is 11–33 GB, pulls take minutes, and thousands of them need terabyte-scale disk. Because CodeGrep training only reads code, the Python environment inside each image is dead weight. We replace Docker with a worktree-based sandbox whose per-rollout setup completes in milliseconds. From any SWE-Bench-style dataset we extract unique (repo, commit) pairs; for each repo we keep a single git clone --bare and use git worktree add to instantiate one lightweight tree per commit (disk drops from N⋅repo_sizeN·repo\_size to repo_size+N⋅worktree_sizerepo\_size+N·worktree\_size, with no network I/O). At rollout time, grep/glob/read run as native subprocesses inside the target worktree, under path-traversal protection, a 6464-way concurrency limit, and per-tool timeouts. Environment interaction per rollout drops from minutes to milliseconds, making the training runs in §3.6 feasible on a single 8×8×B200 node. Full plumbing, rollout scheduler, and the three-layer architecture diagram are in Appendix A. 3.4 Training Data: CATM (Code Agent Trajectory Mining) Ground-truth problem and fix. The natural “relevant files” label—files touched by the SWE-Bench gold patch—is incomplete: it omits auxiliary files that must be read to understand the fix but are not themselves edited. Directly optimizing against the patch signal therefore biases the retriever away from the behaviour we want. We instead adopt a behavioural notion of relevance: a file is relevant if some past agent, while solving the issue, opened it and produced non-trivial reasoning grounded in its contents. CATM (Code Agent Trajectory Mining) instantiates this notion for code retrieval and for agents that emit parallel tool calls; a related notion has been used by LRAT Zhou et al. (2026) in the web-search setting (see Appendix Table 4 for a detailed comparison). Three-stage pipeline. CATM operates on 67,07467,074 open-source OpenHands trajectories Nebius AI (2025). Stage 1 (mining): extract every file-read tool call (str_replace_editor with view), normalize paths, and discard directories, documentation (README.md, issue.md), and extensionless files. For each surviving file f record the following assistant message as the post-reasoning, with token length l(f)l(f). Stage 2 (judge filtering): an LLM judge classifies each file’s post-reasoning as RELEVANT or NOT_RELEVANT; we adopt a conservative bias treating any non-explicit-NOT_RELEVANT output as RELEVANT. Stage 3 (intensity-aware weighting): following LRAT Zhou et al. (2026), each file receives an exponential-saturation score of its reasoning length, w~(f) w(f) =1−exp(−ln2⋅l(f)/β), =1- (- 2· l(f)/β ), (1) w(f) w(f) =w~(f)/μraw, = w(f)/ _raw, (2) where β is the median l(f)l(f) and μraw _raw is the mean of w~ w; the normalization gives [w]≈1E[w]≈ 1 so a single threshold generalizes across issues. Ground truth structure. CATM-mined files enter the training signal not as an auxiliary recall term but through the ground-truth set itself. For each issue x, the reward’s target set is (x)=patch(x)∪f∈ℒ(x):wf≥0.15G(x)=G_patch(x)∪\f (x):w_f≥ 0.15\, where patch(x)G_patch(x) are SWE-Bench gold-patch files and ℒ(x)L(x) is the CATM-mined set. The weights act as a noise filter; every surviving file is a hard positive in the FβF_β reward, on equal footing with patch files. Line ranges from the patch are used as an auxiliary scoring input for v1v_1/v2v_2 and dropped in v3v_3 (§3.5). The pipeline yields 31,97731,977 effective training samples (47.7%47.7\% retention); the discarded remainder is dominated by misdirected reads and documentation lookups, confirming that judge filtering is necessary. 3.5 Reward Design and Three Iterations Let x be an issue and (x)P(x) the file set predicted by a rollout. The target (x)G(x) is the CATM merge (§3.4). Component scores. Two precision-biased FβF_β statistics (β=0.5β=0.5) appear across the iterations. File-level Fβfile(f,f)F_β^file(P_f,G_f) is a standard FβF_β over predicted and target files (with the natural degenerate cases: 11 if both are empty, 0 if exactly one is empty). The precision bias mirrors the downstream constraint: false positives pollute the agent’s context (§4.3), while a miss is usually recoverable. Line-range Fβlr(r,r)F_β^lr(P_r,G_r) is defined analogously, but matching predicted against gold ranges: a prediction p matches a gold g iff they share a filename and p covers at least 50%50\% of g; matching is greedy and one-to-one. Under merge mode, predicted ranges for CATM-only files are dropped before scoring. The FβF_β formula, edge cases, and matching algorithm are in Appendix B. Rollout-level efficiency signal. Let CtotalC_total be the total tool calls a rollout issues and T its number of turns. The average tool calls per turn is c¯:=Ctotal/T(T≥1, 0≤c¯≤8), c\;:=\;C_total/T (T≥1,\ 0≤ c≤8), (3) with the 88 from the per-turn parallel-call budget (§3.2). We treat c¯=4 c=4 as the natural saturation point. Iteration v1v_1: reward-layer efficiency scaling. Average the two component scores and multiply by a reward-level efficiency scale: Rv1=12(Fβfile+Fβlr)⋅σv1(c¯) \ R^v_1= 12 (F_β^file+F_β^lr )·σ^v_1( c)\ (4) σv1(c¯)=1max(1,c¯/4)∈(0,1].σ^v_1( c)= 1 (1,\; c/4)∈(0,1]. (5) σv1σ^v_1 is piecewise: no penalty for c¯≤4 c≤ 4, a 1/(c¯/4)1/( c/4) discount above. Trained v1v_1 checkpoints exhibit two coupled failure modes: policy drift is elevated and per-instance downstream efficiency is negligible. Section 5.2 provides the numerical diagnosis. Iteration v2v_2: move scaling to the advantage layer. Keep the base score, drop the reward-level scale to a hard mask on degenerate rollouts, and move the discount into the GRPO advantage estimator: Rv2=12(Fβfile+Fβlr)⋅c¯>0 \ R^v_2= 12 (F_β^file+F_β^lr )·1_ c>0\ (6) Aiv2=Ai⋅s(c¯i),s(c¯)=min(c¯/4,1). \ A^v_2_i=A_i· s( c_i)\ , s( c)= ( c/4,1). (7) The square root softens the discount: rather than penalizing low-c¯ c rollouts linearly, s(c¯)s( c) preserves a non-trivial fraction of the gradient signal even at c¯=1 c=1 (s=0.50s=0.50), while flattening once c¯ c passes the half-budget saturation point c¯=4 c=4 (s=1s=1). Two properties motivate the split: (i) the group ranking of raw rewards is preserved so GRPO’s intra-group comparison stays anchored to task performance; (i) the discount applies at the gradient step for a specific rollout, not to other group members’ rewards. v2v_2 resolves the drift symptom but develops a new one (length exploitation), taken up in §5.2. Iteration v3v_3: remove line-range from the base reward. Drop the line-range component entirely: Rv3=Fβfile(f,f)⋅c¯>0 \ R^v_3=F_β^file(P_f,G_f)·1_ c>0\ (8) with the same s(c¯)s( c) advantage scaling (Eq. 7). Rationale: (i) Interface mismatch: the downstream editor has no view_range argument, so predicted line ranges are dead information at inference time. (i) Systematic label bias: CATM-only entries have no gold line ranges by construction, so Fβlr=0F_β^lr=0 for a large fraction of training data. The concurrent Cognition system Pan et al. (2025) retains a line-range term; a component-level comparison (Appendix B, Table 6) is necessarily partial as their reward formulation is not fully disclosed. Table 1 summarizes our three iterations. Table 1: Summary of the three reward-design iterations. All variants share the same target G and c¯ c signal (Eq. 3). Component v1v_1 v2v_2 v3v_3 Base task score 12(Fβfile+Fβlr) 12(F_β^file+F_β^lr) =v1=v_1 βfileF_β^file Reward-layer scale 1max(1,c¯/4) 1 (1, c/4) c¯>01_ c>0 c¯>01_ c>0 Advantage-layer scale — s(c¯)s( c) =v2=v_2 3.6 Training Recipe We train CodeGrep with GRPO on top of ms-swift Zhao and others (2024) on a single 8×8×B200 node, using LoRA Hu et al. (2022) plus optimizer offload and vLLM-colocated rollout to fit the 1414B run on one node. End-to-end wall-clock is ∼27 \!27 hours per run; we early-stop at step 897897 of a planned 20002000-step budget. Full hyperparameters (LoRA rank, batch/rollout config, LR schedule, sampling) are in Appendix A.4. Training dynamics. Fig. 2 tracks reward, KL-to-reference, and average rollout length across v1v_1/v2v_2/v3v_3. Three signatures stand out: v3v_3 converges highest on reward (0.600.60–0.650.65 vs. 0.450.45–0.480.48 for v1v_1/v2v_2); v1v_1’s KL drifts to ∼0.31 \!0.31 by step 900900 while v2v_2/v3v_3 stay at 0.090.09/0.150.15; average tool-use turns drop to ∼2.1 \!2.1 under v3v_3 and remain there, while v1v_1/v2v_2 rebound to ∼2.6 \!2.6 after step 500500. Together these are the training-side evidence for the reward-design principles unpacked in §5.2. Additional diagnostics (completion length, gradient norm, clipping ratio) are in Appendix D. Figure 2: Training dynamics of the three reward-design iterations. (a) Reward: v3v_3 climbs faster and levels off higher; v1v_1 and v2v_2 plateau together. (b) KL-to-reference: v1v_1’s reward-layer scaling drives KL to ∼0.31 \!0.31; v2v_2/v3v_3 hold at 0.090.09/0.150.15. (c) Tool-use turns: v3v_3 stabilizes at ∼2.1 \!2.1; v1v_1 and v2v_2 rebound to ∼2.6 \!2.6 after step 500500. 4 Experiments 4.1 Setup We evaluate on SWE-Bench Verified Jimenez et al. (2023) (500500 instances), using OpenHands Wang and others (2024) with Qwen3-30B-A3B-Instruct-2507 Yang and others (2025) as the downstream agent (temperature 0, 100100-round max). We report resolve rate plus efficiency measures (average rounds and total tokens on resolved instances; average rounds on unresolved). Without any retrieval, this baseline resolves 25.8%25.8\% of instances at 23.023.0 rounds and 631631K tokens per resolved issue—within one standard deviation of the publicly reported 25.2±0.7%25.2± 0.7\% for the same configuration Nebius AI (2025), reproducing the reference number all subsequent comparisons anchor to. We compare six configurations: baseline, BM25 (Appendix E), Jina-1.5B Jina AI (2024) (dense embedding retriever), and the three CodeGrep iterations v1v_1/v2v_2/v3v_3. Each retriever is evaluated first on its own retrieval quality (§4.2), then on downstream injection (§4.3). 4.2 Retrieval evaluation The internal evaluation set is constructed from held-out swe-rebench instances with CATM-mined labels, subsequently audited by senior software engineers on our team to filter cases in which the LLM judge over-accepts marginally-relevant reads. Each retriever is scored with FβF_β (β=0.5β=0.5), together with file-level precision and recall. We choose β<1β<1 because a false positive (an irrelevant file injected into the downstream agent) is more costly than a false negative: the former inflates the agent’s context and dilutes attention with distractor code, whereas the latter can often be recovered by the agent’s own tool calls. Table 2 consolidates the five retrievers. Table 2: Retrieval quality on the internal evaluation set. The “Turns” column is specific to the agentic retriever and does not apply to non-agentic baselines. Retriever FβF_β mean FβF_β median Precision Recall Fβ≥0.8F_β≥ 0.8 Turns BM25 0.3590.359 0.4550.455 0.3750.375 0.3860.386 7.0%7.0\% – Jina-1.5B 0.4270.427 0.5000.500 0.4450.445 0.4680.468 7.0%7.0\% – CodeGrep v1v_1 0.5620.562 0.5560.556 0.6410.641 0.4860.486 36.7%36.7\% 3.83.8 CodeGrep v2v_2 0.5260.526 0.5560.556 0.5890.589 0.4830.483 31.7%31.7\% 2.92.9 CodeGrep v3v_3 0.5760.576 0.7140.714 0.6770.677 0.4350.435 43.0%43.0\% 2.32.3 Three observations follow. (i) CodeGrep dominates both BM25 and Jina, with the gap driven primarily by precision. v3v_3’s mean FβF_β is 1.6×1.6× BM25’s and 1.35×1.35× Jina’s, and the three retrievers form a strict precision ordering: BM25 (0.3750.375) << Jina (0.4450.445) << CodeGrep v3v_3 (0.6770.677). The gap is even more pronounced in the tail: CodeGrep v3v_3 produces high-quality retrievals (Fβ≥0.8F_β≥0.8) on 43.0%43.0\% of instances, a 6.1×6.1× increase over both BM25 and Jina (each at 7.0%7.0\%)—the injection regime that matters most for downstream token savings. (i) Among CodeGrep variants, v3v_3 Pareto-dominates on both quality and cost. Median FβF_β improves to 0.7140.714 (+28%+28\% over v1v_1 and v2v_2), the Fβ≥0.8F_β≥0.8 rate reaches 43.0%43.0\% (+36%+36\% relative to v2v_2), and the mean turn count decreases monotonically along the iteration sequence 3.8→2.9→2.33.8→ 2.9→ 2.3. (i) v1v_1 and v2v_2 are quality-comparable in aggregate. Their median FβF_β coincide at 0.5560.556 and their recall values differ by less than 0.0030.003; the mean FβF_β gap (0.5620.562 vs. 0.5260.526) is consistent with v2v_2’s advantage-layer efficiency signal (§5.2) trading a small amount of retrieval quality for a substantially more stable training run (§3.5). The line-range component does not impede file localization; rather, it consumes optimization capacity along a direction the downstream agent never consumes (§5.2). 4.3 Downstream evaluation We now inject each retriever’s output into the frozen OpenHands agent and evaluate end-to-end. Table 3 consolidates the six configurations. Table 3: Downstream comparison of the baseline, BM25 top-22, Jina-1.5B top-22, and CodeGrep v1v_1/v2v_2/v3v_3 on SWE-Bench Verified. Efficiency columns (Resolved r., Resolved tok., Unresolved r.) are averaged over each configuration’s own resolved / unresolved set. Config Resolve Resolved r. Resolved tok. Unresolved r. Baseline 25.8%25.8\% 23.023.0 631631K 32.032.0 BM25 25.2%25.2\% 22.922.9 763763K 29.729.7 Jina-1.5B 25.8%25.8\% 23.223.2 587587K 27.827.8 CodeGrep v1v_1 27.0%27.0\% 22.722.7 627627K 26.226.2 CodeGrep v2v_2 26.6%26.6\% 21.421.4 584584K 26.426.4 CodeGrep v3v_3 27.0%27.0\% 19.619.6 514K 27.527.5 Four observations follow. (i) v3v_3 delivers a small but reproducibly positive resolve-rate lift alongside a much larger efficiency dividend. Resolve rate lifts +1.2+1.2p (25.8%→27.0%25.8\%→ 27.0\%), while resolved rounds drop 23.0→19.623.0→ 19.6 (−15%-15\%) and resolved tokens 631631K→514→ 514K (−19%-19\%). (i) BM25 injection degrades downstream. Resolve drops 0.60.6p and resolved tokens inflate 21%21\% (631631K→763→ 763K); within the 9494 instances both configs resolve, BM25 rollouts spend 6.6%6.6\% more rounds and 38.6%38.6\% more tokens. (i) Jina injection is roughly neutral. Resolve rate is identical to baseline (25.8%25.8\%) and resolved tokens drop 7%7\% (631631K→587→ 587K)—a modest efficiency shift with no resolve lift, placing Jina between BM25 and CodeGrep. (iv) v1v_1 matches v3v_3’s resolve rate but not its efficiency. v1v_1 hits 27.0%27.0\% resolve but only −1.3%-1.3\% rounds and −0.6%-0.6\% tokens—essentially flat; v2v_2 sits between, reaching 26.6%26.6\% resolve with −7%-7\% rounds and −7%-7\% tokens. 5 Analysis We now unpack two non-obvious patterns visible across Tables 2–3: (i) how retrieval quality translates to downstream utility via a precision threshold, and (i) how the three reward iterations induce three qualitatively distinct downstream regimes. A methodological caveat on efficiency accounting follows in §5.3. 5.1 From retrieval quality to downstream utility: a precision threshold A joint reading of Tables 2 and 3 reveals that retrieval quality does not translate linearly into downstream utility. Instead, we observe a monotone precision gradient partitioned into three regimes. (i) Below threshold, retrieval hurts. BM25, at file-precision 0.3750.375, lowers resolve rate by 0.60.6p and inflates resolved tokens by 21%21\% relative to baseline; restricted to the 9494 instances both configurations resolve, BM25 rollouts spend 6.6%6.6\% more rounds and 38.6%38.6\% more tokens. Low-precision candidates function as distractors from which the agent must recover. (i) Near threshold, injection is roughly neutral. A dense embedding retriever (Jina-1.5B) at precision 0.4450.445 leaves the resolve rate at baseline (25.8%25.8\%) and yields only a modest efficiency shift (−7%-7\% resolved tokens). The direction of change is consistent with CodeGrep, but the magnitude is an order of magnitude smaller: a moderately better retriever than BM25 is insufficient to unlock a downstream dividend. (i) Above threshold, marginal quality gains are absorbed by rollout efficiency. Both CodeGrep variants already lift resolve rate above baseline (§4.3); comparing further along the CodeGrep axis, v2→v3v_2→ v_3 improves median FβF_β by +28%+28\% (0.556→0.7140.556→ 0.714) and the Fβ≥0.8F_β≥0.8 rate by +36%+36\%, yet the resolve rate advances by only +0.4+0.4p while resolved rounds and tokens fall 8%8\% and 12%12\% respectively. Once the retriever is precise enough to be net-useful, additional precision no longer expands the resolvable set; it is absorbed as rollout compression. Two mechanisms are consistent with this gradient: (a) file localization is not the binding bottleneck on resolve rate—the downstream agent already recovers much of the task-relevant context through its own grep/view tools on the instances it can resolve, and on the instances it cannot, the failure is typically in patch synthesis rather than in locating the right files; sharper retrieval therefore compresses rollouts rather than enlarging the resolvable set; (b) the marginal harm of a false positive is comparable in magnitude to the marginal benefit of a true positive, so a low-precision retriever can be net-negative in aggregate. Takeaway. Retrieval quality translates to downstream performance through a precision threshold rather than a linear payoff. The three data points—BM25 (0.3750.375, hurts), Jina (0.4450.445, neutral), and CodeGrep (0.6770.677, buys efficiency)—trace a monotone gradient, placing the transition from neutral to net-positive somewhere between precision 0.450.45 and 0.680.68. Whether the exact threshold transfers to other downstream agents remains open (§7). 5.2 Reward iterations: three failure modes, three regimes We now unpack the failure modes underlying the reward transitions introduced in §3.5. Evidence is drawn from the training curves (Fig. 2, Appendix D) and Tables 2–3. v1→v2v_1→ v_2: reward-layer scaling destabilises training and fails to translate into downstream efficiency. (i) Distorted advantage estimates. GRPO advantages are group-relative, so multiplicative scaling on the reward reshapes intra-group variance and distorts the sign structure of the resulting advantage estimates. The observable consequence is a tripled policy drift: v1v_1’s KL divergence to the reference policy reaches ∼0.31 \!0.31 by step 900900 (Fig. 2b), 3.4×3.4× that of v2v_2 (∼0.09 \!0.09). (i) Higher inference cost. v1v_1 requires 3.83.8 mean turns per inference, 1.65×1.65× v3v_3’s 2.32.3. (i) Downstream efficiency does not materialise. v1v_1 matches v3v_3’s 27.0%27.0\% resolve rate but achieves only −1.3%-1.3\% rounds and −0.6%-0.6\% tokens relative to baseline, versus −15%-15\% and −19%-19\% under v3v_3. v2→v3v_2→ v_3: fixing drift exposes length exploitation. (i) Win: v2v_2’s final KL settles at ∼0.09 \!0.09 (Fig. 2b), roughly one-third of v1v_1’s. (i) New failure mode: mean completion length peaks near ∼2000 \!2000 tokens around steps 400400–500500 (Fig. 4a), with a clipping ratio approaching 20%20\%; advantage-layer scaling implicitly rewards long completions whose token totals happen to score well. (i) No net retrieval-quality gain: the file-level FβF_β mean under v2v_2 is 0.5260.526 against 0.5620.562 under v1v_1; the reward-side stability improvement is expended on completion length rather than file localization. v3v_3 closes the loop. Removing FβlrF_β^lr eliminates a signal that has no downstream consumer (the code editor takes no line ranges) and that is systematically zero on CATM-only entries. Under matched hyperparameters, v3v_3 converges higher and faster on reward (Fig. 2a: 0.600.60–0.650.65 vs. 0.450.45–0.480.48), stabilises rollout turns at ∼2.1 \!2.1 (Fig. 2c, from ∼3.5 \!3.5), and delivers the headline downstream gains reported in §4.3. 5.3 Pooled vs. paired-instance efficiency The efficiency numbers in Table 3 are pooled over each configuration’s own resolved set (baseline 129129, v3v_3 135135), so they mix a genuine efficiency effect with a selection effect. Restricting to the 9696 instances both configurations resolve, rounds fall 20.1→18.320.1→ 18.3 (−9%-9\%) and tokens 525525K→448→ 448K (−15%-15\%)—preserving 6060–80%80\% of the pooled effect and confirming the improvement as per-issue acceleration. 6 Case Study: Where the Token Savings Come From We complement the aggregate numbers with an action-level trace on a representative issue where injection converts a stalled 7474-action rollout into a 1515-action success. The issue: django-15278. Adding a nullable OneToOneField via migration crashes on SQLite with Cannot add a UNIQUE column: the OneToOneField constructor in django/db/models/fields/related.py sets unique=True unconditionally, forcing a UNIQUE constraint that SQLite forbids on a nullable column. Baseline: 7474 actions, 3.23.2M tokens, no patch. Without a retrieval hint, the frozen agent stalls after 7474 actions: 3535 terminal calls dominated by repo-wide find and grep, 1717 chain-of-thought turns, and 1818 file-editor operations touching 1313 unique files, none of which contains the fix. Its first 1818 tool calls (Table 8 in Appendix F) expose the failure mode: the agent searches for oauth2—a token from the issue’s third-party reproducer, absent from Django itself—inspects tests/migrations/test_state.py for a related test, and eventually attempts an edit in django/db/migrations/operations/fields.py, which controls how AddField runs rather than why OneToOneField declares itself unique. Injection: 1515 actions, 307307K tokens, patch passes. The injected <retrieved_context> lists three candidate files, including related.py. The same agent deliberates for five turns, opens related.py at action 66, greps for OneToOneField at action 88 to locate the class definition, applies a minimal edit at action 1212 conditioning unique=True on null=False, and calls finish at action 1414. Result: one workspace file touched, 10×10× fewer tokens, patch passes the harness. CodeGrep does not supply the fix—the agent still greps to locate the exact definition. Instead, it compresses the exploratory prefix the frozen agent otherwise burns on repository-wide find/grep sweeps for issue-prose tokens that never appear in the codebase. This prefix is where the token savings originate. 7 Limitations and Future Work CodeGrep’s contribution is concentrated on rollout cost, not resolve rate; a natural next step is end-to-end co-training against a downstream resolve-rate signal, testing whether retrieval can be made to buy both efficiency and effectiveness. 8 Conclusion We introduced CodeGrep, an open 1414B RL-trained agent-style code retriever. Injected into a frozen OpenHands downstream agent, it lifts SWE-Bench Verified resolve rate by +1.2+1.2p and cuts 15%15\% of rounds and 19%19\% of tokens on resolved instances. Our study surfaces a precision threshold governing when retrieval helps downstream, and—in our training setting—identifies the advantage layer, not the reward layer, as the appropriate site for efficiency signals in GRPO-style multi-turn training. All artifacts (model, training pipeline, RL environment, evaluation harnesses) will be released. References Anthropic (2025) Claude Code: anthropic’s official CLI for Claude. Note: https://w.anthropic.com/claude-codeAnthropic product page and documentation. Cited by: §1. Z. Feng, D. Guo, D. Tang, N. Duan, X. Feng, M. Gong, L. Shou, B. Qin, T. Liu, D. Jiang, and M. Zhou (2020) CodeBERT: a pre-trained model for programming and natural languages. Findings of EMNLP. Cited by: §1, §2. D. Guo, S. Lu, N. Duan, Y. Wang, M. Zhou, and J. Yin (2022) UniXcoder: unified cross-modal pre-training for code representation. Annual Meeting of the Association for Computational Linguistics (ACL). Cited by: §2. D. Guo, S. Ren, S. Lu, Z. Feng, D. Tang, S. Liu, L. Zhou, N. Duan, A. Svyatkovskiy, S. Fu, M. Tufano, S. K. Deng, C. Clement, D. Drain, N. Sundaresan, J. Yin, D. Jiang, and M. Zhou (2021) GraphCodeBERT: pre-training code representations with data flow. International Conference on Learning Representations (ICLR). Cited by: §1, §2. E. J. Hu, Y. Shen, P. Wallis, Z. Allen-Zhu, Y. Li, S. Wang, L. Wang, and W. Chen (2022) LoRA: low-rank adaptation of large language models. International Conference on Learning Representations (ICLR). Cited by: §3.6. C. E. Jimenez, J. Yang, A. Wettig, S. Yao, K. Pei, O. Press, and K. Narasimhan (2023) SWE-bench: can language models resolve real-world github issues?. arXiv preprint arXiv:2310.06770. Cited by: §1, §4.1. B. Jin, H. Zeng, Z. Yue, D. Wang, H. Zamani, and J. Han (2025) Search-R1: training LLMs to reason and leverage search engines with reinforcement learning. arXiv preprint arXiv:2503.09516. Cited by: §2. Jina AI (2024) Jina Code Embeddings 1.5B: a multilingual code embedding model. Note: https://huggingface.co/jinaai/jina-code-embeddings-1.5b Cited by: §1, §2, §4.1. X. Li, H. Zou, and P. Liu (2025) ToRL: scaling tool-integrated RL. arXiv preprint arXiv:2503.23383. Cited by: §2. Nebius AI (2025) OpenHands trajectories with Qwen3-coder-480b on SWE-bench verified. Note: https://nebius.com/blog/posts/openhands-trajectories-with-qwen3-coder-480bPublic release of ∼ 67K OpenHands agent trajectories and baseline numbers on SWE-Bench Verified. Cited by: §2, §3.4, §4.1. A. Örwall (2024) Moatless tools: a framework for LLM-assisted code editing. Note: https://github.com/aorwall/moatless-tools Cited by: §2. B. Pan, C. Baronio, A. Tam, P. Marsella, M. Jain, D. Chiu, Swyx, and S. Alberti (2025) Introducing SWE-grep and SWE-grep-mini: RL for multi-turn, fast context retrieval. Note: https://cognition.ai/blog/swe-grepCognition AI blog post; commercial product overview. Cited by: Appendix B, Table 6, §2, §3.5. S. Robertson and H. Zaragoza (2009) The probabilistic relevance framework: BM25 and beyond. Foundations and Trends in Information Retrieval 3 (4), p. 333–389. Cited by: §1, §2. T. Schick, J. Dwivedi-Yu, R. Dessì, R. Raileanu, M. Lomeli, L. Zettlemoyer, N. Cancedda, and T. Scialom (2023) Toolformer: language models can teach themselves to use tools. Advances in Neural Information Processing Systems (NeurIPS). Cited by: §2. R. Shao, R. Qiao, V. Kishore, N. Muennighoff, X. V. Lin, D. Rus, B. K. H. Low, S. Min, W. Yih, P. W. Koh, and L. Zettlemoyer (2025) ReasonIR: training retrievers for reasoning tasks. arXiv preprint arXiv:2504.20595. Cited by: §2. Z. Shao, P. Wang, Q. Zhu, R. Xu, J. Song, X. Bi, H. Zhang, M. Zhang, Y. K. Li, Y. Wu, and D. Guo (2024) DeepSeekMath: pushing the limits of mathematical reasoning in open language models. arXiv preprint arXiv:2402.03300. Cited by: §1, §2. X. Wang et al. (2024) OpenHands: an open platform for ai software developers as generalist agents. arXiv preprint arXiv:2407.16741. Cited by: §1, §2, §4.1. Z. Wang, K. Wang, Q. He, L. Zhang, Y. Zheng, X. Zhou, X. Deng, B. Liu, C. Zhang, H. Ji, and M. Li (2025) RAGEN: understanding self-evolution in LLM agents via multi-turn reinforcement learning. arXiv preprint arXiv:2504.20073. Cited by: §2. C. S. Xia, Y. Deng, S. Dunn, and L. Zhang (2024) Agentless: demystifying LLM-based software engineering agents. arXiv preprint arXiv:2407.01489. Cited by: §2. C. Xie, B. Li, C. Gao, H. Du, W. Lam, D. Zou, and K. Chen (2025) SWE-Fixer: training open-source LLMs for effective and efficient GitHub issue resolution. arXiv preprint arXiv:2501.05040. Cited by: §2. A. Yang et al. (2025) Qwen3 technical report. arXiv preprint arXiv:2505.09388. Cited by: §3.2, §4.1. J. Yang, C. E. Jimenez, A. Wettig, K. Lieret, S. Yao, K. Narasimhan, and O. Press (2024) SWE-agent: agent-computer interfaces enable automated software engineering. arXiv preprint arXiv:2405.15793. Cited by: §2. S. Yao, J. Zhao, D. Yu, N. Du, I. Shafran, K. Narasimhan, and Y. Cao (2023) ReAct: synergizing reasoning and acting in language models. International Conference on Learning Representations (ICLR). Cited by: §2. Y. Zhao et al. (2024) Ms-swift: a framework for scalable training and inference of large language models. Note: https://github.com/modelscope/ms-swift Cited by: §3.6. Y. Zhou, S. Dai, C. Qu, L. Pang, J. Xu, and J. Wen (2026) Learning to retrieve from agent trajectories. arXiv preprint arXiv:2604.04949. Cited by: Table 4, §2, §3.4, §3.4. Appendix A Infrastructure Details This appendix preserves the complete engineering realization of the RL environment (§3.3) and the CATM pipeline (§3.4). A.1 RL Environment Implementation Figure 3: Three-layer RL environment. Layer 1 extracts unique (repo, commit) pairs; Layer 2 uses git clone --bare and git worktree add to share the .git object database across commits; Layer 3 executes grep/glob/read through native subprocesses with safety guards. The right-hand sidebar compares against a Docker sandbox. A rollout begins with the model emitting up to eight parallel grep/glob/read tool calls, which the sandbox executes concurrently inside the target worktree. Their responses are appended to the conversation with a loss mask of zero, so that only the tokens generated by the model itself contribute to the gradient. The model then sees the accumulated context and emits either the next round of tool calls or a final <answer> block. The rollout terminates when the model produces an answer, when no tool call is generated, when the completion budget is exhausted, or after the configured maximum of four turns (33 exploration +1+1 answer, matching §3.2). Layer 2 engineering. A single bare repository (e.g. _bare/django__django/) holds the shared .git object database, and each target commit is materialized as a lightweight worktree (django__django__abc12345/, ..._def67890/, etc.). The initial git clone --bare is a one-time network operation guarded by a 600600-second timeout, and every subsequent git worktree add is a local file-system operation completing in milliseconds. To make the clone pipeline robust in the presence of private repositories or unusual GitHub configurations, we disable interactive prompts with GIT_TERMINAL_PROMPT=0 and GIT_ASKPASS=echo, fall back from fetch <commit> to fetch --all when a commit is not directly fetchable, and pre-validate every commit’s existence with git cat-file -e <commit> before invoking worktree add. Layer 3 engineering. The tool executor (swe_grep_tools.py) canonicalises every argument path and refuses any access that escapes the repository root. A global asyncio semaphore (Semaphore(64)) caps the number of concurrent subprocesses; per-tool timeouts (10s for grep and glob, 5s for read) shield the rollout from pathological queries. Tool outputs are truncated to 40964096 characters, with 5050 matches per grep and 200200 lines per read, so that a single call cannot exhaust the context window. All searches use the native grep -rn --include=*.py ... rather than a pure-Python implementation, gaining roughly an order of magnitude in throughput. Rollout scheduler. SweGrepScheduler is a subclass of ms-swift’s MultiTurnScheduler. It maintains state across turns, masks tool responses out of the loss, injects the correct worktree path per rollout, and dispatches early termination. In total the class is roughly 400400 lines of Python. A.2 CATM Pipeline Implementation Table 4: Comparison of CATM (ours) with LRAT Zhou et al. (2026). Dimension LRAT CATM (ours) Target scenario Web retrieval (Wikipedia QA) Code retrieval (SWE-Bench) Action pattern Sequential, 11 browse per turn Parallel, up to 88 reads per turn Reasoning attribution One reasoning trace per document (one-to-one) One reasoning trace shared across N parallel reads (one-to-many) Sample granularity One (query, doc) pair per browse; many pairs per trajectory One (issue, filtered file set) per trajectory Judge model Qwen3-30B-A3B-Thinking-2507 GLM-5.1-FP8 Data scale 9191K pairs from 2626K trajectories 3232K samples from 6767K trajectories (47.7%47.7\% retention) Training method Weighted InfoNCE (dense retriever) GRPO (multi-turn tool-calling RL) Stage 1. For each trajectory we traverse the message stream, identify role="assistant" messages containing tool_calls, and extract command="view" operations along with their target paths. We auto-detect the repository prefix (/workspace/owner__repo__commit/) and normalize to repo-relative paths. After a view we skip over any subsequent role="tool" messages and locate the next role="assistant" message, whose content is recorded as the file’s post-reasoning. If a file is viewed multiple times, we keep the instance with the longest post-reasoning. Stage 2. We use GLM-5.1-FP8 as the judge, prompted with the file path, the post-reasoning, and the task description. The judge returns either RELEVANT or NOT_RELEVANT; when the model output is ambiguous we default conservatively to RELEVANT. The judge runs with 1616 parallel worker threads under a 6060-second per-call timeout, and the pipeline is resumable by checkpointing processed instance IDs to disk with real-time flushing (append mode). End-to-end the judge stage completes in about five hours. Stage 3. The global constants β (the median post-reasoning length across all mined candidates) and μraw _raw (the mean of the unnormalized weights over the whole dataset) require two passes over the data: the first estimates them; the second assigns per-file weights via Eq. (2). Files with w<0.15w<0.15 are discarded. A.3 Key Engineering Numbers Table 5 lists the salient scale parameters and throughput figures for both the environment and the data pipeline. Table 5: Key engineering scale and throughput. Item Value Environment: unique (repo, commit) pairs ∼ (after dedup) Environment: disk saving (bare + worktree) N×repo_size→repo_size+N×worktreeN\!×\!repo\_size \_size+N\!×\!worktree Environment: tool concurrency cap 6464 (asyncio semaphore) Environment: max parallel tools per turn 88 Environment: max tool execs per rollout 3232 (44 turns × 88) Data: raw trajectories 67,07467,074 Data: judge model GLM-5.1-FP8 (1616-way parallel) Data: judge thresholds reasoning_tokens ≥30≥ 30, w≥0.15w≥ 0.15 Data: effective training samples ,31,977 (47.7%47.7\% retention) Data: judge stage runtime ∼ 5 hours Training: total wall-clock 2727 hours (8×8× B200) A.4 Training Configuration We train CodeGrep with GRPO on ms-swift on a single 8×8×B200 node. Parameter-efficient fine-tuning. LoRA (rank 3232, α=64α=64) is applied to all linear projections of the 1414B backbone; the base model weights stay frozen. Optimizer and model states are offloaded to CPU when idle, and training and rollout share GPUs via vLLM’s colocated mode (tensor-parallel 88, 35%35\% of GPU memory allocated to the vLLM engine, prefix caching on). Optimization. Peak learning rate 5×10−65×10^-6 with cosine decay and 5%5\% linear warmup; GRPO KL coefficient β=0.02β=0.02. Each step processes 6464 prompts (per-device batch 11, gradient accumulation 88, across 88 GPUs) and samples 88 GRPO rollouts per prompt, for 512512 effective rollouts per step. Rollouts cap at 40964096 generation tokens and 44 tool-use turns (33 exploration +1+1 answer); sampling uses temperature 1.01.0, top-p 0.90.9, top-k 5050. We early-stop at step 897897 of a planned 20002000-step budget when reward improvement plateaus and KL-to-reference stays within safe bounds; end-to-end wall-clock is ∼27 \!27 hours per run. Appendix B Reward Design Details Edge cases for FβfileF_β^file and FβlrF_β^lr. Both scores are precision-biased FβF_β with β=0.5β=0.5, with prec⋅rec/(β2prec+rec)⋅(1+β2)prec·rec/(β^2\,prec+rec)·(1+β^2) as the general formula, plus two degenerate cases: if both predicted and target sets are empty the score is 11; if exactly one is empty it is 0. Line-range matching algorithm. Each answer emits a list of line ranges rP_r of the form (filename,start,end)(filename,start,end). The target set rG_r comes from the SWE-Bench gold patch (patch files only). A predicted p matches a gold g iff: (a) p.filename=g.filenamep.filename=g.filename; and (b) |[p.s,p.e]∩[g.s,g.e]|/(g.e−g.s+1)≥0.5|[p.s,p.e]∩[g.s,g.e]|/(g.e-g.s+1)≥ 0.5. Matching is greedy over rP_r and each side consumes at most one match: iterating predictions in order, each pairs with the first still-unpaired gold range it overlaps; both are then removed from further consideration. TPTP is the number of matched pairs; prec=TP/|r|prec=TP/|P_r|, rec=TP/|r|rec=TP/|G_r|. Under merge mode, we drop from rP_r any predicted range whose filename is a CATM-only file before scoring (such files have no gold range to match against, and would otherwise appear as unrecoverable false positives). On merge mode and the “no CATM recall bonus” choice. In principle the pipeline supports an auxiliary CATM-recall term with a mixing weight α∈[0,1]α∈[0,1] that would blend the base task score with a soft weighted recall over CATM files. Under merge mode this branch is inactive (α=0α=0), because every surviving CATM file is already inside G and contributes to FβfileF_β^file directly. Keeping α=0α=0 makes the three iterations cleanly comparable: they differ only in how task and efficiency signals are combined. Contrast with concurrent work. Cognition’s concurrent commercial system Pan et al. (2025) describes its reward as “an average of weighted F1 scores over file retrieval and line retrieval tasks” with advantages scaled “by the average number of tool calls used per turn.” Their blog does not specify β, the line-range matching rule, the tool-scale functional form, or the training data pipeline, so a component-level comparison is partial by necessity. The most consequential difference is our v3v_3’s removal of the line-range term. Its outcome (higher final reward, Fig. 2a; more stable rollouts, Appendix D; 19%19\% downstream token reduction, §4.3) suggests the line-range signal is not universally beneficial. We conjecture the driver is the downstream tool interface: agents whose editor consumes line ranges (plausibly Windsurf’s Cascade) may benefit; agents whose editor operates on full files (OpenHands, Cursor) will not, and the extra reward dimension becomes a training-time distractor. Table 6: Reward-design comparison with concurrent commercial work Pan et al. (2025). Their blog describes a single final configuration; where a component’s mathematical form is not disclosed in the blog we mark it n/s (not specified). We list our final (v3v_3) configuration. Reward component Cognition SWE-grep This work (v3v_3) File-score β (precision bias) Precision-biased (β not specified) β=0.5β=0.5 (precision-biased) Line-range scoring rule n/s (“F1 over line retrieval”) Jaccard with ≥50%≥ 50\% overlap → Fβ=0.5F_β=0.5 Base score composition Avg. of file F1 and line F1 File-only (FβF_β); line-range removed Training data / labels Proprietary; construction not disclosed Open unsupervised CATM pipeline (§3.4) Efficiency signal at reward layer Not described (advantage-layer scaling only) v1v_1: σv1(c¯)=1/max(1,c¯/4)σ^v_1( c)=1/\! (1, c/4); v2v_2/v3v_3: mask only, c¯>01_ c>0 Efficiency signal at advantage layer “Scale by avg tool calls per turn” (functional form n/s) s(c¯)=min(c¯/4,1)s( c)= ( c/4,1) via monkey-patch on GRPO advantage Explicit reward-design study None reported (single final config) v1→v2→v3v_1\!→\!v_2\!→\!v_3, three trained runs (§3.5) Appendix C Positioning: Agent RL vs Traditional RLHF For readers coming from RLHF, Table 7 highlights the main structural differences between the setting we work in and standard single-turn preference-based RL. This is a positioning aid rather than a methodological claim, and is included here for context. Table 7: Comparison of traditional RLHF with the Agent RL setting used in this work. Dimension Traditional RLHF Agent RL (ours) Rollout structure Single-turn Multi-turn (up to 88) Action space Single completion Up to 88 parallel tool calls per turn Reward source Human preference model Environment + rule-based FβF_β Ground truth Prompt–response pair Structured multi-signal (patch + trajectory + weights) Environment None Filesystem sandbox with real code execution Loss mask Entire completion Tool responses must be masked out Data-construction cost Low High (judge inference + global β statistics) Appendix D Training Stability Diagnostics Figure 4 reports three additional diagnostics tracked over the same ∼900 \!900-step training run as Figure 2: mean completion length, gradient norm, and the fraction of clipped tokens per batch. The three panels together characterize the training-stability regime of all three reward configurations and complement the reward / KL / rollout picture in the main text. The completion-length trajectory (a) is the most revealing panel and tells a two-story diagnostic. Under v2v_2, mean completion length inflates from roughly 400400 tokens to a peak of ∼2,000 \!2,000 tokens around step 400400–500500 before slowly retreating, and the completion clipping ratio (c) peaks near 20%20\% during the same window—clear evidence that v2v_2’s advantage-layer scaling implicitly rewards relatively short-and-well-scoring completions within a group in a way that also permits long-completion excursions, opening a length-exploitation channel. v1v_1 shows a milder version of the same inflation (peak ∼880 \!880 smoothed / ∼1500 \!1500 raw around step 300300–400400) but recovers earlier, consistent with its reward-layer scaling directly penalising long-completion / high-turn rollouts on the reward side. v3v_3 removes the line-range component and stays near ∼300 \!300–400400 throughout, with clipping ratio consistently below 5%5\%. Gradient norms (b) remain bounded throughout for all three runs, with a single brief excursion near step 400400 under v1v_1 and v2v_2. Taken together, the three configurations trace a clean design trade-off: v1v_1 (reward-layer scaling) contains the length problem but at the cost of policy drift (KL climbing to ∼0.31 \!0.31; Figure 2b); v2v_2 (advantage-layer scaling) controls policy drift but opens the length channel; only v3v_3 (no line-range) resolves both, producing training that is simultaneously the most reward-productive, the shortest, and among the cleanest on clipping. This picture supports our conclusion that v3v_3’s reward is not only more effective on downstream metrics (§4.3) but also structurally the most stable during training. Figure 4: Training-stability diagnostics over the same ∼900 \!900 GRPO steps as Figure 2, for all three reward iterations. (a) Mean completion length: v2v_2 inflates dramatically (smoothed peak ∼1,150 \!1,150 tokens near step 450450; raw peak ∼2000 \!2000), v1v_1 shows a milder mid-training bump, and v3v_3 stays near 300300–400400 throughout. (b) Gradient norms remain bounded throughout for all three. (c) Completion-clipping ratio mirrors the length curve: v2v_2 peaks at ∼20% \!20\%, v1v_1 at ∼14% \!14\%, and v3v_3 stays below 6%6\% throughout. Appendix E BM25 Baseline Configuration This appendix documents the BM25 baseline used for both the retrieval-quality comparison in Table 2 and the downstream-injection comparison in Table 3, so that both are fully reproducible. Corpus. For each SWE-Bench-Verified instance we index the target repository’s application Python files. We skip __pycache__/, virtual-environment directories (venv/, .venv/, env/), and build artefacts (build/, dist/, .eggs/). Our default includes tests/ and test/ directories in the index; the ablation below shows that excluding them yields nearly identical results. Tokenization. Documents and queries are tokenized identically: split on whitespace, strip characters outside [a-zA-Z0-9_./], lower-case, drop tokens shorter than 22 characters, drop tokens beginning with http (URL fragments in issue text). This is a deliberately simple tokenizer intended to model a “classical BM25” baseline rather than a code-specialized one. BM25 parameters. We use BM25 Okapi with default parameters k1=1.5k_1=1.5 and b=0.75b=0.75 (the rank_bm25 library defaults). We did not tune these on the evaluation set to avoid overfitting. Path signal. We initially expected a file-path signal to help, since SWE-Bench issue reports frequently mention directory or file-name fragments (e.g. “django admin form”, “the ec2 metadata module”). We therefore built a second BM25 index over file-path tokens and added its scores to the content BM25 scores with a 2×2× weight. Empirically this augmentation had no measurable effect: the path-augmented variant (B) and the content-only variant (A) produce identical mean FβF_β on our evaluation set. The reason is that our tokenizer preserves the path separators . and / within tokens, so file-path fragments already appear as long tokens inside the content index. We report variant B as our default for clarity, but the finding is that a simple BM25 over tokenized code content already captures the effect a naive path-aware BM25 could offer. Top-K selection. We report BM25 at K=2K=2 as the default because it approximately matches CodeGrep v3v_3’s mean output length of 1.311.31 files. Larger K is not free: injecting more candidate files into the agent’s prompt inflates the per-rollout context. On retrieval quality, top-22 achieves FβF_β mean 0.3590.359 (Table 2). For completeness we also measured K=5K=5: it raises recall (each list is longer) at the cost of precision, and on downstream evaluation larger K carries the additional cost of longer agent-side prompts, producing qualitatively similar downstream failure to help. We report K=2K=2 as the main comparison because it is the fairest apples-to-apples match to CodeGrep’s output cardinality. Test-directory scope. Our default indexes tests/ and test/ directories alongside application code (via the --include_tests flag), maximizing BM25’s fair shot at the ground truth (approximately 36%36\% of evaluation instances have at least one test file in the ground truth). Ablating this filter (i.e., skipping test directories) yields a comparable FβF_β within 0.010.01, indicating that test-directory inclusion neither meaningfully helps nor hurts BM25 on this task. The default configuration is therefore not artificially disadvantaging BM25. Retrieval. At query time, we take the tokenized issue text (the user turn from the eval prompt, which contains the bug report and error trace), compute the combined BM25 score for every indexed file, and return the top-K by score (K=2K=2 by default). Ties are broken by insertion order; if fewer than K files have non-zero score, we still return the top-scoring 11–K as a fallback. Downstream injection. For the downstream evaluation (Table 3), we inject BM25 top-22 predictions into the same OpenHands prompt template used for CodeGrep. Predictions are formatted as a bulleted <candidate_files> block appended to the issue description, byte-identical to the CodeGrep injection format. The agent then executes its standard code-repair loop without any BM25-specific prompting. Scoring. Predicted files are compared against the SWE-Bench gold patch file set using file-level Fβ=0.5F_β=0.5, identical to §4.2. We use forward-slash paths on both sides; any residual path-separator differences are normalized before set-intersection. Runtime. On CPU, indexing and querying the full evaluation set completes in under 1010 minutes on a single machine. Building the index dominates cost; the retrieval step is under 1010 ms per query. The BM25 downstream evaluation on all 500500 SWE-Bench Verified instances completes with the same wall-clock budget as the CodeGrep downstream evaluations described in §4.1. Appendix F Case Study: Action-Level Trajectory Table 8 shows the first 1818 tool calls of the baseline vs. CodeGrep-injected trajectories on django-15278, illustrating the failure mode discussed in §6. Table 8: Action-level trajectory on django-15278. Baseline spends its first 1818 actions searching for oauth2 (a third-party name in the issue) and reading tangential files; CodeGrep injection sends the same agent directly to related.py. Baseline (unresolved, 7474 actions) CodeGrep (resolved, 1515 actions) # Tool Target # Tool Target 1–2 think analyze issue 1–5 think analyze + read hints 3 task plan 6 file_editor related.py 4–9 terminal find | grep oauth2×6× 6 7 think locate OneToOneField 10 think rewrite plan 8 terminal grep OneToOneField 11–14 terminal grep AddField 9 file_editor related.py 15 file_editor tests/.../test_state.py 10–11 think propose fix 16–17 terminal grep -n for line hits 12 file_editor edit __init__ 18 file_editor test_state.py l. 627627 13 think verify 19–20 think propose migration-op fix 14 finish — 21 file_editor operations/fields.py ⋯·s ⋯·s (never converges)