2026/10/28 19:49:43

用WorkBuddy Skill自动化更新MyBooks书库:从脚本到Agent的实践

用WorkBuddy Skill自动化更新MyBooks书库:从脚本到Agent的实践 1. 从一条书库更新需求说起为什么我盯上了 WorkBuddy 的 Skill 机制书库维护这件事做过的人都懂它不难但烦。我手上有一个自建的 MyBooks 书库里面躺着几百本书的元数据书名、作者、出版社、ISBN、封面链接、阅读状态、评分、标签字段不算多但架不住量大。早些年我是手动改的后来写脚本批量处理再后来发现脚本越写越臃肿每加一个数据源就要改一次解析逻辑维护成本直线上升。直到我开始用 WorkBuddy 的 Skill 机制来接管这类重复但有结构的任务才真正把这件事从每周固定消耗两小时压缩到点一下等结果。这篇内容就是把我用 WorkBuddy 更新 MyBooks 书库书籍信息的完整思路和实操过程摊开讲。核心关键词是WorkBuddy、MyBooks、Skill、Agent Skill、ClawHub我会围绕这几个点把为什么这么设计每一步在干什么哪里容易翻车讲清楚。适合两类人看一类是和我一样有自建书库、想用 Agent 能力做自动化维护的另一类是刚接触 WorkBuddy Skill想找一个真实场景练手的。哪怕你完全没写过 Skill跟着走一遍也能落地。先说结论性的判断书库更新这类任务天然适合用 Agent Skill 来做而不是传统脚本。原因在于它的输入是不确定的不同来源的书籍信息格式千差万别处理过程需要判断这条信息该覆盖还是该保留输出又要求结构化写回 MyBooks 的固定字段。传统脚本擅长确定性流程一旦遇到格式变了字段缺了来源冲突了就得加 if-else加到后面自己都看不懂。而 Agent Skill 的价值就在于它把判断这件事交给模型把执行这件事交给工具调用中间用 Skill 的指令来约束边界正好卡在这个任务的甜点区。2. 整体设计思路把更新书库拆成一条可复用的 Skill 流水线2.1 为什么不是写个脚本而是做成 Skill我一开始也是写脚本的。Python 加 requests 加 BeautifulSoup抓豆瓣、抓出版社官网、抓开放图书 API写了两百多行。问题出在第三个月某个数据源改版了字段位置全变脚本直接报错又过了两周另一本书的 ISBN 在三个来源里对不上脚本按顺序取第一个结果取到了错的。每次出问题我都要回去读自己三个月前写的代码那种感觉非常糟糕。做成 Skill 之后逻辑变了。我不再写如果 A 就 B的硬编码而是写一段给 Agent 看的指令告诉它这个 Skill 是干什么的、输入是什么、输出要满足什么格式、遇到冲突时按什么优先级处理。具体的抓取、比对、写回交给 Agent 去调用工具完成。数据源改版了我只需要调整指令里对来源的描述不用动执行逻辑。这就是 Skill 和脚本最本质的区别脚本描述过程Skill 描述意图。2.2 MyBooks 书库的字段结构先定死不管用什么方式更新第一步永远是先把目标结构定清楚。MyBooks 我用的是一套比较标准的图书元数据字段这里列一下我实际在用的核心字段后面所有操作都围绕它展开字段名类型是否必填说明titlestring是书名主键之一authorstring是作者多作者用逗号分隔isbnstring否13 位或 10 位用于去重publisherstring否出版社publish_datedate否出版日期统一 YYYY-MM 格式cover_urlstring否封面图链接statusenum是想读/在读/已读ratingnumber否0-5支持 0.5 步进tagsarray否标签数组updated_atdatetime是最后更新时间字段定死的好处是Skill 的输出格式就有了明确的校验标准。Agent 返回的结果如果缺了必填字段或者 status 不在枚举范围内我这边直接判为失败不会污染书库。这一步看起来枯燥但它是后面所有自动化的地基跳过它后面一定返工。2.3 Skill 的职责边界怎么划一个常见的误区是把 Skill 做得太全能恨不得一个 Skill 搞定抓取、清洗、比对、写回、通知全流程。我踩过这个坑结果是 Skill 指令写得又长又绕Agent 执行时经常在中途跑偏比如抓取阶段就开始尝试写回或者比对阶段把不该覆盖的字段覆盖了。后来我改成单一职责拆分一个 Skill 只做一件事。具体到书库更新我拆成了三个 Skillfetch-book-info给定书名或 ISBN从指定来源获取原始书籍信息输出结构化 JSON。merge-book-info给定书库现有记录和新抓取记录按优先级规则合并输出最终记录和变更说明。update-mybooks给定最终记录写回 MyBooks 书库返回写入结果。三个 Skill 串起来就是一条完整的更新流水线。拆开的好处是每个 Skill 都能单独测试、单独替换。比如哪天我想换一个数据源只改 fetch-book-info 就行另外两个完全不用动。这种可替换性是长期维护的关键。3. 核心细节解析Skill 指令怎么写才不翻车3.1 Skill 指令的三段式结构WorkBuddy 的 Skill 本质上是一段结构化的指令文本我摸索下来最稳的写法是三段式角色与目标、输入输出契约、边界与异常处理。缺任何一段Agent 都容易在边界情况上出问题。以 fetch-book-info 为例我的指令大致是这样组织的角色与目标 你是一个图书信息抓取助手。给定书名或 ISBN从允许的来源获取书籍元数据。 输入输出契约 输入{ query: 书名或ISBN, query_type: title|isbn } 输出严格返回 JSON字段包括 title, author, isbn, publisher, publish_date, cover_url。缺失字段用 null不要编造。 边界与异常处理 - 如果多个来源结果冲突优先采用 ISBN 匹配的结果。 - 如果所有来源都查不到返回 { found: false }。 - 不要返回任何解释性文字只返回 JSON。这里有几个细节值得说。第一不要编造这句话必须写。模型在没有约束时遇到查不到的字段会倾向于合理推测比如根据书名猜作者这在书库场景里是灾难。第二输出格式要写死明确说只返回 JSON否则它可能给你返回一段好的我帮你查到了以下信息...你还得再解析一遍。第三冲突处理规则要前置不要等出问题了再补Agent 在冲突时如果没有明确指令行为是不确定的。3.2 输入输出契约为什么比自然语言描述更可靠我对比过两种写法。一种是纯自然语言帮我查一下这本书的信息然后整理好。另一种是上面那种带明确契约的。实测下来前者的成功率大概在六成左右后者能到九成五以上。差距就在契约两个字。契约的核心是把模糊变确定。字段名写死、类型写死、缺失值怎么表示写死、返回格式写死。Agent 拿到这种指令相当于拿到了一份 API 文档它知道该往哪个方向收敛。而纯自然语言描述Agent 每次理解都可能不一样今天返回的字段叫 author明天可能叫 writer你的下游处理就崩了。提示契约里的字段名建议直接和 MyBooks 的字段名保持一致。这样 merge 和 update 阶段不用做字段映射少一层转换就少一层出错的可能。3.3 merge 阶段的优先级规则设计merge-book-info 是整个流水线里最需要动脑子的地方。因为新抓取的信息和书库现有信息经常冲突到底听谁的必须有一套明确规则。我的规则是这样的字段优先级理由title现有记录优先书名我可能手动修正过比如去掉副标题author新记录优先抓取来源的作者信息通常更全isbn新记录优先若非空ISBN 是去重关键以权威来源为准publisher新记录优先出版社信息变动少抓取更准publish_date现有记录优先我手动校对过日期格式cover_url新记录优先若非空封面链接容易失效用新的status现有记录优先阅读状态是我个人的绝不能被覆盖rating现有记录优先评分是我的主观数据同理tags合并去重两边标签都保留去重后合并这张表是整个 Skill 的灵魂。status 和 rating 必须现有优先这是血泪教训。我早期没设这条规则结果一次批量更新把几十本书的已读状态全刷成了想读评分也丢了恢复了好久。个人数据字段和客观元数据字段一定要分开对待。3.4 用 ClawHub 管理 Skill 版本Skill 写多了之后版本管理就成了问题。我一开始是把指令文本存在本地文件里改一次存一个副本很快就乱了。后来用 ClawHub 来托管这些 Skill好处是每次修改都有记录可以回滚也能看到哪个版本在什么场景下表现更好。ClawHub 上我一般会给每个 Skill 打上标签比如book、metadata、mybooks方便检索。版本号我用语义化版本指令逻辑有破坏性变更就升大版本只是调整措辞就升小版本。这样当某个 Skill 突然表现异常时我能快速定位是不是最近一次修改引入的。4. 实操过程从零跑通一次完整的书库更新4.1 环境准备与 WorkBuddy 基础配置先把环境搭起来。WorkBuddy 的安装不复杂官网下载对应平台的安装包一路下一步就行。装完之后第一件事是改系统缓存目录默认路径在系统盘跑批量任务时缓存文件会堆得很大我一般改到数据盘。这个设置在偏好设置的存储选项里改完重启生效。然后是配置 MyBooks 的连接。MyBooks 我本地跑的是一个轻量服务暴露了 REST 接口WorkBuddy 通过 HTTP 工具调用它。配置里需要填 base_url 和一个访问 token。token 我建议单独存不要硬编码在 Skill 指令里WorkBuddy 支持环境变量引用用${MYBOOKS_TOKEN}这种形式安全且好换。# 环境变量示例在 WorkBuddy 的环境配置里设置 MYBOOKS_BASE_URLhttp://localhost:8080/api MYBOOKS_TOKENyour_token_here4.2 编写 fetch-book-info Skill 的完整过程打开 WorkBuddy 的 Skill 编辑器新建一个 Skill命名 fetch-book-info。把前面那段三段式指令填进去。然后配置它可用的工具我给它开了两个一个是 HTTP 请求工具用来调开放图书 API一个是网页读取工具用来读出版社页面。配置工具权限时有个原则最小权限。fetch 阶段只需要读不需要写所以我把所有写操作的工具都关掉。这样即使 Agent 理解偏了它也做不出破坏性操作。这个习惯我强烈建议养成Skill 的权限边界就是你的安全边界。写完指令后用几本测试书跑一遍。我一般准备三类测试用例一本信息齐全的、一本信息残缺的、一本查不到的。三类都通过这个 Skill 才算可用。4.3 merge 与 update 的串联执行三个 Skill 都写好之后串联方式有两种。一种是手动串先跑 fetch把结果贴给 merge再把 merge 结果贴给 update。适合调试阶段能看清每一步的中间产物。另一种是让一个编排 Skill 自动串起来适合稳定后的批量执行。我调试阶段用的是手动串因为能看到中间 JSON出问题好定位。等三个 Skill 都稳定了再写一个 orchestrator Skill 把它们串起来。编排 Skill 的指令很简单就是描述先调 fetch把结果传给 merge再把 merge 结果传给 update任何一步失败就中止并报告。批量执行时我会把待更新的书名列表读进来循环调用编排 Skill。这里注意加节流不要一秒发几十个请求既对来源不友好也容易触发限流。我一般设成每个请求间隔 1-2 秒几百本书跑下来也就十几分钟。4.4 一次真实的批量更新记录上周我做了一次批量更新涉及 87 本书。过程记录如下第一轮 fetch87 本中 79 本成功获取8 本查不到多为小众出版物。merge 阶段79 本里有 12 本存在字段冲突按规则自动处理其中 3 本因为 ISBN 冲突被标记为需人工确认。update 阶段76 本成功写回3 本待确认的跳过。总耗时约 14 分钟。那 3 本 ISBN 冲突的我人工核对后发现是同一本书的不同版本手动指定了正确的 ISBN 后重新跑了一遍 update全部通过。这个流程比我以前手动改快了不止一个数量级。5. 常见问题与排查技巧实录5.1 Skill 返回格式不对怎么办这是最高频的问题。表现是 Agent 返回了一段带解释的文字而不是纯 JSON。原因通常是指令里没有强约束。解决办法是在指令末尾加一句只输出 JSON不要有任何其他文字并且在下游解析时做容错比如用正则先提取第一个{到最后一个}之间的内容再解析。如果加了约束还是不稳定可以在 Skill 里加一个输出校验步骤让 Agent 自己检查一遍格式再返回。这个自检步骤会多消耗一点 token但能显著提升稳定性。5.2 字段被意外覆盖的排查思路如果发现书库里某些字段被改了先别急着改 Skill先看 merge 阶段的日志。WorkBuddy 会记录每次 Skill 调用的输入输出找到对应的 merge 记录看它当时拿到的现有记录和新记录分别是什么再对照优先级规则就能判断是规则没覆盖到还是 Agent 没按规则执行。我遇到过一次 status 被覆盖查日志发现是 merge 指令里漏写了 status 的优先级Agent 默认用了新记录的值。补上规则后就再没出现过。所以每次发现异常第一反应是查日志而不是猜。5.3 批量执行中途失败的恢复批量跑到一半失败最怕的是不知道跑到哪了。我的做法是让编排 Skill 每处理完一本就写一条进度记录到一个本地文件记录书名和处理状态。失败后重跑时先读这个文件跳过已成功的只处理失败和未处理的。这样重跑不会重复劳动也不会漏。5.4 常见问题速查表问题现象可能原因解决方向返回非 JSON指令缺格式约束加只输出 JSON并做解析容错字段被覆盖merge 优先级缺失补全优先级规则表查不到书来源覆盖不足增加数据源或放宽匹配批量中途失败无进度记录加进度文件支持断点续跑请求被限流无节流加请求间隔Skill 行为漂移指令过长过杂拆分为单一职责 Skill5.5 几个我踩过的坑第一个坑是指令写得太聪明。我一开始想让一个 Skill 同时处理抓取和判断要不要更新结果 Agent 经常在该抓取的时候去判断该判断的时候又去抓取。后来拆开就顺了。Skill 要笨一点一件事就是一件事。第二个坑是忽略大小写和空格。书名匹配时Python编程 和 Python 编程 会被当成两本不同的书。我在 merge 阶段加了一步标准化去掉多余空格、统一全半角匹配准确率立刻上来了。第三个坑是过度依赖单一来源。早期我只用一个来源那个来源缺的书就永远更新不了。后来加了备用来源覆盖率从八成提到了九成五以上。多来源不是为了冗余是为了覆盖。6. 关于 Skill 复用与扩展的一些个人体会这套东西跑顺之后我发现它的价值不止于 MyBooks。同样的三段式结构、同样的优先级规则设计思路可以平移到很多结构化数据维护的场景。比如我后来用几乎一样的模式做了一个联系人信息更新的 Skill把通讯录里过期的公司、职位信息从公开来源刷新逻辑几乎照搬只改了字段和来源。ClawHub 上现在有不少现成的 Skill 可以参考我建议新手先去上面找几个结构清晰的 Skill 读一读看看别人怎么划分职责、怎么写契约比从零硬憋快得多。但别直接拿来用一定要按自己的字段结构和业务规则改因为优先级规则这种东西是高度依赖个人数据的别人的规则套到你身上大概率不合适。最后分享一个我最近在试的扩展方向给 update 阶段加一个变更摘要输出每次更新完自动生成一份这次改了哪些书、改了哪些字段的清单。这样批量更新后我扫一眼就知道有没有异常不用去翻日志。这个功能还在调等稳定了再单独写一篇。如果你也在维护自建书库或者手上有类似的重复性数据维护任务我真心建议花一个下午把 Skill 这套东西搭起来。前期投入的那点时间后面会以再也不用手动改数据的形式加倍还给你。