博客专栏 产品中心 技能中心

我是如何把微信公众号变成 AI 智能体的:聊天秒回 + 文章自动生成发布

· 原创专栏 · 阅读 4

我是如何把微信公众号变成 AI 智能体的:聊天秒回 + 文章自动生成发布

个人公众号,也能变身 24 小时在线的 AI 智能体——粉丝发消息 AI 秒回,一句话让 AI 写文章并自动发到草稿箱。本文分享我从 0 到 1 打通的全过程,以及踩过的 5 个大坑。

一、最终效果先看

打通之后,这个公众号具备了两个核心能力:

对话即服务:粉丝在公众号里直接和 AI 聊天,命理解读、简历定制、金融资讯等技能随叫随到,无需跳转任何网页

一句话发文:对公众号说"写一篇关于 XX 的文章并发布",AI 自动完成 "写作 → 排版 → 生成封面 → 提交草稿箱" 全流程,我只需在后台点一下"发布"

背后是一套自建的 Java 智能体平台(Spring Boot 3 + Spring AI),公众号只是它的一个"渠道插件"。

二、整体架构:公众号只是一张皮

架构上我把系统拆成三层:

| 层 | 职责 | 关键组件 |

|---|---|---|

| 渠道层 | 微信消息收发、签名校验、XML 编解码 | ChannelController |

| 智能体层 | 意图理解、技能路由、多轮对话 | Spring AI + 技能注册中心 |

| 能力层 | 内容生成、素材上传、草稿发布 | PublishService + Skills |

微信服务器把粉丝消息 POST 到我的回调接口,平台调大模型生成回复,再按微信协议回包——听起来很简单?真正动手才发现,难的全在微信的规则细节里。

三、打通聊天:未认证订阅号的"死局"与破局

3.1 第一盆冷水:客服消息接口不给用

最初的方案是业界常规套路:收到消息先回个"思考中"占位,AI 算完后用客服消息接口主动推送结果。

结果接口直接报错 errcode=48001, api unauthorized——未认证的个人订阅号根本没有客服消息权限,而个人主体连微信认证的资格都没有。主动推送这条路,彻底堵死。

3.2 破局:把微信的"重试机制"变成等待窗口

微信有个规则:回调 5 秒内不响应,它会用相同的 MsgId 重试,最多 3 次。大多数教程把重试当成麻烦,我反过来把它用成了 15 秒的免费等待窗口:

  • 第 1、2 次推送:等待 5.5 秒。AI 算完就直接被动回复;没算完就故意超时,让微信重试
  • 第 3 次推送:这是最后机会,等待 4.2 秒后必须兜底响应
  • MsgId 去重:三次重试共享同一个异步任务,AI 只调用一次
  • 超窗兜底:15 秒还没算完,先回复"我还在思考中",结果暂存,粉丝发「继续」即可取回
  • 被动回复还有 2048 字节的长度上限,超长回复会自动分段暂存,粉丝连续发「继续」逐段阅读——体验上接近"翻页"。

    这套方案不需要任何认证权限,任何个人订阅号都能复刻。

    四、AI 自动发文:草稿箱 API 的三连坑

    聊天打通后,我给智能体注册了一个"发布技能":AI 生成 Markdown 文章 → 转成微信 HTML → 调草稿箱 API 入库。听着顺滑,实际连踩三个坑。

    坑 1:封面图是必填项(errcode=40007)

    草稿接口的 thumb_media_id 必填,不传直接报 invalid media_id。但 AI 写文章哪来的封面?

    我的解法:代码自动画一张。用 Java AWT 在内存里绘制 900×383 的品牌渐变封面(无头服务器也能跑),上传为永久素材并缓存 media_id 复用——从此每篇文章都有统一的品牌封面。

    坑 2:上传素材被拒(HTTP 412)

    上传封面时微信返回 412 Precondition Failed,连错误 JSON 都不给。用 curl 直接复现却成功了,说明不是权限问题。

    排查后确认是 Spring 6.1+ 的著名坑:RestTemplate 上传文件默认改成了 chunked 流式传输,不带 Content-Length,而微信服务器拒收 chunked 请求。解法是手动拼 multipart 字节体,让 Content-Length 恢复为固定长度。

    坑 3:列表全是"空项"(微信私有行为)

    文章发上去后,所有列表每个条目前都多了一个空圆点,有序列表编号 1、3、5 全是空的。

    把草稿内容从 API 拉回来对比才真相大白:微信入库时会把

      内标签之间的换行符强行包装成空
      。而任何标准 Markdown 转换库输出的 HTML 都在标签间带换行——这锅谁都躲不掉。

      解法:提交前用 jsoup 把列表内的空白文本节点全部剔除,输出完全紧凑的 HTML,微信就无从下手了。

      三个坑填完后,AI 在对话里直接回复"已发布到草稿箱",全流程一气呵成。

      五、踩坑速查表

      | 现象 | 根因 | 解法 |

      |---|---|---|

      | errcode=40164 | 服务器 IP 不在白名单 | 公众平台添加 IP 白名单 |

      | errcode=48001 | 未认证号无客服消息权限 | 被动回复 + 重试等待架构 |

      | errcode=40007 | 草稿封面 media_id 必填 | AWT 自动生成品牌封面 |

      | HTTP 412 | Spring 6.1+ chunked 上传被拒 | 手动构造 multipart 字节体 |

      | 列表空项 | 微信把换行符包成空 li | jsoup 剔除空白节点 |

      六、写在最后

      这次实践最大的感受:AI 应用的难点往往不在 AI,而在与真实世界的接缝处。大模型调用只花了 10% 的时间,剩下 90% 都在和微信的协议细节、权限矩阵、私有解析行为斗智斗勇。

      但打通之后的体验是质变的——公众号从一个"单向广播工具"变成了"双向智能服务入口",而且这套架构对所有个人订阅号通用。

      如果你也想给自己的公众号装上 AI 大脑,欢迎留言交流。


      作者:molashaonian


      作者:molashaonian