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