Onboarding
API keys, budgets, and responsible use
Store secrets in .env (never committed) and load them in code
- LLM project lifecycle (browse)
- Privacy and data for AI apps (browse)
Learning objectives
- Store secrets in .env (never committed) and load them in code
- Log a first LLM API call with model, tokens, and rough cost
- State a personal monthly budget and a kill-switch habit
Keys without leaking them
You will call hosted APIs (OpenAI-compatible endpoints, Anthropic, Google, and others) and, later in the course, local OpenAI-compatible servers (Ollama, vLLM). From day one, treat API keys like production database credentials — because that is what they are. A leaked key can burn your budget in hours and exfiltrate data through your account.
The .env pattern
Secrets live in .env. Templates live in .env.example with empty placeholders. Code loads via python-dotenv or your framework's equivalent. Git ignores .env permanently.
# .env.example — commit this
OPENAI_API_KEY=
OPENAI_BASE_URL=https://api.openai.com/v1
# Optional: default model for course drills (use a cheap one)
SHIPAI_DEFAULT_MODEL=gpt-4.1-mini# .env — NEVER commit this
OPENAI_API_KEY=sk-proj-...
OPENAI_BASE_URL=https://api.openai.com/v1
SHIPAI_DEFAULT_MODEL=gpt-4.1-miniYour .gitignore must include .env. Before every push, verify with git status that no secret file is staged. If you accidentally commit a key, rotate it immediately at the provider — deleting the commit from history is not enough once pushed.
Provider hygiene
- Prefer project-scoped keys with spend limits when the provider allows (OpenAI, Anthropic, and others offer budget caps).
- Use separate keys for course work vs. employer work vs. side projects.
- Never paste keys into lesson notes, Slack, screenshots, or LLM chat windows — chat logs are not secret stores.
- For team or portfolio demos, use environment variables in CI, not hardcoded fallbacks.
Callout — OpenAI-compatible is a protocol: Many providers and local servers expose the same
/v1/chat/completionsshape. ShipAI code often works across vendors by changingOPENAI_BASE_URLand model name — but pricing and rate limits differ per provider.
Budgets are part of the craft
AI engineering without cost awareness is demo engineering. A prototype that loops an agent ten times per user message may cost cents in development and dollars per active user in production. The deployment and cost module goes deep; the habit starts here.
Set a monthly cap
Pick a number you can afford to burn on learning — even $10–20 is enough if you default to small models for drills. Write it in m0/README.md:
## Personal API budget
- Monthly cap: $15
- Default drill model: gpt-4.1-mini (or equivalent cheap tier)
- Kill switch: delete/disable key if daily spend > $3Model tier discipline
Not every call needs the frontier model. Use a tiered strategy:
| Use case | Model tier |
|---|---|
| Syntax checks, formatting, "reply with exactly X" drills | Smallest/cheapest |
| Prompt iteration on eval sets | Mid-tier |
| Milestone quality gates, final agent demos | Best you can afford for that milestone |
Escalate model size only when eval scores justify the cost — a pattern you will formalize in the evals module.
Log every call early
When agents arrive in later modules, token usage explodes: system prompts, tool results, multi-turn history, reflection loops. If you only start logging at that point, you will not know what "normal" looks like. The micro-project below establishes JSONL logging from the first call.
Rough cost estimation
Providers bill by tokens. For learning, approximate costs are fine:
est_usd ≈ (prompt_tokens × price_per_1M_input + completion_tokens × price_per_1M_output) / 1_000_000Hardcode a price table in a comment at the top of your script and refresh it when you notice drift. Exact accounting matters for production; directional accuracy matters for learning.
Responsible use (short, non-lawyer)
This is not legal advice — it is engineering hygiene.
Employer and client data. Do not send proprietary employer data, customer PII, or unreleased product details to third-party APIs without explicit policy clearance. Many companies have approved vendors and data-handling rules. When in doubt, use synthetic data or public datasets until you understand the constraints.
Abuse and ToS. Do not use course projects to harass, scrape illegally, bypass authentication, generate spam, or evade content policies. Providers monitor abuse patterns; your key can be revoked without refund.
Training data and licenses. Fine-tuning on random web data without understanding licenses creates legal and quality risk. The SLM module addresses dataset choices; until then, prefer public or synthetic datasets with clear terms.
Local vs. cloud for sensitive prompts. If prompts cannot leave your VPC, closed APIs are off the table unless your org has a private deployment contract. That constraint drives the open-weight vs. API decision you will analyze in the field-map module.
Engineering problem (staff framing)
LLM bugs become invoices. Control secrets, budgets, and abuse before tool-calling agents.
Diagram — Spend control plane
flowchart LR
Env[.env / vault] --> App[Scripts]
App --> API[Provider]
API --> Bill[Usage]
Bill --> Alert[Budget alert]
Alert --> Kill[Circuit breaker]
Precise definitions & mental model
Key=credential; budgets by feature; least-privilege keys; responsible data handling in prompts.
Tradeoffs — when to use what
| Pattern | Safety | Velocity |
|---|---|---|
| Shared org key | Low | High |
| Per-dev + budget | Medium | Medium |
| Vault short-lived | High | Setup cost |
Failure modes (interview + on-call)
Infinite agent loops; logging PII/keys; sharing prod keys in chats.
Production & OSS practices
Vault secrets, burn-rate alerts, COST.md for eval suites, rotate on leak.
Deep dive (FAANG / OSS bar)
Push «api-keys-budgets-responsible-use» past tutorial depth: write the interface contract (inputs/outputs/invariants), list three measurable metrics, and name two degrade modes if the happy path fails. Add a short threat note: what an attacker or noisy tool result could do, and which layer catches it (schema, policy, HITL, or eval gate).
flowchart LR
Contract[Interface contract] --> Metrics
Metrics --> Degrade[Degrade modes]
Degrade --> Threat[Threat + control]
Micro-project: First logged LLM call
Write m0/first_call/main.py that:
- Loads
OPENAI_API_KEYfrom environment (viapython-dotenv). Fail fast with a clear error if missing. - Sends one chat completion request: prompt "Reply with exactly: shipai-ready" (use your configured default model).
- Verifies the response content matches (or note mismatch in the log — debugging wrong outputs is part of the job).
- Appends one JSON line to
m0/first_call/calls.jsonlwith: timestamp (ISO 8601), model name, prompt tokens, completion tokens, estimated USD cost.
Example log line:
{"ts":"2026-08-11T14:32:01Z","model":"gpt-4.1-mini","prompt_tokens":12,"completion_tokens":4,"est_usd":0.0001}Use httpx or the official OpenAI Python SDK — either is fine. Pin the SDK version in your lockfile when you add it.
Add m0/first_call/README.md with: how to run, which env vars are required, and your monthly budget statement (copy from m0/README.md or link to it).
Checklist
-
.envignored;.env.examplecommitted - One successful logged call
- Personal monthly budget written in
m0/README.md
ShipAI delivery model is: