> ## Documentation Index
> Fetch the complete documentation index at: https://braintrust.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# DSPy

> Trace DSPy pipelines in Braintrust to debug modules, evaluate prompts, and monitor LLM calls

If you are a coding agent, prefer the Braintrust [`bt` CLI](/docs/reference/cli/quickstart) for repeatable, scriptable work: running evals, instrumenting code, querying logs, syncing data, managing functions, and configuring coding agents. Use the MCP server for reasoning over Braintrust data in conversation, such as ad-hoc lookups and exploration from your IDE.

[DSPy](https://dspy.ai) is a framework for programming language model pipelines. Braintrust traces the full DSPy execution tree, so a single trace shows how each module decomposed into its underlying steps.

<View title="Python" icon="https://img.logo.dev/python.org?token=pk_BdcHD9e5SCW3j1rnJkNyMQ">
  <h2 id="setup-python">
    Setup
  </h2>

  Install the Braintrust and DSPy packages, then set your API keys. Requires `dspy` v2.6.0 or later.

  <Steps>
    <Step title="Install packages">
      <CodeGroup>
        ```bash uv theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
        uv add braintrust dspy
        ```

        ```bash pip theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
        pip install braintrust dspy
        ```
      </CodeGroup>
    </Step>

    <Step title="Set environment variables">
      ```bash title=".env" theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
      BRAINTRUST_API_KEY=<your-braintrust-api-key>
      OPENAI_API_KEY=<your-openai-api-key>
      ```
    </Step>
  </Steps>

  <h2 id="auto-instrumentation-python">
    Auto-instrumentation
  </h2>

  To trace DSPy runs without modifying your application code, call `braintrust.auto_instrument()` before you configure DSPy. It patches `dspy.configure()` so Braintrust's DSPy callback is attached automatically.

  <CodeGroup>
    ```python Python theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
    import os

    import braintrust

    braintrust.auto_instrument()
    braintrust.init_logger(
        api_key=os.environ["BRAINTRUST_API_KEY"],
        project="dspy-example",  # Replace with your project name
    )

    import dspy

    lm = dspy.LM("openai/gpt-5-mini")
    dspy.configure(lm=lm)

    cot = dspy.ChainOfThought("question -> answer")
    result = cot(question="What is the capital of France?")
    print(result.answer)
    ```
  </CodeGroup>

  To patch only DSPy instead of enabling all supported Python integrations, use `patch_dspy()`.

  <CodeGroup>
    ```python Python theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
    import os

    from braintrust import init_logger
    from braintrust.integrations.dspy import patch_dspy

    init_logger(
        api_key=os.environ["BRAINTRUST_API_KEY"],
        project="dspy-example",  # Replace with your project name
    )
    patch_dspy()

    import dspy

    lm = dspy.LM("openai/gpt-5-mini")
    dspy.configure(lm=lm)

    predict = dspy.Predict("question -> answer")
    result = predict(question="What is 2 + 2?")
    print(result.answer)
    ```
  </CodeGroup>

  <h2 id="manual-instrumentation-python">
    Manual instrumentation
  </h2>

  To trace DSPy runs manually, attach `BraintrustDSpyCallback()` yourself when you configure DSPy. For detailed LiteLLM token and cost spans, patch LiteLLM before importing DSPy.

  <CodeGroup>
    ```python Python theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
    import os

    from braintrust import init_logger
    from braintrust.integrations.dspy import BraintrustDSpyCallback
    from braintrust.integrations.litellm import patch_litellm

    patch_litellm()

    import dspy

    init_logger(
        api_key=os.environ["BRAINTRUST_API_KEY"],
        project="dspy-example",  # Replace with your project name
    )

    # Disable DSPy's disk cache if you want every LiteLLM call to be traced.
    dspy.configure_cache(enable_disk_cache=False, enable_memory_cache=True)

    lm = dspy.LM("openai/gpt-5-mini")
    dspy.configure(lm=lm, callbacks=[BraintrustDSpyCallback()])

    cot = dspy.ChainOfThought("question -> answer")
    result = cot(question="What is the capital of France?")
    print(result.answer)
    ```
  </CodeGroup>

  <h2 id="what-traced-python">
    What Braintrust traces
  </h2>

  A DSPy execution appears as a parent module span with child spans for adapter work and model calls:

  ```text theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
  trace-dspy-auto
  └── dspy.module.ChainOfThought
      ├── dspy.adapter.format
      ├── dspy.lm
      └── dspy.adapter.parse
  ```

  Braintrust captures:

  * Module spans (`dspy.module.Predict`, `dspy.module.ChainOfThought`, and other module classes), with module inputs, the module class, and outputs.
  * Adapter formatting and parsing spans (`dspy.adapter.format` and `dspy.adapter.parse`), with inputs, the adapter class, and outputs.
  * LLM call spans (`dspy.lm`), with inputs, the model and provider, request parameters (`temperature`, `max_tokens`, `top_p`, `top_k`, `stop`), outputs, and latency.
  * Tool spans (named after the invoked tool), with tool inputs and outputs.
  * Evaluation spans (`dspy.evaluate`), with evaluation inputs, the metric name, thread count, outputs, and score metrics (`accuracy`, `score`, `total`, `correct`).
  * Additional LiteLLM completion spans (`Completion`), with token usage and latency metrics, when you patch LiteLLM.

  <h2 id="resources-python">
    Resources
  </h2>

  * [LiteLLM integration](/docs/integrations/sdk-integrations/litellm)
  * [Trace LLM calls](/docs/instrument/trace-llm-calls)
  * [Advanced tracing](/docs/instrument/advanced-tracing)
</View>
