Subchapter 23.26
references/prompt-engineering-by-model.mdMarkdown8 KBView on GitHub
Only Bedrock-specific behaviors that differ from base model documentation or that agents consistently get wrong. For general prompting techniques, agents already have sufficient training data.
Assets
Kb Shim PyThe Converse API maps its unified format to each provider’s native format. This abstraction handles system prompts, message roles, and tool use automatically. Use Converse for all new code — the patterns below are only needed for InvokeModel or when the abstraction leaks.
When the Converse abstraction leaks — use additionalModelRequestFields:
top_k, anthropic_version overridetop_ktextGenerationConfig sub-fields not in inferenceConfigHow Converse maps the system field under the hood (matters when debugging unexpected behavior):
system field — first-class system prompt support<|start_header_id|>system<|end_header_id|> block inside the prompt stringinputText — no native system prompt, so quality may differ from Claude/Llamasystem array — first-class support like ClaudeRefer to the latest AWS documentation on Bedrock Converse additionalModelRequestFields for current supported fields per model.
InvokeModel format (only when Converse API is insufficient):
{
"anthropic_version": "bedrock-2023-05-31",
"max_tokens": 1024,
"system": "You are a helpful assistant.",
"messages": [{"role": "user", "content": "Hello"}]
}Bedrock-specific behaviors:
anthropic_version is REQUIRED and MUST be bedrock-2023-05-31 — this is the Bedrock-specific version string, NOT the Anthropic direct API version. Using the wrong version string returns ValidationException.max_tokens is required in InvokeModel (unlike Converse where it defaults). Omitting it returns ValidationException.system field, not inside messages. Putting system content in a user message works but degrades instruction following.system.cachePoint markers after large system prompts or few-shot examples in Converse API. Refer to the latest AWS documentation on Bedrock prompt caching for current model support and availability.Refer to the latest AWS documentation on Bedrock InvokeModel for Anthropic Claude for current request body fields.
InvokeModel format (Llama 3+):
{
"prompt": "<|begin_of_text|><|start_header_id|>user<|end_header_id|>\nWhat is RAG?\n<|eot_id|>\n<|start_header_id|>assistant<|end_header_id|>\n",
"max_gen_len": 512,
"temperature": 0.7,
"top_p": 0.9
}With system prompt:
{
"prompt": "<|begin_of_text|><|start_header_id|>system<|end_header_id|>\nYou are a helpful assistant.\n<|eot_id|>\n<|start_header_id|>user<|end_header_id|>\nWhat is RAG?\n<|eot_id|>\n<|start_header_id|>assistant<|end_header_id|>\n",
"max_gen_len": 512,
"temperature": 0.7
}Bedrock-specific behaviors:
prompt string — you MUST construct the special token template yourself. The Converse API does this automatically.messages array to InvokeModel for Llama, which returns ValidationException.<|begin_of_text|>, <|start_header_id|>, <|end_header_id|>, <|eot_id|> tokens. The older Llama 2 [INST]<<SYS>> format will not work correctly with Llama 3 models.<|start_header_id|>system<|end_header_id|>) before the user block.max_gen_len (not max_tokens), temperature, top_p.user and assistant header blocks, each terminated with <|eot_id|>. The Converse API handles this — use it for multi-turn.Multi-turn example:
{
"prompt": "<|begin_of_text|><|start_header_id|>user<|end_header_id|>\nWhat is RAG?\n<|eot_id|>\n<|start_header_id|>assistant<|end_header_id|>\nRAG is Retrieval-Augmented Generation.\n<|eot_id|>\n<|start_header_id|>user<|end_header_id|>\nHow do I set it up on Bedrock?\n<|eot_id|>\n<|start_header_id|>assistant<|end_header_id|>\n",
"max_gen_len": 512
}InvokeModel format:
{
"inputText": "You are a helpful assistant.\n\nUser: What is RAG?\nAssistant:",
"textGenerationConfig": {
"maxTokenCount": 512,
"temperature": 0.7,
"topP": 0.9,
"stopSequences": ["User:"]
}
}Bedrock-specific behaviors:
inputText. The Converse API adds system prompt support that InvokeModel lacks for Titan.maxTokenCount (not max_tokens), nested under textGenerationConfig.User: / Assistant: turns in inputText with stopSequences: ["User:"] — this prevents the model from generating the next user turn, which completion-style models will do without a stop sequence. Converse API handles this automatically.Refer to the latest AWS documentation on Bedrock InvokeModel for Amazon Titan for current request body fields.
Note: Titan Embeddings (for Knowledge Bases) use a completely different format from text generation. Refer to the latest AWS documentation on Bedrock Titan Embeddings request body for current parameters.
Nova is AWS-native with less community documentation — this is where the skill adds the most value.
InvokeModel format:
Nova uses a Converse-compatible message format through InvokeModel, unlike other providers:
{
"messages": [{"role": "user", "content": [{"text": "Hello"}]}],
"system": [{"text": "You are a helpful assistant."}],
"inferenceConfig": {"maxTokens": 1024, "temperature": 0.7}
}Bedrock-specific behaviors:
inferenceConfig go in additionalModelRequestFields.aws bedrock list-foundation-models --region <region> --by-provider Amazon| Mistake | Symptom | Fix |
|---|---|---|
Sending Converse messages format to InvokeModel for Llama | ValidationException | Use raw prompt string with Llama 3 special tokens |
| Using Anthropic API version instead of Bedrock version for Claude | ValidationException | Use bedrock-2023-05-31 |
Omitting max_tokens/max_gen_len/maxTokenCount in InvokeModel | ValidationException (Claude/Llama) or model default (Titan) | Always set explicitly |
| Putting system prompt in messages for Titan InvokeModel | Works but poor quality | Prepend to inputText |
| Applying Claude InvokeModel format to Nova | ValidationException | Nova uses Converse-compatible format |
| Using Llama special tokens in Converse API | Redundant, may confuse model | Converse handles formatting — send plain text |