Composer 2 Technical Report

作者/机构: Cursor Research Team

A1 主要贡献

Composer 2 是一款专为代理式软件工程(agentic software engineering)设计的专用模型。该模型在保持高效解决交互式问题的能力的同时,展现出强大的长期规划和编码智能。本文的核心研究目标是通过两阶段训练过程,将一个强大的通用模型特化,使其在代理式编码领域达到前沿水平的性能。

核心问题与研究目标
核心问题是如何通过扩展模型训练来可靠地提升模型在真实世界编码任务上的性能。研究目标是训练一个在软件工程领域具有前沿性能的专用模型,该模型能够处理从简单的交互式编辑到复杂的、长期的工程任务。

创新点与核心贡献
1. 两阶段训练流程:首先通过持续预训练(continued pretraining)来提升模型的基础知识和潜在编码能力,然后进行大规模强化学习(reinforcement learning),通过更强的推理、准确的多步执行以及在长周期现实编码问题上的一致性来提升端到端的编码性能。
2. 最小化训练-测试失配:训练的核心原则是尽可能紧密地模拟真实世界的用户挑战。为此,团队开发了能够在与部署模型相同的 Cursor 工具链(harness)中进行训练的基础设施,使用等效的工具和结构,并在与真实问题高度匹配的环境中进行。
3. 引入CursorBench基准:为了衡量模型在日益困难的任务上的能力,团队引入了一个源自大型代码库(包括其自身代码库)中真实软件工程问题的基准测试——CursorBench。该基准相比公共基准任务更复杂、提示更不明确,更能代表真实世界的软件工程需求。
4. 前沿性能与高性价比:Composer 2 在内部的 CursorBench 评估中取得了61.3分,相比之前的 Composer 模型有重大提升。在公共基准测试中,它在 Terminal-Bench 上获得61.7分,在 SWE-bench Multilingual 上获得73.7分,与最先进的系统相当。同时,由于其专门针对编码能力进行了优化,其服务成本低于最先进模型的API定价,实现了性能与成本的帕累托最优。

图1:Composer 2 相比之前的 Composer 模型有很大改进,实现了与最先进模型相媲美的性能。通过完全专注于编码能力,Composer 在服务成本上低于最先进模型的API定价,同时达到了这样的性能。详细评估见第5节。
图1:Composer 2 相比之前的 Composer 模型有很大改进,实现了与最先进模型相媲美的性能。通过完全专注于编码能力,Composer 在服务成本上低于最先进模型的API定价,同时达到了这样的性能。详细评估见第5节。

A3 背景知识

大语言模型在代码生成领域的应用演进。生成代码已成为大语言模型的一个杰出应用【索引15,Feng等人,Codebert: A pre-trained model for programming and natural languages,EMNLP 2020】【索引9,Clement等人,Pymt5: multi-mode translation of natural language and python code with transformers,EMNLP 2020】【索引7,Chen等人,Evaluating large language models trained on code,arXiv 2021】【索引31,Li等人,Competition-level code generation with alphacode,Science 2022】。代码作为一种丰富的、具有挑战性的训练数据来源,补充了大多数大型模型中的语言数据【索引16,Fried等人,Incoder: A generative model for code infilling and synthesis,ICLR 2023】【索引30,Li等人,Starcoder: may the source be with you!,Trans. Mach. Learn. Res. 2023】【索引36,Lozhkov等人,Starcoder 2 and the stack v2: The next generation,arXiv 2024】【索引51,Rozière等人,Code llama: Open foundation models for code,arXiv 2023】【索引19,Guo等人,Deepseek-coder: When the large language model meets programming–the rise of code intelligence,arXiv 2024】【索引10,DeepSeek-AI,Deepseek-coder-v2: Breaking the barrier of closed-source models in code intelligence,arXiv 2024】【索引5,Allal等人,Santacoder: don’t reach for the stars!,ICML 2023 Workshop】【索引44,Nijkamp等人,Codegen: An open large language model for code with multi-turn program synthesis,ICLR 2023】【索引25,Hui等人,Qwen2.5-coder technical report,arXiv 2024】【索引71,Wang等人,Codet5: Identifier-aware unified pre-trained encoder-decoder models for code understanding and generation,EMNLP 2021】【索引72,Wang等人,Codet5+: Open code large language models for code understanding and generation,EMNLP 2023】【索引62,CodeGemma Team等人,Codegemma: Open code models based on gemma,arXiv 2024】【索引41,Mishra等人,Granite code models: A family of open foundation models for code intelligence,arXiv 2024】。代码生成的早期应用通常集中在自动补全。随后,指令微调将模型转变为能够响应用户请求的编码助手【索引37,Luo等人,Wizardcoder: Empowering code large language models with evol-instruct,ICLR 2024】【索引73,Wei等人,Magicoder: Empowering code generation with OSS-Instruct,ICML 2024】【索引83,Zhuo等人,Parameter-efficient instruction tuning code large language models: An empirical study,ICLR 2025 Workshop】【索引43,Muennighoff等人,Octopack: Instruction tuning code large language models,ICLR 2024】。在过去一年中,软件工程代理获得了广泛采用,推动模型超越聊天功能,能够自主导航代码仓库并解决复杂的工程任务【索引75,Yang等人,Swe-agent: Agent-computer interfaces enable automated software engineering,NeurIPS 2024】【索引76,Yang等人,SWE-smith: Scaling data for software engineering agents,NeurIPS 2025】【索引70,Wang等人,OpenHands: An open platform for AI software developers as generalist agents,ICLR 2025】【索引49,Qian等人,Chatdev: Communicative agents for software development,ACL 2024】【索引23,Hong等人,Metagpt: Meta programming for a multi-agent collaborative framework,ICLR 2023】。

软件工程代理的定义与工作流程。软件工程代理旨在自主行动以解决给定的任务提示。给定一个环境(即一个代码库和一个用于代码执行的隔离容器)以及一个给予代理任务的提示$x$,代理会产生一个包含一系列动作$a_1, \dots, a_T$的执行轨迹(rollout),每个动作会进行一次或多次工具调用并产生响应$y_1, \dots, y_T$。工具调用可能会修改底层环境,而执行轨迹的结果是该环境的最终状态。每个动作$a_i$是通过从语言模型策略$\pi_{\theta}(a_i | x, a_1, y_1, \dots, a_{i-1}, y_{i-1})$中采样来选择的,之后会根据代码的正确性、简洁性以及是否符合软件工程原则来给予奖励。与竞争性编程等更受限的环境相比,一个强大的软件工程代理必须执行非平凡的探索、编写自己的测试,并构建解决任务提示所需的最少更改。

Composer 2的工具集与交互流程。Composer 2 可以使用一小组通用工具,使其能够读写文件、运行shell命令、使用grep或语义搜索来搜索代码库,以及搜索网页。其提示包括系统消息、工具调用格式规范、最近的文件信息、过去的用户消息以及当前任务。这个过程最常见的最终结果是对代码库环境中的文件进行一系列更改,尽管还有许多其他常见的用例,例如回答问题、编写计划、解决版本控制问题或监控长时间运行的作业。

Composer 2的核心研究方向。我们对Composer 2的主要研究重点是探索如何通过扩展模型训练来可靠地提高在真实世界编码任务上的性能。我们通过两个不同的训练阶段来解决这个问题:持续预训练(第3节)和异步强化学习(第4节)。为了衡量进展,我们构建了一套具有挑战性的基准测试(第5节)。

A2 方法细节

3 持续预训练

持续预训练的目标与方法。持续预训练阶段旨在提升语言模型的基础知识,特别是在编码领域。长期以来,这种持续预训练已被证明能显著提高下游任务的性能【索引20,Gururangan等人,Don’t stop pretraining: Adapt language models to domains and tasks,ACL 2020】【索引24,Howard和Ruder,Universal language model fine-tuning for text classification,ACL 2018】。更进一步,近期的模型采用分阶段训练方法,逐步筛选更高质量的数据【索引22,Hoffmann等人,Training compute-optimal large language models,NeurIPS 2022】【索引69,Touvron等人,LLaMA: Open and efficient foundation language models,arXiv 2023】【索引77,Ye等人,Data mixing made efficient: A biannual survey of data mixing for LLM pre-training,arXiv 2024】。虽然我们从本身就用大量代码数据训练的基础模型开始,但我们发现额外的监督学习能够可靠地提高知识基准测试的成绩,并最终提升编码代理的性能。

基础模型的选择。我们使用内部评估和推理性能方面的考量来选择基础模型。我们的评估衡量了内部代码库的困惑度、编码知识和状态跟踪能力。更多细节见附录B。这些评估使我们选择了Kimi K2.5【索引67,Kimi Team,Kimi K2.5: Visual agentic intelligence,arXiv 2026】,一个拥有1.04T参数/32B活跃参数的专家混合(Mixture-of-Experts)模型,作为Composer 2的基础模型。

3.1 训练

三阶段训练流程。我们通过在一个以代码为主的大型数据混合上进行持续预训练来扩展Kimi K2.5。这个阶段的目的是为后续的代理式强化学习(RL)训练提供一个基础模型,通过在编码知识和能力上对模型进行特化。我们将这个阶段分为三个部分。我们在32k令牌序列长度上投入大部分计算资源,随后是一个较短的、将上下文扩展到256k序列长度的长上下文扩展阶段,最后是一个针对特定编码任务的简短监督微调(SFT)阶段。训练使用MXFP8精度在NVIDIA B300s上进行,并采用AdamW优化器。更多训练细节见第6.1节。在训练期间,我们测量了在内部代码库上的评估损失。我们观察到损失在训练过程中呈对数线性下降。

持续预训练与下游RL性能的关系。持续预训练最终是为了提升下游的强化学习(RL)性能,而这两个阶段之间的联系是一个活跃的研究领域。我们通过将我们的持续预训练方法应用于Qwen3-Coder-30B-A3B【索引68,Qwen Team,Qwen3 technical report,arXiv 2025】来研究代码库困惑度与RL性能之间的关系。持续预训练在三个对数间隔的计算水平上进行:小、中、大。这些检查点中的每一个随后都在一个小数据集上进行监督微调(SFT),接着是一个相同的RL运行。图2(左)显示了SFT后的最终损失与固定步数后RL奖励之间的关系,表明交叉熵损失确实可以预测下游的RL性能。

图2:持续预训练能够转化为下游RL性能。左图:我们在一个较小的Qwen模型上研究了这种关系,考察了在不同数量的令牌上训练的检查点。右图:模型训练困惑度稳步下降。
图2:持续预训练能够转化为下游RL性能。左图:我们在一个较小的Qwen模型上研究了这种关系,考察了在不同数量的令牌上训练的检查点。右图:模型训练困惑度稳步下降。

多令牌预测(MTP)层的训练。为了在生产环境中更快地提供模型服务,我们训练了额外的多令牌预测(Multi-Token Prediction, MTP)层【索引17,Gloeckle等人,Better & faster large language models via multi-token prediction,ICML 2024】【索引11,DeepSeek-AI,Deepseek-v3 technical report,arXiv 2024】,以便与推测解码(speculative decoding)配合使用。我们从头开始初始化MTP层,并在相同的数据混合上进行训练。为了加速收敛,我们使用自蒸馏(self-distillation)的方式训练MTP层,教模型在每个位置预测主语言模型头的精确logit分布。为确保这个过程能够泛化,MTP层是在持续预训练中期的一个检查点之上进行训练的。在最后两个阶段(长上下文和SFT)中,MTP层被包含进来,并与模型的其余部分联合训练。

4 强化学习

RL训练任务与环境。Composer 2是通过在一大组编码任务上进行强化学习训练的。这些任务在尽可能模拟真实Cursor会话的环境中运行(基础设施细节见第6.2节)。从宏观上看,RL训练包括采样一个问题,模拟代理针对不同解决方案的一组执行轨迹(rollouts),然后根据解决方案的质量更新模型权重。

训练问题分布。我们创建了一个能反映最常见用例的问题分布。图3显示了按任务类别的细分。值得注意的是,我们的训练分布捕捉了许多流行的人工智能编码基准测试中所缺失的软件工程方面。

图3:RL训练任务。
图3:RL训练任务。

难例上采样策略。在训练的后期阶段,我们使用简单的启发式方法——例如执行轨迹的轮次数量和思考(thinking)令牌数——来上采样越来越难的数据点。

4.1 异步RL训练

异步RL训练框架。我们的强化学习流水线是围绕着在保持稳定性的同时,从大规模策略梯度中学习而构建的。我们使用一种每个提示有多个样本的策略梯度算法【索引53,Shao等人,Deepseekmath: Pushing the limits of mathematical reasoning in open language models,arXiv 2024】【索引2,Ahmadian等人,Back to basics: Revisiting reinforce-style optimization for learning from human feedback in llms,ACL 2024】,并采用固定的组大小。我们在单周期(single-epoch)机制下操作,即同一个提示永远不会被训练两次。我们使用Adam作为底层优化器,并更新全部参数集。RL训练在高度异步的机制下运行,训练工作单元和执行轨迹生成工作单元是独立的(细节见第6.2节)。

策略梯度算法的变体选择。先前的文献中提出了多种策略梯度变体【索引78,Yu等人,DAPO: An open-source LLM reinforcement learning system at scale,NeurIPS 2025】【索引82,Zheng等人,Group sequence policy optimization,arXiv 2025】【索引40,MiniMax,Minimax-m1: Scaling test-time compute efficiently with lightning attention,arXiv 2025】【索引34,Liu等人,Understanding r1-zero-like training: A critical perspective,arXiv 2025】。与Dr. GRPO【索引34】一样,我们发现最小化因转换底层优势(advantage)而可能产生的梯度偏差至关重要。遵循这项工作,我们从GRPO中移除了长度标准化项,因为它会引入长度偏差。我们不对组优势(group advantages)进行标准差归一化,因为这会导致一种退化情况,即在一组所有执行轨迹都达到相同正确性的情况下,微小的行为差异会被极大地加权。

超长序列截断策略。Yu等人【索引78】提出要屏蔽掉超过最大序列长度的执行轨迹。一些后续工作采用了这种屏蔽方法【索引35,Liu等人,Acereason-nemotron 1.1: Advancing math and code reasoning through sft and rl synergy,arXiv 2025】【索引18,Golubev等人,Training long-context, multi-turn software engineering agents with reinforcement learning,arXiv 2025】,而其他工作发现其效果好坏参半。例如,Liu等人【索引34】发现屏蔽过长执行轨迹在长尾推理任务上效果有限,但在中短长度推理任务中能提高响应的准确性和清晰度,而Du等人【索引13】发现过长屏蔽导致输出长度增长过快。我们在小规模实验中没有看到过长屏蔽带来的好处,并选择不屏蔽超过最大序列长度的执行轨迹。我们的自总结系统(下文讨论)在实践中也限制了这些情况的发生。

异步训练的稳定性策略。由于代理的执行轨迹可能非常长,特别是在追求长周期一致性时,我们的系统在高度异步的环境中保持稳定性至关重要。我们的主要策略是最小化样本的离策略(off-policy)程度。在基础设施方面,通过快速的权重同步和运行中权重更新(in-flight weight updates)来减少这种差异,这与PipelineRL【索引48,Piché等人,PipelineRL: Faster on-policy reinforcement learning for long sequence generation,arXiv 2025】类似。推理工作单元能够在执行轨迹中途更新权重,这意味着执行轨迹中后面的令牌可能离策略程度更低。为了进一步减少采样策略和训练策略之间的差异,我们重放了MoE路由【索引38,Ma等人,Stabilizing MoE reinforcement learning by aligning training and inference routers,arXiv 2025】。我们在第6.2节讨论了异步RL流水线的实现。

KL散度正则化与估计器选择。与先前的工作【索引53】【索引66,Kimi Team,Kimi k1.5: Scaling reinforcement learning with LLMs,arXiv 2025】类似,我们使用Kullback–Leibler散度进行正则化,$KL(q \parallel p) = E_{x \sim q}[-\log r(x)]$,其中$r(x) = p(x)/q(x)$。许多开源的RL实现使用Schulman在【索引52,Schulman,Approximating KL divergence,Blog post 2020】中定义的估计器$k_3 = (r - 1) - \log r$来估计KL散度。$k_3$估计器是KL散度的无偏估计量,并且在$p$和$q$接近时能减少方差。然而,Amini等人在【索引6,Amini等人,Better estimation of the kullback–leibler divergence between language models,NeurIPS 2025,图1】中显示,随着$p$和$q$的偏离,方差会急剧增加。如图4所示:对于大的KL值,估计的方差非常大。($k_2$估计器没有方差爆炸问题,但它是有偏的。)因此,我们使用标准的估计器$k_1 = -\log r$。

图4:对于两个具有单位方差和不同均值的合成高斯分布,KL(p ∥ q)估计器的比较。
图4:对于两个具有单位方差和不同均值的合成高斯分布,KL(p ∥ q)估计器的比较。

RL对平均性能与Best-of-K性能的影响。近期越来越多的文献认为,对大语言模型进行强化学习(RL)通常主要是通过将概率质量集中在已知的成功轨迹上,来提高平均性能,这有时会以策略熵和输出多样性为代价【索引79,Yue等人,Does reinforcement learning really incentivize reasoning capacity in LLMs beyond the base model?,NeurIPS 2025】【索引32,Liang等人,Beyond pass@1: Self-play with variational problem synthesis sustains RLVR,ICLR 2026】【索引8,Chen等人,Pass@k training for adaptively balancing exploration and exploitation of large reasoning models,arXiv 2025】【索引74,Wen等人,Reinforcement learning with verifiable rewards implicitly incentivizes correct reasoning in base LLMs,ICLR 2026】【索引61,Tajwar等人,Maximum likelihood reinforcement learning,arXiv 2026】。根据这种观点,best-of-K的改进可能有限,因为模型只是更擅长选择一个高置信度的解决方案,而不是扩展可达到的正确解决方案的集合。

Composer 2中的性能提升观察。在这种背景下,我们的结果值得注意:我们没有观察到平均奖励上升而best-of-K保持平稳的权衡,而是发现我们的训练同时改善了这两个统计数据,如图5所示。这表明,在我们的设置中,RL不仅仅是在重新加权一个固定的推理路径池,而且还在重复采样下提高了模型对正确解决方案的有效覆盖范围。

图5:在RL训练期间,平均性能和best-of-K性能都增加了。以上曲线报告于一个留出的评估集以及CursorBench任务。在整个RL训练过程中,性能稳步提升。重要的是,我们没有观察到平均性能和best-of-K性能之间的权衡。
图5:在RL训练期间,平均性能和best-of-K性能都增加了。以上曲线报告于一个留出的评估集以及CursorBench任务。在整个RL训练过程中,性能稳步提升。重要的是,我们没有观察到平均性能和best-of-K性能之间的权衡。

自总结技术。为了使Composer 2能够处理长周期的任务,我们使用了在Composer 1.5中引入的自总结技术【索引64,Cursor Team,Self-summarization for composer,https://cursor.com/blog/self-summarization,2025】。每个训练执行轨迹可以涉及多个由总结链接在一起的生成过程,而不是单个提示-响应对。我们使用最终的奖励来评价模型在该链中产生的所有令牌。这既上调了好的轨迹中的代理响应,也上调了使其成功的自总结。同时,丢失了关键信息的糟糕总结则被下调。随着Composer的训练,它学会了使用自总结来处理更多的信息,即使在有限的上下文窗口内也是如此。对于困难的例子,它通常会进行多次自总结。在我们的实验中,我们发现自总结与使用单独的基于提示的压缩方法相比,始终能减少错误,同时使用的令牌显著更少,并能重用KV缓存 。

4.2 Agent Behavior

提升开发者体验。虽然RL训练的主要目标是提高模型智能,但我们也旨在产出一个能提供良好开发者体验的模型。这受到模型的沟通风格以及回答问题所需的时间和资源的影响。

辅助奖励与行为监控。为了保证行为和沟通,我们应用了一系列辅助奖励来确保模型提供良好的体验。这些奖励包括编码风格、沟通,以及针对不良工具调用的产品特定惩罚,例如创建了待办事项列表但未完成。在RL训练期间,我们监控模型的涌现行为,并根据需要偶尔引入额外的行为奖励。例如,我们观察到模型会开始在注释中留下长篇的思维链,或者退化到只使用终端工具。

非线性长度惩罚。为了激励模型在简单的请求上快速产出解决方案,同时允许它在困难的请求上思考更长时间,我们向奖励中添加了一个凹向下且递增的非线性长度惩罚:

$$C_{\text{length}\{k,q\}}(x) = \frac{(1+kx)^{1-q}-1}{k(1-q)},$$

其中$k$和$q$是定义惩罚曲率的超参数,输入$x$是思考令牌、工具调用令牌、工具输出令牌、最终消息令牌、工具调用次数和执行轨迹轮次数的加权组合。这种非线性反映了在简单的任务上(只需几次工具调用即可完成),每一点额外的努力都比在长周期任务中感受得更强烈,在长周期任务中,代理可能会迭代数百次工具调用。图6展示了该方程产生的一些非线性曲线示例。我们发现,利用这种长度惩罚可以使模型学到特别高效的行为,例如并行进行多次工具调用。

图6:非线性惩罚促使模型在简单任务上快速响应,在困难任务上投入更多思考。
图6:非线性惩罚促使模型在简单任务上快速响应,在困难任务上投入更多思考。

5 使用CursorBench进行真实世界评估

现有基准的局限性。过去一年,编码代理的应用迅速发展,从简单的、范围严格的编辑扩展到复杂的调试、大规模重构和功能开发。在Cursor,我们观察到,公共评估基准的性能通常与这些模型的真实世界效用关联松散。我们将这种不一致归因于四个主要因素:

四大错位因素
* 领域不匹配 (Domain Mismatch):随着编码代理能力的扩展,静态基准通常无法捕捉到开发者工作流的全部范围。例如,SWE-bench及其变体主要关注孤立的错误修复。Terminal-Bench涵盖了更广泛的任务类型,但其许多任务(例如,计算国际象棋走法)是抽象的谜题,而不是典型的软件工程操作。
* 提示过度指定 (Prompt Over-specification):公共基准通常是高度指定的,假定只有一小部分正确的解决方案。相比之下,真实的开发者请求通常是未充分指定的,并允许多种有效的架构方法。因此,公共基准要么惩罚正确的替代解决方案,要么依赖于不自然的、明确的提示,从而绕过了解释模糊意图的挑战。
* 数据污染与过拟合 (Data Contamination and Overfitting):由于公共基准是从开源仓库的历史抓取中构建的,它们经常被泄露到模型训练混合数据中,人为地抬高了分数。最近,OpenAI在发现前沿模型能够从记忆中生成黄金补丁的证据后,暂停了报告SWE-bench Verified的结果【索引1,Why SWE-bench Verified no longer measures frontier coding capabilities,http://openai.com,2026】。除了污染问题,这些基准的固定和狭窄性质可能会压缩性能差异:例如,Haiku 4.5在SWE-bench Verified上达到73.3%,非常接近GPT-5的74.9%,这与在更广泛、更多样化的任务分布(如Terminal-Bench)上的准确性不符。
* 评估范围狭窄 (Narrow Evaluation Scope):现有的编码评估主要衡量功能正确性。在实践中,开发者还非常看重代码质量、可读性、延迟、成本以及代理在整个会话中的交互行为质量。

CursorBench的引入。为了解决这些限制,我们引入了CursorBench,一个内部评估套件,包含从我们工程团队实际编码会话中提取的任务。由于这些任务源于真实的代理会话,而非精心策划的公共仓库,CursorBench能更好地反映软件工程任务的真实分布,同时完全避免了训练集污染。此外,我们不单单依赖功能正确性,而是使用针对代码质量、执行效率和在现实场景中交互式代理行为的特定指标来评估模型。

CursorBench与公共基准的结构差异。图7突出了CursorBench与公共评估集之间的结构差异。CursorBench任务需要进行大量更广泛的代码修改,中位数为181行代码更改,而SWE-bench Verified和Multilingual仅为7-10行(图7a)。同时,CursorBench的提示也更加不明确,中位描述长度仅为390个字符,而公共基准为1,185-3,055个字符(图7b)。这种广泛的执行范围和高的意图模糊性的结合,准确地反映了真实世界软件工程的内在难度,开发者必须频繁地从生产日志、稀疏的用户错误报告和大型现有代码库中综合上下文来得出解决方案。

图7:与公共基准相比,CursorBench任务的提示指定性较低,并且需要多一个数量级的代码更改。我们发现这更好地代表了真实世界软件工程请求的复杂性和模糊性。
图7:与公共基准相比,CursorBench任务的提示指定性较低,并且需要多一个数量级的代码更改。我们发现这更好地代表了真实世界软件工程请求的复杂性和模糊性。

CursorBench任务示例。图8和图12展示了代表性的例子:一个任务要求根据一个简洁的错误报告和可观察性日志,诊断出重试循环中的构建工具转译错误;而另一个任务则要求在一个包含数百个聊天响应的数据集上设计一个经过调优的启发式检测器,以量化一个微妙的流式传输回归问题并发现其隐藏的不变量。

图8:一个CursorBench任务示例(从我们的评估管道中截断和模糊化)。代理收到一个简洁的错误报告,必须将源代码与生产可观察性日志进行交叉引用以诊断故障。日志中还包含不相关的生产服务警告,这是一个误导:真正的根本原因是esbuild 0.20.2在处理`using`时的降级(downleveling)错误。转译后的输出将高亮显示的声明降级为一个`var`作用域的错误状态,该状态在重试迭代之间没有被重置,导致即使后续尝试成功,生成的`finally`块也会重新抛出陈旧的失败状态。
图8:一个CursorBench任务示例(从我们的评估管道中截断和模糊化)。代理收到一个简洁的错误报告,必须将源代码与生产可观察性日志进行交叉引用以诊断故障。日志中还包含不相关的生产服务警告,这是一个误导:真正的根本原因是esbuild 0.20.2在处理`using`时的降级(downleveling)错误。转译后的输出将高亮显示的声明降级为一个`var`作用域的错误状态,该状态在重试迭代之间没有被重置,导致即使后续尝试成功,生成的`finally`块也会重新抛出陈旧的失败状态。

CursorBench的演进。我们的团队持续开发新的CursorBench迭代版本。随着用户工作流的演变和代理能力的提高,我们定期更新评估集,以保持与开发者实际使用产品的方式一致。图9显示了该基准在不同迭代中的复杂性增长:与早期版本的CursorBench相比,CursorBench-3中的任务平均需要更改的文件和代码行数增加了一倍以上。除了问题规模的增加,任务类型的分布也发生了变化,因为开发者越来越多地将长时间运行的命令执行、实验监控和数据分析委托给代理。这种持续的更新确保了我们的评估始终与真实世界难度的前沿保持一致,而不会饱和。

图9:CursorBench在不同迭代中的演变。每个版本都包含了更复杂的请求。CursorBench-3的中位数任务规模比初始版本增加了一倍以上,如下方条形图中的相对百分比变化所示。
图9:CursorBench在不同迭代中的演变。每个版本都包含了更复杂的请求。CursorBench-3的中位数任务规模比初始版本增加了一倍以上,如下方条形图中的相对百分比变化所示。

补充评估套件。最后,我们通过一套针对编码代理质量和行为其他方面的目标评估来补充我们的主要CursorBench评估。这些评估包括:意图评估,评估模型如何处理模糊的提示;指令遵循评估,衡量模型遵循系统提示、用户提示、规则和技能的程度;急于编辑评估,测试模型在应避免编辑代码的问题上的反应;代码质量评估,评判代码和注释的质量;以及中断评估,量化模型处理执行中中断和用户反馈的能力。我们通过识别代理行为的重要维度、选择能够引发这些行为的数据点,并编写评估标准来开发这些评估。

6 基础设施

6.1 训练基础设施

并行策略的演进。之前的Composer训练堆栈结合了完全分片数据并行(FSDP)【索引50,Rajbhandari等人,ZeRO: Memory optimizations toward training trillion parameter models,SC20 2020】【索引81,Zhao等人,Pytorch fsdp: experiences on scaling fully sharded data parallel,arXiv 2023】、专家并行(EP)【索引54,Shazeer等人,Outrageously large neural networks: The sparsely-gated mixture-of-experts layer,ICLR 2017】【索引14,Fedus等人,Switch transformers: Scaling to trillion parameter models with simple and efficient sparsity,JMLR 2022】和张量并行(TP)【索引55,Shoeybi等人,Megatron-LM: Training multi-billion parameter language models using model parallelism,arXiv 2019】。在最初的MoE设计中,EP与TP重用相同的秩组(rank group),因此EP不是一个独立的扩展轴。这种耦合简化了实现,但限制了对更大多专家配置的支持,并且在持续预训练阶段会不必要地启用激活分片,即使激活内存压力不大。

上下文并行(CP)的应用。Composer 2转而使用上下文并行(CP)【索引33,Liu等人,Ring attention with blockwise transformers for near-infinite context,ICLR 2024】【索引26,Jacobs等人,Deepspeed ulysses: System optimizations for enabling training of extreme long sequence transformer models,arXiv 2023】作为长上下文扩展的主要轴。CP比TP需要更少的通信,并通过在各种投影中保留完整的隐藏维度来提高计算效率;相比之下,TP会产生效率较低的瘦局部矩阵乘法。我们在多头潜在注意力(MLA)架构中高效实现CP使用了一些技巧。为了最小化通信开销,我们先计算局部的KV潜在向量,然后在CP ranks之间对这些潜在向量进行all-gather,最后再计算KV投影。虽然这在所有CP ranks上复制了投影计算,但该投影很小,且减少了CP通信,使我们能够将CP通信与Q投影的计算完全重叠。此外,虽然朴素的CP在因果注意力中会导致负载不平衡,因为后面的token需要关注更多的token,但我们使用了Liu等人【索引33】的技术来解决这个问题:我们将序列分成$2 \times CP$个块,第$i$个rank处理第$i$个和第$2 \times CP - 1 - i$个块,从而使得所有rank在因果注意力中的工作量大致相等。最后,上下文并行维度被折叠到FSDP维度中,使我们能够使用CP ranks来减少每个GPU的参数/状态内存使用。

灵活的专家并行(EP)设计。Composer 2还通过将EP与TP解耦,引入了更灵活的专家并行设计。这需要在分片密集层和专家权重时使用不同的网格(meshes)。EP由DP和CP的能力构成,从而支持更大的专家并行度,并使专家分组的GEMM(通用矩阵乘法)在每个rank有更大token批次时更高效。我们在持续预训练阶段使用EP=8, CP=2,在RL阶段使用EP=8, CP=8。我们使用DeepEP【索引80,Zhao等人,Deepep: an efficient expert-parallel communication library,https://github.com/deepseek-ai/DeepEP,2025】来实现高吞吐量的token分发/合并。DeepEP的通信缓冲区开销相对较低,其内核默认使用20个SM,为并发计算留出了空间。我们还在分发前将token量化为MXFP8(下文讨论)以实现更高效的通信,这不影响我们的精度,因为我们已经在MXFP8中执行专家计算。为了保持更高的精度,我们将合并操作维持在BF16。为了最大化计算-通信重叠,token被分成微批次,并在独立的通信和计算流上进行流水线处理 。

图10:我们专家混合(Mixture-of-Experts)层中单个分组GEMM训练流程的概览。每个色块代表一次内核启动。
图10:我们专家混合(Mixture-of-Experts)层中单个分组GEMM训练流程的概览。每个色块代表一次内核启动。

数据并行(DP)负载均衡。最后,我们发现为了实现高利用率,不同DP ranks拥有相似的计算量至关重要。在持续预训练中,由于序列长度固定,很容易实现DP平衡。在RL中,不同提示的不同执行轨迹可能导致序列长度差异很大,因此在每个训练步骤之前,我们运行一个全局序列打包阶段,以确保DP计算负载均衡。该打包算法考虑了较长序列增加的注意力成本。

自研低精度训练核函数。Composer 2的训练使用了以CUDA、PTX和ThunderKittens/ParallelKittens【索引56,Spector等人,Thunderkittens: Simple, fast, and adorable kernels,ICLR 2025】【索引59,Sul等人,Parallelkittens: Systematic and practical simplification of multi-gpu ai kernels,arXiv 2025】编写的内部核函数。这些核函数主要优化了专家混合(MoE)层的低精度训练。我们的训练方案使用了MXFP8【索引46,Open Compute Project,Ocp microscaling formats (mx) specification version 1.0,2023】和NVFP4【索引45,NVIDIA,Pretraining large language models with nvfp4,arXiv 2025】两种精度格式。我们专门针对NVIDIA Blackwell GPU进行块级缩放的张量核心矩阵乘法(即在脉动阵列矩阵乘法期间进行硬件内反量化)。图10展示了我们MoE层内单个分组GEMM的训练流程。

MoE前向传播中的NVFP4变体。对于MoE的前向传播,我们使用了一种新颖的NVFP4变体:将BF16的值量化为FP4E2M1,使用每块(块大小=16)的FP8E4M3缩放因子和每token的FP32缩放因子。我们发现原始的NVFP4格式(使用每张量的FP32缩放因子)存在两个问题,使其不够稳健。首先,每张量缩放使得训练对批次敏感,会降低数值精度并导致RL训练发散。其次,token间的缩放值会将未来token的信息泄露给过去的token,导致梯度有偏。因此,尽管增加了量化和GEMM尾声的延迟,每token缩放被证明是更有效的方案。

MoE反向传播中的MXFP8。对于MoE的反向传播,我们使用标准的MXFP8格式,即FP8E4M3的值和每32个元素的块使用FP8E8M0的缩放因子。我们能这样做是因为RL训练的不对称性。在前向传播中,训练器必须与推理过程在数值上保持一致以确保稳定性。因此,我们使用训练器中的NVFP4来支持快速推理。然而,反向传播只在训练集群上运行。这对系统级的RL效率不是瓶颈,所以我们可以负担得起更高的精度来提高训练的稳定性。

硬件级数学精度的重要性。最后,硬件级别的数学精度选择非常重要。对于NVFP4量化,我们发现使用符合IEEE标准的浮点运算(例如,__fdiv_rn)至关重要;使用快速近似的替代方案会导致训练在大约一百个RL步骤后发散。相反,对于MXFP8量化,使用快速近似路径(例如,__fdividef)自我们最初训练Composer 1以来没有引起任何发散,因此我们选择它以获得最佳性能。

开源贡献。我们积极开源我们的核函数实现,并支持社区改善GPU核函数生态系统的努力。我们与Colfax紧密合作,为QK 192 / V 128配置(也称为“DeepSeek shapes”)实现了Flash Attention 4的反向传播核函数,该实现已被合并到公共仓库中【索引27,Jay Shah,Flash attention pull request #2270,2026】。我们还与斯坦福大学的Hazy Research团队合作,积极支持ThunderKittens的开发【索引59】【索引60,Sul等人,One kernel for all your gpus,https://hazyresearch.stanford.edu/blog/2025-09-22-pgl,2025】【索引58,Sul等人 ,Loads and loads of fluffy kittens,https://hazyresearch.stanford.edu/blog/2025-11-17-fluffy-kittens,2025】【索引57,Sul和Ré ,Thunderkittens 2.0: Even faster kernels for your gpus,https://hazyresearch.stanford.edu/blog/2026-02-19-tk-2,2026】。最近,我们将最先进的BF16、MXFP8 和NVFP4 GEMM实现开源到了ThunderKittens中【索引21,HazyResearch,Thunderkittens gemm kernels,2026】。最后,我们通过在线博客文章分享我们在量化和MoE核函数实现方面的知识【索引63,Cursor Team,1.5x faster moe training with custom mxfp8 kernels,https://cursor.com/blog/kernels,2025】 。

6.2 RL 基础设施

解耦的服务架构。我们的RL基础设施由四个解耦的服务组成:训练、环境、推理和评估。解耦的服务栈支持更大规模的全局训练、高可用性以及独立的扩展和分片。Composer 2的生产训练作业跨越了3个地区的GPU计算资源和4个地区的CPU计算资源。

训练服务。我们使用一个基于Ray【索引42,Moritz等人,Ray: A distributed framework for emerging AI applications,OSDI 2018】和PyTorch【索引47,Paszke等人,Pytorch: An imperative style, high-performance deep learning library,NeurIPS 2019】构建的完全异步、高吞吐量的训练栈。一个中心化的协调器执行基于槽位的样本生命周期状态管理,将样本通过分布式执行器流水线移动,并实现平衡样本生成吞吐量和策略陈旧性的调度策略。我们在训练器内设计所有服务时都围绕着“futures”的概念,这允许在上游依赖准备就绪时立即执行计算。我们利用Ray对象存储来存放准备好被训练工作单元消费的样本,当节点CPU内存不足时,这允许自然地溢出到本地NVMe存储。

容错与热更新。为了支持大规模的后训练,训练器内的所有组件都具有进程或进程组级别的容错能力。我们在训练期间对所有节点运行被动和主动的健康检查;一旦检测到硬件故障,我们将该节点标记为不健康以供调度,但使用热备节点继续训练。将训练与推理和环境基础设施解耦,自然使训练对这些服务中的故障更具弹性;在训练运行期间,我们看到许多这些服务出现部分或全部中断而没有导致训练作业失败的情况。为了最小化训练作业的重启次数,我们使用一个反应式配置系统,并支持在每个进程级别进行实时代码更新;当新代码部署时,现有actor会清空正在处理的请求并被透明地替换。

策略感知的检查点机制。重放长时间运行的编码执行轨迹是昂贵的。为了减轻作业级故障带来的昂贵失败,我们除了在步骤级别对模型权重进行常规检查点外,还在执行轨迹级别和组级别执行策略感知的检查点。对于执行轨迹检查点,我们依赖代码库环境状态的内存快照,以便在恢复时,我们可以将重建的代码库环境传递给验证器。对于组检查点,我们将带有策略版本标记的序列和优势值写入NFS;作业重启时,调度器在决定是分派新工作还是简单加载已准备好的组时会考虑这些信息。

环境服务与Anyrun平台。有状态的代码库环境是我们后训练栈的一等公民。环境运行在Anyrun之上,这是一个为大规模运行非受信代码而构建的内部计算平台。这也是为Cursor产品中的Cloud Agents和Automations提供支持的同一计算平台。

Anyrun架构。所有来自训练器的环境创建请求都被发送到一个全局服务,该服务将请求路由到底层的Anyrun集群。我们的训练工作负载被分片到多个Anyrun集群,以实现实例可用性和容错。在一个集群内,一组分布式的Anyrun管理器负责调度pod,扩展跨多个区域配置的云计算资源,并执行状态协调以管理每个集群数十万个pod。每个pod都是一个专用的Firecracker虚拟机,能够运行一个完整的开发环境,包括浏览器和用于计算机使用的GUI。我们在多种类型的机器和架构(x86, ARM)的大量混合上运行pod,以最大化实例可用性。

调度吞吐量与资源管理。调度吞D吐量对于RL工作负载的突发性尤为重要。每个Anyrun集群每秒能够调度超过500个pod,同时保持所需的箱式包装(binpacking)要求。一个朴素的打包策略的挑战在于,pod的稳态资源使用可能远低于其启动时的峰值,并且由于超售(overcommits)也可能是突发性的。为了解决这个问题,我们除了使用传统的调度启发式方法外,还监控并根据硬件压力(CPU、内存、磁盘)的实时读数进行调度。

环境的快照与分叉。Anyrun支持在文件系统和内存级别对完整的编码环境进行分叉和快照。这在RL期间解锁了有用的功能,例如轨迹中途的执行轨迹检查点和轨迹结束后的状态捕获以供未来反思。当请求pod分叉时,我们首先尝试将分叉调度到同一节点上;如果由于空间限制不可行,我们将pod状态实时迁移到有容量的节点。

出口流量控制。环境中的出口流量受到严格控制,以限制任何外部影响。任何从pod访问互联网的请求都必须通过Anygress,这是Anyrun内部的一个服务,负责代理流量、执行精细的请求策略和删除敏感头信息。为了更好地复制真实世界的环境,Anygress通过在pod启动时注入一个受信任的根CA并在TCP层重定向pod流量,以透明的方式运行,而不是依赖代理环境变量。

工具与生产环境一致性。我们使用代表Cursor客户端中工具链的工具进行训练。每个代码库环境都以一个共享的工具库开始,可以通过RPC调用。像语义搜索这样的一些工具有外部依赖,并在环境之外处理。为了支持Cursor客户端中可用的完整工具集,我们维护一个Cursor后端的影子部署,该部署在数据集准备和执行轨迹期间都使用。以这种方式共享生产实现,使我们能够安全地扩展实验和训练,同时保持对Composer 2将被部署到的工具链的忠实性。

训练与生产环境的差异化配置。在某些情况下,我们希望工具行为在训练和生产设置之间有所不同。具体的例子包括强制执行更严格的工具参数检查以鼓励更精确的模型行为,以及移除某些工具以提高模型的可控性。为了实现这一点,可用的工具集和每个工具的期望行为是为每个环境动态确定的。

推理与权重同步。我们与Fireworks AI合作进行RL推理。由于Kimi K2.5是一个专家混合模型,数值差异可能导致在推理引擎前向传播和训练器前向传播中选择不同的专家。如果训练器和推理引擎对每个token的专家路由不一致,训练期间计算的对数概率可能与采样token的分布不匹配,从而给策略梯度引入噪声。为了解决这个问题,我们采用了路由器重放(router replay)【索引82】【索引38】:在推理期间,引擎返回每个MoE层每个token选择的专家索引,在训练前向传播期间,路由器的专家分配被覆盖以匹配。路由器仍然计算门控分数,以便梯度能够流经它。我们通过过滤掉门控分数低于从路由器自身top-k选择中得出的合理性阈值的重放专家,并用路由器的候选专家替换它们,来扩展基本的重放方案;我们发现这减少了推理和训练前向传播之间的p99数值不匹配。

高效的权重同步机制。每个训练步骤,我们通过上传到共享的S3桶来将更新的权重同步到推理引擎。为了最小化传输大小,我们使用增量压缩:每个rank缓存其上一次上传,并只传输与新权重的差异。因为RL的更新很小,即使是全参数训练,这些差异对于1T参数的模型也能压缩到几个GB。上传在所有训练rank之间完全分片,使我们能够饱和训练集群的出口带宽;类似地,在Fireworks端的下载也在推理副本之间分片。压缩、上传和热加载信令在后台工作单元中完全流水线化,因此训练永远不会被阻塞。在Composer 2的训练运行期间,我们在美国和欧洲的地理分布式集群上运行推理。每个集群独立地从共享的增量链中下载并重建权重,不需要与训练集群直接连接,从而实现了通过商用云存储进行世界规模的分布式RL推理。

在线评估。为了在训练期间为我们的模型提供忠实的评估,我们为每个评估作业运行一个固定版本的生产后端和Cursor客户端。这为我们提供了高度的信心,即评估期间的模型行为是我们最终用户所见的精确复制,并且也允许我们使用相同的基础设施迭代Cursor工具链和模型系统提示。对于我们想要评估的每个训练步骤,我们获取一个评估部署的租约,自动将GPU移动到该部署,并执行从其所在的训练集群到推理部署的评估检查点的跨区域权重同步。

A4 实验环境

  • 模型架构

    • 基础模型:Kimi K2.5,一个拥有1.04T总参数和32B活跃参数的专家混合(Mixture-of-Experts, MoE)模型。
    • 最终模型:Composer 2,在Kimi K2.5基础上经过持续预训练和强化学习得到。
  • 硬件配置

    • 训练平台:使用NVIDIA B300s GPU进行训练。
    • RL环境:在内部计算平台Anyrun上运行,该平台使用大量混合类型的机器和架构(x86, ARM)。
    • 推理平台:与Fireworks AI合作,在美国和欧洲的地理分布式集群上进行RL推理。
  • 软件配置

    • 训练框架:基于Ray和PyTorch构建的异步、高吞吐量训练栈。
    • 核心库:使用自研的CUDA、PTX和ThunderKittens/ParallelKittens核函数优化MoE层。
    • 运行环境:使用Firecracker虚拟机作为隔离的开发环境。
  • 数据集与基准

    • 内部基准:CursorBench,一个由Cursor工程团队实际编码会话任务组成的内部评估套件,旨在反映真实世界的软件工程挑战。
    • 公共基准
      • SWE-bench Multilingual【索引28,Jimenez等人,SWE-bench: Can language models resolve real-world github issues?,ICLR 2024】:一个多语言的软件工程问题解决基准。
      • Terminal-Bench【索引39,Merrill等人,Terminalbench: Benchmarking agents on hard, realistic tasks in command line interfaces,ICLR 2026】:一个在命令行界面中评估代理执行真实任务的基准。

A4 实验结果

7.1 CursorBench

实验设置:我们在Anyrun基础设施内直接运行Cursor代理来评估模型。对于CursorBench中的每个任务,我们初始化代码库环境和任务提示,并以与生产环境中完全相同的方式运行代理。
评估指标:我们计算在多次评估集上的平均准确率以减少方差。除准确率外,我们还测量了效率指标,如完成令牌数、端到端延迟和推理成本。

实验结果与分析

  • 准确率:如表1所示,Composer 2在CursorBench-3上达到61.3%的准确率。这相比Composer 1.5(44.2%)有37%的相对提升,相比Composer 1(38.0%)有61%的提升。与基础模型Kimi K2.5(36.0%)相比,准确率有显著提高,验证了持续预训练和强化学习流程的有效性。Composer 2的准确率与最强的前沿模型(如GPT-5.4的63.9%)具有竞争力。
  • 效率与成本:图11将准确率与资源消耗进行了对比。在令牌使用方面,Composer 2生成的轨迹长度与其他模型相当,同时提供了前沿水平的准确率,表现出很高的令牌效率。在推理成本方面,Composer 2实现了帕累托最优的权衡:其推理成本与较小或低强度版本的模型相似,而准确率却与大得多的前沿模型相当。

结论:这些结果表明,领域专业化的训练可以产生在真实世界软件工程的苛刻要求下,既更准确又更具成本效益的模型。

表1:在公共和内部评估套件上的基准测试结果。对于第三方模型,我们以(我们的工具链/自报告)格式呈现结果(如果两者都可用)。对于Anthropic模型在Terminal-Bench上的结果,我们报告了官方排行榜上的Claude Code分数,而不是我们的工具链评估。总的来说,Composer 2的准确性与最强的前沿模型相当。†OpenAI的安全过滤器拒绝了5个GPT-5.4和3个GPT-5.3-Codex任务;被拒绝的问题得分为0。
表1:在公共和内部评估套件上的基准测试结果。对于第三方模型,我们以(我们的工具链/自报告)格式呈现结果(如果两者都可用)。对于Anthropic模型在Terminal-Bench上的结果,我们报告了官方排行榜上的Claude Code分数,而不是我们的工具链评估。总的来说,Composer 2的准确性与最强的前沿模型相当。†OpenAI的安全过滤器拒绝了5个GPT-5.4和3个GPT-5.3-Codex任务;被拒绝的问题得分为0。
图11:在CursorBench上,Composer 2在成本方面实现了优越的帕累托前沿,同时在令牌效率方面保持了高度竞争力。对于GPT-5.4、Codex-5.3、Opus 4.6和Sonnet 4.6,我们绘制了高(圆形)、中(三角形)和低(方形)强度变体的性能。
图11:在CursorBench上,Composer 2在成本方面实现了优越的帕累托前沿,同时在令牌效率方面保持了高度竞争力。对于GPT-5.4、Codex-5.3、Opus 4.6和Sonnet 4.6,我们绘制了高(圆形)、中(三角形)和低(方形)强度变体的性能。

7.2 Public Benchmarks

实验设置:我们在SWE-bench Multilingual和Terminal-Bench两个公共基准上进一步评估Composer 2。对于Composer系列模型,我们使用自己的工具链计算分数。对于SWE-bench,我们在问题陈述前简单地加上“please solve this github issue”。对于Terminal-Bench,我们在用户提示中增加了关于文件放置或环境设置的格式化指令。

实验结果与分析
- SWE-bench Multilingual:Composer 2得分73.7%,比Composer 1.5(65.9%)提高了7.8%,比Composer 1(56.9%)提高了16.8%。
- Terminal-Bench:Composer 2得分61.7%,比Composer 1.5(47.9%)提高了13.8%,比Composer 1(40.0%)提高了21.7%。
- 与基础模型对比:与基础模型Kimi K2.5相比,Composer 2在SWE-bench Multilingual上表现相似,在Terminal-Bench上则有显著提升。

结论:Composer 2在这些公共基准上的表现与其他最先进的模型相比仍然具有很强的竞争力。连续的Composer版本在两个基准上都显示出一致的进步,表明在预训练和强化学习方面的持续投入为代理式软件工程带来了复合收益。

A5 结论

Composer 2证明了通过持续预训练和强化学习可以训练出强大的专用模型。从一个强大的通用模型出发,可以将其特化以在代理式编码领域达到前沿水平的性能。无论是从算法还是基础设施的角度来看,核心洞见在于在扩展训练的同时,确保与目标领域的高度匹配。我们通过使用CursorBench进行仔细的领域基准测试、工具链和环境工程、行为奖励开发以及严格的基础设施可靠性来实现这一点。

Composer 2的结果表明,通过进一步扩展,未来仍有很大的改进空间。虽然Composer 2标志着对先前版本的稳步改进,但在许多情况下,模型显示的智能或一致性行为仍有明显可以改进的地方。本文中训练的模型虽然很大(1.04T参数,32B活跃参数),但可能比具有相当能力的其他专有模型要小。我们相信在架构和算法上仍有相当大的发展空间。

编码代理作为一种工具的范围也在从交互式问题扩展到需要数小时人类时间的代理式任务【索引29,Kwa等人,Measuring ai ability to complete long tasks,https://metr.org/blog/2025-03-19-measuring-ai-ability-to-complete-long-tasks/,2025】,并且普遍预期其处理范围在未来会迅速增长【索引65 ,Cursor Team,The third era of software,https://cursor.com/blog/third-era,2025】。对于未来的Composer迭代,我们的团队专注于通过训练方法来扩展模型处理这些问题的能力,这包括有效利用更长期训练信号的算法,以及支持忠实的长周期问题的基础设施 。

A6 附录

B 基础模型选择

候选基础模型。在训练之前,我们评估了几个潜在的开源基础模型,包括GLM5【索引4,Zhipu AI,GLM-5: From vibe coding to agentic engineering,https://z.ai/blog/glm-5,2026】 、Kimi K2.5【索引67】和DeepSeek V3.2【索引12,DeepSeek-AI,Deepseek-v3.2: Pushing the frontier of open large language models,arXiv 2025】。三个基础模型评估促使我们选择了Kimi K2.5:

三大评估维度
* 编码知识:我们使用一个名为FreshBench的内部基准来评分事实知识。FreshBench是一个针对先前Composer模型进行对抗性构建的问答基准。我们识别出Composer必须阅读库源代码或执行网络搜索才能解决编码任务的回合。从这些轨迹中,我们创建了问答对,并用一个网络搜索代理验证答案。
* 状态追踪:在编辑代码库时,编码代理通常需要理解数十个过去的文件编辑才能采取行动。LoCoDiff【索引3,Abante AI,Locodiff-bench: Long context diff reconstruction benchmark,https://abanteai.github.io/LoCoDiff-bench/,2025】是一个要求模型在多次差异修改后重现文件状态的基准,这是模型长期记忆的一项重要基础技能。状态追踪是一个类似于LoCoDiff的内部基准,由我们的单一代码库构建。我们报告的是平均字符级距离,而不是原始准确率,因为我们发现后者对单字符错误很敏感 。
* 代码库困惑度:我们测量困惑度来确定基础模型的编码智能。我们使用我们的私有单一代码库作为未受污染的来源,按字母顺序连接文件,并在一个滚动窗口上计算负对数似然的总和。

评估策略。我们在测试基础模型时,特意不考虑编码代理基准。我们发现这类基准对最终性能的预测性较差,因为代理和长周期能力在RL阶段可能会发生巨大变化。

评估结果与最终选择。表2显示了分析结果。所有三个被考虑的模型在这些实验中都表现得相当好。我们选择了Kimi K2.5【索引67】,因为它具有强大的通用性能以及在我们基础设施中的效率等额外考虑因素。

表2:在我们的内部基准上评估的基础模型。负对数似然是在我们的内部代码库上测量的。
表2:在我们的内部基准上评估的基础模型。负对数似然是在我们的内部代码库上测量的。

C CursorBench

C.1 流式前缀检测

CursorBench任务示例:流式前缀检测。以下是另一个CursorBench任务的例子。

图12:一个CursorBench任务示例。代理必须从部分症状报告中推断出故障模式,针对954个异构的聊天响应编写一个启发式检测算法,并仔细调整该启发式算法以恢复格式错误的“前缀流”案例的精确计数,同时避免对正常的增量输出进行过度计数。此外,该错误的一个变体产生“交错卡顿”,即初始前缀链只有两行长,然后稳定为重复行并递增重复次数,代理必须仔细检查聊天响应以发现这一点。
问题陈述:我们在一些聊天响应中看到了一个奇怪的流式传输错误:

Now I Now I need to updat Now I need to update this. Now I need to update this. I ha Now I need to update this. I have the

我们没有得到正常的流式增量,而是得到了像上面片段那样的重复增长的前缀。我认为这主要发生在思考令牌(think tokens)内部。我想知道这种情况有多普遍。请查看@logs文件夹中的954个响应json文件。

参考diff的算法核心。以下列表显示了此任务参考diff的算法核心。

MIN_CHAIN = 3
MIN_SEED_LEN = 2
MAX_SEED_LEN = 50

def find_prefix_chain(text: str) -> tuple[int, str] | None:
    if len(text) < 10:
        return None
    first_nl = text.find("
")
    if first_nl < MIN_SEED_LEN or first_nl > MAX_SEED_LEN:
        return None
    seed = text[:first_nl]
    needle = "
" + seed
    starts = [0]
    pos = 0
    while True:
        idx = text.find(needle, pos)
        if idx == -1:
            break
        starts.append(idx + 1)
        pos = idx + 1
    if len(starts) < MIN_CHAIN:
        return None
    ends = [s - 1 for s in starts[1:]] + [len(text)]
    chunks = [text[s:e] for s, e in zip(starts, ends)]
    chain = 1
    for i in range(len(chunks) - 1):
        cur, nxt = chunks[i], chunks[i+1]
        if len(cur) < len(nxt) and nxt.startswith(cur):
            chain += 1
        else:
            break
    return (chain, seed) if chain >= MIN_CHAIN else None

def iter_think_blocks(text: str):
    pos = 0
    while True:
        open_idx = text.find("<think>", pos)
        if open_idx == -1:
            return
        close_idx = text.find("</think>", open_idx)
        if close_idx == -1:
            yield text[open_idx + 7:].lstrip("
")
            return
        yield text[open_idx + 7:close_idx].lstrip("
")
        pos = close_idx + 8

def has_prefix_streaming_bug(chat_response: str) -> bool:
    return any(find_prefix_chain(block) is not None for block in iter_think_blocks(chat_response))