liveBook · Manning

Module

As explained in Building LLM Applications with DSPy

A DSPy module composed within another module and invoked as part of its computation.

A DSPy module can invoke another module as part of its computation. The inner module is a submodule; the outer module coordinates its inputs, outputs, and any surrounding logic. This is useful when one language-model call cannot complete the job—for example, when a question must be clarified before it is classified. A signature specifies the inputs and outputs of a call, while a module determines how that call is carried out. section 7.1 section 2.6

To compose a custom module, subclass dspy.Module. In __init__(), call super().__init__() and usually create the submodules. In forward(), pass inputs to them, use intermediate results as needed, and return a final Prediction. Call an instance like a function; DSPy invokes forward() behind the scenes. An optional aforward() supports asynchronous execution. section 7.2 section 2.6

Listing 7.4 Pseudocode for a standard custom module
class MoreComplexModule(dspy.Module):
  def __init__(self, **kwargs):
    super().__init__()
    self.module1 = dspy.Predict(signature1)
    self.module2 = dspy.Predict(signature2)

  def forward(self, input1, input2):
    x1 = preprocess(input1)
    x2 = preprocess(input2)
    x = self.module1(input1=x1, input2=x2)
    x = process_intermediate_results(x)
    x = self.module2(input=x)
    x = final_processing(x)
    return dspy.Prediction(x=x)

mod = MoreComplexModule()
mod(input1="this is the first input", input2="this is the second input")

The two-stage pseudocode shows the composition pattern: preprocess inputs, call a first Predict submodule, process its result, call a second, and package the final output. section 7.2

Clarify, then classify

A classifier first calls a submodule that rewrites a user message as a clear question. It passes that result to a second submodule for classification. BootstrapFewShot can optimize the enclosing program: when the full result satisfies the metric, intermediate inputs and outputs can become demonstrations for both submodules. section 7.6.1

Composition can also control whether a call happens at all. An intent classifier can check a message with a toxicity submodule and skip classification if the check flags it. Alternatively, a module can receive a submodule as a parameter: BestOfN repeatedly runs the supplied module and selects a result using a reward function. Submodules need not be limited to Predict; custom modules can themselves serve as submodules. section 7.4.3 section 7.3.2

Put a repeated multistep pattern inside one module to avoid duplicating orchestration and to optimize the full workflow. Keep programs separate when intermediate results are needed elsewhere, or when specialized, relatively unrelated steps are simpler to optimize independently. Modules may also combine submodule calls with Python logic and tools. section 7.7 section 7.9

How Building LLM Applications with DSPy covers it

How deep it goes
Works through custom-module construction, forward execution, intermediate results, and joint optimization; also weighs when to keep programs separate.
Examples
Shows a Predict wrapper, a two-step clarification-and-classification workflow, toxicity screening, and repeated submodule calls in BestOfN.
What it assumes
Assumes basic Python classes and callable programs while supplying the required dspy.Module, __init__(), and forward() pattern.
What you can do after
Build it from scratch as a dspy.Module that invokes submodules, processes their results, and returns a Prediction.
How it connects
Connects signatures, Predict, ChainOfThought, Prediction, tools, and BootstrapFewShot through callable DSPy programs.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Building LLM Applications with DSPy. The section links point to the parts of the book it draws on.