<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>NeuroSquad 博客</title>
    <link>https://neurosquad.ai/zh/blog/</link>
    <description>NeuroSquad 开发手记：这款桌面应用把 AI 智能体 CLI 作为卡片放在同一块画布上。这里记录设计决策、实测数据、踩过的坑，以及每个版本带来的变化。</description>
    <language>zh-cn</language>
    <lastBuildDate>Sat, 26 Sep 2026 14:31:27 GMT</lastBuildDate>
    <atom:link href="https://neurosquad.ai/zh/blog.xml" rel="self" type="application/rss+xml"/>
    <item>
      <title>十九个智能体 CLI，同一种集成深度</title>
      <link>https://neurosquad.ai/zh/blog/nineteen-agent-clis/</link>
      <guid isPermaLink="true">https://neurosquad.ai/zh/blog/nineteen-agent-clis/</guid>
      <pubDate>Sat, 26 Sep 2026 14:31:27 GMT</pubDate>
      <category>版本发布</category>
      <category>集成</category>
      <category>工程</category>
      <description>NeuroSquad 如何把 19 个智能体 CLI 提升到 Claude Code 的水平：一份约四十项能力的清单，每个工具各用一套机制，做不到的地方给出证明。</description>
      <content:encoded>&lt;p&gt;&lt;img src=&quot;https://neurosquad.ai/blog/nineteen-agent-clis/add-menu-zh.webp&quot; alt=&quot;NeuroSquad 的添加卡片菜单，列出带图标的智能体 CLI，并标出已安装的&quot;/&gt;&lt;/p&gt;&lt;p&gt;NeuroSquad 0.1.137 新增了九个智能体 CLI——Gemini CLI、GitHub Copilot CLI、Amp、Factory Droid、aider、Goose、Kimi Code、Cline 和 Auggie——并把 Cursor CLI 和 Crush 提升到与其他成员相同的水平。总数达到十九个，而“支持”一词第一次对它们所有人都意味着同一件事。&lt;/p&gt;
&lt;p&gt;三天前还不是这样。第一个版本就能在卡片里运行十个 CLI，但只有 Claude Code 是深度集成的：它的状态来自它自己的钩子，重启后会话能够恢复，它能通过箭头拿到工具。其他的只是跑在终端里，大多靠启发式判断来盯着。这篇文章讲的就是如何补上这个差距——在一天之内的三个版本里。&lt;/p&gt;
&lt;p&gt;&lt;em&gt;各个版本中，哪些 CLI 拥有完整集成。在各步之间切换看看。&lt;/em&gt; &lt;a href=&quot;https://neurosquad.ai/zh/blog/nineteen-agent-clis/&quot;&gt;可交互复刻——动手试试&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;“同一种深度”指的是什么&lt;/h2&gt;
&lt;p&gt;我们把应用为 Claude Code 做的所有事情写成了一份约四十项能力的清单，每个 CLI 都有一份自己的文档，逐行对照这份清单。每一行只可能是三种情况之一：&lt;strong&gt;原生&lt;/strong&gt;（CLI 本身具备，应用直接使用）、&lt;strong&gt;模拟&lt;/strong&gt;（借助该 CLI 的另一种机制实现，并写明怎么做），或者&lt;strong&gt;不可能&lt;/strong&gt;——附上证明，通常是 CLI 自己源代码中的一行。&lt;/p&gt;
&lt;p&gt;对画布使用者来说最重要的几行：&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&lt;strong&gt;会话恢复&lt;/strong&gt;：重启应用或卡片后，智能体接着同一段对话继续。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;精确状态&lt;/strong&gt;：工作中、等你处理、已完成——来自 CLI 自身的事件，并附上它具体在问什么。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;通过箭头使用工具&lt;/strong&gt;：应用的 MCP 工具，加上已连接的 MCP 服务器和技能。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;卡片模式&lt;/strong&gt;：智能体通过卡片（用终端跑命令，用浏览器上网）而不是自带的内置工具来工作，而且在危险模式下同样有效。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;安全中断&lt;/strong&gt;：由预算刹车触发，不会丢失会话。&lt;/li&gt;&lt;li&gt;按卡片统计的&lt;strong&gt;用量和模型&lt;/strong&gt;、&lt;strong&gt;上下文指示&lt;/strong&gt;和压缩，以及达到速率限制后的&lt;strong&gt;自动继续&lt;/strong&gt;。&lt;/li&gt;&lt;/ul&gt;
&lt;h2&gt;每个 CLI 都需要一条不同的路子&lt;/h2&gt;
&lt;p&gt;清单是同一份，机制却几乎从不相同。对 Claude Code，应用会在你的设置之上叠加一个设置文件，它的钩子用一行 &lt;code&gt;curl&lt;/code&gt; 上报每一次状态变化。下面是其他几个是怎么做到的。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;OpenCode&lt;/strong&gt; 用的是一个插件——所有卡片共用一个文件——负责上报会话状态和权限请求。它的配置通过一个环境变量传入，这个变量是用排除法选出来的：用于内联 JSON 的那个变量已经在承载 OpenRouter 署名请求头，同一个变量有两个写入方就会互相覆盖；而用于配置&lt;em&gt;目录&lt;/em&gt;的那个变量，会让你的全局指令文件失效。中断它也得小心：在 OpenCode 里，输入框为空时按 Ctrl+C 会&lt;strong&gt;直接关闭应用&lt;/strong&gt;，而预算刹车以前发的恰恰就是这个。现在它改为连按两次 Escape。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Hermes Agent&lt;/strong&gt; 会读取一个管理员级别的配置层，应用把它指向每张卡片专属的一个文件，并按叶子节点逐项合并到你的配置之上。一次实测发现，它的交互模式只有在 MCP 服务器写在你的原始配置里时才会去连接——所以卡片会在提示符就绪后自己输入 &lt;code&gt;/reload-mcp&lt;/code&gt;，第一个提示词要等出现 &lt;code&gt;Agent updated&lt;/code&gt; 之后才会插入。另一个发现是：模型提供方出错时，Hermes 永远不会发出会话结束事件，卡片就一直停在“工作中”；现在只要一轮尚未结束，应用还会在终端里留意 Hermes 打印出的提供方错误。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Gemini CLI&lt;/strong&gt; 和它的分支 Qwen Code 一样有一个系统设置路径，但只有当那个文件归管理员所有、且普通用户不可写时，它才会加载。放在应用文件夹里的文件会被跳过，并给出一条安全警告。Gemini 认的是主目录覆盖，所以每张 Gemini 卡片都用一个自己的主目录运行，里面放着它的设置层——而你真实 &lt;code&gt;~/.gemini&lt;/code&gt; 里的其他一切，包括会话和登录信息，都通过目录联接链接进来。卡片的会话就是你的会话：&lt;code&gt;gemini --resume&lt;/code&gt; 在普通终端里也能用，反之亦然。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;aider&lt;/strong&gt; 没有 MCP 客户端，没有钩子，也没有插件 API。不过它是个 Python 程序，而 Python 会在一切代码之前，先从路径中导入 &lt;code&gt;sitecustomize&lt;/code&gt; 模块。aider 卡片启动时，&lt;code&gt;PYTHONPATH&lt;/code&gt; 的第一位是一个专用文件夹，其中的模块会在 aider 的六个模块加载时逐个打补丁——每个补丁都有防护，如果以后的 aider 改了某个方法的名字，只会关掉那一个功能——然后再把自己的变量移除，这样 aider 启动的任何东西都不会继承它们。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Kilo Code&lt;/strong&gt; 默认会连接到一个正在运行的 Kilo 守护进程，而不是启动自己的工作进程；可守护进程有它自己的环境——卡片会悄无声息地丢掉自己的配置、工具和 MCP 令牌。现在每张 Kilo 卡片启动时都会打开关闭这种连接的开关。&lt;strong&gt;Codex CLI&lt;/strong&gt; 以前在卡片停止后还能活下来：npm 包装脚本退出了，&lt;code&gt;codex.exe&lt;/code&gt; 却还在跑。现在卡片直接启动真正的可执行文件。&lt;/p&gt;
&lt;figure&gt;&lt;img src=&quot;https://neurosquad.ai/blog/nineteen-agent-clis/new-agent-zh.webp&quot; alt=&quot;“新建智能体”对话框，展开了智能体 CLI 列表&quot;/&gt;&lt;figcaption&gt;创建智能体时选择 CLI、提供方和模型。已安装的 CLI 是在本机当前的 PATH 中找到的。&lt;/figcaption&gt;&lt;/figure&gt;
&lt;h2&gt;“不可能”也是一种答案&lt;/h2&gt;
&lt;p&gt;有些行填不上，而把这一点说清楚，本身就是工作的一部分。有几个 CLI——Auggie、Droid、Goose、Kimi——不允许调用方指定会话 id；应用会记下它们自己生成的 id，并据此恢复会话。Auggie 没有压缩命令，因为上下文窗口满了它会自己总结历史；所以它的卡片上干脆没有“压缩”按钮。Cline 只在会话启动时读取一次服务器的工具列表，之后不会刷新——所以会话中途画的箭头要到下次启动才生效，文档里也写明了这一点。&lt;/p&gt;
&lt;p&gt;Kimi Code 有同样的限制，但在它身上做成了模拟：Kimi 卡片从一开始就拿到所有内置工具组，由箭头在调用时决定是否放行。一张在会话中途新建的笔记卡片，在同一个会话里就被写入了内容。&lt;/p&gt;
&lt;p&gt;Amp 是最坦率的一个例子。它的智能体循环——包括模型调用——运行在 Amp 的服务器上；本地 CLI 只负责执行工具。所以对 Amp 来说，OpenRouter 及其署名都是不可能的，应用围绕它所做的一切，都是对着一个本地伪造的 Amp 服务器验证的。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;实测发现：被终端折断的一行&lt;/strong&gt; Goose 的会话被删除后，它会打印 &lt;code&gt;no such session exists&lt;/code&gt;，应用本该据此用一个新会话恢复。第一个版本没认出来：Windows 控制台把这一行折成了 &lt;code&gt;no suc / h session exists&lt;/code&gt;。现在匹配恢复标记时会先去掉所有空白。&lt;/p&gt;
&lt;h2&gt;怎么测的&lt;/h2&gt;
&lt;p&gt;每个 CLI 都装在临时文件夹里，从不全局安装，并由一个独立的应用构建来运行，它有自己的配置文件和一个临时主目录，所以没有读写任何人的真实配置。大多数 CLI 都指向本地回环接口上的一个小型脚本化模型服务器——它会回答 &lt;code&gt;PING&lt;/code&gt;、调用工具、卡住十五秒、返回 429——这样速率限制、卡顿和权限提示都能按需制造，而不必干等。&lt;/p&gt;
&lt;p&gt;同一个服务器还记录了请求头，OpenRouter 署名就是这样核对的：每个与 OpenRouter 通信的 CLI 现在都会发送 NeuroSquad 的请求头，包括使用 CLI 自己的 OpenRouter 登录的卡片，而且每一个都是&lt;strong&gt;在拦截服务器上实测的&lt;/strong&gt;，而不是照搬文档。&lt;/p&gt;
&lt;figure&gt;&lt;img src=&quot;https://neurosquad.ai/blog/nineteen-agent-clis/add-menu-zh.webp&quot; alt=&quot;添加卡片菜单：智能体 CLI 排在最前，有搜索框，并标出已安装的&quot;/&gt;&lt;figcaption&gt;添加卡片菜单把智能体排在最前；本机已安装的会被标出。&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;一路上还顺带修了两个小问题：Kilo Code 卡片不再因为共享的守护进程而丢失设置，Qwen Code 访问应用 MCP 服务器的令牌也不再写入磁盘。完整列表见 &lt;a href=&quot;https://neurosquad.ai/zh/changelog/#v0.1.128&quot;&gt;0.1.128&lt;/a&gt;、&lt;a href=&quot;https://neurosquad.ai/zh/changelog/#v0.1.133&quot;&gt;0.1.133&lt;/a&gt; 和 &lt;a href=&quot;https://neurosquad.ai/zh/changelog/#v0.1.137&quot;&gt;0.1.137&lt;/a&gt; 的更新日志。&lt;/p&gt;</content:encoded>
    </item>
    <item>
      <title>社区卡片、MCP 服务器和技能——全都用一支箭头连接</title>
      <link>https://neurosquad.ai/zh/blog/cards-mcp-skills-by-arrow/</link>
      <guid isPermaLink="true">https://neurosquad.ai/zh/blog/cards-mcp-skills-by-arrow/</guid>
      <pubDate>Fri, 25 Sep 2026 10:25:35 GMT</pubDate>
      <category>版本发布</category>
      <category>扩展</category>
      <category>安全</category>
      <description>NeuroSquad 走向开放：人人可做的卡片、来自公共目录的 MCP 服务器和技能、已验证卡片。每一样如何隔离，以及为什么箭头依然就是权限。</description>
      <content:encoded>&lt;p&gt;&lt;img src=&quot;https://neurosquad.ai/blog/cards-mcp-skills-by-arrow/catalog-zh.webp&quot; alt=&quot;NeuroSquad 中的 MCP 和技能目录，显示来自官方 MCP Registry 的搜索结果&quot;/&gt;&lt;/p&gt;&lt;p&gt;直到这周，NeuroSquad 画布上的每一张卡片都出自我们之手。0.1.123 同时从三个方向改变了这一点：人人都能制作并发布在 GitHub 上的&lt;strong&gt;社区卡片&lt;/strong&gt;、来自官方 MCP Registry 的 &lt;strong&gt;MCP 服务器&lt;/strong&gt;，以及来自 skills.sh 的&lt;strong&gt;技能&lt;/strong&gt;——每一样都通过画一支箭头交给某个特定的智能体。一个半小时后，0.1.125 又加入了&lt;strong&gt;已验证卡片&lt;/strong&gt;：一份经过审查的清单，配一枚含义精确的徽章。&lt;/p&gt;
&lt;p&gt;画布有一条让它清晰可读的规则：智能体能用的，恰好就是它的箭头所指向的东西。只有这条规则保得住，向别人的代码开放才值得做。这两个版本的大部分工作，都是为了确保它保得住。&lt;/p&gt;
&lt;h2&gt;第一步：让添加一张卡片变得便宜&lt;/h2&gt;
&lt;p&gt;最早的卡片是手工接入应用的：联合类型里加一个卡片类型、画布里加一个分支、标签、图标、MCP 服务器表里的一项、删除级联里的一步——每张卡片大约要改十几个地方。一张一张来还能忍，几张并行开发就必然冲突。&lt;/p&gt;
&lt;p&gt;所以内置卡片先变成了插件：页面里一个文件夹，主进程里一个模块，IPC 通道统一使用一个公共前缀，MCP 工具由卡片自己注册，文案放在各自的文件里。画布、侧边栏、箭头和删除流程以同样的方式处理每一张插件卡片。一旦卡片成了插件，让别人来写一张，就只是隔离问题，而不再是接线问题。&lt;/p&gt;
&lt;h2&gt;社区卡片：一个出不了卡片的沙箱&lt;/h2&gt;
&lt;p&gt;社区卡片就是一个小型网页应用。它本可以运行在单独的原生 Web 视图里，但那是操作系统层面的叠加层：它会浮在画布之上而不是嵌在画布之中，也不会随画布一起缩放和裁剪。所以它改为运行在一个具有不透明源的沙箱 &lt;code&gt;iframe&lt;/code&gt; 里，通过应用自己的协议提供内容。在此基础上动工之前，我们在这个确切的 Electron 版本上核实了这样的框架能做什么、不能做什么：&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;它运行在&lt;strong&gt;独立的操作系统进程&lt;/strong&gt;中。一张卡片在忙循环里空转四秒，画布也没有被冻住：宿主的计时器照常走动，最大间隔 63 ms。&lt;/li&gt;&lt;li&gt;&lt;code&gt;window.api&lt;/code&gt;、Node 和 &lt;code&gt;require&lt;/code&gt; 根本不存在，碰一下父页面就会抛出安全错误。&lt;/li&gt;&lt;li&gt;&lt;code&gt;localStorage&lt;/code&gt; 和 IndexedDB 不可用（所以有一套专门的存储 API），对外请求会被框架的内容安全策略拦下。&lt;/li&gt;&lt;li&gt;它无法打开窗口、无法全屏、无法读取剪贴板，也无法打开麦克风。&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;有两项检查没通过，而这恰恰是最有价值的。WebRTC 完全无视内容安全策略：一个对等连接连上了本机的一个 TCP 监听端口。修复很直接——卡片的启动脚本在任何卡片代码运行之前，就把 WebRTC 构造函数删掉。第二个问题出在应用里，而不是框架里：它的权限处理程序会把麦克风授予任何请求者。现在它只授予应用自己的顶层页面；这就是更新日志里“麦克风权限只授予应用本身”那一行。&lt;/p&gt;
&lt;p&gt;卡片从不和绘制它的那个页面直接对话。它拿到的是一个通往主进程的消息端口，绑定在这一个卡片实例上，每个请求都会在主进程里，对照软件包声明、且你在安装时授予的权限进行检查。凡是触及另一张卡片或某个智能体的操作——通过端口发送数据、给智能体发提示词、在终端里输入——都&lt;strong&gt;既&lt;/strong&gt;需要权限，&lt;strong&gt;又&lt;/strong&gt;需要两张卡片之间有一支箭头。箭头就是对这一条数据流的同意。&lt;/p&gt;
&lt;p&gt;安装通过 GitHub 地址进行，固定到某个提交，并与软件包文件树的哈希核对。更新只在你点击时才会发生，并且会先告诉你权限有哪些变化。如何自己做一张，见 &lt;a href=&quot;https://neurosquad.ai/zh/card-sdk/&quot;&gt;Card SDK 页面&lt;/a&gt;。&lt;/p&gt;
&lt;h2&gt;已验证卡片：一枚只代表一件事的徽章&lt;/h2&gt;
&lt;p&gt;按地址安装的模式有个明显的缺口：怎样找到值得安装的卡片？0.1.125 加入了一份由 NeuroSquad 团队审查过的卡片目录，存放在一个公开仓库里，通过 PR 更新。你可以在“自定义卡片…”选择器或“设置”里搜索它。&lt;/p&gt;
&lt;figure&gt;&lt;img src=&quot;https://neurosquad.ai/blog/cards-mcp-skills-by-arrow/verified-zh.webp&quot; alt=&quot;自定义卡片选择器的“已验证”标签页，显示一张经过审查的卡片及其绿色盾牌徽章&quot;/&gt;&lt;figcaption&gt;选择器里的已验证卡片。盾牌表示这份代码本身经过了审查——而不是说它永远不可能造成危害。&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;徽章由主进程判定，含义就是这一条：已安装的卡片来自经过审查的仓库、处于经过审查的提交，&lt;strong&gt;并且&lt;/strong&gt;安装时计算出的文件哈希与目录中的哈希一致。本地开发文件夹、别的提交、不一样的文件——都没有徽章。&lt;/p&gt;
&lt;p&gt;从目录安装还更进一步：如果名称、版本或哈希与目录条目不符，安装会被&lt;strong&gt;拒绝&lt;/strong&gt;。这里要在“装上但不给徽章”和“干脆不装”之间做选择，而被掉包的软件包不该被悄悄装上。更新的已审查版本会以更新的形式提供，附带常规的权限差异，永远不会自行应用；一张卡片从清单中移除后，会失去徽章，但你画布上的任何东西都不会被删除。&lt;/p&gt;
&lt;h2&gt;MCP 服务器和技能，用箭头连接&lt;/h2&gt;
&lt;p&gt;应用内的目录可以搜索官方 MCP Registry（约 3.5 万个服务器）和 skills.sh（安装量最高的 2 万个技能）。搜索在应用本地进行，基于随应用分发、并增量更新的快照——所以离线可用，而且即搜即得。&lt;/p&gt;
&lt;figure&gt;&lt;img src=&quot;https://neurosquad.ai/blog/cards-mcp-skills-by-arrow/catalog-zh.webp&quot; alt=&quot;目录中的 MCP 服务器标签页及搜索结果&quot;/&gt;&lt;figcaption&gt;直接在应用里搜索 MCP Registry。安装时会展示将要运行什么，并只征求一次同意。&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;把 MCP 服务器交给智能体，最直接的办法是把它写进智能体 CLI 的配置里。我们刻意没这么做。NeuroSquad 自己充当你安装的每个服务器的 MCP 客户端，再通过自己的 MCP 服务器把这些工具以 &lt;code&gt;&amp;lt;alias&amp;gt;__&amp;lt;tool&amp;gt;&lt;/code&gt; 的形式重新提供出来——只提供给有箭头连向该服务器卡片的智能体，而且只在箭头存在期间提供。不会往你的 CLI 配置文件夹里写任何东西，服务器的密钥也永远不会离开主进程。Claude Code 无需重启就能识别新画的箭头；其他 CLI 在下次启动时生效。&lt;/p&gt;
&lt;p&gt;&lt;em&gt;复刻：一个已安装的 MCP 服务器、两个智能体，以及把这个服务器只交给其中一个的那支箭头。&lt;/em&gt; &lt;a href=&quot;https://neurosquad.ai/zh/blog/cards-mcp-skills-by-arrow/&quot;&gt;可交互复刻——动手试试&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;技能的工作方式相同，通过一个工具 &lt;code&gt;skill_load&lt;/code&gt; 实现，它的描述里列出了连接到该智能体的技能，以及各自适用的场景。有一个标志决定了这是一个功能还是一场演示：智能体会把 MCP 工具藏在工具搜索后面，在一次实测中，一个全新的智能体一次都没有加载过匹配的技能。标记为“始终加载”后，它自己就加载了对的那个。&lt;/p&gt;
&lt;p&gt;&lt;em&gt;技能同理：用箭头连接，任务需要时加载。&lt;/em&gt; &lt;a href=&quot;https://neurosquad.ai/zh/blog/cards-mcp-skills-by-arrow/&quot;&gt;可交互复刻——动手试试&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;一次安全审查带来了什么&lt;/h2&gt;
&lt;p&gt;两个版本在发布前都经过了安全审查，其中三项结果值得一说：&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&lt;strong&gt;每个智能体都有自己的令牌&lt;/strong&gt;来访问应用的 MCP 服务器，由每次启动生成的密钥和智能体的 id 派生而来。以前，一个智能体理论上可以冒充另一个；现在访问别的智能体的路径会返回 401。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;第三方工具放在第二个 MCP 服务器上&lt;/strong&gt;，它不在 CLI 的预批准工具列表里。所以每次调用别人服务器上的工具之前，CLI 都会先问你——而且工具列表在安装时会生成指纹，服务器之后若改动了工具，就要等你接受这些变更。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;技能整体取自同一个提交。&lt;/strong&gt;skills.sh 自己的内容哈希无法根据它提供的文件复现出来，所以应用对你预览过的那些文件自行固定一个 SHA-256，并且安装的正是那些文件。&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;并非所有东西都能纳入。Figma 官方的远程服务器对动态客户端注册返回 403——它只接受获批的客户端——所以目录改为指向一个使用个人令牌的社区服务器。需要本地 HTTP 服务器的软件包暂不支持。这两点都如实写明，而不是绕过去。&lt;/p&gt;
&lt;p&gt;更多内容见 &lt;a href=&quot;https://neurosquad.ai/zh/mcp/&quot;&gt;MCP 服务器&lt;/a&gt;和&lt;a href=&quot;https://neurosquad.ai/zh/skills/&quot;&gt;技能&lt;/a&gt;页面，完整列表见 &lt;a href=&quot;https://neurosquad.ai/zh/changelog/#v0.1.123&quot;&gt;0.1.123&lt;/a&gt; 和 &lt;a href=&quot;https://neurosquad.ai/zh/changelog/#v0.1.125&quot;&gt;0.1.125&lt;/a&gt; 的更新日志。&lt;/p&gt;</content:encoded>
    </item>
    <item>
      <title>五十张卡片，一块画布：CPU 都花到哪去了，以及“团队”卡片</title>
      <link>https://neurosquad.ai/zh/blog/fifty-cards-one-canvas/</link>
      <guid isPermaLink="true">https://neurosquad.ai/zh/blog/fifty-cards-one-canvas/</guid>
      <pubDate>Thu, 24 Sep 2026 19:07:33 GMT</pubDate>
      <category>版本发布</category>
      <category>性能</category>
      <category>工程</category>
      <description>NeuroSquad 如何把空闲画布的渲染进程 CPU 从约 100% 降到约 15%：实测找出的原因、WebGL 上下文池、语义缩放，以及新的“团队”状态卡片。</description>
      <content:encoded>&lt;p&gt;&lt;img src=&quot;https://neurosquad.ai/blog/fifty-cards-one-canvas/overview-zh.webp&quot; alt=&quot;缩小后的“Launch day”工作区：每张卡片都显示为一块大号概览磁贴，而不是其内容&quot;/&gt;&lt;/p&gt;&lt;p&gt;NeuroSquad 0.1.117 这个版本，你主要是通过“不再发生的事”感受到的：什么都没做时风扇狂转；拖动一个装满卡片的框时一顿一顿；每次缩小到卡片变成磁贴的那个临界点时卡一下。它还加入了“团队”卡片——一块告诉你工作区里每个智能体在做什么的面板。&lt;/p&gt;
&lt;p&gt;从最初那几周起，画布的目标就没变过：最多五十张活的卡片——终端、浏览器、智能体——平移、缩放、拖动和调整大小都要流畅。达成目标的规矩也没变过：先测量。本文中的每个数字，都来自一个使用全新配置文件的独立应用实例，由通过 DevTools 协议发送的真实输入事件驱动。&lt;/p&gt;
&lt;h2&gt;第一轮：五十个终端&lt;/h2&gt;
&lt;p&gt;第一轮优化发生在公开发布之前，场景是一个有五十张卡片的工作区，其中十二个终端在全速输出。缩放之所以慢，原因很容易被忽略：每张卡片的标题栏都要在屏幕上保持固定尺寸，而它是用 &lt;code&gt;width&lt;/code&gt; 和 &lt;code&gt;margin&lt;/code&gt; 实现的。这些都是布局属性。缩放的每一帧都会改变每个标题栏的尺寸，进而改变每张卡片主体的尺寸，进而触发每个终端的尺寸观察器——五十次终端重新适配、五十条发往主进程的消息、五十次控制台尺寸调整。每一帧都是。&lt;/p&gt;
&lt;p&gt;修复办法是：缩放值每个手势只提交一次，而不是每帧都提交；只有当终端的行列网格真正变化时才调整终端尺寸；缩放进行时，把活的终端网格换成静态占位图。随后，终端从 DOM 渲染器换成了 xterm 的 WebGL 渲染器，大部分时间正是耗在这里：缩放的中位帧时间从 18.2 ms 降到 6.1 ms，p95 从 133 ms 降到 12 ms。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Chromium 每个进程恰好保留 16 个 WebGL 上下文&lt;/strong&gt; 这是测出来的，不是猜的。给全部五十个终端都开启 WebGL，一秒之内结果就是 &lt;code&gt;live: 16, lost: 34&lt;/code&gt;——而且幸存的十六个是最先挂载的，而不是你正在看的那些。所以终端从一个容量为十五的池子里领取上下文：分给屏幕上的终端，离开屏幕的则收回。&lt;/p&gt;
&lt;p&gt;那一轮的一项测量定下了一条至今仍在代码里的规则。把终端藏在占位图后面，让缩放快了一倍（中位数 6.1 对 12.0 ms），却让平移变慢了（平均 19.8 对 16.3 ms）：平移只是移动已经绘制好的图层，把五十个网格换出去再换回来，花的比省的还多。所以只有当手势真的改变了缩放时，才会出现占位图。&lt;/p&gt;
&lt;h2&gt;第二轮：空闲的画布&lt;/h2&gt;
&lt;p&gt;第二轮始于一个更奇怪的抱怨：&lt;em&gt;什么都没发生&lt;/em&gt;的时候，画布也很沉。四路并行的代码审查加上一次针对“Launch day”工作区的实时性能剖析，发现原因不是一个，而是一堆小而持续的开销。其中最大的一个，是个卡通形象。&lt;/p&gt;
&lt;p&gt;AI 智能体卡片上有一个显示智能体状态的小吉祥物。它的待机动画是作用在 SVG 子元素上的无限 CSS 动画——而对这类元素，浏览器要在主线程上每一帧都重绘，永无止境。一块缩放在 60% 的画布上放着三张 Claude Code 卡片，什么都不做，渲染进程就占用了一个核心的 98–104%，GPU 占 32–36%。现在只有“工作中”状态会循环，而且动的是外层的 HTML 包装元素，由合成器独立处理；其他状态都只播放几遍，然后停在一个本身就能说明状态的姿势上。&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&lt;strong&gt;~100% → 15%&lt;/strong&gt; — 渲染进程 CPU，放着三张智能体卡片的空闲画布&lt;/li&gt;&lt;li&gt;&lt;strong&gt;~34% → 3%&lt;/strong&gt; — 同一块画布上的 GPU&lt;/li&gt;&lt;li&gt;&lt;strong&gt;180 → 66&lt;/strong&gt; — 一条 CSS 规则之后的合成层数量&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;剩下的是一串清单，每一项都只花一点点，却全都一刻不停地在跑：&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;**画布下带 &lt;code&gt;&lt;em&gt;&lt;/code&gt; 和 &lt;code&gt;:has()&lt;/code&gt; 的选择器。&lt;/em&gt;*每次在画布面板上切换一个类，都要花 25–34 ms 重新计算样式，因为“手势下的所有后代元素”这类规则必须对每张卡片的每个节点重新匹配。改为只列出真正有动画的元素后，降到了约 1.5 ms。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;面板上的 CSS 变量。&lt;/strong&gt;缩放级别存放在包含所有卡片的那个元素的自定义属性里，一改动就会让整棵子树（包括终端）的样式失效——每次提交 22–34 ms。现在它是 &lt;code&gt;&amp;lt;style&amp;gt;&lt;/code&gt; 标签里的一条规则，只作用于真正读取它的元素。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;自带图层的按钮。&lt;/strong&gt;组件库会给按钮单独分配一个 GPU 图层。在画布里，这意味着多出几十个图层；一条在非按下状态下生效的覆盖规则，把图层数从 180 降到了 66。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;卡片里的定时器。&lt;/strong&gt;需要轮询的卡片——端口、预算、站会、网页监视——现在只在所属工作区打开且窗口可见时才计时，并且同一周期共用一个时钟，而不是各开一个定时器。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;没人在看的浏览器卡片&lt;/strong&gt;一直在推送画面帧。现在只有当某个窗口正在显示这张卡片时，画面帧才会流动：在概览中和隐藏的工作区里为 0，回来后恢复。&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;拖动框、框选、跨越概览阈值缩放、在概览中平移——这些手势期间的长任务都消失了。平移和拖动所需的渲染进程 CPU 大约减半；一次平移的性能追踪中，样式计算时间从 311 ms 降到 53 ms，布局时间从 378 ms 降到 28 ms。&lt;/p&gt;
&lt;h2&gt;当卡片小到看不清时&lt;/h2&gt;
&lt;p&gt;缩得足够小，终端就只是一个灰色矩形。低于 55%（阈值可在“设置”中调整）时，每张卡片会改为显示一块磁贴：它的图标、名称，以及对这类卡片最重要的一项信息——智能体的状态、待办清单上的 &lt;code&gt;3/11&lt;/code&gt;、看板的各列、笔记的第一行。&lt;/p&gt;
&lt;p&gt;卡片主体仍然以原本的尺寸挂载在下面——终端没有被杀掉，甚至没有重新适配。磁贴按屏幕像素绘制，所以在任何缩放下都清晰可读。跨越阈值时，重新渲染的卡片主体是零个，每块磁贴各渲染一次；平移则什么都不渲染。&lt;/p&gt;
&lt;figure&gt;&lt;img src=&quot;https://neurosquad.ai/blog/fifty-cards-one-canvas/overview-zh.webp&quot; alt=&quot;缩小到 55% 以下的 Launch day 工作区：每张卡片都是一块显示状态、清晰可读的磁贴&quot;/&gt;&lt;figcaption&gt;缩小后的“Launch day”：每张卡片都变成一块显示其主要信息的磁贴，而终端仍在下面继续运行。&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;这里有个微妙之处。藏在磁贴后面的终端虽然看不见，却没有暂停——终端库自带的可见性检测感知不到 CSS 的可见性——所以它会继续渲染没人看的输出。现在的做法是：卡片把输出攒起来，等你放大回来时一次性写入。只有一类数据块例外：程序向终端提出的询问（“你是什么终端？”“光标在哪？”）是对话的一部分，必须当场回答。延迟的回答曾经以字面量 &lt;code&gt;1;2c&lt;/code&gt; 的形式出现在 bash 提示符里——这是实测中发现并修复的。&lt;/p&gt;
&lt;h2&gt;“团队”卡片&lt;/h2&gt;
&lt;p&gt;画布上智能体一多，“谁在等我？”这个问题就不该需要你把画布巡视一遍。“团队”卡片在一块面板上回答它：工作区里的每个 AI 智能体，按&lt;em&gt;等你处理&lt;/em&gt;、&lt;em&gt;工作中&lt;/em&gt;、&lt;em&gt;已完成&lt;/em&gt;和&lt;em&gt;空闲&lt;/em&gt;分组，并显示它的 CLI、模型以及当前这一轮已经运行了多久。点击磁贴可以筛选；点击某一行，镜头就会飞到那张卡片。&lt;/p&gt;
&lt;p&gt;&lt;em&gt;“团队”卡片的复刻，用的是应用自己的文字。时钟在走；先点一块磁贴，再点一行。&lt;/em&gt; &lt;a href=&quot;https://neurosquad.ai/zh/blog/fifty-cards-one-canvas/&quot;&gt;可交互复刻——动手试试&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;模型这一栏比看上去更讲究。它显示的是智能体自己的会话日志里记录的最近一次请求所用的模型；没有的话，就用卡片上设置的模型；再没有的话，就用 CLI 自己配置文件里的默认值。三者都没有时，它显示“默认模型”——而不是瞎猜。&lt;/p&gt;
&lt;figure&gt;&lt;img src=&quot;https://neurosquad.ai/blog/fifty-cards-one-canvas/squad-zh.webp&quot; alt=&quot;Launch day 工作区中的“团队”卡片，列出三个 Claude Code 智能体及其状态&quot;/&gt;&lt;figcaption&gt;真实的卡片。当某个智能体停下来问你问题时，它那一行会泛起一次琥珀色。&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;“团队”卡片会被添加到每个工作区一次，位于最左侧卡片的左边。删掉之后它就不会再回来——你可以从菜单里重新添加。把“一次”做对，还多修了一个问题：最初的版本在工作区保存的布局加载完成之前就放下了这张卡片，结果画布从头重新排布了所有卡片。首次打开已有工作区时，所有卡片可能会堆在一个角落里。这就是本版本“修复”一栏里列出的那个 bug。&lt;/p&gt;
&lt;p&gt;添加卡片菜单也变了：智能体排在最前面，本机已安装的会被标出，多了一个搜索框，空白画布会以大号智能体磁贴开场。完整列表见 &lt;a href=&quot;https://neurosquad.ai/zh/changelog/#v0.1.117&quot;&gt;0.1.117 的更新日志&lt;/a&gt;。&lt;/p&gt;</content:encoded>
    </item>
    <item>
      <title>我们自己写了安装程序，NeuroSquad 从此会自动更新</title>
      <link>https://neurosquad.ai/zh/blog/own-installer-and-auto-updates/</link>
      <guid isPermaLink="true">https://neurosquad.ai/zh/blog/own-installer-and-auto-updates/</guid>
      <pubDate>Thu, 24 Sep 2026 06:17:11 GMT</pubDate>
      <category>版本发布</category>
      <category>安装程序</category>
      <category>工程</category>
      <description>NeuroSquad 为什么用自研安装程序替换自动生成的那个：安装包从 550 MB 减到 96 MB，挡路的进程按名称和 PID 列出，更新绝不会留下装了一半的应用。</description>
      <content:encoded>&lt;p&gt;&lt;img src=&quot;https://neurosquad.ai/blog/own-installer-and-auto-updates/installer-welcome-zh.webp&quot; alt=&quot;NeuroSquad 安装程序窗口：选择安装文件夹，以及是否创建桌面快捷方式&quot;/&gt;&lt;/p&gt;&lt;p&gt;NeuroSquad 0.1.100 是第一个能自己保持最新的版本。走到这一步，用了不到一天、连发三个版本，也得到了这周最有用的一条教训：安装程序是产品的一部分。它是用户看到的第一个窗口，而它一旦失败，就败在最糟糕的位置——旧版本已经没了，新版本还没到。&lt;/p&gt;
&lt;h2&gt;从 550 MB 到 96 MB&lt;/h2&gt;
&lt;p&gt;第一个公开的安装程序有 550 MB。大头是听写模型：解压后约 640 MB，打包进来是为了让语音输入在应用打开的那一刻就能用。可听写是可选功能，为了试一块智能体画布就让所有人把它下载下来，这笔账算错了。&lt;/p&gt;
&lt;p&gt;0.1.92 不再打包它。模型改为在你需要时下载——在设置向导的“听写”步骤，或之后在“设置”里——下载一完成，听写就自动启用，无需重启。在此之前，状态栏会显示“听写：请下载模型”，而不是报错。安装程序降到了约 110 MB。&lt;/p&gt;
&lt;p&gt;剩下的瘦身来自一个不那么光鲜的地方：到底打包了什么。打包工具会把应用的每一个生产依赖完整复制进去，而桌面应用把整套界面技术栈都列在了那里——组件库、图标集、无障碍工具包——尽管打包器早已把这些编译进了页面。把只有页面才需要的东西移出运行时依赖后，省下了约 70 MB 从来没有被加载过的文件。0.1.94 发布时是 96 MB。&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&lt;strong&gt;550 MB&lt;/strong&gt; — 首个公开安装程序，0.1.91&lt;/li&gt;&lt;li&gt;&lt;strong&gt;110 MB&lt;/strong&gt; — 去掉听写模型，0.1.92&lt;/li&gt;&lt;li&gt;&lt;strong&gt;96 MB&lt;/strong&gt; — 只保留应用运行时加载的内容，0.1.94&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;1.7 GB 的弯路&lt;/strong&gt; 有一次试验让安装程序膨胀到了 1.7 GB。只为 Windows 声明的文件列表不会追加到通用列表上——而是直接替换它——于是构建把文件夹里的一切都打了进去。现在这已是构建的一条成文规则。&lt;/p&gt;
&lt;h2&gt;为什么自动生成的安装程序必须下岗&lt;/h2&gt;
&lt;p&gt;最初的安装程序由打包工具生成，其中有两个问题严重到足以让我们自己动手重写。&lt;/p&gt;
&lt;p&gt;第一个：NeuroSquad 明明已经关了，它却提示“NeuroSquad 无法关闭”并拒绝安装。它的检查逻辑是“有没有任何进程从安装文件夹里运行”，而且不报名字。真正在运行的，是智能体卡片里那些终端的控制台宿主进程，应用退出后被遗留了下来。你看不到它们，提示里也不点名，也没有任何可以点的按钮。&lt;/p&gt;
&lt;p&gt;第二个更糟：被中断的安装可能留下一个写了一半的应用。有一次的情况是：&lt;code&gt;neurosquad.exe&lt;/code&gt; 只有 8 MB（本该是 200 MB），而且 Windows 的应用列表里也没有它的条目，连卸载都无从下手。&lt;/p&gt;
&lt;h2&gt;新的安装程序&lt;/h2&gt;
&lt;p&gt;它是一个小巧的 WPF 程序，基于 Windows 10 和 11 自带的 .NET Framework 4.8，所以无需预先安装任何东西。可执行文件本身约 240 KB；应用作为 LZMA 负载附加在它后面，切成 32 MB 的块并行压缩和解压，每个文件都有 CRC-32 校验。构建时只下载一次 C# 编译器，并用固定的 SHA-256 校验；构建机器上同样不需要任何 SDK。&lt;/p&gt;
&lt;figure&gt;&lt;img src=&quot;https://neurosquad.ai/blog/own-installer-and-auto-updates/installer-welcome-zh.webp&quot; alt=&quot;安装程序的第一页：安装文件夹和桌面快捷方式&quot;/&gt;&lt;figcaption&gt;选择文件夹——默认位置不需要管理员权限——以及是否创建桌面快捷方式。安装程序支持英语、俄语和中文。&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;它的不同之处，主要在于对你说实话：&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&lt;strong&gt;每一步都有实时日志&lt;/strong&gt;，既显示在窗口里，也写进 &lt;code&gt;%TEMP%&lt;/code&gt; 下的文件，出了问题总有一行字可以指给人看。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;挡路的进程按名称和 PID 列出&lt;/strong&gt;，只有在你按下按钮后才会结束它们。不靠猜，也不悄悄强杀。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;更新从不原地覆盖。&lt;/strong&gt;新版本解压到旧版本旁边，校验通过、一切就绪后才交换两个文件夹。失败或取消都会让旧版本原封不动。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;卸载只删除装进来的东西&lt;/strong&gt;——安装时记录的文件、快捷方式和“应用”列表中的条目。你的数据只有在勾选后才会删除。&lt;/li&gt;&lt;/ul&gt;
&lt;figure&gt;&lt;img src=&quot;https://neurosquad.ai/blog/own-installer-and-auto-updates/installer-processes-zh.webp&quot; alt=&quot;安装程序列出占用安装文件夹的进程：neurosquad.exe 和 OpenConsole.exe 及其 PID&quot;/&gt;&lt;figcaption&gt;占用文件夹的是什么，按名称和 PID 列出——应用本身和它卡片里的终端——只有你按下按钮才会结束它们。&lt;/figcaption&gt;&lt;/figure&gt;
&lt;figure&gt;&lt;img src=&quot;https://neurosquad.ai/blog/own-installer-and-auto-updates/installer-failed-zh.webp&quot; alt=&quot;安装无法替换某个文件：显示错误、日志，并注明原来的版本仍然保留&quot;/&gt;&lt;figcaption&gt;如果某个文件仍然无法替换，安装会停下并打开日志，你原来的版本保持原样。&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;有一个细节看不见，却至关重要：“开始”菜单快捷方式必须带有应用的 AppUserModelID。没有它，Windows 就不会投递应用的通知——而“你的智能体在等你”恰恰是整个产品赖以成立的那条通知。&lt;/p&gt;
&lt;p&gt;在开发用的机器上测试安装程序是有风险的，所以它为此准备了两个开关。&lt;code&gt;--snapshot&lt;/code&gt; 会把每一页渲染成 PNG，三种语言任选。&lt;code&gt;--sandbox&lt;/code&gt; 会把快捷方式和“应用”列表条目放进一个文件夹，而不是写进“开始”菜单和注册表，这样安装、更新和卸载都能完整跑一遍，而不碰系统分毫。&lt;/p&gt;
&lt;h2&gt;会自己安装的更新&lt;/h2&gt;
&lt;p&gt;有了能安全替换正在运行的副本的安装程序，自动更新才成为可能。NeuroSquad 每次启动时和之后每小时检查一次新版本，在后台下载，并用发布页自己公布的校验和核对 SHA-256。没有校验和，就不安装。&lt;/p&gt;
&lt;p&gt;更新不是可选项；你能选的是时机。标题栏里的一个圆环显示下载进度；下载完成后，一个带小圆点的图标让你随时可以更新，另有一个对话框对每个版本只问一次：现在，还是下次启动时。选“现在”，应用会关闭并把工作交给安装程序，安装程序等应用退出后覆盖安装，再启动新版本。下次启动时，如果已知有更新的版本，会在应用打开之前就先装好——如果你处于离线状态，应用尝试三次后放弃，打开你现有的版本。&lt;/p&gt;
&lt;p&gt;&lt;em&gt;标题栏和更新对话框的复刻，用的是应用自己的文字。选“立即更新”或“下次启动时”试试。&lt;/em&gt; &lt;a href=&quot;https://neurosquad.ai/zh/blog/own-installer-and-auto-updates/&quot;&gt;可交互复刻——动手试试&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;更新测试揪出来的那个 bug&lt;/h2&gt;
&lt;p&gt;更新流程是实打实测过的：两个构建、一个本地发布源，分别测试启动时更新、应用工作中更新，以及离线状态下用已下载好的更新启动。选“立即更新”后，大约十秒钟新版本就出现在屏幕上。&lt;/p&gt;
&lt;p&gt;在那之前，第一次运行失败了——卡在交换文件夹这一步。有东西仍然占着安装文件夹，而且不是应用本身。还是那个曾让旧安装程序犯迷糊的孤儿控制台宿主进程：它是某张卡片终端的子进程，它的&lt;em&gt;工作目录&lt;/em&gt;就是安装文件夹，因为应用本身就是从那里启动的。一个进程只要把某个文件夹当作当前目录，就足以让 Windows 无法重命名它。&lt;/p&gt;
&lt;p&gt;修复只有一行，放在应用启动的最开头：把工作目录切换到用户主文件夹。子进程会继承它，安装文件夹也就不再是任何进程的当前目录。0.1.108 补上了另一半：从旧版本更新时，如果旧版本遗留的终端仍占着文件夹，安装程序现在会把它们和其他进程一起列出来；如果还有它识别不出的东西占着某个文件——比如一个资源管理器窗口——它会逐个替换文件而不是直接放弃，并且任何一步失败都会把一切恢复原样。&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;安装程序是应用里唯一一个无法靠下一次更新来修复的部分。它必须在其他一切都没运行的时候做对。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;如果你用的是 0.1.94 或更早的版本，请在其上运行一次新的安装程序；之后更新都会自动到来。所有变化见 &lt;a href=&quot;https://neurosquad.ai/zh/changelog/#v0.1.100&quot;&gt;0.1.100 的更新日志&lt;/a&gt;。&lt;/p&gt;</content:encoded>
    </item>
    <item>
      <title>为什么做 NeuroSquad：把智能体放上画布，而不是排成一排标签页</title>
      <link>https://neurosquad.ai/zh/blog/why-neurosquad/</link>
      <guid isPermaLink="true">https://neurosquad.ai/zh/blog/why-neurosquad/</guid>
      <pubDate>Wed, 23 Sep 2026 15:33:19 GMT</pubDate>
      <category>版本发布</category>
      <category>设计</category>
      <description>NeuroSquad 首个公开版本：为什么每个智能体 CLI 都是画布上的一张卡片，应用如何分辨智能体是做完了还是在等你，以及为什么箭头就是工具。</description>
      <content:encoded>&lt;p&gt;&lt;img src=&quot;https://neurosquad.ai/blog/why-neurosquad/canvas-zh.webp&quot; alt=&quot;NeuroSquad 窗口：画布上有一张智能体卡片、一个终端、一篇笔记、一份待办清单和一块任务看板，彼此用箭头相连&quot;/&gt;&lt;/p&gt;&lt;p&gt;今天，NeuroSquad 0.1.91 正式公开——一个 Windows 安装程序、十个智能体 CLI，外加一块画布。第一次提交是在 9 月 3 日，开发过程中，运行在 NeuroSquad 自家卡片里的智能体也帮着一起写了它。这篇文章讲的是：它为什么长成现在这个样子。&lt;/p&gt;
&lt;h2&gt;问题：一排需要你一直盯着的标签页&lt;/h2&gt;
&lt;p&gt;智能体 CLI 已经好用到这种程度：只开一个，瓶颈就不在它身上了。于是你再开一个去写测试，第三个去补文档，也许第四个去处理另一个仓库。接下来，工作就变成了“盯梢”：哪个标签页已经做完了，哪个卡在“我可以运行这条命令吗？”这种问题上已经十分钟，哪个还在跑。&lt;/p&gt;
&lt;p&gt;标签页天生不适合这件事。它把眼前这一个之外的一切都藏起来，不告诉你任何状态，彼此之间也一无所知。第三个标签页里的智能体看不到第五个标签页里的浏览器——哪怕那正是它需要的。&lt;/p&gt;
&lt;p&gt;所以 NeuroSquad 押了三个注。每个智能体都是画布上的一张&lt;strong&gt;带真实终端的卡片&lt;/strong&gt;，整块画布一眼尽收。智能体做完一轮或需要你时，应用会&lt;strong&gt;主动告诉你&lt;/strong&gt;，你不用再挨个去看。两张卡片之间的一支&lt;strong&gt;箭头&lt;/strong&gt;，让智能体可以使用箭头指向的东西。&lt;/p&gt;
&lt;figure&gt;&lt;img src=&quot;https://neurosquad.ai/blog/why-neurosquad/canvas-zh.webp&quot; alt=&quot;NeuroSquad 中的演示工作区：中间是一张智能体卡片，箭头分别连向终端、笔记和待办清单&quot;/&gt;&lt;figcaption&gt;每次全新安装后打开的工作区：一张真实的 Claude Code 卡片、一个真实的 Shell、一篇笔记、一份待办清单和一块看板。那些箭头就是智能体的工具。&lt;/figcaption&gt;&lt;/figure&gt;
&lt;h2&gt;卡片就是真实的终端，而且绝不能死&lt;/h2&gt;
&lt;p&gt;卡片不是一个假装成智能体的聊天窗口。它就是你本来就在用的 CLI——Claude Code、Codex CLI、OpenCode、Qwen Code，以及另外六个——运行在真实的伪终端里，有它自己的界面、自己的快捷键和自己的小脾气。CLI 明天更新，卡片明天就用上新版本。&lt;/p&gt;
&lt;p&gt;这个选择定下了整个代码库的第一条铁律：&lt;strong&gt;只要智能体还活着，终端组件就绝不能卸载&lt;/strong&gt;，因为一卸载，进程就被杀掉了。听上去理所当然，结果它几乎决定了画布上的每一个功能：&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;切换工作区不会替换画布。本次会话中打开过的每个工作区都保留着自己已挂载的画布，不活跃的只是被隐藏起来。&lt;/li&gt;&lt;li&gt;放大到一组卡片，是把镜头移到这个分组的框上，而不是做筛选——筛选会把分组外的卡片卸载掉。&lt;/li&gt;&lt;li&gt;把卡片展开到全屏，是一个 1:1 的视口加上一份保存下来的几何信息，而不是换一个组件。&lt;/li&gt;&lt;li&gt;画布库在按下 Delete 键时会删除选中的节点。在这里，这等于按一下键就杀掉一个会话，所以画布库根本无权删除节点：由我们自己的监听器收集选中项，并在一个对话框里统一问你一次。&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;同一个赌注下面还压着一大堆 Windows 的“管道活”。CLI 要通过系统自身的查找机制解析成绝对路径，因为桌面应用看到的 PATH 和你终端里的不一样。路径要用正斜杠传递，因为伪终端库会把反斜杠搞乱——&lt;code&gt;cmd.exe&lt;/code&gt; 除外，它会把 &lt;code&gt;C:/…&lt;/code&gt; 当成一串命令开关。父智能体留在环境里的变量要在子智能体启动前清掉，否则子智能体会悄悄停止保存会话记录。这些都看不见，而且全都是靠把真东西跑起来才发现的。&lt;/p&gt;
&lt;h2&gt;“已完成”和“等你处理”是两件不同的事&lt;/h2&gt;
&lt;p&gt;画布的全部意义在于：你可以把目光移开。所以应用必须知道什么时候该把你叫回来——而原因有两种，截然不同。&lt;em&gt;已完成&lt;/em&gt;意味着智能体结束了这一轮，你想什么时候看回答都行。&lt;em&gt;等你处理&lt;/em&gt;意味着智能体此刻被卡住了，在你批准某件事之前寸步难行。&lt;/p&gt;
&lt;p&gt;第一个版本分不清这两者。它盯着终端看：窗口标题 1.2 秒不再变化、输出安静 2.5 秒，就算这一轮结束了。对“已完成”来说这是个不错的猜测，可它和一个正在等权限确认的智能体，是完全相同的沉默。&lt;/p&gt;
&lt;p&gt;办法是直接问智能体本身。Claude Code 有生命周期钩子，所以每张卡片启动它时，都会在你自己的设置之上叠加一个小小的设置文件：你提交提示词时，它报告&lt;em&gt;工作中&lt;/em&gt;；它发出通知时，报告&lt;em&gt;等你处理&lt;/em&gt;；它停下时，报告&lt;em&gt;已完成&lt;/em&gt;。每个钩子都只是一行 &lt;code&gt;curl&lt;/code&gt;，发往应用在本地回环接口上运行的服务器，卡片的令牌放在 URL 里而不是请求头里——这样无论在哪种 Shell 里执行，这条命令都能原样生效。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;两条看似不起眼、却很要紧的规则&lt;/strong&gt; “等你处理”的通知会带上智能体自己的原话——比如 &lt;code&gt;Claude needs your permission to use Bash&lt;/code&gt;——因为一条分不清是在问 &lt;code&gt;rm -rf&lt;/code&gt; 还是在问读个文件的通知，只是噪音。而且它永远不会自动消失：被卡住的智能体不会在五秒后自己解开。&lt;/p&gt;
&lt;p&gt;通过钩子上报状态的智能体，会为自己关掉旧的猜测式检测器，否则你会收到两次提醒，而且猜出来的“已完成”会覆盖真实的“等你处理”。没有钩子的 CLI 仍然使用启发式判断。点击通知，画布镜头会飞到那张卡片上，卡片闪起绿光，而且会一直闪到镜头飞到为止。&lt;/p&gt;
&lt;h2&gt;箭头就是工具&lt;/h2&gt;
&lt;p&gt;第三个赌注是大家问得最多的。NeuroSquad 在 &lt;code&gt;127.0.0.1&lt;/code&gt; 上运行自己的 MCP 服务器，每个支持 MCP 的智能体都会在上面拿到一个会话。会话里有什么，由画布上的箭头决定。&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;一支指向浏览器卡片的箭头，给智能体 &lt;code&gt;browser_*&lt;/code&gt; 工具：一个真实的 Chrome，就显示在卡片里，你看着智能体在里面点击和输入。&lt;/li&gt;&lt;li&gt;一支指向终端卡片的箭头，给它 &lt;code&gt;terminal_&lt;em&gt;&lt;/code&gt;：在&lt;/em&gt;那个* Shell 里运行命令，并读取它的屏幕。&lt;/li&gt;&lt;li&gt;指向笔记的箭头给它 &lt;code&gt;note_&lt;em&gt;&lt;/code&gt;，指向待办清单的给它 &lt;code&gt;todo_&lt;/em&gt;&lt;/code&gt;。&lt;/li&gt;&lt;li&gt;指向另一个智能体的箭头给它 &lt;code&gt;agent_*&lt;/code&gt;——而这支箭头是有方向的。它从负责人指向助手；助手不能把活儿反推回去。&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;箭头就是权限。没有箭头，就没有工具——于是画布如实地画出了每个智能体能触及的范围。每一次调用都会在发生的那一刻画在对应的箭头上，你能亲眼看到负责人把任务交给助手，而不必去日志里翻。&lt;/p&gt;
&lt;p&gt;&lt;em&gt;在本页运行的画布复刻：一个负责人智能体沿着箭头把任务分给三个助手，每个助手在看板上移动自己的卡片。&lt;/em&gt; &lt;a href=&quot;https://neurosquad.ai/zh/blog/why-neurosquad/&quot;&gt;可交互复刻——动手试试&lt;/a&gt;&lt;/p&gt;
&lt;figure&gt;&lt;img src=&quot;https://neurosquad.ai/blog/why-neurosquad/arrows-zh.webp&quot; alt=&quot;一张智能体卡片的特写，箭头连向终端、笔记和待办清单&quot;/&gt;&lt;figcaption&gt;真实应用中的同一套连线。每支箭头都是智能体手里的一组工具；画布上的其余部分，它够不着。&lt;/figcaption&gt;&lt;/figure&gt;
&lt;h2&gt;默认本地&lt;/h2&gt;
&lt;p&gt;这里没有账号，中间也没有我们的服务器。工作区、卡片和箭头都是应用数据文件夹里的 JSON 文件。听写在你的电脑上完成识别，用的是 Parakeet 或 Whisper。“用量”页面从智能体自己的日志里读取 token 和费用，而不是在它们前面架一个代理。删除卡片永远不会碰你的项目文件夹。&lt;/p&gt;
&lt;p&gt;这个版本里还有不少这篇文章没能展开的内容：能在手机浏览器里运行整个应用的&lt;a href=&quot;https://neurosquad.ai/zh/remote/&quot;&gt;远程访问&lt;/a&gt;，每个智能体各自隔离的 git worktree，以及预算刹车——工作区花费达到上限时，它会中断其中的每一个智能体，用的是 Ctrl+C 而不是强杀，所以不会丢失任何会话。&lt;/p&gt;
&lt;h2&gt;接下来&lt;/h2&gt;
&lt;p&gt;第一个版本的安装程序有 550 MB，其中大部分是一个语音模型，只有用听写的人才会加载它。这是第一件要解决的事。再往后：一个会明确告诉你是什么挡了路的安装程序，以及能自己安装的更新。&lt;/p&gt;
&lt;p&gt;0.1.91 的完整内容见&lt;a href=&quot;https://neurosquad.ai/zh/changelog/#v0.1.91&quot;&gt;更新日志&lt;/a&gt;。&lt;/p&gt;</content:encoded>
    </item>
  </channel>
</rss>
