The Five Distinctions the Exam Leans On Hardest
RAG vs fine-tuning, agent vs Step Functions, gateway vs interface endpoint, guardrails vs IAM, prompt caching vs provisioned throughput — the pairs that decide the most questions.
Question writers build discrimination into an exam by picking pairs of services that overlap enough to be confusable and differ enough to have a right answer. Five pairs carry a disproportionate share of AIP-C01. If you can state, in one sentence each, what the boundary between the two members is, you have covered a large slice of the paper.
1. RAG vs fine-tuning
RAG changes what the model knows at request time. Fine-tuning changes how the model behaves. Retrieval is the answer whenever the facts change, whenever answers must be attributable to a source, and whenever different users may see different documents — because access control lives in the retrieval layer, not in the weights. Fine-tuning is the answer when the model already has the knowledge but will not produce it in the right form: a house tone of voice, a rigid output structure, a specialist vocabulary, or shorter prompts (and therefore lower per-request cost) because the instructions are baked in.
Say what fine-tuning is not: it is not a way to add facts you can rely on, it cannot cite, and it cannot be refreshed cheaply when the source documents change next month. If a stem mentions monthly or nightly updates, fine-tuning is wrong. Continued pre-training sits alongside fine-tuning for large volumes of unlabelled domain text; distillation sits alongside both when the goal is a smaller, cheaper model that imitates a larger one.
2. Agent vs Step Functions
An agent decides which tools to call and in what order, at runtime, using the model. A Step Functions state machine executes an order you decided at design time. Choose the agent when the path genuinely varies with the input and enumerating the branches is impractical. Choose Step Functions when the sequence is known, when you need deterministic retries and catch handlers, when a regulator wants to see that step three always follows step two, or when the execution history itself is the audit artefact.
The two are not rivals in practice, and the exam likes the hybrid: a Step Functions workflow that calls Bedrock at one deterministic step, or an agent whose action-group Lambda starts a state machine for the deterministic sub-process. If a stem says "non-deterministic", "varies by request", or "the model should decide", it wants an agent. If it says "the same five steps every time", "must be repeatable", or "must be auditable step by step", it wants a workflow.
3. Gateway endpoint vs interface VPC endpoint
This one is decided by a fact, not a judgement. Gateway endpoints exist only for Amazon S3 and Amazon DynamoDB. They are free, they work by adding a prefix-list route to a route table, and they cannot be reached from on-premises over Direct Connect or VPN, or from a peered VPC. Interface endpoints use AWS PrivateLink: an elastic network interface with a private IP in your subnets, protected by security groups, billed per hour per availability zone plus per gigabyte, and reachable from on-premises and peered networks. Everything else — including bedrock, bedrock-runtime, bedrock-agent and bedrock-agent-runtime — is an interface endpoint. S3 offers both, which is exactly why it appears in distractors.
4. Guardrails vs IAM
IAM answers "may this principal make this call?". Guardrails answer "is this content acceptable?". They operate at different layers and neither substitutes for the other. Amazon Bedrock Guardrails apply content filters, denied topics, word filters, sensitive-information (PII) filters and contextual grounding checks to the prompt and to the model's response. IAM decides who can invoke which model, which agent and which knowledge base, and can be used with condition keys to require that a guardrail be present on the call at all.
If the stem is about blocking a category of user request, redacting personal data, or stopping ungrounded answers, it wants Guardrails. If it is about stopping one team from using an expensive model, or restricting an application role to a single knowledge base, it wants IAM. If it is about proving that nobody can call the model without a guardrail attached, it wants both: an IAM condition on the guardrail identifier.
5. Prompt caching vs Provisioned Throughput
Prompt caching reduces the cost and latency of re-sending the same long prefix — a large system prompt, a fixed document, a stable few-shot block. Cached tokens are billed at a reduced rate on subsequent reads, the cache lives for a short time measured in minutes, and it is supported on a subset of models. It buys you nothing if every request starts differently, and it guarantees nothing about capacity.
Provisioned Throughput buys dedicated model capacity in model units, billed by the hour whether or not you send traffic, with commitment terms available at lower rates. It is the answer for consistently high, predictable volume where on-demand quotas are the constraint, and it is also the path for serving a model you have customised in Bedrock. It is the wrong answer for a spiky workload and a wrong answer whenever the stem says "unpredictable traffic" or "minimise cost for a pilot". Latency-optimised inference is a third, separate lever and should not be confused with either.
Example
# Prompt caching in the Converse API: the cachePoint marks the end of the
# reusable prefix. Everything BEFORE it can be served from cache on later
# calls; the user's question after it varies and is never cached.
import boto3
bedrock = boto3.client("bedrock-runtime", region_name="us-east-1")
LONG_HANDBOOK = open("policy_handbook.md").read() # stable, large, reused
def ask(question: str):
return bedrock.converse(
modelId="us.amazon.nova-pro-v1:0",
system=[
{"text": LONG_HANDBOOK},
{"cachePoint": {"type": "default"}}, # <-- end of cacheable prefix
],
messages=[{"role": "user", "content": [{"text": question}]}],
inferenceConfig={"maxTokens": 512},
)
first = ask("What is the storm damage excess?")
second = ask("And for flood?")
# Compare the two: the first call writes the cache, the second reads it.
for label, r in (("first", first), ("second", second)):
u = r["usage"]
print(label,
"write:", u.get("cacheWriteInputTokens"),
"read:", u.get("cacheReadInputTokens"))
# If cacheReadInputTokens stays at 0 across calls, something in the prefix
# changed between requests — a timestamp, a user ID, a reordered field.
# That is the production gotcha, and it is also an exam distractor:
# caching gives you nothing when the prefix is not byte-identical.When to use it
- A stem describes a chatbot answering from a policy library that changes weekly, and you must choose between fine-tuning and a knowledge base.
- A stem requires that traffic to Amazon Bedrock never traverse the internet and offers both a gateway endpoint and an interface endpoint as options.
- A stem asks how to guarantee that no application in the account can invoke a model without an approved guardrail attached.
Discussion