与 Amazon Bedrock 流对话 - Amazon Bedrock

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

与 Amazon Bedrock 流对话

注意

Amazon Bedrock 流多轮对话在 Amazon Bedrock 中为预览版,可能会有更改。

Amazon Bedrock 流多轮对话支持用户和流之间的动态来回对话,类似于自然对话。当代理节点需要澄清或更多上下文时,它可以智能地暂停流的执行并提示用户输入特定信息。这就创造了一种更具互动性和情境感知性的体验,因为节点可以根据用户的响应调整其行为。例如,如果初始用户查询不明确或不完整,节点可以提出后续问题以收集必要的详细信息。用户提供所请求的信息后,流将使用扩充后的输入无缝恢复执行,从而确保结果更加准确和相关。对于单次交互可能不足以完全理解和满足用户需求的复杂场景来说,此功能特别有用。

如何在流中处理多轮对话

要在流中使用多轮对话,您需要一个连接到 Amazon Bedrock 代理的代理节点。运行流时,如果代理需要从用户处获得更多信息才能继续,就会发生多轮对话。此部分将介绍一个流,该流使用的代理遵循以下指令:

You are a playlist creator for a radio station. When asked to create a playlist, ask for the number of songs, the genre of music, and a theme for the playlist.

有关创建代理的信息,请参阅使用人工智能代理在应用程序中自动执行任务

步骤 1:启动流

您可以通过调用 InvokeFlow 操作来启动流。您需要添加要发送到流的初始内容。在以下示例中,document 字段包含创建播放列表的请求。每个对话都有一个唯一标识符(执行 ID),用于标识流中的对话。要获取执行 ID,您无需在首次调用 InvokeFlow 时发送 executionID 字段。来自 InvokeFlow 的响应包含执行 ID。在您的代码中,请使用标识符跟踪多个对话,并在后续调用 InvokeFlow 操作时标识一个对话。

以下是调用 InvokeFlow 的请求的示例 JSON。

{ "flowIdentifier": "XXXXXXXXXX", "flowAliasIdentifier": "YYYYYYYYYY", "inputs": [ { "content": { "document": "Create a playlist." }, "nodeName": "FlowInputNode", "nodeOutputName": "document" } ] }

步骤 2:检索代理请求

如果流中的代理节点确定需要从用户处获得更多信息,来自 InvokeFlow 的响应流(responseStream)将包含一个 FlowMultiTurnInputRequestEvent 事件对象。该事件的 contentFlowMultiTurnInputContent)字段中包含要求提供的信息。在以下示例中,document 字段中的请求是获取有关播放列表的歌曲数量、音乐流派和主题的信息。在您的代码中,您随后需要从用户处获取这些信息。

以下是 FlowMultiTurnInputRequestEvent JSON 对象的示例:

{ "nodeName": "AgentsNode_1", "nodeType": "AgentNode", "content": { "document": "Certainly! I'd be happy to create a playlist for you. To make sure it's tailored to your preferences, could you please provide me with the following information: 1. How many songs would you like in the playlist? 2. What genre of music do you prefer? 3. Is there a specific theme or mood you'd like for the playlist? Once you provide these details, I'll be able to create a customized playlist just for you." } }

由于在收到更多输入之前流无法继续,因此流还会发出一个 FlowCompletionEvent 事件。流总是在 FlowCompletionEvent 之前发出 FlowMultiTurnInputRequestEvent。如果 FlowCompletionEvent 事件中的 completionReason 的值为 INPUT_REQUIRED,则流需要更多信息才能继续。

以下是 FlowCompletionEvent JSON 对象的示例:

{ "completionReason": "INPUT_REQUIRED" }

步骤 3:将用户响应发送到流

再次调用 InvokeFlow 操作将用户响应发送回流。务必包含对话的 executionId

以下是调用 InvokeFlow 的请求的示例 JSON。document 字段包含来自用户的响应。

{ "flowIdentifier": "AUS7BMHXBE", "flowAliasIdentifier": "4KUDB8VBEF", "executionId": "b6450554-f8cc-4934-bf46-f66ed89b60a0", "inputs": [ { "content": { "document": "1. 5 songs 2. Welsh rock music 3. Castles" }, "nodeName": "AgentsNode_1", "nodeInputName": "agentInputText" } ] }

如果流需要更多信息,流会创建更多 FlowMultiTurnInputRequestEvent 事件。

步骤 4:结束流

当不需要更多信息时,流会发出一个包含最终响应的 FlowOutputEvent 事件。

以下是 FlowOutputEvent JSON 对象的示例:

{ "nodeName": "FlowOutputNode", "content": { "document": "Great news! I've created a 5-song Welsh rock playlist centered around the theme of castles. Here's the playlist I've put together for you: Playlist Name: Welsh Rock Castle Anthems Description: A 5-song Welsh rock playlist featuring songs about castles Songs: 1. Castell y Bere - Super Furry Animals 2. The Castle - Manic Street Preachers 3. Caerdydd (Cardiff Castle) - Stereophonics 4. Castell Coch - Catatonia 5. Chepstow Castle - Feeder This playlist combines Welsh rock bands with songs that reference castles or specific Welsh castles. Enjoy your castle-themed Welsh rock music experience!" } }

流还会发出一个 FlowCompletionEvent 事件。completionReason 的值为 SUCCESS

以下是 FlowCompletionEvent JSON 对象的示例:

{ "completionReason": "SUCCESS" }

以下序列图显示了多轮流中的步骤。

多轮对话的流步骤。

创建并运行示例流

在此示例中,您将创建一个使用代理为电台创建播放列表的流。代理要求澄清问题,以确定播放列表的歌曲数量、音乐流派和主题。

创建流
  1. 按照手动创建和配置代理中的说明在 Amazon Bedrock 控制台中创建代理。

    • 对于步骤 2.d,请输入 You are a playlist creator for a radio station. When asked to create a playlist, ask for the number of songs, the genre of music, and a theme for the playlist.

    • 对于步骤 2.e,请在用户输入中选择已启用。这样做可以让代理根据需求请求更多信息。

  2. 按照在 Amazon Bedrock 中创建和设计流中的说明创建流。确保流具有输入节点、代理节点和输出节点。

  3. 将代理节点链接到您在步骤 1 中创建的代理。流应类似下图内容。

    流多轮对话
  4. 在 Amazon Bedrock 控制台中运行流。在测试时,您可以跟踪流执行的步骤。有关更多信息,请参阅在 Amazon Bedrock 中测试流

以下 Python 代码示例演示如何使用流。

要运行该代码,请指定以下内容:

  • region_name – 您运行流的 AWS 区域。

  • FLOW_ID – 流的 ID。

  • FLOW_ALIAS_ID – 流的别名 ID。

有关获取这些 ID 的信息,请参阅在 Amazon Bedrock 中查看有关流的信息。该代码会提示输入要向流发送的初始请求,然后根据流的需求请求更多输入。该代码不会管理来自代理的其他请求,例如调用 AWS Lambda 函数的请求。有关更多信息,请参阅Amazon Bedrock 代理的工作原理。运行时,代码会生成 FlowTraceEvent 对象,您可以使用这些对象来跟踪从输入到流返回的响应的路径。有关更多信息,请参阅通过在 Amazon Bedrock 中查看流中每一步的跟踪记录来跟踪流中的每一步

""" Runs an Amazon Bedrock flow and handles muli-turn interaction for a single conversation. """ import logging import boto3 import botocore import botocore.exceptions logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) def invoke_flow(client, flow_id, flow_alias_id, input_data, execution_id): """ Invoke an Amazon Bedrock flow and handle the response stream. Args: client: Boto3 client for Amazon Bedrock agent runtime flow_id: The ID of the flow to invoke flow_alias_id: The alias ID of the flow input_data: Input data for the flow execution_id: Execution ID for continuing a flow. Use the value None on first run. Returns: Dict containing flow_complete status, input_required info, and execution_id """ response = None request_params = None if execution_id is None: # Don't pass execution ID for first run. request_params = { "flowIdentifier": flow_id, "flowAliasIdentifier": flow_alias_id, "inputs": [input_data], "enableTrace": True } else: request_params = { "flowIdentifier": flow_id, "flowAliasIdentifier": flow_alias_id, "executionId": execution_id, "inputs": [input_data], "enableTrace": True } response = client.invoke_flow(**request_params) if "executionId" not in request_params: execution_id = response['executionId'] input_required = None flow_status = "" # Process the streaming response for event in response['responseStream']: # Check if flow is complete. if 'flowCompletionEvent' in event: flow_status = event['flowCompletionEvent']['completionReason'] # Check if more input us needed from user. elif 'flowMultiTurnInputRequestEvent' in event: input_required = event # Print the model output. elif 'flowOutputEvent' in event: print(event['flowOutputEvent']['content']['document']) elif 'flowTraceEvent' in event: logger.info("Flow trace: %s", event['flowTraceEvent']) return { "flow_status": flow_status, "input_required": input_required, "execution_id": execution_id } if __name__ == "__main__": session = boto3.Session(profile_name='default', region_name='YOUR_FLOW_REGION') bedrock_agent_client = session.client('bedrock-agent-runtime') # Replace these with your actual flow ID and alias ID FLOW_ID = 'YOUR_FLOW_ID' FLOW_ALIAS_ID = 'YOUR_FLOW_ALIAS_ID' flow_execution_id = None finished = False # Get the intial prompt from the user. user_input = input("Enter input: ") flow_input_data = { "content": { "document": user_input }, "nodeName": "FlowInputNode", "nodeOutputName": "document" } logger.info("Starting flow %s", FLOW_ID) try: while not finished: # Invoke the flow until successfully finished. result = invoke_flow( bedrock_agent_client, FLOW_ID, FLOW_ALIAS_ID, flow_input_data, flow_execution_id) status = result['flow_status'] flow_execution_id = result['execution_id'] more_input = result['input_required'] if status == "INPUT_REQUIRED": # The flow needs more information from the user. logger.info("The flow %s requires more input", FLOW_ID) user_input = input( more_input['flowMultiTurnInputRequestEvent']['content']['document'] + ": ") flow_input_data = { "content": { "document": user_input }, "nodeName": more_input['flowMultiTurnInputRequestEvent']['nodeName'], "nodeInputName": "agentInputText" } elif status == "SUCCESS": # The flow completed successfully. finished = True logger.info("The flow %s successfully completed.", FLOW_ID) except botocore.exceptions.ClientError as e: print(f"Client error: {str(e)}") logger.error("Client error: %s", {str(e)}) except Exception as e: print(f"An error occurred: {str(e)}") logger.error("An error occurred: %s", {str(e)}) logger.error("Error type: %s", {type(e)})