>- Decision rubric for promoting a prose prompt into a typed DSPy Signature. This is an answers the coder-agent decision "when do I stop hand-writing a prompt string and declare it as a `dspy.Signature`, and how do I name/describe its fields so the optimizer and the lines; the LM output is consumed by code (parsed, branched on, stored) rather than read by a human; the same prompt is reused across >1 call site; or a teammate asks "should this be a Signature?". Do NOT activate for one-shot throwaway prompts, or for HOW-TO questions about DSPy modules /optimizers/compile — defer those to the [[dspy]] skill and the Signature, prompt as a function, prompt contract, when to formalize a prompt.
npx skills add https://github.com/agentsope/SkillAlchemy --skill agentsop-signature-design
> *"DSPy uses the field names as the only natural-language hint the optimizer has about intent before it sees
> data. Name them like you'd name function parameters in well-written code."*
> — derived from [dspy.ai/learn/programming/signatures/], see references/R1-source-evidence.md
This skill is the decision layer, not the library layer. It tells you *when* a prose prompt has become
"load-bearing" enough to deserve a typed Signature, and *how* to shape its fields. For the actual API
(dspy.Signature, InputField, OutputField, Predict, ChainOfThought, compile, save) defer to the
[[dspy]] skill; for the full program→evaluate→optimize SOP defer to [[agentsop-dspy]].
Activate this overlay the moment a hand-written prompt crosses any one of three load-bearing thresholds.
| Trigger | Concrete signal | Why it matters |
|---|---|---|
| Length | A single prompt string grows past ~50 lines of f-string / template | Long prose prompts hide their I/O contract inside narration; the [[agentsop-dspy]] skill names this exact symptom: "hand-written prompts grow past ~50 lines; brittleness on model swap" (R1, claim S1) |
| Code-consumed output | The LM response is parsed, branched on, or stored by downstream code (not just shown to a human) | If code reads the output, the output has a *type*. An untyped prompt forces brittle regex/JSON-scraping at every call site |
| Reuse | The same prompt (or a copy-pasted variant) is called from >1 call site or in a loop | Reuse means the contract is now an API surface. Drift between copies is a guaranteed bug source |
Secondary signals (each strengthens, none alone is sufficient):
R1, claim S6; see [[agentsop-dspy]] Case B).Do NOT activate when:
R1, claim S7).A Signature is a typed function contract for a single LM call. Promote a prose prompt to a Signature exactly
when the prompt becomes *load-bearing* — when something other than a one-time human reader depends on its shape.
Think of the progression as the same lifecycle a script goes through when it earns a function:
prose prompt string → typed Signature
───────────────────────── ─────────────────────────
"You are an expert... given class Classify(dspy.Signature):
the ticket below, output """Route a support ticket."""
the category and a one-line ticket: str = dspy.InputField()
reason. Categories are..." category: Literal[...] = dspy.OutputField()
reason: str = dspy.OutputField(desc="<=15 words")
inline narration of I/O explicit, named, typed I/O
human reads / eyeballs code parses category, logs reason
each caller copies the blob one contract, N callers import it
optimizer sees nothing optimizer rewrites instructions, keeps field names
Three load-bearing ideas (all sourced; see references/R1-source-evidence.md):
field names. question -> answer ≠ query -> response. Name fields like function parameters in clean code
(R1, claim S2). This is *the* reason promotion is worth it: you convert narration into a machine-readable
intent signal.
rewrites *instructions* and *demos* — but it never changes field names, field count, or types (R1, claim
S5). So the Signature is the stable seam between "what I own" and "what the compiler owns." A prose prompt has
no such seam — everything is tangled.
overhead. The payoff appears only when the prompt is long, code-consumed, or reused. Below that line, raw
prompting wins (R1, claims S7, S1).
The PyTorch analogy from [[agentsop-dspy]] holds: a Signature ≈ a forward() shape contract. You don't write a
nn.Module for a one-line lambda; you write one when the shape is reused and trained.
A four-step gate. Run it top-to-bottom; each step has an exit criterion. Implementation of any step lives in the
[[dspy]] skill — this SOP only tells you *what decision* to make at each step.
Run the §1 trigger table. If zero triggers fire → stop, keep the prose prompt. Promotion is overhead.
Exit: at least one of {>50 lines, code-consumed output, reused} is true.
Read the prose prompt and extract every *variable* thing the LM is given (inputs) and every *distinct* thing it
must return (outputs). A common smell: the prose says "output the category and a confidence and a reason"
— that is three output fields, not one paragraph to regex later.
Exit: you can list inputs and outputs as a flat set of named slots, each with a Python type.
Rename each slot to read like a function parameter. text → ticket, out → category, resp → reason.
The name carries the optimizer's only pre-data intent signal (R1, claim S2). Avoid generic input/output.
Exit: every field name would be self-explanatory to a teammate reading only the field list.
Add InputField(desc=...) / OutputField(desc=...) only when the field name alone is ambiguous or the value
needs a constraint the name can't carry (format, length, units, allowed values). The DSPy cheatsheet's own example
adds a desc on output (answer, desc="often between 1 and 5 words") but leaves the input bare (R1, claim S3).
Over-describing every field bloats the prompt and fights the optimizer. Exit: descriptions exist for exactly
the fields that need disambiguation, and no others.
Picking Predict vs ChainOfThought vs ReAct, then evaluating and compiling, is out of scope for this
decision skill — that is the [[dspy]] skill (modules) and [[agentsop-dspy]] (Stage 1–3 workflow). Your deliverable from
this skill is a *well-shaped Signature*, handed to those skills. Exit: Signature is named, typed, minimally
described, and committed; you have switched contexts to [[dspy]].
If, after compiling (in [[dspy]]), the optimizer plateaus, the most common root cause is an **ambiguous
Signature** — not a bad optimizer (R1, claim S8). Loop back to Step 1: are inputs/outputs really separated? Are
field names carrying intent?
Eight operations. The first two are the gate; the rest are the shaping rubric. Full Trigger/Action/Output/Evidence
records are in intermediate/operation_candidates.json.
Promote prose → Signature when you can check ≥1 box. Each box maps to a §1 trigger:
[ ] LENGTH prompt string > ~50 lines
[ ] CONSUMED LM output is parsed / branched on / stored by code (not just human-read)
[ ] REUSED same prompt called from > 1 site, or inside a loop
[ ] (bonus) about to model-swap, OR a metric already exists, OR blob mixes instruction+demos+format
Zero boxes → do not promote. One box → promote. (Source: §1 triggers; R1 S1, S6, S7.)
| # | Trigger | Action | Output | Evidence |
|---|---|---|---|---|
| OP-1 | Prompt crosses a §1 threshold | Run the §4.1 checklist | promote / keep-prose decision | R1 S1, S7 |
| OP-2 | Decision = promote | Extract variable inputs + distinct outputs into named slots | Flat list of typed slots | R1 S2 |
| OP-3 | Slots listed | Rename each to a semantic, parameter-style name | Field names that read as intent | R1 S2 |
| OP-4 | Names set | Add desc= only to underspecified fields | Minimal descriptions | R1 S3 |
| OP-5 | Output has fixed value set | Type the output field (Literal[...] / bool / int) instead of str | Typed OutputField | R1 S3, S5 |
| OP-6 | Reasoning would help quality | Note "needs CoT" but defer module choice to [[dspy]] | Hand-off note | R1 S4 (module table is dspy's) |
| OP-7 | Optimizer plateaus later | Loop back: re-audit Signature for ambiguity before blaming optimizer | Revised Signature | R1 S8 |
| OP-8 | Output consumed by code AND must be machine-valid | Pair the Signature with a grammar/JSON enforcer (Outlines) — Signature shapes intent, enforcer guarantees syntax | Signature + enforcement layer | R1 S9 |
customer_email, not the text the user pasted.Literal["bug","billing","other"] over str when theset is closed (OP-5) — the type *is* documentation and a parse guard.
desc= for what the name can't say: format, length, units, allowed values, edge-case handling.| Side | Add a desc when… | Skip the desc when… |
|---|---|---|
| InputField | The input has a non-obvious format/source ("raw OCR text, may contain noise"), or the LM tends to misread which input is which | The field name fully explains it (question, ticket) — the cheatsheet leaves question bare (R1 S3) |
| OutputField | You need to constrain the value: length ("≤15 words"), format ("ISO-8601 date"), or allowed set | The output type already constrains it (e.g. Literal[...] or bool carries the spec) |
Rule of thumb: input descs prevent confusion; output descs prevent malformed values. Default to fewer descs;
add one only when you can name the specific failure it prevents.
困境: A support-triage prompt is 80 lines: persona + 4 categories with examples + output-format spec +
edge-case rules. The output ("category, confidence, escalate?") is parsed by routing code. Promote it verbatim
into one Signature, or restructure first?
约束:
category and escalate) → §1 CONSUMED trigger fires.决策步骤:
R1 S1).ticket: str. Outputs = `category:Literal[...], confidence: float, escalate: bool` (OP-2, OP-5). The four category descriptions and examples
are demos/instructions the optimizer will own — drop them from your code (mental model #2, R1 S5).
escalate: bool replaces parsing the word"yes" out of prose.
desc only on confidence ("0–1, calibrated") since the name underspecifies the range (OP-4, §4.4).ChainOfThought (reasoning helps category choice) and to compile against theexisting routing-accuracy metric.
结果: An 80-line blob collapses to a 5-field typed contract; the router drops all string-scraping; the prose
that *was* the prompt becomes optimizer-owned instructions/demos.
可提取的操作: **When promoting a mega-prompt, keep only the I/O shape in code; let the instruction/demo prose
become the optimizer's territory. Split fused outputs; type closed-set and boolean outputs.**
困境: A teammate has a 6-line prompt that runs once in a migration script ("classify these 200 rows once,
then we throw the script away") and asks you to "make it a proper Signature so it's robust."
约束:
决策步骤:
no second reader over time (disposable script). This is the boundary the [[agentsop-dspy]] skill flags: compile
only after the I/O contract stabilizes and will be reused (R1 S7).
Literaloutput stops bad values landing in the DB), but do not optimize/compile it. A typed dspy.Predict(Sig)
with no compile is cheap and gives the parse guard without the compile-loop overhead.
DSPy without a metric is just verbose prompting (R1 S10). Say so explicitly.
结果: A 10-line typed Signature with no compile: enough to make the written column type-safe, not enough to
waste a compile budget on a script that's about to be deleted.
可提取的操作: **CONSUMED alone justifies a *typed* Signature (parse safety) but NOT optimization. Separate
"promote to typed contract" from "compile/optimize" — they have different gates.**
pure boilerplate. If no §1 trigger fires, the prose prompt is the *correct* artifact (R1 S7).
class Sig: input: str; output: str defeats the entire point — theoptimizer gets zero intent signal and code still can't trust the output shape. Field names ARE the contract
(R1 S2). Generic names are the most common silent failure.
result: str and regex-scraping three valuesout of it re-creates the fragility you were escaping. Split into typed fields (OP-2, OP-5).
freezing it in your Signature both bloats your code and fights the compiler (mental model #2, R1 S5).
boilerplate. Stabilize first (R1 S7).
desc= to every field reflexively. Descriptions you can't tie to a specific prevented failure arenoise that bloats the prompt; the cheatsheet leaves obvious inputs bare (R1 S3).
OutputField *pushes* towardstructure but does not *enforce* grammar — pair with Outlines/Guidance when machine-validity is mandatory
(R1 S9, OP-8).
skill stops at "the Signature is shaped."
LMQL), orthogonal to Signature design (R1 S9).
transfers, but the implementation does not (see §7 for the cross-framework mapping).
The decision ("promote prose → typed contract when the prompt becomes load-bearing") is framework-agnostic.
Only the *artifact* differs. This overlay's rubric (§4) tells you when to reach for any column below.
| Approach | What the "contract" is | Optimizable? | Enforces output syntax? | Best when |
|---|---|---|---|---|
| Raw prompt string | None — narration only | No | No | One-shot, human-read, unstable, no reuse (§6 boundary) |
| DSPy Signature | Named + typed I/O fields; field names carry intent for the optimizer (R1 S2) | Yes — instructions/demos rewritten on compile, field shape preserved (R1 S5) | Pushes toward structure, no hard guarantee (R1 S9) | Load-bearing prompt + a metric exists / model-swap planned. Implementation: [[dspy]] |
| Pydantic output model | A typed schema the response is *validated against* after generation | No (it's validation, not prompt-tuning) | Yes — validation raises on mismatch | You need a hard post-hoc type check but are not optimizing the prompt |
| instructor (Pydantic + LLM) | Pydantic model used both as prompt scaffold and parse target; auto-retries on validation failure | No prompt-optimization loop; retries only | Yes — re-asks the LM until the schema validates | You want structured-output-with-retries on a raw provider SDK, no compile pipeline |
How they compose (not mutually exclusive):
output is valid JSON/grammar at the token level (R1 S9, OP-8).
*optimizer* that instructor lacks, and instructor adds *validation-retry* that a bare Signature lacks. Pick
DSPy when you have a metric and want to compile; pick instructor when you just need structured output + retries
on a raw SDK.
type gate with no prompt machinery.
Bottom line: this skill decides *whether* the prompt deserves a typed contract. If yes and you're in DSPy
with a metric → the contract is a Signature, and you continue in [[dspy]] / [[agentsop-dspy]]. If you only need
validation → Pydantic/instructor. If the prompt isn't load-bearing → no contract at all.
overlay defers ALL implementation to it.
selection, cost guardrails). This overlay is the narrow "should this prose become a Signature" slice of its
Stage 1.
All claims tagged S1–S10 are sourced verbatim in references/R1-source-evidence.md, drawn from the local
dspy-sop-skill/SKILL.md Signatures material and the upstream DSPy docs it cites
([dspy.ai/learn/programming/signatures/], [dspy.ai/cheatsheet/], [arxiv.org/abs/2310.03714]).
Automatically creates user-facing changelogs from git commits by analyzing commit history, categorizing changes, and transforming technical commits into clear, customer-friendly release notes. Turns hours of manual changelog writing into minutes of automated generation.
Use when the user asks to run Codex CLI (codex exec, codex resume) or references OpenAI Codex for code analysis, refactoring, or automated editing. Uses GPT-5.2 by default for state-of-the-art software engineering.
Implement memory-safe programming with RAII, ownership, smart pointers, and resource management across Rust, C++, and C. Use when writing safe systems code, managing resources, or preventing memory bugs.
Python/HTSlib workflows for genomic files. Use when reading, querying, filtering, or writing SAM/BAM/CRAM, VCF/BCF, FASTA/FASTQ, or tabix data with pysam, including pileup, coverage, indexing, and CRAM references.
Evaluate scientific claims and evidence quality. Use for assessing experimental design validity, identifying biases and confounders, applying evidence grading frameworks (GRADE, Cochrane Risk of Bias), or teaching critical analysis. Best for understanding evidence quality, identifying flaws. For formal peer review writing use peer-review.
Use when a user asks to debug or fix failing GitHub PR checks that run in GitHub Actions; use `gh` to inspect checks and logs, summarize failure context, draft a fix plan, and implement only after explicit approval. Treat external providers (for example Buildkite) as out of scope and report only the details URL.
> Create, build, deploy, and localize declarative agents for M365 Copilot and Teams. USE THIS SKILL for ANY task involving a declarative agent — including localization, scaffolding, editing manifests, adding capabilities, and deploying. Localization requires tokenized manifests and language files that only this skill knows how to produce. "scaffold an agent", "new agent project", "add a capability", "add a plugin", "configure my agent", "deploy my agent", "fix my agent manifest", "edit my agent", "localize my agent", "add localization", "translate my agent", "multi-language agent", "add an API plugin", "add an MCP plugin", "add OAuth to my plugin", "review instructions", "improve instructions", "fix my instructions"
Documentation generation workflow covering API docs, architecture docs, README files, code comments, and technical writing.
Take agentsope/agentsop-signature-design from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.