> ## 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, and for capabilities the CLI doesn't cover, such as monitor views, alerts, and authoring evaluators, preprocessors, and facets.

[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>
