2025, Dec 03 06:02
Как исправить ошибку tagged union в AWS Bedrock при отправке текста и PDF в одном сообщении
Падение converse в AWS Bedrock: ParamValidationError при совмещении text и document в messages.content. Объясняем tagged union и показываем пример с PDF.
Передавать PDF и подсказку в AWS Bedrock Runtime одним блоком контента кажется безобидным, пока всё не рушится с загадочной ошибкой валидации. Если ваш вызов converse для модели amazon.nova-premier-v1:0 падает при объединении текста и документа, проблема не в модели. Дело в форме messages.content и в том, как Bedrock применяет тегированное объединение (tagged union).
Воспроизводимый пример в коде
Этот фрагмент открывает PDF, отправляет его вместе с подсказкой и вызывает ошибку валидации. Логика проста, но структура тела запроса не соответствует ожиданиям Bedrock.
def run_flow():
with open("file.pdf", "rb") as fh:
pdf_bytes = fh.read()
rt = boto3.client("bedrock-runtime", "us-east-1")
out = rt.converse(
modelId=MODEL_ID,
messages=[
{
"role": "user",
"content": [
{
"text": "explain this document",
"document": {
"format": "pdf",
"name": "file",
"source": {
"bytes": pdf_bytes,
},
},
},
],
},
],
)
print(out)
return outСервис отвечает прозрачной подсказкой:
botocore.exceptions.ParamValidationError: Parameter validation failed: Invalid number of parameters set for tagged union structure messages[0].content[0]. Can only set one of the following keys: text, image, document, video, toolUse, toolResult, guardContent, cachePoint, reasoningContent.
Что происходит на самом деле
В Bedrock Runtime поле messages[...].content — это массив блоков контента, и каждый блок — это объединение. В одном блоке можно задать только одного участника этого объединения. В официальном описании это сформулировано прямо:
Этот тип данных является UNION, поэтому при использовании или возврате может быть указан только один из следующих членов.
Размещение одновременно text и document в одном элементе content нарушает правило объединения. Поэтому валидатор отклоняет запрос, хотя оба поля по отдельности допустимы.
Решение: разделите контент на отдельные блоки
Правильный подход — отправлять PDF как один блок контента, а подсказку — как другой блок в рамках того же сообщения. Так каждый блок соблюдает ограничение объединения и при этом сохраняется задуманная семантика.
def run_flow():
with open("file.pdf", "rb") as fh:
pdf_bytes = fh.read()
rt = boto3.client("bedrock-runtime", "us-east-1")
out = rt.converse(
modelId=MODEL_ID,
messages=[
{
"role": "user",
"content": [
{
"document": {
"format": "pdf",
"name": "file",
"source": {
"bytes": pdf_bytes,
},
},
},
{
"text": "explain this document",
},
],
},
],
)
print(out)
return outПочему это важно
Как только вы начинаете сочетать разные модальности в Bedrock Runtime, форма запроса становится столь же значимой, как и его содержимое. Непонимание контракта объединения приводит к жёстким остановкам ещё до запуска модели, и ошибка проявляется на стороне клиента. Зная, что messages.content — это массив однотипных блоков, вы экономите время, делаете запросы предсказуемыми и выстраиваете код в соответствии с тем, как API задуман для рассуждения над раздельными входами.
Выводы
Если нужно отправить подсказку и документ вместе, держите их в отдельных блоках контента внутри одного сообщения. Относитесь к каждому блоку как к строго одному типу: text, document, image и т. д. Эта небольшая структурная правка устраняет ошибку валидации и позволяет модели получить и файл, и инструкцию именно так, как задумано.