Bedrock via SDK Best Practices
Prompt/response handling, retries, and token-cost monitoring.
Busca en todas las páginas de la documentación
Prompt/response handling, retries, and token-cost monitoring.
This is the checklist to run before and after putting Bedrock inference into production. Each item is a rule stated positively with a one-line rationale, grouped from API choice outward through prompt handling, reliability, cost, and security. Work top to bottom - the early groups keep your code correct and portable; the later ones keep it cheap and safe.
messages, system, inferenceConfig, toolConfig) keeps code portable across families; reserve InvokeModel for embeddings, image generation, or model-specific params.ListFoundationModels.us.anthropic.claude-...); check ListInferenceProfiles.maxTokens. It caps reply length and output-token cost and prevents runaway generations.system, not the user turn. The separate system field is treated as guidance and keeps prompts clean and reusable.stopReason. Handle max_tokens (truncated - raise the cap or continue), content_filtered (blocked), and tool_use (run a tool) distinctly from end_turn.temperature for the task. Low for extraction and classification, higher for creative text; do not leave it at a default you have not considered.ThrottlingException.ConverseStream, wrap iteration in try/except (boto3) or try/catch (v3) - errors can arrive during the stream, not just at the start.stopReason is end_turn with a maximum iteration count to avoid runaway cost.Configure retries and log the identifiers you will need to debug.
# --- Python (boto3) ---
import boto3
from botocore.config import Config
cfg = Config(
retries={"max_attempts": 5, "mode": "adaptive"}, # backoff + throttling-aware
read_timeout=120, # long generations need headroom
)
brt = boto3.client("bedrock-runtime", region_name="us-east-1", config=cfg)
resp = brt.converse(
modelId="amazon.nova-lite-v1:0",
messages=[{"role": "user", "content": [{"text": "Hi"}]}],
inferenceConfig={"maxTokens": 200},
)
u = resp["usage"]
print("stop:", resp["stopReason"], "| tokens:", u["inputTokens"], u["outputTokens"])// --- TypeScript (AWS SDK v3) ---
import { BedrockRuntimeClient, ConverseCommand } from "@aws-sdk/client-bedrock-runtime";
const brt = new BedrockRuntimeClient({
region: "us-east-1",
maxAttempts: 5, // retries with backoff
requestHandler: { requestTimeout: 120_000 }, // long generations need headroom
});
const resp = await brt.send(new ConverseCommand({
modelId: "amazon.nova-lite-v1:0",
messages: [{ role: "user", content: [{ text: "Hi" }] }],
inferenceConfig: { maxTokens: 200 },
}));
const u = resp.usage!;
console.log("stop:", resp.stopReason, "| tokens:", u.inputTokens, u.outputTokens);usage block on every call. inputTokens/outputTokens are the basis for billing - emit them as metrics to catch cost regressions early.bedrock:InvokeModel. Scope the action to the specific model ARNs your workload calls, not *; add InvokeModelWithResponseStream only if you stream.$metadata.requestId (v3) or the boto3 response metadata so AWS support can trace calls.bedrock control-plane actions; grant those only to the roles that provision, not to inference workloads.Converse, for its model-agnostic shape and portability. Fall back to InvokeModel only for non-chat modalities (embeddings, image generation) or a model-specific parameter Converse does not expose.
Logging the usage block and setting maxTokens on every call. Together they cap runaway generations and make token spend visible so regressions surface immediately.
On-demand capacity is shared and quota-limited. Enable the SDK's adaptive/standard retry mode with backoff, and if throttling is constant, request a quota increase or move to Provisioned Throughput.
Because end_turn is only one outcome. max_tokens means truncated, content_filtered means blocked, and tool_use means the model wants a function run. Each needs different handling.
Treat them as configuration, not constants. IDs are region/version-specific and some need inference profiles. List current options with the bedrock control-plane client and verify at build time.
bedrock:InvokeModel (plus bedrock:InvokeModelWithResponseStream for streaming), scoped to the specific model ARNs. Managing Provisioned Throughput needs separate control-plane actions.
Be careful - they can contain PII. Log token usage and request ids by default; log content only with a clear data-handling policy, and prefer Guardrails for platform-level redaction and filtering.
Loop until stopReason is end_turn with a hard iteration cap, set maxTokens, and monitor per-request token usage. Chained tool calls multiply cost quickly without a cap.
Start on-demand - no commitment, per-token billing. Move to Provisioned Throughput only for steady high volume needing guaranteed capacity and latency, and delete unused units since they bill while idle.
Mostly yes. Retries, timeouts, cost logging, least-privilege IAM, and model-id hygiene apply to both surfaces. Only the request/response shape differs.
Stack versions: This page was written for boto3 1.43.x (Python 3.10+) and the AWS SDK for JavaScript v3 (Node.js 18+). Bedrock model IDs and inference profiles are region/version-specific - verify against the current Bedrock catalog at build time.
Revisado por Chris St. John·Última actualización: 24 jul 2026