
Dspy Predict
- 7 installs
- 11 repo stars
- Updated June 28, 2026
- lebsral/dspy-programming-not-prompting-lms-skills
Helps with ai & agent building tasks.
About
dspy-predict is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted coding.
- dspy-predict
- AI & Agent Building
- AI-coding skill
Dspy Predict by the numbers
- 7 all-time installs (skills.sh)
- Ranked #12,545 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 2, 2026 (Skillselion catalog sync)
npx skills add https://github.com/lebsral/dspy-programming-not-prompting-lms-skills --skill dspy-predictAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 7 |
|---|---|
| repo stars | ★ 11 |
| Last updated | June 28, 2026 |
| Repository | lebsral/dspy-programming-not-prompting-lms-skills ↗ |
What it does
Helps with ai & agent building tasks.
Files
Direct LM Calls with dspy.Predict
Guide the user through using dspy.Predict -- the simplest and fastest DSPy module for calling a language model. It takes inputs, calls the LM, and returns typed outputs. No intermediate reasoning, no extra steps.
What is dspy.Predict
dspy.Predict is the atomic building block of every DSPy program -- one LM call, no reasoning chain, no tool loops. It takes a signature and calls the LM once to produce the output fields. Every other DSPy module (ChainOfThought, ReAct, etc.) builds on top of it.
When to use Predict vs ChainOfThought
Use dspy.Predict when... | Use dspy.ChainOfThought when... |
|---|---|
| The task is straightforward (classification, extraction, formatting) | The task benefits from step-by-step reasoning |
| You want minimal latency and token usage | Accuracy matters more than speed |
| The mapping from input to output is direct | The LM needs to "think through" intermediate steps |
| You're building a simple sub-step inside a larger pipeline | You need to inspect the model's reasoning |
Rule of thumb: Start with Predict. If accuracy is too low, switch to ChainOfThought -- it's a one-word change.
Predict with Pydantic output types
For complex structured outputs, use a Pydantic BaseModel as the output type:
import dspy
from pydantic import BaseModel
lm = dspy.LM("openai/gpt-4o-mini")
dspy.configure(lm=lm)
class ContactInfo(BaseModel):
name: str
email: str
phone: str
class ExtractContact(dspy.Signature):
"""Extract contact information from the text."""
text: str = dspy.InputField()
contact: ContactInfo = dspy.OutputField()
extractor = dspy.Predict(ExtractContact)
result = extractor(text="Reach out to Jane Doe at jane@example.com or 555-0123")
print(result.contact.name) # Jane Doe
print(result.contact.email) # jane@example.com
print(result.contact.phone) # 555-0123Async and batch processing
For async calls, use acall or aforward:
result = await predict.acall(question="What is DSPy?")For batch processing, use the built-in batch() method instead of a Python loop:
examples = [dspy.Example(question=q).with_inputs("question") for q in questions]
results = predict.batch(examples, num_threads=8, timeout=120)Save and load optimized predictors:
predict.save("my_predictor.json")
predict.load("my_predictor.json")Gotchas
1. Predict is not "dumb" -- optimizers can add few-shot demos and tuned instructions, making Predict surprisingly powerful. Don't underestimate it. 2. If accuracy is low, try `ChainOfThought` before reaching for complex solutions -- it's a one-word swap (dspy.ChainOfThought instead of dspy.Predict) and often gets you 10-20% accuracy gains on reasoning-heavy tasks. 3. For batch processing, use `predict.batch()` rather than a Python loop -- it uses dspy.Parallel internally, handles concurrency, and is significantly faster for large batches. 4. Only keyword arguments -- predict("my input") raises ValueError. Always use predict(question="my input").
Cross-references
Install any skill: npx skills add lebsral/DSPy-Programming-not-prompting-LMs-skills --skill <name>- Defining signatures (inline and class-based, typed fields, Pydantic outputs) -- see
/dspy-signatures - Adding step-by-step reasoning -- see
/dspy-chain-of-thought - Building multi-step programs with modules that compose Predict calls -- see
/dspy-modules - Classification and sorting with real-world patterns -- see
/ai-sorting - For worked examples, see examples.md
- Install `/ai-do` if you do not have it — it routes any AI problem to the right skill and is the fastest way to work:
npx skills add lebsral/DSPy-Programming-not-prompting-LMs-skills --skill ai-do
Additional resources
- dspy.Predict API docs
- For complete constructor signatures and method reference, see reference.md
- For worked examples (classification, extraction, batch processing), see examples.md
[
{
"prompt": "I need to classify support tickets into categories like billing, technical, and general. Keep it simple and fast — no reasoning needed.",
"expected_output": "A DSPy program using dspy.Predict with a Literal-typed output field for classification categories",
"assertions": [
"Uses dspy.Predict (not ChainOfThought)",
"Defines a dspy.Signature with InputField and OutputField",
"Uses Literal type to constrain classification categories",
"Configures an LM with dspy.LM and dspy.configure",
"Does not hardcode a single provider as the only option"
]
},
{
"prompt": "Extract the sender name, subject, and date from raw email text. Return it as a structured object I can pass to my API.",
"expected_output": "A DSPy program using dspy.Predict with a Pydantic BaseModel output type for structured extraction",
"assertions": [
"Uses dspy.Predict for direct extraction (not ChainOfThought)",
"Defines a Pydantic BaseModel for the output structure",
"Uses the BaseModel as an OutputField type in the signature",
"Shows how to access the extracted fields from the result"
]
},
{
"prompt": "I have thousands of product descriptions to tag. How do I process them efficiently with DSPy Predict?",
"expected_output": "Uses dspy.Predict with batch() or dspy.Parallel for concurrent processing",
"assertions": [
"Uses dspy.Predict as the core module",
"Uses predict.batch() or dspy.Parallel for batch processing (not a plain Python for loop)",
"Shows how to pass a list of examples or items",
"Mentions concurrency or parallelism benefit"
]
}
]
dspy-predict -- Worked Examples
Example 1: Simple text classification with Predict
Classify customer feedback into categories using Predict with a Literal type constraint. No reasoning needed -- the mapping is direct.
import dspy
from typing import Literal
class ClassifyFeedback(dspy.Signature):
"""Classify customer feedback into a category for the product team."""
feedback: str = dspy.InputField(desc="Raw customer feedback text")
category: Literal["bug", "feature_request", "praise", "question", "other"] = dspy.OutputField()
priority: Literal["low", "medium", "high"] = dspy.OutputField(
desc="How urgently this needs attention"
)
# --- Usage ---
lm = dspy.LM("openai/gpt-4o-mini") # or any LiteLLM-supported provider
dspy.configure(lm=lm)
classify = dspy.Predict(ClassifyFeedback)
# Single prediction
result = classify(feedback="The export button doesn't work on Safari, I get a blank page")
print(result.category) # bug
print(result.priority) # high
# Try several inputs
samples = [
"Would be great if you added dark mode",
"Your app saved me hours of work this week!",
"How do I connect my Slack workspace?",
"App crashes every time I upload a CSV larger than 10MB",
]
for text in samples:
r = classify(feedback=text)
print(f"[{r.priority}] {r.category}: {text}")Key points:
Literalconstrains the LM to only return values from the listed optionsPredictis ideal here because classification is a direct mapping -- no reasoning steps needed- Two output fields (
categoryandpriority) are generated in a single LM call - If accuracy is too low, swap
dspy.Predictfordspy.ChainOfThought-- everything else stays the same
Example 2: Multi-field extraction
Extract structured data from unstructured text using Predict with a Pydantic output type. This pattern is common for parsing emails, invoices, resumes, or any semi-structured text.
import dspy
from pydantic import BaseModel, Field
from typing import Optional
class Address(BaseModel):
street: str
city: str
state: str
zip_code: str
country: str = "US"
class PersonInfo(BaseModel):
full_name: str
email: Optional[str] = None
phone: Optional[str] = None
company: Optional[str] = None
role: Optional[str] = None
address: Optional[Address] = None
class ExtractPerson(dspy.Signature):
"""Extract structured person information from the text.
If a field is not mentioned, leave it as null."""
text: str = dspy.InputField(desc="Unstructured text containing person information")
person: PersonInfo = dspy.OutputField(desc="Extracted person details")
# --- Usage ---
lm = dspy.LM("openai/gpt-4o-mini") # or any LiteLLM-supported provider
dspy.configure(lm=lm)
extractor = dspy.Predict(ExtractPerson)
# Full info
result = extractor(
text="Please send the contract to Maria Garcia, VP of Engineering at Acme Corp. "
"Her email is maria@acme.com and she's at 123 Main St, Austin, TX 78701."
)
person = result.person
print(person.full_name) # Maria Garcia
print(person.role) # VP of Engineering
print(person.company) # Acme Corp
print(person.email) # maria@acme.com
print(person.address.city) # Austin
print(person.address.state) # TX
# Partial info -- missing fields become None
result = extractor(text="Got a call from Bob at 555-0199")
person = result.person
print(person.full_name) # Bob
print(person.phone) # 555-0199
print(person.email) # None
print(person.company) # NoneKey points:
- Pydantic
BaseModelgives you nested, validated, typed output from a single LM call Optionalfields handle cases where information is missing in the source textPredictis the right module here because extraction is a direct mapping from text to structure- The extracted
PersonInfoobject works like any Python object -- pass it to your database, API, or next pipeline step
Example 3: Batch processing pattern
Process a list of items with Predict inside a dspy.Module. This pattern keeps your batch logic optimizable by DSPy.
import dspy
from typing import Literal
class TagItem(dspy.Signature):
"""Tag a product listing with relevant categories for search."""
title: str = dspy.InputField(desc="Product listing title")
description: str = dspy.InputField(desc="Product listing description")
primary_category: Literal[
"electronics", "clothing", "home", "sports", "books", "other"
] = dspy.OutputField()
tags: list[str] = dspy.OutputField(desc="3-5 search tags for this product")
class ProductTagger(dspy.Module):
"""Tag a batch of product listings for a search index."""
def __init__(self):
super().__init__()
self.tag = dspy.Predict(TagItem)
def forward(self, products: list[dict]):
results = []
for product in products:
tagged = self.tag(
title=product["title"],
description=product["description"],
)
results.append({
"id": product["id"],
"title": product["title"],
"primary_category": tagged.primary_category,
"tags": tagged.tags,
})
return dspy.Prediction(tagged_products=results)
# --- Usage ---
lm = dspy.LM("openai/gpt-4o-mini") # or any LiteLLM-supported provider
dspy.configure(lm=lm)
tagger = ProductTagger()
products = [
{
"id": "SKU-001",
"title": "Wireless Noise-Canceling Headphones",
"description": "Bluetooth over-ear headphones with 30hr battery and ANC.",
},
{
"id": "SKU-002",
"title": "Organic Cotton T-Shirt",
"description": "Soft breathable crew neck tee, available in 6 colors.",
},
{
"id": "SKU-003",
"title": "Cast Iron Dutch Oven 6qt",
"description": "Enameled cast iron pot, oven-safe to 500F, dishwasher safe.",
},
]
result = tagger(products=products)
for item in result.tagged_products:
print(f"\n{item['title']} ({item['id']})")
print(f" Category: {item['primary_category']}")
print(f" Tags: {item['tags']}")
# --- Optimization ---
# To optimize, define a metric and provide labeled examples:
#
# def tagging_metric(example, prediction, trace=None):
# """Check if the primary category matches the gold label."""
# gold = example.tagged_products
# pred = prediction.tagged_products
# correct = sum(
# 1 for g, p in zip(gold, pred)
# if g["primary_category"] == p["primary_category"]
# )
# return correct / len(gold)
#
# optimizer = dspy.BootstrapFewShot(metric=tagging_metric, max_bootstrapped_demos=4)
# optimized_tagger = optimizer.compile(tagger, trainset=trainset)
# optimized_tagger.save("product_tagger.json")Key points:
- Wrapping the loop in a
dspy.Modulemakes the entire batch pipeline optimizable - The
Predictsub-module is declared in__init__so optimizers can discover and tune it - Each item gets its own LM call -- DSPy handles the prompting for each one
dspy.Predictionbundles the batch results into a clean return value- The commented optimization section shows how to evaluate and tune the batch pipeline end-to-end
Condensed from dspy.ai/api/modules/Predict. Verify against upstream for latest.
dspy.Predict — API Reference
Constructor
dspy.Predict(signature, callbacks=None, **config)| Parameter | Type | Default | Description |
|---|---|---|---|
signature | `str \ | type[Signature]` | (required) |
callbacks | `list[BaseCallback] \ | None` | None |
**config | keyword args | — | Forwarded to the LM (e.g., temperature=0.7, max_tokens=500); overridable per call |
Key methods
Execution
| Method | Signature | Description |
|---|---|---|
__call__ | (**kwargs) | Invoke prediction. Only keyword args — positional args raise ValueError |
forward | (**kwargs) | Main execution: builds prompt via adapter, calls LM, returns Prediction |
acall | (**kwargs) | Async version of __call__ |
aforward | (**kwargs) | Async execution with streaming support |
Batch processing
predict.batch(
examples, # list[dspy.Example]
num_threads=None, # max parallel threads
max_errors=None, # stop after N errors
return_failed_examples=False,
provide_traceback=None,
disable_progress_bar=False,
timeout=120, # per-example timeout in seconds
straggler_limit=3, # slow-example threshold multiplier
)Returns a list of results. If return_failed_examples=True, returns (results, failed_examples, exceptions).
Save / Load
# Save to file
predict.save("path/to/model.json")
# Load from file
predict.load("path/to/model.json")
# Lower-level state management
state = predict.dump_state()
predict.load_state(state)Introspection
| Method | Returns | Description |
|---|---|---|
get_lm() | LM | Returns the LM; raises if multiple LMs in use |
set_lm(lm) | — | Sets LM for all predictors recursively |
named_predictors() | list[(str, Predict)] | All named Predict instances |
inspect_history(n=1) | — | Print the last n LM calls for debugging |
reset() | — | Clears LM, traces, demos, and train data |
Config
predict.get_config() # current kwargs dict
predict.update_config(**kw) # merge new kwargsOverride config per call:
result = predict(question="...", config={"temperature": 0.0})