Bedrock + RAG + tools covers most internal coding assistants. Fine-tuning on SageMaker JumpStart pays off only when prompting cannot encode your private SDK dialect, latency budgets demand a smaller specialist, or residency rules forbid sending code to a multi-tenant foundation model API. This is the decision framework seniors use before opening a training ticket — not a hype matrix.
⚡ TL;DR: Default to Bedrock foundation models with retrieval and tools. Fine-tune (JumpStart / custom) when eval shows persistent symbol hallucination on internal APIs after RAG, when you need sub-200ms autocomplete with a distilled model, or when legal requires weights in your account. Measure quality, p95 latency, $/1M tokens (or hosting hours), and ops burden. Companions: RAG OpenSearch vs pgvector, Bedrock prompt caching, Bedrock Agents.
Decision tree (ship this in the ADR)
Need private weights / VPC-only inference?
yes → SageMaker real-time or JumpStart endpoint (or Bedrock Custom Model Import if eligible)
no → Can RAG + tools hit quality bar on golden set?
yes → Stay on Bedrock FM (cheaper ops)
no → Is failure mode "wrong internal API"?
yes → Fine-tune or train adapter on call sites
no → Fix retrieval / prompts / tools first
❌ Wrong trigger: "competitors fine-tune, so we should"
✅ Right trigger: hit-rate on internal SDK questions flat after RAG@20 + rerank
When Bedrock prompting still wins
- Rapidly changing APIs (weekly exports) — retrieval beats stale weights
- Tool use / multi-step coding agents (Bedrock Agents)
- Burst traffic where paying per token beats GPU idle time
- Prompt caching for stable system rules (prompt caching)
When JumpStart fine-tunes earn their keep
# Illustrative eval gate before approving fine-tune job
def should_finetune(metrics: dict) -> bool:
# ✅ Persistent gap on internal symbols after strong RAG
if metrics["internal_api_accuracy"] < 0.75 and metrics["rag_hit_at_5"] > 0.85:
return True
# ✅ Latency SLO unmet even with small Bedrock model
if metrics["p95_ms"] > 400 and metrics["task"] == "inline_autocomplete":
return True
return False
JumpStart gives curated base models and training containers; you still own data curation, eval, endpoint autoscaling, and patch cadence.
# Conceptual: JumpStart fine-tune then deploy (CLI shapes vary by model)
aws sagemaker create-training-job --training-job-name sdk-ft-$(date +%s) ...
aws sagemaker create-endpoint-config --endpoint-config-name sdk-ft-cfg ...
aws sagemaker create-endpoint --endpoint-name sdk-ft-prod --endpoint-config-name sdk-ft-cfg
Cost and ops comparison (illustrative)
| Dimension | Bedrock FM + RAG | JumpStart fine-tune + endpoint |
|---|---|---|
| Quality on public langs | Excellent | Marginal gain |
| Quality on private SDK | Depends on RAG | Often better if curated |
| Latency | Model-dependent | Can optimize with smaller FT model |
| Ops | API, almost none | Endpoints, scaling, AMIs/containers |
| Change velocity | Prompt/RAG deploy | Retrain + redeploy |
| Residency | AWS managed | Weights in your account |
Data curation beats hyperparameter cosplay
Fine-tunes fail when training data is random GitHub clones. Curate (prefix, completion) from your monorepo call sites; redact secrets; dedupe; hold out packages for eval.
def example_from_callsite(file: str, line: int, window: str) -> dict:
# ✅ Supervised pairs from real internal usage
return {"prompt": window.split("<CURSOR>")[0], "completion": window.split("<CURSOR>")[1]}
# ❌ Fine-tuning on unredacted `.env` samples and customer fixtures
Ground retrieval first with a serious code index (RAG comparison).
Hybrid patterns that ship
Many teams keep Bedrock for chat/agents and a small JumpStart/SageMaker model for IDE autocomplete. Route by task — don’t force one model to do both.
export function route(task: "chat" | "autocomplete") {
if (task === "autocomplete") return { backend: "sagemaker", endpoint: process.env.FT_ENDPOINT! };
return { backend: "bedrock", modelId: process.env.BEDROCK_MODEL! };
}
Closing checklist
✅ Dos
– ✅ Prove RAG/tool gaps with golden evals before FT
– ✅ Curate redacted internal call sites as training data
– ✅ Compare $/query including idle GPU time
– ✅ Prefer hybrid routing (chat vs autocomplete)
– ✅ Write an ADR with kill criteria for the endpoint
❌ Don’ts
– ❌ Don’t fine-tune to paper over bad chunking
– ❌ Don’t train on secrets or PII
– ❌ Don’t skip holdout packages in eval
– ❌ Don’t run oversized endpoints 24/7 for spiky IDE traffic without scale-to-zero strategy
– ❌ Don’t abandon Bedrock Guardrails when importing custom weights
Related reading
- RAG on AWS: OpenSearch vs Aurora pgvector for Codebase Chat
- Bedrock Prompt Caching and Batch Inference: Cut Latency and Cost
- Amazon Bedrock Agents: Tool Use, Memory, and Production Guardrails
- LLM Coding Agents on AWS: Safe Tool Sandboxes with Lambda
Last updated on September 11, 2026
Discover more from CheatCoders
Subscribe to get the latest posts sent to your email.
