Bedrockで出力が切れる問題を解決する方法

SDKからBedrockを呼び出した際に出力が途中で切れてしまったことありませんか? 私は約10,000文字の文字起こしデータをBedrockで整形しようとした際にこの事象に遭遇しました。その時の対処方法をご紹介します。

Bedrockの回答が途中で切れる問題

invoke_modelで実行すると以下のエラーが発生しました。そのため、原因はタイムアウトだと考えました。

Reason: Read timeout on endpoint URL: "https://bedrock-runtime.us-east-1.amazonaws.com/model/anthropic.claude-3-5-sonnet-20240620-v1%3A0/invoke"

それであればinvoke_model_with_response_streamで結果をstreamで受け取れば良いのではないかと考えました。試してみると正常終了したので仮説通りかと思いきや、出力が途中で切れてしまいます。max_tokesをいくら増やしても同じところで切れてしまい困りました。

Bedrockの回答が途中で切れる原因

invoke_model_with_response_streamでは以下のレスポンスを返します。

  • content_block_delta: streamで返される回答内容
  • message_delta: 回答の終わりに関する情報
  • amazon-bedrock-invocationMetrics: トークン数やレイテンシーに関する情報

message_deltaを確認することで回答が途中で切れる原因を探りました。その結果、stop_reason: max_tokensとなっており、トークン数が上限に達した事により止まっていることが分かりました。max_tokensの値をいくら増やしてもoutputTokenCountが約4000で止まることからclaude3.5 sonnetの出力は4000トークンが上限だと考えられます。

以下は確認したmessage_deltaとamazon-bedrock-invocationMetricsの内容です。

message_delta: {'stop_reason': 'max_tokens', 'stop_sequence': None}
amazon-bedrock-invocationMetrics:{'inputTokenCount': 11119, 'outputTokenCount': 4070, 'invocationLatency': 136770, 'firstByteLatency': 1860}

対応方法

続きの作成を促すプロンプトを与えることで最後まで回答を生成することができます。OpenAIのAssistants APIであれば過去の会話のコンテキストを引き継いでいますが、BedrockのAPIでは引き継いでいません。そのため、単純に「続きをお願いします。」と依頼しても「対応できません。」と返ってきてしまいます。

そこで使うのが入力パラメータのmessagesです。messagesではroleにuserかassistantを設定できます。これにより今までのやり取りを全て設定したのちに「続きをお願いします。」とすれば続きを作成してくれます。以下のようなイメージです。

[
  {"role": "user", "content": "文字起こしデータを整形して下さい。"},
  {"role": "assistant", "content": f"{response}"},
  {"role": "user", "content": "続きをお願いします。"},
]

stop_reason: end_turnとなるまで続けることで最後まで回答を生成することができます。

回答を1つにまとめるコツ

単純に続きを依頼してしまうと以下のように途中で切れた文を最初から出力しなおすことがあります。私が作成していたアプリではつなげて1つの文章にしたかったので同じ内容が出力されると都合が悪かったです。

意図しない出力

  • 最初の出力
     spk_0: 吾輩は
  • 続きの出力
     spk_0: 吾輩は猫である

望む出力

  • 最初の出力
     spk_0: 吾輩は
  • 続きの出力
     猫である

これを実現するために以下のようなプロンプトを与えました。これにより複数回invoke_model_with_response_streamを実行した結果を繋げても、1つの文章として違和感のない結果を得ることができました。

続きを処理して下さい。
前の文章から続くように出力を開始して下さい。
例)
前の文章が「spk_0 吾輩は」で終わっていた場合、
続きは「猫である」を出力して下さい。
「spk_0 吾輩は猫である」とは出力しないでください。

まとめ

Bedrockの出力が途中で止まってしまう際の対応方法について解説しました。先日OpenAIからGPT-4oのLong Outputの試験バージョンを公開すると発表がありました。出力トークン数が4kから64kに増えるそうです。各種LLMがLong Outputに対応するようになるまではこの記事で紹介したテクニックは役に立ちそうです。

この記事を書いた人
新技術基盤開発室の鈴村です。AWS初心者からAWSアンバサダーを目指すチャレンジをしています。このアイコンはChatGPTに描かせました。
新技術基盤開発室の鈴村です。AWS初心者からAWSアンバサダーを目指すチャレンジをしています。このアイコンはChatGPTに描かせました。
>お役立ち資料のダウンロード

お役立ち資料のダウンロード

ブログでは紹介しきれないシステム開発や導入におけるケーススタディを資料にまとめました。お気軽にダウンロードください。

CTR IMG