Skip to main content
DSRs lets you call language models with typed Rust structs. Define your inputs and outputs as a struct, and the library handles prompt formatting and response parsing. This guide walks you through building your first typed LM pipeline. Call init_tracing() once at startup in your app examples.
1

Install DSRs

Add to your Cargo.toml:
Or via cargo:
2

Configure the LM

Tell DSRs which model to use. This sets a global default that all predictors will use:
Set OPENAI_API_KEY in your environment. For other providers, use the appropriate prefix (e.g., anthropic:claude-3-haiku).
3

Define a signature

A signature declares your task’s inputs and outputs:
The doc comments become:
  • Struct docstring → instruction for the LM
  • Field docstrings → field descriptions in the prompt
4

Call the LM

Create a predictor and call it:
The #[derive(Signature)] macro generates QAInput from your #[input] fields. You get back a QA struct with both input and output fields filled in - output.answer is a typed String.

Complete example

Next steps

How DSRs thinks

The mental model behind the library

Signatures

Every attribute, every supported type, constraints

Predict

Builder surface, demos, metadata, errors

Modules

ChainOfThought, predictor discovery, composition

Adding complexity

Input formatting and rendering

Use #[format("json")] for serialization, or #[render(jinja = "...")] for custom field text. See the full attribute reference in Signatures & types and runtime behavior in Adapters.

Custom types

When you need more than primitives, add #[Schema]:

Few-shot demos

Add examples to guide the LM:

Constraints

Validate outputs with #[check] and #[assert]:

Multi-step pipelines

Chain predictors for complex workflows:
See Modules for how to make this optimizer-compatible.