Mastering Individual Calls to LLMs

Roles of AI in software, prompt engineering, structured outputs, and stateless vs stateful interactions

Slides: Roles of AI in Software · Mastering Individual Calls

The plan for today

  1. Roles of AI in software — Understand the roles of AI in software: think before you implement
  2. Making good individual calls — Understand how to make "good" individual calls to AI
  3. Stateless vs stateful interactions — Understand nuances of stateless vs stateful interactions and context management

Learning objectives

By the end of this lesson, you will be able to:

  1. Identify the three roles AI plays in software systems and decide when each applies
  2. Construct effective API calls with well-designed system messages, user messages, and parameters
  3. Apply prompting techniques: few-shot, chain-of-thought, structured output, and prompt chaining
  4. Understand the difference between stateless and stateful interactions and how to manage context
01 / ROLES OF AI IN SOFTWARE

Three roles for AI

Before writing any code, ask: what role does AI play in this system? The answer shapes everything — architecture, testing, risk management.

01 — AI as a Component

AI is embedded inside your solution — a model call in the pipeline. You design around its strengths and limitations: prompts, guardrails, evaluation, fallback logic.

02 — AI as a Coding Agent

AI helps you write, review, and refactor code. It accelerates development but the output is traditional software — deterministic, testable, fully under your control.

03 — AI as a User

AI consumes and produces information through your system. It calls your APIs, reads your docs, and acts on your data. You need to design for this new kind of consumer.

When do you need AI as a component?

Category Characteristics Examples
No AI
Fully specifiable
Behavior is specified, reviewed, and approved. Outputs are deterministic and testable. Adding AI adds complexity without value. Billing logic, form validation, API routing, access control
AI as a Convenience
Easier in English
The behavior can be fully written down as rules, but a prompt is simpler than writing code. English becomes the implementation language. Outputs are known — you can still test correctness. Data format conversion, template filling, rule-based classification
AI as a System Component
Hard to specify
Behavior is too complex or contextual for rules. Hard to write conventional tests — no expected output. The value comes precisely from what's hard to specify. Summarization, intent detection, creative generation, open-ended Q&A
Think before you build

Ask yourself: 1. What are you building — how "reviewable" and fixed you want your output? 2. Who are you building for? If the answer to #2 is "humans", think harder.

Four challenges of working with LLMs

  1. Getting a single call right — How do I craft a prompt that reliably produces the output I need?
  2. Managing a conversation — How do I give the model the right context across turns without blowing up cost?
  3. Long-term memory — How do I remember a user across sessions — their facts, preferences, history?
  4. Enterprise / community knowledge — How do I connect knowledge across users while respecting privacy?
02 / ANATOMY OF AN API CALL

The building blocks

Every API call has three parts: the system message, the user message, and the parameters.

Your first API call

from openai import OpenAI

client = OpenAI()

response = client.chat.completions.create(
    model="gpt-4.1-mini",
    messages=[
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "What is the capital of France?"},
    ],
    temperature=0.0,
)

print(response.choices[0].message.content)
# >>> The capital of France is Paris.

System vs. User messages

Two distinct roles that frame every API call.

System Message

Purpose: Defines the model's persona, tone, constraints, and output format.

Convention: You resend it every call, but keep it the same across turns. The API is stateless.

Tip: Put guardrails and formatting rules here so they can't be overridden by user input.

User Message

Purpose: The actual task, question, or input data for this specific request.

Changes: Every turn. Each new request or follow-up goes here.

Tip: Include few-shot examples, context, and delimiters in the user message for best results.

Key principle

System = stable rules. User = variable input. Separate concerns cleanly.

System message examples

Same question, same model, same temperature — completely different tone and depth:

System Message User Message Output
"You are a formal financial analyst. Be precise and use technical terminology." "Explain what an API is." An Application Programming Interface (API) is a formally defined contract specifying how software components exchange data and invoke operations...
"You are a friendly teacher explaining concepts to a 10-year-old. Use analogies." "Explain what an API is." Think of an API like a waiter in a restaurant! You tell the waiter what you want, they go to the kitchen, and bring back exactly what you asked for...

UI vs API

With both, you have defaults and controls. But they vary — and you must make choices intentionally. New features come out every day.

Capability Chat UI API
Tools Product-managed Developer-defined
Memory Product-managed Developer-managed (if you want)
Structured outputs Best-effort Enforced via JSON Schema
03 / TEMPERATURE & PARAMETERS

The creativity dial

Low Temperature (0.0 – 0.3)

Behavior: Picks the most likely token almost every time. Output is almost consistent and repeatable.

Best for: Classification, data extraction.

High Temperature (0.7 – 1.5)

Behavior: Flattens the probability distribution, giving less-likely tokens a real chance. Output varies across runs.

Best for: Creative writing, brainstorming, dialogue, exploration, generating diverse options.

Temperature in action

Prompt: "Write a one-sentence description of the ocean."

temp=0.0 temp=0.7 temp=1.5
The ocean is a vast body of saltwater that covers over 70% of the Earth's surface. The ocean is an immense, ever-shifting expanse of saltwater teeming with life. Beneath turquoise veils the ocean hums ancient lullabies to forgotten shores.
Deterministic, same every time Similar but varied Wildly different
Rule of thumb

Start at 0.0 for precision tasks, 0.7 for creative tasks. Adjust from there.

Other useful API parameters

Six knobs that control how the model generates its response:

Parameter What it does
top_p (Nucleus) Alternative to temperature. Samples from the smallest set of tokens whose cumulative probability exceeds p.
max_tokens Hard cap on response length. Prevents runaway generation and controls cost.
stop sequences Strings that halt generation when encountered. Useful for structured outputs.
frequency_penalty Penalizes tokens proportional to how often they've appeared. Reduces repetition in long-form text.
presence_penalty Flat penalty for any token that has appeared at all. Encourages the model to explore new topics.

Default values work for most cases. Tune one parameter at a time and measure the impact.

04 / PROMPTING COOKBOOK

Reusable patterns for modern LLMs

The real key insights

1. Ask the model — iterate — "fine tune" the prompt. 2. Don't trust people with "key meta-insight slides" — just try stuff.

The meta-insight

  1. Calibrate specificity — Find the Goldilocks zone between brittle over-specification and vague under-specification. Anthropic calls this "the right altitude."
  2. Models follow literally — Claude 4.x does exactly what you ask — no more, no less. If you want thoroughness, ask for it. If you want brevity, specify it.
  3. Cut redundancy, not structure — Remove hedging and over-explanation. Keep output format, constraints, audience, and verification criteria.

A possible prompt skeleton

ROLE OBJECTIVE CONTEXT CONSTRAINTS OUTPUT FORMAT VERIFY
Expert stance (optional) One-sentence goal Facts, input data Audience, length, tone Exact structure Quality gate

Claude prefers XML tags (<context>, <instructions>). OpenAI works with both XML and LABEL: sections.

Direct instruction & role prompting

Direct Instruction

The baseline. Clear, literal instructions for simple tasks.

Summarize for a VP:
- exactly 5 bullets
- include 1 risk + 1 recommendation
Text: [paste]

If output drifts, add an output clamp.

Role Prompting

Shapes tone, vocabulary, depth. Does NOT improve factual correctness.

Act as a senior SRE.
Return:
1) Findings (major)
2) Missing evidence
3) Follow-ups (top 5)

Gemini takes personas very seriously — test for conflicts.

Scope & structure

Scope Discipline

Set explicit boundaries. "Fix this function" without scope may trigger a full refactor.

Implement EXACTLY this and nothing else. If ambiguous, pick simplest valid interpretation.

Structured Formatting

Delimiters prevent the model from confusing instructions with data. Separate instructions from data. Put long data first, instructions last.

FormatExampleBest for
XML tags<context>...</context>Claude, OpenAI
LABEL: sectionsROLE: / CONSTRAINTS:Quick UIs, Gemini 3
Markdown## InstructionsGeneral readability
Triple quotes"""content"""Data vs instructions

Few-shot prompting

Show the model what you want by providing examples in the prompt itself.

The technique

  • Zero-shot: No examples. Relies entirely on the model's training.
  • One-shot: One input–output pair shows the pattern.
  • Few-shot (3–5): Multiple examples lock in format, tone, and edge cases.

Best practices

  • Diverse examples: Cover typical cases AND edge cases.
  • Consistent format: Use identical delimiters (Input: / Output:) in every example.
  • Order matters: Place the most similar example last, closest to the actual task.
Key insight

Few-shot is the single most reliable way to control output format without fine-tuning.

Chain of Thought (CoT)

Force the model to show its work before giving a final answer.

Why it works

LLMs generate tokens sequentially. When you force intermediate reasoning steps, each subsequent token is conditioned on better context.

Key insight: The model "thinks" by writing. No writing = no thinking. CoT gives the model scratch space.

CoT variants

  • Zero-shot CoT: Add "Let's think step by step" to trigger reasoning.
  • Structured CoT: Prescribe steps: "First analyze X, then evaluate Y, finally conclude Z."
  • Few-shot CoT: Provide examples that include reasoning traces, not just answers.

CoT is most impactful for math, logic, multi-step reasoning, and complex decision-making tasks.

Long-context placement

Where you place instructions relative to data significantly affects quality.

Poor Placement (maybe) Good Placement (maybe)
Answer these questions:
1. Retention period?
2. Backup procedures?

Document:
[15,000 words of policy...]
<document>
[15,000 words of policy...]
</document>

Based on the document above:
1. Retention period?
2. Backup procedures?
Cite relevant section numbers.
The rule

Long data first → instructions last → query at the very end.

05 / STRUCTURED OUTPUT

Schema extraction & reasoning depth

Schema extraction

The biggest practical difference between UI and API.

UI: Best-Effort

Extract into JSON with exactly these keys:
party_name, jurisdiction,
effective_date, termination_summary

If unknown, set null.
No extra keys.

API: Enforced

OpenAI: text.format with strict: true → guaranteed shape

Anthropic: Prefilling + tool-use schemas → enforced structure

If you're building a pipeline that parses model output, always use API-level enforcement.

Reasoning depth

Trade off latency/cost vs. correctness. Not all tasks need deep reasoning.

OpenAI Anthropic Google
Knob reasoning.effort
(none/low/med/high)
thinking.budget_tokens
(extended thinking)
Model selection
(Flash vs Pro)
Best for Granular effort tuning Complex multi-step; interleaved thinking Binary model choice
06 / QUALITY & PRODUCTION PATTERNS

From prompts to production

Quality patterns

Answer → Review → Re-answer

A single-call self-critique: Draft your answer, critique it for errors and gaps, then revise. All three steps in one API call — no orchestration needed.

Especially powerful for factual tasks, math, and any output that can be objectively verified.

Evaluation-First

Define success before proposing solutions. The prompting equivalent of test-driven development.

Before proposing, do this:

  1. Define success metrics
  2. Define baseline + thresholds
  3. Propose 3 interventions
  4. Predict impact + validation plan

Reflection loops

Multi-turn self-improvement: ask the LLM to evaluate and iterate on its own output.

The loop

  1. Call 1: Generate initial answer.
  2. Call 2: "Here is your previous answer. Rate it 1–10 on [criteria]. What would you improve?"
  3. Call 3: "Apply those improvements and produce the final version."

Repeat calls 2–3 until quality plateaus or budget is reached.

When to use

  • High-stakes output: Legal drafts, medical summaries, customer-facing content.
  • Latency-tolerant: Batch processing, async workflows where extra calls are acceptable.

Set a max iteration count (2–3 rounds). Diminishing returns kick in fast.

Prompt chaining

The bridge between "prompting" and "building an AI system."

Call 1: EXTRACT Call 2: ANALYZE Call 3: GENERATE Read 5 paper abstracts. → Group by methodology. → Write a 500-word literature For each: research question, Identify agreements, review. Academic tone. methodology, key finding. contradictions, and gaps. Highlight the key gap. Return as JSON array. Structured comparison. effort: low effort: medium effort: high

Why chain? Verify intermediate results. Different models/reasoning per step. Clear debugging surface. Prevent corner-cutting.

Error handling & retries

Production LLM calls fail. Plan for it.

Common failures

  • Rate limits (429): Back off exponentially. Use jitter to avoid thundering herds.
  • Timeouts: Set aggressive timeouts (30–60s). Retry with the same prompt; non-determinism means a retry may succeed.
  • Malformed output: JSON didn't parse? Retry once. If it fails again, fall back to a simpler prompt or model.

Robustness patterns

  • Retry with backoff: 1s → 2s → 4s with random jitter. Max 3 retries for most use cases.
  • Model fallback: If GPT-4o fails, fall back to GPT-4o-mini. Graceful degradation beats total failure.
  • Validation layer: Always validate output before using it. Schema checks, length checks, safety checks.
07 / STATELESS VS STATEFUL INTERACTIONS

Managing conversation state

The API is stateless: every call is independent. The model has no memory of previous interactions. To have a conversation, you manage the state.

Stateless agent

Each call is self-contained. Send a system message + user message, get a response. No history, no context. Simple, cheap, predictable.

# Every call starts fresh
response = client.chat.completions.create(
    model="gpt-4.1-mini",
    messages=[
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "What is the capital of France?"},
    ],
)

Stateful agent

You maintain the conversation history and resend it with each call. The model sees the full context and can reference earlier turns.

# You manage the conversation history
history = [
    {"role": "system", "content": "You are a helpful assistant."},
]

def chat(user_message):
    history.append({"role": "user", "content": user_message})
    response = client.chat.completions.create(
        model="gpt-4.1-mini",
        messages=history,
    )
    assistant_msg = response.choices[0].message.content
    history.append({"role": "assistant", "content": assistant_msg})
    return assistant_msg
The trade-off

More context = better responses, but also more tokens = more cost. You must decide what context is worth keeping and what to trim.

Context management strategies

CLOSING

Start simple. Escalate on failure. Measure everything.

Patterns persist across model updates; knobs don't.

Lab notebooks

Python scripts

REFERENCES

Sources & further reading

Prompting guides

API documentation