This page requires JavaScript to display.
G
Unpacking...
← Generative AI
Generative AI

Generative AI Reference

LLM fundamentals, prompting, calling models from Python, structured extraction, tool use and agents, embeddings and RAG, data engineering for AI, cost, evaluation, and Gen AI platforms.

Contents
1. What Generative AI & LLMs Are 2. Prompt Engineering 3. Calling an LLM from Python 4. Structured Extraction for Pipelines 5. Tool Use & Agents 6. Embeddings & Vector Search 7. Retrieval-Augmented Generation (RAG) 8. Data Engineering for Gen AI 9. Cost, Caching & Performance 10. Evaluation, Guardrails & Safety 11. Gen AI on Cloud & Data Platforms 12. Common Interview Questions

1. What Generative AI & LLMs Are

Large language models (LLMs) are neural networks (transformers) trained on huge text corpora to predict the next token. With instruction tuning and reinforcement learning from feedback, they follow instructions, write and explain code, extract information, reason over documents and call tools. Generative AI is the broader family that generates text, code, images, audio and video.

ConceptWhat it means in practice
TokenThe unit models read and bill by: roughly ¾ of an English word. Prices are quoted per million input and output tokens
Context windowHow many tokens fit in one request (prompt + documents + history + output). Current frontier models handle around 1M tokens
InferenceRunning the trained model on your prompt. You call it through an API; you do not train it
Temperature / samplingRandomness of generation. Some current models fix sampling server-side and steer quality through other controls
Reasoning / thinkingModels can reason internally before answering; an effort setting trades depth against cost and latency
HallucinationA fluent but unsupported answer. Mitigate with retrieval (RAG), citations, structured outputs and evaluation
Fine-tuning vs prompting vs RAGTry prompting first, add RAG for private or fresh knowledge, and fine-tune only for style or format at very high volume

2. Prompt Engineering

System: You are a data-quality assistant for a bank's data platform.
        Answer only from the table profile provided. If something cannot be
        determined from the profile, say "unknown" instead of guessing.

User:   <table_profile>
        table: silver.transactions   rows: 48,210,334
        column txn_id      nulls: 0       distinct: 48,210,334
        column amount      nulls: 1,204   min: -50.00   max: 9,800,000.00
        column channel     nulls: 0       values: UPI, CARD_POS, ATM, NEFT, upi
        </table_profile>

        List the data-quality issues as a numbered list, each with a suggested SQL check.

A good answer flags the NULL amounts, the negative amount, a suspiciously large maximum, and inconsistent casing ("UPI" vs "upi"), each with a check. That is the kind of task LLMs do well for data teams.

3. Calling an LLM from Python

Examples use the Anthropic Python SDK (pip install anthropic). The client reads credentials from the ANTHROPIC_API_KEY environment variable; never hard-code keys.

import anthropic

client = anthropic.Anthropic()            # reads ANTHROPIC_API_KEY from the environment

response = client.messages.create(
    model="claude-opus-5-5",
    max_tokens=16000,
    output_config={"effort": "medium"},   # low / medium / high / xhigh / max: depth vs cost
    system="You are a senior data engineer. Answer concisely with PySpark examples.",
    messages=[{"role": "user",
               "content": "How do I deduplicate a DataFrame keeping the latest row per id?"}],
)

if response.stop_reason == "refusal":
    print("Request declined:", response.stop_details)
else:
    for block in response.content:            # content is a list of typed blocks
        if block.type == "text":
            print(block.text)

print(response.usage.input_tokens, response.usage.output_tokens)   # what you are billed for

4. Structured Extraction for Pipelines

A common data-engineering use: turn unstructured text (emails, invoices, tickets, KYC documents) into validated rows. Structured outputs guarantee the response matches your schema:

from datetime import date
from pydantic import BaseModel
import anthropic

class Invoice(BaseModel):
    vendor: str
    invoice_number: str
    invoice_date: date
    currency: str
    total_amount: float
    line_items: list[str]

client = anthropic.Anthropic()

def extract_invoice(text: str) -> Invoice:
    response = client.messages.parse(
        model="claude-opus-5-5",
        max_tokens=16000,
        system="Extract invoice fields exactly as written. Use ISO dates and 3-letter currency codes.",
        messages=[{"role": "user", "content": f"<invoice>\n{text}\n</invoice>"}],
        output_format=Invoice,
    )
    return response.parsed_output          # a validated Invoice instance

inv = extract_invoice(open("invoice_0425.txt").read())
print(inv.vendor, inv.total_amount)

5. Tool Use & Agents

With tool use, the model decides to call functions you define (query a warehouse, look up a customer, open a ticket). Your code executes them and returns the results. The SDK's tool runner handles the loop:

import anthropic
from anthropic import beta_tool

client = anthropic.Anthropic()

@beta_tool
def row_count(table: str, business_date: str) -> str:
    """Return the row count of a warehouse table for one business date.

    Args:
        table: Fully qualified table name, e.g. silver.transactions.
        business_date: Date in YYYY-MM-DD format.
    """
    allowed = {"silver.transactions", "gold.daily_sales"}       # read-only allow-list
    if table not in allowed:
        return f"Table {table} is not allowed."
    n = run_sql(f"SELECT COUNT(*) FROM {table} WHERE event_date = %s", [business_date])
    return str(n)

runner = client.beta.messages.tool_runner(
    model="claude-opus-5-5",
    max_tokens=16000,
    tools=[row_count],
    messages=[{"role": "user",
               "content": "Did silver.transactions load fully on 2026-10-25 compared with 2026-10-24?"}],
)
for message in runner:                     # each step: model reply, tool calls, tool results
    for block in message.content:
        if block.type == "text":
            print(block.text)

6. Embeddings & Vector Search

An embedding is a vector of numbers representing the meaning of a text. Similar meanings give vectors that point in similar directions, so you can search by meaning instead of keywords.

import numpy as np

def cosine(a: np.ndarray, b: np.ndarray) -> float:
    return float(a @ b / (np.linalg.norm(a) * np.linalg.norm(b)))

# vectors come from an embedding model (hundreds to thousands of dimensions)
query = np.array([0.12, 0.85, 0.31])
docs = {"refund policy":      np.array([0.10, 0.80, 0.35]),
        "kafka partitioning": np.array([0.90, 0.05, 0.20])}

ranked = sorted(docs, key=lambda d: cosine(query, docs[d]), reverse=True)
print(ranked)    # ['refund policy', 'kafka partitioning']
ComponentOptions
Embedding modelDedicated embedding models, e.g. Voyage AI, open-source sentence-transformers, Amazon Titan, Azure OpenAI or Vertex AI embeddings. Claude itself does not provide an embeddings endpoint
Vector storepgvector (Postgres), OpenSearch, Azure AI Search, Databricks Vector Search, Pinecone, Weaviate, Milvus
Index typeHNSW or IVF approximate nearest-neighbour indexes trade a little recall for large speed-ups
-- pgvector: store and search embeddings next to your relational data
CREATE EXTENSION IF NOT EXISTS vector;

CREATE TABLE doc_chunks (
  chunk_id   BIGSERIAL PRIMARY KEY,
  doc_id     TEXT,
  content    TEXT,
  embedding  VECTOR(1024),
  department TEXT                       -- metadata for filtering and access control
);
CREATE INDEX ON doc_chunks USING hnsw (embedding vector_cosine_ops);

SELECT doc_id, content
FROM doc_chunks
WHERE department = 'risk'               -- filter first: only documents this user may see
ORDER BY embedding <=> :query_embedding -- <=> is cosine distance
LIMIT 5;

7. Retrieval-Augmented Generation (RAG)

RAG answers questions from your documents: retrieve the most relevant chunks, put them in the prompt, and ask the model to answer only from them, with citations.

 INDEXING (batch / incremental)                     QUERY TIME
 docs (PDF, wiki, tickets, tables)                  user question
   → parse & clean → chunk (300–800 tokens,           → embed question
     with overlap + metadata) → embed                 → vector (+ keyword) search, filtered by user's access
   → vector store (+ source, owner, ACL, date)        → rerank top results
                                                      → prompt: instructions + retrieved chunks + question
                                                      → answer with citations → log for evaluation
def answer(question: str, user: User) -> str:
    chunks = search(embed(question), allowed_departments=user.departments, k=6)
    context = "\n\n".join(
        f'<doc id="{c.doc_id}" title="{c.title}">\n{c.content}\n</doc>' for c in chunks)

    response = client.messages.create(
        model="claude-opus-5-5",
        max_tokens=16000,
        system=("Answer using only the documents provided. Cite document ids in square brackets. "
                "If the documents do not contain the answer, say you don't know."),
        messages=[{"role": "user",
                   "content": f"<documents>\n{context}\n</documents>\n\nQuestion: {question}"}],
    )
    return next(b.text for b in response.content if b.type == "text")
ProblemFix
Relevant passage not retrievedBetter chunking (by headings), hybrid keyword + vector search, query rewriting, reranking
Answer not grounded in sourcesStrict "answer only from documents" instruction, citations, refuse when evidence is missing
Stale answersIncremental re-indexing from change feeds (e.g. Delta Change Data Feed) with document versioning
Users see documents they should notEnforce access control at retrieval time with metadata filters, never only in the prompt

8. Data Engineering for Gen AI

Most of the work in production Gen AI is data engineering: the model is only as good as the data and context it receives.

9. Cost, Caching & Performance

LLM cost is mostly input tokens times requests. Prompt caching stores a long, repeated prefix (instructions, schemas, reference documents) so later requests read it at a fraction of the price:

response = client.messages.create(
    model="claude-opus-5-5",
    max_tokens=16000,
    cache_control={"type": "ephemeral"},     # cache the longest stable prefix automatically
    system=LONG_DATA_DICTIONARY,             # identical on every request
    messages=[{"role": "user", "content": question}],   # varies per request (after the cached prefix)
)
print(response.usage.cache_read_input_tokens)    # > 0 on later calls means the cache was hit

10. Evaluation, Guardrails & Safety

PracticeHow
Golden test setsRepresentative questions with expected answers or facts; run on every prompt or model change, like regression tests
Automatic gradingExact-match or schema checks where possible; an LLM-as-judge with a clear rubric for open-ended answers, spot-checked by humans
GroundednessCheck that answers cite retrieved documents and that cited text supports the claim
Prompt-injection defenceSeparate instructions from data, least-privilege tools, approval for side-effecting actions, output filtering
RefusalsCheck stop_reason == "refusal" and handle it explicitly (fallback model, message to the user)
Monitoring in productionTrack quality metrics, user feedback, latency, cost and refusal rate over time

The API can automatically retry a declined request on a fallback model (beta):

response = client.beta.messages.create(
    model="claude-opus-5-5",
    max_tokens=16000,
    betas=["server-side-fallback-2026-07-01"],
    fallbacks="default",                      # the API picks a suitable fallback model
    messages=[{"role": "user", "content": question}],
)
if response.stop_reason == "refusal":         # the whole fallback chain declined
    handle_refusal(response.stop_details)

11. Gen AI on Cloud & Data Platforms

PlatformGen AI services
Anthropic APIClaude models directly, with prompt caching, batches, tool use and structured outputs
AWSAmazon Bedrock (Claude and other models, Knowledge Bases for RAG, Guardrails, Agents), SageMaker for custom models, OpenSearch / Aurora pgvector for vectors
AzureMicrosoft Foundry (model catalog including Claude and OpenAI models), Azure AI Search for retrieval, Prompt Flow, content safety
Google CloudVertex AI (Gemini, Claude and open models), Vertex AI Search, AlloyDB / BigQuery vector search
DatabricksMosaic AI: Model Serving and AI Gateway, Vector Search, Agent Framework and evaluation, AI Functions in SQL, all governed by Unity Catalog
SnowflakeCortex AI functions (summarise, extract, classify in SQL), Cortex Search

Running models inside your existing cloud platform keeps data in your account and region, reuses existing IAM, networking and billing, and simplifies compliance reviews.

12. Common Interview Questions

QuestionShort answer
What is RAG and why use it instead of fine-tuning?Retrieve relevant documents and put them in the prompt. It adds private and fresh knowledge without training, supports citations and access control, and updates by re-indexing; fine-tuning suits style or format, not facts
How do you choose chunk size?Big enough to hold a complete idea and small enough to stay specific: usually a few hundred tokens with some overlap, split on document structure; tune with retrieval evaluation
What is an embedding?A vector representing meaning; similar texts have high cosine similarity, enabling semantic search
How do you reduce hallucinations?Ground with retrieval, instruct to answer only from sources and cite them, allow "I don't know", use structured outputs, and evaluate groundedness
How do you secure an LLM app that reads company data?Enforce access control at retrieval, redact PII, least-privilege tools, approvals for writes, treat retrieved text as untrusted, log and audit
How do you evaluate an LLM feature?A versioned golden set, automatic metrics or rubric-based LLM grading with human spot checks, and production monitoring of quality, cost and latency
How do you control cost?Prompt caching for repeated prefixes, batching offline work, sending only relevant context, right-sizing model and effort, measuring cost per task
What is an agent?A loop where the model plans, calls tools and observes results until done; use it for open-ended tasks, with guardrails and limits