← 返回信息流

热点精选AWS AI Blog新闻

Amazon Bedrock AgentCore 推出从自然语言生成 Dogwood 策略的 AI 工具

aws.amazon.com作者:Sandesh Swamy产品政策监管AI评分:70/100

亚马逊云科技在 Bedrock AgentCore 中扩展了 Policy 功能,新增基于时间的约束,并升级 Policy Authoring 工具,可将自然语言策略文档自动转换为 Dogwood 形式规范,支持时间约束、轨迹约束、Guardrails 调用及工具参数限制,帮助团队在代理系统中实施治理控制。

AI代理可以自动化复杂的工作流程,但如果在没有适当控制的情况下使用,可能会采取不符合您组织策略或监管约束的行动。为了解决这个问题,我们在Amazon Bedrock AgentCore中构建了Policy功能,使团队能够实施适用于在Amazon Bedrock AgentCore中运行的所有代理的控制措施。该功能最近得到了扩展,新增了跨时间约束代理行为的限制能力,支持诸如速率限制、前置条件和工具调用的顺序排列以及累积效应等策略。这些策略以Dogwood(一种开源治理语言)表达,并由内置于AgentCore Gateway(Amazon Bedrock AgentCore的一项功能)中的Dogwood监控器实时应用于代理操作。

作为此次新发布的一部分,我们扩展了Policy Authoring的功能,这是一个由AI驱动的工具,用于将自然语言策略规范文档转换为语法和语义上正确的Dogwood形式化规范。借助这一新功能,您可以生成实施时间和轨迹约束的策略,调用Amazon Bedrock Guardrails服务来检测自由文本语义内容中的不当内容,以及对工具输入参数施加限制的策略(后者在AgentCore的上一版Policy中已可用)。无论您的技术背景如何,您都可以直接将用自然语言编写的策略文档导入Amazon Bedrock AgentCore中的Policy,以保护您部署的代理系统。

在本文中,我们通过示例演示这一新功能,并提供有关在构建自然语言策略时如何运用最佳实践的指导。

自然语言策略到Dogwood的自动翻译

Dogwood策略可以完全手工编写,对于少量控制来说,这是一个完全合理的起点。当您已经有以散文形式编写的规则,而您面前的工作是转录而非设计时,Policy Authoring效果最佳。您可以提供一份包含清晰规则集的文档:策略列表、操作流程中的规则部分,或一段关于允许或限制操作的书面说明。Authoring是一个翻译器而非摘要器,因此将规则与理由、背景和评论交织在一起的文档最好先精简为规则本身。

示例设置

为了使示例具体化,让我们考虑一家零售银行的客户服务代理。它负责验证来电者身份、提交争议、针对有争议的费用发放退款、在客户自己的账户之间转移资金,并且可以请求主管批准某项费用。其工具通过AgentCore Gateway访问,每个工具接受少量参数并返回结果:

工具用途输入输出
verify_identity对来电者进行升级验证{ account: String }{ verified: Bool }
initiate_transfer在客户账户之间转移资金{ account: String, dest_account: String, amount: Long }{ confirmation: String }
issue_refund撤销有争议的费用{ account: String, charge_id: String, amount: Long }{ refunded: Bool }
file_dispute开启争议案件{ account: String, description: String }{ case_id: String }
request_approval请求主管批准某项费用{ charge_id: String }{ approved: Bool }

除了策略文档之外,Authoring还接收一个包含这些确切信息的模式:工具名称、它们接受的参数以及返回的值。该模式从代理的Model Context Protocol(MCP)工具清单生成,因此生成的策略引用的是代理实际调用的相同名称。例如,生成策略中的context.input.amount就是上表中的amount参数。Authoring还会获得可用的Amazon Bedrock Guardrails检查集以及策略允许引用的身份声明。

银行的合规团队将其控制措施以书面文档的形式维护,格式与其用于人工员工的格式相同。以下规则取自该文档,每条规则后面是Policy Authoring为其生成的Dogwood策略。两个约定使输出更易于阅读。Dogwood默认拒绝,且禁止覆盖允许,因此授予某项能力的规则变为带有条件的允许,而限制或封顶某项内容的规则则变为禁止。条件可以检查正在被决策的调用,也可以检查同一会话中已经发生的情况。以下示例同时展示了这两种情况。

策略翻译示例

以下示例展示了自动形式化器如何将自然语言策略翻译为Dogwood公式。

对工具参数的限制

退款可能仅在营业时间内(定义为 UTC 时间上午 9:00 至下午 5:00)发放,且金额不得超过 2,500 美元。

permit ( principal, action == AgentCore::Action::"issue_refund", resource )
when { context.system.now.toTime() >= duration("9h")
    && context.system.now.toTime() <= duration("17h") }
when { context.input.amount <= 2500 };

一个包含两个独立要求的句子变成了一条包含两个条件的策略,两个条件都必须满足才能允许退款。context.input.amount 是代理发出 issue_refund 调用时的金额参数,以工具声明的任何单位进行比较。文档中的“$2,500”和工具的金额需要在此方面保持一致。时间比较在调用被决定的那一刻读取时钟,两个条件都不依赖于代理之前所做的任何事情。有关 duration 等基于时间的函数的更多详细信息,请参阅基于时间的策略支持。

必需的前置步骤

除非调用者的身份在过去 15 分钟内已针对同一账户完成验证,否则不得发起转账。

permit ( principal, action == AgentCore::Action::"initiate_transfer", resource )
when temporal {
    formerly within 15m AgentCore::Action::"verify_identity"::response{
        input.account:   context.input.account,
        output.verified: true
    }
};

此规则无法仅凭转账请求本身来判定,因此生成的条件会查看代理已经执行的操作。formerly within 15m 询问它所描述的事件是否在过去十五分钟内的任何时间点发生过。这里指的是 verify_identity 调用(::response,即结果,而非调用本身)的完成,且返回结果为 verified: true。在事件模式内部,裸的 input.account 命名的是该先前事件的字段,而 context.input.account 命名的是正在被决定的调用上的字段。将两者设为相等,正是使“同一账户”变得精确的原因。对其他账户的验证,或者尝试过但返回未验证结果的验证,都不满足该规则。并且由于所检查的历史记录是当前会话的,该规则不需要为调用者单独设置 ID,这就是 verify_identity 只接受账户作为参数的原因。

累计上限

如果过去 12 小时内的转账总金额将超过 50,000 美元,则阻止转账。

forbid ( principal, action == AgentCore::Action::"initiate_transfer", resource )
when temporal {
    exists (total: Long). (
        (sum a for (a: Long), (t: Timepoint). where (
            formerly within 12h (
                AgentCore::Action::"initiate_transfer"::request{ input.amount: a } && tp(t)
            )
        )) == total && total > 50000
    )
};

这里,历史记录不是被搜索而是被累加。策略获取过去 12 小时内每次转账的金额参数,将它们求和,如果累计总额超过 50,000 美元,则拒绝当前调用。该时间窗口内的每一笔单独转账可能金额很小且不起眼,但该条件约束的是它们的总和。还要注意文档中未明确说明的内容:它说“已转账”,但没有说明被阻止或失败的尝试是否计入。翻译对 ::request 事件求和,意味着代理尝试过的每一次转账,这对于上限来说是更安全的解读。然而,在文档中明确说明这一点可以消除猜测,这正是接下来第一个最佳实践的主题。

速率限制

代理在一小时内针对同一账户的退款尝试不得超过三次。

forbid ( principal, action == AgentCore::Action::"issue_refund", resource )
when temporal {
    exists (n: Long). (
        (count for (t: Timepoint). where (
            formerly within 1h (
                AgentCore::Action::"issue_refund"::request{ input.account: context.input.account } && tp(t)
            )
        )) == n && n > 3
    )
};

这与前一个策略具有相同的结构,只是对事件进行计数而非对字段求和。计数仅限于针对正在考虑的调用中所指定账户的退款,并且它包含该调用本身,因此一小时内第四次尝试将被拒绝。此规则明确说明了“尝试”,因此与前一个规则不同,它不需要任何推断:被拒绝或失败的退款仍然计入限制。

对自由格式文本的检查

拒绝任何描述中包含社会安全号码的争议提交。

forbid ( principal, action == AgentCore::Action::"file_dispute", resource )
when {
    BedrockGuardrails::SensitiveInformation(["US_SOCIAL_SECURITY_NUMBER"], [context.input.description])
        .maxConfidenceScore().greaterThanOrEqual(decimal("0.2"))
};

有些规则涉及自由文本的含义,而非结构化值,任何字段上的比较都无法决定这类规则。对于这些情况,生成的策略会在规则指定的字段上内联调用 Amazon Bedrock Guardrails 检查,并将报告的置信度与阈值进行比较。该规则未指定阈值,因此转换使用该检查的默认值。当文档确实指定了阈值时(例如“高置信度”或具体数字),则沿用该值。

一条涉及多种条件的规则

超过500美元的退款需要该笔收费的主管审批,且审批须在最近30分钟内记录。

该句子包含两个以截然不同方式检查的部分:对当前调用参数的一个阈值,以及对已发生事件的一个条件。两个子句位于同一策略中。该规则收窄了一项现有权限:它拒绝超过500美元的退款,而 unless 子句是例外,当存在匹配的审批记录时解除拒绝。与前面的先决条件示例一样,charge_id 上的关联关系确保一笔收费的审批不会授权另一笔收费的退款。

最佳实践

清晰无歧义的策略能带来更可预测的行为和更少的错误,无论执行者是人类用户还是自主代理。此外,这还能提升前面介绍的自然语言到 Dogwood 策略生成方案的性能。接下来,我们回顾一些构建自然语言策略的技巧和最佳实践。

  • 明确说明你指的是尝试还是结果。“转账之后”是有歧义的。“转账成功之后”则没有。尝试是指代理发出的任何调用,包括被拒绝或失败的调用。只有完成的调用才携带工具返回的值。速率限制和累计上限通常针对尝试,先决条件和顺序规则则针对结果。
  • 明确时间窗口。“最近”无法转换。“过去30分钟内”可以。时间窗口从被决策的调用向前回溯,因此如果规则意在按日历边界重置而非随时间滑动,请明确说明,因为这需要不同的控制机制。
  • 明确规则的关键字段。“每小时不超过三笔转账”没有说明是谁的:是此调用方的三笔,还是针对此账户的三笔?两者都可以表达,它们是不同的策略,而该句子两者都没有选择。凡是规则涉及计数、求和或关联,请指明将事件联系在一起的字段。
  • 给出阈值及其边界。“超过三笔”和“至少三笔”相差一个操作,通常正是该规则旨在阻止的那个操作。内容检查的置信度级别也是如此。
  • 审查生成的 Dogwood 策略以确保正确性。每条 Dogwood 策略都会与其来源句子一同返回,以便你并排阅读两者。虽然验证可以确认策略格式正确且锚定在正确的模式中,但它不能确认策略表达了作者的本意。这一判断仍由文档所有者负责。

了解哪些内容无法强制执行

虽然策略生成服务可以过滤并高亮显示与 AgentCore 中 Policy 强制执行不兼容的策略,但你也应了解常见问题。

  • 它不是关于操作的规则。“代理应始终以客户的最佳财务利益行事,并运用合理的专业判断。”这里没有任何对操作、字段或主体的条件。这是一个真实的需求,它属于代理的指令、评估和训练,而非授权引擎。
  • 它要求的是操作,而非裁决。“当争议描述包含社会安全号码时,在备注存储之前将其脱敏。”策略引擎允许或拒绝调用,它不会修改调用。相邻的拒绝包含社会安全号码的提交的规则是可以表达的,并出现在前面的示例中。脱敏是另一种控制,在流水线的不同节点应用。
  • 它超出了语言所能表达的范围。“拒绝周末和美国联邦银行假日的电汇。”Dogwood 中的日期和时间支持涵盖时间点、偏移量和差值。没有星期几的访问器,也没有假日日历。Dogwood 语言指南详细列出了哪些构造可用,当策略被策略生成服务搁置时,值得通读该指南,既是为了确认缺口,也是为了查看是否有相近的表述受支持。
  • 它超出了强制执行的范围。“客户每天最多发起十笔转账,跨该客户所有并发会话累计计算。”强制执行评估的是会话内的轨迹,因此跨会话汇总的上限不是通过改变措辞就能恢复的。

在每种情况下,有用的输出不是策略,而是一个标签,表明它无法被翻译成Dogwood,这告诉你应该考虑替代方案:重写它,将其移至不同的控制措施,或者接受它仍然是一个人工流程。

策略编写的工作原理

自动形式化流水线分四步运行。首先是对文档进行分解。为读者编写的规则往往是复合的:编号条款经常承载多个独立的义务,而单个句子有时承载两个义务,正如前面营业时间的例子所示。分解将这些规则拆分为原子规则,每条规则都是关于特定工具或工具集的陈述,可以独立执行。然后对每条规则进行路由。一条规则要么可以用Dogwood及其组成监控器表达,要么不能,而那些不能表达的规则会被搁置而不是翻译,通常是因为上一节中提到的四个原因。在尝试翻译之前进行此过滤,可以防止无法表达的规则变成能够干净验证却执行错误内容的策略。剩余的规则被自动形式化为Dogwood,并以随文档一起提供的工具模式为锚点。最后,每个候选策略都使用与开源语言一同发布的Dogwood命令行工具进行验证。这是流水线中不涉及判断的部分:编译器是判断策略是否能解析、其中每个名称是否存在于模式中的精确且确定性的权威。当候选策略被拒绝时,其诊断信息会被返回,并在看到这些错误的情况下重新翻译该规则,进行有限轮次的迭代。

输出的结果是两个集合:通过语法验证并与环境模式兼容的策略及其生成的原子自然语言规则,以及被搁置的原子自然语言规则。

结论

本文演示了Policy Authoring如何将书面策略文档转化为Dogwood策略。你看到了涵盖工具参数约束、前置条件、累计上限、速率限制以及自由格式内容检查的翻译示例。此外,你还了解了使自然语言规则能够良好翻译的属性:明确的时间窗口、具名的主体、显式的阈值,以及尝试与结果之间的清晰选择。Dogwood可以直接编写,喜欢使用该语言的团队欢迎继续这样做。Authoring适用于规则已经以散文形式存在的常见情况,缩短了从你已经维护的文档到一套可以审查和部署的策略之间的距离。

要开始使用,请参阅AgentCore文档中的Policy部分,了解如何创建策略引擎并从文档编写策略;如果你想自行阅读或扩展生成的策略,请参阅Dogwood语言指南。有关这些策略在运行时如何被解释和执行的更多信息,请参阅《使用Amazon Bedrock AgentCore中的时间策略保护AI代理》和《Introducing Dogwood:AI代理的运行时验证》。

我们还要感谢团队中其余的应用科学家Chao Shang、Sadat Shahriar、Wanyu Du和Devang Kulshreshtha对本次发布的贡献。

关于作者

阅读原文