Four runnable notebooks for Amazon Bedrock Advanced Prompt Optimization (APO): one per evaluator mode, plus local/spot optimization with advpo: tags. All boto3, all explained inline.
| Notebook | Mode | Chapters |
|---|---|---|
01_lambda_metric.ipynb |
Lambda metric | Text (NESTFUL) + PDF (MMVQA) |
02_llm_as_judge.ipynb |
LLM-as-Judge | Text (IFBench) + Image (Defactify) |
03_steering_criteria.ipynb |
Steering criteria | Text (XSum) + Image (MathVista) |
04_local_spot_optimization.ipynb |
Steering + advpo: tags |
Local/spot optimization of a chosen prompt section |
You need an AWS account configured locally.
setup.pydiscovers everything from your AWS CLI profile — it does not prompt for access keys or take any account info as input. Make sure you have:
- The AWS CLI installed (
aws --versionworks).- A profile with valid credentials — verify with
aws sts get-caller-identity(oraws sts get-caller-identity --profile <name>if you use a named profile). This must return your account ID without error before you runsetup.py.- The AWS principal those credentials belong to must have enough permissions to create an IAM role, an S3 bucket, and a Lambda (or use
--skip-permsand have an admin apply the policysetup.pyprints).If
aws sts get-caller-identityfails, runaws configure(oraws configure sso, depending on your auth flow) first.
# 1. Install Python prerequisites
pip install -r requirements.txt
# 2. Bootstrap your AWS environment (interactive)
python setup.py
# 3. Open any notebook
jupyter notebook 01_lambda_metric.ipynbThat's the whole flow. The setup script reads no static account info — it discovers your account ID, region, bucket, and IAM role from your own AWS profile.
advanced-prompt-optimization/
├── .env.example # Template; the real .env is generated by setup.py
├── README.md # This file
├── requirements.txt # boto3 1.43.8 + jupyter
├── setup.py # Interactive bootstrap (env, bucket, IAM role, mode)
├── utils.py # All helper logic (single self-contained module)
├── 01_lambda_metric.ipynb
├── 02_llm_as_judge.ipynb
├── 03_steering_criteria.ipynb
├── 04_local_spot_optimization.ipynb
└── data/ # Per-example samples, templates, lambda code, multimodal assets
├── nestful/, mmvqa/, ifbench/, defactify/, xsum/, mathvista/, spot/
└── <each>/reference_results.jsonl # Pre-baked results from a real run (replay mode)
Run it once per machine / account. It is idempotent — re-running re-confirms each step, defaulting to your prior choices.
- Verifies AWS credentials via
sts:GetCallerIdentity. - Auto-detects your account ID.
- Asks for a region (defaults to your profile's region or
us-west-2). - Lists existing S3 buckets — pick one or create a new one (default name
apo-tutorial-<account>-<region>). - Creates the Lambda execution role
apo-tutorial-lambda-roleif missing. - Attaches a narrow inline IAM policy
apo-tutorial-permissionsto your caller (IAM user or assumed-role) granting only what the notebooks need (see below). If your caller is a federated/SSO session it can't modify, the policy JSON is printed for an admin to apply. - Asks for the default notebook mode —
live(real APO jobs) orreplay(bundled results from a real prior run). - Writes
./.envwith the resolved values. - (live mode only) Deploys the metric Lambdas under
data/<example>/lambda_function.pyand smoke-tests each with an identity pred/gold pair — fails fast if a Lambda is broken, before any APO job runs.
Non-interactive variants:
python setup.py -y # accept all defaults
python setup.py --region us-west-2 --bucket my-bucket # mix flags + prompts
python setup.py --mode replay --reuse-env # flip mode without re-asking
python setup.py --skip-perms # don't touch caller IAM| Mode | When the notebook calls run_job(...) |
|---|---|
| Live | Uploads input to S3, submits a real APO job, polls Bedrock for status, downloads the result JSONL. Wall-clock per chapter: 20–50 min. |
| Replay | Returns the bundled data/<example>/reference_results.jsonl immediately. Full notebook executes in seconds. Great for learning the flow without burning Bedrock tokens. |
Default mode is chosen during setup.py and stored in .env as APO_USE_REFERENCE (1 = replay, 0 = live). To temporarily override without re-running setup:
APO_USE_REFERENCE=1 jupyter notebook # force replay
APO_USE_REFERENCE=0 jupyter notebook # force liveShell-set environment variables always win over .env.
Each notebook has a TARGET_MODEL_ID cell near the top (and JUDGE_MODEL_ID in notebook 02). Defaults match the bundled reference run. Edit and re-run to try different target / judge models — the rest of the notebook does not change.
When you're done, cleanup.py reverses everything setup.py (and the notebooks) put in your account.
python cleanup.py --dry-run # preview what would be deleted
python cleanup.py # interactive, confirms each step
python cleanup.py -y # accept all confirmations
python cleanup.py --delete-bucket # also delete the S3 bucket itself
python cleanup.py --keep-perms # leave caller IAM policy + Lambda role intact
python cleanup.py --keep-env # leave the local .env file in placeIn order, cleanup removes:
- APO jobs whose name starts with
apo-tutorial-(stops in-flight ones first, then batch-deletes). - Lambda functions matching
apo-tutorial-*(deployed bysetup.pyin live mode). - S3 objects under the
apo-tutorial/prefix of the bucket from.env. - (Only with
--delete-bucket) the S3 bucket itself — refuses if it has objects outside the tutorial prefix. - The inline IAM policy
apo-tutorial-permissionsfrom your caller. - The IAM role
apo-tutorial-lambda-role(detaches attached policies first). - The local
.envfile (skipped with--keep-env).
Cleanup is idempotent — safe to re-run.
setup.py attaches a narrow inline policy named apo-tutorial-permissions to your caller. Its scope (after substitution):
| Sid | Actions | Resource |
|---|---|---|
AllowAPOAPIs |
bedrock:{Create,Get,List,Stop}AdvancedPromptOptimizationJob |
* |
AllowBucketObjectRW |
s3:{Put,Get,Delete}Object |
arn:aws:s3:::<your-bucket>/* |
AllowBucketLevel |
s3:ListBucket, s3:GetBucketLocation |
arn:aws:s3:::<your-bucket> |
AllowLambdaCRUD |
lambda:{Create,Update,Get,Invoke,Delete,AddPermission}Function* |
arn:aws:lambda:<region>:<account>:function:apo-tutorial-* |
AllowPassLambdaRole |
iam:PassRole |
apo-tutorial-lambda-role |
AllowSTSWhoAmI |
sts:GetCallerIdentity |
* |
setup.py calls APIs that need permissions before the inline policy is in place. You need one of:
- The four AWS-managed policies
AmazonBedrockFullAccess+AWSLambda_FullAccess+AmazonS3FullAccess+IAMFullAccess, OR - An admin to run
setup.py --skip-perms, then attach the inline policy by hand from the JSON it prints.
Once the inline policy is attached, you no longer need the broad managed policies for day-to-day notebook usage — the inline scope is enough.