

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

# 结合使用护栏和推理操作来评估用户输入
<a name="guardrails-input-tagging-base-inference"></a>

您可以将护栏与基本推理操作[InvokeModel](https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_InvokeModel.html)和 [InvokeModelWithResponseStream](https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_InvokeModelWithResponseStream.html)（流式传输）一起使用。这一部分介绍了如何选择性地评估用户输入以及如何配置流式响应行为。请注意，对于对话应用程序，您可以使用 [Converse API](guardrails-use-converse-api.md) 实现相同的结果。

有关调用基本推理操作的示例代码，请参阅[使用以下命令提交单个提示 InvokeModel](inference-invoke.md)。有关在基本推理操作中使用护栏的信息，请按照的[测试护栏](guardrails-test.md)中 API 选项卡中的步骤操作。

**Topics**
+ [

# 用标签标记用户输入以筛选内容
](guardrails-tagging.md)
+ [

# 配置流式响应行为以筛选内容
](guardrails-streaming.md)
+ [

# 在使用 Converse API 时添加护栏
](guardrails-use-converse-api.md)

# 用标签标记用户输入以筛选内容
<a name="guardrails-tagging"></a>

输入标签让您能够在输入文本中标记出需要由护栏处理的特定内容。当您想对输入的某些部分应用护栏而不处理其他部分时，输入标签非常有用。

例如，RAG 应用程序中的输入提示可能包含系统提示、来自可信文档来源的搜索结果和用户查询。由于系统提示由开发人员提供，并且搜索结果来自可信来源，因此您可能只需要对用户查询进行护栏评估。

再比如，对话应用程序中的输入提示可能包含系统提示、对话历史记录和当前用户输入。系统提示是开发人员设定的指令，对话历史记录包含历史用户输入和模型响应，这些内容可能已经过护栏评估。在这种情况下，您可能只需要评估当前用户输入。

通过使用输入标签，您可以更好地控制输入提示的哪些部分应由护栏处理和评估，从而确保根据您的应用场景定制保护措施。这还有助于提高性能和降低成本，因为您可以灵活地评估输入中相对较短且相关的部分，而不是整个输入提示。

**标记内容以供护栏处理**

要标记内容以供护栏处理，请使用包含一个预留前缀和一个自定义 `tagSuffix` 的 XML 标签。例如：

```
{
    "text": """
        You are a helpful assistant.
        Here is some information about my account:
          - There are 10,543 objects in an S3 bucket.
          - There are no active EC2 instances.
        Based on the above, answer the following question:
        Question: 
        <amazon-bedrock-guardrails-guardContent_xyz>
        How many objects do I have in my S3 bucket? 
        </amazon-bedrock-guardrails-guardContent_xyz>
         ...
        Here are other user queries:
        <amazon-bedrock-guardrails-guardContent_xyz>
        How do I download files from my S3 bucket?
        </amazon-bedrock-guardrails-guardContent_xyz>    
    """,
    "amazon-bedrock-guardrailConfig": {
        "tagSuffix": "xyz"
    }
}
```

在前面的示例中，内容 *`How many objects do I have in my S3 bucket?`* 和 "*How do I download files from my S3 bucket?*" 经过标记（使用标签 `<amazon-bedrock-guardrails-guardContent_xyz>`），以供护栏处理。请注意，前缀 `amazon-bedrock-guardrails-guardContent` 是护栏预留的。

**标签后缀**

标签后缀（前面的示例中的 `xyz`）是一个动态值，您必须在 `amazon-bedrock-guardrailConfig` 的 `tagSuffix` 字段中提供该值才能使用输入标签。建议每次请求使用新的随机字符串作为 `tagSuffix`。通过使标签结构不可预测，这有助于缓解潜在的提示注入攻击。静态标签可导致恶意用户关闭 XML 标签并在标签关闭后附加恶意内容，从而导致*注入攻击*。您只能使用字母数字字符，长度为 1 到 20 个字符（含）。使用示例后缀`xyz`，您必须使用带有后缀的 XML 标签来封装所有要保护的内容：。`<amazon-bedrock-guardrails-guardContent_xyz>` *your content* `</amazon-bedrock-guardrails-guardContent_xyz>`建议对每个请求使用动态唯一标识符作为标签后缀。

**多个标签**

您可以在输入文本中多次使用相同的标签结构来标记内容的不同部分，以供护栏处理。标签不能相互嵌套。

**未被标记的内容**

输入标签之外的任何内容不会被护栏处理。这让您能够添加指令、示例对话、知识库或您认为安全且不想被护栏处理的其他内容。如果输入提示中没有标签，护栏会处理整个提示。唯一的例外是 [使用 Amazon Bedrock 护栏检测提示攻击](guardrails-prompt-attack.md) 筛选条件，它要求输入中必须包含标签。

# 配置流式响应行为以筛选内容
<a name="guardrails-streaming"></a>

[InvokeModelWithResponseStream](https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_InvokeModelWithResponseStream.html)API 以流媒体格式返回数据。这让您能够分块访问响应，而无需等待整个结果返回完毕。在流式响应中使用护栏时，有两种操作模式：同步模式和异步模式。

**同步模式**

在默认的同步模式下，护栏会“缓冲”数据并将配置的策略应用于一个或多个响应块，然后再将响应发送给用户。同步处理模式会导致响应块产生一些延迟，因为在护栏扫描完成后，系统才会发送响应。但是，这提高了准确性，因为每个响应块在发送给用户之前都要通过护栏的扫描。

**异步模式**

在异步模式下，护栏会在响应块可用时立即将其发送给用户，同时在后台异步应用配置的策略。这一模式的优点是可以立即提供响应块，不会受到延迟的影响，但在护栏扫描完成之前，响应块可能包含不当内容。如果护栏发现不当内容，就会立即屏蔽后续的响应块。

**警告**  
Amazon Bedrock 护栏不支持在异步模式下屏蔽敏感信息。

**启用异步模式**

要启用异步模式，您需要在 `InvokeModelWithResponseStream` 请求的 `amazon-bedrock-guardrailConfig` 对象中包含 `streamProcessingMode` 参数：

```
{
   "amazon-bedrock-guardrailConfig": {
   "streamProcessingMode": "ASYNCHRONOUS"
   }
}
```

了解同步模式和异步模式的优缺点后，您可以根据应用程序对延迟和内容审查准确性的要求选择合适的模式。

# 在使用 Converse API 时添加护栏
<a name="guardrails-use-converse-api"></a>

您可以使用护栏来保护您通过 Converse API 创建的对话应用程序。例如，如果您通过 Converse API 创建聊天应用程序，则可以使用护栏来阻止用户输入的不当内容以及模型生成的不当内容。有关 Converse API 的信息，请参阅[使用 Converse API 操作进行对话](conversation-inference.md)。

**Topics**
+ [

## 调用带护栏的 Converse API
](#guardrails-use-converse-api-call)
+ [

## 在使用 Converse API 时处理响应
](#guardrails-use-converse-api-response)
+ [

## 使用 Converse API 和护栏的代码示例
](#converse-api-guardrail-example)

## 调用带护栏的 Converse API
<a name="guardrails-use-converse-api-call"></a>

要使用护栏，请在调用 C [onverse](https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_Converse.html) 或 [ConverseStream](https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_ConverseStream.html)（用于流式响应）操作中包含护栏的配置信息。或者，您可以选择您希望护栏评估的消息中的特定内容。有关可用于护栏和 Converse API 的模型的信息，请参阅[支持的模型和模型功能](conversation-inference-supported-models-features.md)。

**Topics**
+ [

### 配置护栏以便与 Converse API 配合使用
](#guardrails-use-converse-api-call-configure)
+ [

### 仅评估消息中的特定内容
](#guardrails-use-converse-api-call-message)
+ [

### 保护发送到 Converse API 的系统提示
](#guardrails-use-converse-api-call-message-system-guard)
+ [

### 护栏在保护消息和系统提示时的行为
](#guardrails-use-converse-api-call-message-system-message-guard)

### 配置护栏以便与 Converse API 配合使用
<a name="guardrails-use-converse-api-call-configure"></a>

您需要在 `guardrailConfig` 输入参数中指定护栏配置信息。配置包括您要使用的护栏的 ID 和版本。您还可以为护栏启用跟踪功能，该功能可以提供关于被护栏屏蔽的内容的信息。

在`Converse`操作中，`guardrailConfig`是一个[GuardrailConfiguration](https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_GuardrailConfiguration.html)对象，如以下示例所示。

```
{
        "guardrailIdentifier": "Guardrail ID",
        "guardrailVersion": "Guardrail version",
        "trace": "enabled"
}
```

如果使用`ConverseStream`，则传递一个[GuardrailStreamConfiguration](https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_GuardrailStreamConfiguration.html)对象。或者，您可以使用 `streamProcessingMode` 字段，指定您希望模型在返回流式响应块之前完成护栏评估。或者，您可以让模型在做出异步响应的同时，护栏继续在后台进行评估。有关更多信息，请参阅 [配置流式响应行为以筛选内容](guardrails-streaming.md)。

### 仅评估消息中的特定内容
<a name="guardrails-use-converse-api-call-message"></a>

当您将[消息](https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_Message.html)传递给模型时，护栏会评测消息中的内容。您还可以使用 `guardContent` ([GuardrailConverseContentBlock](https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_GuardrailConverseContentBlock.html)) 字段评估消息的特定部分。

**提示**  
使用该`guardContent`字段与使用带有[InvokeModel](https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_InvokeModel.html)和的输入标签类似[InvokeModelWithResponseStream](https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_InvokeModelWithResponseStream.html)。有关更多信息，请参阅 [用标签标记用户输入以筛选内容](guardrails-tagging.md)。

例如，以下护栏仅评估 `guardContent` 字段中的内容，而不评估消息的其余部分。这有助于让护栏仅评测对话中最近的消息（如以下示例所示）。

```
[
    {
        "role": "user",
        "content": [
            {
                "text": "Create a playlist of 2 pop songs."
            }
        ]
    },
    {
        "role": "assistant",
        "content": [
            {
                "text": "Sure! Here are two pop songs:\n1. \"Bad Habits\" by Ed Sheeran\n2. \"All Of The Lights\" by Kanye West\n\nWould you like to add any more songs to this playlist?"
            }
        ]
    },
    {
        "role": "user",
        "content": [
            {
                "guardContent": {
                    "text": {
                        "text": "Create a playlist of 2 heavy metal songs."
                    }
                }
            }
        ]
    }
]
```

`guardContent` 的另一个使用案例是为消息提供额外的上下文，而不让护栏评测该上下文。在以下示例中，护栏仅评测 `"Create a playlist of heavy metal songs"` 而忽略 `"Only answer with a list of songs"`。

```
messages = [
    {
        "role": "user",
        "content": [
            {
                "text": "Only answer with a list of songs."
            },
            {
                "guardContent": {
                    "text": {
                        "text": "Create a playlist of heavy metal songs."
                    }
                }
            }
        ]
    }
]
```

如果内容不在 `guardContent` 块中，并不一定意味着不会对其进行评估。此行为取决于护栏使用的筛选策略。

以下示例展示了两个带有[上下文一致性检查](guardrails-contextual-grounding-check.md)（基于 `qualifiers` 字段）的 `guardContent` 块。护栏中的上下文一致性检查只会评估这些块中的内容。但是，如果护栏还包含阻止“背景”一词的[单词筛选条件](guardrails-content-filters.md)，系统会评估文本“一些其他背景信息”，即使它不在 `guardContent` 块中。

```
[{
    "role": "user",
    "content": [{
            "guardContent": {
                "text": {
                    "text": "London is the capital of UK. Tokyo is the capital of Japan.",
                    "qualifiers": ["grounding_source"]
                }
            }
        },
        {
            "text": "Some additional background information."
        },
        {
            "guardContent": {
                "text": {
                    "text": "What is the capital of Japan?",
                    "qualifiers": ["query"]
                }
            }
        }
    ]
}]
```

### 保护发送到 Converse API 的系统提示
<a name="guardrails-use-converse-api-call-message-system-guard"></a>

您可以使用护栏来保护发送到 Converse API 的系统提示。要保护系统提示符，请在传递给 API 的系统提示符中指定 `guardContent` ([SystemContentBlock](https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_SystemContentBlock.html)) 字段，如以下示例所示。

```
[
    {
        "guardContent": {
            "text": {
                "text": "Only respond with Welsh heavy metal songs."
            }
        }
    }
]
```

如果您没有提供 `guardContent` 字段，护栏不会评估系统提示消息。

### 护栏在保护消息和系统提示时的行为
<a name="guardrails-use-converse-api-call-message-system-message-guard"></a>

护栏在处理系统提示和您传递的消息时，评估 `guardContent` 字段的方式有会有所不同。


|  | 系统提示包含护栏块 | 系统提示不包含护栏块 | 
| --- | --- | --- | 
|  **消息包含护栏块**  |  系统：护栏调查护栏块中的内容 消息：护栏调查护栏块中的内容  | 系统：护栏不评估任何内容 消息：护栏调查护栏块中的内容 | 
|  **消息不包含护栏块**  |  系统：护栏调查护栏块中的内容 消息：护栏评估所有内容  |  系统：护栏不评估任何内容 消息：护栏评估所有内容  | 

## 在使用 Converse API 时处理响应
<a name="guardrails-use-converse-api-response"></a>

当您调用 Converse 操作时，护栏会评估您发送的消息。如果护栏检测到被屏蔽的内容，会发生以下情况。
+ 响应中的 `stopReason` 字段会被设置为 `guardrail_intervened`。
+ 如果您启用了跟踪，则跟踪在 `trace` ([ConverseTrace](https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_ConverseTrace.html)) 字段中可用。使用`ConverseStream`，跟踪位于操作返回的元数据 ([ConverseStreamMetadataEvent](https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_ConverseStreamMetadataEvent.html)) 中。
+ 在 `output` ([ConverseOutput](https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_ConverseOutput.html)) 字段中返回您在护栏中配置的屏蔽内容文本。如果您使用 `ConverseStream`，被屏蔽的内容文本会显示在流式传输消息中。

以下提供了部分响应，展示了被屏蔽的内容文本和来自护栏评估的跟踪信息。护栏屏蔽了消息中的 *Heavy metal* 这一词汇。

```
{
    "output": {
        "message": {
            "role": "assistant",
            "content": [
                {
                    "text": "Sorry, I can't answer questions about heavy metal music."
                }
            ]
        }
    },
    "stopReason": "guardrail_intervened",
    "usage": {
        "inputTokens": 0,
        "outputTokens": 0,
        "totalTokens": 0
    },
    "metrics": {
        "latencyMs": 721
    },
    "trace": {
        "guardrail": {
            "inputAssessment": {
                "3o06191495ze": {
                    "topicPolicy": {
                        "topics": [
                            {
                                "name": "Heavy metal",
                                "type": "DENY",
                                "action": "BLOCKED"
                            }
                        ]
                    },
                    "invocationMetrics": {
                        "guardrailProcessingLatency": 240,
                        "usage": {
                            "topicPolicyUnits": 1,
                            "contentPolicyUnits": 0,
                            "wordPolicyUnits": 0,
                            "sensitiveInformationPolicyUnits": 0,
                            "sensitiveInformationPolicyFreeUnits": 0,
                            "contextualGroundingPolicyUnits": 0
                        },
                        "guardrailCoverage": {
                            "textCharacters": {
                                "guarded": 39,
                                "total": 72
                            }
                        }
                    }
                }
            }
        }
    }
}
```

## 使用 Converse API 和护栏的代码示例
<a name="converse-api-guardrail-example"></a>

以下示例展示了如何使用 `Converse` 和 `ConverseStream` 操作来保护对话，还展示了如何防止模型创建包含重金属歌曲的播放列表。

**保护对话**

1. 按照[创建护栏](guardrails-components.md)中的说明创建护栏。
   + **名称** – 输入 *Heavy metal*。
   + **主题定义** – 输入 *Avoid mentioning songs that are from the heavy metal genre of music*。
   + **添加示例短语** – 输入 *Create a playlist of heavy metal songs*。

   在步骤 9 中，输入以下内容：
   + **对于被屏蔽的提示，系统显示的消息** – 输入 *Sorry, I can't answer questions about heavy metal music*。
   + **对于被屏蔽的响应，系统显示的消息** – 输入 *Sorry, the model generated an answer that mentioned heavy metal music*。

   您可以配置其他护栏选项，但在本示例中不是必填项。

1. 按照[创建护栏的版本](guardrails-versions-create.md)中的说明创建护栏的版本。

1. 在以下代码示例（[Converse](#converse-api-guardrail-example-converse) 和 [ConverseStream](#converse-api-guardrail-example-converse-stream)）中，设置以下变量：
   + `guardrail_id` – 您在第 1 步中创建的护栏的 ID。
   + `guardrail_version` – 您在第 2 步中创建的护栏的版本。
   + `text` – 使用 `Create a playlist of heavy metal songs.`。

1. 运行示例代码。输出应该显示护栏评估和输出消息 `Text: Sorry, I can't answer questions about heavy metal music.`。护栏输入评估表明，模型在输入消息中检测到了 *heavy metal* 这一词汇。

1. 通过将 `text` 的值改为 *List all genres of rock music.*，测试护栏能否屏蔽模型生成的不当文本内容。再次运行示例代码。您应该会在响应中看到输出评估。

------
#### [ Converse ]

以下代码将您的护栏与 `Converse` 结合使用。

```
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0
"""
Shows how to use a guardrail with the <noloc>Converse</noloc> API.
"""

import logging
import json
import boto3


from botocore.exceptions import ClientError


logger = logging.getLogger(__name__)
logging.basicConfig(level=logging.INFO)


def generate_conversation(bedrock_client,
                          model_id,
                          messages,
                          guardrail_config):
    """
    Sends a message to a model.
    Args:
        bedrock_client: The Boto3 Bedrock runtime client.
        model_id (str): The model ID to use.
        messages JSON): The message to send to the model.
        guardrail_config : Configuration for the guardrail.

    Returns:
        response (JSON): The conversation that the model generated.

    """

    logger.info("Generating message with model %s", model_id)

    # Send the message.
    response = bedrock_client.converse(
        modelId=model_id,
        messages=messages,
        guardrailConfig=guardrail_config
    )

    return response


def main():
    """
    Entrypoint for example.
    """

    logging.basicConfig(level=logging.INFO,
                        format="%(levelname)s: %(message)s")

    # The model to use.
    model_id="meta.llama3-8b-instruct-v1:0"

    # The ID and version of the guardrail.
    guardrail_id = "Your guardrail ID"
    guardrail_version = "DRAFT"

    # Configuration for the guardrail.
    guardrail_config = {
        "guardrailIdentifier": guardrail_id,
        "guardrailVersion": guardrail_version,
        "trace": "enabled"
    }

    text = "Create a playlist of 2 heavy metal songs."
    context_text = "Only answer with a list of songs."

    # The message for the model and the content that you want the guardrail to assess.
    messages = [
        {
            "role": "user",
            "content": [
                {
                    "text": context_text,
                },
                {
                    "guardContent": {
                        "text": {
                            "text": text
                        }
                    }
                }
            ]
        }
    ]

    try:

        print(json.dumps(messages, indent=4))

        bedrock_client = boto3.client(service_name='bedrock-runtime')

        response = generate_conversation(
            bedrock_client, model_id, messages, guardrail_config)

        output_message = response['output']['message']

        if response['stopReason'] == "guardrail_intervened":
            trace = response['trace']
            print("Guardrail trace:")
            print(json.dumps(trace['guardrail'], indent=4))

        for content in output_message['content']:
            print(f"Text: {content['text']}")

    except ClientError as err:
        message = err.response['Error']['Message']
        logger.error("A client error occurred: %s", message)
        print(f"A client error occured: {message}")

    else:
        print(
            f"Finished generating text with model {model_id}.")


if __name__ == "__main__":
    main()
```

------
#### [ ConverseStream ]

以下代码将您的护栏与 `ConverseStream` 结合使用。

```
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0
"""
Shows how to use a guardrail with the ConverseStream operation.
"""

import logging
import json
import boto3


from botocore.exceptions import ClientError


logger = logging.getLogger(__name__)
logging.basicConfig(level=logging.INFO)


def stream_conversation(bedrock_client,
                    model_id,
                    messages,
                    guardrail_config):
    """
    Sends messages to a model and streams the response.
    Args:
        bedrock_client: The Boto3 Bedrock runtime client.
        model_id (str): The model ID to use.
        messages (JSON) : The messages to send.
        guardrail_config : Configuration for the guardrail.


    Returns:
        Nothing.

    """

    logger.info("Streaming messages with model %s", model_id)

    response = bedrock_client.converse_stream(
        modelId=model_id,
        messages=messages,
        guardrailConfig=guardrail_config
    )

    stream = response.get('stream')
    if stream:
        for event in stream:

            if 'messageStart' in event:
                print(f"\nRole: {event['messageStart']['role']}")

            if 'contentBlockDelta' in event:
                print(event['contentBlockDelta']['delta']['text'], end="")

            if 'messageStop' in event:
                print(f"\nStop reason: {event['messageStop']['stopReason']}")

            if 'metadata' in event:
                metadata = event['metadata']
                if 'trace' in metadata:
                    print("\nAssessment")
                    print(json.dumps(metadata['trace'], indent=4))


def main():
    """
    Entrypoint for streaming message API response example.
    """

    logging.basicConfig(level=logging.INFO,
                        format="%(levelname)s: %(message)s")

    # The model to use.
    model_id = "amazon.titan-text-express-v1"

    # The ID and version of the guardrail.
    guardrail_id = "Change to your guardrail ID"
    guardrail_version = "DRAFT"

    # Configuration for the guardrail.
    guardrail_config = {
        "guardrailIdentifier": guardrail_id,
        "guardrailVersion": guardrail_version,
        "trace": "enabled",
        "streamProcessingMode" : "sync"
    }

    text = "Create a playlist of heavy metal songs."
  
    # The message for the model and the content that you want the guardrail to assess.
    messages = [
        {
            "role": "user",
            "content": [
                {
                    "text": text,
                },
                {
                    "guardContent": {
                        "text": {
                            "text": text
                        }
                    }
                }
            ]
        }
    ]

    try:
        bedrock_client = boto3.client(service_name='bedrock-runtime')

        stream_conversation(bedrock_client, model_id, messages,
                        guardrail_config)

    except ClientError as err:
        message = err.response['Error']['Message']
        logger.error("A client error occurred: %s", message)
        print("A client error occured: " +
              format(message))

    else:
        print(
            f"Finished streaming messages with model {model_id}.")


if __name__ == "__main__":
    main()
```

------