中文 English

如何写提示词,让 OpenClaw、HermesAgent、Codex、Claude、Gemini、OpenCode、Droid 自动写文章并发布到微信公众号草稿箱

发布时间: 2026-05-05
Agent Prompt OpenClaw HermesAgent Codex Claude Gemini OpenCode Droid 微信公众号 自动化 Hugo 写作

先说结论

想让 OpenClaw、HermesAgent、Codex、Claude、Gemini、OpenCode、Droid 这类 Agent 自动写文章、生成博客、转换微信公众号 HTML、检查预览效果,并最终把内容发布到微信公众号草稿箱,提示词不能只写“帮我发一篇文章”。真正有用的提示词要把目标、素材、路径、账号约束、网络白名单、检查项、失败回退、隐私边界和最终验收写清楚。Agent 才能从“写一段内容”升级成“完成一次可验证的发布流程”。

本文整理一套可以复用的写法:如何准备微信公众号草稿箱 API,为什么固定 IP Linux 机器很重要,怎样让 Agent 先直连再走中转,如何使用 Markdown 到公众号 HTML 的转换器,如何让 Agent 检查白字白底、奇怪缩进、图片可访问性,最后如何把整条流程写进一段高质量提示词里。

为了避免泄露任何私人环境信息,本文只使用占位符和抽象示例,不出现真实 AppSecret、内网地址、跳板机地址、仓库地址、主机名、token、cookie 或任何可定位到具体环境的配置。你可以把文中的占位符替换成自己的值,但不要把真实密钥写进公开文章、公开仓库或聊天截图。

提示词驱动 Agent 自动写作、转换、检查和发布的全貌

图 1:Agent 自动发布不是单点动作,而是从提示词、写作、转换、预览、API 到发布验证的一条闭环。

1. 为什么这件事值得专门写提示词

很多人第一次让 Agent 写公众号文章,会这样说:

帮我写一篇文章,然后发布到微信公众号。

这句话当然可以启动写作,但它离“自动发布到草稿箱”还差得很远。因为 Agent 不知道文章风格、不知道博客仓库在哪里、不知道配图放在哪里、不知道公众号 HTML 要不要走转换器、不知道微信 API 的白名单限制、不知道失败时能不能使用固定 IP 机器,也不知道发布后要检查什么。

更关键的是,公众号发布不是单纯的文本生成。它至少包含七个环节:

  1. 生成文章主题、结构、标题、摘要和正文。
  2. 生成或整理插图,并确保图片地址可被公众号访问。
  3. 把 Markdown 转成适合微信公众号编辑器的 HTML。
  4. 本地预览 HTML,检查排版、空格、代码块、图片和标题层级。
  5. 使用微信公众号接口获取 access_token
  6. 上传正文图片和封面图,再创建草稿。
  7. 验证草稿内容、线上博客页面和源码仓库状态。

如果提示词只说“帮我发布”,Agent 很容易只完成第一步,最多再给你一份 Markdown。真正要提高自动化程度,就要把这些动作拆开,告诉 Agent 每一步的边界和验收标准。

这也是本文的核心观点:提示词不是愿望清单,而是操作合同。 它要让 Agent 明确知道什么可以做、什么不能做、做到什么程度才算完成。

2. 先准备微信公众号草稿箱 API

微信公众号草稿箱 API 的关键点不复杂,但有几个容易踩坑的地方。

2.1 需要 AppID 和 AppSecret

公众号后台会提供 AppIDAppSecret。它们的使用方式通常是先请求:

https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=<WECHAT_APPID>&secret=<WECHAT_APPSECRET>

拿到 access_token 后,再调用素材上传、草稿新增、草稿更新等接口。注意,AppSecret 应该只放在运行环境变量、密钥管理器或受保护的配置文件里。不要写入博客文章、Git 仓库、公开 issue、截图或 Agent 记忆文件。

在提示词里也不要直接要求 Agent 把真实密钥写入脚本。更稳妥的表达是:

请从环境变量 WECHAT_APPID 和 WECHAT_APPSECRET 读取公众号配置,不要把密钥写入任何文件。

这样 Agent 可以写出可复用脚本,但不会把密钥固化到源码里。

2.2 需要配置 IP 白名单

微信公众号接口对调用来源有白名单限制。也就是说,即使 AppIDAppSecret 都正确,如果请求从一个未加入白名单的公网出口 IP 发出,接口仍然会拒绝。

这就是为什么自动发布流程通常需要一台有固定公网 IP 的 Linux 机器。这台机器不一定要承担写作任务,但它必须能稳定访问微信 API,并且它的公网出口 IP 要添加到微信公众号后台白名单。

在真实流程里,可以有两种执行方式:

  1. 本地 Agent 直接访问微信 API,如果本地出口 IP 已加入白名单,就直接发布。
  2. 本地 Agent 无法通过白名单时,把 HTML、图片和必要参数传到固定 IP Linux 机器,由那台机器代为调用微信 API。

提示词必须明确这个顺序。因为如果你不说,Agent 可能会先折腾本地代理,也可能直接尝试跳板机,导致排障路径混乱。

微信公众号 API 白名单和固定 IP Linux 中转关系

图 2:白名单限制本质上是公网出口问题。写作可以在本地完成,API 调用可以交给固定出口 IP 的 Linux 机器。

2.3 素材上传和草稿创建是两步

公众号正文里的图片不能随便引用本地路径,也不应该引用内网地址。可靠做法是先把图片上传到微信素材接口,拿到微信返回的图片 URL,再把 HTML 中的本地图片路径替换成微信图片 URL。

草稿封面图则需要通过永久素材或临时素材接口上传,拿到 media_id,然后在 draft/add 请求里填入 thumb_media_id

一个典型流程如下:

读取 HTML
扫描 HTML 中的本地图片路径
逐张上传正文图片 -> 得到微信图片 URL
替换 HTML 图片路径
上传封面图 -> 得到 thumb media_id
调用 draft/add 创建草稿
输出 draft_media_id

这段流程看似啰嗦,但它能避免两类常见问题:公众号草稿里图片裂掉,以及草稿创建成功但封面不可用。

3. Markdown 到微信公众号 HTML:为什么要使用转换器

Markdown 适合写作,但微信公众号编辑器不是普通网页。它对 CSS、标签、图片、代码块、外链、样式隔离都有自己的限制。直接把博客 Markdown 粘进去,通常会出现标题弱、代码块丑、列表间距怪、图片边距不稳等问题。

我更推荐把 Markdown 先转换成公众号友好的 HTML,再把 HTML 作为草稿内容提交。这里可以使用“可能吧微信文章转换器”这类工具,也可以封装一个本地脚本自动调用转换器接口。

示例脚本的关键片段大概是这样:

def direct_network_env() -> None:
    for key in ("http_proxy", "https_proxy", "HTTP_PROXY", "HTTPS_PROXY", "ALL_PROXY", "all_proxy"):
        os.environ.pop(key, None)


def convert(markdown: str) -> str:
    data = urllib.parse.urlencode(
        {
            "name": "作者名",
            "pic": "",
            "color": "greenblue",
            "font": "1",
            "numbers": "1",
            "f": "notime",
            "u": "mp",
            "mdtxt": markdown,
        }
    ).encode("utf-8")
    request = urllib.request.Request(
        "https://mp.knb.im/tohtml.php",
        data=data,
        headers={
            "Content-Type": "application/x-www-form-urlencoded; charset=utf-8",
            "User-Agent": "Mozilla/5.0",
            "Referer": "https://mp.knb.im/",
            "Origin": "https://mp.knb.im",
        },
    )
    with urllib.request.urlopen(request, timeout=45) as response:
        page = response.read().decode("utf-8", errors="replace")
    match = re.search(r'<textarea name="editor1" id="editor1">\\s*(.*?)\\s*</textarea>', page, flags=re.S)
    if not match:
        raise RuntimeError("converter did not return editor HTML")
    return html.unescape(match.group(1)).strip() + "\\n"

这只是核心片段。完整代码需要处理浏览器兜底、代理清理、异常提示、文件输入输出、HTML 预览生成等细节。如果需要完整代码,可以关注微信公众号【ClawLoader】并回复 convert_knb 获取。

3.1 转换器不是最后一步

使用转换器不等于排版已经完成。转换器会生成一套适合公众号的结构和样式,但你仍然需要检查:

  1. 标题层级是否过深或过浅。
  2. 导读、章节标题和子标题是否清晰。
  3. 代码块是否还能阅读。
  4. 图片是否变形、过宽、过小或丢失。
  5. 是否存在白色文字放在白色背景上。
  6. 是否存在连续空格导致正文异常缩进。
  7. 是否把内网路径、真实 IP、密钥或私人目录写进正文。

所以提示词里应该明确写上“转换后必须检查并修复”,而不是只写“转换为 HTML”。

4. 让 Agent 自动化工作的提示词结构

一个好的自动发布提示词,建议分成十个区块。

4.1 目标

目标区块要写清楚最终产物,而不是只写动作。

推荐写法:

请写一篇中文和英文双语博客文章,并将中文版本转换为微信公众号草稿。
最终需要完成:
1. Hugo 博客中文文章和英文文章。
2. 多张插图,图片放入指定静态资源目录。
3. 微信公众号专用 Markdown 和 HTML。
4. 本地浏览器预览检查。
5. 微信公众号草稿箱创建。
6. 博客发布后访问线上地址验证。
7. Git 仓库提交并推送。

这段话把“最终完成”定义得很具体。Agent 在执行时就不会停在 Markdown 阶段。

4.2 输入素材

输入素材包括主题、参考提示词、代码片段、已有文章风格、仓库路径、发布脚本、作者名等。

但这里要特别注意:如果素材里包含密钥、内网地址、真实主机名,提示词要同时要求 Agent 去敏。

推荐写法:

可以参考我提供的提示词结构,但文章中必须去掉所有敏感信息。
不要出现真实 AppID、AppSecret、token、cookie、内网 IP、跳板机 IP、仓库私有地址、用户名、主机名或个人目录。
所有配置都用 <WECHAT_APPID>、<WECHAT_APPSECRET>、<PUBLIC_EGRESS_IP>、<BLOG_REPO_PATH> 这类占位符表示。

这比简单说“注意隐私”更有效,因为它列出了具体禁止项,也给了替代表达。

4.3 写作风格

如果你希望文章和之前博客风格一致,就要让 Agent 先看已有文章。不要直接让它凭空模仿。

可以写:

请先检查最近几篇博客的结构和风格,再写新文章。
文章需要结论先行、章节清晰、技术步骤具体、失败场景有恢复方案,不要写成营销文。
中文不少于 5000 字,英文提供完整镜像文章。

这里的“结论先行”“失败场景有恢复方案”会直接影响文章质量。很多自动生成文章的问题不是语言不通,而是没有操作密度。

4.4 图片要求

图片要求要写到数量、风格、位置和用途。

例如:

需要多张插图:
1. 需要 1 张全文概要图,手绘风格,总结文章主线。
2. 其他图片放在白名单调用、Agent 闭环、预览检查等位置。
3. 图片不能包含敏感信息。
4. 博客图片放在 static/post-images/<slug>/。
5. 微信版本如果不适合使用 SVG,需要转换为 PNG。

这样 Agent 才会把图片当成正文的一部分,而不是最后随便补一张装饰图。

4.5 转换与预览

微信公众号 HTML 的转换和预览必须写得很硬。

请使用 scripts/convert_knb_wechat.py 将微信 Markdown 转换为 HTML。
转换后尝试用本地浏览器渲染 HTML,并检查以下问题:
1. 是否存在纯白色文字显示在纯白背景上。
2. 是否存在多余可见空格导致正文奇怪缩进。
3. 标题、子标题、导读样式是否仍然存在。
4. 图片是否能正常显示。
5. 代码块是否可读。
如果发现问题,请修复 Markdown 或 HTML 后重新检查。

这段提示词的关键是“发现问题后重新检查”。没有这句话,Agent 很可能只报告问题而不修复。

Agent 执行提示词时应该形成上下文、执行、验证、修复的闭环

图 3:好的提示词会让 Agent 形成闭环,而不是写完正文就停。

4.6 API 调用顺序

微信公众号 API 有白名单限制,所以提示词要明确网络顺序。

请先在本地直接访问微信开发者平台接口。
如果本地直连失败,并且错误与 IP 白名单或网络出口有关,再通过固定 IP Linux 机器间接调用。
不要把跳板机地址、内网 IP 或密钥写入文章正文。

“先直连,再中转”看起来是小事,但它能节省大量排障时间。因为直连失败可能是 DNS、代理、证书、白名单、密钥错误、接口参数错误,每一种处理方法都不一样。

4.7 验收标准

最后一定要写验收标准。

完成后请报告:
1. 新增或修改了哪些文件。
2. 中文和英文文章字数或长度检查结果。
3. HTML 预览检查结果。
4. 白字白底扫描结果。
5. 多余空格扫描结果。
6. 微信草稿 media_id。
7. 线上博客中文和英文 URL 的 HTTP 状态。
8. Git commit 和 push 结果。

这会让 Agent 从一开始就知道最终需要拿证据说话,而不是用“已完成”三个字结束。

5. 一段可直接复用的完整提示词模板

下面是一段可以改造后直接使用的提示词模板。请把所有尖括号占位符替换成你自己的环境信息,并确认不要把真实密钥写进公开对话或公开仓库。

请帮我写一篇博客文章,并把中文版本发布到微信公众号草稿箱。

主题:
<ARTICLE_TOPIC>

写作要求:
1. 参考当前博客最近几篇技术文章的风格。
2. 中文不少于 <MIN_CHINESE_LENGTH> 字。
3. 需要英文镜像文章。
4. 结论先行,章节和子章节清晰,包含操作步骤、失败恢复、安全注意事项。
5. 不要出现任何敏感信息。真实密钥、token、cookie、内网 IP、跳板机地址、私有仓库地址、用户名、主机名、个人目录都必须去掉,用占位符代替。

配图要求:
1. 至少 <IMAGE_COUNT> 张插图。
2. 第 1 张是全文概要图,手绘风格,帮助读者理解全貌。
3. 其他图片放在关键概念附近。
4. 图片放到 static/post-images/<SLUG>/。

博客发布要求:
1. Hugo 中文文章:content/post/<SLUG>.md。
2. Hugo 英文文章:content/post/<SLUG>.en.md。
3. 执行发布脚本。
4. 发布后访问线上中文和英文 URL,确认 HTTP 200 且页面包含文章标题。
5. 最后提交并推送 Git 仓库。

微信公众号要求:
1. 作者填写 <WECHAT_AUTHOR>。
2. 使用 scripts/convert_knb_wechat.py 将微信 Markdown 转换为 HTML。
3. 转换后使用本地浏览器预览 HTML。
4. 检查并修复纯白文字、异常缩进、多余可见空格、图片裂图、标题层级丢失、代码块不可读等问题。
5. 从环境变量 WECHAT_APPID 和 WECHAT_APPSECRET 读取公众号配置,不要把密钥写入文件。
6. 先从本地直连微信 API。如果失败且与白名单或网络出口有关,再通过固定公网 IP Linux 机器 <PUBLIC_EGRESS_HOST> 间接调用。
7. 创建草稿后输出 draft media_id。

验收输出:
请列出文件路径、预览检查结果、白字白底扫描结果、空格检查结果、草稿 media_id、线上 URL、Git commit 和 push 结果。

这段模板的重点不是语气,而是边界。它把 Agent 需要做的事情分成了写作、配图、博客、公众号、网络、验证六个层面。你可以把它交给 OpenClaw、HermesAgent、Codex、Claude、Gemini、OpenCode、Droid 等任意 Agent,再根据每个工具的权限和运行环境微调。

6. 自动化脚本应该如何组织

文章发布自动化不一定要写成一个巨大的脚本。更稳的做法是拆成几个小工具:

  1. build_wechat_<slug>.py:从博客 Markdown 生成微信 Markdown,调整标题层级、摘要、图片路径。
  2. convert_knb_wechat.py:调用 Markdown 到公众号 HTML 转换器。
  3. publish_wechat_draft.py:上传图片、上传封面、创建或更新草稿。
  4. deploy_github_pages.sh:构建并发布 Hugo 博客。
  5. validate_wechat_html.py:扫描 HTML 中的白字白底、异常空格、本地路径和敏感信息。

这种拆分对 Agent 也更友好。因为每个脚本职责清楚,失败时容易定位。例如转换失败就看转换器,草稿失败就看微信 API,线上 404 就看 Hugo 发布和文章日期。

6.1 发布草稿脚本的最小逻辑

发布草稿脚本大致需要这些函数:

def token(appid: str, secret: str) -> str:
    ...

def upload_article_image(access_token: str, image_path: Path) -> str:
    ...

def upload_cover(access_token: str, cover_path: Path) -> str:
    ...

def add_draft(access_token: str, article: dict) -> str:
    ...

然后主流程是:

清理代理环境
读取 WECHAT_APPID / WECHAT_APPSECRET
读取 HTML
上传正文图片并替换 src
上传封面图并拿到 thumb_media_id
组装 title / author / digest / content / source_url
调用 draft/add
打印 draft_media_id

注意这里的“清理代理环境”不是绝对必须,但在很多本地开发机器上很有价值。因为本地 shell 可能残留代理变量,导致请求从错误的出口走,最后误判为微信 API 不可用。

7. 本地预览和质量检查

微信公众号草稿最怕三类问题:

  1. 肉眼看不到的正文:比如白色字体落在白色背景上。
  2. 肉眼很别扭的正文:比如段首多出一串空格,代码块缩进破碎。
  3. 发布后才发现的资源问题:比如图片引用本地路径或内网地址。

所以预览检查应该同时包含静态扫描和浏览器渲染。

7.1 白字白底检查

静态扫描可以先找这些模式:

color: #fff
color: #ffffff
color: white
rgb(255, 255, 255)

但不能简单地看到 color: white 就判定失败。很多转换器会在深色标题块、渐变色块或强调样式里使用白色文字,这是正常的。真正要警惕的是白色文字所在容器也没有背景色,或者背景同样是白色。

更靠谱的提示词写法是:

请扫描 HTML 中的白色文字样式,并判断其父级或当前节点是否有非白色背景。
如果白色文字只出现在深色标题块或渐变装饰里,可以保留。
如果白色文字可能落在白色背景上,必须修复。

这能避免 Agent 把转换器生成的正常标题样式误删。

7.2 多余空格检查

公众号排版里的“多余空格”也不能一刀切。标题装饰、编号、代码块里可能需要空格;正文段落里连续很多 &nbsp; 或全角空格,就可能导致奇怪缩进。

建议检查:

正文段落中的连续 &nbsp;
正文段落开头的多个全角空格
普通段落中的连续 3 个以上空格
非代码块里的 tab 字符

修复时不要全局删除所有 &nbsp;。有些公众号转换器会用它维持标题样式,暴力删除会让章节标题变丑。更稳妥的做法是只清理正文段落,不碰标题装饰和代码块。

微信公众号 HTML 预览需要检查标题、图片、白字白底、缩进和代码块

图 4:预览检查要有明确清单,不要只凭肉眼扫一遍。

7.3 敏感信息检查

自动化发布最容易在这里翻车。因为 Agent 会读取真实路径、真实命令、真实配置,如果你不要求去敏,它可能把这些内容原样写进文章。

建议提示词里强制加入:

发布前请扫描正文、HTML、图片文字和提交 diff,确认没有真实密钥、token、cookie、内网 IP、私有仓库地址、用户名、主机名、个人目录、跳板机地址。
如果发现,请替换为占位符后再发布。

如果文章主题本身就是“如何发布公众号草稿”,那更要小心。你可以讲清楚“需要固定 IP Linux 机器”,但不需要写出你的真实机器地址。你可以讲清楚“需要 AppID 和 AppSecret”,但不需要展示真实值。

8. 失败时如何让 Agent 正确排障

提示词里最好提前写失败处理策略。否则 Agent 失败后可能会原地重试同一个命令,浪费时间。

8.1 转换器失败

如果转换器接口失败,先区分三类情况:

  1. DNS 或网络不可达。
  2. 转换器页面结构变化,无法提取 HTML。
  3. Markdown 内容触发了转换器异常。

Agent 应该先保留 Markdown,再尝试浏览器兜底转换。如果仍然失败,至少生成本地预览 HTML,不能把整条发布流程卡死在转换器上。

8.2 微信 API 失败

微信 API 失败也要分类:

  1. invalid credential:检查 AppID、AppSecret。
  2. ip not in whitelist:检查调用出口 IP 和公众号后台白名单。
  3. invalid media_id:检查封面上传流程。
  4. 图片上传失败:检查图片格式、大小和路径。
  5. 网络不可达:检查 DNS、代理、证书和固定 IP 中转机。

提示词可以写:

如果微信 API 失败,请先根据 errcode 和 errmsg 判断是密钥、白名单、素材、参数还是网络问题。不要把所有失败都归因于白名单。

这句话非常重要。很多自动化失败不是一个原因,盲目切换网络只会掩盖真正的问题。

8.3 博客发布失败

Hugo 博客发布后还要检查线上 URL。构建成功不代表页面真的可访问。常见问题包括:

  1. 文章日期在服务器当前时间之后,被 Hugo 当成未来文章。
  2. slug 写错,线上 URL 和预期不一致。
  3. 图片路径大小写不一致。
  4. 静态站点推送失败。
  5. CDN 或浏览器缓存导致看不到最新页面。

所以提示词里要写“访问线上 URL 检查 HTTP 200 和标题内容”,不能只写“运行发布脚本”。

9. 用在不同 Agent 上的微调建议

这套提示词可以用于 OpenClaw、HermesAgent、Codex、Claude、Gemini、OpenCode、Droid 等工具,但每类 Agent 的环境能力不同。

9.1 OpenClaw

OpenClaw 更适合做跨工具、跨主机、跨渠道的自动化编排。如果你的文章发布链路里同时有博客仓库、微信公众号 API、固定 IP Linux 机器、素材转换脚本和发布后验证,OpenClaw 可以把这些动作组织成一个可追踪的任务流。

9.2 HermesAgent

HermesAgent 更适合在固定运行环境里承担执行型任务,例如按既定脚本生成微信 HTML、通过白名单机器调用 API、读取草稿结果并回填状态。给 HermesAgent 的提示词要把输入、输出、失败分类和幂等行为写清楚。

9.3 Codex

Codex 更适合直接操作仓库、运行脚本、检查 diff、提交代码。给 Codex 的提示词可以更强调路径、命令、验收项和不要泄露隐私。它可以把写作、文件落盘、脚本执行和验证串起来。

9.4 Claude

Claude 在长文结构、解释逻辑和语言润色上通常表现很好。如果使用 Claude 做内容生产,可以先让它生成文章骨架和正文,再交给能操作环境的 Agent 做转换和发布。

9.5 Gemini

Gemini 适合做多模态理解和长上下文整理。如果你有大量素材、截图、历史文章,可以让它先归纳风格和要点,再输出给执行 Agent。

9.6 OpenCode

OpenCode 更像本地代码执行助手,适合在已有脚本和仓库结构中跑流程。给 OpenCode 的提示词要更具体:哪些脚本、哪些路径、哪些命令、哪些检查项。

9.7 Droid

如果 Droid 运行在移动设备或受限环境里,就不要让它承担完整 API 发布流程。可以让它负责草稿内容整理、标题备选、摘要和人工检查清单,再把最终发布交给固定 IP Linux 机器或桌面环境。

10. 最后总结:把“写文章”升级成“发布系统”

如果只把 Agent 当成写作工具,你会得到一篇文章。如果把提示词写成操作合同,你会得到一条发布流水线。

这条流水线最重要的不是某个具体模型,而是几条原则:

  1. 目标明确:最终产物必须包括博客、微信 HTML、草稿、线上验证和 Git 推送。
  2. 边界明确:密钥、内网、私有路径必须去敏。
  3. 网络明确:先本地直连,失败后再使用固定 IP Linux 中转。
  4. 转换明确:Markdown 要走公众号 HTML 转换器,转换后还要预览。
  5. 检查明确:白字白底、异常空格、图片、代码块、标题层级都要查。
  6. 证据明确:完成后要给 URL、media_id、检查结果和 commit。

写提示词时,不要只描述你想要的结果,也要描述 Agent 应该如何证明它已经完成。自动化发布的可靠性,往往不是来自“模型更聪明”,而是来自你把流程、约束和验收写得足够清楚。

当提示词把这些内容都说清楚之后,OpenClaw、HermesAgent、Codex、Claude、Gemini、OpenCode、Droid 这类 Agent 就不再只是帮你写一段文字,而是可以成为一个真正的发布助手:它知道要写什么、放哪里、如何转换、怎么检查、失败时怎么换路径、最后如何把结果交付到博客和微信公众号草稿箱。