agentsclimarketplace

Dspy utils

Skill lebsral/DSPy-Programming-not-prompting-LMs-skills/skills/dspy-utils

AI skills for Claude Code, Cursor, and other coding agents. Build reliable AI features with DSPy — classification, RAG, parsing, agents, and more. Just type /ai-do.

Install
npx -y skills add lebsral/DSPy-Programming-not-prompting-LMs-skills --skill dspy-utils

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
  • 11 stars11 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

DSPy utility functions for caching control, debugging with inspect_history, saving/loading optimized programs, and runtime validation with Refine/BestOfN. Use when you need DSPy infrastructure - controlling the cache to avoid stale results, debugging with inspect_history to see raw prompts, saving and loading optimized programs, or validating outputs with reward functions. For streaming see /dspy-streaming, for async see /dspy-async, for MCP see /dspy-mcp. Related - ai-tracing-requests, ai-serving-apis, ai-monitoring, dspy-streaming, dspy-async, dspy-mcp. Also used for dspy.configure_cache, dspy.inspect_history, dspy.load, cache control in DSPy, save and load DSPy program, debug DSPy prompts, see what DSPy sent to the model, DSPy program serialization, production DSPy utilities, clear DSPy cache, view prompt history.

SKILL.md

10.3 KB, ~2.3k tokens by cl100k_base, as published. Nobody here has run it

DSPy Utilities: Caching, Debugging, Save/Load, and Validation

Guide the user through DSPy's utility functions -- controlling caching, debugging calls, persisting optimized programs, and enforcing runtime constraints with reward functions.

Looking for streaming, async, or MCP? These have dedicated skills now:

  • Streaming tokens to a UI -- see /dspy-streaming
  • Async execution and FastAPI -- see /dspy-async
  • MCP server integration -- see /dspy-mcp

Step 1: Which utility do you need?

Ask the user before diving in:

  1. What are you trying to do? Debug a failing program, save/load an optimized program, control caching, or validate outputs with reward functions?
  2. Is this for development or production? Development needs (debugging, cache control) differ from production needs (save/load, validation).

Then jump to the relevant section below.

2. configure_cache -- controlling cache behavior

DSPy caches LM responses by default to reduce costs and speed up development. Use dspy.configure_cache to control this globally.

# Disable all caching (disk and memory)
dspy.configure_cache(enable_disk_cache=False, enable_memory_cache=False)

# Disable only disk cache (keep memory cache for speed)
dspy.configure_cache(enable_disk_cache=False)

# Re-enable both caches
dspy.configure_cache(enable_disk_cache=True, enable_memory_cache=True)

# DSPy 3.2+ - harden the on-disk cache against untrusted pickle payloads
dspy.configure_cache(restrict_pickle=True)

Per-LM cache control

You can also control caching per LM instance:

# This LM never caches
lm_no_cache = dspy.LM("openai/gpt-4o-mini", cache=False)

# This LM caches (default)
lm_cached = dspy.LM("openai/gpt-4o-mini", cache=True)

When to disable caching

  • Generating diverse outputs -- when you need different responses for the same prompt (e.g., data generation)
  • Testing real latency -- cache hits are instant, which skews benchmarks
  • Streaming -- caching may interfere with streaming behavior in some configurations

Cache is stored locally on disk. Identical calls (same prompt, parameters, model) return cached results with no API call.

When NOT to disable caching: During optimization runs -- optimizers rely heavily on cache to avoid redundant LM calls. Disabling cache globally during optimization dramatically increases cost and time.

3. inspect_history -- debugging LM calls

dspy.inspect_history shows the raw prompts and responses from recent LM calls. This is the single most useful debugging tool in DSPy.

import dspy

lm = dspy.LM("openai/gpt-4o-mini")  # or "anthropic/claude-sonnet-4-5-20250929", etc.
dspy.configure(lm=lm)

classify = dspy.Predict("text -> label")
classify(text="Great product!")

# See what was actually sent to and received from the LM
dspy.inspect_history(n=1)  # Show last 1 call
dspy.inspect_history(n=3)  # Show last 3 calls

What inspect_history shows

  • The full prompt sent to the LM (including system message, few-shot demos, instructions)
  • The raw LM response
  • Which adapter formatted the prompt (ChatAdapter, JSONAdapter, etc.)

Debugging workflow

  1. Run your program on a failing input
  2. Call dspy.inspect_history(n=1) to see the last LM call
  3. Check if the prompt makes sense -- are the instructions clear? Are few-shot demos relevant?
  4. Check the raw response -- did the LM follow the format? Did it hallucinate?
  5. Adjust your signature, module, or optimization strategy based on what you see

Verbose logging

For more detailed tracing, configure DSPy with an empty trace list:

dspy.configure(lm=lm, trace=[])

You can also print a module to see its structure:

print(my_program)  # Shows module tree with all sub-modules and signatures

4. save/load -- persisting optimized programs

After optimizing a DSPy program, save its learned state (few-shot demos, instructions) for production use.

Save

# After optimization
optimized = optimizer.compile(my_program, trainset=trainset)

# Save learned state only (default -- class definition must exist at load time)
optimized.save("optimized_program.json")

# Save entire program including class definition (load without recreating the class)
optimized.save("optimized_program_dir", save_program=True)

Load

# Option A: load state into a fresh instance of the same class
program = MyProgram()
program.load("optimized_program.json")

# Option B: load an entire saved program (only when saved with save_program=True)
program = dspy.load("optimized_program_dir")

# Use it
result = program(question="What is DSPy?")

What gets saved

  • Few-shot demonstrations discovered by optimizers
  • Optimized instructions (from MIPROv2, GEPA, etc.)
  • Any state tracked by dspy.Predict modules

What does NOT get saved (state-only save)

  • Python logic in forward() -- that's your code, it must exist at load time
  • Model weights (unless you used BootstrapFinetune)
  • LM configuration -- you must call dspy.configure() before loading

Use save(save_program=True) to include the class definition. Then dspy.load() reconstructs the program without needing the class imported.

Production deployment pattern

import dspy

class MyPipeline(dspy.Module):
    def __init__(self):
        self.classify = dspy.Predict("text -> category")
        self.respond = dspy.ChainOfThought("text, category -> response")

    def forward(self, text):
        cat = self.classify(text=text)
        return self.respond(text=text, category=cat.category)

# --- Optimization (run once) ---
# optimizer = dspy.MIPROv2(metric=metric, auto="medium")
# optimized = optimizer.compile(MyPipeline(), trainset=trainset)
# optimized.save("pipeline_v1.json")

# --- Production (run on every request) ---
lm = dspy.LM("openai/gpt-4o-mini")  # or "anthropic/claude-sonnet-4-5-20250929", etc.
dspy.configure(lm=lm)

pipeline = MyPipeline()
pipeline.load("pipeline_v1.json")

result = pipeline(text="How do I reset my password?")

5. dspy.Refine and dspy.BestOfN -- reward-based output validation

Use dspy.Refine to wrap any module and retry until a reward function returns a score meeting a threshold. This replaced dspy.Assert/dspy.Suggest in DSPy 3.x:

import dspy

qa = dspy.ChainOfThought("question -> answer")

def answer_reward(args, pred):
    """Score answer quality. Returns 0.0-1.0."""
    if not pred.answer.strip():
        return 0.0
    if len(pred.answer.split()) < 5:
        return 0.5  # soft penalty for short answers
    return 1.0

validated_qa = dspy.Refine(
    module=qa,
    N=3,
    reward_fn=answer_reward,
    threshold=1.0,
)

result = validated_qa(question="What is DSPy?")
ApproachHow it worksUse when
dspy.RefineRetries with feedback from the reward function until threshold met or N attempts exhaustedLater attempts can improve based on earlier failures
dspy.BestOfNRuns N independent attempts, returns the best-scoring oneAttempts are independent; cross-attempt feedback would not help

Both require threshold (no default -- must be explicit). Both accept fail_count (how many failures allowed before raising; defaults to N).

For detailed patterns and examples, see /dspy-refine and /dspy-best-of-n.

Gotchas

  1. save() does not persist forward() logic -- only learned state (demos, instructions) is saved. The class definition must exist in your production code at load time.
  2. Must dspy.configure() before load() -- loading a saved program before configuring the LM causes silent failures where the program runs but uses no LM (or the wrong one).
  3. inspect_history shows cached calls too -- after a cache hit, inspect_history still shows the call, but the prompt may look different from what was originally sent. Disable cache if you need exact prompt inspection.
  4. Never disable cache globally during optimizer runs. Optimizers rely heavily on cache to avoid redundant LM calls. Disabling cache with enable_disk_cache=False, enable_memory_cache=False during optimization dramatically increases cost and time -- only disable cache for specific inference calls, not globally.

Additional resources

Cross-references

Install any skill: npx skills add lebsral/DSPy-Programming-not-prompting-LMs-skills --skill <name>

  • Streaming tokens to a UI -- see /dspy-streaming
  • Async execution and FastAPI -- see /dspy-async
  • MCP server integration -- see /dspy-mcp
  • /dspy-lm -- Configure language models, per-LM caching, inspect_history on LM instances
  • /dspy-modules -- Build composable programs with dspy.Module, save/load patterns
  • /ai-tracing-requests -- Production observability and tracing for DSPy programs
  • /dspy-refine -- Refine patterns, reward functions, and iterative improvement
  • /dspy-best-of-n -- BestOfN for independent sampling without cross-attempt feedback
  • /ai-serving-apis -- Serve DSPy programs as web APIs
  • Install /ai-do if you do not have it -- it routes any AI problem to the right skill and is the fastest way to work: npx skills add lebsral/DSPy-Programming-not-prompting-LMs-skills --skill ai-do

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.