Converse との会話を実行する - Amazon Bedrock

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

Converse との会話を実行する

Amazon Bedrock Converse を使用してAPI、Amazon Bedrock モデルとの間でメッセージを送受信する会話アプリケーションを作成できます。例えば、多くのターンにわたって会話を維持し、役に立つテクニカルサポートアシスタントなど、ニーズに固有のペルソナやトーンのカスタマイズを使用するチャットボットを作成できます。

Converse を使用するにはAPI、Converse または (ストリーミングレスポンスの場合) オペレーションを使用してモデルにメッセージを送信します。 ConverseStream会話アプリケーションには、既存の推論オペレーション (InvokeModel または InvokeModelWithResponseStream) を使用できます。ただし、メッセージをサポートするすべての Amazon Bedrock モデルで動作する一貫した APIを提供するためAPI、Converse を使用することをお勧めします。つまり、コードを 1 回記述して、異なるモデルで使用できるということです。モデルに一意の推論パラメータがある場合、Converse では、モデル固有の構造でそれらの一意のパラメータを渡すAPIこともできます。

Converse を使用してAPI、ツールの使用ガードレールをアプリケーションに実装できます。

注記

で Mistral AI また、Meta モデルでは、会話を可能にするモデル固有のプロンプトテンプレートに Converse が入力をAPI埋め込みます。

サポートされているモデルとモデル機能

Converse は、以下の Amazon Bedrock モデルとモデル機能APIをサポートしています。Converse APIは、埋め込みモデル ( など Titan Embeddings G1 - Text) または画像生成モデル (例:Stability AI).

モデル 会話 ConverseStream システムプロンプト ドキュメントチャット 視覚 ツールの使用 ストリーミングツールの使用 ガードレール

AI21 Jamba-Instruct

あり

はい

はい

いいえ

いいえ

いいえ

いいえ

なし

AI21 Labs Jurassic-2 (テキスト)

制限あり。チャットはサポートされていません。

なし

いいえ

いいえ

いいえ

いいえ

いいえ

あり

Amazon Titan モデル

あり

はい

なし

はい ( を除く Titan Text Premier)

なし

いいえ

いいえ

あり

Anthropic Claude 2 以前

あり

はい

はい

はい

いいえ

いいえ

いいえ

あり

Anthropic Claude 3

あり

はい

はい

はい

はい

はい

はい

あり

Anthropic Claude 3.5

あり

はい

はい

いいえ

はい

はい

はい

あり

Cohere Command

制限あり。チャットはサポートされていません。

制限あり。チャットはサポートされていません。

なし

はい

いいえ

いいえ

いいえ

あり

Cohere Command Light

制限あり。チャットはサポートされていません。

制限あり。チャットはサポートされていません。

なし

いいえ

いいえ

いいえ

いいえ

あり

Cohere Command R また、Command R+

あり

はい

はい

はい

いいえ

はい

いいえ

なし

Meta Llama 2 また、Llama 3

あり

はい

はい

はい

いいえ

いいえ

いいえ

はい

Meta Llama 3.1

はい

はい

はい

はい

いいえ

はい

いいえ

はい

Mistral AI Instruct

はい

はい

いいえ

はい

いいえ

いいえ

いいえ

はい

Mistral Large

はい

はい

はい

はい

いいえ

はい

いいえ

はい

Mistral Large 2 (24.07)

はい

はい

はい

はい

いいえ

はい

いいえ

はい

Mistral Small はい はい はい いいえ いいえ はい いいえ あり
注記

Cohere Command (テキスト) と AI21 Labs Jurassic-2 (テキスト) は、会話 とのチャットをサポートしていませんAPI。モデルは一度に 1 つのユーザーメッセージしか処理できず、会話の履歴を維持できません。複数のメッセージを渡そうとすると、エラーが発生します。

Converse の使用 API

Converse を使用するにはAPI、 Converseまたは ConverseStreamオペレーションを呼び出してモデルにメッセージを送信します。を呼び出すにはConversebedrock:InvokeModelオペレーションのアクセス許可が必要です。を呼び出すにはConverseStreambedrock:InvokeModelWithResponseStreamオペレーションのアクセス許可が必要です。

リクエスト

使用するモデルを指定するには、 modelIdフィールドを設定します。Amazon Bedrock がサポートIDsするモデルのリストについては、「」を参照してくださいAmazon Bedrock モデル IDs

会話は、ユーザーとモデル間の一連のメッセージです。会話を開始するには、ユーザー (ユーザーロール) としてメッセージをモデルに送信します。モデルはアシスタント (アシスタントロール ) として機能し、メッセージで返されるレスポンスを生成します。必要に応じて、さらにユーザーロールメッセージをモデルに送信することで、会話を続けることができます。会話コンテキストを維持するには、モデルから受信したアシスタントロールメッセージを後続のリクエストに必ず含めてください。サンプルコードについては、「会話APIの例」を参照してください。

messages フィールドにモデルに渡すメッセージを指定します。これは、Message オブジェクトの配列にマッピングされます。各メッセージには、メッセージのコンテンツと、会話でメッセージが再生するロールが含まれます。

注記

Amazon Bedrock は、コンテンツとして提供したテキスト、イメージ、またはドキュメントを保存しません。データはレスポンスの生成にのみ使用されます。Converse を使用する場合はAPI、サイズが 4.5 MB 未満の非圧縮およびデコードされたドキュメントを使用する必要があります。

メッセージのコンテンツは、 ContentBlock オブジェクトの配列にマッピングされる contentフィールドに保存します。各 内でContentBlock、次のいずれかのフィールドを指定できます (どのモデルがどのモダリティをサポートしているかを確認するには、「」を参照してくださいサポートされているモデルとモデル機能)。

text

text フィールドは、プロンプトを指定する文字列にマッピングされます。text フィールドは、同じ で指定されている他のフィールドと一緒に解釈されますContentBlock

以下は、テキスト のみを含むcontent配列を持つ Message オブジェクトを示していますContentBlock

{ "role": "user | assistant", "content": [ { "text": "string" } ] }
image

image フィールドは にマッピングされますImageBlock。base64 でエンコードされた raw バイトを bytesフィールドのイメージに渡します。を使用する場合 AWS SDKでは、base64 でバイトをエンコードする必要はありません。

text フィールドを除外すると、モデルはイメージを記述します。

以下は、イメージ のみを含むcontent配列を持つ Message オブジェクトを示していますContentBlock

{ "role": "user", "content": [ { "image": { "format": "png | jpeg | gif | webp", "source": { "bytes": "image in bytes" } } } ] }
document

document フィールドは にマッピングされますDocumentBlock。を含める場合はDocumentBlock、リクエストが次の制限に準拠していることを確認します。

  • Message オブジェクトの contentフィールドには、ドキュメントに関連するプロンプトを含む text フィールドも含める必要があります。

  • bytes フィールドのドキュメントに、base64 でエンコードされた raw バイトを渡します。を使用する場合 AWS SDK、base64 でドキュメントバイトをエンコードする必要はありません。

  • name フィールドには、次の文字のみを含めることができます。

    • アルファベットの文字

    • 空白文字 (1 行に 1 つ以下)

    • ハイフン

    • 括弧

    • 角括弧

    注記

    name このフィールドは、モデルが誤って指示として解釈する可能性があるため、プロンプト挿入に対して脆弱です。したがって、中立の名前を指定することをお勧めします。

以下は、ドキュメント ContentBlock と必須の付随テキスト のみを含むcontent配列を持つ Message オブジェクトを示していますContentBlock

{ "role": "user", "content": [ { "text": "string" }, { "document": { "format": "pdf | csv | doc | docx | xls | xlsx | html | txt | md", "name": "string", "source": { "bytes": "document in bytes" } } } ] }

の他のフィールドContentBlockツール用です

role フィールドでロールを指定します。ロールは次のいずれかになります。

  • user — モデルにメッセージを送信している人間。

  • Assistant — 人間のユーザーにメッセージを送信しているモデル。

注記

以下の制限は、 contentフィールドに関連しています。

  • 最大 20 個のイメージを含めることができます。各イメージのサイズ、高さ、幅は、それぞれ 3.75 MB、8,000 px、8,000 px 以下にする必要があります。

  • 最大 5 つのドキュメントを含めることができます。各ドキュメントのサイズは 4.5 MB 以下にする必要があります。

  • イメージとドキュメントを含めることができるのroleは、 が の場合のみですuser

次のmessages例では、ユーザーは 3 つのポップ曲のリストを要求し、モデルは曲のリストを生成します。

[ { "role": "user", "content": [ { "text": "Create a list of 3 pop songs." } ] }, { "role": "assistant", "content": [ { "text": "Here is a list of 3 pop songs by artists from the United Kingdom:\n\n1. \"As It Was\" by Harry Styles\n2. \"Easy On Me\" by Adele\n3. \"Unholy\" by Sam Smith and Kim Petras" } ] } ]

システムプロンプトは、実行するタスク、または会話中に採用するペルソナに関する指示やコンテキストをモデルに提供するプロンプトの一種です。次の例に示すように、 system (SystemContentBlock) フィールドでリクエストのシステムプロンプトのリストを指定できます。

[ { "text": "You are an app that creates playlists for a radio station that plays rock and pop music. Only return song names and the artist. " } ]

推論パラメータ

Converse は、 inferenceConfigフィールド () で設定した推論パラメータの基本セットAPIをサポートしますInferenceConfiguration。推論パラメータの基本セットは次のとおりです。

  • maxTokens – 生成されたレスポンスで許可されるトークンの最大数。

  • stopSequences – 停止シーケンスのリスト。停止シーケンスは、モデルがレスポンスの生成を停止する一連の文字です。

  • temperature – モデルがレスポンスの生成中に確率の高いオプションを選択する可能性。

  • topP – モデルが次のトークンと見なす可能性が最も高い候補の割合。

詳細については、「推論パラメータによる影響レスポンスの生成」を参照してください。

次の例では、temperature推論パラメータJSONを設定します。

{"temperature": 0.5}

使用しているモデルに追加の推論パラメータがある場合は、 JSONadditionalModelRequestFieldsフィールドに と指定することで、それらのパラメータを設定できます。次の例はtop_k、 で利用可能な を設定する方法JSONを示しています。Anthropic Claude はモデルですが、メッセージ のベース推論パラメータではありませんAPI。

{"top_k": 200}

次の例に示すように、 additionalModelResponseFieldPathsフィールドで追加のモデルパラメータのパスを指定できます。

[ "/stop_sequence" ]

は、 フィールドでリクエストした追加のadditionalModelResponseFieldsフィールドAPIを返します。

レスポンス

Converse から得られるレスポンスは、呼び出すオペレーション、Converseまたは APIによって異なりますConverseStream

逆レスポンス

からのレスポンスではConverseoutputフィールド (ConverseOutput) には、モデルが生成するメッセージ (メッセージ ) が含まれます。メッセージの内容は content (ContentBlock) フィールドにあり、メッセージに対応するロール (user または assistant) は roleフィールドにあります。

metrics フィールド (ConverseMetrics) には、呼び出しのメトリクスが含まれます。モデルがコンテンツの生成を停止した理由を確認するには、 stopReasonフィールドを確認します。usage フィールド () を確認することで、リクエストでモデルに渡されたトークンと、レスポンスで生成されたトークンに関する情報を取得できますTokenUsage。リクエストで追加のレスポンスフィールドを指定した場合、 はそれらを additionalModelResponseFieldsフィールドJSONで としてAPI返します。

次の例は、「」で説明されているプロンプトに合格Converseしたときの からのレスポンスを示していますリクエスト

{ "output": { "message": { "role": "assistant", "content": [ { "text": "Here is a list of 3 pop songs by artists from the United Kingdom:\n\n1. \"Wannabe\" by Spice Girls\n2. \"Bitter Sweet Symphony\" by The Verve \n3. \"Don't Look Back in Anger\" by Oasis" } ] } }, "stopReason": "end_turn", "usage": { "inputTokens": 125, "outputTokens": 60, "totalTokens": 185 }, "metrics": { "latencyMs": 1175 } }

ConverseStream レスポンス

ConverseStream を呼び出してモデルからレスポンスをストリーミングすると、ストリームはstreamレスポンスフィールドで返されます。ストリームは次の順序で次のイベントを出力します。

  1. messageStart (MessageStartEvent)。メッセージの開始イベント。メッセージのロールが含まれます。

  2. contentBlockStart (ContentBlockStartEvent)。コンテンツブロック開始イベント。ツールの使用のみ。

  3. contentBlockDelta (ContentBlockDeltaEvent)。コンテンツブロックの差分イベント。モデルが生成する部分的なテキスト、またはツール用の部分的な入力 JSON が含まれます。

  4. contentBlockStop (ContentBlockStopEvent)。コンテンツブロック停止イベント。

  5. messageStop (MessageStopEvent)。メッセージの停止イベント。モデルが出力の生成を停止した理由が含まれます。

  6. metadata (ConverseStreamMetadataEvent)。リクエストのメタデータ。メタデータには、 usage (TokenUsage) のトークン使用量と () の呼び出しのメトリクスが含まれますmetricsConverseStreamMetadataEvent

ConverseStream は、完全なコンテンツブロックをContentBlockStartEventイベント、1 つ以上のContentBlockDeltaEventイベント、およびContentBlockStopEventイベントとしてストリーミングします。contentBlockIndex フィールドをインデックスとして使用して、コンテンツブロックを構成するイベントを関連付けます。

次の例は、 からの部分的なレスポンスですConverseStream

{'messageStart': {'role': 'assistant'}} {'contentBlockDelta': {'delta': {'text': ''}, 'contentBlockIndex': 0}} {'contentBlockDelta': {'delta': {'text': ' Title'}, 'contentBlockIndex': 0}} {'contentBlockDelta': {'delta': {'text': ':'}, 'contentBlockIndex': 0}} . . . {'contentBlockDelta': {'delta': {'text': ' The'}, 'contentBlockIndex': 0}} {'messageStop': {'stopReason': 'max_tokens'}} {'metadata': {'usage': {'inputTokens': 47, 'outputTokens': 20, 'totalTokens': 67}, 'metrics': {'latencyMs': 100.0}}}

会話APIの例

次の例は、 Converseおよび ConverseStreamオペレーションの使用方法を示しています。

トピック
    Conversation with text message example

    この例では、 を使用して Converseオペレーションを呼び出す方法を示します。 Anthropic Claude 3 Sonnet モデル。この例では、入力テキスト、推論パラメータ、およびモデルに固有の追加パラメータを送信する方法を示します。このコードは、モデルに曲のリストを作成するように依頼することで会話を開始します。その後、英国のアーティストによる曲であることを尋ねることで会話を続けます。

    # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. # SPDX-License-Identifier: Apache-2.0 """ Shows how to use the Converse API with Anthropic Claude 3 Sonnet (on demand). """ import logging import boto3 from botocore.exceptions import ClientError logger = logging.getLogger(__name__) logging.basicConfig(level=logging.INFO) def generate_conversation(bedrock_client, model_id, system_prompts, messages): """ Sends messages to a model. Args: bedrock_client: The Boto3 Bedrock runtime client. model_id (str): The model ID to use. system_prompts (JSON) : The system prompts for the model to use. messages (JSON) : The messages to send to the model. Returns: response (JSON): The conversation that the model generated. """ logger.info("Generating message with model %s", model_id) # Inference parameters to use. temperature = 0.5 top_k = 200 # Base inference parameters to use. inference_config = {"temperature": temperature} # Additional inference parameters to use. additional_model_fields = {"top_k": top_k} # Send the message. response = bedrock_client.converse( modelId=model_id, messages=messages, system=system_prompts, inferenceConfig=inference_config, additionalModelRequestFields=additional_model_fields ) # Log token usage. token_usage = response['usage'] logger.info("Input tokens: %s", token_usage['inputTokens']) logger.info("Output tokens: %s", token_usage['outputTokens']) logger.info("Total tokens: %s", token_usage['totalTokens']) logger.info("Stop reason: %s", response['stopReason']) return response def main(): """ Entrypoint for Anthropic Claude 3 Sonnet example. """ logging.basicConfig(level=logging.INFO, format="%(levelname)s: %(message)s") model_id = "anthropic.claude-3-sonnet-20240229-v1:0" # Setup the system prompts and messages to send to the model. system_prompts = [{"text": "You are an app that creates playlists for a radio station that plays rock and pop music." "Only return song names and the artist."}] message_1 = { "role": "user", "content": [{"text": "Create a list of 3 pop songs."}] } message_2 = { "role": "user", "content": [{"text": "Make sure the songs are by artists from the United Kingdom."}] } messages = [] try: bedrock_client = boto3.client(service_name='bedrock-runtime') # Start the conversation with the 1st message. messages.append(message_1) response = generate_conversation( bedrock_client, model_id, system_prompts, messages) # Add the response message to the conversation. output_message = response['output']['message'] messages.append(output_message) # Continue the conversation with the 2nd message. messages.append(message_2) response = generate_conversation( bedrock_client, model_id, system_prompts, messages) output_message = response['output']['message'] messages.append(output_message) # Show the complete conversation. for message in messages: print(f"Role: {message['role']}") for content in message['content']: print(f"Text: {content['text']}") print() 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()
    Conversation with image example

    この例では、メッセージの一部としてイメージを送信する方法と、モデルがイメージを記述するようにリクエストする方法を示します。この例では、 Converseオペレーションと を使用します。 Anthropic Claude 3 Sonnet モデル。

    # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. # SPDX-License-Identifier: Apache-2.0 """ Shows how to send an image with the Converse API to Anthropic Claude 3 Sonnet (on demand). """ import logging import boto3 from botocore.exceptions import ClientError logger = logging.getLogger(__name__) logging.basicConfig(level=logging.INFO) def generate_conversation(bedrock_client, model_id, input_text, input_image): """ Sends a message to a model. Args: bedrock_client: The Boto3 Bedrock runtime client. model_id (str): The model ID to use. input text : The input message. input_image : The input image. Returns: response (JSON): The conversation that the model generated. """ logger.info("Generating message with model %s", model_id) # Message to send. with open(input_image, "rb") as f: image = f.read() message = { "role": "user", "content": [ { "text": input_text }, { "image": { "format": 'png', "source": { "bytes": image } } } ] } messages = [message] # Send the message. response = bedrock_client.converse( modelId=model_id, messages=messages ) return response def main(): """ Entrypoint for Anthropic Claude 3 Sonnet example. """ logging.basicConfig(level=logging.INFO, format="%(levelname)s: %(message)s") model_id = "anthropic.claude-3-sonnet-20240229-v1:0" input_text = "What's in this image?" input_image = "path/to/image" try: bedrock_client = boto3.client(service_name="bedrock-runtime") response = generate_conversation( bedrock_client, model_id, input_text, input_image) output_message = response['output']['message'] print(f"Role: {output_message['role']}") for content in output_message['content']: print(f"Text: {content['text']}") token_usage = response['usage'] print(f"Input tokens: {token_usage['inputTokens']}") print(f"Output tokens: {token_usage['outputTokens']}") print(f"Total tokens: {token_usage['totalTokens']}") print(f"Stop reason: {response['stopReason']}") 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()
    Conversation with document example

    この例では、メッセージの一部としてドキュメントを送信する方法と、モデルがドキュメントの内容を記述するようにリクエストする方法を示します。この例では、 Converseオペレーションと を使用します。 Anthropic Claude 3 Sonnet モデル。

    # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. # SPDX-License-Identifier: Apache-2.0 """ Shows how to send an document as part of a message to Anthropic Claude 3 Sonnet (on demand). """ import logging import boto3 from botocore.exceptions import ClientError logger = logging.getLogger(__name__) logging.basicConfig(level=logging.INFO) def generate_message(bedrock_client, model_id, input_text, input_document): """ Sends a message to a model. Args: bedrock_client: The Boto3 Bedrock runtime client. model_id (str): The model ID to use. input text : The input message. input_document : The input document. Returns: response (JSON): The conversation that the model generated. """ logger.info("Generating message with model %s", model_id) # Message to send. message = { "role": "user", "content": [ { "text": input_text }, { "document": { "name": "MyDocument", "format": "txt", "source": { "bytes": input_document } } } ] } messages = [message] # Send the message. response = bedrock_client.converse( modelId=model_id, messages=messages ) return response def main(): """ Entrypoint for Anthropic Claude 3 Sonnet example. """ logging.basicConfig(level=logging.INFO, format="%(levelname)s: %(message)s") model_id = "anthropic.claude-3-sonnet-20240229-v1:0" input_text = "What's in this document?" input_document = 'path/to/document.pdf' try: bedrock_client = boto3.client(service_name="bedrock-runtime") response = generate_message( bedrock_client, model_id, input_text, input_document) output_message = response['output']['message'] print(f"Role: {output_message['role']}") for content in output_message['content']: print(f"Text: {content['text']}") token_usage = response['usage'] print(f"Input tokens: {token_usage['inputTokens']}") print(f"Output tokens: {token_usage['outputTokens']}") print(f"Total tokens: {token_usage['totalTokens']}") print(f"Stop reason: {response['stopReason']}") 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()
    Conversation streaming example

    この例では、 を使用して ConverseStreamオペレーションを呼び出す方法を示します。 Anthropic Claude 3 Sonnet モデル。この例では、入力テキスト、推論パラメータ、およびモデルに固有の追加パラメータを送信する方法を示します。

    # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. # SPDX-License-Identifier: Apache-2.0 """ Shows how to use the Converse API to stream a response from Anthropic Claude 3 Sonnet (on demand). """ import logging import boto3 from botocore.exceptions import ClientError logger = logging.getLogger(__name__) logging.basicConfig(level=logging.INFO) def stream_conversation(bedrock_client, model_id, messages, system_prompts, inference_config, additional_model_fields): """ 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. system_prompts (JSON) : The system prompts to send. inference_config (JSON) : The inference configuration to use. additional_model_fields (JSON) : Additional model fields to use. Returns: Nothing. """ logger.info("Streaming messages with model %s", model_id) response = bedrock_client.converse_stream( modelId=model_id, messages=messages, system=system_prompts, inferenceConfig=inference_config, additionalModelRequestFields=additional_model_fields ) 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 'usage' in metadata: print("\nToken usage") print(f"Input tokens: {metadata['usage']['inputTokens']}") print( f":Output tokens: {metadata['usage']['outputTokens']}") print(f":Total tokens: {metadata['usage']['totalTokens']}") if 'metrics' in event['metadata']: print( f"Latency: {metadata['metrics']['latencyMs']} milliseconds") def main(): """ Entrypoint for streaming message API response example. """ logging.basicConfig(level=logging.INFO, format="%(levelname)s: %(message)s") model_id = "anthropic.claude-3-sonnet-20240229-v1:0" system_prompt = """You are an app that creates playlists for a radio station that plays rock and pop music. Only return song names and the artist.""" # Message to send to the model. input_text = "Create a list of 3 pop songs." message = { "role": "user", "content": [{"text": input_text}] } messages = [message] # System prompts. system_prompts = [{"text" : system_prompt}] # inference parameters to use. temperature = 0.5 top_k = 200 # Base inference parameters. inference_config = { "temperature": temperature } # Additional model inference parameters. additional_model_fields = {"top_k": top_k} try: bedrock_client = boto3.client(service_name='bedrock-runtime') stream_conversation(bedrock_client, model_id, messages, system_prompts, inference_config, additional_model_fields) 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()