Zenaique

How does a declarative LLM framework differ from an imperative one in what the developer actually writes?

Flashcard·Easy·4.0 · 0·~30s·Asked atCanvaDifyNotion
Attempt it
TL;DR

Declarative tools like DSPy and BAML compile prompts from a signature plus a metric; imperative tools like LangChain and LlamaIndex execute the prompts and steps the developer wrote.

Memory aid
Sign in to see the mnemonic that makes this stick.
Easy to grasp

Picture two cooks asked to make the perfect omelet. The first cook writes the recipe themselves, three eggs, this much butter, sixty seconds on each side, and follows it exactly. If the omelet is bad, they edit the recipe and try again. The second cook only writes down what counts as a great omelet and hands a robot a basket of eggs. The robot tries hundreds of recipes, keeps the ones the judge liked best, and serves the winner. Cook one knows every detail of how the omelet was made. Cook two never sees the recipe but the omelet usually scores higher. Different tradeoffs, both valid.

Concept explanation~2 min read

Everything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example. Click to expand.

The declarative versus imperative split is the most useful single axis for thinking about LLM frameworks in 2026. It cuts cleaner than the popular tribal lines, LangChain versus LlamaIndex, Python versus TypeScript, agents versus chains, because it names what the developer's artifact actually is.

This deep dive walks through what each family asks of the developer, what each one produces, where the tradeoffs land, and why most serious production systems end up using both at different layers of the stack.

The imperative side: you write the prompt

LangChain and LlamaIndex are imperative frameworks. The developer authors the prompt text, decides what to put in the context window, picks the chain steps, and wires them together with explicit code. The framework provides composition primitives, LCEL's pipe operator, LlamaIndex's QueryEngine, and execution machinery. It does not change what the model sees.

What this looks like in code

In LangChain you write ChatPromptTemplate.from_messages([('system', '...'), ('human', '{query}')]), you wire it into a chain with prompt | model | parser, and what runs is exactly what you wrote. A traced run shows the literal text sent to the model on each call.

What you get from this

The imperative side wins on three things. First, debuggability: every prompt is a string you can read in source, every step is a node in a trace. Second, control: you can branch on any signal at any point because the orchestration is your code. Third, novelty handling: when a task is brand new and you do not know what good looks like yet, the ability to iterate on prompts directly is faster than setting up a metric and an optimizer.

What you give up

The imperative side does not optimize prompts for you. Every improvement is a human edit. The prompt that ships is the prompt the developer typed; if a slightly different phrasing scores 15 percent better on the eval set, the developer has to find that phrasing manually.

The declarative side: you write the spec
Why the analogy with SQL matters
How serious teams mix the two
Sign in to unlock the full deep dive.

Situations where this technique stops working.

Sign in to see when this approach fails.

2–4 min · Everything important, quickly.

Sign in to see the quick scan of the deep dive.
AxisImperative (LangChain, LlamaIndex)Declarative (DSPy, BAML)
What developer writesPrompts plus chain codeSignature or schema plus metric
What model receivesWhat the developer wroteWhat the compiler generated
OptimizationManual prompt iterationAutomatic search against a metric or codegen from schema
DebuggabilityEvery step visibleFinal prompt is a compiler artifact
Best fitMoving target, no labels, deep custom controlStable task, labeled data, want prompt to keep improving

Real products, models, and research that use this idea.

  • DSPy 2.6 ships MIPROv2 as the default optimizer, used in production by Databricks and several Anthropic-customer pipelines.
  • BAML is used by Vercel and Notion-style teams that want schema-first LLM calls with TypeScript codegen.
Sign in to see more production examples.

What an interviewer would ask next. Try answering before peeking at the approach.

QWalk through how DSPy's MIPROv2 optimizer actually searches the prompt space.
A

It uses a teacher-student bootstrapping loop: a stronger model proposes candidate instructions and exemplars, the metric scores each candidate against the labeled set, Bayesian-style search narrows toward high scorers; the output is the prompt the cheaper model will run at inference.

2 more follow-ups an interviewer would ask next. Sign in to reveal them.

Red flags & common mistakes

The phrases that signal junior thinking. Click to expand.

Most common mistake

Treating DSPy as just another chain builder, then being confused that you never get to write the actual prompt text the model sees.

Sign in to see all red flags and common mistakes.

60 second bullets to scan on the way to the call.

  • What a DSPy Signature contains and how it differs from a prompt template

  • What BAML codegen produces and at which point in the build pipeline

Sign in to unlock the revision sheet.

Primary sources. Browse if you want the original framing.

Similar questions

Same topic, related formats. Practice these next.

4 curated
Next question
Defend the call to…
Short answer·Hard