AutoGPT 平台 Publish to Medium 发布块:源码级解读与自动化发文实战指南
本篇技术指南围绕 AutoGPT 平台中的 Publish to Medium(发布到 Medium) 块展开。它面向需要在自动化工作流中把博客文章一键发布到 Medium 的开发者与内容运营团队,从块的能力定位、9 个输入参数与 4 个输出字段的逐一解析,到其底层的 Medium API 调用实现与错误处理机制,再到可运行的图文编排方案,读完即可在自己的 Agent 流程中直接配置和使用该发布块。文中所有参数、接口与默认值均以当前仓库的源码与文档为准,并提供对应源码路径供进一步追溯。
一、Publish to Medium 块是什么
根据官方文档 medium.md 的定义,Publish to Medium 块是 AutoGPT 平台内置的社交发布类块,其能力是:接收一篇已经格式化完成的博客文章及其元数据,调用 Medium 官方 API 直接发布到 Medium 平台,发布过程涉及的标题、正文、标签、可见性、版权许可等细节均由块内部统一处理。
在平台内部,该块在另一份汇总文档 misc.md 的 “Publish To Medium” 一节中也有同源描述,说明它支持以 HTML 或 Markdown 提供正文,并可配置标题、标签与发布选项。两份文档共同构成该块的官方说明骨架,本文则以仓库中的实际实现代码为准对其逐项校验与深化。
从代码结构看,该块的真实类名为 PublishToMediumBlock,完整实现位于 medium.py,并带有固定的块 ID 3f7b2dcb-4a78-4e3f-b0f1-88132e1b89df。块的创建代码如下:
super().__init__(
id="3f7b2dcb-4a78-4e3f-b0f1-88132e1b89df",
input_schema=PublishToMediumBlock.Input,
output_schema=PublishToMediumBlock.Output,
description="Publishes a post to Medium.",
categories={BlockCategory.SOCIAL},
...
)
在 blocks/_base.py 中,BlockCategory.SOCIAL 被定义为 “Block that interacts with social media platforms.”,即社交媒体交互类块;与它同属社交范畴的还有本仓库中的 Twitter、Discord、Reddit 等相关块。这意味着你可以在流程中把它与其他社交分发块并行使用,实现“一文多平台”的矩阵分发。
二、工作流程概览:从认证到返回发布结果
结合源码 medium.py 的 create_post 与 run 方法,发布过程分为五个阶段:
- 认证:块使用用户提供的 Medium API Key 与作者 Author ID 进行身份识别。API Key 被放入请求头
Authorization: Bearer <api_key>。 - 构造请求体:把标题、正文、正文格式、标签、canonical 链接、发布状态、版权许可、是否通知粉丝等字段组装成一个 JSON payload。
- 发送请求:向 Medium REST API 的创建文章端点发起 POST 请求。
- 解析响应:发布成功后从响应中取出文章 ID(
id)、公开访问 URL(url)与发布时间戳(publishedAt)。 - 失败兜底:若响应中不含
data字段,则读取错误信息并抛出运行时异常。
请求的真实发送依赖平台封装的异步 HTTP 客户端 Requests(见 util/request.py 中的 Requests.post),最终请求目标为 Medium 官方端点:
POST https://api.medium.com/v1/users/{author_id}/posts
这正是 Medium API 中“为指定作者创建文章”的标准接口形态,仓库内代码与文档描述完全一致。
三、输入参数详解
官方文档 medium.md 给出了以下输入清单,下表结合源码补齐了字段类型、必填性、默认值与取值范围:
| 输入 | 说明(来自官方文档) | 类型 / 必填 / 默认值(来自源码) |
|---|---|---|
| Author ID | Medium 作者账号的唯一标识 | str(以 BlockSecret 密文形式存储),必填 |
| Title | 文章标题 | str,必填 |
| Content | 文章正文(HTML 或 Markdown 格式) | str,必填 |
| Content Format | 正文格式,取值为 html 或 markdown |
str,必填 |
| Tags | 用于文章分类的主题标签,最多 5 个 | List[str],必填;占位示例 ['technology', 'AI', 'blogging'] |
| Canonical URL | 若内容首发于别处,在此填写原始出处 URL | str 或 None,可选,默认 None |
| Publish Status | 文章可见性:public、draft、unlisted |
枚举 PublishToMediumStatus,必填;占位示例为 draft |
| License | 文章版权许可,默认 all-rights-reserved |
str,可选,默认 all-rights-reserved |
| Notify Followers | 是否通知作者粉丝新文章已发布 | bool,可选,默认 False |
| API Key | 用于认证的 Medium API 密钥 | 凭据(Credentials)字段,属于 Medium 集成 |
几个值得注意的细节:
- Author ID 以密文存储。源码中该字段被声明为
BlockSecret = SecretField(key="medium_author_id", ...),说明平台在持久化与展示时会对作者 ID 做与密钥同等密级的保护,避免在画布节点中明文暴露。 - Publish Status 是三值枚举。代码定义了
PublishToMediumStatus(str, Enum),取值严格限定为public/draft/unlisted三者之一(见 medium.py),比自由文本输入更不易出错,也对应 Medium 的发布状态语义:公开、草稿、非公开链接。 - License 有明确的 9 个合法值。源码描述字段写明:
all-rights-reserved、cc-40-by、cc-40-by-sa、cc-40-by-nd、cc-40-by-nc、cc-40-by-nc-nd、cc-40-by-nc-sa、cc-40-zero、public-domain。默认all-rights-reserved表示保留所有权利,其余值分别对应 CC BY 4.0 系列协议(署名、相同方式共享、禁止演绎、非商业等组合)以及 CC0 与公有领域声明。若你的文章在 GitHub 等仓库中已使用开源许可,可在此显式指定对应 CC 协议以保持一致。
关于必填性可参考 misc.md 中同一块的说明表:title、content、content_format、tags、publish_status 为必填,author_id、canonical_url、license、notify_followers 均可选;从源码看 license 与 notify_followers 有默认值,canonical_url 允许为空。
四、输出解析
发布完成后,块会向下游节点输出以下四个字段:
| 输出 | 说明 |
|---|---|
| Post ID | Medium 分配给已发布文章的唯一 ID |
| Post URL | 文章的公开访问地址 |
| Published At | 文章发布的时间戳(整型 Unix 时间戳) |
| Error | 发布失败时的错误信息 |
从实现看,成功分支按序产出三个值:
if "data" in response:
yield "post_id", response["data"]["id"]
yield "post_url", response["data"]["url"]
yield "published_at", response["data"]["publishedAt"]
其中 published_at 在输出 Schema 中被声明为 int 类型(见 medium.py),对应 Medium 返回的 Unix 秒级时间戳,若下游需要人类可读时间,建议在后续块中自行转换。error 输出只在流程节点因异常失败时体现——代码中对失败的处理并非通过 yield 返回错误字符串,而是解析错误响应并抛出异常:
error_message = response.get("errors", [{}])[0].get("message", "Unknown error occurred")
raise RuntimeError(f"Failed to create Medium post: {error_message}")
因此在实际使用中,可把该块的错误视为“流程失败信号”,在编排层通过错误分支或重试机制处理,而不要指望 error 作为成功路径下的常规数据流。这也是源码对文档“Error 输出字段”最精确的补充说明。
五、前置准备:获取 API Key 与 Author ID
该块的认证依赖两样东西:Medium 的集成凭据(API Key) 与 作者 Author ID。
- API Key:在源码中,块的
credentials字段通过CredentialsMetaInput[Literal[ProviderName.MEDIUM], Literal["api_key"]]声明,即认证方式为 API Key 类型;ProviderName.MEDIUM在 integrations/providers.py 中被定义为枚举值"medium"。实际运行时,run方法从credentials.api_key取用密钥,并写入请求头。平台会以APIKeyCredentials形式持有该凭据,例如块内置测试中使用的APIKeyCredentials(provider="medium", api_key=SecretStr("mock-medium-api-key"), ...)。使用前需在平台的凭据 / 集成管理界面为 Medium 添加一个具有发布权限的 API Key,然后在块的凭据下拉框中选择它。 - Author ID:作者 ID 需要调用 Medium API 的
/me端点获取。源码字段描述中直接给出了获取命令,这是仓库提供的权威方法:
curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" https://api.medium.com/v1/me
响应中的 authorId 字段即为所需值,把它填入块的 Author ID 输入。需要说明的是,虽然源码将 Author ID 定义为块级 Secret 输入,但其语义上更接近“账号定位信息”,与 API Key 一并构成请求端点 https://api.medium.com/v1/users/{author_id}/posts 的两个关键参数。
六、正文格式、标签与内容格式化的最佳实践
发布块的 Content Format 直接决定了正文如何被 Medium 渲染。源码 create_post 方法会把该字段原样映射为 API 请求体中的 contentFormat 键:
data = {
"title": title,
"content": content,
"contentFormat": content_format,
"tags": tags,
"canonicalUrl": canonical_url,
"publishStatus": publish_status,
"license": license,
"notifyFollowers": notify_followers,
}
因此实操时需注意:
- HTML 与 Markdown 二选一。
content与content_format必须配对一致。例如填 HTML 正文时就应把content_format设为html。 - Tags 是列表而非字符串。块 Schema 中
tags声明为List[str](文档表写作逗号分隔),平台画布上一般以列表形式输入;Medium 限制最多 5 个标签,超出部分将由 Medium 侧裁剪或报错,建议在流程上游用列表块控制标签数量。 - Canonical URL 用于跨平台首发声明。如果这篇文章先在自有博客、Newsletter 或 GitHub Pages 发布,把原始链接填入
canonical_url,Medium 就会把这篇转载标注为二次分发,避免与原创链接产生 SEO 冲突。 - 字段映射的命名差异。所有请求体键均为 Medium API 的驼峰命名(
contentFormat、canonicalUrl、publishStatus、notifyFollowers),与平台画布上的 snake_case 输入(content_format、canonical_url、publish_status、notify_followers)一一对应,这正是块在底层做的一次“画布语义 → 上游 API 契约”的转换。
七、典型应用场景与流程编排建议
官方文档 medium.md 给出的典型场景是:数字营销团队将发布块接入内容管理系统,在自有系统完成创作与审批后自动把内容发布到 Medium,实现跨平台、无人工干预的定时分发。misc.md 进一步补充了三类可落地的用例:
- 内容聚合分发(Content Syndication):自动把博客文章或 Newsletter 发布到 Medium,触达更大读者群;
- AI 内容发布(AI Content Publishing):让 LLM 块先生成文章,再直接发布到 Medium,形成“生成—发布”全自动链路;
- 跨平台转发(Cross-Posting):把其他平台已发布的内容转载到 Medium,并通过 Canonical URL 做来源归属。
结合仓库中的块能力(LLM、文本处理、定时等),一个完整的可编排方案可以如下构成:
- 上游内容源:接入「Read RSS Feed」监控自有博客的 RSS,或使用 LLM 块直接按选题生成草稿正文;
- 内容加工:用文本处理类块把正文统一为 HTML 或 Markdown,并把前 5 个有效标签整理成列表;
- 策略控制:把
publish_status配置为draft,先让人工在 Medium 后台审校后再手动公开;或直接使用public全自动发布,并视需求决定是否开启notify_followers; - 下游追踪:消费块的
post_id与post_url,写入数据库或发送到 Slack 通知,便于归档与数据分析。
若追求“保留所有权利”之外的开源授权,可按前文列出的 9 个 license 取值之一显式设置,保证自动发布文章的版权声明始终一致。
八、可测试性与内置示例
该块的质量保障内嵌于块定义本身。在 medium.py 中,块注册时即声明了 test_input、test_output 与 test_mock,构成一套无需真实网络即可运行的自检样例:
- test_input:一组最小合法入参,例如标题
Test Post、HTML 正文<h1>Test Content</h1><p>This is a test post.</p>、content_format=html、标签["test", "automation"]、publish_status=draft,以及一个 Mock 凭据; - test_mock:以
{"create_post": lambda ...}拦截网络调用,伪造 Medium 返回{"data": {"id": "e6f36a", "url": "https://medium.com/@username/test-post-e6f36a", "authorId": "...", "publishedAt": 1626282600}}; - test_output:断言上述入参应产出
post_id=e6f36a、对应post_url与published_at=1626282600三项输出。
这意味着块的行为契约(入参校验、输出字段名与类型)可在 CI 中反复验证;当你基于它构建“文章生成 → 发布 → 记录回执”的自定义 Agent 时,也可参考这套样例约定为自定义块补齐同样的测试数据。当前仓库未发现为该块单独编写的测试文件,其测试以块内置的自测样例形式存在。
九、总结
Publish to Medium 是 AutoGPT 平台社交发布块族中实现最直白、边界最清晰的一个:输入一篇成稿与元数据,输出文章的 ID、URL 与时间戳。从源码看,它把 Medium REST API 的 POST /v1/users/{author_id}/posts 完整封装为可视化的节点,同时妥善处理了密文凭据、三值发布状态、9 种版权许可与失败异常。无论是数字营销团队的 CMS 自动分发,还是 LLM 驱动的“AI 成文即发布”链路,该块都可以作为内容管线的末端出口稳定复用。
关键源码与文档索引:
- 块实现:autogpt_platform/backend/backend/blocks/medium.py(输入/输出 Schema、
create_post请求构造与错误处理) - 块分类定义:autogpt_platform/backend/backend/blocks/_base.py(
BlockCategory.SOCIAL) - 集成提供方枚举:autogpt_platform/backend/backend/integrations/providers.py(
ProviderName.MEDIUM) - HTTP 客户端:autogpt_platform/backend/backend/util/request.py(
Requests.post异步请求封装) - 官方块文档:docs/integrations/block-integrations/medium.md 与 docs/integrations/block-integrations/misc.md
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0627
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00