<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" version="2.0">
<channel>
<atom:link href="https://carota.site/feed" rel="self" type="application/rss+xml"/>
<title>知行</title>
<link>https://carota.site</link>
<description>欢迎光临~  技术分享，生活感思，好玩的东西</description>
<language>zh-CN</language>
<copyright>© lollapalooza </copyright>
<pubDate>Fri, 03 Jul 2026 20:08:31 GMT</pubDate>
<generator>Mix Space CMS (https://github.com/mx-space)</generator>
<docs>https://mx-space.js.org</docs>
<image>
    <url>https://avatars.githubusercontent.com/u/17880398?v=4</url>
    <title>知行</title>
    <link>https://carota.site</link>
</image>
<item>
    <title>MAGRPO：用多智能体强化学习训练真正会协作的 LLM</title>
    <link>https://carota.site/posts/books/magrpo-llm</link>
    <pubDate>Thu, 25 Jun 2026 07:59:55 GMT</pubDate>
    <description>

Why Independent Fine-Tuning Fails When LLMs Need</description>
    <content:encoded><![CDATA[
      <blockquote>This rendering is produced by marked and may have formatting issues. For the best experience, visit: <a href='https://carota.site/posts/books/magrpo-llm'>https://carota.site/posts/books/magrpo-llm</a></blockquote>
          <p></p>
<p>多 Agent LLM 系统现在很常见：一个负责规划，一个负责写代码，一个负责审查，一个负责总结。听起来像一个高效团队，但现实里经常出现一个问题：<strong>多个 LLM 被 prompt 临时组织起来，并不等于它们真的学会了协作</strong>。</p>
<p>Bohrium 这篇文章解读的 MAGRPO，全称是 <strong>Multi-Agent Group Relative Policy Optimization</strong>，它试图把“LLM 如何协作”从 prompt 工程问题，重新建模为一个多智能体强化学习问题。核心思想是：不要只靠提示词让多个模型“看起来像在配合”，而是在训练阶段用共享奖励让它们学会共同优化一个团队目标。(<a href="https://www.bohrium.com/en/blog/research-notes/aaai-2026-llm-collaboration-multi-agent-reinforcement-learning/" title="MAGRPO Explained: 3x Faster LLM Collaboration">Bohrium</a>)</p>
<h2>1. 为什么普通多 Agent Prompt 容易失败？</h2>
<p>很多多 Agent 系统本质上还是测试时编排：模型不变，只是在推理时通过 debate、discussion、review、sequential pipeline 等方式让它们交换输出。问题是，这些 Agent 并没有被训练成一个团队，它们只是被 prompt 临时要求“合作”。原论文指出，这类方法容易出现沟通低效、角色遵循不稳定、错误信息互相传播，以及 prompt/角色设计不清晰等问题。(<a href="https://ar5iv.org/html/2508.04652v7" title="[2508.04652] LLM Collaboration With Multi-Agent Reinforcement Learning">ar5iv</a>)</p>
<p>另一类方法是独立微调每个 Agent，比如给“规划者”“执行者”“审查者”分别设计奖励。但这又带来两个难点：</p>
<p>第一，<strong>奖励设计很复杂</strong>。你需要手动判断每个角色应该拿什么奖励，但协作任务的成功往往来自整体效果，很难拆成每个 Agent 的独立贡献。</p>
<p>第二，<strong>多智能体环境是非平稳的</strong>。当一个 Agent 的策略更新后，另一个 Agent 面对的“环境”也变了。这会让每个模型都在一个不断变化的环境里学习，收敛会更困难。原论文也明确批评了这类独立学习方法在非平稳环境下缺少可靠保证。(<a href="https://ar5iv.org/html/2508.04652v7" title="[2508.04652] LLM Collaboration With Multi-Agent Reinforcement Learning">ar5iv</a>)</p>
<p>所以，MAGRPO 要解决的不是“怎么写更好的多 Agent Prompt”，而是：</p>
<blockquote>
<p>能不能让多个 LLM 在训练时就围绕同一个团队目标学习，并在推理时仍然保持并行、高效、去中心化执行？</p>
</blockquote>
<h2>2. MAGRPO 的基本思路：训练时集中，执行时分散</h2>
<p></p>
<p>MAGRPO 把 LLM 协作建模为 <strong>Dec-POMDP</strong>，也就是 Decentralized Partially Observable Markov Decision Process，去中心化部分可观测马尔可夫决策过程。</p>
<p>这个名字很长，但直观理解并不复杂：</p>
<p>多个 Agent 共享一个最终目标，但每个 Agent 只能看到自己的局部输入。比如在协作写作中，一个 Agent 负责写摘要，另一个负责补充细节；在协作编程中，一个 Agent 写辅助函数，另一个 Agent 写主函数。它们不能直接读取彼此的内部状态，只能通过任务输入、历史输出或环境反馈间接协作。原论文把状态、局部观察、自然语言响应、共享奖励和回合限制都放进 Dec-POMDP 框架里，用它来描述 LLM 协作任务。(<a href="https://ar5iv.org/html/2508.04652v7" title="[2508.04652] LLM Collaboration With Multi-Agent Reinforcement Learning">ar5iv</a>)</p>
<p>MAGRPO 采用的是一种 <strong>Centralized Training, Decentralized Execution</strong> 的思路：</p>
<p>训练时，系统可以从整体结果计算一个共享奖励，判断多个 Agent 的联合输出好不好。</p>
<p>执行时，每个 Agent 不需要中心控制器逐步指挥，而是根据自己的局部上下文独立生成，多个 Agent 可以并行工作。</p>
<p>这点很关键。很多多 Agent 系统慢，是因为它们需要一轮轮对话、互相等待、反复汇总。MAGRPO 想要的是：<strong>协作能力在训练中学进去，推理时少沟通甚至不沟通，也能自然配合</strong>。</p>
<h2>3. MAGRPO 和 GRPO 的关系</h2>
<p>MAGRPO 是对 GRPO，也就是 Group Relative Policy Optimization 的多智能体扩展。</p>
<p>普通 GRPO 的一个重要思想是：不一定要训练一个额外的 value model，而是可以生成一组候选输出，然后用组内相对表现估计 advantage。MAGRPO 把这个思想扩展到多个 Agent 的联合输出上。</p>
<p>训练流程可以粗略理解为：</p>
<ol>
<li>从数据集中采样一个任务；</li>
<li>多个 Agent 根据自己的局部 prompt 分别生成多组响应；</li>
<li>把多个 Agent 的输出组合成联合动作；</li>
<li>环境或奖励模型给这些联合输出打一个共享奖励；</li>
<li>用组内平均表现作为基准，计算每组联合输出的相对优势；</li>
<li>用这个优势去更新每个 Agent 的策略。</li>
</ol>
<p>原论文特别强调，MAGRPO 不使用显式 value model，而是通过一组 Monte Carlo 样本估计当前状态的期望回报，从而获得一种集中式的 advantage 估计，再分别更新每个 Agent 的策略。(<a href="https://ar5iv.org/html/2508.04652v7" title="[2508.04652] LLM Collaboration With Multi-Agent Reinforcement Learning">ar5iv</a>)</p>
<p>这带来的好处是：它既不像传统 CTDE 方法那样依赖巨大的 centralized critic，也不像完全独立训练那样丢掉团队层面的反馈。它用“共享奖励 + 组内相对优势”在两者之间做了一个折中。</p>
<h2>4. 实验结果：协作不是多聊几轮，而是训练出来的</h2>
<p>原文和论文主要展示了两个方向的实验：协作写作和协作编程。</p>
<h3>4.1 协作写作</h3>
<p>写作实验包括 TLDR 摘要和 arXiv 摘要扩写。系统使用两个 Qwen3-1.7B Agent：一个负责更短的核心摘要，另一个负责更详细的总结或扩写。奖励由结构、风格一致性、逻辑连贯性等指标组合而成。(<a href="https://ar5iv.org/html/2508.04652v7" title="[2508.04652] LLM Collaboration With Multi-Agent Reinforcement Learning">ar5iv</a>)</p>
<p>结果很有意思：在 TLDR 任务上，MAGRPO 的速度是 202.3 tokens/s，响应时间约 2.1 秒；单个 Qwen3-4B 模型是 64.1 tokens/s，响应时间约 6.6 秒。也就是说，两个小模型并行协作，速度接近单个较大模型的 3 倍。更重要的是，MAGRPO 在 TLDR 上的 normalized return 达到 94.5%，明显高于 one-round discussion 的 22.3% 和 sequential generation 的 21.7%。(<a href="https://ar5iv.org/html/2508.04652v7" title="[2508.04652] LLM Collaboration With Multi-Agent Reinforcement Learning">ar5iv</a>)</p>
<p>这说明一个问题：<strong>多 Agent 的关键不是让模型“多讨论”，而是让它们在训练中学会稳定分工</strong>。</p>
<h3>4.2 协作编程</h3>
<p>编程实验里，论文让两个 Qwen2.5-Coder-3B Agent 协作生成 Python 函数：一个生成辅助函数，另一个生成主函数。它们的输出会被拼接成完整代码，并通过结构完整性、语法正确性、单元测试通过率和协作质量来评估。(<a href="https://ar5iv.org/html/2508.04652v7" title="[2508.04652] LLM Collaboration With Multi-Agent Reinforcement Learning">ar5iv</a>)</p>
<p>在 HumanEval 和 CoopHumanEval 上，MAGRPO 的结果整体优于 naive concatenation、sequential pipeline 和 one-round discussion 等 prompt-based baseline。尤其在 CoopHumanEval 这种更适合协作拆解的数据集上，multi-turn MAGRPO 的总回报达到 88.1%，明显高于其他 baseline。(<a href="https://ar5iv.org/html/2508.04652v7" title="[2508.04652] LLM Collaboration With Multi-Agent Reinforcement Learning">ar5iv</a>)</p>
<p>这里还有一个细节很重要：普通 HumanEval 中很多题本身并不适合拆成两个 Agent 协作，比如一个很短的原子函数。论文因此构造了 CoopHumanEval，让任务更具备协作结构。结果显示，当数据本身更适合分工，MAGRPO 的训练效果更稳定，回报也更高。(<a href="https://ar5iv.org/html/2508.04652v7" title="[2508.04652] LLM Collaboration With Multi-Agent Reinforcement Learning">ar5iv</a>)</p>
<p>这对工程落地很有启发：<strong>多 Agent 不应该强行套在所有任务上，它更适合那些天然可以模块化、并且有清晰反馈信号的任务。</strong></p>
<h2>5. MAGRPO 学到的不是固定流程，而是协作模式</h2>
<p>在协作编程中，论文观察到 MAGRPO 会自然形成几类合作模式：</p>
<p>一种是 <strong>fallback</strong>。辅助函数尝试完成核心逻辑，主函数保留一套兜底逻辑，避免辅助函数出错导致整体失败。</p>
<p>一种是 <strong>decorator</strong>。辅助函数完成主要逻辑，主函数负责边界处理、格式整理或额外健壮性增强。</p>
<p>还有一些更主动的模式，比如主函数像 coordinator 一样拆解问题，或者辅助函数像 strategy filter 一样引导主函数处理特定情况。论文认为，这些合作模式是在简单共享奖励下自然涌现出来的。(<a href="https://ar5iv.org/html/2508.04652v7" title="[2508.04652] LLM Collaboration With Multi-Agent Reinforcement Learning">ar5iv</a>)</p>
<p>这也是 MAGRPO 最值得关注的地方：它不是写死一个 workflow，而是让多个 Agent 在奖励驱动下学出适合任务的协作策略。</p>
<h2>6. 它适合什么场景？</h2>
<p>MAGRPO 最适合下面这类任务：</p>
<p>任务可以拆成多个相对稳定的角色，比如摘要/扩写、主函数/辅助函数、前端/后端、规划/执行。</p>
<p>任务有可自动验证或半自动验证的奖励信号，比如单元测试、格式检查、结构约束、风格一致性、集成测试结果。</p>
<p>推理速度很重要，希望多个小模型并行执行，而不是一个大模型串行完成所有工作。</p>
<p>任务会反复出现，值得通过训练把协作模式沉淀进模型权重，而不是每次都靠 prompt 临时协调。</p>
<p>原文也提到，MAGRPO 可以启发软件开发、创意写作、隐私保护型诊断、多角色金融分析等应用。但其中很多属于长期设想，真正落地仍然依赖可验证奖励、数据质量和安全控制。(<a href="https://www.bohrium.com/en/blog/research-notes/aaai-2026-llm-collaboration-multi-agent-reinforcement-learning/" title="MAGRPO Explained: 3x Faster LLM Collaboration">Bohrium</a>)</p>
<h2>7. 局限性：这还不是“通用 Agent 团队训练法”</h2>
<p>MAGRPO 的局限也很明显。</p>
<p>首先，目前实验主要集中在短 horizon 任务，比如摘要、扩写、函数级代码生成。长周期任务，例如完整软件项目、长篇小说、多日研究流程，可能仍然需要显式通信、共享记忆和阶段性规划。Bohrium 原文也指出，当前结果还不能证明这种隐式协调能稳定扩展到极长上下文场景。(<a href="https://www.bohrium.com/en/blog/research-notes/aaai-2026-llm-collaboration-multi-agent-reinforcement-learning/" title="MAGRPO Explained: 3x Faster LLM Collaboration">Bohrium</a>)</p>
<p>其次，奖励设计并没有消失，只是从“给每个 Agent 手工设计奖励”变成了“给联合输出设计共享奖励”。在代码任务里，单元测试是天然反馈；但在开放式产品设计、复杂研究、商业决策中，什么是好结果并不总是容易量化。</p>
<p>第三，MAGRPO 的优势和数据结构强相关。论文中 CoopHumanEval 比原始 HumanEval 更适合协作，因此效果更好。这说明训练多 Agent 时，数据集本身是否具备可分工结构非常关键。(<a href="https://ar5iv.org/html/2508.04652v7" title="[2508.04652] LLM Collaboration With Multi-Agent Reinforcement Learning">ar5iv</a>)</p>
<p>最后，论文中的 baseline 多数仍是 prompt-based 方法，而不是其他强力 fine-tuned 多 Agent 方法。因此，MAGRPO 证明了“训练协作优于临时 prompt 协作”，但还需要和更多多智能体训练算法进一步比较。</p>
<h2>8. 对 Agent 工程的启发</h2>
<p>MAGRPO 给 Agent 系统设计带来的最大启发是：<strong>协作不应该只停留在 prompt 编排层，而应该进入训练目标层。</strong></p>
<p>今天很多 Agent 框架的核心是“搭流程”：谁先说，谁后说，谁 review，谁总结。这个方向当然有用，但它更像是在组织一群没有磨合过的人开会。MAGRPO 的思路更像是训练一支长期配合的团队：每个成员不需要每一步都开会，但知道自己在什么位置、该如何输出、如何和别人的结果形成整体最优。</p>
<p>对工程实践来说，可以总结成三句话：</p>
<p>第一，不要迷信“多 Agent = 更强”。如果没有共享目标和反馈信号，多 Agent 可能只是更贵、更慢、更难 debug。</p>
<p>第二，优先选择有明确验证信号的任务做多 Agent 训练，比如代码生成、数据处理、报告生成、结构化写作。</p>
<p>第三，小模型并行协作可能比单个大模型串行执行更高效，但前提是这些小模型经过面向协作的训练，而不是只靠 prompt 分工。</p>
<h2>结语</h2>
<p>MAGRPO 的价值不只是提出了一个新算法，而是把多 Agent LLM 的问题重新摆正了：</p>
<blockquote>
<p>多 Agent 系统真正难的不是让模型互相说话，而是让它们围绕同一个目标形成稳定、可泛化、可并行执行的协作策略。</p>
</blockquote>
<p>如果未来 Agent 系统要从 demo 走向真实生产环境，光靠 prompt orchestration 可能不够。像 MAGRPO 这样的多智能体强化学习方法，可能会成为训练“专业 AI 团队”的关键路径之一。</p>
<p>参考：Bohrium 原文解读、arXiv 论文《LLM Collaboration With Multi-Agent Reinforcement Learning》，以及作者开源的 CoMLRL 框架。CoMLRL 提供了用于训练多个 LLM 协作的 MARL 算法实现，并包含 writing、coding、Minecraft 等环境和 benchmark。(<a href="https://www.bohrium.com/en/blog/research-notes/aaai-2026-llm-collaboration-multi-agent-reinforcement-learning/" title="MAGRPO Explained: 3x Faster LLM Collaboration">Bohrium</a>)</p>

          <p style='text-align: right'>
          <a href='https://carota.site/posts/books/magrpo-llm#comments'>Finished reading? Leave a comment</a>
          </p>
    ]]>
    </content:encoded>
  <guid isPermaLink="false">151961292196810752</guid>
  <category>post</category>
<category>阅读</category>
 </item>
  <item>
    <title>从 MDP 到 Dec-POMDP：理解单智能体与多智能体决策模型的差异</title>
    <link>https://carota.site/posts/books/mdp-dec-pomdp</link>
    <pubDate>Thu, 25 Jun 2026 07:47:12 GMT</pubDate>
    <description>

在强化学习和多智能体系统中，经常会遇到几个层层递进的概念：MDP、POMDP、Dec-POMDP</description>
    <content:encoded><![CDATA[
      <blockquote>This rendering is produced by marked and may have formatting issues. For the best experience, visit: <a href='https://carota.site/posts/books/mdp-dec-pomdp'>https://carota.site/posts/books/mdp-dec-pomdp</a></blockquote>
          <p>在强化学习和多智能体系统中，经常会遇到几个层层递进的概念：<strong>MDP、POMDP、Dec-POMDP</strong>。</p>
<p>它们都在描述“智能体如何在环境中连续做决策”，但它们对智能体数量、状态可见性、信息共享方式的假设并不相同。</p>
<p>本文主要对比 <strong>MDP</strong> 和 <strong>Dec-POMDP</strong>，并顺带引入 <strong>POMDP</strong> 作为中间桥梁，帮助理解它们之间的演进关系。</p>
<hr>
<h2>1. MDP：完整可观测下的单智能体决策</h2>
<p><strong>MDP</strong> 全称是 <strong>Markov Decision Process</strong>，中文叫 <strong>马尔可夫决策过程</strong>。</p>
<p>它描述的是：</p>
<blockquote>
<p>一个智能体在能够观察完整环境状态的情况下，如何选择动作来最大化长期累计收益。</p>
</blockquote>
<p>一个 MDP 通常可以表示为：</p>
<p><span class="katex-render">$
\mathcal{M} = (S, A, P, R, \gamma)
$</span></p>
<p>其中：</p>
<ul>
<li><span class="katex-render">S</span>：状态集合，表示环境可能处于哪些状态；</li>
<li><span class="katex-render">A</span>：动作集合，表示智能体可以执行哪些动作；</li>
<li><span class="katex-render">P(s' \mid s, a)</span>：状态转移概率，表示在状态 <span class="katex-render">s</span> 下执行动作 <span class="katex-render">a</span> 后进入状态 <span class="katex-render">s'</span> 的概率；</li>
<li><span class="katex-render">R(s, a)</span>：奖励函数，表示在状态 <span class="katex-render">s</span> 下执行动作 <span class="katex-render">a</span> 可以获得的即时奖励；</li>
<li><span class="katex-render">\gamma</span>：折扣因子，用来衡量未来奖励的重要性。</li>
</ul>
<p>MDP 的核心假设是 <strong>马尔可夫性</strong>：</p>
<p>$$
P(s_{t+1} \mid s_t, a_t, s_{t-1}, a_{t-1}, \dots)</p>
<p>P(s_{t+1} \mid s_t, a_t)
$$</p>
<p>它的意思是：</p>
<blockquote>
<p>下一步会发生什么，只取决于当前状态和当前动作，而不取决于更早的历史。</p>
</blockquote>
<p>也就是说，只要当前状态 <span class="katex-render">s_t</span> 已经包含了足够的信息，智能体就不需要再关心过去发生了什么。</p>
<hr>
<h2>2. Bellman 方程：MDP 的核心思想</h2>
<p>在 MDP 中，一个非常重要的公式是 <strong>Bellman 最优方程</strong>：</p>
<p><span class="katex-render">$
V(s) = \max_a \left[ R(s, a) + \gamma \sum_{s'} P(s' \mid s, a) V(s') \right]
$</span></p>
<p>这个公式表达的是：</p>
<blockquote>
<p>当前状态的最优价值，等于在所有可选动作中，选择那个“当前奖励 + 折扣后的未来期望价值”最大的动作。</p>
</blockquote>
<p>拆开来看，<span class="katex-render">V(s)</span> 表示状态 <span class="katex-render">s</span> 的价值，也就是从状态 <span class="katex-render">s</span> 出发，之后都采取最优策略时，能够获得的长期期望收益。</p>
<p><span class="katex-render">R(s, a)</span> 表示当前这一步马上获得的奖励。</p>
<p>而这一项：</p>
<p><span class="katex-render">$
\sum_{s'} P(s' \mid s, a) V(s')
$</span></p>
<p>表示执行动作 <span class="katex-render">a</span> 后，未来可能进入多个不同状态。每个状态 <span class="katex-render">s'</span> 有不同的发生概率 <span class="katex-render">P(s' \mid s, a)</span>，也有自己的价值 <span class="katex-render">V(s')</span>，因此需要对这些未来状态价值做加权平均。</p>
<p>再乘上折扣因子：</p>
<p><span class="katex-render">$
\gamma \sum_{s'} P(s' \mid s, a) V(s')
$</span></p>
<p>表示折扣后的未来期望价值。</p>
<p>所以这一整项：</p>
<p><span class="katex-render">$
R(s, a) + \gamma \sum_{s'} P(s' \mid s, a) V(s')
$</span></p>
<p>表示：</p>
<blockquote>
<p>在状态 <span class="katex-render">s</span> 下选择动作 <span class="katex-render">a</span>，能够带来的总价值。</p>
</blockquote>
<p>最后外面的 <span class="katex-render">\max_a</span> 表示：</p>
<blockquote>
<p>在所有可能动作中，选择总价值最大的那个动作。</p>
</blockquote>
<p>因此，Bellman 方程本质上是在说：</p>
<blockquote>
<p>一个动作好不好，不只取决于它眼前能带来多少奖励，还取决于它会把智能体带到什么样的未来状态。</p>
</blockquote>
<p>这也是动态规划、Q-learning、DQN、PPO 等强化学习方法的重要理论基础。</p>
<hr>
<h2>3. POMDP：当智能体看不清完整状态</h2>
<p>MDP 有一个较强的假设：智能体能够知道完整的当前状态。</p>
<p>但现实中，很多场景并不满足这个条件。</p>
<p>例如：</p>
<ul>
<li>自动驾驶汽车无法知道所有车辆的真实意图；</li>
<li>机器人只能通过摄像头看到局部环境；</li>
<li>游戏 AI 可能看不到地图上的全部敌人；</li>
<li>推荐系统无法完全知道用户真实偏好。</li>
</ul>
<p>这时就需要 <strong>POMDP</strong>。</p>
<p><strong>POMDP</strong> 全称是 <strong>Partially Observable Markov Decision Process</strong>，中文叫 <strong>部分可观测马尔可夫决策过程</strong>。</p>
<p>相比 MDP，POMDP 多了一个核心概念：<strong>观察 Observation</strong>。</p>
<p>POMDP 通常可以表示为：</p>
<p><span class="katex-render">$
\mathcal{M} = (S, A, P, R, \Omega, O, \gamma)
$</span></p>
<p>其中：</p>
<ul>
<li><span class="katex-render">S</span>：真实状态集合；</li>
<li><span class="katex-render">A</span>：动作集合；</li>
<li><span class="katex-render">P</span>：状态转移函数；</li>
<li><span class="katex-render">R</span>：奖励函数；</li>
<li><span class="katex-render">\Omega</span>：观察集合；</li>
<li><span class="katex-render">O(o \mid s', a)</span>：观察概率函数；</li>
<li><span class="katex-render">\gamma</span>：折扣因子。</li>
</ul>
<p>在 POMDP 中，智能体看不到真实状态 <span class="katex-render">s</span>，只能看到一个局部观察 <span class="katex-render">o</span>。</p>
<p>因此，策略不再直接写成：</p>
<p><span class="katex-render">$
\pi(a \mid s)
$</span></p>
<p>而更像是：</p>
<p><span class="katex-render">$
\pi(a \mid o)
$</span></p>
<p>不过更准确地说，智能体通常需要根据历史观察和历史动作维护一个 belief，也就是对真实状态的概率估计：</p>
<p><span class="katex-render">$
b(s) = P(s \mid h)
$</span></p>
<p>其中 <span class="katex-render">h</span> 表示智能体过去经历过的观察和动作历史。</p>
<p>belief 可以理解为：</p>
<blockquote>
<p>智能体对“当前真实状态是什么”的概率分布。</p>
</blockquote>
<p>例如，一个机器人在迷宫中移动，但它的传感器不够精确。它可能会认为：</p>
<p><span class="katex-render">$
b(s_A) = 0.7
$</span></p>
<p><span class="katex-render">$
b(s_B) = 0.2
$</span></p>
<p><span class="katex-render">$
b(s_C) = 0.1
$</span></p>
<p>也就是说，它认为自己有 <span class="katex-render">70%</span> 的概率在位置 <span class="katex-render">A</span>，<span class="katex-render">20%</span> 的概率在位置 <span class="katex-render">B</span>，<span class="katex-render">10%</span> 的概率在位置 <span class="katex-render">C</span>。</p>
<p>这就是 POMDP 比 MDP 更难的地方：智能体不仅要做决策，还要推断自己到底处于什么状态。</p>
<hr>
<h2>4. Dec-POMDP：多个智能体，各自只能看到局部信息</h2>
<p><strong>Dec-POMDP</strong> 全称是 <strong>Decentralized Partially Observable Markov Decision Process</strong>，中文可以叫 <strong>去中心化部分可观测马尔可夫决策过程</strong>。</p>
<p>它可以理解成 POMDP 的多智能体版本。</p>
<p>如果用一句话对比：</p>
<ul>
<li>MDP：一个智能体，能看到完整状态；</li>
<li>POMDP：一个智能体，只能看到局部观察；</li>
<li>Dec-POMDP：多个智能体，每个智能体都只能看到自己的局部观察。</li>
</ul>
<p>Dec-POMDP 描述的是：</p>
<blockquote>
<p>多个智能体在无法看到完整环境、也无法完全知道彼此信息的情况下，如何协作完成一个共同目标。</p>
</blockquote>
<p>一个 Dec-POMDP 通常可以表示为：</p>
<p><span class="katex-render">$
\mathcal{M} = (S, {A_i}*{i=1}^{n}, T, R, {\Omega_i}*{i=1}^{n}, O, \gamma)
$</span></p>
<p>其中：</p>
<ul>
<li><span class="katex-render">S</span>：全局真实状态集合；</li>
<li><span class="katex-render">A_i</span>：第 <span class="katex-render">i</span> 个智能体的动作集合；</li>
<li><span class="katex-render">T</span>：状态转移函数；</li>
<li><span class="katex-render">R</span>：团队共享奖励函数；</li>
<li><span class="katex-render">\Omega_i</span>：第 <span class="katex-render">i</span> 个智能体的观察集合；</li>
<li><span class="katex-render">O</span>：观察概率函数；</li>
<li><span class="katex-render">\gamma</span>：折扣因子；</li>
<li><span class="katex-render">n</span>：智能体数量。</li>
</ul>
<p>在 Dec-POMDP 中，每个智能体 <span class="katex-render">i</span> 都有自己的动作 <span class="katex-render">a_i</span>。</p>
<p>所有智能体的动作组合在一起，形成联合动作：</p>
<p><span class="katex-render">$
\mathbf{a} = (a_1, a_2, \dots, a_n)
$</span></p>
<p>环境根据当前真实状态 <span class="katex-render">s</span> 和联合动作 <span class="katex-render">\mathbf{a}</span> 转移到下一个状态 <span class="katex-render">s'</span>：</p>
<p><span class="katex-render">$
P(s' \mid s, \mathbf{a})
$</span></p>
<p>或者写成：</p>
<p><span class="katex-render">$
P(s' \mid s, a_1, a_2, \dots, a_n)
$</span></p>
<p>每个智能体会收到自己的局部观察：</p>
<p><span class="katex-render">$
o_i \in \Omega_i
$</span></p>
<p>整个团队获得一个共享奖励：</p>
<p><span class="katex-render">$
R(s, \mathbf{a})
$</span></p>
<p>目标是最大化团队的长期累计奖励：</p>
<p><span class="katex-render">$
\mathbb{E} \left[ \sum_{t=0}^{\infty} \gamma^t R(s_t, \mathbf{a}_t) \right]
$</span></p>
<hr>
<h2>5. Decentralized 到底是什么意思？</h2>
<p>Dec-POMDP 中的 <strong>Decentralized</strong>，重点不是说训练时一定不能使用集中信息，而是说：</p>
<blockquote>
<p>执行时，每个智能体只能根据自己的局部信息独立做决策。</p>
</blockquote>
<p>在 MDP 中，策略通常可以写成：</p>
<p><span class="katex-render">$
\pi(a \mid s)
$</span></p>
<p>意思是：</p>
<blockquote>
<p>给定完整状态 <span class="katex-render">s</span>，选择动作 <span class="katex-render">a</span>。</p>
</blockquote>
<p>但在 Dec-POMDP 中，第 <span class="katex-render">i</span> 个智能体看不到完整状态 <span class="katex-render">s</span>，它只能根据自己的局部历史 <span class="katex-render">h_i</span> 选择动作：</p>
<p><span class="katex-render">$
\pi_i(a_i \mid h_i)
$</span></p>
<p>这里的 <span class="katex-render">h_i</span> 可以表示：</p>
<p><span class="katex-render">$
h_i = (o_i^0, a_i^0, o_i^1, a_i^1, \dots, o_i^t)
$</span></p>
<p>也就是说，第 <span class="katex-render">i</span> 个智能体只能基于自己过去看到过什么、做过什么，以及当前观察到了什么来决策。</p>
<p>多个智能体的局部策略组合起来，形成联合策略：</p>
<p><span class="katex-render">$
\boldsymbol{\pi} = (\pi_1, \pi_2, \dots, \pi_n)
$</span></p>
<p>Dec-POMDP 要求我们寻找一个最优联合策略：</p>
<p><span class="katex-render">$
\boldsymbol{\pi}^* = \arg\max_{\boldsymbol{\pi}} \mathbb{E}*{\boldsymbol{\pi}} \left[ \sum*{t=0}^{\infty} \gamma^t R(s_t, \mathbf{a}_t) \right]
$</span></p>
<p>这就是 Dec-POMDP 的核心问题。</p>
<hr>
<h2>6. 一个直观例子：仓库机器人协作</h2>
<p>假设有两个机器人在仓库中寻找并搬运一个包裹。</p>
<p>如果用 MDP 建模，问题可能是：</p>
<ul>
<li>只有一个机器人；</li>
<li>它知道完整仓库地图；</li>
<li>它知道自己和包裹的准确位置；</li>
<li>它每一步选择上、下、左、右；</li>
<li>目标是用最短路径找到包裹。</li>
</ul>
<p>这时，机器人的策略可以写成：</p>
<p><span class="katex-render">$
\pi(a \mid s)
$</span></p>
<p>也就是根据完整状态 <span class="katex-render">s</span> 选择动作 <span class="katex-render">a</span>。</p>
<p>但在 Dec-POMDP 中，情况会变成：</p>
<ul>
<li>有多个机器人；</li>
<li>每个机器人只能看到自己附近的区域；</li>
<li>机器人之间不能实时共享所有信息；</li>
<li>每个机器人都不知道其他机器人具体观察到了什么；</li>
<li>它们需要协作完成寻找和搬运任务；</li>
<li>最终奖励由整个团队共享。</li>
</ul>
<p>比如：</p>
<ul>
<li>机器人 A 可能看到了包裹；</li>
<li>机器人 B 没看到包裹，但看到了通道堵塞；</li>
<li>A 不一定知道 B 的观察；</li>
<li>B 也不一定知道 A 的观察；</li>
<li>但它们仍然要通过各自的局部决策完成协作。</li>
</ul>
<p>此时，两个机器人的联合动作可以写成：</p>
<p><span class="katex-render">$
\mathbf{a} = (a_A, a_B)
$</span></p>
<p>环境转移可以写成：</p>
<p><span class="katex-render">$
P(s' \mid s, a_A, a_B)
$</span></p>
<p>共享奖励可以写成：</p>
<p><span class="katex-render">$
R(s, a_A, a_B)
$</span></p>
<p>机器人 A 和机器人 B 的策略分别是：</p>
<p><span class="katex-render">$
\pi_A(a_A \mid h_A)
$</span></p>
<p><span class="katex-render">$
\pi_B(a_B \mid h_B)
$</span></p>
<p>其中 <span class="katex-render">h_A</span> 和 <span class="katex-render">h_B</span> 分别是两个机器人各自的局部历史。</p>
<p>这就是 Dec-POMDP 的核心难点：</p>
<blockquote>
<p>每个智能体都只掌握不完整的信息，但最终要形成全局协作行为。</p>
</blockquote>
<hr>
<h2>7. MDP 与 Dec-POMDP 的核心区别</h2>
<table>
<thead>
<tr>
<th>维度</th>
<th>MDP</th>
<th>Dec-POMDP</th>
</tr>
</thead>
<tbody><tr>
<td>智能体数量</td>
<td>单个智能体</td>
<td>多个智能体</td>
</tr>
<tr>
<td>状态可见性</td>
<td>完整可观测</td>
<td>部分可观测</td>
</tr>
<tr>
<td>决策方式</td>
<td>基于全局状态决策</td>
<td>每个智能体基于自己的局部观察或局部历史决策</td>
</tr>
<tr>
<td>动作形式</td>
<td>单个动作 <span class="katex-render">a</span></td>
<td>联合动作 <span class="katex-render">\mathbf{a} = (a_1, a_2, \dots, a_n)</span></td>
</tr>
<tr>
<td>奖励形式</td>
<td>单个智能体奖励 <span class="katex-render">R(s, a)</span></td>
<td>团队共享奖励 <span class="katex-render">R(s, \mathbf{a})</span></td>
</tr>
<tr>
<td>策略形式</td>
<td><span class="katex-render">\pi(a \mid s)</span></td>
<td><span class="katex-render">\pi_i(a_i \mid h_i)</span></td>
</tr>
<tr>
<td>难点</td>
<td>如何选择长期收益最大的动作</td>
<td>局部观察、信息不对称、协作、联合动作空间膨胀</td>
</tr>
<tr>
<td>典型应用</td>
<td>游戏、路径规划、基础强化学习</td>
<td>多机器人协作、多智能体强化学习、分布式传感器、协同控制</td>
</tr>
</tbody></table>
<hr>
<h2>8. 为什么 Dec-POMDP 比 MDP 难很多？</h2>
<p>MDP 的核心问题是：</p>
<blockquote>
<p>当前状态下，如何选择最优动作？</p>
</blockquote>
<p>但 Dec-POMDP 的难点是多层叠加的。</p>
<h3>8.1 每个智能体看不到完整状态</h3>
<p>在 MDP 中，智能体知道当前状态 <span class="katex-render">s</span>。</p>
<p>但在 Dec-POMDP 中，每个智能体只能看到自己的局部观察 <span class="katex-render">o_i</span>：</p>
<p><span class="katex-render">$
o_i \sim O_i(o_i \mid s)
$</span></p>
<p>这意味着智能体必须先推断环境，再做决策。</p>
<hr>
<h3>8.2 每个智能体不知道其他智能体看到了什么</h3>
<p>在多智能体协作中，一个智能体不仅要考虑环境，还要考虑队友。</p>
<p>但问题是：</p>
<blockquote>
<p>我不知道队友看到了什么，也不知道队友会如何判断，但我还要和它配合。</p>
</blockquote>
<p>这会导致协作难度显著上升。</p>
<hr>
<h3>8.3 联合动作空间会快速膨胀</h3>
<p>如果有 <span class="katex-render">n</span> 个智能体，每个智能体都有 <span class="katex-render">m</span> 个动作，那么联合动作空间大小是：</p>
<p><span class="katex-render">$
|A| = m^n
$</span></p>
<p>例如，5 个机器人，每个机器人有 10 个动作，那么联合动作空间就是：</p>
<p><span class="katex-render">$
10^5 = 100000
$</span></p>
<p>这意味着动作组合数量会随着智能体数量指数级增长。</p>
<hr>
<h3>8.4 历史信息也会快速膨胀</h3>
<p>在 MDP 中，智能体可以直接根据当前状态 <span class="katex-render">s_t</span> 做决策。</p>
<p>但在 Dec-POMDP 中，每个智能体通常要基于自己的历史信息 <span class="katex-render">h_i^t</span> 做决策：</p>
<p><span class="katex-render">$
h_i^t = (o_i^0, a_i^0, o_i^1, a_i^1, \dots, o_i^t)
$</span></p>
<p>随着时间步 <span class="katex-render">t</span> 增长，可能的历史轨迹数量也会快速增加。</p>
<p>因此，Dec-POMDP 通常比 MDP 难求解得多。</p>
<hr>
<h2>9. 从 MDP 到 Dec-POMDP 的演进关系</h2>
<p>可以用下面这个路径来理解：</p>
<p>$$
\text{MDP：}</p>
<p>\text{Single-Agent}
+
\text{Fully Observable}
$$</p>
<p>$$
\text{POMDP：}</p>
<p>\text{Single-Agent}
+
\text{Partially Observable}
$$</p>
<p>$$
\text{Dec-POMDP：}</p>
<p>\text{Multi-Agent}
+
\text{Partially Observable}
+
\text{Decentralized Execution}
$$</p>
<p>也就是说，Dec-POMDP 在 MDP 的基础上同时增加了两个复杂度：</p>
<p><span class="katex-render">$
\text{Single-Agent} \rightarrow \text{Multi-Agent}
$</span></p>
<p><span class="katex-render">$
\text{Fully Observable} \rightarrow \text{Partially Observable}
$</span></p>
<p>如果再加上去中心化执行的限制，问题会进一步复杂化。</p>
<hr>
<h2>10. 集中训练，去中心化执行</h2>
<p>在现代多智能体强化学习中，经常会使用一种范式：</p>
<blockquote>
<p>Centralized Training, Decentralized Execution，简称 CTDE。</p>
</blockquote>
<p>它的意思是：</p>
<p>训练时，可以使用更多全局信息，例如完整状态 <span class="katex-render">s</span>、所有智能体的动作 <span class="katex-render">\mathbf{a}</span>、全局奖励 <span class="katex-render">R</span>。</p>
<p>但执行时，每个智能体仍然只能根据自己的局部历史 <span class="katex-render">h_i</span> 做决策：</p>
<p><span class="katex-render">$
\pi_i(a_i \mid h_i)
$</span></p>
<p>这种方式试图在训练效率和部署约束之间取得平衡。</p>
<p>也就是说，训练时可以“开上帝视角”，但真正执行时，每个智能体仍然必须只依赖自己的局部信息。</p>
<hr>
<h2>11. 总结</h2>
<p>MDP 和 Dec-POMDP 都是在描述序列决策问题，但它们适用的场景不同。</p>
<p>MDP 更适合描述：</p>
<ul>
<li>单个智能体；</li>
<li>能够观察完整状态；</li>
<li>根据当前状态做动作选择；</li>
<li>目标是最大化长期累计奖励。</li>
</ul>
<p>它的策略形式通常是：</p>
<p><span class="katex-render">$
\pi(a \mid s)
$</span></p>
<p>它的目标可以写成：</p>
<p><span class="katex-render">$
\pi^* = \arg\max_{\pi} \mathbb{E}*{\pi} \left[ \sum*{t=0}^{\infty} \gamma^t R(s_t, a_t) \right]
$</span></p>
<p>Dec-POMDP 更适合描述：</p>
<ul>
<li>多个智能体；</li>
<li>每个智能体只能看到局部信息；</li>
<li>执行时没有中心控制器；</li>
<li>所有智能体需要协作完成共同目标。</li>
</ul>
<p>它的局部策略形式通常是：</p>
<p><span class="katex-render">$
\pi_i(a_i \mid h_i)
$</span></p>
<p>它的联合优化目标可以写成：</p>
<p><span class="katex-render">$
\boldsymbol{\pi}^* = \arg\max_{\boldsymbol{\pi}} \mathbb{E}*{\boldsymbol{\pi}} \left[ \sum*{t=0}^{\infty} \gamma^t R(s_t, \mathbf{a}_t) \right]
$</span></p>
<p>一句话总结：</p>
<blockquote>
<p>MDP 是强化学习中最基础的单智能体决策模型；Dec-POMDP 则是面向多智能体、部分可观测、去中心化协作场景的更复杂模型。</p>
</blockquote>
<p>如果说 MDP 关心的是：</p>
<blockquote>
<p>我在当前状态下应该做什么？</p>
</blockquote>
<p>那么 Dec-POMDP 关心的是：</p>
<blockquote>
<p>我们每个人都只知道一部分信息，在无法完全共享视野的情况下，应该如何配合？</p>
</blockquote>
<p>这也是 Dec-POMDP 在多机器人协作、自动驾驶车队、分布式控制、多智能体强化学习中非常重要的原因。</p>

          <p style='text-align: right'>
          <a href='https://carota.site/posts/books/mdp-dec-pomdp#comments'>Finished reading? Leave a comment</a>
          </p>
    ]]>
    </content:encoded>
  <guid isPermaLink="false">151958094153256960</guid>
  <category>post</category>
<category>阅读</category>
 </item>
  <item>
    <title>rsync 的实现原理：它为什么能快速同步两个文件？</title>
    <link>https://carota.site/posts/tech/rsync-analyze</link>
    <pubDate>Thu, 25 Jun 2026 06:34:45 GMT</pubDate>
    <description>在日常开发和运维中，rsync 是一个非常常见的文件同步工具。相比 cp、scp 这类直接复制工具，</description>
    <content:encoded><![CDATA[
      <blockquote>This rendering is produced by marked and may have formatting issues. For the best experience, visit: <a href='https://carota.site/posts/tech/rsync-analyze'>https://carota.site/posts/tech/rsync-analyze</a></blockquote>
          <p>在日常开发和运维中，<code>rsync</code> 是一个非常常见的文件同步工具。相比 <code>cp</code>、<code>scp</code> 这类直接复制工具，<code>rsync</code> 最大的特点是：<strong>它不一定会把整个文件重新传输，而是尽量只传输变化的部分</strong>。</p>
<p>这篇文章会从三个问题入手解释 rsync 的核心原理：</p>
<ol>
<li>rsync 如何快速判断两个文件是否需要同步？</li>
<li>rsync 如何只传输文件中的差异部分？</li>
<li>rolling checksum 和 strong checksum 是如何协作的？</li>
</ol>
<p>--</p>
<h2>1. rsync 解决的核心问题</h2>
<p>假设我们有两个文件：</p>
<pre><code class="language-text">源端新文件：A
目标端旧文件：B</code></pre><p>我们希望把目标端的 <code>B</code> 更新成源端的 <code>A</code>。</p>
<p>最简单的做法是直接把 <code>A</code> 整个传过去，覆盖 <code>B</code>：</p>
<pre><code class="language-bash">scp A remote:/path/B</code></pre><p>但是如果文件很大，比如几个 GB，而实际只改了其中几 KB，那么整体传输就很浪费。</p>
<p>rsync 的目标就是：</p>
<pre><code class="language-text">尽量复用目标端已经存在的数据，只传输真正变化的部分。</code></pre><p>这就是 rsync 的核心价值。</p>
<hr>
<h2>2. rsync 默认如何判断文件是否一致？</h2>
<p>很多人以为 rsync 默认会对文件内容做 hash 校验，其实不是。</p>
<p>默认情况下，rsync 会使用一种很快的判断方式，通常叫做 quick check。</p>
<p>它主要看两个元信息：</p>
<pre><code class="language-text">1. 文件大小 size
2. 最后修改时间 mtime</code></pre><p>如果源端和目标端的文件大小一致，并且修改时间也一致，rsync 默认会认为这个文件没有变化，不需要同步。</p>
<p>所以执行：</p>
<pre><code class="language-bash">rsync -av src/ dst/</code></pre><p>时，大多数未变化文件会被快速跳过。因为读取文件大小和修改时间只需要访问文件元数据，不需要把整个文件读一遍。</p>
<p>这也是 rsync 在同步大量文件时很快的原因之一。</p>
<p>不过，这种判断不是严格的内容校验。如果文件内容被修改了，但文件大小没变，而且修改时间也被人为恢复成原来的值，那么默认 rsync 可能无法发现变化。</p>
<p>如果你希望严格按文件内容判断，可以使用：</p>
<pre><code class="language-bash">rsync -avc src/ dst/</code></pre><p>其中 <code>-c</code> 或 <code>--checksum</code> 会让 rsync 计算文件内容的 checksum，再判断文件是否一致。</p>
<p>代价是：两端都要读取完整文件内容，所以会明显增加磁盘 I/O。</p>
<p>简单总结：</p>
<pre><code class="language-text">默认模式：size + mtime，速度快，但不是严格内容校验
checksum 模式：按内容校验，更可靠，但更慢</code></pre><hr>
<h2>3. rsync 真正厉害的地方：差异传输</h2>
<p>当 rsync 判断某个文件需要更新时，它并不一定会把整个文件重新传过去。</p>
<p>它会尝试找出：</p>
<pre><code class="language-text">源端新文件 A 中，哪些内容目标端旧文件 B 已经有了？
哪些内容是目标端没有的，需要真正传输？</code></pre><p>这个过程就是 rsync 的 delta-transfer algorithm，也就是差异传输算法。</p>
<p>核心思想可以概括为一句话：</p>
<pre><code class="language-text">目标端告诉源端：我已有这些数据块；
源端扫描新文件：发现哪些块你已经有了，我就不传，只传你没有的部分。</code></pre><hr>
<h2>4. 差异传输的基本流程</h2>
<p>假设目标端已有旧文件 <code>B</code>。</p>
<p>第一步，目标端会把旧文件 <code>B</code> 切成固定大小的 block：</p>
<pre><code class="language-text">B = [B0][B1][B2][B3][B4]...</code></pre><p>然后目标端会为每个 block 计算两个 checksum：</p>
<pre><code class="language-text">B0 -&gt; weak0, strong0
B1 -&gt; weak1, strong1
B2 -&gt; weak2, strong2
...</code></pre><p>这里有两种 checksum：</p>
<pre><code class="language-text">weak checksum：弱校验，也就是 rolling checksum
strong checksum：强校验，用来最终确认块是否真的一致</code></pre><p>目标端不会把整个旧文件传给源端，而是只把这些 block 的 checksum 列表发给源端。</p>
<p>接下来，源端拿到这些 checksum 后，开始扫描源端的新文件 <code>A</code>。</p>
<hr>
<h2>5. rolling checksum 是什么？</h2>
<p>rolling checksum 可以理解成一种适合“滑动窗口”的弱校验。</p>
<p>普通 hash 的问题是：如果窗口移动 1 个字节，通常要重新计算整个窗口的 hash。</p>
<p>例如窗口大小是 4KB：</p>
<pre><code class="language-text">窗口 1：[第 0 字节 ... 第 4095 字节]
窗口 2：[第 1 字节 ... 第 4096 字节]</code></pre><p>两个窗口只差了一个字节，但普通 hash 通常需要重新读完整个 4KB 来计算。</p>
<p>rolling checksum 的优势是：它可以基于上一个窗口的结果，快速算出下一个窗口的校验值。</p>
<p>可以粗略理解为：</p>
<pre><code class="language-text">新 checksum = 旧 checksum - 离开窗口的字节 + 进入窗口的字节</code></pre><p>真实算法会比这个更复杂，但直觉就是这样。</p>
<p>所以 rolling checksum 非常适合源端扫描新文件：</p>
<pre><code class="language-text">A = abcdefghijklmnop
    [----]            窗口 1
     [----]           窗口 2
      [----]          窗口 3</code></pre><p>窗口每次向后滑动 1 个字节，都可以快速得到新的 weak checksum。</p>
<hr>
<h2>6. strong checksum 是什么？</h2>
<p>rolling checksum 虽然快，但它是弱校验，可能发生碰撞。</p>
<p>也就是说，两个不同的数据块，有可能算出相同的 weak checksum。</p>
<p>如果 rsync 只依赖 rolling checksum，就可能把两个不同的数据块误认为相同，导致最终同步出来的文件内容错误。</p>
<p>所以 rsync 还需要 strong checksum。</p>
<p>strong checksum 的作用是：</p>
<pre><code class="language-text">当 rolling checksum 发现一个“疑似匹配”时，再用 strong checksum 做最终确认。</code></pre><p>它比 rolling checksum 更可靠，但计算成本也更高。</p>
<p>因此，rsync 不会对每一个滑动窗口都计算 strong checksum，而是只在 weak checksum 命中时才计算。</p>
<hr>
<h2>7. rolling checksum 和 strong checksum 如何协作？</h2>
<p>这部分是 rsync 算法的核心。</p>
<p>目标端旧文件 <code>B</code> 已经被切成多个 block，并且每个 block 都有一对 checksum：</p>
<pre><code class="language-text">B0 -&gt; weak0, strong0
B1 -&gt; weak1, strong1
B2 -&gt; weak2, strong2
...</code></pre><p>源端扫描新文件 <code>A</code> 时，会不断移动一个大小相同的窗口。</p>
<p>对于每个窗口，先计算 rolling checksum：</p>
<pre><code class="language-text">window = A[pos : pos + block_size]
weak = rolling_checksum(window)</code></pre><p>然后拿这个 weak checksum 去目标端发来的 checksum 表中查找。</p>
<h3>情况一：weak checksum 没有命中</h3>
<p>如果没有命中，说明这个窗口大概率不是目标端已有的任何 block。</p>
<p>于是源端继续向后滑动 1 个字节：</p>
<pre><code class="language-text">当前位置没有匹配
=&gt; 窗口后移 1 字节
=&gt; 继续计算 rolling checksum</code></pre><p>这一步很快，因为 rolling checksum 可以增量计算。</p>
<h3>情况二：weak checksum 命中</h3>
<p>如果 weak checksum 命中了某个旧 block，比如 <code>B7</code>：</p>
<pre><code class="language-text">A 的当前窗口 weak checksum == B7 的 weak checksum</code></pre><p>这说明当前窗口“可能”和旧文件里的 <code>B7</code> 相同。</p>
<p>但这只是疑似匹配。</p>
<p>接下来，源端会对当前窗口计算 strong checksum：</p>
<pre><code class="language-text">strong = strong_checksum(A[pos : pos + block_size])</code></pre><p>然后和 <code>B7</code> 的 strong checksum 比较：</p>
<pre><code class="language-text">如果 strong == strong7
=&gt; 基本确认 A 的当前窗口和 B7 是同一段内容</code></pre><p>确认匹配之后，源端就不需要发送这段数据本身了。</p>
<p>它只需要告诉目标端：</p>
<pre><code class="language-text">复制你本地旧文件里的第 7 个 block</code></pre><p>也就是发送一条类似这样的指令：</p>
<pre><code class="language-text">copy block B7</code></pre><p>对于无法匹配的内容，源端才会发送原始字节数据，也就是 literal data。</p>
<p>最终，目标端收到的是一串构造指令：</p>
<pre><code class="language-text">literal "abc"
copy B7
copy B8
literal "xyz"
copy B12
...</code></pre><p>目标端根据这些指令，把旧文件已有的 block 和新传输的 literal data 组合起来，重建出新的文件 <code>A</code>。</p>
<hr>
<h2>8. 为什么不只用 strong checksum？</h2>
<p>因为源端扫描新文件时，不是只看固定块边界，而是要在新文件的所有可能偏移位置上寻找匹配。</p>
<p>如果文件很大，每个偏移位置都计算 strong checksum，成本会非常高。</p>
<p>rolling checksum 的价值就在于：</p>
<pre><code class="language-text">它可以非常便宜地扫描大量候选位置。</code></pre><p>所以它适合做第一层过滤。</p>
<p>只有当 rolling checksum 命中时，rsync 才会计算 strong checksum。</p>
<p>这样可以避免大量不必要的强校验计算。</p>
<hr>
<h2>9. 为什么不只用 rolling checksum？</h2>
<p>因为 rolling checksum 是弱校验，存在碰撞风险。</p>
<p>如果只靠它判断两个 block 是否相同，就可能出现误判。</p>
<p>strong checksum 的作用就是降低误判概率，保证最终重建出来的文件尽可能可靠。</p>
<p>所以二者的分工是：</p>
<pre><code class="language-text">rolling checksum：负责快速发现疑似匹配
strong checksum：负责确认疑似匹配是否真的成立</code></pre><p>可以把它理解成一个两阶段过滤器：</p>
<pre><code class="language-text">第一阶段：rolling checksum 快速筛选候选块
第二阶段：strong checksum 精确确认候选块</code></pre><p>这就是 rsync 能同时做到“快”和“可靠”的原因。</p>
<hr>
<h2>10. 一个简化例子</h2>
<p>假设目标端旧文件 <code>B</code> 被切成 4 个 block：</p>
<pre><code class="language-text">B = [B0][B1][B2][B3]</code></pre><p>目标端计算并发送：</p>
<pre><code class="language-text">B0 -&gt; weak0, strong0
B1 -&gt; weak1, strong1
B2 -&gt; weak2, strong2
B3 -&gt; weak3, strong3</code></pre><p>源端新文件 <code>A</code> 内容中，前面插入了一小段新数据，但后面大部分内容和旧文件一样：</p>
<pre><code class="language-text">A = [新数据][B1][B2][B3]</code></pre><p>源端扫描 <code>A</code> 时，会发现：</p>
<pre><code class="language-text">开头的新数据无法匹配旧 block
=&gt; 需要发送 literal data

后面的窗口匹配到 B1
=&gt; 发送 copy B1

继续匹配到 B2
=&gt; 发送 copy B2

继续匹配到 B3
=&gt; 发送 copy B3</code></pre><p>最终源端只需要发送：</p>
<pre><code class="language-text">literal "新数据"
copy B1
copy B2
copy B3</code></pre><p>目标端就可以根据旧文件 <code>B</code> 和这些指令重建出新文件 <code>A</code>。</p>
<p>这就是为什么在大文件只改动一小部分时，rsync 的传输量会远小于直接复制整个文件。</p>
<hr>
<h2>11. 本地判断两个文件是否完全一致，应该用什么？</h2>
<p>如果只是想在本机判断两个文件是否完全一致，最直接的方式其实不是 rsync，而是 <code>cmp</code>：</p>
<pre><code class="language-bash">cmp -s file1 file2 && echo same || echo diff</code></pre><p><code>cmp</code> 会按字节比较两个文件。</p>
<p>几种方式的区别：</p>
<pre><code class="language-text">stat：
只看元数据，例如 size、mtime，最快，但不严格

cmp：
逐字节比较，适合判断两个本地文件是否完全一致

sha256sum：
计算完整 hash，适合生成指纹、跨机器保存和比对

rsync：
适合同步目录或跨机器增量同步</code></pre><p>如果只是同步目录：</p>
<pre><code class="language-bash">rsync -av src/ dst/</code></pre><p>如果你怀疑文件的修改时间不可靠，希望按内容判断：</p>
<pre><code class="language-bash">rsync -avc src/ dst/</code></pre><p>如果只是想预览哪些文件会变化：</p>
<pre><code class="language-bash">rsync -avcni src/ dst/</code></pre><p>其中：</p>
<pre><code class="language-text">-a：归档模式，保留权限、时间等信息
-v：显示详细信息
-c：按 checksum 判断内容变化
-n：dry-run，只预演，不真正修改
-i：输出变更摘要</code></pre><hr>
<h2>12. 总结</h2>
<p>rsync 的实现原理可以分成两层：</p>
<p>第一层是快速判断文件是否需要处理。</p>
<p>默认情况下，rsync 使用：</p>
<pre><code class="language-text">文件大小 size + 修改时间 mtime</code></pre><p>来快速跳过未变化文件。</p>
<p>第二层是对需要更新的文件做差异传输。</p>
<p>它使用：</p>
<pre><code class="language-text">rolling checksum + strong checksum</code></pre><p>来寻找源端新文件中哪些数据块已经存在于目标端旧文件中。</p>
<p>两者的协作方式是：</p>
<pre><code class="language-text">rolling checksum 负责快速扫描和发现候选块；
strong checksum 负责确认候选块是否真的相同。</code></pre><p>找到匹配块后，源端不需要发送真实数据，只需要发送类似：</p>
<pre><code class="language-text">copy block N</code></pre><p>这样的引用指令。</p>
<p>找不到匹配的部分，才发送原始数据。</p>
<p>因此，rsync 能够在文件变化很小的情况下，大幅减少传输量。</p>
<p>一句话概括：</p>
<pre><code class="language-text">rsync 默认靠 size + mtime 快速判断文件是否变化；
真正同步变化文件时，靠 rolling checksum 找候选块，靠 strong checksum 确认匹配，只传输目标端缺失的数据。</code></pre><p>这就是 rsync 高效同步的核心原理。</p>

          <p style='text-align: right'>
          <a href='https://carota.site/posts/tech/rsync-analyze#comments'>Finished reading? Leave a comment</a>
          </p>
    ]]>
    </content:encoded>
  <guid isPermaLink="false">151939859429199872</guid>
  <category>post</category>
<category>技术</category>
 </item>
  <item>
    <title>用 STORM 方法做一次真正的深度调研</title>
    <link>https://carota.site/posts/books/claude-storm</link>
    <pubDate>Tue, 23 Jun 2026 13:42:49 GMT</pubDate>
    <description>很多人使用 AI 的方式，其实还停留在“搜索框时代”。

输入一个问题，等待一个答案。
如果答案看起</description>
    <content:encoded><![CDATA[
      <blockquote>This rendering is produced by marked and may have formatting issues. For the best experience, visit: <a href='https://carota.site/posts/books/claude-storm'>https://carota.site/posts/books/claude-storm</a></blockquote>
          <p>很多人使用 AI 的方式，其实还停留在“搜索框时代”。</p>
<p>输入一个问题，等待一个答案。
如果答案看起来流畅，就觉得它“很聪明”；如果答案有点空，就换个模型再问一遍。</p>
<p>但这并没有真正发挥大模型的价值。</p>
<p>最近 Nav Toor 在 X 上分享了一套基于 Stanford STORM 思路的 Claude 调研方法，核心不是让 AI “更会回答”，而是让 AI 像研究者一样拆解问题：从多个立场提问，暴露冲突，综合证据，再进行自我审查。(<a href="https://x.com/heynavtoor/article/2067194761446920264?utm_source=chatgpt.com" title="The Stanford STORM Method: How to Make Claude ...">X (formerly Twitter)</a>)</p>
<h2>STORM 到底是什么？</h2>
<p>STORM 是 Stanford OVAL 提出的一个知识整理与长文写作系统，全称是 <strong>Synthesis of Topic Outlines through Retrieval and Multi-perspective Question Asking</strong>，大意是：通过检索和多视角提问来综合主题大纲。它的目标不是简单生成一篇文章，而是在写作之前先完成“研究”和“搭框架”的过程。(<a href="https://aclanthology.org/2024.naacl-long.347/?utm_source=chatgpt.com" title="Assisting in Writing Wikipedia-like Articles From Scratch ...">ACL Anthology</a>)</p>
<p>它背后的思想很朴素：</p>
<blockquote>
<p>好的问题，往往不是从一个角度问出来的。
真正的洞察，通常藏在不同视角的冲突里。</p>
</blockquote>
<p>所以 STORM 不急着输出结论，而是先让模型模拟不同角色：实践者、学者、怀疑者、经济学人、历史学家。每个角色都带着自己的问题意识去看同一个主题。</p>
<p>这一步非常关键。
因为普通提问容易得到“互联网平均答案”，而多视角提问会逼迫模型暴露问题的复杂性。</p>
<h2>一套可复用的 AI 深度调研流程</h2>
<p>这套方法可以拆成四步。</p>
<h3>第一步：多视角扫描</h3>
<p>不要直接问：</p>
<blockquote>
<p>帮我分析一下 X。</p>
</blockquote>
<p>而是让 AI 从多个角色出发：</p>
<blockquote>
<p>请从实践者、学术研究者、怀疑论者、经济学人、历史观察者五个角度分析这个问题。
每个角度都要说明：它最关心什么、它掌握什么证据、它可能看到哪些其他角度忽略的事实。</p>
</blockquote>
<p>这样做的好处是，模型不会只顺着一个方向讲故事。</p>
<p>实践者会提醒你现实操作里的摩擦；
学者会要求证据和同行评议；
怀疑者会专门找漏洞；
经济学人会追问利益结构；
历史学家会寻找周期和先例。</p>
<p>一个问题被五种视角同时照亮后，信息密度会明显提高。</p>
<h3>第二步：画出矛盾地图</h3>
<p>多视角分析之后，不要马上总结。
下一步应该让 AI 找冲突。</p>
<p>你可以继续问：</p>
<blockquote>
<p>上面这些视角之间，哪些观点是直接矛盾的？
哪些证据最强？哪些证据最弱？
所有视角都承认的共识是什么？
有没有所有人都忽略的盲区？</p>
</blockquote>
<p>这一步的价值在于：它把“看起来都对”的观点放到同一张桌子上比较。</p>
<p>很多 AI 生成内容的问题，不是没有信息，而是没有冲突。
它会把各种材料平铺出来，但不告诉你哪些观点互相打架、哪些论点其实站不住。</p>
<p>而研究的关键，恰恰是识别冲突。</p>
<h3>第三步：综合成研究简报</h3>
<p>当视角和冲突都清楚之后，再让 AI 输出正式简报。</p>
<p>可以要求它包含：</p>
<ol>
<li>用一段话讲清楚核心结论</li>
<li>按可信度排序列出关键发现</li>
<li>说明每个发现由哪些视角支持、又被哪些视角质疑</li>
<li>找出一个隐藏关联</li>
<li>给出面向具体角色的行动建议</li>
<li>提出一个最值得继续研究的前沿问题</li>
</ol>
<p>这一步很适合用于写文章、做竞品分析、研究新技术方向、准备面试、判断商业机会。</p>
<p>因为它输出的不是“资料堆砌”，而是一份有结构、有冲突、有行动含义的研究结果。</p>
<h3>第四步：让 AI 自我评审</h3>
<p>最后一步很多人会忽略：让 AI 审查自己的答案。</p>
<p>你可以问：</p>
<blockquote>
<p>请对刚才的研究简报做一次严格评审。
哪些结论置信度最高？哪些最弱？
是否存在偏见？
是否缺少关键视角？
如果由一位严苛的教授审阅，他会要求你修改哪里？</p>
</blockquote>
<p>这一步不是形式主义。</p>
<p>大模型最大的问题之一，是它很容易把“讲得顺”包装成“讲得对”。
自我评审的作用，就是强制它把结论拆开，标记不确定性，暴露薄弱环节。</p>
<h2>为什么这比普通 Prompt 更有效？</h2>
<p>普通 Prompt 的逻辑是：</p>
<blockquote>
<p>我问一个问题，你给一个答案。</p>
</blockquote>
<p>STORM 式 Prompt 的逻辑是：</p>
<blockquote>
<p>我先让你从多个角度提出问题，再让你比较冲突，最后才综合答案。</p>
</blockquote>
<p>这两者差别很大。</p>
<p>前者像搜索。
后者像研究。</p>
<p>搜索追求速度，研究追求结构。
搜索容易得到结论，研究会先暴露不确定性。
搜索把 AI 当信息压缩器，研究把 AI 当思考协作者。</p>
<p>Stanford 的 STORM 论文也强调了预写作阶段的重要性：在正式写作前，系统需要先发现不同视角、模拟带有不同立场的提问，并基于可信来源整理信息和大纲。(<a href="https://aclanthology.org/2024.naacl-long.347/?utm_source=chatgpt.com" title="Assisting in Writing Wikipedia-like Articles From Scratch ...">ACL Anthology</a>)</p>
<h2>适合用在哪些场景？</h2>
<p>这套方法特别适合复杂问题，比如：</p>
<ul>
<li>调研一个新技术方向</li>
<li>分析一个产品机会</li>
<li>判断一个行业趋势</li>
<li>写一篇深度博客</li>
<li>准备面试或分享</li>
<li>做投资、职业、创业方向判断</li>
<li>分析一个争议性观点</li>
</ul>
<p>它不太适合问简单事实，比如“某个命令怎么写”“某个概念是什么意思”。
但只要问题涉及多方利益、历史背景、证据强弱、行动决策，这套方法就很有用。</p>
<h2>但也别神化它</h2>
<p>STORM 不是让 AI 自动变成博士。
它只是把研究流程结构化了。</p>
<p>你仍然需要注意三件事：</p>
<p>第一，AI 可能引用不可靠来源。
第二，它可能把无关事实强行关联。
第三，它可能继承检索结果里的偏见。</p>
<p>STORM 论文中也提到，生成长文仍然会遇到来源偏差转移、无关事实过度关联等挑战。(<a href="https://arxiv.org/abs/2402.14207?utm_source=chatgpt.com" title="Assisting in Writing Wikipedia-like Articles From Scratch with Large Language Models">arXiv</a>)</p>
<p>所以更准确的说法是：</p>
<blockquote>
<p>STORM 不是替你完成判断，而是帮你搭建一个更好的判断框架。</p>
</blockquote>
<h2>一个可直接复制的通用模板</h2>
<p>你可以把下面这段保存下来，以后调研复杂问题时直接使用：</p>
<pre><code class="language-text">我想对【你的研究主题】做一次深度调研。

请不要直接给结论，而是按照以下流程完成：

1. 多视角分析：
请从实践者、学术研究者、怀疑论者、经济学人、历史观察者五个角度分析这个主题。
每个角度需要给出：
- 核心立场
- 最重要的证据
- 它能看到但其他视角容易忽略的事实

2. 矛盾地图：
请比较这些视角之间的冲突：
- 哪些观点直接矛盾？
- 哪些证据最强，哪些证据最弱？
- 所有视角都承认的共识是什么？
- 是否存在共同忽略的盲区？

3. 研究简报：
请把以上内容整理成一份研究简报：
- 一段话核心总结
- 5 个最重要发现，并按可信度排序
- 一个隐藏关联
- 面向【你的身份/目标】的行动建议
- 一个最值得继续研究的问题

4. 自我评审：
请审查这份简报：
- 每个关键发现的置信度
- 最薄弱的论点
- 可能存在的偏见
- 是否缺少关键视角
- 如果由严苛专家审阅，最需要修改哪里</code></pre><h2>结语</h2>
<p>AI 时代真正重要的能力，可能不是“会不会用某个模型”，而是“会不会组织问题”。</p>
<p>当你只问一个问题时，AI 给你的往往是平均答案。
当你让它从多个视角互相辩论时，它才更可能产出洞察。</p>
<p>不要只把 Claude、ChatGPT 或 Gemini 当搜索框。
让它们成为你的研究小组。</p>
<p>这才是 STORM 方法最值得借鉴的地方。</p>

          <p style='text-align: right'>
          <a href='https://carota.site/posts/books/claude-storm#comments'>Finished reading? Leave a comment</a>
          </p>
    ]]>
    </content:encoded>
  <guid isPermaLink="false">151322808704569344</guid>
  <category>post</category>
<category>阅读</category>
 </item>
  <item>
    <title>LLM 也需要虚拟内存：Demand Paging for Context Window</title>
    <link>https://carota.site/posts/tech/arxiv-llms-need-virtual-memory-demand-paging-context-window</link>
    <pubDate>Thu, 12 Mar 2026 08:23:05 GMT</pubDate>
    <description>最近看到一篇非常有意思的论文：

《The Missing Memory Hierarchy: De</description>
    <content:encoded><![CDATA[
      <blockquote>This rendering is produced by marked and may have formatting issues. For the best experience, visit: <a href='https://carota.site/posts/tech/arxiv-llms-need-virtual-memory-demand-paging-context-window'>https://carota.site/posts/tech/arxiv-llms-need-virtual-memory-demand-paging-context-window</a></blockquote>
          <p>最近看到一篇非常有意思的论文：</p>
<p><strong>《The Missing Memory Hierarchy: Demand Paging for LLM Context Windows》</strong></p>
<p>论文地址：</p>
<ul>
<li>The Missing Memory Hierarchy: Demand Paging for LLM Context Windows</li>
<li>原文：<a href="https://arxiv.org/abs/2603.09023">https://arxiv.org/abs/2603.09023</a></li>
</ul>
<p>这篇论文的核心观点非常简单但极具启发性：</p>
<blockquote>
<p><strong>LLM 的上下文窗口，本质上是一个没有内存管理系统的“裸内存”。</strong></p>
</blockquote>
<p>如果把 LLM Agent 看成一个程序，那么当前的设计就像：</p>
<ul>
<li>所有历史数据都一直留在内存里</li>
<li>每次执行都重新扫描整个内存</li>
<li>没有分页</li>
<li>没有缓存</li>
<li>没有工作集</li>
<li>没有淘汰策略</li>
</ul>
<p>这显然是非常原始的。</p>
<p>论文作者做了一件很“操作系统味”的事情：</p>
<blockquote>
<p><strong>给 LLM 上下文加一个虚拟内存系统。</strong></p>
</blockquote>
<hr>
<h1>一、问题：LLM 上下文在大量浪费 token</h1>
<p>作者首先做了一件很重要的事情：</p>
<p><strong>分析真实生产日志。</strong></p>
<p>数据来源：</p>
<ul>
<li>857 个 Claude Code 会话</li>
<li>54,170 次 API 调用</li>
<li>总输入 token：<strong>4.45B</strong></li>
</ul>
<p>作者把每条消息拆成几类：</p>
<ul>
<li>用户输入</li>
<li>模型回复</li>
<li>工具输出（read file / bash / etc）</li>
</ul>
<p>然后统计：</p>
<ul>
<li>token 占比</li>
<li>使用频率</li>
<li>重复读取情况</li>
</ul>
<p>结果非常惊人。</p>
<h2>1 结构性浪费：21.8%</h2>
<p>约 <strong>21.8% 的 token 是结构性浪费</strong>：</p>
<p>主要来自：</p>
<p>1️⃣ <strong>工具定义</strong></p>
<p>很多工具定义几千 token
但会话里从未调用。</p>
<p>却在 <strong>每一轮请求里重复发送</strong>。</p>
<hr>
<p>2️⃣ <strong>旧工具输出</strong></p>
<p>比如：</p>
<pre><code class="language-">Read file: file.py (10KB)</code></pre><p>后续 80 轮对话里：</p>
<ul>
<li>每一轮 API 调用</li>
<li>都重新发送这 10KB</li>
<li>都参与 attention</li>
</ul>
<p>但实际 <strong>再也没被引用过</strong>。</p>
<hr>
<p>3️⃣ <strong>重复配置</strong></p>
<p>例如：</p>
<ul>
<li>skill 列表</li>
<li>agent 说明</li>
<li>prompt 模板</li>
</ul>
<p>经常被复制多份。</p>
<hr>
<h1>二、关键观察：工具输出会被“无限放大”</h1>
<p>论文提出一个概念：</p>
<p><strong>Amplification Factor（放大因子）</strong></p>
<p>例如：</p>
<ul>
<li>第 5 轮读取一个文件</li>
<li>文件大小 10KB</li>
<li>会话共 85 轮</li>
</ul>
<p>那么这个文件会被：</p>
<pre><code class="language-">重复发送 ≈ 80 次</code></pre><p>放大因子：</p>
<pre><code class="language-">80×</code></pre><p>而每一次都要参与 attention 计算。</p>
<hr>
<h1>三、解决方案：给 LLM 上下文做“虚拟内存”</h1>
<p>论文的核心系统叫：</p>
<p><strong>Pichay</strong></p>
<p>它的实现非常巧妙。</p>
<p>不是改模型。</p>
<p>而是：</p>
<blockquote>
<p><strong>在客户端和 LLM API 之间插一个代理。</strong></p>
</blockquote>
<p>架构如下：</p>
<pre><code class="language-">IDE / Agent
      ↓
   Pichay Proxy
      ↓
   LLM API</code></pre><p>代理负责：</p>
<ul>
<li>统计 token</li>
<li>修改上下文</li>
<li>删除旧内容</li>
<li>必要时再恢复</li>
</ul>
<p>模型和客户端完全无感。</p>
<hr>
<h1>四、核心思想：Demand Paging</h1>
<p>作者把 LLM 上下文类比为操作系统内存。</p>
<table>
<thead>
<tr>
<th>OS</th>
<th>LLM</th>
</tr>
</thead>
<tbody><tr>
<td>RAM</td>
<td>Context Window</td>
</tr>
<tr>
<td>Page</td>
<td>工具输出</td>
</tr>
<tr>
<td>Page fault</td>
<td>再次读取文件</td>
</tr>
<tr>
<td>Page eviction</td>
<td>删除旧工具输出</td>
</tr>
</tbody></table>
<hr>
<h2>1 淘汰策略（Eviction）</h2>
<p>非常简单：</p>
<p>当一个工具输出满足：</p>
<pre><code class="language-">大小 &gt; 500B
且
超过 4 个用户回合未使用</code></pre><p>就淘汰。</p>
<hr>
<h2>2 被淘汰的内容如何表示？</h2>
<p>替换成一个 <strong>占位符</strong>：</p>
<pre><code class="language-">[Paged out: Read file.py (8192 bytes). Re-read if needed]</code></pre><p>模型如果需要：</p>
<p>就会再次调用工具。</p>
<hr>
<h2>3 Page Fault（缺页）</h2>
<p>如果模型再次调用：</p>
<pre><code class="language-">Read file.py</code></pre><p>代理检测到：</p>
<pre><code class="language-">刚刚淘汰过这个内容</code></pre><p>于是：</p>
<ul>
<li>重新读取文件</li>
<li>注入上下文</li>
</ul>
<p>这就是：</p>
<p><strong>LLM 的 page fault。</strong></p>
<hr>
<h2>4 Fault-driven Pinning</h2>
<p>如果某个页面：</p>
<pre><code class="language-">被淘汰 → 发生缺页</code></pre><p>说明淘汰太早。</p>
<p>系统就会：</p>
<pre><code class="language-">pin 这个页面</code></pre><p>以后不再淘汰。</p>
<p>除非：</p>
<pre><code class="language-">文件内容发生变化</code></pre><hr>
<h1>五、离线实验：删错概率极低</h1>
<p>作者用 <strong>29 个完整会话</strong>做离线重放实验。</p>
<p>模拟：</p>
<pre><code class="language-">如果当时删掉这些内容
后面会不会再用？</code></pre><p>结果：</p>
<ul>
<li>模拟删除：<strong>1,393,000 次</strong></li>
<li>缺页：<strong>354 次</strong></li>
</ul>
<p>缺页率：</p>
<pre><code class="language-">0.0254%</code></pre><p>也就是说：</p>
<blockquote>
<p><strong>99.97% 的删除都是安全的。</strong></p>
</blockquote>
<hr>
<h1>六、在线实验：token 下降 37%</h1>
<p>作者对比三种策略：</p>
<table>
<thead>
<tr>
<th>模式</th>
<th>策略</th>
</tr>
</thead>
<tbody><tr>
<td>Baseline</td>
<td>不做任何修改</td>
</tr>
<tr>
<td>Trimmed</td>
<td>裁剪工具定义</td>
</tr>
<tr>
<td>Compact+Trim</td>
<td>加分页</td>
</tr>
</tbody></table>
<p>结果：</p>
<pre><code class="language-">Trimmed
↓
token -22.6%

Compact + Trim
↓
token -37.1%</code></pre><p>而任务：</p>
<ul>
<li>全部完成</li>
<li>没有质量下降</li>
</ul>
<p>甚至有些情况下：</p>
<p><strong>回答质量更好。</strong></p>
<p>原因很简单：</p>
<blockquote>
<p>噪音减少，注意力更集中。</p>
</blockquote>
<hr>
<h1>七、真实生产案例</h1>
<p>作者把 Pichay 用在自己的开发环境。</p>
<h2>Case A：正常开发</h2>
<p>原始上下文：</p>
<pre><code class="language-">剩余空间：7%</code></pre><p>启用分页：</p>
<pre><code class="language-">剩余空间：43%</code></pre><p>删除：</p>
<pre><code class="language-">15 个数据块</code></pre><p>缺页：</p>
<pre><code class="language-">1 次</code></pre><p>几乎完美。</p>
<hr>
<h2>Case B：极端长会话</h2>
<p>681 轮。</p>
<p>系统出现：</p>
<p><strong>Thrashing（抖动）</strong></p>
<pre><code class="language-">删除 680 次
缺页 659 次</code></pre><p>原因：</p>
<p>工作集太大。</p>
<p>不断：</p>
<pre><code class="language-">删 → 读 → 删 → 读</code></pre><p>类似操作系统的：</p>
<p><strong>swap storm。</strong></p>
<hr>
<h1>八、最重要的理论结论</h1>
<p>传统操作系统：</p>
<pre><code class="language-">缺页很贵</code></pre><p>所以策略是：</p>
<pre><code class="language-">尽量减少缺页</code></pre><p>但 LLM 完全相反。</p>
<hr>
<h2>LLM 的成本模型</h2>
<p>如果一个内容一直留在上下文：</p>
<p>每生成一个 token
都要重新计算 attention。</p>
<p>复杂度：</p>
<pre><code class="language-">O(n²)</code></pre><p>因此：</p>
<p><strong>保留 token 的累计成本非常高。</strong></p>
<hr>
<p>而重新读取文件：</p>
<p>成本是：</p>
<pre><code class="language-">O(n)</code></pre><p>所以结论是：</p>
<blockquote>
<p><strong>在 LLM 中，宁可多一点 page fault，也不要保留太多 token。</strong></p>
</blockquote>
<hr>
<h1>九、这件事为什么很重要</h1>
<p>这篇论文其实在说一件很大的事情：</p>
<blockquote>
<p><strong>未来的 LLM 系统必须有内存层级。</strong></p>
</blockquote>
<p>可以类比成：</p>
<table>
<thead>
<tr>
<th>层级</th>
<th>含义</th>
</tr>
</thead>
<tbody><tr>
<td>L1</td>
<td>当前上下文</td>
</tr>
<tr>
<td>L2</td>
<td>Working set</td>
</tr>
<tr>
<td>L3</td>
<td>会话总结</td>
</tr>
<tr>
<td>L4</td>
<td>长期记忆</td>
</tr>
</tbody></table>
<p>当前 LLM 系统：</p>
<p>只有 <strong>L1。</strong></p>
<hr>
<h1>十、未来方向</h1>
<p>论文提出了很多值得研究的方向：</p>
<h3>1 成本驱动的 eviction</h3>
<p>不再看：</p>
<pre><code class="language-">回合数</code></pre><p>而是计算：</p>
<pre><code class="language-">未来 attention 成本</code></pre><hr>
<h3>2 phase-aware memory</h3>
<p>识别：</p>
<pre><code class="language-">planning phase
execution phase</code></pre><p>不同阶段使用不同策略。</p>
<hr>
<h3>3 pin decay</h3>
<p>当前：</p>
<pre><code class="language-">缺页一次 → 永久 pin</code></pre><p>未来：</p>
<pre><code class="language-">pin 逐渐衰减</code></pre><hr>
<h3>4 object-level memory</h3>
<p>不再按：</p>
<pre><code class="language-">文件
消息</code></pre><p>分页。</p>
<p>而是：</p>
<pre><code class="language-">决策
任务
debug 会话</code></pre><hr>
<h1>十一、我的一些思考</h1>
<p>这篇论文的最大价值是：</p>
<blockquote>
<p><strong>把 LLM memory 问题彻底系统化。</strong></p>
</blockquote>
<p>它告诉我们：</p>
<p>未来 AI Agent 的架构可能会像这样：</p>
<pre><code class="language-">LLM
 ↓
Memory Manager
 ↓
Context Cache
 ↓
Retrieval System
 ↓
Persistent Memory</code></pre><p>而不是：</p>
<pre><code class="language-">LLM
 ↓
巨大 prompt</code></pre><p>换句话说：</p>
<p><strong>Prompt Engineering → Context Engineering</strong></p>
<hr>
<h1>十二、总结</h1>
<p>这篇论文最核心的发现：</p>
<p>1️⃣ <strong>21.8% token 是结构性浪费</strong></p>
<p>2️⃣ <strong>简单分页策略缺页率只有 0.025%</strong></p>
<p>3️⃣ <strong>token 使用减少 37%</strong></p>
<p>4️⃣ <strong>回答质量没有下降</strong></p>
<p>5️⃣ <strong>LLM 的成本模型与传统虚拟内存完全相反</strong></p>
<hr>
<p>如果未来 LLM agent 真的要：</p>
<ul>
<li>长时间工作</li>
<li>多工具协作</li>
<li>持续项目开发</li>
</ul>
<p>那么：</p>
<blockquote>
<p><strong>Memory hierarchy 可能会成为 AI 系统的核心基础设施。</strong></p>
</blockquote>
<p>而这篇论文很可能会成为这个领域的 <strong>早期经典工作之一</strong>。</p>

          <p style='text-align: right'>
          <a href='https://carota.site/posts/tech/arxiv-llms-need-virtual-memory-demand-paging-context-window#comments'>Finished reading? Leave a comment</a>
          </p>
    ]]>
    </content:encoded>
  <guid isPermaLink="false">138265555285590087</guid>
  <category>post</category>
<category>技术</category>
 </item>
  <item>
    <title>在 Agent 时代如何做软件工程</title>
    <link>https://carota.site/posts/books/software-engineering-in-the-agent-era</link>
    <pubDate>Wed, 11 Mar 2026 13:23:45 GMT</pubDate>
    <description>—— OpenAI 如何用 Codex 构建一个 100 万行代码的系统

最近 OpenAI 工程</description>
    <content:encoded><![CDATA[
      <blockquote>This rendering is produced by marked and may have formatting issues. For the best experience, visit: <a href='https://carota.site/posts/books/software-engineering-in-the-agent-era'>https://carota.site/posts/books/software-engineering-in-the-agent-era</a></blockquote>
          <h2>—— OpenAI 如何用 Codex 构建一个 100 万行代码的系统</h2>
<p>最近 OpenAI 工程团队分享了一篇非常值得工程师阅读的文章：</p>
<p><strong>原文：</strong>
<a href="https://openai.com/zh-Hans-CN/index/harness-engineering/">https://openai.com/zh-Hans-CN/index/harness-engineering/</a></p>
<p>文章讲述了他们进行的一次实验：</p>
<blockquote>
<p><strong>构建一个真实的软件产品，但整个代码库没有一行代码是人工编写的。</strong></p>
</blockquote>
<p>所有代码，包括：</p>
<ul>
<li>应用逻辑</li>
<li>测试</li>
<li>CI/CD</li>
<li>文档</li>
<li>运维脚本</li>
<li>内部工具</li>
</ul>
<p><strong>全部由 Codex 生成。</strong></p>
<p>而人类工程师只做一件事：</p>
<blockquote>
<p><strong>设计系统、约束和反馈循环。</strong></p>
</blockquote>
<p>最终他们用 <strong>3 个工程师</strong> 在 <strong>5 个月内构建了一个接近 100 万行代码的系统</strong>。</p>
<p>这篇文章其实揭示了一个重要趋势：</p>
<blockquote>
<p><strong>软件工程正在从 “写代码” 转变为 “设计 AI 能工作的系统”。</strong></p>
</blockquote>
<p>下面我把这篇文章的核心内容拆解出来，分析它对未来工程模式意味着什么。</p>
<hr>
<h1>一、实验：一个完全由 AI 生成代码的产品</h1>
<p>OpenAI 团队从 <strong>一个空 Git 仓库</strong>开始。</p>
<p>初始架构由 Codex + GPT-5 自动生成，包括：</p>
<ul>
<li>项目结构</li>
<li>CI 配置</li>
<li>代码格式规则</li>
<li>包管理</li>
<li>应用框架</li>
<li>AGENTS.md</li>
</ul>
<p>甚至：</p>
<blockquote>
<p><strong>指导 AI 如何在仓库中工作的文档，也是 AI 写的。</strong></p>
</blockquote>
<p>5 个月后结果：</p>
<ul>
<li><strong>约 100 万行代码</strong></li>
<li><strong>1500+ Pull Request</strong></li>
<li><strong>团队只有 3 个工程师</strong></li>
<li>平均 <strong>每人每天处理 3.5 个 PR</strong></li>
</ul>
<p>系统已经有：</p>
<ul>
<li>内部日活用户</li>
<li>外部 Alpha 用户</li>
</ul>
<p>换句话说：</p>
<blockquote>
<p>这不是 Demo，而是一个真实运行的产品。</p>
</blockquote>
<p>他们的核心原则是：</p>
<blockquote>
<p><strong>Humans steer, agents execute.</strong>
人类掌舵，AI 执行。</p>
</blockquote>
<hr>
<h1>二、工程师角色发生了变化</h1>
<p>在这个体系下：</p>
<p><strong>工程师几乎不写代码。</strong></p>
<p>工程师的工作变成：</p>
<p>1️⃣ 设计系统结构
2️⃣ 定义任务目标
3️⃣ 设计反馈循环
4️⃣ 构建 AI 能使用的工具</p>
<p>换句话说：</p>
<p>以前：</p>
<pre><code class="language-">工程师 -&gt; 写代码 -&gt; 提 PR</code></pre><p>现在：</p>
<pre><code class="language-">工程师 -&gt; 描述任务
      -&gt; 运行 Agent
      -&gt; Agent 提 PR
      -&gt; Agent review
      -&gt; 自动修复</code></pre><p>整个流程类似这样：</p>
<pre><code class="language-">Engineer
   ↓
Prompt
   ↓
Codex
   ↓
Open PR
   ↓
Agent Review
   ↓
Fix
   ↓
Merge</code></pre><p>很多时候：</p>
<blockquote>
<p><strong>PR review 也是 AI 做的。</strong></p>
</blockquote>
<hr>
<h1>三、系统必须“对 Agent 可读”</h1>
<p>一个非常重要的经验：</p>
<blockquote>
<p><strong>Agent 看不到的知识 = 不存在。</strong></p>
</blockquote>
<p>例如：</p>
<ul>
<li>Slack 讨论</li>
<li>Google Docs</li>
<li>人脑记忆</li>
</ul>
<p>对 AI 来说都是 <strong>不可见的知识</strong>。</p>
<p>因此他们做了一个关键决定：</p>
<blockquote>
<p><strong>把代码仓库变成唯一的信息来源。</strong></p>
</blockquote>
<p>所有内容都写入 repo：</p>
<ul>
<li>架构文档</li>
<li>设计文档</li>
<li>产品规格</li>
<li>执行计划</li>
<li>技术债务</li>
<li>决策记录</li>
</ul>
<p>目录结构大概是这样：</p>
<pre><code class="language-">AGENTS.md
ARCHITECTURE.md

docs/
 ├ design-docs/
 ├ exec-plans/
 ├ product-specs/
 ├ references/
 ├ SECURITY.md
 ├ RELIABILITY.md
 └ QUALITY_SCORE.md</code></pre><p>AI 通过这个结构：</p>
<ul>
<li>找信息</li>
<li>推理系统</li>
<li>修改代码</li>
</ul>
<p>他们称这种方式为：</p>
<blockquote>
<p><strong>Agent-readable repository</strong></p>
</blockquote>
<hr>
<h1>四、不要写 1000 行 prompt</h1>
<p>他们曾尝试：</p>
<pre><code class="language-">一个巨大 AGENTS.md</code></pre><p>结果完全失败。</p>
<p>原因是：</p>
<h3>1 情境窗口是稀缺资源</h3>
<p>长文档会挤掉：</p>
<ul>
<li>代码</li>
<li>任务</li>
<li>重要上下文</li>
</ul>
<hr>
<h3>2 过多规则会失效</h3>
<p>当所有东西都重要：</p>
<blockquote>
<p>其实没有东西重要。</p>
</blockquote>
<hr>
<h3>3 文档会腐烂</h3>
<p>如果维护成本太高：</p>
<p>文档会变成：</p>
<blockquote>
<p><strong>过期规则的坟场</strong></p>
</blockquote>
<hr>
<p>他们最后采用的方法是：</p>
<p><strong>AGENTS.md 只做目录</strong></p>
<p>类似：</p>
<pre><code class="language-">AGENTS.md
  ↓
ARCHITECTURE.md
  ↓
docs/
  ↓
design-docs/</code></pre><p>也就是：</p>
<blockquote>
<p><strong>给 AI 一张地图，而不是一本说明书。</strong></p>
</blockquote>
<hr>
<h1>五、架构必须严格</h1>
<p>Agent 在这种环境下有一个特点：</p>
<blockquote>
<p><strong>会复制已有模式。</strong></p>
</blockquote>
<p>如果架构不严格：</p>
<p>代码会快速漂移。</p>
<p>因此他们强制使用：</p>
<p><strong>严格分层架构</strong></p>
<p>例如：</p>
<pre><code class="language-">Types
  ↓
Config
  ↓
Repo
  ↓
Service
  ↓
Runtime
  ↓
UI</code></pre><p>规则：</p>
<ul>
<li>只能向下依赖</li>
<li>不允许跨层调用</li>
</ul>
<p>所有规则通过：</p>
<ul>
<li>custom linter</li>
<li>结构测试</li>
</ul>
<p>自动执行。</p>
<p>也就是说：</p>
<blockquote>
<p>架构约束是机器执行的。</p>
</blockquote>
<hr>
<h1>六、吞吐量改变了工程文化</h1>
<p>Agent 写代码的速度远远超过人类。</p>
<p>这带来了一个新问题：</p>
<p><strong>代码吞吐量远大于人类审查能力。</strong></p>
<p>因此他们改变了传统工程文化：</p>
<p>以前：</p>
<pre><code class="language-">严格 gate
必须 review
CI 必须通过</code></pre><p>现在：</p>
<pre><code class="language-">快速 merge
问题后修</code></pre><p>因为：</p>
<blockquote>
<p><strong>等待的成本比修复更高。</strong></p>
</blockquote>
<hr>
<h1>七、AI 可以自动完成整个开发流程</h1>
<p>随着工具完善，现在 Codex 已经可以：</p>
<p>自动完成整个开发流程：</p>
<p>1️⃣ 验证代码库状态
2️⃣ 复现 bug
3️⃣ 录制 bug 视频
4️⃣ 实现修复
5️⃣ 运行应用验证
6️⃣ 录制修复视频
7️⃣ 提 PR
8️⃣ 处理 review
9️⃣ 修复 CI
🔟 自动 merge</p>
<p>人类只在必要时介入。</p>
<hr>
<h1>八、新问题：AI 会制造“技术债”</h1>
<p>完全 AI 开发会带来一个问题：</p>
<blockquote>
<p><strong>AI 会复制错误模式。</strong></p>
</blockquote>
<p>例如：</p>
<ul>
<li>不一致的实现</li>
<li>不合理 abstraction</li>
<li>重复工具</li>
</ul>
<p>他们最初的做法是：</p>
<p><strong>每周五清理 AI 代码。</strong></p>
<p>后来发现不可扩展。</p>
<p>最终解决方法是：</p>
<blockquote>
<p><strong>把工程原则写进代码。</strong></p>
</blockquote>
<p>例如：</p>
<ul>
<li>禁止 YOLO parsing</li>
<li>强制 typed SDK</li>
<li>优先共享工具库</li>
</ul>
<p>然后：</p>
<p>定期运行 <strong>Refactor Agent</strong>。</p>
<p>类似：</p>
<blockquote>
<p><strong>自动垃圾回收（GC）。</strong></p>
</blockquote>
<hr>
<h1>九、真正稀缺的资源：人类注意力</h1>
<p>这篇文章最后总结了一句话：</p>
<blockquote>
<p><strong>软件工程的瓶颈不再是写代码，而是人类注意力。</strong></p>
</blockquote>
<p>未来工程体系的核心问题变成：</p>
<ul>
<li>如何设计环境</li>
<li>如何设计反馈循环</li>
<li>如何设计约束系统</li>
</ul>
<p>而不是：</p>
<blockquote>
<p>写代码。</p>
</blockquote>
<hr>
<h1>十、对未来软件工程的启示</h1>
<p>这篇文章透露了一个非常重要的趋势：</p>
<p>软件工程正在进入：</p>
<blockquote>
<p><strong>Agent-first engineering</strong></p>
</blockquote>
<p>未来工程师更像：</p>
<p><strong>系统设计师</strong></p>
<p>而不是：</p>
<p><strong>代码工人</strong></p>
<p>未来的核心能力可能是：</p>
<ul>
<li>架构设计</li>
<li>Agent workflow</li>
<li>工程自动化</li>
<li>feedback loop 设计</li>
<li>工程知识建模</li>
</ul>
<p>而不是：</p>
<ul>
<li>写 CRUD</li>
</ul>
<hr>
<h1>结语</h1>
<p>这篇文章其实说明了一件事：</p>
<p><strong>AI 不只是写代码工具。</strong></p>
<p>它正在改变：</p>
<blockquote>
<p><strong>软件工程本身的结构。</strong></p>
</blockquote>
<p>未来的软件团队可能会变成：</p>
<pre><code class="language-">少量工程师
+
大量 AI Agent
+
高度结构化的代码仓库</code></pre><p>而工程师的核心价值将变成：</p>
<blockquote>
<p><strong>设计 AI 能高效工作的系统。</strong></p>
</blockquote>

          <p style='text-align: right'>
          <a href='https://carota.site/posts/books/software-engineering-in-the-agent-era#comments'>Finished reading? Leave a comment</a>
          </p>
    ]]>
    </content:encoded>
  <guid isPermaLink="false">138265555285590086</guid>
  <category>post</category>
<category>阅读</category>
 </item>
  <item>
    <title>不用 Docker 也能训练 AI 写代码：SWE-MiniSandbox 深度解析</title>
    <link>https://carota.site/posts/tech/arxiv-swe-minisanbox</link>
    <pubDate>Tue, 10 Mar 2026 03:19:12 GMT</pubDate>
    <description>SWE-MiniSandbox: Container-Free Reinforcement Lear</description>
    <content:encoded><![CDATA[
      <blockquote>This rendering is produced by marked and may have formatting issues. For the best experience, visit: <a href='https://carota.site/posts/tech/arxiv-swe-minisanbox'>https://carota.site/posts/tech/arxiv-swe-minisanbox</a></blockquote>
          <blockquote>
<p><strong>SWE-MiniSandbox: Container-Free Reinforcement Learning for Building Software Engineering Agents</strong>
arXiv:2602.11210</p>
</blockquote>
<p>近年来，**Software Engineering Agents（AI 自动修 bug / 改代码）**成为一个热门方向，例如：</p>
<ul>
<li>SWE-agent</li>
<li>OpenHands</li>
<li>Devin 类系统</li>
<li>SWE-bench 等评测体系</li>
</ul>
<p>但这类系统背后有一个 <strong>非常现实的工程问题</strong>：</p>
<blockquote>
<p>如何为 AI agent 提供可执行代码、运行测试、修改仓库的隔离环境？</p>
</blockquote>
<p>传统方案几乎全部依赖 <strong>Docker 容器</strong>。</p>
<p>然而容器带来了新的问题：</p>
<ul>
<li>环境准备慢</li>
<li>镜像非常大</li>
<li>高并发训练成本高</li>
<li>需要 Docker / Kubernetes 基础设施</li>
</ul>
<p>最近的一篇论文 <strong>SWE-MiniSandbox</strong> 提出了一种非常有意思的思路：</p>
<blockquote>
<p><strong>完全不使用容器，而是用 Linux 内核机制实现轻量隔离环境。</strong></p>
</blockquote>
<p>结果是：</p>
<ul>
<li>存储占用减少 <strong>85%+</strong></li>
<li>环境准备时间降低 <strong>75%</strong></li>
<li>RL 训练效果几乎一致</li>
</ul>
<p>本文我们来系统分析这套系统。</p>
<hr>
<h1>一、问题背景：为什么 Docker 会成为瓶颈</h1>
<p>在 SWE Agent 系统中，一个任务通常是：</p>
<pre><code class="language-">1. clone GitHub repo
2. checkout 某个 commit
3. 安装依赖
4. 运行测试
5. agent 修改代码
6. 再次运行测试
7. 判断 patch 是否成功</code></pre><p>为了防止：</p>
<ul>
<li>不同任务互相污染</li>
<li>依赖冲突</li>
<li>agent 执行危险命令</li>
</ul>
<p>通常每个任务都会运行在 <strong>独立 Docker 容器里</strong>。</p>
<p>典型流程：</p>
<pre><code class="language-">task -&gt; docker container
     -&gt; code repo
     -&gt; python env
     -&gt; run tests</code></pre><p>但问题在于：</p>
<h3>1 镜像体积巨大</h3>
<p>很多 SWE-bench 任务的镜像：</p>
<pre><code class="language-">1GB ~ 3GB</code></pre><p>几十个任务就可能：</p>
<pre><code class="language-">&gt; 100GB</code></pre><h3>2 启动时间慢</h3>
<p>容器启动 + 初始化环境：</p>
<pre><code class="language-">~90 秒</code></pre><h3>3 RL 训练并发非常高</h3>
<p>强化学习训练常见：</p>
<pre><code class="language-">128 - 512 parallel environments</code></pre><p>Docker 带来的开销就变得非常明显。</p>
<hr>
<h1>二、核心思想：用 Linux 内核替代容器</h1>
<p>SWE-MiniSandbox 的关键思路是：</p>
<blockquote>
<p><strong>容器其实不是必须的。</strong></p>
</blockquote>
<p>很多隔离能力 <strong>Linux 内核本身就提供了</strong>。</p>
<p>论文选择了两个核心机制：</p>
<pre><code class="language-">mount namespace
+
chroot</code></pre><p>实现隔离 sandbox。</p>
<hr>
<h1>三、核心技术一：mount namespace</h1>
<p>Linux 的 <strong>namespace</strong> 是容器技术的基础。</p>
<p>Docker 本质上就是组合了：</p>
<pre><code class="language-">PID namespace
Network namespace
Mount namespace
User namespace
...</code></pre><p>SWE-MiniSandbox只使用其中一部分。</p>
<h3>mount namespace 的作用</h3>
<p>它可以让一个进程：</p>
<blockquote>
<p>看到 <strong>完全不同的文件系统挂载视图</strong></p>
</blockquote>
<p>例如：</p>
<p>主机目录</p>
<pre><code class="language-">/
├── home
├── usr
└── data</code></pre><p>sandbox 内看到：</p>
<pre><code class="language-">/
├── repo
├── venv
└── tmp</code></pre><p>每个 sandbox：</p>
<pre><code class="language-">文件系统完全独立</code></pre><hr>
<h1>四、核心技术二：chroot</h1>
<p><code>chroot</code> 是 Linux 非常古老但强大的功能。</p>
<p>它可以：</p>
<blockquote>
<p><strong>改变进程的 root 目录</strong></p>
</blockquote>
<p>执行：</p>
<pre><code class="language-">chroot /sandbox/task_001</code></pre><p>后这个进程看到的：</p>
<pre><code class="language-">/ == /sandbox/task_001</code></pre><p>所以：</p>
<pre><code class="language-">/repo
/venv
/tmp</code></pre><p>都变成了独立环境。</p>
<p>结合 <strong>mount namespace + chroot</strong>：</p>
<p>每个任务就像拥有一个 <strong>自己的 Linux 根目录</strong>。</p>
<p>但它仍然共享：</p>
<pre><code class="language-">kernel
系统库
部分资源</code></pre><p>所以非常轻量。</p>
<hr>
<h1>五、核心技术三：Python 环境复用</h1>
<p>SWE-MiniSandbox 的另一个关键优化：</p>
<blockquote>
<p><strong>避免重复创建 Python 环境</strong></p>
</blockquote>
<p>传统 Docker：</p>
<pre><code class="language-">每个镜像包含
OS
Python
依赖</code></pre><p>体积很大。</p>
<p>MiniSandbox 的方案：</p>
<h3>Step 1：共享 miniconda</h3>
<p>宿主机安装：</p>
<pre><code class="language-">miniconda3</code></pre><h3>Step 2：创建 venv</h3>
<p>每个任务：</p>
<pre><code class="language-">python -m venv</code></pre><p>venv 结构：</p>
<pre><code class="language-">venv/
  bin/
  site-packages/
  symlink -&gt; python</code></pre><p>很多文件其实是：</p>
<pre><code class="language-">符号链接</code></pre><p>所以体积只有：</p>
<pre><code class="language-">~100MB</code></pre><hr>
<h1>六、核心技术四：环境缓存</h1>
<p>环境构建最慢的步骤是：</p>
<pre><code class="language-">pip install
repo setup
test run</code></pre><p>MiniSandbox 的做法：</p>
<h3>预构建环境</h3>
<p>第一次：</p>
<pre><code class="language-">repo
+ venv
+ dependencies
+ tests</code></pre><p>全部准备好后：</p>
<pre><code class="language-">tar.gz</code></pre><p>缓存。</p>
<p>之后每个任务只需要：</p>
<pre><code class="language-">untar</code></pre><p>就能直接使用。</p>
<hr>
<h1>七、核心技术五：I/O 并发控制</h1>
<p>解压 tar 包其实是 <strong>磁盘 I/O 密集任务</strong>。</p>
<p>如果 100 个任务同时解压：</p>
<pre><code class="language-">磁盘直接打爆</code></pre><p>作者提出一个简单模型：</p>
<p>假设：</p>
<pre><code class="language-">磁盘带宽 = B
每个解压 = bj</code></pre><p>同时解压数量：</p>
<pre><code class="language-">∑ bj ≤ B</code></pre><p>实现方式：</p>
<pre><code class="language-">Ray resource tags
+
semaphore</code></pre><p>控制同时解压任务数。</p>
<hr>
<h1>八、系统架构</h1>
<p>MiniSandbox 并不是单独系统，而是嵌入 SWE Agent 生态。</p>
<p>整体结构：</p>
<pre><code class="language-">                +-------------------+
                |      SkyRL        |
                |  RL distributed   |
                +---------+---------+
                          |
                          |
               +----------v-----------+
               |      SWE-agent       |
               |   solve issues       |
               +----------+-----------+
                          |
                          |
                +---------v---------+
                |      SWE-Rex      |
                | terminal control  |
                +---------+---------+
                          |
                          |
                +---------v---------+
                |   MiniSandbox     |
                | mount + chroot    |
                +-------------------+</code></pre><p>每个 sandbox：</p>
<pre><code class="language-">repo
venv
terminal</code></pre><hr>
<h1>九、实验结果</h1>
<p>论文使用：</p>
<pre><code class="language-">SWE-smith
SWE-bench Verified</code></pre><h2>1 存储节省</h2>
<table>
<thead>
<tr>
<th>数据集</th>
<th>Docker</th>
<th>MiniSandbox</th>
</tr>
</thead>
<tbody><tr>
<td>SWE-smith</td>
<td>295 GB</td>
<td>13.5 GB</td>
</tr>
<tr>
<td>SWE-bench</td>
<td>605 GB</td>
<td>89 GB</td>
</tr>
</tbody></table>
<p>节省：</p>
<pre><code class="language-">85%+</code></pre><hr>
<h2>2 环境准备时间</h2>
<table>
<thead>
<tr>
<th>方法</th>
<th>时间</th>
</tr>
</thead>
<tbody><tr>
<td>Docker</td>
<td>88.9 s</td>
</tr>
<tr>
<td>MiniSandbox</td>
<td>23.6 s</td>
</tr>
</tbody></table>
<p>加速：</p>
<pre><code class="language-">~4x</code></pre><hr>
<h2>3 rollout 时间</h2>
<p>平均任务时间：</p>
<pre><code class="language-">Docker       ~350s
MiniSandbox  ~250s</code></pre><p>明显更快。</p>
<hr>
<h2>4 训练效果</h2>
<p>论文引入指标：</p>
<pre><code class="language-">Reward MD (Mean Deviation)</code></pre><p>衡量：</p>
<pre><code class="language-">两种框架训练的 reward 差异</code></pre><p>结果：</p>
<pre><code class="language-">≈ 0</code></pre><p>说明：</p>
<blockquote>
<p>RL 训练信号几乎一致。</p>
</blockquote>
<hr>
<h1>十、为什么这项工作重要</h1>
<p>这篇论文并没有提出新的 AI 模型。</p>
<p>但它解决了一个 <strong>非常关键的系统问题</strong>：</p>
<blockquote>
<p>如何低成本运行 SWE agents。</p>
</blockquote>
<p>它带来的影响可能是：</p>
<h3>1 降低研究门槛</h3>
<p>很多团队没有：</p>
<pre><code class="language-">Docker cluster
Kubernetes</code></pre><p>MiniSandbox：</p>
<pre><code class="language-">普通 Linux 服务器
+
Python</code></pre><p>即可运行。</p>
<hr>
<h3>2 大规模 RL 更可行</h3>
<p>强化学习非常依赖：</p>
<pre><code class="language-">并行环境数量</code></pre><p>环境越轻：</p>
<pre><code class="language-">rollout 越快</code></pre><p>训练成本就越低。</p>
<hr>
<h3>3 企业部署更容易</h3>
<p>企业内部：</p>
<pre><code class="language-">CI
测试
自动修 bug</code></pre><p>很多场景其实不需要：</p>
<pre><code class="language-">完整容器</code></pre><p>MiniSandbox 更轻。</p>
<hr>
<h1>十一、局限性</h1>
<p>论文也非常坦诚地指出问题。</p>
<h3>1 安全隔离不如容器</h3>
<p>MiniSandbox 只有：</p>
<pre><code class="language-">mount namespace
chroot</code></pre><p>而 Docker 还有：</p>
<pre><code class="language-">cgroup
seccomp
user namespace
capabilities</code></pre><p>所以安全性略弱。</p>
<hr>
<h3>2 Python 项目为主</h3>
<p>实验主要集中：</p>
<pre><code class="language-">Python repos</code></pre><p>对于：</p>
<pre><code class="language-">C++
Rust
Java
复杂 build system</code></pre><p>仍需验证。</p>
<hr>
<h3>3 I/O 仍然是瓶颈</h3>
<p>即使优化后：</p>
<pre><code class="language-">repo copy
venv copy
untar</code></pre><p>仍然消耗较多时间。</p>
<p>未来可能用：</p>
<pre><code class="language-">overlayfs
copy-on-write</code></pre><p>进一步优化。</p>
<hr>
<h1>十二、我的一些思考</h1>
<p>这篇论文最有意思的地方是：</p>
<blockquote>
<p><strong>很多 AI 系统瓶颈其实不是模型，而是系统工程。</strong></p>
</blockquote>
<p>SWE agent 的发展：</p>
<pre><code class="language-">模型能力
+
工具链
+
环境系统</code></pre><p>缺一不可。</p>
<p>MiniSandbox 本质上是在做：</p>
<pre><code class="language-">AI infra optimization</code></pre><p>类似于：</p>
<pre><code class="language-">RL environment acceleration</code></pre><p>如果未来：</p>
<ul>
<li>SWE agents</li>
<li>Devin 类系统</li>
<li>自动代码修复</li>
</ul>
<p>大规模部署，</p>
<p>这种 <strong>轻量 sandbox</strong> 很可能成为新的基础设施。</p>
<hr>
<h1>总结</h1>
<p>SWE-MiniSandbox 的核心贡献可以总结为一句话：</p>
<blockquote>
<p><strong>用 Linux 原生隔离 + Python 环境缓存，替代 Docker 容器，构建轻量级 SWE agent 运行环境。</strong></p>
</blockquote>
<p>带来的收益：</p>
<ul>
<li>存储降低 <strong>85%+</strong></li>
<li>环境准备 <strong>4x 加速</strong></li>
<li>RL 训练效果 <strong>几乎一致</strong></li>
</ul>
<p>这说明：</p>
<blockquote>
<p>在 AI 系统工程里，很多时候 <strong>更好的系统设计比更大的模型更重要</strong>。</p>
</blockquote>

          <p style='text-align: right'>
          <a href='https://carota.site/posts/tech/arxiv-swe-minisanbox#comments'>Finished reading? Leave a comment</a>
          </p>
    ]]>
    </content:encoded>
  <guid isPermaLink="false">138265555285590085</guid>
  <category>post</category>
<category>技术</category>
 </item>
  <item>
    <title>让软件工程 Agent 学会“按步骤复盘”：子任务级记忆机制解读</title>
    <link>https://carota.site/posts/tech/arxiv-saslm-for-se-agents</link>
    <pubDate>Fri, 27 Feb 2026 02:04:05 GMT</pubDate>
    <description>Structurally Aligned Subtask-Level Memory for Soft</description>
    <content:encoded><![CDATA[
      <blockquote>This rendering is produced by marked and may have formatting issues. For the best experience, visit: <a href='https://carota.site/posts/tech/arxiv-saslm-for-se-agents'>https://carota.site/posts/tech/arxiv-saslm-for-se-agents</a></blockquote>
          <blockquote>
<p><strong>Structurally Aligned Subtask-Level Memory for Software Engineering Agents</strong><br>Kangning Shen, Jingyuan Zhang, Chenxi Sun et al.<br>arXiv:2602.21611 (2026)<br>🔗 原论文地址：<a href="https://arxiv.org/abs/2602.21611">https://arxiv.org/abs/2602.21611</a></p>
</blockquote>
<hr>
<h2>✨ 一句话总结</h2>
<p>这篇论文解决的是：</p>
<blockquote>
<p>❌ 过去：AI 只会“按整道题记经验”，容易误用<br>✅ 现在：AI 按 <strong>推理步骤</strong> 记经验，只在对应阶段调用 → 更稳、更准、更能复用</p>
</blockquote>
<p>在 SWE-bench Verified 上：</p>
<ul>
<li><p>平均提升 <strong>+4.7% Pass@1</strong></p>
</li>
<li><p>困难任务最高 <strong>+8.7%</strong></p>
</li>
<li><p>同时 <strong>显著降低结果波动</strong></p>
</li>
</ul>
<p>对于一个已经很难提升的 benchmark，这个增幅非常有含金量。</p>
<hr>
<h1>🧠 问题背景：为什么现有 Agent 的“记忆”不好用？</h1>
<p>现在很多 SWE Agent 的记忆方式是这样的：</p>
<blockquote>
<p>做完一个 issue → 写一份完整复盘 → 下次找“最像的一题”</p>
</blockquote>
<p>问题在于：</p>
<p>看起来像 ≠ 推理过程一样</p>
<p>例如：</p>
<table>
<thead>
<tr>
<th>issue</th>
<th>本质</th>
</tr>
</thead>
<tbody><tr>
<td>登录按钮点不了</td>
<td>前端事件绑定</td>
</tr>
<tr>
<td>登录一段时间后退出</td>
<td>后端 session 超时</td>
</tr>
</tbody></table>
<p>文本都包含 “login”，但解决路径完全不同。</p>
<p>这会导致：</p>
<ul>
<li><p>检索到错误经验</p>
</li>
<li><p>强模型反而被误导</p>
</li>
<li><p>性能波动变大</p>
</li>
</ul>
<hr>
<h1>🧩 核心思想：记忆必须和推理结构对齐</h1>
<p>软件工程任务天然是分阶段的：</p>
<ol>
<li><p>ANALYZE — 分析问题</p>
</li>
<li><p>REPRODUCE — 复现 bug</p>
</li>
<li><p>EDIT — 修改代码</p>
</li>
<li><p>VERIFY — 验证修复</p>
</li>
</ol>
<p>论文的核心设计：</p>
<blockquote>
<p>不再按“整道题”记<br>而是按“子任务阶段”记</p>
</blockquote>
<hr>
<h1>🗂 新的记忆单元长什么样？</h1>
<p>每条记忆变成三元组：</p>
<pre><code class="language-">(z, d, e)</code></pre><h3>1️⃣ z：阶段标签</h3>
<p>例如：</p>
<ul>
<li><p>ANALYZE</p>
</li>
<li><p>EDIT</p>
</li>
<li><p>VERIFY</p>
</li>
</ul>
<hr>
<h3>2️⃣ d：当时的小目标（意图）</h3>
<p>结构化描述：</p>
<ul>
<li><p>当前要解决什么</p>
</li>
<li><p>关键线索（函数名 / 报错）</p>
</li>
</ul>
<hr>
<h3>3️⃣ e：抽象经验</h3>
<p>不是存全过程，而是提炼：</p>
<p>✅ 可迁移策略<br>❌ 仓库特有细节</p>
<p>例如：</p>
<blockquote>
<p>当 a+b 正常但 b+a 报错 → 检查 <strong>radd</strong></p>
</blockquote>
<p>这就是可以跨项目复用的经验。</p>
<hr>
<h1>🔍 检索机制：只在“当前阶段的抽屉”里找</h1>
<p>传统方式：</p>
<blockquote>
<p>在整个记忆库做语义相似度匹配 ❌</p>
</blockquote>
<p>论文方式：</p>
<pre><code class="language-">先按阶段过滤
再做语义匹配</code></pre><p>效果：</p>
<ul>
<li><p>避免跨阶段干扰</p>
</li>
<li><p>Top-1 检索也足够稳</p>
</li>
</ul>
<hr>
<h1>🧠 经验是如何产生的？</h1>
<p>在子任务结束时做一次 <strong>反思</strong>：</p>
<p>成功 → 总结套路<br>失败 → 总结反模式</p>
<p>然后抽象成经验卡片写入记忆。</p>
<p>这是一个 <strong>在线自进化系统</strong>：</p>
<blockquote>
<p>做的任务越多 → Agent 越像老员工</p>
</blockquote>
<hr>
<h1>📊 实验结果</h1>
<h2>总体表现</h2>
<p>在 SWE-bench Verified：</p>
<table>
<thead>
<tr>
<th>模型</th>
<th>提升</th>
</tr>
</thead>
<tbody><tr>
<td>Gemini 2.5 Pro</td>
<td>+6.8%</td>
</tr>
<tr>
<td>平均</td>
<td>+4.7%</td>
</tr>
</tbody></table>
<hr>
<h2>对强模型的影响</h2>
<p>实例级记忆：</p>
<ul>
<li><p>性能下降</p>
</li>
<li><p>方差变大 ❌</p>
</li>
</ul>
<p>子任务级记忆：</p>
<ul>
<li><p>性能提升</p>
</li>
<li><p>更稳定 ✅</p>
</li>
</ul>
<p>说明：</p>
<blockquote>
<p>强模型不怕没记忆<br>怕错误记忆</p>
</blockquote>
<hr>
<h2>对困难任务的提升最大</h2>
<p>按轨迹长度划分：</p>
<table>
<thead>
<tr>
<th>难度</th>
<th>提升</th>
</tr>
</thead>
<tbody><tr>
<td>Easy</td>
<td>+1.8%</td>
</tr>
<tr>
<td>Hard</td>
<td><strong>+8.7%</strong></td>
</tr>
</tbody></table>
<p>因为困难任务最依赖经验复用。</p>
<hr>
<h1>🧪 关键消融实验</h1>
<h3>❌ 只强制分步骤思考（不存记忆）</h3>
<p>仅 +1%</p>
<p>→ 真正的提升来自“经验复用”</p>
<hr>
<h3>❌ 不按阶段分类检索</h3>
<p>提升只剩 +1.6%</p>
<p>→ 阶段对齐是关键</p>
<hr>
<h3>❌ 存原始轨迹</h3>
<p>提升 +1.2%</p>
<p>→ 必须做抽象</p>
<hr>
<h1>🏗 工程视角：这件事为什么重要？</h1>
<p>这篇论文最有价值的地方在于：</p>
<blockquote>
<p>不需要训练新模型<br>只靠系统设计就能提升</p>
</blockquote>
<p>现实系统可以直接复用：</p>
<ul>
<li><p>Cursor / Devin 类 Agent</p>
</li>
<li><p>企业内部 Code Agent</p>
</li>
<li><p>自动化修复 Bot</p>
</li>
</ul>
<hr>
<h2>对团队的意义</h2>
<p>AI 不再是：</p>
<blockquote>
<p>每次都从零开始的实习生</p>
</blockquote>
<p>而是：</p>
<blockquote>
<p>会积累项目经验的老员工</p>
</blockquote>
<p>带来的变化：</p>
<ul>
<li><p>更快修复重复问题</p>
</li>
<li><p>更稳定的 CI 自动修复</p>
</li>
<li><p>更低的 onboarding 成本</p>
</li>
</ul>
<hr>
<h1>🌍 这套范式可以迁移到所有 Agent</h1>
<p>不仅限于写代码：</p>
<h3>数据分析 Agent</h3>
<p>阶段：</p>
<ul>
<li><p>理解需求</p>
</li>
<li><p>找数据</p>
</li>
<li><p>建模</p>
</li>
<li><p>解释结果</p>
</li>
</ul>
<hr>
<h3>客服 Agent</h3>
<p>阶段：</p>
<ul>
<li><p>澄清问题</p>
</li>
<li><p>查政策</p>
</li>
<li><p>给方案</p>
</li>
<li><p>跟进</p>
</li>
</ul>
<hr>
<h3>科研 Agent</h3>
<p>阶段：</p>
<ul>
<li><p>检索文献</p>
</li>
<li><p>提出假设</p>
</li>
<li><p>设计实验</p>
</li>
<li><p>分析结果</p>
</li>
</ul>
<hr>
<h1>⚠️ 局限性</h1>
<p>论文目前还没有解决：</p>
<h3>1️⃣ 记忆无限增长问题</h3>
<p>需要：</p>
<ul>
<li><p>淘汰机制</p>
</li>
<li><p>压缩</p>
</li>
<li><p>分层记忆</p>
</li>
</ul>
<hr>
<h3>2️⃣ 错误经验污染</h3>
<p>现在的系统：</p>
<blockquote>
<p>写进去就信</p>
</blockquote>
<p>未来必须解决：</p>
<ul>
<li><p>记忆可信度</p>
</li>
<li><p>自动降权</p>
</li>
<li><p>版本控制</p>
</li>
</ul>
<hr>
<h3>3️⃣ 子任务划分仍是手工设计</h3>
<p>未来方向：</p>
<blockquote>
<p>自动学习阶段结构</p>
</blockquote>
<hr>
<h1>🔮 未来值得关注的方向</h1>
<p>我认为最有潜力的三个：</p>
<h3>1️⃣ 记忆治理系统</h3>
<p>类似：</p>
<ul>
<li><p>Git for memory</p>
</li>
<li><p>memory diff / rollback</p>
</li>
</ul>
<hr>
<h3>2️⃣ 多 Agent 共享经验库</h3>
<p>团队级 AI 知识沉淀。</p>
<hr>
<h3>3️⃣ 长期运行的代码管家</h3>
<p>真正的：</p>
<blockquote>
<p>AI 老员工</p>
</blockquote>
<hr>
<h1>🏁 我的评价</h1>
<p>这篇论文的价值在于：</p>
<p>它不是做了一个更大的模型<br>而是回答了一个更本质的问题：</p>
<blockquote>
<p>Agent 应该“如何学习经验”</p>
</blockquote>
<p>这是：</p>
<p>LLM → 真正智能体<br>过程中非常关键的一步。</p>
<hr>
<h1>📌 Takeaway</h1>
<p>如果你正在做 Agent 系统，这篇论文给了一个可以直接落地的设计原则：</p>
<h3>✅ 正确的记忆设计</h3>
<ul>
<li><p>记忆单位 = 推理子任务</p>
</li>
<li><p>只存抽象经验</p>
</li>
<li><p>检索必须阶段对齐</p>
</li>
</ul>
<p>而不是：</p>
<ul>
<li><p>存整段对话</p>
</li>
<li><p>全局相似度检索</p>
</li>
</ul>
<hr>
<h1>🧵 最后</h1>
<p>如果你在做：</p>
<ul>
<li><p>AI 编程工具</p>
</li>
<li><p>企业代码 Agent</p>
</li>
<li><p>自动化修复系统</p>
</li>
</ul>
<p>这篇论文属于：</p>
<blockquote>
<p>可以直接改系统设计的那种工作</p>
</blockquote>
<p>而不是“只在 leaderboard 上多 1%”。</p>

          <p style='text-align: right'>
          <a href='https://carota.site/posts/tech/arxiv-saslm-for-se-agents#comments'>Finished reading? Leave a comment</a>
          </p>
    ]]>
    </content:encoded>
  <guid isPermaLink="false">138265555285590084</guid>
  <category>post</category>
<category>技术</category>
 </item>
  <item>
    <title>Core 4 框架：重新定义开发者生产力的四个维度</title>
    <link>https://carota.site/notes/10</link>
    <pubDate>Thu, 26 Feb 2026 03:17:57 GMT</pubDate>
    <description>最近看到宝玉叔分享的一场来自 Pragmatic Summit 的演讲总结，主讲人是 DX 公司 C</description>
    <content:encoded><![CDATA[
      <blockquote>This rendering is produced by marked and may have formatting issues. For the best experience, visit: <a href='https://carota.site/notes/10'>https://carota.site/notes/10</a></blockquote>
          <p>最近看到<a href="https://x.com/dotey/article/2026755174761431119">宝玉叔分享的一场来自 Pragmatic Summit 的演讲总结</a>，<a href="https://www.youtube.com/watch?v=LOHgRw43fFk">主讲人是 DX 公司 CTO、<strong>Core 4 开发者生产力框架</strong>的联合作者 Laura Tacho</a>。</p>
<p>她手里有一份非常恐怖的数据集：</p>
<ul>
<li>12 万开发者</li>
<li>450+ 公司真实样本</li>
</ul>
<p>这不是方法论，而是<strong>基于真实组织行为的数据科学结论</strong>。</p>
<p>这篇文章最有价值的点在于：
👉 它重新定义了“开发效率到底是什么”。</p>
<hr>
<h2>一、开发者生产力的误区</h2>
<p>很多公司衡量研发效率的方式：</p>
<ul>
<li>写了多少行代码</li>
<li>提交次数</li>
<li>需求完成数量</li>
<li>工时利用率</li>
</ul>
<p>这些指标有一个共同问题：</p>
<p>❌ 衡量的是「忙碌程度」
而不是「价值交付能力」</p>
<p>真正的问题是：</p>
<blockquote>
<p>我们如何更快、更稳定、更可持续地把价值交付到用户手里？</p>
</blockquote>
<hr>
<h2>二、Core 4：开发者生产力的四个核心维度</h2>
<p>Core 4 并不看“人写了多少代码”，而是看系统是否高效。</p>
<h3>1️⃣ 速度（Speed）</h3>
<p>不是单纯的快，而是：</p>
<ul>
<li>从 idea → production 的时间</li>
<li>PR 合并周期</li>
<li>发布节奏</li>
</ul>
<p>核心问题：</p>
<blockquote>
<p>组织是否能快速把想法变成可运行的软件？</p>
</blockquote>
<hr>
<h3>2️⃣ 易用性（Ease）</h3>
<p>开发环境是否顺滑：</p>
<ul>
<li>本地启动是否痛苦</li>
<li>CI 是否经常炸</li>
<li>调试是否困难</li>
</ul>
<p>这直接决定：</p>
<p>🧠 开发者每天有多少时间在“真正创造价值”</p>
<hr>
<h3>3️⃣ 质量（Quality）</h3>
<p>不是测试覆盖率，而是：</p>
<ul>
<li>变更失败率</li>
<li>线上回滚频率</li>
<li>修复周期</li>
</ul>
<p>高质量团队的特点：</p>
<p>👉 发布更频繁
👉 反而更稳定</p>
<hr>
<h3>4️⃣ 影响力（Impact）</h3>
<p>这是最容易被忽略的：</p>
<p>开发者是否在做：</p>
<ul>
<li>高价值项目</li>
<li>对业务真正重要的事情</li>
</ul>
<p>而不是被：</p>
<ul>
<li>低效流程</li>
<li>组织阻塞</li>
<li>技术债</li>
</ul>
<p>消耗掉。</p>
<hr>
<h2>三、一个反直觉的关键结论</h2>
<p>数据表明：</p>
<blockquote>
<p>提升开发者生产力
❌ 不是靠压榨个人
✅ 而是优化系统体验</p>
</blockquote>
<p>真正高效的公司在做的是：</p>
<ul>
<li>投资 DevEx（开发者体验）</li>
<li>优化 CI/CD</li>
<li>减少等待时间</li>
<li>自动化流程</li>
</ul>
<p>而不是：</p>
<p>❌ 强制加班
❌ 增加 KPI
❌ 用绩效驱动代码产出</p>
<hr>
<h2>四、AI 时代对研发效率的真正影响</h2>
<p>这部分是我认为最值得思考的。</p>
<p>AI 确实在提升：</p>
<ul>
<li>写代码速度</li>
<li>生成样板代码能力</li>
</ul>
<p>但 Core 4 的视角会告诉你：</p>
<p>如果你的系统存在这些问题：</p>
<ul>
<li>发布流程 2 天</li>
<li>CI 30 分钟</li>
<li>环境初始化半天</li>
<li>需求评审一周</li>
</ul>
<p>那么：</p>
<p>🤖 AI 只能让你更快写完
⛔ 但无法让你更快交付</p>
<hr>
<h2>五、高绩效团队真正的投资方向</h2>
<p>数据中表现最好的团队有几个共同点：</p>
<h3>✅ 极度重视开发者体验</h3>
<p>把 DevEx 当作产品在做。</p>
<hr>
<h3>✅ 减少“等待时间”</h3>
<p>包括：</p>
<ul>
<li>等 CI</li>
<li>等评审</li>
<li>等环境</li>
<li>等权限</li>
</ul>
<p>等待 = 最大的生产力黑洞</p>
<hr>
<h3>✅ 小批量、高频发布</h3>
<p>这会带来：</p>
<ul>
<li>更低风险</li>
<li>更快反馈</li>
<li>更高稳定性</li>
</ul>
<hr>
<h2>六、对个人开发者的启示</h2>
<p>很多人关心：</p>
<p>AI 会不会取代程序员？</p>
<p>但从这个模型看，真正的分水岭变成了：</p>
<h3>初级开发者</h3>
<p>只会：</p>
<ul>
<li>写代码</li>
<li>完成功能</li>
</ul>
<h3>高级开发者</h3>
<p>会：</p>
<ul>
<li>优化交付流程</li>
<li>设计工程系统</li>
<li>提升团队整体效率</li>
</ul>
<p>未来最值钱的能力不再是：</p>
<p>❌ 写代码速度</p>
<p>而是：</p>
<p>✅ 提升系统生产力的能力</p>
<hr>
<h2>七、总结</h2>
<p>Core 4 的本质是在说一件事：</p>
<blockquote>
<p>开发者生产力是一个系统问题，而不是个人问题。</p>
</blockquote>
<p>真正决定效率的不是：</p>
<p>“你有多努力”</p>
<p>而是：</p>
<ul>
<li>工程体系是否顺滑</li>
<li>组织是否减少阻力</li>
<li>工具链是否现代化</li>
</ul>
<hr>
<h1>最后的思考</h1>
<p>在 AI 时代，一个非常重要的认知转变是：</p>
<p>个人写代码的速度正在被抹平
但：</p>
<p>🏗 构建高效工程系统的能力
正在成为核心竞争力</p>
<p>这可能才是软件工程的下一个分水岭。</p>
<hr>

          <p style='text-align: right'>
          <a href='https://carota.site/notes/10#comments'>Finished reading? Leave a comment</a>
          </p>
    ]]>
    </content:encoded>
  <guid isPermaLink="false">138265555306561543</guid>
  <category>note</category>
false
 </item>
  <item>
    <title>Something Big Is Happening —— 我们可能低估了 AI 的跃迁速度</title>
    <link>https://carota.site/notes/9</link>
    <pubDate>Thu, 12 Feb 2026 10:30:30 GMT</pubDate>
    <description>最近，AI 创业者 Matt Shumer 写了一篇标题颇具张力的文章：

Something Bi</description>
    <content:encoded><![CDATA[
      <blockquote>This rendering is produced by marked and may have formatting issues. For the best experience, visit: <a href='https://carota.site/notes/9'>https://carota.site/notes/9</a></blockquote>
          <p>最近，AI 创业者 <strong>Matt Shumer</strong> 写了一篇标题颇具张力的文章：</p>
<blockquote>
<p><em>Something Big Is Happening</em></p>
</blockquote>
<p>标题看起来像危言耸听，但读完之后，我反而觉得值得认真对待。</p>
<p><a href="https://shumer.dev/something-big-is-happening">这篇文章</a>真正讨论的，并不是“AI 会不会变强”，而是一个更重要的问题：</p>
<blockquote>
<p>AI 是否已经跨过了一条能力分界线？</p>
</blockquote>
<hr>
<h2>1. 从“辅助工具”到“任务执行者”</h2>
<p>过去两年，大多数人对 AI 的理解停留在一个工具层面：</p>
<ul>
<li>帮你写代码</li>
<li>帮你润色文章</li>
<li>帮你总结文档</li>
<li>帮你生成脚本</li>
</ul>
<p>它很强，但仍然需要频繁的人类介入。</p>
<p>Shumer 的判断是：
<strong>最近模型的变化，已经从“能力增强”转向“能力形态改变”。</strong></p>
<p>关键区别在于：</p>
<ul>
<li>能否持续执行多步骤任务</li>
<li>能否发现自身错误并修复</li>
<li>能否在没有人工干预的情况下完成目标</li>
</ul>
<p>如果一个系统可以完成任务闭环，那么它的角色就不再只是工具。</p>
<hr>
<h2>2. 为什么他说这是“质变”</h2>
<p>文章中提到几个信号：</p>
<h3>（1）模型开始参与模型研发</h3>
<p>像 <strong>OpenAI</strong>、<strong>Anthropic</strong> 这样的机构，已经在使用模型辅助代码生成、测试与评估流程。</p>
<p>这意味着：</p>
<blockquote>
<p>AI 不只是被训练的对象，它开始参与自身的改进。</p>
</blockquote>
<p>这在技术史上具有象征意义。</p>
<p>工具开始成为生产工具的组成部分。</p>
<hr>
<h3>（2）认知型任务的边际成本快速下降</h3>
<p>过去十年，自动化主要替代的是：</p>
<ul>
<li>重复劳动</li>
<li>流水线作业</li>
<li>标准化操作</li>
</ul>
<p>而现在，AI 正在逼近的是：</p>
<ul>
<li>分析</li>
<li>推理</li>
<li>写作</li>
<li>编程</li>
<li>决策支持</li>
</ul>
<p>也就是说，它触及的是“认知层工作”。</p>
<p>这才是这篇文章真正令人不安的地方。</p>
<hr>
<h2>3. 但我们需要避免技术情绪化</h2>
<p>我并不完全认同那种“马上全面替代”的叙事。</p>
<p>历史上每一次技术跃迁都经历了三个阶段：</p>
<ol>
<li>技术突破</li>
<li>应用验证</li>
<li>结构重构</li>
</ol>
<p>现在显然处在第一阶段向第二阶段过渡的时期。</p>
<p>真实世界仍然存在：</p>
<ul>
<li>成本约束</li>
<li>可靠性问题</li>
<li>系统整合难度</li>
<li>法律与监管</li>
<li>企业流程惯性</li>
</ul>
<p>技术能力的出现 ≠ 立刻改变产业结构。</p>
<hr>
<h2>4. 真正重要的不是“替代”，而是“结构变化”</h2>
<p>我更关心的是一个趋势：</p>
<blockquote>
<p>认知工作的边际成本正在下降。</p>
</blockquote>
<p>当认知成本下降，会带来什么？</p>
<ul>
<li>小团队能力上限提升</li>
<li>个人生产力极大放大</li>
<li>创业门槛降低</li>
<li>决策周期缩短</li>
</ul>
<p>这意味着竞争模型会变化。</p>
<p>可能不是“你失业”，
而是“你所在的组织结构被重写”。</p>
<hr>
<h2>5. 对个体的现实意义</h2>
<p>如果你是知识型工作者：</p>
<ul>
<li>程序员</li>
<li>产品经理</li>
<li>研究员</li>
<li>分析师</li>
<li>内容创作者</li>
</ul>
<p>真正值得思考的问题不是：</p>
<blockquote>
<p>AI 会不会替代我？</p>
</blockquote>
<p>而是：</p>
<blockquote>
<p>在 AI 存在的情况下，什么能力仍然具有稀缺性？</p>
</blockquote>
<p>可能包括：</p>
<ul>
<li>判断力</li>
<li>系统性思维</li>
<li>抽象建模能力</li>
<li>多领域整合能力</li>
<li>复杂问题拆解能力</li>
</ul>
<p>执行层的价值可能会压缩，
结构层的价值可能会上升。</p>
<hr>
<h2>6. 也许我们低估的不是风险，而是速度</h2>
<p>这篇文章最值得重视的一点，并不是它的语气，而是它的判断：</p>
<blockquote>
<p>能力跃迁往往不是线性的。</p>
</blockquote>
<p>当模型跨过某个阈值时，
它带来的变化会突然显现，而不是渐进体现。</p>
<p>如果这一判断成立，那么真正的挑战不是技术本身，而是：</p>
<blockquote>
<p>我们的认知是否跟得上技术曲线。</p>
</blockquote>
<hr>
<h2>结语</h2>
<p>这篇文章并不是一篇技术论文。
它更像是一种时代感知。</p>
<p>也许时间线会比作者预想得慢。
也许某些行业的变化会更温和。</p>
<p>但有一点越来越清晰：</p>
<p>AI 已经不再处在“实验玩具阶段”。</p>
<p>它正在进入真实生产环境。</p>
<p>真正危险的不是 AI 太快。
而是我们对变化的感知太慢。</p>

          <p style='text-align: right'>
          <a href='https://carota.site/notes/9#comments'>Finished reading? Leave a comment</a>
          </p>
    ]]>
    </content:encoded>
  <guid isPermaLink="false">138265555306561542</guid>
  <category>note</category>
false
 </item>
  
</channel>
</rss>