起飞就起飞

kid-process:用「小工人」给小朋友讲进程

Posted on By baixiao

kid-process:用「小工人」给小朋友讲进程

关键词: kidlab、进程、PID、PPID、DeepSeek Harness、插件、启蒙

核心结论:我们把「进程」讲成小朋友能懂的故事:每运行一个程序,就派一个小工人上工作台,工号是 PID、师傅工号是 PPID。一个插件包同时给出四个查询工具和一张每 15 秒自动点名的卡片,全部免 sudo、零第三方依赖,离线自检 112 项全过,并在真实的 dsh web 上验证通过。

1. 背景:系列的最后一块拼图

kidlab 电脑启蒙系列的目标,是把电脑讲成小朋友能理解的日常场景。此前六个成员里,内存被比作「工作台」、存储被比作「大仓库」,唯独进程——这台电脑此刻到底在忙什么——一直没讲清楚。

要讲它,难在两点。一是概念本身抽象,PID、PPID、进程状态这些词对成年人都嫌枯燥;二是工程上要跟上升级后的 DSH 0.2 形态,把插件从动态加载整体迁到静态 bundle。

2. 主体:一个包,四个工具,一张卡片

我们延续「内存 = 工作台」的隐喻,把进程定义为在工作台上干活的小工人:每打开一个程序就派一个小工人上场;工号是 PID,师傅工号是 PPID,状态则分成卖力干活、打盹等活儿、赖着不走的「僵尸」。

围绕这个隐喻,插件提供四个模型工具,全部只读、全部免 sudo:

工具 讲什么 数据来源
proc_count 现在有多少小工人(总数 + 按状态分类) ps -axo stat=
proc_busiest 谁最卖力(CPU 强度榜,最多 12 行) ps -axo pcpu=,comm= + sort
proc_family 工人家族(师傅链向上 + 直接徒弟向下) ps -axo pid=,ppid=,comm= 建树
proc_badge 查工牌(工种/工号/师傅/状态/工时/强度) ps -p N -o ... + lstart/comm

表格之后是常驻的 🧑‍🏭 卡片:它挂在输入框上方,每 15 秒自己点一次名,分成四个区——点名板(总数 + 卖力/打盹/僵尸三段占比条)、最卖力榜(Top 6)、工人家族、僵尸名单(只在真出现僵尸时才冒出来)。数据来自插件自带的只读路由 GET /kid-process/collect。

关键洞察:把「查询」和「展示」拆开——模型按需调工具,人随时看卡片,两者共享同一份采集逻辑,各取所需。

安全与实现

家族树在 JS 内存里构建,shell 不接收任何用户输入;proc_badge 的 PID 经正整数校验后才拼进命令行,注入面为零。所有命令硬编码、免 sudo、逐条设超时,拿不到数据就返回中文提示,而不是抛错。

迁到 0.2 后,整个包只剩 5 个文件、零第三方依赖:宿主半部 index.js、客户端半部 client.js、纯函数层 collect.js 与 tools.js,外加一份 cordis.patch.yml。宿主半部只 import node: 内置模块与相对路径,不再触碰 @deepseek-ai/*。把两代形态放在一起看,差异一目了然:

维度 0.1 动态形式 0.2 静态 bundle
结构 src/*.ts + lib/ 构建产物 + 根 tsconfig.json 单包 5 个文件,零第三方依赖
工具注册 defineTool / inject 顶层导出 child.tools.register(...) 普通对象
依赖 依赖 @deepseek-ai/* 仅 node: 内置与相对路径
output schema 四个工具各一份 + config 一份(共 5 处) 收敛为一个 TEXT_OUTPUT(共 2 处)
装载 用户层手写 insert 一个包一次装完,自带 patch

表格背后是一句经验:结构越收敛,越不容易出错。0.2 把重复的 schema、深层依赖、装载步骤都收进了包内,用户层的改动面缩到几乎为零。

验证:离线全绿,真机跑通

离线自检做到全绿:node verify.mjs 112 项全过(结构、manifest、宿主纯净性、路由契约、四个工具的 JSON-Schema 与文案、客户端 IIFE 与样式注入);node --check 对几个文件全部通过。

真机(运行中的 dsh web)上它同样站得住:GET /kid-process/collect 返回 200 与正确的 content-type / cache-control,HEAD 长度一致,POST 得到 405 allow=GET,5 秒缓存按预期生效。四个工具跑出的真实数据是 510 个小工人(4 个卖力 / 504 个打盹 / 2 个僵尸),最卖力的是 Google Chrome 53.1%。

卡片侧,我们把包装成 bundle:profile 的依赖与 dsh.profile.bundles 都登记了它,HMR 图里出现该条目后,不重启 dsh web 就出现了卡片;线上 bundle 与磁盘 client.js 逐字节一致。改客户端半部只需刷页面,而用户层 ~/.dsh/cordis.patch.yml 甚至是热生效的——把旧 insert 换成按 id 覆盖后,/kid-process/collect 在同一进程里立刻从 200 变 404。

3. 结论与建议

至此,kidlab 系列的七个插件全部完成:coder、sysmon、network、storage、memory、security、process。kid-process 是最后一个从 0.1 迁到 0.2 的成员,迁完之后整个系列统一成同一种形状——一个包 = 一份自带的 cordis.patch.yml + 若干模型工具 + 可选的一张常驻卡片。

几条可以带走的经验:

  • 客户端脚本必须用 IIFE 包裹。顶层裸 const 会泄漏到页面全局并与其他 bundle 撞名,轻则该条目不激活,重则整段脚本解析失败。
  • 改哪一层就重启哪一层:宿主半部改完重启 dsh web,客户端半部改完刷页面,用户层 patch 是热的。
  • 同一个 id 的 insert 不能共存,要改默认值就按 id 覆盖,别重复插入。

行动建议:如果你也想给小朋友讲进程,可以照这个隐喻直接讲——「谁在干活、谁在打盹、谁没交工牌」。孩子记住的,往往比术语多得多。

画图建议(供绘图模型参考)

一句话 prompt:一座明亮的卡通小工厂里,许多戴着工牌、穿着工装的小工人正在长长的木工作台前忙碌,有的挥汗猛干、有的靠在椅子上打盹、角落里一个抱着工牌发呆的「僵尸」工人,画面一角立着一块点名板——用温暖扁平插画风格,表现「电脑进程就像在工厂里上工的小工人」。

分项拆解:

  • 场景:卡通工厂车间 + 长工作台 + 门口一块「点名板」。
  • 主体元素:戴工牌的小工人(工牌上写「工号」)、忙碌 / 打盹 / 发呆三种状态、师傅领着徒弟的连线。
  • 风格:温暖、扁平、明快的儿童绘本插画,圆角、柔和配色。
  • 构图:中景俯视,工厂从左到右铺开,点名板在右上角,突出「一群小工人在电脑里上工」的比喻。

参考资源

  • 插件仓库:https://github.com/baixiaoustc/dsh-kidlab(plugins/kid-process)
  • 离线自检脚本:node verify.mjs(112 项)
  • 系列其他成员:coder、sysmon、network、storage、memory、security