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に対応するようになるまではこの記事で紹介したテクニックは役に立ちそうです。