HyphenHyphen
HomeConsole
  • Get Started
  • Connect your coding agent
  • Build with Hyphen
  • Chat UIs & automation
  • Recipes
  • Guides
  • API Reference
OverviewLangChain & LangGraphLlamaIndexPydantic AICrewAIInstructorDSPyVercel AI SDKMastraOpenAI Node SDK
powered by Zudoku
Build with Hyphen

DSPy

DSPy replaces hand-written prompts with declarative modules and optimisers. Configure it once with dspy.LM and every module in your program uses Hyphen.

TerminalCode
pip install -U dspy export HYPHEN_API_KEY="sk-..."

Setup guide: this config comes from DSPy's official documentation and has not been run end to end against the gateway. Corrections to support@hyphen-solution.com.

The model

Code
import os import dspy lm = dspy.LM( "openai/minimax-m3", api_base="https://api.hyphen-solution.com/v1", api_key=os.environ["HYPHEN_API_KEY"], model_type="chat", max_tokens=4000, ) dspy.configure(lm=lm)

Two naming details, both easy to get wrong:

  • The openai/ prefix is required. DSPy routes through LiteLLM, and the prefix is what tells it to treat this as a generic OpenAI-shaped endpoint. DSPy's own docs say to add it for any OpenAI-compatible provider. It is stripped before the request, so Hyphen receives minimax-m3.
  • It is api_base, not base_url. That is LiteLLM's name. api_base and api_key are not named parameters on dspy.LM; they ride through **kwargs into LiteLLM, which is by design.

model_type="chat" is the default and can be omitted. Passing it explicitly is cheap insurance.

Predict and ChainOfThought

Code
classify = dspy.Predict("sentence -> sentiment: bool") print(classify(sentence="it's a charming and often affecting journey.").sentiment) qa = dspy.ChainOfThought("question -> answer") result = qa(question="Why is a Bloom filter probabilistic?") print(result.reasoning) print(result.answer)

ChainOfThought injects a reasoning field before your declared outputs. Note that this is DSPy's own prompted reasoning, which is separate from the model's internal reasoning. Both consume tokens from the same max_tokens budget, which is why 4000 is the floor here.

A typed signature

Code
from typing import Literal import dspy class ClassifyIssue(dspy.Signature): """Classify a bug report by severity and component.""" report: str = dspy.InputField() severity: Literal["low", "medium", "high", "critical"] = dspy.OutputField() component: str = dspy.OutputField() classify = dspy.ChainOfThought(ClassifyIssue) out = classify(report="The CSV exporter drops the last row on 2.4.1. Blocking reporting.") print(out.severity, out.component)

DSPy builds structured output by prompting and parsing, not by response_format, so it works on the M-series without any special configuration.

A module with tools

Code
def multiply(a: float, b: float) -> float: """Multiply two numbers.""" return a * b agent = dspy.ReAct("question -> answer", tools=[multiply], max_iters=6) print(agent(question="What is 1234 * 4567?").answer)

Keep max_iters bounded. A ReAct loop that will not converge is the fastest way to spend a monthly cap.

Two models in one program

Use the cheap fast model for bulk classification and the flagship where quality matters.

Code
fast = dspy.LM( "openai/minimax-m2.5", api_base="https://api.hyphen-solution.com/v1", api_key=os.environ["HYPHEN_API_KEY"], max_tokens=4000, ) with dspy.context(lm=fast): result = classify(report="...") # this call uses minimax-m2.5

Optimisers and your budget

DSPy's optimisers (MIPROv2, BootstrapFewShot and friends) work by running your program many times over a training set. That is dozens to hundreds of requests per compile.

Do the optimisation runs on minimax-m2.5, check your remaining budget in the console first, and keep the trainset small while you are iterating. The hard cap means a runaway compile returns 429 rather than an invoice, but a spent cap still stops your day.

DSPy caches by default (cache=True on dspy.LM), so repeated identical calls during development cost nothing.

Gotchas

  • openai/ prefix required. Without it LiteLLM cannot route the call.
  • api_base, not base_url.
  • max_tokens of 4000. Prompted reasoning plus internal reasoning share the budget. See Choosing a model.
  • No embedding models on the gateway, so DSPy retrievers need an embedder from elsewhere.
  • 429 means the monthly budget is spent. Optimisers reach it fast. See Handling the 429 cap.

Related

  • DSPy language models
  • dspy.LM reference
  • Choosing a model: which model for compile vs run.
Last modified on July 28, 2026
InstructorVercel AI SDK
On this page
  • The model
  • Predict and ChainOfThought
  • A typed signature
  • A module with tools
  • Two models in one program
  • Optimisers and your budget
  • Gotchas
  • Related