

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 生命周期钩子
<a name="harness-lifecycle-hooks"></a>

生命周期挂钩在线束代理循环的定义点向 Amazon Lambda 函数、Amazon SNS 主题或 EventBridge Amazon 事件总线发送事件。使用挂钩来验证调用或工具调用、记录其他系统中的活动或启动异步工作流程。

您可以使用`CreateHarness`或在安全带上配置挂钩`UpdateHarness`。挂钩配置不能作为`InvokeHarness`替代项使用。一个安全带最多支持 20 个挂钩，并且每个挂钩名称在安全带中必须是唯一的。

## 选择生命周期事件
<a name="harness-hook-events"></a>

事件类型决定挂钩何时运行、发送到目标的上下文以及 Lambda `deny` 决策的效果。


| 事件 | 上下文 | Lambda 决策`deny`的影响 | 
| --- | --- | --- | 
|  `before_invocation`  | 在安全带恢复会话状态之前，在当前`InvokeHarness`请求中`messages`提供的订单。 | 在代理启动之前停止调用。响应流会发出一个`stopReason`设置为`messageStop``hook_stopped`的事件。 | 
|  `before_tool_call`  | 刀具名称、刀具类型、刀具使用 ID 和模型生成的刀具输入。 | 跳过工具调用。代理循环仍在继续。 | 
|  `after_tool_call`  | 工具名称、刀具类型、刀具使用 ID、刀具结果，以及线束执行的刀具引发异常时的错误字符串。 | 保留已完成的工具结果，然后停止调用。响应流会发出一个`stopReason`设置为`messageStop``hook_stopped`的事件。 | 
|  `after_invocation`  | 调用停止原因以及输入和输出令牌计数。 | 在响应流中报告决策。调用已经完成，因此挂钩无法撤回流式输出。 | 

### 使用带有内联函数的工具调用挂钩
<a name="harness-hook-inline-functions"></a>

Tool-call 钩子也适用于`inline_function`工具。在模型生成工具请求`before_tool_call`之后，以及线束将待处理的调用移交给客户端执行之前，线束就会调用。使用完整的响应流，然后仅在最后一个`messageStop`事件`stopReason`设置为时才处理内联调用`tool_use`。模型生成的请求可以在挂钩决策之前出现在较早的直播事件中；`before_tool_call`控制的是执行，而不是在流中的可见性。

在以后的`InvokeHarness`请求`toolResult`中返回匹配项，该请求使用相同的匹配项`runtimeSessionId`。Harness 会恢复待处理的呼叫，使用客户端提供的结果`after_tool_call`进行调用，如果挂钩允许结果，则继续代理循环。有关完整的回调流程，请参阅[内联函数调用](harness-tools.md#harness-inline-functions)。

一个模型响应中的工具保留顺序执行顺序。对于 harness 执行的工具 A、内联函数 B 和 harness 执行的工具 C，harness 在交出 B 之前执行 A，等待 B 的结果再执行 C。后续请求是新的调用，因此调用挂钩会再次运行；`before_tool_call`对于待处理的内联函数，不会重复，而是使用提交的结果运行一次。`after_tool_call`

您可以在一个后续请求中提交待处理结果和任何紧随其后的内联结果。安全带按顺序处理它们`before_tool_call`和`after_tool_call`挂钩。如果您的客户需要在每次外部操作之前`allow`做出决定，请每次移交返回一个内联结果。稍后的请求可以在挂钩运行之前出现在流中。

如果`before_tool_call`拒绝 B，则安全带会跳过 B 并继续使用 C，而不将 B 交给客户端。如果在客户端返回结果后`after_tool_call`拒绝 B，则安全带会保留 B 的结果并在 C 之前停止。

**验证客户提供的结果**  
内联函数`after_tool_call`的事件确认线束处理了客户端提供的结果。它不能证明客户端执行了该结果所代表的外部操作。在将事件用作授权或审计信号之前，请对调用者进行身份验证并验证结果。

## 选择一个目标
<a name="harness-hook-targets"></a>

Hook 支持以下目标类型。


| Target | Delivery | 决策行为 | 
| --- | --- | --- | 
|  Amazon Lambda | 安全带与同步调用该函数`RequestResponse`并等待。`timeoutSeconds` | 该函数必须返回`allow`或`deny`。Lambda 是唯一可以改变代理循环行为的目标类型。 | 
| Amazon SNS | 安全带将挂钩有效载荷发布为 SNS `Message`。发布不会阻止代理循环。 | 仅限通知。SNS 不会返回挂钩决定。 | 
| Amazon EventBridge | 安全带将挂钩有效载荷发送进来`detail`，并附有来源`bedrock-agentcore.harness`和细节类型`Harness Lifecycle Hook`。发送不会阻塞代理循环。 | 仅限通知。 EventBridge 不返回挂钩决定。 | 

该安全带无需等待回复即可安排 SNS 和 EventBridge 交付。传送错误不会停止调用。对于 SNS FIFO 主题，该工具会从线束 ARN 和会话 ID 中派生消息组 ID。这会保留该会话中的发布顺序。标准 SNS 主题， EventBridge 不保证生命周期事件顺序。

授予安全带执行角色调用每个目标的权限。有关策略示例，请参阅[生命周期挂钩目标](harness-security.md#harness-lifecycle-hook-permissions)。

## 配置挂钩
<a name="harness-hook-configure"></a>

以下示例在每次调用之前配置 Lambda 决策挂钩，在每次工具调用后配置 SNS 通知，并在 EventBridge 每次调用后配置通知。在以下位置定义挂钩`hooks.json`：

```
[
  {
    "beforeInvocation": {
      "name": "validate_request",
      "target": {
        "lambda": {
          "arn": "arn:aws:lambda:us-west-2:123456789012:function:validate-harness-request",
          "timeoutSeconds": 5,
          "failureMode": "deny"
        }
      }
    }
  },
  {
    "afterToolCall": {
      "name": "record_tool_result",
      "target": {
        "sns": {
          "arn": "arn:aws:sns:us-west-2:123456789012:harness-tool-events"
        }
      }
    }
  },
  {
    "afterInvocation": {
      "name": "record_invocation",
      "target": {
        "eventBridge": {
          "arn": "arn:aws:events:us-west-2:123456789012:event-bus/harness-events"
        }
      }
    }
  }
]
```

**Example**  
应用钩子：  

```
aws bedrock-agentcore-control update-harness \
  --harness-id "MyHarness-UuFdkQoXSL" \
  --hooks file://hooks.json
```
加载并应用相同的配置：  

```
import json
import boto3

client = boto3.client("bedrock-agentcore-control")

with open("hooks.json", encoding="utf-8") as hooks_file:
    hooks = json.load(hooks_file)

client.update_harness(
    harnessId="MyHarness-UuFdkQoXSL",
    hooks=hooks,
)
```

当您传递`hooks`到时`UpdateHarness`，提供的列表将替换现有的挂接配置。传递一个空列表以删除所有钩子。省略`hooks`以保留现有配置。

## 返回 Lambda 决策
<a name="harness-hook-lambda"></a>

Lambda 目标直接接收挂钩有效负载。它必须返回一个`decision`值为`allow`或的 JSON 对象`deny`。它也可以返回`reason`。该工具在`hookEvent`响应流事件中包含此原因，并将其限制在 1,024 个字符以内。

当目标无法评估完整的钩子上下文时，以下处理程序会拒绝`before_invocation`事件。将此逻辑替换为应用程序的规则。

```
def lambda_handler(event, _context):
    hook_context = event["context"]

    if event["event"] == "before_invocation" and hook_context.get("truncated"):
        return {
            "decision": "deny",
            "reason": "The request context exceeded the evaluation limit.",
        }

    return {"decision": "allow"}
```

对于 Lambda 目标，`timeoutSeconds`默认为 60 秒，接受介于 1 到 900 秒之间的值。 `failureMode`决定函数何时超时、返回错误或返回无效响应：
+  `deny`— 应用拒绝决定。这是默认值。
+  `allow`— 应用允许决定。

**配置长时间运行的挂钩连接**  
同步挂钩可以使`InvokeHarness`直播保持空闲状态，直到钩子返回或到达为止`timeoutSeconds`。将 SDK 读取超时配置为超过预期的最长空闲时间。对于配置为 900 秒的挂钩，以下示例使用 1,000 秒的读取超时来提供额外的余量：  

```
import boto3
from botocore.config import Config

client = boto3.client(
    "bedrock-agentcore",
    config=Config(
        read_timeout=1000,
        tcp_keepalive=True,
    ),
)
```
如果连接通过 NAT 网关、接口 VPC 终端节点或 Network Load Balancer，请将操作系统 TCP keepalive 空闲时间配置为小于 350 秒。在 Linux 上`TCP_KEEPIDLE`，这是由配置的`net.ipv4.tcp_keepalive_time`。`tcp_keepalive=True`单独设置即可启用 TCP keepalive，但不会缩短操作系统的默认空闲时间。有关更多信息，请参阅[连接超时或长时间运行或空闲连接时重](https://docs.amazonaws.cn/bedrock/latest/userguide/troubleshooting-api-error-codes.html)置。

上下文截断不会激活。`failureMode`Lambda 函数接收截断的上下文，必须返回决策。

当多个 Lambda 挂钩使用相同的事件类型时，该工具会同时调用它们。任何`deny`决定都将应用事件的拒绝行为。如果有多个挂钩拒绝该事件，则配置列表中的第一个拒绝挂钩会提供原因。

## 处理挂钩有效载荷
<a name="harness-hook-payload"></a>

每个目标都会收到以下公共字段：

```
{
  "hookEventId": "1234abcd-12ab-34cd-56ef-1234567890ab",
  "name": "validate_request",
  "event": "before_invocation",
  "harnessArn": "arn:aws:bedrock-agentcore:us-west-2:123456789012:harness/MyHarness-UuFdkQoXSL",
  "sessionId": "12345678-1234-5678-9abc-123456789012",
  "context": {
    "messageCount": 1,
    "messages": [
      {
        "role": "user",
        "content": [{"text": "Summarize this report."}]
      }
    ]
  }
}
```

这些`context`字段取决于事件类型。



- **  `before_invocation`  **
  - **字段:**  `messageCount`  / **说明:** 在钩子上下文截断之前，当前`InvokeHarness`请求中的消息数。
  - **字段:**  `messages`  / **说明:** 从当前`InvokeHarness`请求中排序消息。
  - **字段:**  `truncated`  / **说明:** 当上下文超过 64 KiB `true` 时存在并设置为。

- **  `before_tool_call`  **
  - **字段:**  `toolName`  / **说明:** Model-facing 工具名称。
  - **字段:**  `toolType`  / **说明:** 线束工具类型，例如`builtin``remote_mcp`、`agentcore_gateway`、或`inline_function`。
  - **字段:**  `toolInput`  / **说明:** Model-generated 工具的输入。
  - **字段:**  `toolUseId`  / **说明:** 将工具请求与其结果关联的 ID。

- **  `after_tool_call`  **
  - **字段:**  `toolName`  / **说明:** Model-facing 工具名称。
  - **字段:**  `toolType`  / **说明:** 线束工具类型。
  - **字段:**  `toolResult`  / **说明:** 安全带观察到的结果。对于内联函数，这是客户端提供的结果。
  - **字段:**  `toolUseId`  / **说明:** 将工具请求与其结果关联的 ID。
  - **字段:**  `error`  / **说明:** 线束执行的工具引发异常时的错误文本。未发生此类异常时省略。

- **  `after_invocation`  **
  - **字段:**  `stopReason`  / **说明:** 最终调用停止原因。
  - **字段:**  `usage`  / **说明:** 包含`inputTokens`和的对象`outputTokens`。



`before_invocation`上下文不包括挂接运行后线束从会话状态恢复的消息。L `after_tool_call` ambda 拒绝决定不会删除已完成的工具结果。

### 处理上下文截断
<a name="harness-hook-context-limit"></a>

安全带将每个挂钩`context`对象限制在 64 KiB 以内。

因为`before_invocation`，该工具保留了符合限制的最新的连续完整消息序列。有效载荷保留`messageCount`并`messages`作为列表保存。它还增加了`"truncated": true`上下文。如果仅最新的消息超过限制，`messages`则列表为空。

对于其他事件类型，该工具会替换最大的上下文字段，直到上下文适合为止。每个替换的字段都使用以下格式：

```
{
  "truncated": true,
  "preview": "<prefix of the serialized field>"
}
```

在使用字段之前，请检查截断标记。需要完整上下文的 Lambda 目标可以在收到截`deny`断标记时返回。SNS 或 EventBridge 消费者可以记录事件并从自己的记录系统中获取其他数据。

## 从响应流中读取挂钩事件
<a name="harness-hook-stream"></a>

 `InvokeHarness`每触发一个已配置`hookEvent`的挂钩都会发出一个。Lambda 事件包括已应用的决策和可选原因：

```
{
  "hookEvent": {
    "hookEventId": "1234abcd-12ab-34cd-56ef-1234567890ab",
    "name": "validate_request",
    "type": "before_invocation",
    "decision": "allow",
    "reason": "Request accepted."
  }
}
```

用于社交网络和 EventBridge 目标，`decision`并且`reason`不存在。他们`hookEvent`确认安全带安排了派遣。它不能确认目标已收到事件。

继续阅读，直到事件流关闭。当直播中包含终端时`messageStop`，任何`type`设置为`hookEvent`的终端都将`after_invocation`紧随其后。有些错误路径在没`after_invocation`有 a `messageStop` 的情况下发出。

## 相关主题
<a name="_related_topics"></a>
+  [工具](harness-tools.md)-配置工具和内联函数
+  [可观察性和成本控制](harness-operations.md) — 监控线束调用
+  [安全和访问控制](harness-security.md) — 配置线束执行角色和控制工具访问权限
+  [API 文档](harness-get-started.md#api-documentation) 