三个月前我写了一篇《VSCode 中搭建 OpenCode AI 编程助手完整指南》,那篇文章主要讲怎么装、怎么配。装好之后呢?它到底能帮我们省多少事?
这几个月下来,我摸索出一整套从写文章到自动发布的工作流。今天把我博客的完整流水线拆开给大家看——从在 VSCode 里写 Markdown,到 GitHub Actions 自动构建部署,再到自动同步到微信公众号,全链路自动化,一次编写,多平台分发。
一、OpenCode 项目配置:从通用助手到专属博客架构师
OpenCode 默认是通用的编程助手,但真正好用的是它的项目级自定义配置。通过 .opencode.yaml 和 AGENTS.md 两个文件,我们可以让 AI 完全理解项目上下文,变成专属于这个博客的助手。
1.1 模型配置
我的博客用的是 DeepSeek V4 Flash,配置在 .opencode.yaml 中:
1 | model: deepseek/deepseek-v4-flash |
选 DeepSeek V4 Flash 的原因很直接:速度快、中文理解好、成本趋近于零。写博客场景不像写生产代码,不需要反复推理,更需要的是快速理解和风格一致的自然语言输出。V4 Flash 在中文技术写作上的表现,明显优于同价位的其他模型。
role 字段定义了助手在项目中的多个角色视角,这直接影响了 OpenCode 的回答风格——当你在 /chat 中问博客相关问题时,它会自动切换到”博客架构师”视角;当问代码逻辑时,切换到”高级软件工程师”视角。
1.2 AGENTS.md:项目知识库
真正让 OpenCode 理解这个博客的,是根目录下的 AGENTS.md 文件。它定义了项目的完整 DNA:
- 项目概览:博客基于 Hexo + Next 主题,目录结构说明
- 构建命令:
hexo clean && hexo g、hexo s、hexo d - 代码风格:JavaScript 用
'use strict',Python 用 f-string,Markdown 用 bracket-wrapped tags - 文件规范:文章命名 kebab-case,相册目录结构,工具脚本目录
- 禁止操作:不修改
node_modules/,不提交public/和db.json - 发布前检查:本地构建测试 → 用户确认 → 提交部署
有了这份配置,OpenCode 在生成代码或文章时就会自动遵循项目规范,不需要每次重复交代上下文。比如我写 hexo new post "xxx" 后让 OpenCode 帮我补全 front-matter,它自动就知道 tags 要用 bracket-wrapped 格式、categories 要写什么、date 用什么格式。
二、文章开发工作流:从想法到成文
有了配置好的助手,实际的写作流程变成这样:
2.1 创建文章骨架
1 | hexo new post "VSCode-OpenCode-DeepSeek-博客文章全自动开发流水线实战" |
OpenCode 会自动补全 front-matter,然后我通过 /read 查看当前文章模板,通过 /edit 调整结构大纲。
2.2 AI 辅助写作
写作过程中,我经常用到这几个 OpenCode 的 Tools:
/read— 查阅已有的文章,确保风格一致。比如写这篇之前,我/read了之前那篇 OpenCode 安装指南,避免内容重复/edit— 精确替换文章内容,不用自己拉滚动条找位置/bash— 直接在 VSCode 里跑hexo s预览效果/grep和/glob— 快速查找项目中已有的配置文件和代码片段
比如我需要确认某个 GitHub Actions 配置的语法,直接 /read .github/workflows/deploy.yml 就能看到完整配置,不用切到文件管理器去找。
2.3 图片处理
博客的图片主要来自钓鱼相册。每次拍完照片,先用 tools/图片重命名.py 批量处理:
1 | python tools/图片重命名工具/图片重命名.py --album img2026 --keywords "花碑水库" --species "鲤鱼" |
这个脚本会做三件事:
- 图片转 WebP 并压缩
- 调用 DeepSeek API 自动生成 alt 文本(根据图片内容描述场景)
- 生成相册 HTML 代码片段
生成的 HTML 直接贴进 source/fish/img2026/index.md,然后把新图片推送到 fish-images 仓库。
2.4 多仓库管理
我的博客涉及两个 Git 仓库:
| 仓库 | 用途 | 操作 |
|---|---|---|
grj1981/BlogCode |
博客源码(文章、主题、配置) | git push origin master |
grj1981/fish-images |
图片 CDN 源 | git push origin main |
OpenCode 的 AGENTS.md 里定义了禁止自动提交的规则,所以每次都是我先手动 review 变更,确认无误后再让它执行提交操作。
三、自动部署:GitHub Actions 接管构建与发布
以前我的部署流程是:本地 hexo clean && hexo g,确认没问题,然后 hexo d。虽然不太麻烦,但人总有忘记的时候。而且如果在外地没有本地环境,就完全没法更新博客。
自从配了 GitHub Actions,部署这件事基本就从我的待办列表里消失了。
3.1 工作流配置
完整的部署流程写在 .github/workflows/deploy.yml 中:
1 | name: Deploy Blog |
几个值得一提的设计:
路径过滤:只监听 source/_posts/、scripts/、themes/next/ 等目录的变更。如果只是改了 README 或者 tools 目录下的脚本,不会触发部署,省 Action 分钟数。
TiDB 凭据注入:博客的评论区热榜数据在构建时从 TiDB Cloud 读取,通过 GitHub Secrets 注入环境变量,不会暴露在源码中。
SSH Deploy Key:部署到 grj1981.github.io 仓库用的是 base64 编码的 SSH 私钥,存放在 DEPLOY_KEY_B64 Secret 中。构建时解码写入临时文件,用完即弃。
3.2 构建流程时序
1 | 用户 push → GitHub 检测到变更 → |
整个过程大约 40-60 秒。文章推送到 master 后,不到一分钟就能在 www.bytefisher.top 上看到更新。
3.3 踩坑:路径过滤不生效
🔴 问题:配置了 paths 过滤后,有几次改了 source/_posts/ 下的文章却没触发部署。
排查发现是 GitHub Actions 的 paths 过滤规则的问题——如果 push 包含多个 commit,其中只有部分 commit 命中 paths,整个 workflow 也可能被跳过。最终在配置里加了 workflow_dispatch 手动触发作为兜底,需要时去 GitHub 仓库页面点一下 “Run workflow” 就行。
四、公众号同步:博客到微信的自动化桥梁
部署到博客只是第一步。我的内容还需要同步到微信公众号,而这一步的自动化程度最高,也最复杂。
4.1 同步方案设计
微信公众号文章的格式要求和博客完全不同:
- 不支持标准 Markdown,需要转成内联 HTML
- 图片不能引用外链,必须上传到微信素材库
- 封面图有严格的尺寸要求(900×500)
- 已经发布的草稿不支持修改(只能重新创建)
面对这些限制,我决定写一个专门的工具,目录在 tools/wechat-sync/。整体架构如下:
1 | source/_posts/*.md |
4.2 自动同步工作流
同步也是通过 GitHub Actions 触发,配置在 .github/workflows/wechat-sync.yml 中:
1 | name: WeChat Sync |
工作流的触发方式有两种:
自动触发:当有新的文章 push 到 source/_posts/ 时,自动检测变更的文章,只同步新增或内容有修改的文章。
手动触发:通过 GitHub Actions 的 workflow_dispatch,支持多种模式:
auto— 自动检测增量变更(默认)all— 强制同步全部文章year-2026— 只同步指定年份dry-run— 试运行,不调用微信 API,只输出将要执行的操作specific_file— 指定单个文件同步
4.3 核心模块拆解
4.3.1 文章解析(post-parser.js)
这个模块负责把 Hexo 的 Markdown 文章解析成结构化数据:
1 | function parsePost(filePath) { |
关键点:摘要生成逻辑——优先使用 description 字段,其次是 <!--more--> 之前的内容,最后是正文前 200 字符。
4.3.2 Markdown 转微信 HTML(markdown-to-html.js)
微信公众号的编辑器不支持标准 Markdown,必须使用内联样式的 HTML。我用 marked 库自定义了一个 Renderer:
1 | const renderer = new marked.Renderer(); |
图片处理是最特别的——它不是直接输出 <img> 标签,而是生成 <!-- IMG:url --> 占位符,等图片上传到微信素材库后,再统一替换成真正的微信图片地址。
安全性方面,内置了 sanitizeHtml 函数过滤 XSS:
1 | function sanitizeHtml(html) { |
4.3.3 图片处理流水线(image-processor.js)
图片处理是整个同步过程中最耗时、也最容易出问题的环节。流程如下:
1 | async function processImages(imageUrls, client, options = {}) { |
压缩策略非常保守——先从 quality 85 开始,如果超过 2MB 就降 10,循环到 40 为止。实测绝大多数图片在 quality 75 左右就能压到 2MB 以内。
4.3.4 微信 API 封装(wechat-api.js)
微信公众号 API 有两个关键接口需要调用:
获取 Access Token:
1 | async getAccessToken() { |
创建/更新草稿:
1 | async createDraft(article) { |
创建草稿时传入的参数包括:标题、作者、摘要、正文 HTML、原文链接、是否开启评论等。其中 content_source_url 字段指向博客原文,读者可以点击”阅读原文”跳转到博客。
4.3.5 增量同步状态追踪(tracker.js)
这是保证同步效率和避免重复创建草稿的关键模块:
1 | class SyncTracker { |
同步状态文件 sync-state.json 记录了每篇文章的同步状态:
1 | { |
增量同步的逻辑:
- 对所有文章计算 contentHash
- 和状态文件中的记录对比
- 新增 → 创建草稿
- 内容变更 → 更新草稿
- 未变更 → 跳过
这样即使博客有上百篇文章,每次触发时也只需要处理最近变更的那一两篇,整个同步过程能在 10-20 秒内完成。
4.4 踩坑集锦
公众号同步过程中踩过的坑不少,列几个比较典型的:
🔴 踩坑 1:图片尺寸超限
微信素材库对图片的限制是 2MB(普通图片)和 10MB(高清图片),但博客的图片经过 WebP 压缩后很多只有 200-300KB,按理不会超限。问题出在格式转换上——有些 png 图片在转成 jpg 时,由于色彩复杂,文件体积反而膨胀了。
解决方案:compressImage 函数在转格式后主动检测文件大小,超标就循环降 quality,直到达标为止。
🔴 踩坑 2:Markdown 差异导致排版错乱
标准 Markdown 的很多特性在微信公众号里是不支持的:
- 表格没有带边框 → 需要手动加
border:1px solid #ddd - [ ]复选框 → 完全不兼容- 行内 HTML 标签 → 微信编辑器会过滤掉一部分
解决方案:自建 Renderer,每个元素都指定完整的内联样式,从 h1 到 blockquote 到 table,全部显式设置 font-size、color、margin。
🔴 踩坑 3:公众号 API 的 media_id 过期
微信的草稿 media_id 在草稿已发布后会失效,此时再调用 updateDraft 会返回错误码 40007。而且已发布的文章不能修改,必须重新创建。
解决方案:在 syncPost 函数中捕获 40007 错误,自动转为 createDraft 重新创建:
1 | if (err.errcode === 40007) { |
🔴 踩坑 4:GitHub Actions 并发冲突
有一次连续 push 了两篇文章,触发了两次 wechat-sync 工作流。两个并行的同步实例同时对 sync-state.json 进行读写,导致状态文件损坏,部分文章重复同步。
解决方案:在 workflow 中设置 concurrency 组:
1 | concurrency: |
这样同一个 group 内的 workflow 会排队执行,不会并发。cancel-in-progress: false 保证不会取消已经在执行的同步任务。
五、一条指令完成全流程
现在,整个文章开发流程变成了这样:
1 | 写文章 |
1 | ┌─────────────────────┐ |
这张图就是我现在发布一篇文章的完整路径。从在 VSCode 里敲下最后一个字,到博客上线 + 公众号草稿就绪,只需要 git push 这一条指令。
六、总结
6.1 自动化的价值
这套流水线跑下来,最大的感受是:精力从”发布操作”转移到了”内容创作”。
以前每次发文章:
- 本地构建 → 检查报错(3 分钟)
- 截图 → 上传图床 → 替换链接(5 分钟)
- 部署到 GitHub Pages(2 分钟)
- 登录公众号后台 → 复制粘贴 → 重新排版(15 分钟)
- 上传图片 → 调整格式 → 保存草稿(10 分钟)
现在:
- 写完 →
git push(10 秒) - 等 40 秒博客自动更新
- 等 15 秒公众号草稿自动创建
- 登录公众号 → 预览 → 发布(2 分钟)
6.2 成本分析
| 服务 | 月费用 | 说明 |
|---|---|---|
| DeepSeek V4 Flash API | ≈ ¥0 | 写博客用量极少,免费额度足够 |
| GitHub Actions | 免费 | 每月 2000 分钟免费额度,博客部署只用了不到 50 分钟 |
| GitHub Pages | 免费 | 静态托管免费 |
| Cloudflare Workers | 免费 | 图片代理,免费计划每天 10 万请求 |
| Vercel (Waline) | 免费 | Serverless 函数运行评论系统 |
| TiDB Cloud Serverless | ≈ ¥0 | 评论区数据存储,25GB 免费容量 |
| 总计 | ≈ ¥0/月 |
6.3 未来展望
目前自动化的最后一公里——微信公众号的手动发布——还没有打通。虽然草稿是自动创建好的,但还是需要登录公众号后台点一下发布按钮。
考虑过接入微信发布的 API,但微信公众号的群发接口有严格的调用限制(订阅号每天只能群发 1 次),而且发布后的文章不能修改。自动发布的风险太高,手动预览一次再发布更稳妥。
下一个想接入的是 RSS 自动同步到其他平台(掘金、CSDN 等),通过标准的 RSS feed 让第三方平台自动抓取新文章。atom.xml 已经有了,缺的是各平台的接入适配。
相关链接:
- VSCode 中搭建 OpenCode AI 编程助手完整指南
- Hexo 博客二次优化实战:从性能压缩到品牌打磨全记录
- Hexo 博客图床迁移实战:从 iili.io 到 Cloudflare Workers + 工具链改造全记录
- OpenCode 官网
- DeepSeek 官网
本文对应的完整配置和工具代码可在 GitHub BlogCode 仓库 中找到。