Adapters act as the crucial link between dspy.Predict modules and Language Models (LMs). They are responsible for transforming DSPy signatures and user inputs into LM-compatible multi-turn messages and parsing LM responses back into structured DSPy outputs.
dspy.Prediction instances.dspy.Tool, dspy.Image).Sets the adapter for the entire Python process. dspy.ChatAdapter is the default if not specified.
import dspy
# Default behavior (ChatAdapter is implicit)
dspy.configure(lm=dspy.LM("openai/gpt-4o-mini"))
# Explicitly set ChatAdapter
dspy.configure(
lm=dspy.LM("openai/gpt-4o-mini"),
adapter=dspy.ChatAdapter(),
)
Applies an adapter only within a specific scope using dspy.context().
import dspy
dspy.configure(lm=dspy.LM("openai/gpt-4o-mini"))
with dspy.context(adapter=dspy.JSONAdapter()):
# DSPy Predict calls within this block use JSONAdapter
predict_json = dspy.Predict("fact -> statement")
result = predict_json(fact="Earth is round")
# Outside the 'with' block, the default adapter (ChatAdapter) is used
predict_chat = dspy.Predict("question -> answer")
The journey from a DSPy agent call to a structured LM response.
dspy.Module or dspy.Predict)dspy.Predict invoked. (to get the LM response)Adapter.format() is called. (converts signature, inputs, demos into LM messages)Adapter.parse() converts LM response. (into structured DSPy outputs)dspy.Predict)You can explicitly call Adapter.format() to see the messages sent to the LM or use dspy.inspect_history() to view the full interaction with the LM.
import dspy
signature = dspy.Signature("question -> answer")
inputs = {"question": "What is 2+2?"}
demos = [{"question": "What is 1+1?", "answer": "2"}]
adapter = dspy.ChatAdapter()
formatted_messages = adapter.format(signature, demos, inputs)
# Output structure (truncated):
# {'role': 'system', 'content': 'Your input fields are:...'}
# {'role': 'user', 'content': '[[ ## question ## ]]\nWhat is 1+1?...'}
# ...
To see the full prompt and response details, use dspy.inspect_history() after a dspy.Predict call.
The default adapter, compatible with all LMs. It uses a field-based format with special markers to define request and response structures. For non-primitive types, it includes JSON schema.
| When to Use | When Not to Use |
|---|---|
✔ Universal compatibility |
✖ Latency-sensitive applications (more boilerplate tokens) |
✔ Automatic fallback to JSONAdapter on failure |
Defining a signature with a Pydantic model for structured outputs and configuring ChatAdapter.
import dspy
import pydantic
dspy.configure(lm=dspy.LM("openai/gpt-4o-mini"), adapter=dspy.ChatAdapter())
class ScienceNews(pydantic.BaseModel):
text: str
scientists_involved: list[str]
class NewsQA(dspy.Signature):
science_field: str = dspy.InputField()
news: list[ScienceNews] = dspy.OutputField(desc="news")
predict = dspy.Predict(NewsQA)
# To observe the full prompt, call predict and then dspy.inspect_history()
# predict(science_field="Computer Theory", year=2022, num_of_outputs=1)
# dspy.inspect_history()
Prompt Structure: Uses [[ ## field_name ## ]] markers for fields and JSON schema descriptions for complex types like list[ScienceNews].
Prompts the LM to return JSON data for all output fields specified in the signature. Ideal for models that natively support structured output via the response_format parameter, leading to more reliable parsing and lower latency.
| When to Use | When Not to Use |
|---|---|
✔ LM supports response_format |
✖ Models without native structured output (e.g., small open-source models) |
✔ Low latency (minimal tokens) |
Defining a signature for structured outputs and configuring JSONAdapter.
import dspy
import pydantic
dspy.configure(lm=dspy.LM("openai/gpt-4o-mini"), adapter=dspy.JSONAdapter())
class ScienceNews(pydantic.BaseModel):
text: str
scientists_involved: list[str]
class NewsQA(dspy.Signature):
science_field: str = dspy.InputField()
news: list[ScienceNews] = dspy.OutputField(desc="news")
predict = dspy.Predict(NewsQA)
# To observe the full JSON output prompt, call predict and then dspy.inspect_history()
# predict(science_field="Computer Theory", year=2022, num_of_outputs=1)
# dspy.inspect_history()
Prompt Structure: The LM is instructed to directly output a JSON object containing the specified output fields.