{ "cells": [ { "cell_type": "markdown", "id": "cc2b57e5-9ba9-4146-bd85-963b561d3b87", "metadata": {}, "source": [ "# Quick Start Guide: Enhanced Converse API\n", "\n", "This guide shows you how to use `aws_bedrock_runtime_mate` to build multi-round conversations with Amazon Bedrock models. This library provides a simpler, more intuitive API than the raw boto3 client.\n", "\n", "## Setup" ] }, { "cell_type": "code", "execution_count": 1, "id": "b3529232-43f4-4ea3-ad58-db2f841eb4e9", "metadata": {}, "outputs": [], "source": [ "# Import aws_bedrock_runtime_mate\n", "import aws_bedrock_runtime_mate.api as aws_bedrock_runtime_mate" ] }, { "cell_type": "code", "execution_count": 2, "id": "cf1fdf52-a193-4539-a246-13d54a77f8af", "metadata": { "ExecuteTime": { "end_time": "2023-09-25T15:36:14.929877Z", "start_time": "2023-09-25T15:36:14.925278Z" } }, "outputs": [], "source": [ "# Initialize the Bedrock Runtime client\n", "import boto3\n", "from rich import print as rprint\n", "\n", "boto_ses = boto3.Session(profile_name=\"esc_app_dev_us_east_1\")\n", "bdrt_client = boto_ses.client(\"bedrock-runtime\")" ] }, { "cell_type": "markdown", "id": "38822f4b-ab6d-417c-8455-93738eb2a8dc", "metadata": {}, "source": [ "## Example: Multi-Round Conversation\n", "\n", "We'll build a chatbot that remembers information across multiple turns." ] }, { "cell_type": "code", "execution_count": 3, "id": "7e12d1c6-dbac-417d-94dc-f072598368f8", "metadata": {}, "outputs": [], "source": [ "# Test messages\n", "msg_1 = \"Remember this, my name is Lea Katsurou, my date of birth is 1993-08-14. Say 'Yes I got it' if you understand.\"\n", "msg_2 = \"What is my name?\"" ] }, { "cell_type": "markdown", "id": "668879e3-a516-4232-93bc-7392e538fc81", "metadata": {}, "source": [ "## 1. Non-Streaming Conversations with ChatSession\n", "\n", "`ChatSession` automatically manages conversation history, so you don't need to manually track messages.\n", "\n", "### Create a Chat Session" ] }, { "cell_type": "code", "execution_count": 4, "id": "084695eb-0663-40ec-880d-484b6efa212d", "metadata": {}, "outputs": [], "source": [ "# Initialize session with default configuration\n", "default_converse_kwargs=aws_bedrock_runtime_mate.ConverseKwargs(\n", " model_id=\"us.amazon.nova-micro-v1:0\",\n", ") # we can reuse this later\n", "\n", "chat_session = aws_bedrock_runtime_mate.patterns.ChatSession(\n", " client=bdrt_client,\n", " converse_kwargs=default_converse_kwargs,\n", " verbose=True,\n", ")" ] }, { "cell_type": "markdown", "id": "c25be9ea-bc6f-42bb-9de7-7b795171ca47", "metadata": {}, "source": [ "### Send Messages" ] }, { "cell_type": "code", "execution_count": 6, "id": "7a0fc8b4-1304-4867-9f13-1bb1fd87bb26", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
===== Send messages, n_msg = 1, hash = 1656d481c066934d1296a1e4359cc31c\n",
"\n"
],
"text/plain": [
"===== Send messages, n_msg = \u001b[1;36m1\u001b[0m, hash = 1656d481c066934d1296a1e4359cc31c\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"----- Converse kwargs:\n",
"\n"
],
"text/plain": [
"----- Converse kwargs:\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"{\n", " 'modelId': 'us.amazon.nova-micro-v1:0',\n", " 'messages': [\n", " {\n", " 'role': 'user',\n", " 'content': [\n", " {\n", " 'text': \"Remember this, my name is Lea Katsurou, my date of birth is 1993-08-14. Say 'Yes I got\n", "it' if you understand.\"\n", " }\n", " ]\n", " }\n", " ]\n", "}\n", "\n" ], "text/plain": [ "\u001b[1m{\u001b[0m\n", " \u001b[32m'modelId'\u001b[0m: \u001b[32m'us.amazon.nova-micro-v1:0'\u001b[0m,\n", " \u001b[32m'messages'\u001b[0m: \u001b[1m[\u001b[0m\n", " \u001b[1m{\u001b[0m\n", " \u001b[32m'role'\u001b[0m: \u001b[32m'user'\u001b[0m,\n", " \u001b[32m'content'\u001b[0m: \u001b[1m[\u001b[0m\n", " \u001b[1m{\u001b[0m\n", " \u001b[32m'text'\u001b[0m: \u001b[32m\"Remember this, my name is Lea Katsurou, my date of birth is 1993-08-14. Say 'Yes I got\u001b[0m\n", "\u001b[32mit' if you understand.\"\u001b[0m\n", " \u001b[1m}\u001b[0m\n", " \u001b[1m]\u001b[0m\n", " \u001b[1m}\u001b[0m\n", " \u001b[1m]\u001b[0m\n", "\u001b[1m}\u001b[0m\n" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
----- Converse response:\n",
"\n"
],
"text/plain": [
"----- Converse response:\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"{\n", " 'output': {\n", " 'message': {\n", " 'role': 'assistant',\n", " 'content': [\n", " {\n", " 'text': \"Yes, I've got it. Your name is Lea Katsurou, and your date of birth is August 14, \n", "1993. If you need anything else or have any questions, feel free to let me know!\"\n", " }\n", " ]\n", " }\n", " },\n", " 'stopReason': 'end_turn',\n", " 'usage': {'inputTokens': 38, 'outputTokens': 49, 'totalTokens': 87},\n", " 'metrics': {'latencyMs': 591}\n", "}\n", "\n" ], "text/plain": [ "\u001b[1m{\u001b[0m\n", " \u001b[32m'output'\u001b[0m: \u001b[1m{\u001b[0m\n", " \u001b[32m'message'\u001b[0m: \u001b[1m{\u001b[0m\n", " \u001b[32m'role'\u001b[0m: \u001b[32m'assistant'\u001b[0m,\n", " \u001b[32m'content'\u001b[0m: \u001b[1m[\u001b[0m\n", " \u001b[1m{\u001b[0m\n", " \u001b[32m'text'\u001b[0m: \u001b[32m\"Yes, I've got it. Your name is Lea Katsurou, and your date of birth is August 14, \u001b[0m\n", "\u001b[32m1993. If you need anything else or have any questions, feel free to let me know!\"\u001b[0m\n", " \u001b[1m}\u001b[0m\n", " \u001b[1m]\u001b[0m\n", " \u001b[1m}\u001b[0m\n", " \u001b[1m}\u001b[0m,\n", " \u001b[32m'stopReason'\u001b[0m: \u001b[32m'end_turn'\u001b[0m,\n", " \u001b[32m'usage'\u001b[0m: \u001b[1m{\u001b[0m\u001b[32m'inputTokens'\u001b[0m: \u001b[1;36m38\u001b[0m, \u001b[32m'outputTokens'\u001b[0m: \u001b[1;36m49\u001b[0m, \u001b[32m'totalTokens'\u001b[0m: \u001b[1;36m87\u001b[0m\u001b[1m}\u001b[0m,\n", " \u001b[32m'metrics'\u001b[0m: \u001b[1m{\u001b[0m\u001b[32m'latencyMs'\u001b[0m: \u001b[1;36m591\u001b[0m\u001b[1m}\u001b[0m\n", "\u001b[1m}\u001b[0m\n" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# First turn: Store information\n", "response = chat_session.converse_text(msg_1)" ] }, { "cell_type": "code", "execution_count": 7, "id": "ed47818d-ce3b-48f8-9483-012cf253e606", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Yes, I've got it. Your name is Lea Katsurou, and your date of birth is August 14, 1993. If you need anything else or have any questions, feel free to let me know!\n" ] } ], "source": [ "# The .text property provides convenient access to the response text\n", "print(response.text)" ] }, { "cell_type": "markdown", "id": "b8ea7a87-5e6e-40bd-8480-681939b3d8c6", "metadata": {}, "source": [ "### Continue the Conversation\n", "\n", "The session automatically remembers previous messages!" ] }, { "cell_type": "code", "execution_count": 8, "id": "d969e5e5-66d0-4884-afd9-54a1d5eb171f", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
===== Send messages, n_msg = 3, hash = 0853a9d3987dcfd5271cddcc2175743a\n",
"\n"
],
"text/plain": [
"===== Send messages, n_msg = \u001b[1;36m3\u001b[0m, hash = 0853a9d3987dcfd5271cddcc2175743a\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"----- Converse kwargs:\n",
"\n"
],
"text/plain": [
"----- Converse kwargs:\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"{\n", " 'modelId': 'us.amazon.nova-micro-v1:0',\n", " 'messages': [\n", " {\n", " 'role': 'user',\n", " 'content': [\n", " {\n", " 'text': \"Remember this, my name is Lea Katsurou, my date of birth is 1993-08-14. Say 'Yes I got\n", "it' if you understand.\"\n", " }\n", " ]\n", " },\n", " {\n", " 'role': 'assistant',\n", " 'content': [\n", " {\n", " 'text': \"Yes, I've got it. Your name is Lea Katsurou, and your date of birth is August 14, \n", "1993. If you need anything else or have any questions, feel free to let me know!\"\n", " }\n", " ]\n", " },\n", " {'role': 'user', 'content': [{'text': 'What is my name?'}]}\n", " ]\n", "}\n", "\n" ], "text/plain": [ "\u001b[1m{\u001b[0m\n", " \u001b[32m'modelId'\u001b[0m: \u001b[32m'us.amazon.nova-micro-v1:0'\u001b[0m,\n", " \u001b[32m'messages'\u001b[0m: \u001b[1m[\u001b[0m\n", " \u001b[1m{\u001b[0m\n", " \u001b[32m'role'\u001b[0m: \u001b[32m'user'\u001b[0m,\n", " \u001b[32m'content'\u001b[0m: \u001b[1m[\u001b[0m\n", " \u001b[1m{\u001b[0m\n", " \u001b[32m'text'\u001b[0m: \u001b[32m\"Remember this, my name is Lea Katsurou, my date of birth is 1993-08-14. Say 'Yes I got\u001b[0m\n", "\u001b[32mit' if you understand.\"\u001b[0m\n", " \u001b[1m}\u001b[0m\n", " \u001b[1m]\u001b[0m\n", " \u001b[1m}\u001b[0m,\n", " \u001b[1m{\u001b[0m\n", " \u001b[32m'role'\u001b[0m: \u001b[32m'assistant'\u001b[0m,\n", " \u001b[32m'content'\u001b[0m: \u001b[1m[\u001b[0m\n", " \u001b[1m{\u001b[0m\n", " \u001b[32m'text'\u001b[0m: \u001b[32m\"Yes, I've got it. Your name is Lea Katsurou, and your date of birth is August 14, \u001b[0m\n", "\u001b[32m1993. If you need anything else or have any questions, feel free to let me know!\"\u001b[0m\n", " \u001b[1m}\u001b[0m\n", " \u001b[1m]\u001b[0m\n", " \u001b[1m}\u001b[0m,\n", " \u001b[1m{\u001b[0m\u001b[32m'role'\u001b[0m: \u001b[32m'user'\u001b[0m, \u001b[32m'content'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m{\u001b[0m\u001b[32m'text'\u001b[0m: \u001b[32m'What is my name?'\u001b[0m\u001b[1m}\u001b[0m\u001b[1m]\u001b[0m\u001b[1m}\u001b[0m\n", " \u001b[1m]\u001b[0m\n", "\u001b[1m}\u001b[0m\n" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
----- Converse response:\n",
"\n"
],
"text/plain": [
"----- Converse response:\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"{\n", " 'output': {\n", " 'message': {\n", " 'role': 'assistant',\n", " 'content': [\n", " {\n", " 'text': 'Your name is Lea Katsurou. If you need any further assistance or have any questions, \n", "just let me know!'\n", " }\n", " ]\n", " }\n", " },\n", " 'stopReason': 'end_turn',\n", " 'usage': {'inputTokens': 97, 'outputTokens': 23, 'totalTokens': 120},\n", " 'metrics': {'latencyMs': 342}\n", "}\n", "\n" ], "text/plain": [ "\u001b[1m{\u001b[0m\n", " \u001b[32m'output'\u001b[0m: \u001b[1m{\u001b[0m\n", " \u001b[32m'message'\u001b[0m: \u001b[1m{\u001b[0m\n", " \u001b[32m'role'\u001b[0m: \u001b[32m'assistant'\u001b[0m,\n", " \u001b[32m'content'\u001b[0m: \u001b[1m[\u001b[0m\n", " \u001b[1m{\u001b[0m\n", " \u001b[32m'text'\u001b[0m: \u001b[32m'Your name is Lea Katsurou. If you need any further assistance or have any questions, \u001b[0m\n", "\u001b[32mjust let me know!'\u001b[0m\n", " \u001b[1m}\u001b[0m\n", " \u001b[1m]\u001b[0m\n", " \u001b[1m}\u001b[0m\n", " \u001b[1m}\u001b[0m,\n", " \u001b[32m'stopReason'\u001b[0m: \u001b[32m'end_turn'\u001b[0m,\n", " \u001b[32m'usage'\u001b[0m: \u001b[1m{\u001b[0m\u001b[32m'inputTokens'\u001b[0m: \u001b[1;36m97\u001b[0m, \u001b[32m'outputTokens'\u001b[0m: \u001b[1;36m23\u001b[0m, \u001b[32m'totalTokens'\u001b[0m: \u001b[1;36m120\u001b[0m\u001b[1m}\u001b[0m,\n", " \u001b[32m'metrics'\u001b[0m: \u001b[1m{\u001b[0m\u001b[32m'latencyMs'\u001b[0m: \u001b[1;36m342\u001b[0m\u001b[1m}\u001b[0m\n", "\u001b[1m}\u001b[0m\n" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Second turn: Test memory\n", "response = chat_session.converse_text(msg_2)" ] }, { "cell_type": "code", "execution_count": 9, "id": "7849adc9-5f38-455f-9285-220880f9b1b1", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Your name is Lea Katsurou. If you need any further assistance or have any questions, just let me know!\n" ] } ], "source": [ "print(response.text)" ] }, { "cell_type": "markdown", "id": "74444a0d-fc02-48ae-8b1f-14d184ea8a78", "metadata": {}, "source": [ "## 2. Streaming Conversations with ChatSession\n", "\n", "Streaming is perfect for real-time applications where you want to display responses as they arrive.\n", "\n", "### Create a New Session" ] }, { "cell_type": "code", "execution_count": 10, "id": "5430aa8e-cabb-468b-b4b2-ec9b433b50a9", "metadata": {}, "outputs": [], "source": [ "chat_session = aws_bedrock_runtime_mate.patterns.ChatSession(\n", " client=bdrt_client,\n", " converse_kwargs=default_converse_kwargs,\n", " verbose=True,\n", ")" ] }, { "cell_type": "markdown", "id": "e70e57bb-b31e-46b9-b5fd-363fb3c1a023", "metadata": {}, "source": [ "### Send Streaming Message" ] }, { "cell_type": "code", "execution_count": 11, "id": "97c1f6bf-b957-4255-943d-29d610a2d1f9", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
===== Send messages, n_msg = 1, hash = 1656d481c066934d1296a1e4359cc31c\n",
"\n"
],
"text/plain": [
"===== Send messages, n_msg = \u001b[1;36m1\u001b[0m, hash = 1656d481c066934d1296a1e4359cc31c\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"----- Converse kwargs:\n",
"\n"
],
"text/plain": [
"----- Converse kwargs:\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"{\n", " 'modelId': 'us.amazon.nova-micro-v1:0',\n", " 'messages': [\n", " {\n", " 'role': 'user',\n", " 'content': [\n", " {\n", " 'text': \"Remember this, my name is Lea Katsurou, my date of birth is 1993-08-14. Say 'Yes I got\n", "it' if you understand.\"\n", " }\n", " ]\n", " }\n", " ]\n", "}\n", "\n" ], "text/plain": [ "\u001b[1m{\u001b[0m\n", " \u001b[32m'modelId'\u001b[0m: \u001b[32m'us.amazon.nova-micro-v1:0'\u001b[0m,\n", " \u001b[32m'messages'\u001b[0m: \u001b[1m[\u001b[0m\n", " \u001b[1m{\u001b[0m\n", " \u001b[32m'role'\u001b[0m: \u001b[32m'user'\u001b[0m,\n", " \u001b[32m'content'\u001b[0m: \u001b[1m[\u001b[0m\n", " \u001b[1m{\u001b[0m\n", " \u001b[32m'text'\u001b[0m: \u001b[32m\"Remember this, my name is Lea Katsurou, my date of birth is 1993-08-14. Say 'Yes I got\u001b[0m\n", "\u001b[32mit' if you understand.\"\u001b[0m\n", " \u001b[1m}\u001b[0m\n", " \u001b[1m]\u001b[0m\n", " \u001b[1m}\u001b[0m\n", " \u001b[1m]\u001b[0m\n", "\u001b[1m}\u001b[0m\n" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
----- Converse response:\n",
"\n"
],
"text/plain": [
"----- Converse response:\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"{'stream': <botocore.eventstream.EventStream object at 0x107d1a010>}\n", "\n" ], "text/plain": [ "\u001b[1m{\u001b[0m\u001b[32m'stream'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mbotocore.eventstream.EventStream\u001b[0m\u001b[39m object at \u001b[0m\u001b[1;36m0x107d1a010\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m\n" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Send first message with streaming enabled\n", "response = chat_session.converse_text_stream(msg_1)" ] }, { "cell_type": "markdown", "id": "d29977ad-6288-4f3a-a0da-3e7ab4f5382e", "metadata": {}, "source": [ "### Option 1: Iterate Text Only (Simplest)\n", "\n", "Most of the time, you only care about the text content. Use `iterate_text()`:" ] }, { "cell_type": "code", "execution_count": 12, "id": "cbc97c0c-89e8-4664-8177-481564dd751b", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Yes, I've got it. Your name is Lea Katsurou, and your date of birth is August 14, 1993. If you need anything else or have any questions, feel free to let me know!\n", "\n", "--- Full Response ---\n", "Yes, I've got it. Your name is Lea Katsurou, and your date of birth is August 14, 1993. If you need anything else or have any questions, feel free to let me know!\n" ] } ], "source": [ "# Collect text chunks\n", "chunks = []\n", "for text in chat_session.iterate_text(response):\n", " chunks.append(text)\n", " print(text, end=\"\", flush=True) # Stream to console\n", "print() # New line\n", "\n", "# Full response\n", "full_text = \"\".join(chunks)\n", "print(f\"\\n--- Full Response ---\\n{full_text}\")" ] }, { "cell_type": "markdown", "id": "0c3b1416-9b21-4edb-933b-4454f0cfd170", "metadata": {}, "source": [ "### Option 2: Iterate All Events (Advanced)\n", "\n", "For more control, iterate over all streaming events:" ] }, { "cell_type": "code", "execution_count": 13, "id": "238c67c1-bbb1-4900-b5d7-c106cb95abb2", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "š Message starting...\n", "Yes, I've got it. Your name is Lea Katsurou, and your date of birth is August 14, 1993. If you need anything else or have any questions, feel free to let me know!\n", "ā Done! Stop reason: end_turn\n" ] } ], "source": [ "# Process each event\n", "for event in chat_session.iterate_events(response):\n", " if event.is_messageStart():\n", " print(\"š Message starting...\")\n", " elif event.is_contentBlockDelta():\n", " if event.text:\n", " print(event.text, end=\"\", flush=True)\n", " elif event.is_messageStop():\n", " print(f\"\\nā Done! Stop reason: {event.messageStop.stopReason}\")" ] }, { "cell_type": "markdown", "id": "83f4e141-a1c8-4efc-922b-1ac57ff87c9c", "metadata": {}, "source": [ "### Option 3: One-Shot Text Extraction\n", "\n", "If you don't need real-time streaming, just get the complete text:" ] }, { "cell_type": "code", "execution_count": 15, "id": "ee2a2914-ebe6-4a13-b1e6-8606bcae598f", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
===== Send messages, n_msg = 3, hash = 0853a9d3987dcfd5271cddcc2175743a\n",
"\n"
],
"text/plain": [
"===== Send messages, n_msg = \u001b[1;36m3\u001b[0m, hash = 0853a9d3987dcfd5271cddcc2175743a\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"----- Converse kwargs:\n",
"\n"
],
"text/plain": [
"----- Converse kwargs:\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"{\n", " 'modelId': 'us.amazon.nova-micro-v1:0',\n", " 'messages': [\n", " {\n", " 'role': 'user',\n", " 'content': [\n", " {\n", " 'text': \"Remember this, my name is Lea Katsurou, my date of birth is 1993-08-14. Say 'Yes I got\n", "it' if you understand.\"\n", " }\n", " ]\n", " },\n", " {\n", " 'role': 'assistant',\n", " 'content': [\n", " {\n", " 'text': \"Yes, I've got it. Your name is Lea Katsurou, and your date of birth is August 14, \n", "1993. If you need anything else or have any questions, feel free to let me know!\"\n", " }\n", " ]\n", " },\n", " {'role': 'user', 'content': [{'text': 'What is my name?'}]}\n", " ]\n", "}\n", "\n" ], "text/plain": [ "\u001b[1m{\u001b[0m\n", " \u001b[32m'modelId'\u001b[0m: \u001b[32m'us.amazon.nova-micro-v1:0'\u001b[0m,\n", " \u001b[32m'messages'\u001b[0m: \u001b[1m[\u001b[0m\n", " \u001b[1m{\u001b[0m\n", " \u001b[32m'role'\u001b[0m: \u001b[32m'user'\u001b[0m,\n", " \u001b[32m'content'\u001b[0m: \u001b[1m[\u001b[0m\n", " \u001b[1m{\u001b[0m\n", " \u001b[32m'text'\u001b[0m: \u001b[32m\"Remember this, my name is Lea Katsurou, my date of birth is 1993-08-14. Say 'Yes I got\u001b[0m\n", "\u001b[32mit' if you understand.\"\u001b[0m\n", " \u001b[1m}\u001b[0m\n", " \u001b[1m]\u001b[0m\n", " \u001b[1m}\u001b[0m,\n", " \u001b[1m{\u001b[0m\n", " \u001b[32m'role'\u001b[0m: \u001b[32m'assistant'\u001b[0m,\n", " \u001b[32m'content'\u001b[0m: \u001b[1m[\u001b[0m\n", " \u001b[1m{\u001b[0m\n", " \u001b[32m'text'\u001b[0m: \u001b[32m\"Yes, I've got it. Your name is Lea Katsurou, and your date of birth is August 14, \u001b[0m\n", "\u001b[32m1993. If you need anything else or have any questions, feel free to let me know!\"\u001b[0m\n", " \u001b[1m}\u001b[0m\n", " \u001b[1m]\u001b[0m\n", " \u001b[1m}\u001b[0m,\n", " \u001b[1m{\u001b[0m\u001b[32m'role'\u001b[0m: \u001b[32m'user'\u001b[0m, \u001b[32m'content'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m{\u001b[0m\u001b[32m'text'\u001b[0m: \u001b[32m'What is my name?'\u001b[0m\u001b[1m}\u001b[0m\u001b[1m]\u001b[0m\u001b[1m}\u001b[0m\n", " \u001b[1m]\u001b[0m\n", "\u001b[1m}\u001b[0m\n" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
----- Converse response:\n",
"\n"
],
"text/plain": [
"----- Converse response:\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"{'stream': <botocore.eventstream.EventStream object at 0x107d58110>}\n", "\n" ], "text/plain": [ "\u001b[1m{\u001b[0m\u001b[32m'stream'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mbotocore.eventstream.EventStream\u001b[0m\u001b[39m object at \u001b[0m\u001b[1;36m0x107d58110\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m\n" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "Your name is Lea Katsurou. If you need any further assistance or have any questions, just let me know!\n" ] } ], "source": [ "# Send another message\n", "response = chat_session.converse_text_stream(msg_2)\n", "\n", "# Get complete text directly (waits for full response)\n", "print(response.text)" ] }, { "cell_type": "markdown", "id": "c53bf15f-f46c-44a9-a4ee-e335d86937a7", "metadata": {}, "source": [ "**Note**: The session automatically adds streaming responses to conversation history after consumption!" ] }, { "cell_type": "markdown", "id": "e5e8c0ca-424b-41fe-94c3-6946ebf3c563", "metadata": {}, "source": [ "## 3. Advanced: MessageContentBuilder\n", "\n", "For complex messages with multiple content types (text, images, documents), use `MessageContentBuilder`:" ] }, { "cell_type": "code", "execution_count": 17, "id": "03601f62-b9e5-49d8-8a9b-a40352a5122b", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'role': 'user', 'content': [{'text': \"What's in this image?\"}]}" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Build a multi-modal message\n", "builder = aws_bedrock_runtime_mate.MessageContentBuilder()\n", "builder.add_text(\"What's in this image?\")\n", "# builder.add_image(format=\"png\", bytes=image_bytes) # Add image from bytes\n", "# builder.add_document(name=\"report.pdf\", format=\"pdf\", bytes=pdf_bytes) # Add PDF\n", "\n", "# Send the constructed message\n", "builder.to_message()" ] }, { "cell_type": "markdown", "id": "73dc9a80-957d-4c66-9227-7c91507a034d", "metadata": {}, "source": [ "### Builder Examples" ] }, { "cell_type": "code", "execution_count": 19, "id": "a336aa4a-4ff5-4720-a2c1-1f723b01e01a", "metadata": {}, "outputs": [], "source": [ "# Example 1: Text + Image from S3\n", "builder = aws_bedrock_runtime_mate.MessageContentBuilder()\n", "builder.add_text(\"Analyze this diagram\")\n", "builder.add_image(format=\"png\", s3_uri=\"s3://my-bucket/diagram.png\")\n", "\n", "# Example 2: Chained construction\n", "message = (\n", " aws_bedrock_runtime_mate.MessageContentBuilder()\n", " .add_text(\"Review this document\")\n", " .add_document(name=\"contract.pdf\", format=\"pdf\", s3_uri=\"s3://my-bucket/contract.pdf\")\n", " .to_message()\n", ")\n", "\n", "# Example 3: Tool results (for function calling)\n", "builder = aws_bedrock_runtime_mate.MessageContentBuilder()\n", "builder.add_tool_result(\n", " tool_use_id=\"tool_abc123\",\n", " content=[{\"text\": \"The weather in Paris is 18°C and sunny\"}]\n", ")\n", "tool_result_message = builder.to_message()" ] }, { "cell_type": "markdown", "id": "300c2f4f-b1c5-4cfa-994a-dccb6425e3d6", "metadata": {}, "source": [ "## 4. Understanding Stream Events: ConverseStreamOutput\n", "\n", "When you iterate over streaming events, each event is a `ConverseStreamOutput` object with helper methods:" ] }, { "cell_type": "code", "execution_count": 21, "id": "5c450173-1712-4cfe-b63a-64d6eb3798d9", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
===== Send messages, n_msg = 1, hash = 9928b30560cbd5f1e0e4938566115560\n",
"\n"
],
"text/plain": [
"===== Send messages, n_msg = \u001b[1;36m1\u001b[0m, hash = 9928b30560cbd5f1e0e4938566115560\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"----- Converse kwargs:\n",
"\n"
],
"text/plain": [
"----- Converse kwargs:\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"{\n", " 'modelId': 'us.amazon.nova-micro-v1:0',\n", " 'messages': [{'role': 'user', 'content': [{'text': 'Tell me a super short story'}]}]\n", "}\n", "\n" ], "text/plain": [ "\u001b[1m{\u001b[0m\n", " \u001b[32m'modelId'\u001b[0m: \u001b[32m'us.amazon.nova-micro-v1:0'\u001b[0m,\n", " \u001b[32m'messages'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m{\u001b[0m\u001b[32m'role'\u001b[0m: \u001b[32m'user'\u001b[0m, \u001b[32m'content'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m{\u001b[0m\u001b[32m'text'\u001b[0m: \u001b[32m'Tell me a super short story'\u001b[0m\u001b[1m}\u001b[0m\u001b[1m]\u001b[0m\u001b[1m}\u001b[0m\u001b[1m]\u001b[0m\n", "\u001b[1m}\u001b[0m\n" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
----- Converse response:\n",
"\n"
],
"text/plain": [
"----- Converse response:\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"{'stream': <botocore.eventstream.EventStream object at 0x107daa010>}\n", "\n" ], "text/plain": [ "\u001b[1m{\u001b[0m\u001b[32m'stream'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mbotocore.eventstream.EventStream\u001b[0m\u001b[39m object at \u001b[0m\u001b[1;36m0x107daa010\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m\n" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "Message starting...\n", "Once, a tiny ant named Andy found a tiny acorn. He carried it home, but as he struggled, a gentle rain began. The acorn rolled away, and Andy watched it sink into the earth. Days later, a mighty oak sprouted where the acorn lay. Andy smiled, knowing he had helped it grow.\n", "Content block complete\n", "Stop reason: end_turn\n" ] } ], "source": [ "chat_session = aws_bedrock_runtime_mate.patterns.ChatSession(\n", " client=bdrt_client,\n", " converse_kwargs=default_converse_kwargs,\n", " verbose=True,\n", ")\n", "# Create streaming response\n", "response = chat_session.converse_text_stream(\"Tell me a super short story\")\n", "\n", "# In a streaming loop:\n", "for event in chat_session.iterate_events(response):\n", " # Check event type\n", " if event.is_messageStart():\n", " print(\"Message starting...\")\n", " elif event.is_contentBlockStart():\n", " print(\"Content block starting...\")\n", " elif event.is_contentBlockDelta():\n", " # Extract text easily\n", " if event.text:\n", " print(event.text, end=\"\")\n", " # Or extract reasoning content (for advanced models)\n", " if event.reasoning_content_text:\n", " print(f\"[Thinking: {event.reasoning_content_text}]\")\n", " elif event.is_contentBlockStop():\n", " print(\"\\nContent block complete\")\n", " elif event.is_messageStop():\n", " print(f\"Stop reason: {event.messageStop.stopReason}\")" ] }, { "cell_type": "markdown", "id": "af797ac4-bfaf-4ef5-86b3-7c66af484eb4", "metadata": {}, "source": [ "## 5. Stream Management: ConverseStreamResponse\n", "\n", "`ConverseStreamResponse` intelligently manages streaming:" ] }, { "cell_type": "code", "execution_count": 20, "id": "84fffa19-49b6-4b4d-b014-dce007a923e6", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
===== Send messages, n_msg = 1, hash = 9928b30560cbd5f1e0e4938566115560\n",
"\n"
],
"text/plain": [
"===== Send messages, n_msg = \u001b[1;36m1\u001b[0m, hash = 9928b30560cbd5f1e0e4938566115560\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"----- Converse kwargs:\n",
"\n"
],
"text/plain": [
"----- Converse kwargs:\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"{\n", " 'modelId': 'us.amazon.nova-micro-v1:0',\n", " 'messages': [{'role': 'user', 'content': [{'text': 'Tell me a super short story'}]}]\n", "}\n", "\n" ], "text/plain": [ "\u001b[1m{\u001b[0m\n", " \u001b[32m'modelId'\u001b[0m: \u001b[32m'us.amazon.nova-micro-v1:0'\u001b[0m,\n", " \u001b[32m'messages'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m{\u001b[0m\u001b[32m'role'\u001b[0m: \u001b[32m'user'\u001b[0m, \u001b[32m'content'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m{\u001b[0m\u001b[32m'text'\u001b[0m: \u001b[32m'Tell me a super short story'\u001b[0m\u001b[1m}\u001b[0m\u001b[1m]\u001b[0m\u001b[1m}\u001b[0m\u001b[1m]\u001b[0m\n", "\u001b[1m}\u001b[0m\n" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
----- Converse response:\n",
"\n"
],
"text/plain": [
"----- Converse response:\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"{'stream': <botocore.eventstream.EventStream object at 0x107e16090>}\n", "\n" ], "text/plain": [ "\u001b[1m{\u001b[0m\u001b[32m'stream'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mbotocore.eventstream.EventStream\u001b[0m\u001b[39m object at \u001b[0m\u001b[1;36m0x107e16090\u001b[0m\u001b[1m>\u001b[0m\u001b[1m}\u001b[0m\n" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "Once, a tiny ant named Andy found a giant cookie. Too big to eat alone, he called his friends. Together, they shared the cookie, learning that teamwork makes even the biggest things shareable.\n", "\n", "Cached text length: 192\n", "Stream consumed: True\n" ] } ], "source": [ "chat_session = aws_bedrock_runtime_mate.patterns.ChatSession(\n", " client=bdrt_client,\n", " converse_kwargs=default_converse_kwargs,\n", " verbose=True,\n", ")\n", "# Create streaming response\n", "response = chat_session.converse_text_stream(\"Tell me a super short story\")\n", "\n", "# First consumption: Reads from API\n", "for text in chat_session.iterate_text(response):\n", " print(text, end=\"\", flush=True)\n", "\n", "# Second consumption: Uses cached events (no new API call!)\n", "full_text = \"\".join(chat_session.iterate_text(response))\n", "print(f\"\\n\\nCached text length: {len(full_text)}\")\n", "\n", "# Check if stream was consumed\n", "print(f\"Stream consumed: {response.is_stream_consumed()}\") # True" ] }, { "cell_type": "markdown", "id": "70cabfa3-f479-44cf-8aa1-d83bce837f5d", "metadata": {}, "source": [ "**Key Features:**\n", "\n", "- **Automatic Caching**: Events are cached on first iteration\n", "- **Multiple Iterations**: Iterate multiple times without re-fetching\n", "- **History Management**: Session automatically collects messages for history\n", "- **Convenient Properties**:\n", " - `response.text` - Get complete text (waits if not consumed)\n", " - `response.message` - Get complete message structure\n", " - `response.is_stream_consumed()` - Check consumption status" ] }, { "cell_type": "code", "execution_count": null, "id": "2e228534-e37e-44e1-8062-1893e6568b39", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.11.8" } }, "nbformat": 4, "nbformat_minor": 5 }