WorkBuddy 专家包:AI 错题本管家开发全程复盘

WorkBuddy 专家包:AI 错题本管家开发全程复盘

我给孩子做了一个本地优先的「AI 错题本」桌面引擎(拍照转录、错题管理、练习卷生成),一直缺一个顺手的对话入口。WorkBuddy 的专家包机制正好补上这块:让大模型当管家,用自然语言驱动本地引擎------拍照录入、诊断薄弱点、讲解错题。

这篇文章复盘整个开发过程:专家包到底是什么、怎么从零到发布、以及三个让我返工三次的坑。如果你也想给 WorkBuddy 写专家包,看完这篇可以直接上手。

一、30 秒理解专家包

WorkBuddy 专家包的本质是:一个纯文本目录 + 一份注册记录,不含任何可执行代码。

bash 复制代码
wrongbook-expert/
├── .codebuddy-plugin/plugin.json   # 元数据:卡片展示、快捷指令、技能声明、版本号
├── agents/wrongbook-expert.md      # 人设:YAML frontmatter + 正文规则(谁、能做什么、怎么做的 SOP)
├── skills/wrongbook-skill/SKILL.md # 技能:按需加载的操作规程(分步命令,模型照着执行)
├── avatars/expert.png              # 头像(512×512、≤500KB)
└── README.md

它的工作原理是把 WorkBuddy 还原成一个 Agent 运行时:模型 + 一组工具(终端、文件读写、技能加载)。专家包就是注入给模型的提示词程序 ------人设定义「你是谁」,技能定义「怎么做」,模型在 agent loop 里读规则、调终端执行 curl、观察返回、走下一步。

所以专家包天生适合一种架构:提示词程序(专家包) + 本地引擎(HTTP 服务) 。对话、编排、推理交给模型(白嫖 WorkBuddy 的算力额度);存储、OCR、长耗时任务交给本地引擎(127.0.0.1:8899)。专家包是零代码的"遥控器 + 伴学大脑",引擎是干重活的。

我的错题本引擎正好已有 Web UI 和 REST 接口,于是分工非常干净:

javascript 复制代码
┌─ WorkBuddy(Agent 运行时)────────────┐      ┌─ AI错题本引擎(Flask, :8899)────┐
│ 模型 + 工具                            │ curl │ 本地 JSON 存储                   │
│ └─ 专家包 = 注入的提示词               │ ───→ │ 拍照转录管线(用户自配 API Key) │
│    agents/*.md(人设 + 三个 SOP)      │      │ Web UI(录入 / 人审视图 / 工作台)│
│    skills/*.md(启动 / 看护 / 停止)   │      └──────────────────────────────────┘
└────────────────────────────────────────┘

二、标准开发流程:一条命令起步

WorkBuddy 内置了脚手架脚本,从零到注册可见只要五步:

bash 复制代码
# 官方脚本目录
SCRIPTS="/Applications/WorkBuddy.app/Contents/Resources/app.asar.unpacked/resources/plugins/workbuddy-builtin/skills/expert-manager/scripts"
# 专家包唯一合法位置
EXPERTS="${WORKBUDDY_CONFIG_DIR:-$HOME/.workbuddy}/plugins/marketplaces/my-experts/plugins"

# 1. 生成骨架(Agent 型:plugin.json + agents/*.md + avatars + README,全带 [TODO])
python3 "$SCRIPTS/init_expert.py" wrongbook-expert --type agent --path "$EXPERTS"

# 2. 填内容(编辑 plugin.json / agents/*.md / skills/)

# 3. 校验(0 error 才能继续)
python3 "$SCRIPTS/validate_expert.py" "$EXPERTS/wrongbook-expert"

# 4. 注册(写入 marketplace.json,专家才会在「我的专家」里出现)
python3 "$SCRIPTS/register_expert.py" "$EXPERTS/wrongbook-expert"

# 5. 重启 WorkBuddy → 新建对话测试

几个硬性校验规则,初学者最容易栽在这里:

  • categoryId 只认 12 个枚举值(内置样例用的 15-Education 是非法值 ,别照抄;教育类我用 09-OperationsHR)
  • displayDescription.zh 限 40--50 字;tags 和 quickPrompts 恰好 3 个 ;defaultInitPrompt 必须与第一条快捷指令完全一致
  • 命名五处一致:目录名 = name = agentName = plugin = agents 下的 MD 文件名,创建后严禁修改
  • frontmatter 里禁止写 tools 字段(工具由系统统一分配)

三、四个核心能力的实现

1. 启动服务:探测 → 记忆路径 → 看护

技能 wrongbook-skill 的 SOP:

  1. curl /api/license 探测 8899 是否已在运行(响应含 app_version 即本程序;被占用但不是本程序 → 报错终止,防灾)
  2. 读取 ~/.workbuddy/wrongbook-app-path 里记忆的安装路径
  3. 没有路径 → 引导用户把 App 图标拖进聊天框
  4. 后台任务拉起引擎 + 看护循环(下文细讲)
  5. 返回 http://127.0.0.1:8899 工作台链接

2. 跨端照片录入:状态机 + 轮询

手机 WorkBuddy 发照片(一次最多 9 张),专家投递给引擎,电脑 Web 端完成定稿:

css 复制代码
手机拍照 → POST /api/intake ──→ [arrived 仅存照片,秒回,不调 LLM]
                                   │  Web 页每 3s 轮询发现新单
                                   ▼
             照片自动显示到上传区 + 全屏遮罩逐张转录(i/N 进度)
                                   │  POST /api/sheets/<sid>/transcribe
                                   ▼
             [pending 已转录待提交] → 人审视图勾选/标错因 →「提交」
                                   ▼
             [processed 已入库]

两个设计点值得说:

  • 投递接口只存照片不转录。转录一张要 20--60 秒,放在投递阶段多张必超时;挪到 Web 端做,还能复用页面上的年级上下文和进度遮罩。
  • 人审是刻意保留的把关环节。模型 OCR 经常把图形抓错、漏题、识别倒置------引擎只做初稿,「人审视图」里人工核对、手动框选图形、标注错因后才真正入库。

3. 学情诊断:禁止瞎编

诊断 SOP 的第一条是「不要瞎编,必须先 curl /api/questions 拉真实数据」,然后基于 question/kps/reason 字段做推理------先统计、再指漏洞、最后给复习建议。这比让模型自由发挥靠谱得多。

四、踩坑实录(这部分最值钱)

以下五个坑,官方指南都没写,全部是我用返工换来的。

坑 1:版本号缓存------改了技能不生效的最大元凶

现象:改了 SKILL.md,重新校验、重新注册、重启 WorkBuddy,模型还是按旧流程执行。

真相:运行时读的不是你的源目录,而是按版本号拷贝的快照:

javascript 复制代码
~/.workbuddy/plugins/cache/<市场>/<专家名>/<版本号>/

register_expert.py 只更新 marketplace.json 元数据,不刷新这份拷贝 。版本号不变,重启一百次也是旧内容。我在缓存目录里甚至找到了前一天误提交又被我删掉的 #SKILL.md# 垃圾文件------快照有多老可想而知。

正确姿势 :每次实质性修改,把 plugin.json 的 version 升一位(1.0.0 → 1.1.0 → ...),再校验注册重启;顽固时手动删除缓存里对应的旧版本目录。

坑 2:旧对话冻结旧技能

修完技能后,在一个早就存在的对话里测试,模型依然按旧流程走。因为技能内容在对话创建时被快照进上下文------旧对话永远带着旧版。

正确姿势 :每次改完技能,重启 WorkBuddy + 新建对话测试。旧对话测出来的"没生效"不作数。

坑 3:技能命名必须全库唯一

我最初给技能起名 workbench,结果机器上另一个专家包(降噪陪学)也有一个 workbench。会话里按名加载技能时互相污染,模型加载到的内容随缓存状态漂移。技能名改成 wrongbook-skill 这种带前缀的唯一名后,问题根除。

坑 4:沙箱------后台任务里跑不了"重"程序

我想让「打开错题本」在 WorkBuddy 里显示后台任务条(像其他专家那样可随时停止),于是把引擎二进制直接放进后台任务运行。结果:引擎启动即退出。

原因:后台任务的进程继承 WorkBuddy 沙箱 ,而沙箱禁止对个人目录(~/Library)的 rename/删除操作------引擎启动时的授权校验恰好要原子替换授权文件(临时文件 + rename 覆盖),被拦 → 异常没人接 → 进程退出。

最终方案是看护模式:

bash 复制代码
# 后台任务只跑这个循环(带 run_in_background: true):
APP="<引擎路径>"; echo $$ > ~/.workbuddy/wrongbook-watch.pid; open "$APP"; \
while curl -s -m 2 http://127.0.0.1:8899/api/license >/dev/null 2>&1; do sleep 3; done; \
rm -f ~/.workbuddy/wrongbook-watch.pid; echo "引擎已退出"
  • 引擎本体用 open 拉起 → 走 launchd,在沙箱外运行,权限完整;
  • 后台任务只做看护循环:引擎活着任务就活着(任务条持续可见),引擎退出任务自然结束;
  • 顺手把引擎的 JSON 落盘加了降级:os.replace 被拒时回退就地覆写,授权校验失败不再阻断启动。

坑 5:小模型对"示例"的遵循度远高于"描述"

"必须带 run_in_background: true 参数"这句话写三遍,模型还是会忘。把 SKILL.md 改成给一个可以照抄的工具调用 JSON 示例 ,遵循率立刻上来了。写技能时记住:你是在给一个不太听话的实习生写操作手册,能给它模板就不要给它道理。

杂项坑

  • 头像从产品 logo 直接拿来用会超规格(我的是 1024×765、536KB),sips 居中裁剪 + 缩放到 512×512 才合规;
  • 引擎的崩溃要自己兜住:启动校验、心跳、激活全链路 try/except,沙箱/只读环境下按本地凭证继续运行,而不是进程退出。

五、一个亮点设计:看护联动(删任务 = 关服务)

看护模式有个天然的别扭点:后台任务只是个监测循环,用户点任务条的 🗑 删除按钮,只能杀掉看护循环,杀不到沙箱外的引擎------"删了任务服务还在",违反直觉。

解法是令牌联动:

  1. 看护任务启动引擎前,把自己的 PID 写入令牌文件 ~/.workbuddy/wrongbook-watch.pid;
  2. 引擎(v1.4.2+)启动时读取令牌并武装看护检查:每 5 秒探测看护进程是否存活;
  3. 看护消失连续两次(用户点了 🗑,或 WorkBuddy 会话结束)→ 引擎自动优雅退出、释放端口。

效果:删任务 = 关服务,10 秒内生效。同时有三重防护保证不误杀:

  • 令牌 120 秒时效:过期令牌(WorkBuddy 崩溃残留)自动清除并解除联动;
  • 普通双击启动(无令牌)永不自动退出,引擎独立生命周期不受影响;
  • 引擎正常退出时看护循环自然结束、清理令牌,任务条随之消失。

六、发布:两条交付线

最终交付物是两个文件,用户侧各装一次:

  1. 引擎 App :AI错题本-v1.4.2-mac.zip,解压拖进 Applications(PyInstaller 打包,build_mac.sh 一键完成回归门禁 → 构建 → 资源复制 → 白名单校验 → 压缩);
  2. 专家包 ZIP :wrongbook-expert.zip(241KB,5 个纯文本文件 + 头像),解压到专家目录、跑一次注册脚本即可。

之后改引擎发新版不影响专家包;改专家包(提示词迭代)也不需要重新分发引擎------发布分离,双端独立升级。

七、迭代工作流(直接抄)

bash 复制代码
source packaging/workbuddy-demo/expert-env.sh   # SCRIPTS / EXPERTS / NAME / EXPERT 四个变量

# 1. 改源目录内容(SKILL.md / agent MD / plugin.json)
# 2. ⚠️ bump version:plugin.json 版本号升一位(否则改了白改!)
python3 "$SCRIPTS/validate_expert.py" "$EXPERT"
python3 "$SCRIPTS/register_expert.py" "$EXPERT"
python3 "$SCRIPTS/package_expert.py" "$EXPERT" packaging/workbuddy-expert   # 分发 ZIP
# 3. 重启 WorkBuddy + 新建对话测试

结语

做完这个专家包,我对"Agent 时代的软件形态"有了更具体的体感:

  • 专家包是提示词程序------它没有传统意义上的代码,但它有状态机(草稿单三态)、有 I/O 契约(curl 接口)、有容错分支(防灾探测、路径回退)。写它更像写一份给聪明但字面理解的实习生的操作手册;
  • 模型能力的边界要用工程补:OCR 会错,就加人审视图;模型会忘参数,就给可照抄的示例;进程会被沙箱杀,就用看护循环 + 令牌联动把生命周期还给用户;
  • 本地引擎 + 平台模型是绝配:数据留在本机、长任务不占对话额度、对话体验由大模型兜底。

如果你也在做一个有本地服务的工具,不妨试试给它配一个 WorkBuddy 专家包------五步起步,最大的坑我都替你踩完了。


环境:WorkBuddy 专家包规范 v2.0(Agent 型)、macOS;文中命令与行为均在 2026-11 实测。

相关推荐
Linye1 小时前
配了 3 套 AI 规则还打架?聊聊 Agent 信源仲裁与三层验真
人工智能·架构
枕月而栖1 小时前
消息积压清不掉,ZEEKEAI 上用 Claude Fable 5.1 从消费指标里找到瓶颈
人工智能
nice_lcj5201 小时前
【从零理解 Spring AI · 16】Agent 与工作流:什么该写死,什么该让模型决定
java·人工智能·后端·spring ai·ai应用开发
yimiagent实验室1 小时前
封装一个限流退避器:指数退避 + 等抖动 + 最大等待的一次封装
人工智能
丘山录1 小时前
llama.cpp 完整教程,放错盘读一遍多等 1 小时
人工智能
AI前端工程狮1 小时前
用户点了「取消」,我的服务进程退出了
人工智能·程序员
网易云信1 小时前
别急着让 AI 出方案:学会追问三步走,医美咨询全跑通
人工智能
panyz2 小时前
不想再开 7 个标签页查AI额度,我用 Node 写了个本地看板
人工智能·开源·github
炫酷的大高个2 小时前
3.2TB 权重开源了,我算了 4bit 之后还要几张卡
人工智能·架构·开源