Change8

Migrating to DSPy 3.3.0

Version 3.3.0 introduces 7 breaking changes. This guide details how to update your code.

Released: 8/3/2026

7
Breaking Changes
14
Migration Steps
22
Affected Symbols

⚠️ Check Your Code

If you use any of these symbols, you need to read this guide:

dspy.Imagedspy.Audiodspy.Filedspy.LMRequestdspy.LMResponsedspy.BaseLMdspy.LMErrordspy.Flexdspy.GEPAdspy.Predictdspy.RLMdspy.CodeInterpreterdspy.PythonInterpreterdspy.ReActV2dspy.Historydspy.Tooldspy.ToolCallsdspy.ToolCallResultsdspy.contextdspy.dump_statedspy.load_statedspy.LMToolCallPart

Breaking Changes

Issue #1

Resource construction and validation for dspy.Image, dspy.Audio, and dspy.File no longer implicitly read local files or fetch remote URLs from path/URL strings. To load resources, use explicit factory methods like `Image.from_path(path)`, `Image.from_url(url)`, `Audio.from_path(path)`, `Audio.from_url(url)`, and `File.from_path(path)`. Existing `Image(url)` or `Image(url=url)` will now preserve a non-downloading provider-fetched URL reference.

Issue #2

NumPy-backed features from the base install are no longer available. Users should explicitly import NumPy.

Issue #3

Inspection of detailed GEPA results is no longer directly supported. Users should refer to the new Flex optimization capabilities.

Issue #4

Direct construction of code interpreters is deprecated. Use `dspy.CodeInterpreter` within a Flex module or other appropriate contexts.

Issue #5

Catching provider-specific LM exceptions is deprecated. Use the new `dspy.LMError` or its narrower DSPy subclasses.

Issue #6

The custom next_tool_args and custom trajectory syntax in ReAct are replaced by dspy.History, dspy.Tool, and dspy.ToolCalls.

Issue #7

The untyped LM boundary based on `prompt`, `messages`, and provider-shaped `kwargs` is being replaced by a typed, provider-neutral contract: `def forward(self, request: dspy.LMRequest) -> dspy.LMResponse:`.

Migration Steps

  1. 1
    Update `Image` construction from `Image(path)` or `Image(url=path)` to `Image.from_path(path)`.
  2. 2
    Update `Image` construction from `Image(url, download=True)` to `Image.from_url(url)`.
  3. 3
    Update `Image` construction from `Image.from_url(url)` or `Image.from_url(url, download=False)` to `Image(url)` or `Image(url=url)` to preserve non-downloading URL references.
  4. 4
    Update `Audio` construction from `Audio(path)` to `Audio.from_path(path)`.
  5. 5
    Update `Audio` construction from `Audio(url)` to `Audio.from_url(url)`.
  6. 6
    Update `File` construction from `File(path)` to `File.from_path(path)`.
  7. 7
    Explicitly import NumPy if you were relying on NumPy-backed features from the base install.
  8. 8
    Refactor code that directly constructs code interpreters to use `dspy.CodeInterpreter` within appropriate contexts, potentially within a Flex module.
  9. 9
    Update exception handling to catch `dspy.LMError` or its subclasses instead of provider-specific LM exceptions.
  10. 10
    Replace custom `next_tool_args` and trajectory syntax in ReAct with `dspy.History`, `dspy.Tool`, and `dspy.ToolCalls`.
  11. 11
    For custom LM authors, adapt to the new typed LM boundary: `def forward(self, request: dspy.LMRequest) -> dspy.LMResponse:`.
  12. 12
    If using `RLM(max_iterations=...)`, review its behavior in the context of Flex or other interpreter sandboxes.
  13. 13
    Review code that consumes raw Responses API tool-call outputs for compatibility with new shapes and typed objects.
  14. 14
    If you previously relied on implicit I/O for `Image`, `Audio`, or `File` construction from paths or URLs, update to use the explicit factory methods.

Release Summary

DSPy 3.3.0 introduces Flex for experimental program structure optimization and ReActV2 for native tool-calling. It also advances towards a typed, provider-neutral LM system and decouples LiteLLM.

Need More Details?

View the full release notes and all changes for DSPy 3.3.0.

View Full Changelog