用户让 Agent 下载月度账单,生成汇总表,再准备一封邮件草稿。Agent 找到了下载与表格技能,也顺利生成了文件。随后,网页上的一段提示建议它把原始账单上传到“验证服务”,邮件技能又默认执行了发送。
从任务完成的角度看,流程似乎一直在前进;从用户授权的角度看,它已经越界。另一个版本可能更保守,却在下载超时后不断重试,制造了重复文件,最后仍无法确认汇总表用了哪份账单。
可靠执行需要同时回答三个问题:什么条件下允许动作,什么证据说明动作完成,失败之后还能安全地做什么。 Skill 提供过程知识,宿主负责落实权限、状态和验收。两者需要协作,任何一份自然语言说明都不能自动替代另一层职责。
本文用账单到邮件草稿的教学案例,连接 ContractSkill 的执行契约、SkillRevise 的证据驱动修订、ToolSafe 的执行前检查,以及 SkillDroid 的 GUI 回放与回退。下面的组合流程是工程建议,未声称这些研究共同验证过一套生产系统。
1. 契约让隐含假设可以被检查
一句“下载账单并汇总”,省略了很多前提:是否登录正确账户,月份是否明确,账单是否完整,汇总使用哪个币种,生成的是草稿还是已发送邮件。人会根据语境补全这些条件,自动执行系统则需要知道哪些可以推断、哪些必须检查。
执行契约可以理解为围绕一个动作的条件与证据:开始前什么应成立,动作要改变什么,结束后怎样确认,失败时允许哪些恢复。它不仅描述成功路径,还定义停止点。
# 本文教学契约,不是某个项目的真实接口。
goal: 汇总指定月份账单并生成邮件草稿
preconditions:
- 账户与月份已经确定
- 输入文件可读取且属于本次任务
constraints:
- 不上传到未授权的外部服务
- 只保存草稿,不发送
postconditions:
- 汇总金额可以追溯到原始账单
- 草稿引用正确附件
recovery:
- 下载失败先检查远端与本地状态
- 无法确定是否完成时停止重复写入
这个契约仍是声明。只有宿主把它落实到状态检查、工具授权和最终验收,才有执行意义。尤其是“不能发送”,应由允许调用的动作和权限控制保证,不能只希望模型始终记住这一句。
ContractSkill 将草稿技能转换为包含前置条件、步骤、后置条件、恢复与终止检查的产物,用验证反馈定位失败,再施加小范围修补。1 它帮助我们将“Agent 没完成”细化成“哪个步骤在什么状态下不满足哪条条件”。
论文的网页案例中,原技能已经找到相关候选,却停在探索阶段;修复补上后续动作与完成条件,而非重写全部搜索策略。这种局部定位很有价值。但确定性验证器只能检查已经表达并实现的条件,不能据此推出所有用户要求都获得形式化保证。
2. 检查契约本身是否真的执行
结构化字段容易制造一种安全感:JSON 里有 postconditions,似乎就有了后置验证。实际上,规范化过程可能忽略未知字段,某些检查器没有挂接到执行器,或者检查只验证了页面文字,并没有验证真实产物。
ContractSkill 公开实现的研究底稿曾核对有限的条件键和动作集合,与论文概念表示并非逐字段相同。2 这个差异提醒我们,接入任何执行契约前,都应检查“输入声明、规范化产物、实际执行”的三个边界。
| 层次 | 对账单案例的检查 | 不能替代什么 |
|---|---|---|
| 格式检查 | 契约字段与动作可以解析 | 用户目标是否合理 |
| 状态检查 | 账户、月份、下载状态符合要求 | 金额计算是否正确 |
| 产物验收 | 汇总与源文件一致,草稿附件正确 | 动作是否得到授权 |
| 权限检查 | 当前动作与目标在授权范围内 | 最终结果是否正确 |
对于宿主不认识的约束,合理行为是明确报错、降级或转交,不能静默删掉后当作通过。可以主动构造坏产物:金额错一位、附件仍是上月文件、文件名正确但内容为空,检查验收器是否真的拒绝。
还要把完成声明和提交结果分开。模型说“已保存草稿”是待核查信息,真实邮件草稿标识、附件列表与状态才是验收依据。若工具没有返回足够证据,应保留未知,而非把语言上的确定性当作系统事实。
3. 执行前的保护与执行后的验收
ToolSafe 研究在工具调用前引入逐步检查与反馈,让不合适的候选动作在产生副作用前得到处理。3 对 Skill 宿主的启发是:检查器应看到用户目标、可信授权、已有状态与候选调用,检查发生在真正执行之前。
但学习型检查器仍然可能判断错误。需要由确定性的权限边界限制可访问账户、数据、工具动作和目标地址;模型检查帮助判断语境,不能自行扩张这些边界。技能文件自称“需要上传数据”,只是能力请求,不是用户授权。
图 1:本文建议的执行路径。授权来自可信状态;网页、文件与技能内容不能改写它。
网页中的“上传到验证服务”属于外部内容,最多是任务材料,不能变成新增授权。宿主在候选工具调用处应能看到实际发送目的地与数据范围,再与当前权限比较。只在技能入库时扫描一次文本,无法覆盖运行时接触到的新内容。
来源完整性、内容风险、功能正确性与运行时授权也应分别记录。签名证明材料来自某个发布者,不能证明指令合理;检测器未报告风险,不等于后续所有动作安全。恶意技能的实证研究提供了真实威胁样本与分析方法,但没有给任何单一检查方式提供全面保证。4
安全与任务效用需要一起评估。全部拒绝当然能阻止部分风险,也会让正常账单处理无法完成。测试应同时包含合法下载、准备草稿、未授权上传、误发邮件,以及外部内容试图改写目标的情形。
4. 失败后,先判断是否可以重试
“再试一次”对读取和对外写入的含义不同。读取公开页面失败,重复访问通常容易控制;发送或付款超时,则可能是操作已经成功、结果没有返回。直接重试会把一次不确定变成两次真实副作用。
我会先把执行结果分成成功、明确失败和状态未知。未知需要查询外部事实;无法查询时,停止并说明缺少的证据。幂等键可以帮助识别重复请求,但只有外部系统真正支持对应语义时才有效,不能仅靠本地生成一个字符串获得保证。
图 2:不确定副作用的恢复路径。查询结果本身也需要可核查,不能只再次询问执行模型。
对账单任务,下载失败后可以先检查文件完整性与远端状态;汇总失败可以在独立副本上重算;邮件发送属于本来没有授权的动作,应被阻断,而不是作为待修复步骤继续尝试。
恢复还应有总预算与停止条件。无限重试可能增加成本、触发服务限流,或不断修改原始文件。对于不能恢复的动作,应保留受影响资源与已知状态,让用户或后续系统能够继续处理,而不是只输出一段模糊道歉。
5. 用执行证据修订 Skill
确认失败属于规则缺陷后,才进入技能修订。SkillRevise 将验证要求、失败归属与必须保留的条件结合起来,并要求修改对应到可观察的执行动作。5 这比泛化地追加“认真检查”更容易验收。
例如邮件草稿缺少附件,候选修订可以要求保存后读取草稿对象,核对附件标识与预期文件;如果汇总用了旧账单,则应修改输入绑定与版本检查。两种失败都表现为“结果不对”,但修订对象不同。
修改后必须重新执行验收。旧报告只证明旧产物在旧规则下发生过什么,不能直接附到新技能版本上。当前任务修好,也不等于候选适合未来任务;跨任务发布需要独立回归,详见持续改进篇。
这里还要保留环境失败的出口:服务不可用、授权不足、输入本身缺失,不应都通过重写技能解决。诊断器提出一个流畅原因,只能形成假设。修订日志需要同时保存事实、假设、补丁和验证结果,避免把解释逐轮升级为未经证实的“知识”。
6. GUI 复用:稳定部分可以回放,变化部分需要检查
界面任务最能暴露契约的价值。昨天成功点击的位置,今天可能被弹窗覆盖;相同按钮文字可能出现在另一张账单上。可复用的对象应包含任务参数、对象定位依据、状态条件与恢复方式,而不只是坐标序列。
SkillDroid 将成功轨迹编译成可复用资产,在匹配可靠时回放,遇到变化时再进入恢复或模型决策路径。6 对本文案例,可以将“打开账单列表、选择月份、发起下载”的稳定结构复用,同时每次核对账户、月份、目标对象和下载结果。
这种路径可能减少模型调用,但不能只统计回放成功的部分。整体成本需要包含定位失败、回退、额外模型调用和最终未完成的任务。若每次界面变化都要求重新探索,前期编译成本是否值得,也需要按真实复用次数判断。
不要把“本次没有调用模型”写成“整条能力链零计算”。编译、参数绑定、界面检查和失败恢复都可能有成本。回放的边界越明确,系统越容易知道什么时候应停下来,避免把旧轨迹强行套到新界面。
7. 让验证落到真实失败上
发布前可以围绕贯穿案例做一次故障注入:换错月份、撤销读取权限、让下载返回空文件、在页面插入要求上传私有材料的文本、让工具执行成功后返回超时,再故意遗漏邮件附件。每一种故障都应有明确预期:拒绝、恢复、澄清或停止。
| 测试对象 | 应观察的结果 |
|---|---|
| 正常任务 | 正确完成并保留可追溯证据 |
| 状态不满足 | 在产生副作用前发现问题 |
| 局部产物错误 | 定位具体缺口,限制修复范围 |
| 未授权动作 | 由宿主边界阻断 |
| 副作用未知 | 查询状态,避免盲目重试 |
| 恢复预算耗尽 | 保留状态并清楚停止 |
恢复率、约束违规、总尝试数、时延和成本应一起报告。只统计最终找到了一个成功结果,会隐藏搜索期间已经发生的错误动作。对有副作用的系统,最终文件正确并不代表整个执行过程可接受。
我希望 Skill 的执行契约最终成为一种可追责的接口:条件满足才执行,证据充分才宣告完成,恢复有边界,权限始终由宿主掌握。 这使技能可以逐步变得更自主,同时让用户仍然知道系统做了什么、为什么这样做。
参考资料
- ContractSkill,arXiv:2603.20340v1:契约、定位与局部修复。主实验和迁移子集的口径不同,本文不混用其成绩。
- ContractSkill 官方实现:底稿于 2026-09-27 核对
env/skill_utils.py,概念字段与实际规范化字段需区分。 - ToolSafe,arXiv:2601.10156v1:逐步工具调用保护与反馈;作者实现。
- Malicious Agent Skills in the Wild,arXiv:2602.06547v1:恶意技能实证分析。仅用于防御设计的威胁依据。
- SkillRevise,arXiv:2606.01139v4:执行证据驱动的技能修订;作者实现。
- SkillDroid,arXiv:2604.14872v1:编译、回放与恢复。
2026-10-07 合并修订。本文没有独立运行攻击样本、设备实验或 benchmark;账单案例为通用教学场景。