AutoGPT Platform AgentMail Drafts 块解析:草稿邮件的创建、人审、排程与全生命周期管理
本文以 AutoGPT Platform 仓库中的 Agent Mail Drafts 集成文档 为主体,结合 drafts.py 块实现 与 _config.py 共享配置,完整讲解 AgentMail 的 7 个草稿块:如何在 AutoGPT 工作流中创建草稿、读取草稿、按收件箱/组织两个层级列出草稿、更新草稿内容或改期、发送草稿以及删除(即取消排程)草稿。读完本文,你可以理解每个块的输入/输出契约、send_at 定时发送与 labels=['scheduled'] 过滤机制,以及 AgentMail 凭据是如何统一接入块框架的。
为什么需要草稿块
AgentMail 为 AI 代理提供可编程邮箱(Inbox),而 Draft(草稿)是一种未发送的消息状态:它可以被审查、编辑、改期,直到明确发送。源码文件头注释对此有明确定位(drafts.py):
A Draft is an unsent message that can be reviewed, edited, and sent later. Drafts enable human-in-the-loop review, scheduled sending (via send_at), and complex multi-step email composition workflows.
文档给出的三类核心场景在整篇文档中被反复印证:
- Human-in-the-Loop Review — 代理先生成草稿,人类审查批准后再发送;
- Scheduled Outreach — 设置
send_at让邮件在未来某个时刻自动投递; - Multi-Step Composition — 先创建草稿,再由后续工作流步骤用 Update Draft 块逐步完善收件人或正文。
凭据与客户端:所有 Drafts 块的共同前提
7 个块都依赖同一个凭据字段和客户端构造逻辑,这由 agent_mail/_config.py 统一管理:
- 通过
ProviderBuilder("agent_mail")声明 API Key 凭据,密钥名为AGENTMAIL_API_KEY,描述为 "AgentMail API Key",凭据在 AutoGPT 凭据中心配置后即可被各块复用; _client(credentials)用密钥值构造AsyncAgentMail(api_key=...)异步客户端(第 37–39 行),所有块的create/get/list/update/send/delete静态方法都是先调用_client,再调用 AgentMail SDK 对应资源;- 从
_config.py的注释可以推断出计费策略:AgentMail 处于 beta 阶段且尚未公布公开计价,with_base_cost(1, BlockCostType.RUN)设置每次运行 1 credit 的保守保底费用,以避免不计费漏洞,待 AgentMail 公布用量计价后再调整。
值得注意的两个源码细节:
is_sensitive_action=True— Send Draft 和 Delete Draft 两个块被标记为敏感操作(第 486 行、第 564 行)。可以推断,这类"造成外部副作用或不可逆删除"的块在平台侧会走更严格的执行/审批流程,与文档中"草稿用于人审"的定位一致。- 测试内建 — 每个块都携带
test_credentials、test_input、test_output与test_mock(例如 Create Draft 的 mock 在第 102–112 行),块框架可用 mock 客户端离线验证输出契约,无需真实 API Key。
Agent Mail Create Draft:创建草稿并可选排程
功能与原理
创建一封供审查或定时发送的草稿邮件。源码调用 client.inboxes.drafts.create(inbox_id, **params)(drafts.py 第 116–118 行)。至少必须提供收件人列表;主题、纯文本正文、HTML 正文、cc、bcc、in_reply_to 均为可选。
从源码结构看(第 120–147 行),块采用真值过滤组装请求参数:只有非空的 subject/text/html/cc/bcc/in_reply_to/send_at 才会进入 params,空值字段不传给 API。这意味着"留空"等价于"不设置",与 Update 块中用 None 区分"保留"与"清空"的语义不同(后文详述)。
两个关键行为:
- 若提供
send_at,草稿被排程为自动投递,返回的send_status为scheduled; - 若省略
send_at,草稿保持未发送状态,直到你用 Send Draft 块显式发送。
输入
| Input | 说明 | 类型 | 必填 |
|---|---|---|---|
| credentials | AgentMail API Key(来自 https://console.agentmail.to,凭据中心配置) | APIKey | 是 |
| inbox_id | 创建草稿所在收件箱的 ID 或邮箱地址 | str | 是 |
| to | 收件人邮箱列表(如 ['user@example.com']) |
List[str] | 是 |
| subject | 邮件主题行 | str | 否(默认空) |
| text | 纯文本正文 | str | 否(默认空) |
| html | HTML 富文本正文(高级项) | str | 否(默认空) |
| cc | 抄送收件人列表(高级项) | List[str] | 否(默认空列表) |
| bcc | 密送收件人列表(高级项) | List[str] | 否(默认空列表) |
| in_reply_to | 本草稿所回复的消息 ID,用于跟进邮件的线程关联(高级项) | str | 否(默认空) |
| send_at | 定时自动发送的 ISO 8601 时间(如 '2025-01-15T09:00:00Z'),留空则为手动发送(高级项) |
str | 否(默认空) |
输出
| Output | 说明 | 类型 |
|---|---|---|
| error | 操作失败时的错误信息 | str |
| draft_id | 创建草稿的唯一标识 | str |
| send_status | 设置了 send_at 时为 scheduled,否则为空。取值:scheduled / sending / failed |
str |
| result | 含全部元数据的完整草稿对象 | Dict[str, Any] |
典型用例
- Human-in-the-Loop Review — 创建草稿供人类在发送前审查批准;
- Scheduled Outreach — 用
send_at排队一封未来日期时间自动投递的跟进邮件; - Multi-Step Composition — 先创建含初始内容的草稿,后续步骤用 Update Draft 块完善收件人或正文。
Agent Mail Get Draft:读取单个草稿
功能与原理
按 ID 获取单个草稿以审查其内容、收件人与排程发送状态。源码调用 client.inboxes.drafts.get(inbox_id, draft_id)(第 216–218 行),返回草稿的主题、发送状态、计划发送时间及完整草稿对象。块输出时对 subject、send_status、send_at 均做了 or "" 空值归一化(第 229–233 行),保证下游块拿到的是稳定的空字符串而非 None。
输入
| Input | 说明 | 类型 | 必填 |
|---|---|---|---|
| credentials | AgentMail API Key | APIKey | 是 |
| inbox_id | 草稿所属收件箱的 ID 或邮箱地址 | str | 是 |
| draft_id | 要获取的草稿 ID | str | 是 |
输出
| Output | 说明 | 类型 |
|---|---|---|
| error | 操作失败时的错误信息 | str |
| draft_id | 草稿唯一标识 | str |
| subject | 草稿主题行 | str |
| send_status | 排程发送状态:scheduled / sending / failed 或空 |
str |
| send_at | 若设置了排程,则为 ISO 8601 发送时间 | str |
| result | 含全部字段的完整草稿对象 | Dict[str, Any] |
典型用例
- Approval Gate — 取回草稿让人类审查员在批准发送前检查内容与收件人;
- Schedule Monitoring — 取回已排程草稿,检查
send_status确认其仍排队待发; - Content Verification — 创建或更新草稿后回读,验证主题与正文符合预期再进入下一步。
Agent Mail List Drafts:列出单个收件箱的草稿
功能与原理
列出某收件箱中的草稿。源码调用 client.inboxes.drafts.list(inbox_id, **params)(第 311–313 行)。可用 limit 控制每页大小、page_token 翻页、labels 过滤(例如 ['scheduled'] 只取排队中的发送)。输出把每个草稿对象 model_dump() 成字典列表(第 328 行),并返回当前页草稿计数与 next_page_token。
从源码结构看,limit 有默认值 20(第 253–257 行),且描述标注取值范围为 1–100;page_token 与 labels 非空时才会附加到请求参数。
输入
| Input | 说明 | 类型 | 必填 |
|---|---|---|---|
| credentials | AgentMail API Key | APIKey | 是 |
| inbox_id | 列出草稿的收件箱 ID 或邮箱地址 | str | 是 |
| limit | 每页最大草稿数(1–100,默认 20,高级项) | int | 否 |
| page_token | 上一页响应中的翻页 token(高级项) | str | 否 |
| labels | 按标签过滤草稿(如 ['scheduled'] 取排队发送,高级项) |
List[str] | 否 |
输出
| Output | 说明 | 类型 |
|---|---|---|
| error | 操作失败时的错误信息 | str |
| drafts | 草稿对象列表(含 subject、recipients、send_status 等) | List[Dict[str, Any]] |
| count | 本页返回的草稿数 | int |
| next_page_token | 下一页 token,无更多结果时为空 | str |
典型用例
- Inbox Dashboard — 列出收件箱全部草稿,展示待审查/待批准的邮件队列;
- Scheduled Send Audit — 用
labels=['scheduled']过滤,核对所有排队投递草稿的发送时间; - Batch Processing — 翻页遍历收件箱全部草稿,执行批量更新或删除清理。
Agent Mail List Org Drafts:跨组织列出全部草稿
功能与原理
与 List Drafts 不同,此块在组织层级调用 client.drafts.list(**params)(第 659–661 行),一次查询返回组织内所有收件箱的草稿,因此不需要 inbox_id。同样支持 limit(默认 20)与 page_token 翻页。源码 docstring 指出其设计目标是"central approval dashboard"——让一个人类监督者审查并批准任意代理创建的草稿。
输入
| Input | 说明 | 类型 | 必填 |
|---|---|---|---|
| credentials | AgentMail API Key | APIKey | 是 |
| limit | 每页最大草稿数(1–100,默认 20,高级项) | int | 否 |
| page_token | 上一页响应中的翻页 token(高级项) | str | 否 |
输出
| Output | 说明 | 类型 |
|---|---|---|
| error | 操作失败时的错误信息 | str |
| drafts | 组织内所有收件箱的草稿对象列表 | List[Dict[str, Any]] |
| count | 本页返回的草稿数 | int |
| next_page_token | 下一页 token,无更多结果时为空 | str |
典型用例
- Central Approval Dashboard — 一次列出所有收件箱的待发草稿,让管理者在一处审查批准出站邮件;
- Organization-Wide Analytics — 统计并归类各收件箱草稿,报告邮件管线吞吐量与瓶颈;
- Stale Draft Cleanup — 翻页遍历组织全部草稿,识别并删除从未发送的过期草稿。
Agent Mail Update Draft:更新内容、收件人或改期
功能与原理
更新草稿的内容、收件人或排程发送时间。源码调用 client.inboxes.drafts.update(inbox_id, draft_id, **params)(第 415–421 行)。文档特别强调其字段语义:只提供会修改的字段,省略的字段保持不变。
这一点在源码中体现得非常精确(第 427–437 行):所有可选输入都声明为 Optional[...] 且默认 None,块内用 is not None 判断是否发送该字段:
if input_data.to is not None:
params["to"] = input_data.to
if input_data.subject is not None:
params["subject"] = input_data.subject
# ... text / html / send_at 同理
因此 None 表示"保留当前值"。这与 Create 块的"空字符串不传"策略形成对照:Create 时字段不存在于草稿,用真值过滤即可;Update 时字段已有值,必须用 None 区分"省略"与"清空"。文档原文对此的表述是:None is used to distinguish between "omit this field" and "clear this field to empty"。
另外,块 docstring 明确提示:取消排程应使用 Delete 块("To cancel a scheduled send, delete the draft instead"),Update 只负责改期或编辑。
输入
| Input | 说明 | 类型 | 必填 |
|---|---|---|---|
| credentials | AgentMail API Key | APIKey | 是 |
| inbox_id | 草稿所属收件箱的 ID 或邮箱地址 | str | 是 |
| draft_id | 要更新的草稿 ID | str | 是 |
| to | 新的收件人列表(整体替换原列表)。省略保留当前值 | List[str] | 否 |
| subject | 新的主题行。省略保留当前值 | str | 否 |
| text | 新的纯文本正文。省略保留当前值 | str | 否 |
| html | 新的 HTML 正文(高级项)。省略保留当前值 | str | 否 |
| send_at | 改期:新的 ISO 8601 发送时间(如 '2025-01-20T14:00:00Z',高级项)。省略保留当前值 |
str | 否 |
输出
| Output | 说明 | 类型 |
|---|---|---|
| error | 操作失败时的错误信息 | str |
| draft_id | 更新后的草稿 ID | str |
| send_status | 更新后的发送状态 | str |
| result | 完整的更新后草稿对象 | Dict[str, Any] |
典型用例
- Reschedule Delivery — 修改已排程草稿的
send_at,推迟或提前其投递窗口; - Reviewer Edits — 允许审查者在批准发送前修改草稿的主题或正文;
- Dynamic Recipient Updates — 根据前序步骤采集的数据更新收件人列表,无需重建草稿。
Agent Mail Send Draft:立即发送并转为消息
功能与原理
立即发送草稿,使其成为已投递消息。源码调用 client.inboxes.drafts.send(inbox_id, draft_id)(第 512–514 行)。发送完成后,草稿从收件箱中删除,取而代之返回一个 message 对象;块输出新邮件的 message_id 与 thread_id 以及完整消息结果。
此块注册时带有 is_sensitive_action=True(第 486 行),呼应"发送即产生外部副作用"的风险属性。源码 docstring 给出的标准人审流程是:agent creates draft, human reviews, then this block sends it(第 456–457 行)。
输入
| Input | 说明 | 类型 | 必填 |
|---|---|---|---|
| credentials | AgentMail API Key | APIKey | 是 |
| inbox_id | 草稿所属收件箱的 ID 或邮箱地址 | str | 是 |
| draft_id | 现在要发送的草稿 ID | str | 是 |
输出
| Output | 说明 | 类型 |
|---|---|---|
| error | 操作失败时的错误信息 | str |
| message_id | 已发送邮件的消息 ID(草稿已删除) | str |
| thread_id | 已发送消息所属的线程 ID | str |
| result | 完整的已发送消息对象 | Dict[str, Any] |
典型用例
- Post-Approval Dispatch — 在审查工作流中人类批准后立即发送草稿;
- On-Demand Notifications — 工作流前段生成草稿,仅当触发事件发生时才发送;
- Retry After Edit — 更新校验失败的草稿后重新发送,而无需从头重建。
Agent Mail Delete Draft:删除草稿或取消排程
功能与原理
永久删除草稿,或取消一次排程邮件。源码调用 client.inboxes.drafts.delete(inbox_id, draft_id)(第 578–582 行)。若草稿已设置 send_at 等待未来投递,删除即取消该排程发送——这是取消定时邮件的官方途径。成功后块 yield "success", True;与 Send 块相同,此块也标记 is_sensitive_action=True(第 564 行),且测试 mock 中 delete_draft 返回 None(第 572–574 行),印证了 API 删除操作无返回体的特性。
输入
| Input | 说明 | 类型 | 必填 |
|---|---|---|---|
| credentials | AgentMail API Key | APIKey | 是 |
| inbox_id | 草稿所属收件箱的 ID 或邮箱地址 | str | 是 |
| draft_id | 要删除的草稿 ID(同时取消其排程发送) | str | 是 |
输出
| Output | 说明 | 类型 |
|---|---|---|
| error | 操作失败时的错误信息 | str |
| success | 草稿成功删除/取消时为 True | bool |
典型用例
- Cancel Scheduled Send — 删除设置了
send_at的草稿,阻止其投递; - Clean Up Rejected Drafts — 在审批工作流中移除人类审查员驳回的草稿;
- Abort Workflow — 上游条件变化、邮件不再需要时,删除进行中的草稿。
组合成完整工作流:从文档用例到块链路
把 7 个块串起来,可以覆盖文档中反复出现的三类场景:
- 人审发送链:
Create Draft(无send_at)→Get Draft(审查内容/收件人)→ 审查者不满意则Update Draft(改主题/正文/收件人)→ 通过则Send Draft获得message_id;被驳回则Delete Draft清理。 - 排程管理链:
Create Draft(设send_at,返回send_status=scheduled)→List Drafts(labels=['scheduled']审计所有排队项)→Update Draft(改期)或Delete Draft(取消排程)。 - 组织级审批看板:
List Org Drafts(无需inbox_id,跨收件箱翻页)→ 对目标草稿执行Get Draft/Update Draft/Send Draft/Delete Draft,全部草稿操作均回落到具体收件箱维度。
所有块共享统一的错误契约:任何 API 异常都被捕获并 yield "error", str(e),与文档所述"errors propagate to the block framework's global error handler, which yields them on the error output"一致。在 AutoGPT 画布中,你可以把 error 输出接到条件分支,实现失败重试或人工兜底。
适用前提与参考文件
- 使用这些块的前提是已在 AutoGPT 凭据中心配置
AGENTMAIL_API_KEY(见 agent_mail/_config.py),并从 AgentMail 控制台获取密钥; send_at与send_at输出均使用 ISO 8601 格式(如'2025-01-15T09:00:00Z');limit取值 1–100,默认 20;- 相关文档与源码索引:
- 文档主体:agent_mail/drafts.md
- 块实现:blocks/agent_mail/drafts.py
- 共享凭据与客户端配置:blocks/agent_mail/_config.py
- 同族集成文档(Inbox 是 Drafts 的上游实体,可配合阅读):agent_mail/inbox.md、agent_mail/messages.md、agent_mail/threads.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 StartedRust0624
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