我把语雀长文到博客、公众号和小红书,做成了一个 Codex 插件

我一般先在语雀里把文章写完。
文字落下最后一句后,事情却还没结束:博客、微信公众号和小红书各有一套内容形态,我还要重新排版、配图、拆文和检查,一轮下来大概要再花两个小时。
最近我把这段流程做成了一个 Codex Plugin。它会读取语雀原文,让 AI 完成润色、配图和平台改写,再由脚本负责上传、校验、落盘、断点恢复和发布前检查。这篇文章也正好是它的第一份完整测试。我想把制作过程记下来,也讲清楚哪些步骤真的能自动化,哪些仍然需要人在平台页面确认。
1. 为什么要把内容分发做成插件

我一直有写博客的习惯,日常记录通常先放在语雀。文章完成后,我会先发布到个人网站,再处理微信公众号和小红书。三个后台看着都能粘贴 Markdown,真正做起来却各有一摊事情。
博客需要完整的结构、代码块和 Hexo front matter;公众号更关心手机阅读体验,还要有单独的 2.35:1 封面;小红书需要把长文重新组织成一篇短笔记和一组竖版卡片。图片也不能混着用,正文首图、章节图、公众号封面和小红书卡片承担的任务都不一样。
最开始,我在仓库的 .agents/skills/ 下面陆续写了几个 Skill:拉取语雀、迁移图片、上传图床、润色 Markdown。单独使用都没问题,组合起来却越来越难管。
比如,语雀 Skill 只知道把文章下载到本地,不知道最终要放到哪里;润色 Skill 可以学习语气,却不知道公众号应该保留多少博客内容;图片上传 Skill 更不会判断一张图是否真的解释了章节。每次执行时,AI 都要重新拼接这些能力,目录、参数和上下文也容易漏掉。把仓库复制给别人以后,还可能缺少某个 .agents/skills 依赖。
另外,这条链路本身很长。语雀读取、润色、生图、上传、三端改写和发布,中间任何一步遇到网络或页面问题,任务都可能中断。如果进度只留在当前会话里,下次只能重新梳理。
这些问题让我确定了一件事:需要一个完整的 Plugin 来约束整条工作流。它要带着自己的说明、脚本、reference、测试和产物契约,也要把个人凭据与任务进度留在工作区。这样复制插件时不会带走 token,任务恢复时也不用猜上次做到了哪里。
2. 我是如何做出这个插件的

插件和这篇文章全程使用 Codex 完成。下面讲一下大概的思路。
2.1. 先划清 AI 与脚本的边界
语气判断、内容补充、图片创意和平台改写都需要结合上下文,我把它们交给 AI。AI 还要做最后一次复审,检查事实边界、标题编号、图片语义和平台差异。
下载文件、上传图床、检查图片比例、比较公众号与博客正文、创建目录和记录状态都有明确结果,适合用脚本完成。脚本只判断“文件在不在”“比例对不对”“字段齐不齐”,不会偷偷替作者改正文。
这条边界后来成了插件的核心。AI 可以发挥,但必须留下可检查的产物;脚本保持稳定,也不会把创作任务简化成字符串替换。
2.2. 把零散 Skill 收进一个 Plugin
原来的语雀拉取、图床上传和语气缓存被改造成插件内部组件。对外只保留一个主 Skill,由它描述完整工作流和质量要求。AI 不再临时寻找多个 Skill,也不依赖目标仓库的 .agents/ 目录。
语雀读取优先使用已经登录的浏览器会话。这样可以处理私有文档、非会员页面和接口策略变化;页面能复制 Markdown 时直接保留格式,复制能力不可用时再根据可见结构还原标题、列表、引用、代码和图片。原图会重新上传到用户自己的图床。
2.3. 用 86 篇旧文生成作者语气基线
我不希望每次润色都重新读取历史文章,所以先让 AI 阅读了博客里原有的 86 篇文章,整理出一份 author-voice.md。这份个人档案保存在工作区 .codex/yuque-multichannel-publisher/style-profiles/,不会打包进 Plugin。
别人安装插件后,第一次运行也会走同样的学习过程,只读取他自己工作区里的历史文章。如果工作区暂时没有可用样本,插件会明确使用克制的通用语气,等积累了文章再建立个人档案。这个过程只生成语气 reference,不会生成任何密钥。图床 token 需要用户通过环境变量或工作区配置提供,公众号和小红书则使用用户已经登录的平台会话。
这份 reference 记录了第一人称工程师视角、常见开头、句段节奏、技术文章的推理方式、结尾习惯,以及需要避免的表达。后续润色只读取这份紧凑基线。旧文发生变化时再更新语料指纹;某个分类确实有明显差异时,再补一个小型分类档案。
语气保障分成两遍。第一遍先守住事实,只补理解文章所需的背景、因果、例子和边界;第二遍才按照语气档案重组句段,保留我的第一人称判断、技术推理、犹豫和自然转场。这样可以避免为了“像我”而编出新的经历。
完成后再做去 AI 痕迹复审,重点处理模板化开场、空泛黑话、整齐排比、万能总结和高频的否定对照句。项目会记录本次使用的语气档案路径、语料指纹、检查项和复审说明。脚本负责确认这些证据存在并扫描高风险表达,最终语言判断仍由 AI 完成。
2.4. 让图片先有内容,再谈风格
第一版章节图虽然比例正确,看起来也挺“科技”,但画面和章节没有多少关系。这个问题促使我把图片生成拆成三个动作:先写视觉 brief,再生图,最后看图复审。
brief 会写清本节的核心判断、必须出现的对象与关系、适合的信息类型,以及需要避开的元素。流程和架构优先使用编辑式信息图;有真实材料时优先用截图;个人经历更适合叙事插画。生成后还要检查文字、关系和缩略图可读性,内容对不上就重画。
正文首图保留温暖手绘动画氛围。公众号封面单独生成,严格使用 2.35:1,并在安全区加入短标题。小红书先组织卡片叙事,每张卡只推进一个信息点,然后再制作 3:4 图片。
2.5. 用检查点保存长任务
每个内容项目都会在 content-projects/<slug>/.codex/ 下保存 state.json 和事件记录。当前阶段、已完成产物、哈希和最终目标目录都在里面。
插件把任务分成初始化、拉取、润色、配图、复审和持久化几个阶段。中断后运行 resume,可以直接看到上次停在哪里。只有记录了 reviewed 检查点,materialize 才允许把草稿写入正式目录。
最后,我给流水线补了契约测试。现在会检查标题编号、图片比例和 brief、作者语气指纹、公众号正文相似度、小红书卡片数量、跨轮指代、最终目录,以及各平台是否被误记成同一个发布状态。这次测试文章跑完后,草稿校验、物化校验和 Hexo 构建都通过了。
3. 插件的结构、产物和优点

插件现在只有一个对外 Skill,目录大致如下:
1 | yuque-multichannel-publisher/ |
plugin.json 负责插件身份、版本和 Codex 中的展示信息;SKILL.md 告诉 AI 应该怎样完成整条工作流;references/ 存放通用的语气学习、编辑、配图、产物和发布规范;scripts/ 处理确定性操作;tests/ 防止目录和校验规则在更新后悄悄失效。
个人数据单独放在工作区:
1 | <workspace>/.codex/yuque-multichannel-publisher/ |
真正运行时,个人语气、登录态、图床 token、分类缓存和任务状态不会写进插件目录。它们保存在工作区的 .codex/yuque-multichannel-publisher/ 或具体内容项目下。插件只检查凭据是否已配置,不会生成密钥,也不会读取浏览器密码。插件可以更新或复制,个人配置不会被覆盖。
3.1. 三个平台如何落盘
博客保留完整论证、代码、引用和目录结构,最终写入:
1 | source/_posts/<slug>.md |
公众号与博客使用同一份正文,只做轻量段落适配,同时生成 Markdown 和带行内样式的 HTML:
1 | wechat/<slug>/article.md |
小红书先判断原文能支撑几篇独立笔记。每一轮都要重新交代对象和核心观点,并生成正文与卡片计划:
1 | rednote/<slug>/series-plan.json |
这篇文章最终只生成一轮。动机、制作流程和插件结构属于同一个主题,拆成三轮后,后两篇会缺少必要上下文。
3.2. 小红书如何决定拆成几轮
小红书拆分先看主题,再看章节。AI 会从长文里提取文章对象、目标读者、核心判断、可执行信息和真实材料,然后逐个判断候选主题离开其他内容后是否仍然完整。
一轮至少要回答三个问题:讲的是什么、为什么值得看、读者能怎么做。它还要有自己的背景、收益和配图材料。只是长文里的一个步骤,或者需要依赖“上一轮”才能理解,就继续留在同一篇笔记里。
轮数确定后,每轮先写 series-plan.json 里的上下文,再写 cards.json。首卡说明主题和目标读者,中间每卡只推进一个信息点,末卡收住结论或提出具体问题。图片优先使用真实截图和材料,其次才是重绘、图文卡和 AI 场景图。最后单独阅读每轮正文和卡片,做一次“陌生读者测试”。
这篇文章包含动机、制作过程、插件结构和优势,但它们都在回答“这个插件是怎么做出来的”。拆开后,结构和优势会失去产品背景,所以最终只保留一轮。
3.3. 先检查,再决定怎样投递草稿
我参考了 md2wechat 和 XiaohongshuSkills 的做法,把“生成发布包”和“操作外部平台”拆成两步。流水线先输出机器可读的就绪报告:
1 | python3 pipeline.py inspect --project <slug> --probe |
报告会列出正文字符数、标题数量、远程图片、摘要长度、AI 套话风险、三端缺失产物和适配器状态。后面的动作只认这份报告里的 blocker,不再根据一句“文件已经生成”猜测能不能发布。
微信公众号可以接入用户单独安装的 md2wechat。插件先调用 inspect 检查账号配置、封面和目标状态,再执行草稿写入。AppID、Secret 和 API Key 都留在外部工具自己的配置里,插件只保存可执行文件路径和账号别名。
1 | python3 pipeline.py send-draft \ |
小红书这边要保守一些。参考项目通过 Chrome DevTools Protocol 操作创作后台,能上传图片、填写标题和正文,但自动化会受页面改版、登录校验和账号风控影响。插件因此固定调用它的 --preview 模式:只填充编辑器,不自动点击发布,也不会把“页面填好了”写成“平台草稿已保存”。
1 | python3 pipeline.py send-draft \ |
小红书页面明确提示保存成功后,才记录 draft_saved。微信公众号、小红书和每个小红书轮次都有自己的状态;filled_for_review、draft_saved、published 三者也完全分开。这样某一轮失败时,不会把其他平台已经完成的内容阶段一起回滚。
这两个外部项目都不直接打包进插件。md2wechat 的许可对商业使用和再分发有额外要求;XiaohongshuSkills 的浏览器选择器也需要跟着平台更新。保留适配层以后,插件本身只维护内容契约、能力探测和状态记录,外部工具可以独立安装与升级。
3.4. 我觉得它目前最有价值的地方
第一,插件是自包含的。复制整个目录就能带走主 Skill、内部脚本、reference 和测试,不需要再拼装仓库里的多个 Skill。
第二,AI 的创作能力和脚本的稳定性都有明确位置。文章、图片和渠道改写仍由 AI 完成,目录、比例、状态和相似度交给脚本检查。出现问题时,也比较容易知道应该改 prompt、reference 还是代码。
第三,长任务可以恢复。图片生成或浏览器操作中断后,原文、草稿、图片和检查点都还在本地,下次会话可以从有效阶段继续。
第四,三个平台共享事实和长文底稿,但产物形态各自独立。公众号不会被改成摘要,小红书也不会按一级标题机械拆轮。
第五,质量要求能够留下记录。作者语气使用了哪份 reference、章节图要表达什么、公众号封面标题是否检查过、小红书为什么分成当前轮数,都可以在项目文件中找到。
它目前还有边界。公众号草稿箱可以通过外部适配器自动写入,但凭据、IP 白名单和账号权限仍要由用户配置;小红书自动化目前可靠做到的是编辑器填充,草稿是否真正保存必须看平台反馈。博客仓库也有自己的 Git 规则。真正发布前,仍然要确认账号、标题、时间和可见范围。
插件源码和使用说明已经放在 wxxlamp/ai-coding-config 仓库,进入 plugins/yuque-multichannel-publisher/ 目录即可查看完整 Plugin。
对我来说,这个插件已经把最烦的搬运工作收进了一条可重复的流程。以后文章写完,我可以先把注意力留在内容上,等本地发布包检查通过,再决定什么时候打开各个平台。