The Tech ArchiveThe Tech ArchiveThe Tech Archive
Small BusinessMarketingDevelopers
ArticlesTopicsSeriesAbout

Get the practical AI brief

Verified, no-hype AI tips you can actually use - in your inbox. Free.

No spam. We verify what we send. Unsubscribe anytime.

The Tech ArchiveThe Tech Archive

The Tech Archive

AI news, analysis & explainers

AboutSmall BusinessMarketingDevelopersArticlesTopicsSeriesMethodologyAI DisclosureCorrections

© 2026 All rights reserved.

Back to home
0 readers reading
  1. Home
  2. Articles
  3. Artificial Intelligence
  4. How to Separate the Task From the Model in Your LLM Pipeline in 2026 (DSPy Practical Guide)

Contents

How to Separate the Task From the Model in Your LLM Pipeline in 2026 (DSPy Practical Guide)
Artificial Intelligence

How to Separate the Task From the Model in Your LLM Pipeline in 2026 (DSPy Practical Guide)

DSPy lets you define what your AI task should do in code, lock the contract with examples, and auto-search the cheapest model that clears your bar. Here is the full 2026 playbook.

Sham

Sham

AI Engineer & Founder, The Tech Archive

18 min read
1 views
July 29, 2026

Verdict: The single most leveraged move you can make with LLM pipelines in 2026 is to separate what the task should do (a stable contract you control) from how the model does it (the volatile, ever-improving region underneath). DSPy — the open-source framework from Stanford NLP — is the tool that codifies this split. Shopify used the same discipline to cut one AI workload's cost by roughly 550× by swapping an expensive model for a cheap one without touching the business logic (dspy.ai/community/use-cases). This guide shows how to apply the same idea to your own pipeline — with the four primitives, three claim layers, four optimizer choices, and a worked example you can run this afternoon.

Last verified: 2026-07-29 · Best for cost-critical, repeated tasks · Saves the most when models change often · 1 pip install (pip install dspy) · Python 3.10+ (dspy.ai/installation) Pricing/feature facts below are volatile — DSPy moves fast (latest stable: 3.2.1 at time of writing). Re-check the docs before committing to a specific API.


TL;DR — the four-bullet version

  • The core insight: treat each LLM task like a Python function — separate the interface (inputs/outputs) from the implementation (the prompt, the model, tool loops).
  • The three claim layers you must pin down before optimizing: spec (natural-language instructions), code (hard constraints enforced in Python), and evals (examples that show what "good" looks like).
  • DSPy does the search for you — given a signature, training data, and a metric, its optimizers (BootstrapFewShot, MIPROv2, GEPA, SIMBA) automatically find the prompt + few-shot mix that maximizes your metric.
  • The payoff is agility, not just accuracy: when a new, cheaper model lands, you re-run the optimizer against the same pinned contract — no prompt rewrite, no integration churn.

What does "separate the task from the model" actually mean?

It means locking the boundary of a task — its inputs, outputs, and constraints — in code, and keeping the internals (the prompt wording, the reasoning strategy, which model is called) completely free to change. When the boundary is fixed, the internals become an optimization target someone else (or an algorithm) can search.

The everyday analogy is a Python function. You give a function a name, a list of inputs, and a return type. Then you get to: reuse it thousands of times, swap the inside, compose it into bigger programs, distribute it as a black box. DSPy brings every one of those properties to LLM programs (dspy.ai, github.com/stanfordnlp/dspy).

This split is valuable for the same reason the function split in ordinary software was valuable. When models improve (or get cheaper) every few weeks, you want to upgrade the inside without touching anything outside. You want to search the inside. You want to compose the inside. And when the next research paper drops a trick — chain-of-thought, retrieval, tool use, agentic loops — you want to try it without rebuilding the system around it.


The three claim layers you must pin down before you optimize

DSPy's core design insight is that a task is fully specified only when you pin three things together. Miss any of the three and you cannot hand the task to an automatic optimizer.

1. Spec — "what should happen" (instructions)

The spec is the natural-language declaration of what the LLM should do. In DSPy, it lives inside a Signature — a class that declares named input and output fields plus an optional docstring. The docstring and field names become the prompt the model sees; you don't write prompt strings by hand.

class ExtractTax(dspy.Signature):
    """Extract the tax value (as a float) from the invoice text.
    If the amount is illegible, output zero."""
    invoice: str = dspy.InputField()
    tax: float = dspy.OutputField()

The signature is the contract — the boundary that does not move. Your integration depends only on invoice -> tax, never on the wording that produced it.

2. Code — "what must happen" (hard constraints)

Specs are natural language; some things you need enforced as code. DSPy ships with a small primitives layer for this — e.g. dspy.Predict (vanilla call), dspy.ChainOfThought (adds reasoning). You compose them in forward(), and you can branch on the result:

class TaxProgram(dspy.Module):
    def __init__(self):
        self.extract = dspy.Predict(ExtractTax)
        self.extract_cot = dspy.ChainOfThought(ExtractTax)
    def forward(self, invoice):
        pred = self.extract(invoice=invoice).tax
        if pred == 0:                     # fallback: reasoning helps
            pred = self.extract_cot(invoice=invoice).tax
        if pred < 0:                      # hard guardrail
            raise ValueError("negative tax — hand to a human")
        return pred

The if pred == 0 and if pred < 0 checks are constraints you refuse to give up, even if the inside changes. They are the part of the contract the optimizer cannot touch.

3. Evals — "what good looks like" (examples + metric)

The third layer is empirical. Some things cannot be written as instructions or code — they can only be shown by example. A beginner recognizes a maple tree because someone pointed at enough examples over time, not because they memorized a definition. DSPy formalizes this with Examples (your labeled training data) and a metric function that scores a prediction from 0 to 1.

examples = [
    dspy.Example(invoice="Invoice 4410, tax 8.20", tax=8.20).with_inputs("invoice"),
    dspy.Example(invoice="Invoice 4411, tax 0.00", tax=0.00).with_inputs("invoice"),
]

def tax_metric(example, pred, trace=None):
    return float(abs(pred.tax - example.tax) < 0.01)

With spec + code + evals in hand, your task is fully specified. Every new release of any model can now be benchmarked against the same bar; every new technique can be tried as a one-line swap inside the boundary; and automatic optimization becomes possible.


The DSPy primitives you build with

Primitive What it is One-line role
Signature Typed input/output spec for one LLM step The contract. The thing that does not move.
Module A class wrapping signatures with forward() logic Where you compose steps and add code guards.
Optimizer A search algorithm that improves your module The thing that fills in the inside for you.
Example A labeled input/output pair for training/eval The unit of "what good looks like."

You configure the model once — fully independent of your signatures — and every module inherits it. This is the literal moment the "task vs model" separation happens in code:

import dspy
lm = dspy.LM("openai/gpt-4o-mini", api_key="...")
dspy.configure(lm=lm)           # the model — changeable anytime
program = TaxProgram()           # the task — stable contract

To swap models later you change one line (dspy.LM(...)). Nothing else in the codebase moves. (dspy.ai/installation, github.com/stanfordnlp/dspy)


Which DSPy optimizer should you use?

This is the single most common question for new DSPy users. The answer depends on how much data you have, how important accuracy is, and how long you can wait for compilation to finish. DSPy lists all of them under dspy.<OptimizerName> (dspy.ai/optimizers).

Optimizer Best for What it optimizes Min. data Time
BootstrapFewShot Quick prototyping, small sets Few-shot demos ~20–50 labeled minutes
BootstrapFewShotWithRandomSearch Mid-size sets, better than baseline Demos + which to include ~50–200 labeled tens of minutes
MIPROv2 Production-grade accuracy Instructions + demos (Bayesian search) ~200–500 labeled hours / overnight
GEPA Multi-objective search (Pareto) Instructions on the Pareto frontier labeled + metric hours
SIMBA Self-reflective rule discovery Rules + demos from mini-batch failures labeled + metric hours

Decision shortcut: validate your pipeline with BootstrapFewShot first. Graduate to MIPROv2 when you have 200+ examples and need production-grade accuracy. Reach for GEPA when you want a frontier of strong prompts (it maintains a Pareto set diversifying across problem types — see arXiv:2507.19457). Reach for SIMBA when you want the optimizer to write self-reflective rules from its own hard examples (dspy.ai/api/optimizers/SIMBA).

A common mistake is jumping straight to MIPROv2 before validating the signature, module, and metric work. A broken metric produces "optimized but useless" output. Start simple, confirm the pipeline produces something sane with BootstrapFewShot, then scale up the optimizer.


How to put it together: a worked extractor example

Here is a minimal but complete pattern — the kind of thing you can run this afternoon — that orchestrates the separation. Real production versions swap the signature, add more code guards, and pick a bigger optimizer.

import dspy

lm = dspy.LM("openai/gpt-4o-mini", api_key="...")
dspy.configure(lm=lm)

# 1. SPEC — the contract that does not move
class ExtractTax(dspy.Signature):
    """Extract the tax value (as a float) from the invoice text.
    If the amount is illegible, output zero."""
    invoice: str = dspy.InputField()
    tax: float = dspy.OutputField()

# 2. CODE — your hard constraints live in the module
class TaxProgram(dspy.Module):
    def __init__(self):
        self.extract = dspy.Predict(ExtractTax)
        self.extract_cot = dspy.ChainOfThought(ExtractTax)
    def forward(self, invoice):
        pred = self.extract(invoice=invoice).tax
        if pred == 0:
            pred = self.extract_cot(invoice=invoice).tax
        if pred < 0:
            raise ValueError("negative tax — hand to a human")
        return pred

program = TaxProgram()

# 3. EVALS — examples + a metric
examples = [
    dspy.Example(invoice="Invoice 4410 tax 8.20", tax=8.20).with_inputs("invoice"),
    dspy.Example(invoice="Invoice 4411 tax 0.00", tax=0.00).with_inputs("invoice"),
    dspy.Example(invoice="Invoice 4412 tax 13.50", tax=13.50).with_inputs("invoice"),
    dspy.Example(invoice="Invoice 4413 tax 5.00", tax=5.00).with_inputs("invoice"),
]
def tax_metric(example, pred, trace=None):
    return float(abs(pred - example.tax) < 0.01)

# 4. OPTIMIZE — let the optimizer fill in the inside
optimizer = dspy.BootstrapFewShot(metric=tax_metric)
compiled = optimizer.compile(program, trainset=examples)

# 5. USE — model gets swapped in one place; contract never moves
print(compiled(invoice="Invoice 9999 tax 2.40"))

The compiled result is an ordinary Python object — call it, cache it, save it (compiled.save("program.json")), load it later. The optimizer didn't change your code; it filled in the prompts with the best few-shot demonstrations and, for MIPROv2+, tuned the instruction text itself.

If you'd rather not wire an optimizer's harness yourself, you can let an autonomous AI agent loop do the bookkeeping — see our guide on self-running loops with Doer-Judge verification for the broader pattern of letting a system improve itself at runtime.


The Shopify 550× case study in plain terms

The most-cited enterprise result coming out of the DSPy ecosystem is from Shopify. According to DSPy's own use-case list, Shopify applied DSPy + GEPA to structured metadata extraction across all Shopify shops, and reduced yearly costs on that workload by roughly 550× (dspy.ai/community/use-cases; Shopify's own engineering talk is here).

The mechanism is the entire point of this article. Because the task — extract metadata, match a schema, return structured output — was pinned behind a signature and a metric, Shopify's engineers could:

  1. keep iterating on business logic inside the boundary — no integration churn,
  2. swap an expensive model for a cheap one using the same email/grader pipeline, and
  3. let GEPA search the prompt and few-shot space automatically against the same metric the team already trusted.

The 550× number is a vendor-reported metric (per DSPy's community page), so treat it as Vendor claim — Confirmed by DSPy's source list rather than a third-party audited number. We list it because DSPy's own website is the primary source here and the company itself features the result. The deeper principle — that pinning the boundary lets you chase cost dominance without breaking the system — holds regardless of the exact multipler.

If you want more like this from real production systems, Dropbox published optimizing Dash's relevance judge with DSPy for ranking, training data generation, and offline evaluation.


What new techniques are coming to DSPy (and why they all fit inside the same boundary)

DSPy ships new techniques constantly, and the whole point of the task/model split is that every new technique becomes a one-line swap inside a boundary you've already written. None of them touch your integration. Recent examples from the ecosystem:

  • Recursive Language Models (RLMs) — a paper-driven approach from the DSPy community for long-context programs. If your task spans a large inbox or a full codebase, you add RLM in one line; your signature stays the same.
  • GEPA — prompt optimizer based on Pareto-frontier selection across problem types (arXiv:2507.19457). Good when different prompts excel at different sub-tasks.
  • MIPROv2 — instruction + demo co-optimization via Bayesian search (arXiv:2406.11695). The production-grade default.
  • BetterTogether — composes optimizers so running MIPROv2 then finetuning gives better results than either alone.
  • SIMBA — Stochastic Introspective Mini-Batch Ascent (dspy.ai/api/optimizers/SIMBA). The optimizer analyzes its own failures and writes self-reflective rules.
  • DSPy Flex (upcoming in DSPy 4) — instead of optimizing prompts, optimizes the code harness itself: for any function you want to implement, DSPy can learn an entire code harness over time to solve it. Your business measure stays in place; only the learned harness changes.

The throughline is that a well-specified task can be handed to a search process that finds the cheapest implementation clearing the eval bar. Each new optimizer or technique is a better search — not a new contract.

For wider context, two of our earlier deep-dives are worth pairing with this one: how to use an open-source model as the brain of an autonomous agent (the model swap is exactly the kind of inside-change DSPy makes safe) and the broader playbook on self-improving AI agents vs static copilots (DSPy's optimizers are a concrete instance of an agent improving itself against an eval bar).


What does separating the task from the model cost you?

Nothing upfront per LLM call — DSPy is open source (MIT license, github.com/stanfordnlp/dspy) and pip install dspy works in Python 3.10+ (dspy.ai/installation). The real cost is the one-time work of writing a signature, gathering 20-500 labeled examples, and defining a metric — plus whatever time the optimizer spends (which is mostly LLM calls during compilation; you pay per call, hundreds to thousands depending on the optimizer and dataset size).

The optimizer cost is why teams often use a cheaper model during optimization and a more capable model for the compiled, deployed program — BootstrapFewShot and MIPROv2 make hundreds of LLM calls per compile. The same pattern recurs across the field: cheap agent-grade models like Gemma 4 running locally can serve as your "search/draft" model, while a frontier model is invoked only for final answers. DSPy doesn't force this — but the task/model split makes it trivial to try.


When should you NOT bother with DSPy?

DSPy adds real value for optimization-heavy, repeated tasks, but it is not free. From the trade-off literature and DSPy's own docs:

  • One-shot creative tasks — if "summarize this paragraph" with a zero-shot prompt already scores 95% on your quality bar, optimization overhead doesn't pay back.
  • Tasks with no clear metric — DSPy needs a metric to search against. If your quality is subjective and unwilling to be LLM-as-judge, you can't let the optimizer drive.
  • Rapid prototyping — for a working demo in hours, writing a prompt directly is faster than setting up training data and compilation. DSPy pays off in the optimization phase, not the prototyping phase.
  • Single-API-call pipelines with surrounding code already factored — if your pipeline is one LLM call and you've already factored that call into a function, you've already done a smaller version of the separation this article argues for.

The moment you have repeated AI tasks and any quality bar — even an approximate one — the discipline wins.


What does separating the task from the model mean for your small business or team?

If you run AI inside a recurring business process (support triage, document extraction, ad copy, content summarization, contract review), the pattern above means a few practical things:

  1. Stop hand-tuning prompts. Write a signature for each recurring task, gather 20-500 labeled examples, define a metric that proxies the business outcome (not surface-level string match), and let an optimizer find the prompt.
  2. Lock the contracts you refuse to give up. Business-critical guards — non-negative tax, JSON schema validity, PII redaction, no empty response — live as Python in forward(). These do not move when the model moves. See our playbook on redacting sensitive data before sending files to ChatGPT for the contract-first mindset.
  3. When a cheaper model drops, swap in one line and re-run. You do not start over. The optimizer re-finds the prompt for the new model against the same metric.
  4. Pick the optimizer by data size and patience. Validate with BootstrapFewShot. Go production with MIPROv2 when you have 200+ examples. Reach GEPA/SIMBA when a single prompt can't fit your whole problem space.
  5. Use the right cheap model for search, the right expensive model for answers. Treat the optimizer's model and the deployed program's model as separate knobs.

The bigger strategic point: the entire industry is splitting into two layers — a stable "what" layer that encodes business context (specs, code, evals) and a fast-changing "how" layer that DSPy and similar tools progressively commoditize. Teams that master the split now gain a durable cost-and-agility advantage as the model wars keep accelerating.


FAQ

Q: What does "separate the task from the model" mean in DSPy? A: You define the task once as a typed input/output contract (a DSPy Signature) plus constraints in code, and keep the model, prompt wording, and reasoning strategy as swappable internals. The boundary — invoice -> tax, for example — never moves; everything inside is free to be optimized or swapped for a cheaper model.

Q: Is DSPy free and open source? A: Yes. DSPy is open source under the MIT license, maintained by the Stanford NLP group. Install with pip install dspy in any Python 3.10+ environment (dspy.ai/installation, github.com/stanfordnlp/dspy). You still pay for the LLM API calls your program and its optimizer make.

Q: How many training examples do I need to start with DSPy? A: DSPy does not require massive datasets. ~20–50 labeled examples is enough for BootstrapFewShot. Plan on ~200–500 for MIPROv2. The bigger the dataset, the more signal the optimizer has to pick good demonstrations and instructions.

Q: Which DSPy optimizer should I use first? A: Start with BootstrapFewShot to validate your signature, module, and metric produce sane output. Move to MIPROv2 when you have 200+ examples and need production-grade accuracy. Reach GEPA or SIMBA when a single optimal prompt cannot cover all your problem types.

Q: How did Shopify get a 550× cost reduction with DSPy? A: Per DSPy's own use-case list, Shopify applied DSPy + GEPA to structured metadata extraction across all its shops, and moved from an expensive model to a cheap one while keeping the same business logic, examples, and grading metrics. The 550× number is Vendor-confirmed on DSPy's site; the deeper principle — pinning the boundary lets you chase cost dominance without breaking the system — holds regardless of the exact multiplier (dspy.ai/community/use-cases).

Q: Do I need to rewrite my whole pipeline to use DSPy? A: No. You can wrap any individual LLM call with a Signature + Module and optimize just that step first. DSPy modules are plain Python objects — call them, cache results, save and load the compiled program. Use it where it pays off; leave the rest of your codebase as-is.

Q: What's coming next in DSPy? A: DSPy 4 introduces further Flex optimizations (the optimizer learns an entire code harness, not just a prompt) and continues to fold in research innovations like Recursive Language Models (RLMs) for long-context programs. The constant is that each new technique is a one-line swap inside a boundary you've already pinned (dspy.ai).


Sources

Primary sources for every load-bearing claim in this article:

  1. DSPy official site & docs — dspy.ai framework overview, installation, signature/module/optimizer API.
  2. DSPy GitHub repository — github.com/stanfordnlp/dspy — MIT license, Stanford NLP maintainer, pip install dspy, Python 3.10+.
  3. DSPy use-case list (Shopify 550× and Dropbox, Microsoft AI, Databricks cases) — dspy.ai/community/use-cases.
  4. DSPy installation page — dspy.ai/getting-started/installation — pip install dspy, dspy.LM configuration.
  5. DSPy optimizers overview — dspy.ai/learn/optimization/optimizers — LabeledFewShot, BootstrapFewShot, MIPROv2 and the rest of the optimizer family.
  6. MIPROv2 paper — arXiv:2406.11695 — Optimizing Instructions & Demonstrations.
  7. GEPA paper — arXiv:2507.19457 — Genetic Pareto Optimization of LLM Prompts.
  8. SIMBA optimizer API — dspy.ai/api/optimizers/SIMBA — Stochastic Introspective Mini-Batch Ascent.
  9. Shopify engineering talk on metadata extraction with DSPy + GEPA — youtube.com/watch?v=bxToahwOVpY (linked from DSPy's use-case list).
  10. Dropbox engineering blog — dropbox.tech/machine-learning/optimizing-dropbox-dash-relevance-judge-with-dspy — Dash relevance judge optimization.
  11. DSPy original framework paper — arXiv:2310.03714 — DSPy: Compiling Declarative LM Calls into Self-Improving Pipelines (Oct 2023).

Updates & Corrections
  • 2026-07-29 — Initial publication. DSPy version (3.2.1) and catalog of optimizers verified against dspy.ai and github.com/stanfordnlp/dspy on 2026-07-29. Shopify 550× figure sourced from DSPy's own community use-case list (primary material) and labelled Vendor claim — Confirmed by DSPy's source list.

Get the practical AI brief

Verified, no-hype AI tips you can actually use - in your inbox. Free.

No spam. We verify what we send. Unsubscribe anytime.

Tags

#"LLM pipelines"#"AI engineering"#"shopify case study"#prompt optimization#DSPy#GEPA

Discussion

0 comments
Sham

Sham

AI Engineer & Founder, The Tech Archive

AI engineer (Azure AI-102/AI-900). Writes practical, tested, hype-free guides on using AI for real work and small business at The Tech Archive.

Related Articles

View all
IBM's Q2 Revenue Miss Explained: What the AI Infrastructure Spending Shift Means for Your Software Budget in 2026
Artificial Intelligence

IBM's Q2 Revenue Miss Explained: What the AI Infrastructure Spending Shift Means for Your Software Budget in 2026

16 min
Graph RAG for the Lakehouse: How Metadata Graphs and Document Structures Augment AI Agents
Artificial Intelligence

Graph RAG for the Lakehouse: How Metadata Graphs and Document Structures Augment AI Agents

16 min
How to Use Claude Record a Skill: Turn Any Task Into a Reusable AI Automation (2026 Guide)
Artificial Intelligence

How to Use Claude Record a Skill: Turn Any Task Into a Reusable AI Automation (2026 Guide)

14 min
Ollama Gemma 4 Tool Calling in 2026: How the Reliability Fix Actually Works
Artificial Intelligence

Ollama Gemma 4 Tool Calling in 2026: How the Reliability Fix Actually Works

16 min
The AI Kill Switch Act of 2026: What the Bill Does, the OpenAI–Hugging Face Incident Behind It, and What Builders Should Actually Do
Artificial Intelligence

The AI Kill Switch Act of 2026: What the Bill Does, the OpenAI–Hugging Face Incident Behind It, and What Builders Should Actually Do

16 min
Why AI Software Factories Fail Without Code Review (2026 Guide)
Artificial Intelligence

Why AI Software Factories Fail Without Code Review (2026 Guide)

10 min