AutoSignature
Generate typed dspy.Signature classes from prompts, SDK messages, or datasets.
Explore the Documentation »
Report Bug
Request Feature
Table of Contents
About
AutoSignature inspects a prompt, SDK message array, or dataset and generates a
complete dspy.Signature subclass. Structured inputs are designed
deterministically; anything else gets a single LLM call (dspy.ChainOfThought).
No sandbox, no Deno, no iterative loop — one call and you're done.
- Automatic signature design — Infers instructions, inputs, outputs, field descriptions, and types
- Strongly typed outputs — When the LLM designs the signature (
mode="cot"ormode="rlm"), structured outputs become real PydanticBaseModeltypes with nested models,Literalenums, and validation - Dataset-aware generation — Profiles DataFrame columns, distributions, and representative rows
- Ready to use — Returns signatures compatible with
dspy.Predict,dspy.ChainOfThought, and other DSPy modules - Exportable — Renders generated signatures as Python source with
to_source()
Requires Python 3.12+ and DSPy 3.2+.
Quick Start
Install
Install AutoSignature with uv (recommended):
uv add dspy-auto-signature
Or with pip:
pip install dspy-auto-signature
Basic Usage
import dspy
import dspy_auto_signature as das
das.configure(lm=dspy.LM("openrouter/openai/gpt-oss-120b"))
signature = das.generate(
"Given an article, produce a concise summary and three key takeaways."
)
print(signature.to_source())
dspy.configure(lm=dspy.LM("openrouter/openai/gpt-oss-120b"))
summarize = dspy.ChainOfThought(signature.to_signature())
result = summarize(article="...")
SDK Message Formats
AutoSignature accepts message arrays from popular LLM SDKs. Pass your existing conversation history directly — no conversion needed.
OpenAI SDK
import dspy
import dspy_auto_signature as das
das.configure(lm=dspy.LM("openrouter/openai/gpt-oss-120b"))
messages = [
{"role": "system", "content": "You are a technical writer who produces clear documentation."},
{"role": "user", "content": "Write a README for a Python CLI tool that converts CSV to JSON."},
]
signature = das.generate(messages)
print(signature.to_source())
Anthropic SDK
messages = [
{"role": "user", "content": "Analyze the sentiment of customer reviews."},
{"role": "assistant", "content": "I'll classify each review as positive, negative, or neutral."},
]
signature = das.generate(messages)
Google Gemini SDK
contents = [
{"role": "user", "parts": [{"text": "Extract key entities from this legal contract."}]},
{"role": "model", "parts": [{"text": "I'll identify parties, dates, and obligations."}]},
]
signature = das.generate(contents)
LiteLLM / OpenAI-Compatible
Any SDK that produces OpenAI-style [{"role": "...", "content": "..."}] arrays
works out of the box — including LiteLLM, Azure OpenAI, Ollama, and vLLM.
See examples/sdk.py for a complete runnable example.
DataFrame Example
Install with the pandas extra to get pandas:
uv add "dspy-auto-signature[pandas]"
Or with pip:
pip install "dspy-auto-signature[pandas]"
Datasets are profiled before generation so the signature reflects your column
names, types, and representative rows. Add mode="cot" to let an LLM design
the signature from the profile instead.
import dspy
import pandas as pd
import dspy_auto_signature as das
das.configure(lm=dspy.LM("openrouter/openai/gpt-oss-120b"))
tickets = pd.DataFrame(
[
{"message": "Server is down", "urgency": "high"},
{"message": "Please update my profile", "urgency": "low"},
{"message": "Payment failed", "urgency": "high"},
]
)
signature = das.generate(
tickets,
task_hint="Classify support ticket urgency from the message",
)
print(signature.to_source())
API
generate(source, task_hint=None, *, input_hints=None, output_hints=None)
Generates a dspy.Signature subclass from prompt material or tabular data.
| Parameter | Type | Description |
|---|---|---|
source |
Any |
Prompt string, SDK message array (OpenAI, Anthropic, Google, LiteLLM), DataFrame, list of dictionaries, or list of dspy.Example objects |
task_hint |
str | None |
Optional task description, especially useful for identifying dataset targets |
input_hints |
dict[str, str] | None |
Input field descriptions to supplement or override generated descriptions |
output_hints |
dict[str, str] | None |
Output field descriptions to supplement or override generated descriptions |
mode |
"auto" | "fast" | "cot" | "rlm" |
Generation strategy. Defaults to auto — see below |
Supported input formats:
- Raw strings (system prompts, task descriptions)
- OpenAI SDK message arrays:
[{"role": "system", "content": "..."}, {"role": "user", "content": "..."}] - Anthropic SDK message arrays:
[{"role": "user", "content": "..."}] - Google Gemini SDK contents:
[{"role": "user", "parts": [{"text": "..."}]}] - LiteLLM / Azure OpenAI / Ollama / vLLM message arrays
- pandas DataFrames, polars DataFrames / LazyFrames
list[dict],list[dspy.Example], singledspy.Example
Generation modes (mode parameter):
| Mode | Behavior |
|---|---|
auto |
Default. Deterministic design for structured inputs (placeholders, SDK arrays, datasets); a single dspy.ChainOfThought call for everything else |
fast |
Fully deterministic — never contacts an LLM |
cot |
Always uses a single dspy.ChainOfThought call, even for structured inputs |
rlm |
Heavy recursive dspy.RLM architect (sandboxed exploration; requires Deno) |
auto is right for almost everything. Pass mode="cot" or mode="rlm" when
you want the LLM to design even structured inputs.
Typed outputs with Pydantic models
Whenever ChainOfThought or the RLM architect designs a signature, structured
outputs are strongly typed. Instead of a plain str field described as "JSON
containing ...", the architect proposes a full Pydantic model schema, and the
generated signature uses a real BaseModel class as the output field type:
import dspy
import dspy_auto_signature as das
das.configure(lm=dspy.LM("openai/gpt-4o-mini"))
Signature = das.generate(
"Extract the customer's contact information from the support ticket: {ticket}",
mode="cot",
)
contact_field = Signature.output_fields["contact"].annotation
# A generated pydantic model, e.g. ContactRecord(full_name=..., age=..., ...)
print(contact_field.model_json_schema())
Behavior:
- Multi-field and nested outputs become
pydanticmodel schemas with concrete field types (str,int,float,bool,list[str],dict[str, str],Literal, and nestedpydanticmodels). DSPy validates model responses against the generated model at runtime. - Enumerated outputs become
typing.Literaltypes. - Simple scalar outputs stay plain (
str,int, ...). to_source()renders the Pydantic model classes above the signature class, so exported source is self-contained and importable.- Deterministic paths (
mode="fast"and structuralautoinputs) keep their existing inferred types.
The generated PydanticModelSchema type is exported for programmatic use with
SignatureSpec and FieldSpec.model_schema.
configure(lm=None, dataset_lm=None, sub_lm=None)
Configures the models used during signature generation.
| Parameter | Type | Description |
|---|---|---|
lm |
dspy.LM | None |
Default generation model. Falls back to the model configured through dspy.configure |
dataset_lm |
dspy.LM | None |
Optional generation model override for dataset sources |
sub_lm |
dspy.LM | None |
Optional cheap inner model used by mode="rlm" sub-queries |
Contributing
Quick workflow:
- Fork and branch:
git checkout -b feature/name - Make changes
- Commit and push
- Open a Pull Request
License
MIT (as declared in pyproject.toml).
Built by thememium
Metadata
Release files for dspy-auto-signature 0.1.8
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| dspy_auto_signature-0.1.8.tar.gz | 37.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| dspy_auto_signature-0.1.8-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 83.5 kB
Release files / dspy_auto_signature-0.1.8.tar.gz
| Download URL | dspy_auto_signature-0.1.8.tar.gz |
|---|---|
| Size | 37.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
88ab8763adf0b27dd0db38bd5b8de0c0a9ae940614d2c1539df32b85dc53d0e6
|
|
BLAKE2b-256 checksum How to use checksums |
369ad5fb2732d4e4cd1c9f0bf002cc44a575f8c0e054b2dbef16ce6f3a2826f4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.13 {"installer":{"name":"uv","version":"0.12.13","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / dspy_auto_signature-0.1.8-py3-none-any.whl
| Download URL | dspy_auto_signature-0.1.8-py3-none-any.whl |
|---|---|
| Size | 46.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
38dcb38d097faab31d4acf999bee1aa2d6ec19a5b3e0198a4177056a257a1059
|
|
BLAKE2b-256 checksum How to use checksums |
e1c87ae5185739b355099a42bf6f7c2c613b280819dbc7c4b715233c48d0525c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.13 {"installer":{"name":"uv","version":"0.12.13","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|