AI 智能体的撤销功能:一份用于撤销智能体已完成操作的规范草案
Undo for AI agents: a draft spec for taking back what an agent already did
我们发现了什么
方向观察:AI 智能体的撤销功能:一份用于撤销智能体已完成操作的规范草案。原文包含第三方或历史项目线索,暂不能归属于本产品,需核对完整来源。
- 来源:DEV Community(发现于 2026-11-01)
- 证据等级:D · 包含历史项目、第三方案例或未来计划;不能作为当前项目收入证据。
- 商业模式:待核验
- 主题:AI Agent
- 初筛评分:18.1/100 · 收录 1 次
证据,比故事更重要。
规则清洗与初筛,未经人工商业核验。原文语境、实际客户和付费情况仍需自行验证。
引用与数字披露
来源类型(原作者自述/第三方测算/媒体转引)需采集端标注,本版尚未落字段。
- 作者
- 未标注
- 抓取日期
- 来源类型
- 未标注
- 币种
- 未标注
- 口径
- 未标注
- 披露主体
- 未标注
- 披露日期
- 未标注
中文辅助译文(全文)
一名销售代理正在整理 Q4 商机管道。它在 CRM 中把商机 D-881 标记为 Won,与客户预订了一次启动会议,并向其买方发送了一封欢迎邮件。一小时后,你发现它选错了商机。客户尚未签署。
为清理善后,你打开三个系统,查明发生了什么,恢复商机阶段(除非有同事在此期间编辑过它),取消会议(这会通知参会者),并接受邮件已经发出的事实。
在 我上一篇文章中,我介绍了 HATP:这是一项草案协议,可让多步骤代理操作在发生之前做到全有或全无——规划、准备、获得人工签署的批准,然后提交。你对那篇文章的评论促成了 v0.2 的大部分内容,谢谢。
但大多数代理不会规划。它们一次调用一个工具,而你事后才会发现。因此,为 v0.3,我起草了另一半:the Journal,即面向代理的撤销机制。目前尚未构建任何东西。我想在开始之前听听你的意见。
缺口
| 现有机制 | 作用 | 缺失之处 |
|---|---|---|
MCP 工具注解 (destructiveHint, idempotentHint) | 向客户端提示某项工具可能具有破坏性 | 仅是提示:无法撤销任何操作 |
| Sagas 和补偿事务 | 撤销单个应用内部的各个步骤 | 没有能在代理所调用的独立工具服务器之间运作的机制 |
HATP v0.1 compensate 层级 | 当事务中途失败时撤销各个步骤 | 仅限已规划的事务内部,且只能在事务成功之前执行 |
| 代理轨迹和日志 | 显示发生了什么 | 无法收回任何东西 |
构想 1:每项操作效果都带回其撤销信息
一个 Recorder 位于代理与其工具服务器之间,通常充当 MCP 网关。代理无需作任何改动。当工具服务器支持 Journal 时,其常规工具结果会额外包含三项信息:改动了什么、用于撤销该改动的令牌,以及撤销操作在多长时间内仍然可行。
"_meta": { "hatp/journal": {
"undo": { "kind": "compensate", "undoBy": "2026-11-07T14:02:10Z" },
"compensationToken": "ctk_9QwX…",
"effect": { "summary": "商机 D-881 阶段:Proposal → Won",
"resource": "crm://acme/deal/D-881", "version": "v13" },
"receipt": { "…": "由 CRM 签名" } } }工具服务器依据实际变更而非代理生成的文本来撰写摘要,因为人稍后决定要撤销什么时会阅读它。Recorder 将每一条记录串联成一份经签名且采用哈希链的 Run Record。
即使工具服务器完全不了解 HATP,也仍会被记入 Journal。其调用会被记录为 unknown,并视为不可逆。因此,它从第一天起就能与任何 MCP 服务器配合使用,并会随着服务器加入撤销支持而不断改进。
每项操作都会预先声明自身是否可撤销:
| 操作 | 声明 | 原因 |
|---|---|---|
update_deal | compensate,7 天 | 可以恢复原先的阶段 |
create_event | compensate,30 天,副作用:“参会者会收到取消通知” | 可以撤销,但这一过程是可见的 |
refund_order | compensate,1 天,费用 $2.50 | 撤销需要付费 |
send_email | none:“已交付给外部收件人” | 无法撤回已发送的邮件 |
export_report | none:“向组织外部披露数据” | 读取操作无法收回 |
构想 2:自主权由可逆性授予
一旦每项操作都说明自身是否可撤销,你就可以不再问“这个代理是否应当被允许执行操作?”,而改问“如果它做错了,我们能把操作收回吗?”
{ "autonomy": { "compensate": "allow", "unknown": "ask", "none": "ask",
"approver": "human://acme.com/role/team-lead" } }代理可以自由执行所有可逆操作。在执行任何不可逆操作之前,Recorder 不会转发该调用:它会将其作为普通的 HATP 事务运行并获得人工批准,因此邮件只有在有人签字确认后才会发出。该政策由你的组织设定,而不是由代理设定,且代理无法更改它。
撤销是一个决策,而非按钮
撤销工作可能会破坏他人较新的编辑,或通知公司外部的人员,因此撤销操作与任何其他高风险操作一样,都需要经过批准。
你请求撤销该次运行中“从第 2 步开始及之后”的内容。然后 Recorder 会:
- 添加依赖步骤:如果第 5 步使用了第 2 步的结果,那么只撤销第 2 步会让第 5 步无所指向;
- 检查每个步骤:在不做任何更改的情况下,询问每个工具服务器撤销当前是否可行;
- 构建一个 Reversal Plan,按逆序排列,列出无法撤销的内容,并通过 Human Gateway 将其路由给人类:
撤销 sales-bot 为 Dana 执行的 2 项操作:
1. 取消 Nov 4 的“与 Globex 的启动会议”(参会者会收到取消通知)
2. 商机 D-881 阶段:Won → Proposal
无法撤销:
- 发往 buyer@globex.com 的邮件(已交付给外部收件人)- 按逆序运行各项补偿,在批准后执行,并记录结果。如果其中一项失败,它不会撤销失败步骤仍然依赖的任何内容,并会准确报告哪些内容已撤销、失败或被跳过。
对于无法撤销的内容,它会建议补救措施,例如“发送一封更正邮件”,但绝不执行。纠正措施是一项新的操作,需要重新取得同意。
绝不覆盖人类更新的工作成果
在代理作出更改与你执行撤销之间,Eve 可能已经把商机移至“Negotiation”。盲目恢复为“Proposal”会抹掉她的更改。
因此,每项补偿都携带 ifVersion:代理留下的版本(v13)。如果记录此后已发生变化,工具服务器将以 UNDO_CONFLICT 拒绝执行,并说明发生了哪些变化。随后,审批界面会显示该冲突,且只有人可以选择覆盖它。
事务提交后的撤销
HATP v0.1 仅在事务中途失败时执行补偿。有了 Journal,协调器会将已提交的事务记录为一次运行,因此同样的令牌可用于之后撤销它:“那次行程提交成功了,但选错了周次。”
它不会做什么
- 撤销读取操作。信息一旦披露就无法收回,因此,会将数据发送到组织外部的读取操作会被声明为不可逆,并受自主权政策约束。
- 重做。修复一次撤销属于一次新的运行。
- 证明工具服务器确实撤销了效果。与 HATP 中的一切一样,签名只能证明是谁声称了什么,而不能证明该声称属实。
状态
- 规范草案: spec/hatp-journal.md。该草案仅以 v0.1 为基础,并列出了它将对 v0.1 做出的每一项更改。
- 尚无代码。相关工作已规划在 v0.3 milestone 中:模式、SDK 中的 Recorder、MCP 绑定,以及一个可从浏览器审批器撤销代理某次运行部分内容的演示。
- v0.2(待完成的投票、锁和 Sessions)将优先推进。
我希望得到以下方面的反馈
- 你愿意让 MCP 服务器的工具返回
compensationToken和undoBy吗? 什么会让这件事变得困难? - 撤销会跳过
prepare。 为降低撤销机制的采用成本,工具服务器可选用check,而不必采用完整的两阶段流程;只有人类进行投票。这样是否太弱了? - 依赖关系。代理宿主通常不知道某次调用使用了先前哪个结果。目前草案假定“依赖于此前的一切”,这很安全,但会让“只撤销这一步”牵涉过多内容。Recorder 是否应根据参数值匹配来推断关联?
- 以可逆性为门槛的自主权:“对可撤销的内容自由执行,对不可撤销的内容事先询问”是否是合适的默认设置,还是过于宽松?
- 较长的撤销窗口:如果 Dana 在窗口关闭前换了职务,是否应在撤销时再次检查她的权限?
规范和 SDK:https://github.com/probita-ai/hatp。欢迎在此处发表评论,也欢迎在 GitHub 上提交 issue。
译文由上游机器翻译生成,可能有误;判断请以英文原文为准。
英文原文(来源本站未改写)
A sales agent is tidying up the Q4 pipeline. It marks deal D-881 as Won in the CRM, books a kickoff meeting with the customer, and emails their buyer a welcome note. An hour later you notice it picked the wrong deal. The customer hasn't signed.
To clean up, you open three systems, work out what changed, put back the deal stage (unless a colleague has edited it since), cancel the meeting (which tells the attendees), and accept that the email has gone.
In my last post I described HATP, a draft protocol that makes multi-step agent actions all-or-nothing before they happen: plan, prepare, get a human's signed approval, then commit. Your comments on that post shaped most of v0.2, so thank you.
But most agents don't plan. They call one tool at a time, and you find out afterwards. So for v0.3 I've drafted the other half: the Journal, undo for agents. Nothing is built yet. I'd like your opinion before we start.
The gap
| What exists | What it does | What's missing |
|---|---|---|
MCP tool annotations (destructiveHint, idempotentHint) | Tell the client a tool might be dangerous | Hints only: no way to reverse anything |
| Sagas and compensating transactions | Undo steps inside one application | Nothing that works across independent tool servers an agent calls |
HATP v0.1 compensate tier | Undoes steps when a transaction fails partway | Only inside a planned transaction, and only before it succeeds |
| Agent traces and logs | Show what happened | Can't take anything back |
Idea 1: every effect comes back with its undo
A Recorder sits between the agent and its tool servers, usually an MCP gateway. The agent needs no changes. When a tool server supports the journal, its normal tool result carries three extra things: what changed, a token to reverse it, and how long reversal stays possible.
"_meta": { "hatp/journal": {
"undo": { "kind": "compensate", "undoBy": "2026-11-07T14:02:10Z" },
"compensationToken": "ctk_9QwX…",
"effect": { "summary": "Deal D-881 stage: Proposal → Won",
"resource": "crm://acme/deal/D-881", "version": "v13" },
"receipt": { "…": "signed by the CRM" } } }The tool server writes the summary from the actual change, not from the agent's text, because a human reads it later when deciding what to undo. The Recorder chains every entry into a signed, hash-chained Run Record.
Tool servers that know nothing about HATP still get journaled. Their calls are recorded as unknown and treated as irreversible. So it works with any MCP server on day one, and gets better as servers add undo.
Each operation declares up front whether it can be undone:
| Operation | Declares | Why |
|---|---|---|
update_deal | compensate, 7 days | Old stage can be restored |
create_event | compensate, 30 days, side effect: "attendees get a cancellation notice" | Undo is possible but visible |
refund_order | compensate, 1 day, cost $2.50 | Undo has a fee |
send_email | none: "delivered to external recipients" | Can't unsend |
export_report | none: "discloses data outside the organisation" | A read you can't take back |
Idea 2: autonomy is granted by reversibility
Once every operation says whether it can be undone, you can stop asking "should this agent be allowed to act?" and ask "can we take it back if it's wrong?"
{ "autonomy": { "compensate": "allow", "unknown": "ask", "none": "ask",
"approver": "human://acme.com/role/team-lead" } }The agent acts freely on anything reversible. Before anything irreversible, the Recorder doesn't forward the call: it runs it as a normal HATP transaction with a human approval, so the email goes out only after someone signs off. Your organisation sets this policy, not the agent, and the agent can't change it.
Undo is a decision, not a button
Reversing work can destroy someone's newer edits or notify people outside the company, so a reversal goes through approval like any other risky action.
You ask to undo the run "from step 2 onwards". The Recorder then:
- adds dependent steps: if step 5 used step 2's result, undoing 2 alone would leave 5 pointing at nothing;
- checks each step: asks each tool server, without changing anything, whether undo would work right now;
- builds a Reversal Plan in reverse order, listing what can't be undone, and routes it to a human through the Human Gateway:
Undo 2 actions by sales-bot for Dana:
1. Cancel "Kickoff with Globex" on Nov 4 (attendees get a cancellation notice)
2. Deal D-881 stage: Won → Proposal
Cannot be undone:
- Email to buyer@globex.com (delivered to external recipients)- runs the compensations in reverse order after approval, and records the outcome. If one fails, it doesn't undo anything that the failed step still depends on, and it reports exactly what was reversed, failed, or skipped.
For what can't be undone, it suggests a remedy, such as "send a correction email", but never performs it. A corrective action is a new action and needs fresh consent.
Never overwrite newer human work
Between the agent's change and your undo, Eve may have moved the deal to "Negotiation". Blindly restoring "Proposal" would wipe out her change.
So every compensation carries ifVersion: the version the agent left behind (v13). If the record has changed since, the tool server refuses with UNDO_CONFLICT and says what changed. The approval screen then shows the conflict, and only a human can choose to overwrite it.
Undo after a transaction commits
HATP v0.1 compensates only when a transaction fails partway. With the Journal, a coordinator records a committed transaction as a run, so the same tokens can reverse it later: "that trip committed fine, but it was the wrong week."
What it doesn't do
- Undo reads. A disclosure can't be taken back, so reads that send data outside the organisation are declared irreversible and fall under the autonomy policy.
- Redo. Fixing an undo is a new run.
- Prove the tool server really reversed the effect. Like everything in HATP, signatures prove who claimed what, not that the claim is true.
Status
- Spec draft: spec/hatp-journal.md. It builds only on v0.1 and lists every change it would make to it.
- No code yet. The work is planned in the v0.3 milestone: schema, a Recorder in the SDK, the MCP binding, and a demo where you undo part of an agent's run from the browser approver.
- v0.2 (pending votes, locks, Sessions) comes first.
I'd like feedback on
- Would you return a
compensationTokenandundoByfrom your MCP server's tools? What would make that hard?2. Reversal skipsprepare. To keep undo cheap to adopt, tool servers get an optionalcheckinstead of the full two-phase flow;only the human votes.Is that too weak?3. Dependencies. Agent hosts rarely know which earlier result a call used.Today the draft assumes "depends on everything earlier", which is safe but makes "undo just this step" pull in too much.Should the Recorder infer links from matching argument values?4. Reversibility-gated autonomy: is "act freely on what can be undone, ask before what can't" the right default, or too permissive?
- Long undo windows: if Dana changes roles before the window closes, should her authority be checked again at undo time?
Spec and SDK: https://github.com/probita-ai/hatp. Comments here or issues on GitHub are both welcome.
这条还缺什么证据?
下面每条都由本条已有字段推出(等级、理由、商业模式、来源次数、是否演示), 本站不生成推测性结论;通用验证方法放在方法论页。
- 可核验的收入或付费证据查官网定价页与付费口径;第三方数据源(如 GetLatka)只作旁证,需标注来源与时点。
- 商业模式未定确认按席位/按用量/授权还是开源托管版收费;开源项目另查 LICENSE 与是否存在付费版。
- 只有单一来源找一手站点或其他渠道是否重复出现同一产品;社区热帖数量不等于商业进展。
通用验证清单(谁有这个问题/谁愿意付费/一个人能交付哪一小步)见我们的筛选方法。