<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
    <channel>
      <title>bigfish的网络博客 - Rust</title>
      <link>https://blog.laofu.online</link>
      <description>记录技术和生活</description>
      <generator>Zola</generator>
      <language>zh</language>
      <atom:link href="https://blog.laofu.online/tags/rust/rss.xml" rel="self" type="application/rss+xml"/>
      <lastBuildDate>Sat, 03 Oct 2026 00:00:00 +0000</lastBuildDate>
      <item>
          <title>Rust 版 Pi 工作基本完成了，记录下性能对比</title>
          <pubDate>Sat, 03 Oct 2026 00:00:00 +0000</pubDate>
          <author>bigfish</author>
          <link>https://blog.laofu.online/blog/20261003-rpi-performance/</link>
          <guid>https://blog.laofu.online/blog/20261003-rpi-performance/</guid>
          <description xml:base="https://blog.laofu.online/blog/20261003-rpi-performance/">&lt;p&gt;最近做了一个 Rust 项目：&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://github.com/bigfish1913/pi-rust&quot;&gt;pi-rust&lt;/a&gt;。把 TypeScript 版的 Pi 编码助手用 Rust 重写，命令叫 &lt;code&gt;rpi&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;先把测试结果放出来。&lt;/p&gt;
&lt;h2 id=&quot;xian-kan-shu-ju-dui-bi&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#xian-kan-shu-ju-dui-bi&quot; aria-label=&quot;Anchor link for: xian-kan-shu-ju-dui-bi&quot;&gt;先看数据对比&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;对比版本是 rpi 0.3.6 和 Pi 0.87.1&lt;/p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;指标&lt;/th&gt;&lt;th style=&quot;text-align: right&quot;&gt;Rust 版 rpi&lt;/th&gt;&lt;th style=&quot;text-align: right&quot;&gt;TypeScript 版 Pi&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;打印版本号 &lt;code&gt;--version&lt;/code&gt;&lt;/td&gt;&lt;td style=&quot;text-align: right&quot;&gt;17.5 ms&lt;/td&gt;&lt;td style=&quot;text-align: right&quot;&gt;169.5 ms&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;启动到能够响应状态请求&lt;/td&gt;&lt;td style=&quot;text-align: right&quot;&gt;17.7 ms&lt;/td&gt;&lt;td style=&quot;text-align: right&quot;&gt;189.5 ms&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;刚就绪时的常驻内存 RSS&lt;/td&gt;&lt;td style=&quot;text-align: right&quot;&gt;12.0 MiB&lt;/td&gt;&lt;td style=&quot;text-align: right&quot;&gt;91.5 MiB&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;安装体积&lt;/td&gt;&lt;td style=&quot;text-align: right&quot;&gt;21.8 MiB&lt;/td&gt;&lt;td style=&quot;text-align: right&quot;&gt;约 385 MiB&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;启动时间相差约 &lt;strong&gt;10.7 倍&lt;/strong&gt;，rpi 的就绪内存约为 Pi 的 &lt;strong&gt;13%&lt;/strong&gt;。安装体积这一项，Pi 还没有算上 Node 运行时。&lt;/p&gt;
&lt;h2 id=&quot;wei-shen-me-yao-yong-rust-zhong-xie&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#wei-shen-me-yao-yong-rust-zhong-xie&quot; aria-label=&quot;Anchor link for: wei-shen-me-yao-yong-rust-zhong-xie&quot;&gt;为什么要用 Rust 重写？&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id=&quot;1-xue-xi-rust&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#1-xue-xi-rust&quot; aria-label=&quot;Anchor link for: 1-xue-xi-rust&quot;&gt;1. 学习 Rust&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;首先就是想学 Rust。&lt;/p&gt;
&lt;p&gt;我想找一个能持续写下去的项目。Agent 涉及异步请求、流式输出、文件操作和状态管理，后面还有终端界面和插件。这些需求会逼着我把 Rust 用起来：共享状态怎么处理，错误怎么往上传，异步任务怎么取消，接口怎么拆。&lt;/p&gt;
&lt;p&gt;选 Pi 来重写，也有一个好处：有现成的项目可以参考。遇到一个功能，可以先看原版怎么做，再考虑在 Rust 里怎么实现。写完以后还有东西可以对照，不至于只凭自己的想象判断是否合理。&lt;/p&gt;
&lt;h3 id=&quot;2-xiang-nong-ming-bai-yi-ge-agent-shi-zen-me-gong-zuo-de&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#2-xiang-nong-ming-bai-yi-ge-agent-shi-zen-me-gong-zuo-de&quot; aria-label=&quot;Anchor link for: 2-xiang-nong-ming-bai-yi-ge-agent-shi-zen-me-gong-zuo-de&quot;&gt;2. 想弄明白一个  Agent 是怎么工作的&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;平时用 AI 编码工具，看到的是输入需求、等它改代码。自己实现一次，就得处理那些界面上看不见的细节。&lt;/p&gt;
&lt;p&gt;模型返回一个工具调用以后，谁去执行？工具出错了，要把什么结果交给模型？流式消息还没结束，用户取消了怎么办？程序中断后，下一次启动看到的历史应该是什么？&lt;/p&gt;
&lt;p&gt;这些问题在调一次聊天 API 时未必会遇到，做完整 Agent 就绕不过去。&lt;/p&gt;
&lt;p&gt;核心循环其实不长：请求模型，发现工具调用，执行工具，回传结果，再请求模型。周围的错误处理、取消、会话保存，才是需要花心思的地方。&lt;/p&gt;
&lt;h3 id=&quot;3-xiang-ba-ta-zuo-cheng-yi-ge-neng-fu-yong-de-ku&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#3-xiang-ba-ta-zuo-cheng-yi-ge-neng-fu-yong-de-ku&quot; aria-label=&quot;Anchor link for: 3-xiang-ba-ta-zuo-cheng-yi-ge-neng-fu-yong-de-ku&quot;&gt;3. 想把它做成一个能复用的库&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;我希望 rpi 除了能在终端里运行，也能直接嵌进自己的 Rust 程序。应用调用接口、订阅事件，就能使用 Agent 的能力。&lt;/p&gt;
&lt;p&gt;所以项目用了 Cargo workspace，把模型适配、Agent 循环、工具执行和会话管理拆开。CLI 再把它们组合起来。&lt;/p&gt;
&lt;p&gt;最小的 Agent 不需要终端界面，也不一定需要持久化。需要文件工具，就加工具层；需要保存会话和压缩上下文，再接 Harness。这样不同应用能各取所需。&lt;/p&gt;
&lt;h3 id=&quot;4-kan-kan-yuan-sheng-cheng-xu-neng-sheng-xia-duo-shao-kai-xiao&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#4-kan-kan-yuan-sheng-cheng-xu-neng-sheng-xia-duo-shao-kai-xiao&quot; aria-label=&quot;Anchor link for: 4-kan-kan-yuan-sheng-cheng-xu-neng-sheng-xia-duo-shao-kai-xiao&quot;&gt;4. 看看原生程序能省下多少开销&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;终端工具最后能交付一个可执行文件，安装时少管理一套 Node 和 npm 依赖，我觉得值得试。&lt;/p&gt;
&lt;p&gt;启动和内存上的收益，前面的测试已经给了一组结果。代价也有：Rust 的异步接口、共享状态和动态插件都需要仔细处理。把原版代码逐行翻译过来，很多地方并不好用，接口也得跟着重新整理。&lt;/p&gt;
&lt;h2 id=&quot;xian-zai-dao-na-yi-bu-liao&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#xian-zai-dao-na-yi-bu-liao&quot; aria-label=&quot;Anchor link for: xian-zai-dao-na-yi-bu-liao&quot;&gt;现在到哪一步了&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;已经有 CLI、TUI 和 SDK，不只是一个调用模型的 demo。当前工作区版本是 &lt;strong&gt;0.3.14&lt;/strong&gt;；发布状态以仓库 Releases 和 crates.io 为准。&lt;/p&gt;
&lt;p&gt;模型侧有 Anthropic 和 OpenAI 兼容接口，也支持通过配置接自定义网关。Agent 能处理流式响应、工具调用和取消，配有文件读写、编辑和命令执行等工具。&lt;/p&gt;
&lt;p&gt;会话用 JSONL 保存，支持分支、上下文压缩和中断恢复。这里也一直在修实际问题。比如 CHANGELOG 里记录过：会话中断时，工具调用已经保存，结果还没保存，恢复后的消息就可能被模型服务拒绝。现在会补上表示中断的错误结果，让上下文可以继续使用，而不会直接重跑那个工具。&lt;/p&gt;
&lt;p&gt;扩展方面已经有动态库插件 SDK 和加载器。远程模式也有了，可以在一台机器上跑 Agent，另一端用终端连接。&lt;/p&gt;
&lt;p&gt;这些功能对应九个产品 crate。主要几层如下：&lt;/p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;crate&lt;/th&gt;&lt;th&gt;做什么&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;rpi-ai&lt;/code&gt;&lt;/td&gt;&lt;td&gt;模型适配、消息类型和流式响应&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;rpi-agent&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Agent 循环、工具调用、事件和取消&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;rpi-tools&lt;/code&gt;&lt;/td&gt;&lt;td&gt;内置工具和执行环境&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;rpi-harness&lt;/code&gt;&lt;/td&gt;&lt;td&gt;会话、持久化、恢复和上下文压缩&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;rpi-cli&lt;/code&gt;&lt;/td&gt;&lt;td&gt;配置、CLI、TUI 和远程模式&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;想从代码看起，可以先跑两个例子：&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;powershell&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cargo run &lt;/span&gt;&lt;span class=&quot;z-d-8&quot;&gt;-&lt;/span&gt;&lt;span&gt;p minimal&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cargo run &lt;/span&gt;&lt;span class=&quot;z-d-8&quot;&gt;-&lt;/span&gt;&lt;span&gt;p tools&lt;/span&gt;&lt;span class=&quot;z-d-8&quot;&gt;-&lt;/span&gt;&lt;span&gt;example&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;它们用模拟 Provider，不需要模型密钥。第二个例子会驱动真实工具，在临时目录写文件，再读取并验证内容。这样可以先检查 Agent 的执行流程，不受真实模型输出影响。目前还有不少需要打磨的地方。&lt;/p&gt;
&lt;h2 id=&quot;you-mei-you-hou-xu-de-kuo-zhan-ji-hua&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#you-mei-you-hou-xu-de-kuo-zhan-ji-hua&quot; aria-label=&quot;Anchor link for: you-mei-you-hou-xu-de-kuo-zhan-ji-hua&quot;&gt;有没有后续的扩展计划&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;有，接下来想继续做的主要是这些方向。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;扩展更容易写和安装。&lt;/strong&gt; 插件接口和加载器已经有了，但还需要更顺手的模板、版本兼容说明，以及能直接拿来用的扩展。先把开发和使用的流程理顺，比单纯增加插件数量更有用。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;继续补模型适配。&lt;/strong&gt; 现有 Provider 接口可以复用，后面会根据使用需求考虑 Gemini、Bedrock 等适配器。每接一种协议，都要检查流式事件、工具调用和错误处理，不能只验证普通聊天能返回文字。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;把性能测试往长任务上补。&lt;/strong&gt; 下一步值得测的是长会话内存增长、工具循环吞吐、上下文压缩和 TUI 渲染。启动数据已经有了，我也想知道连续用上几个小时以后是什么表现。&lt;/p&gt;
&lt;p&gt;更往后的方向包括执行隔离、编辑器集成，以及是否把多 Agent 编排放进核心运行时。这些需要继续设计，暂时没有确定的交付时间。&lt;/p&gt;
&lt;p&gt;项目地址：&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://github.com/bigfish1913/pi-rust&quot;&gt;bigfish1913/pi-rust&lt;/a&gt;。如果你也在学 Rust，或者想拆开看看  Agent 的实现，可以从两个离线示例开始。&lt;/p&gt;
</description>
      </item>
    </channel>
</rss>
