{"id":"068166a0-1544-4e34-a8d0-3ea8402e3a81","shortId":"YdtxdL","kind":"skill","title":"dspy-advanced-module-composition","tagline":"This skill should be used when the user asks to \"compose DSPy modules\", \"use Ensemble optimizer\", \"combine multiple programs\", \"use dspy.MultiChainComparison\", mentions \"ensemble voting\", \"module composition\", \"sequential pipelines\", or needs to build complex multi-module DSPy pr","description":"# DSPy Advanced Module Composition\n\n## Goal\n\nCompose complex DSPy programs using the Ensemble optimizer, MultiChainComparison for reasoning synthesis, and sequential module patterns.\n\n## When to Use\n\n- Need consensus from multiple approaches\n- Comparing different reasoning strategies\n- Building robust pipelines with fallbacks\n- Complex multi-step workflows with branching\n- Ensemble methods for improved accuracy\n\n## Related Skills\n\n- Design modules: [dspy-custom-module-design](../dspy-custom-module-design/SKILL.md)\n- Define signatures: [dspy-signature-designer](../dspy-signature-designer/SKILL.md)\n- Evaluate performance: [dspy-evaluation-suite](../dspy-evaluation-suite/SKILL.md)\n\n## Inputs\n\n| Input | Type | Description |\n|-------|------|-------------|\n| `modules` | `list[dspy.Module]` | Modules to compose |\n| `composition_type` | `str` | \"ensemble\", \"sequential\", \"comparison\" |\n\n## Outputs\n\n| Output | Type | Description |\n|--------|------|-------------|\n| `composed_program` | `dspy.Module` | Composed multi-module program |\n\n## Workflow\n\n### Phase 1: Ensemble Voting\n\nCombine multiple programs using the Ensemble optimizer:\n\n```python\nimport dspy\nfrom dspy.teleprompt import Ensemble\n\ndspy.configure(lm=dspy.LM(\"openai/gpt-4o-mini\"))\n\n# Define a signature for the task\nclass BasicQA(dspy.Signature):\n    \"\"\"Answer questions with short factoid answers.\"\"\"\n    question = dspy.InputField()\n    answer = dspy.OutputField()\n\n# Create multiple program instances (should be optimized/compiled programs)\n# For simple demonstration, we'll use different predictors\nprogram1 = dspy.Predict(BasicQA)\nprogram2 = dspy.ChainOfThought(BasicQA)\nprogram3 = dspy.Predict(BasicQA)\n\n# Ensemble is an optimizer that compiles programs together\nensemble = Ensemble(reduce_fn=dspy.majority)\nensembled_program = ensemble.compile([program1, program2, program3])\n\n# Use the ensembled program\nresult = ensembled_program(question=\"What is 2 + 2?\")\nprint(result.answer)  # Voted answer\n```\n\n### Phase 2: MultiChainComparison\n\nCompare multiple reasoning attempts:\n\n```python\nimport dspy\n\nclass BasicQA(dspy.Signature):\n    \"\"\"Answer questions with short factoid answers.\"\"\"\n    question = dspy.InputField()\n    answer = dspy.OutputField(desc=\"often between 1 and 5 words\")\n\nclass ComparisonPipeline(dspy.Module):\n    def __init__(self):\n        # Generate multiple reasoning attempts\n        self.cot = dspy.ChainOfThought(BasicQA)\n\n        # Compare M attempts and select best\n        # Must pass a Signature class, not a string\n        self.compare = dspy.MultiChainComparison(\n            BasicQA,\n            M=3,  # Number of attempts to compare\n            temperature=0.7\n        )\n\n    def forward(self, question):\n        # Generate multiple completions to compare\n        # Each completion must have rationale/reasoning field\n        completions = [\n            self.cot(question=question)\n            for _ in range(3)\n        ]\n\n        # MultiChainComparison synthesizes them into best answer\n        # Pass completions as positional arg, not keyword arg\n        return self.compare(completions, question=question)\n\n# Usage\ndspy.configure(lm=dspy.LM(\"openai/gpt-4o-mini\"))\npipeline = ComparisonPipeline()\nresult = pipeline(question=\"Explain quantum computing\")\nprint(f\"Best answer: {result.answer}\")\nprint(f\"Rationale: {result.rationale}\")\n```\n\n### Phase 3: Sequential Composition\n\nChain modules for multi-step workflows:\n\n```python\nimport dspy\n\n# Define signatures for each step\nclass QueryRewrite(dspy.Signature):\n    \"\"\"Rewrite a question for better retrieval.\"\"\"\n    question = dspy.InputField()\n    refined_query: str = dspy.OutputField()\n\nclass GenerateAnswer(dspy.Signature):\n    \"\"\"Generate answer from context and question.\"\"\"\n    context = dspy.InputField()\n    question = dspy.InputField()\n    answer = dspy.OutputField()\n\nclass ValidateAnswer(dspy.Signature):\n    \"\"\"Validate answer quality.\"\"\"\n    answer = dspy.InputField()\n    question = dspy.InputField()\n    is_valid: bool = dspy.OutputField()\n    confidence: float = dspy.OutputField()\n\nclass SequentialRAG(dspy.Module):\n    \"\"\"Multi-step RAG pipeline.\"\"\"\n\n    def __init__(self):\n        # Step 1: Query rewriting\n        self.rewrite = dspy.Predict(QueryRewrite)\n\n        # Step 2: Retrieval\n        self.retrieve = dspy.Retrieve(k=5)\n\n        # Step 3: Answer generation\n        self.generate = dspy.ChainOfThought(GenerateAnswer)\n\n        # Step 4: Validation\n        self.validate = dspy.Predict(ValidateAnswer)\n\n    def forward(self, question):\n        # Sequential execution\n        refined = self.rewrite(question=question)\n        passages = self.retrieve(refined.refined_query).passages\n\n        answer_pred = self.generate(\n            context=passages,\n            question=question\n        )\n\n        validation = self.validate(\n            answer=answer_pred.answer,\n            question=question\n        )\n\n        return dspy.Prediction(\n            answer=answer_pred.answer,\n            is_valid=validation.is_valid,\n            confidence=validation.confidence\n        )\n\n# Usage\ndspy.configure(lm=dspy.LM(\"openai/gpt-4o-mini\"))\nrag = SequentialRAG()\nresult = rag(question=\"What causes lightning?\")\nprint(f\"Answer: {result.answer} (valid: {result.is_valid})\")\n```\n\n### Phase 4: Fallback Strategies\n\nHandle failures with fallback modules:\n\n```python\nimport dspy\nimport logging\n\nlogger = logging.getLogger(__name__)\n\nclass BasicQA(dspy.Signature):\n    \"\"\"Answer questions with short factoid answers.\"\"\"\n    question = dspy.InputField()\n    answer = dspy.OutputField()\n\nclass RobustQA(dspy.Module):\n    \"\"\"Fallback strategy for errors.\"\"\"\n\n    def __init__(self):\n        self.primary = dspy.ChainOfThought(BasicQA)\n        self.fallback = dspy.Predict(BasicQA)\n\n    def forward(self, question):\n        try:\n            result = self.primary(question=question)\n            if result.answer and len(result.answer) > 10:\n                return result\n        except Exception as e:\n            logger.error(f\"Primary failed: {e}\")\n\n        return self.fallback(question=question)\n```\n\n## Production Example\n\n```python\nimport dspy\nfrom dspy.teleprompt import BootstrapFewShot, Ensemble\n\nclass GenerateAnswer(dspy.Signature):\n    \"\"\"Generate answer from context and question.\"\"\"\n    context = dspy.InputField()\n    question = dspy.InputField()\n    answer = dspy.OutputField()\n\nclass MultiStrategyQA(dspy.Module):\n    \"\"\"Production QA with retrieval.\"\"\"\n\n    def __init__(self):\n        self.retrieve = dspy.Retrieve(k=3)\n        self.generate = dspy.ChainOfThought(GenerateAnswer)\n\n    def forward(self, question: str):\n        context = self.retrieve(question).passages\n        return self.generate(context=context, question=question)\n\n# Usage with optimization\ndspy.configure(lm=dspy.LM(\"openai/gpt-4o-mini\"))\nqa = MultiStrategyQA()\n\n# First, optimize the base program\noptimizer = BootstrapFewShot(\n    metric=lambda ex, pred, trace: ex.answer in pred.answer,\n    max_bootstrapped_demos=3\n)\n\ncompiled_qa = optimizer.compile(qa, trainset=trainset)\n\n# Then create ensemble from multiple optimized programs\n# (train with different seeds or optimizers to get diversity)\nprogram1 = optimizer.compile(qa, trainset=trainset)\nprogram2 = optimizer.compile(qa, trainset=trainset)\nprogram3 = optimizer.compile(qa, trainset=trainset)\n\nensemble = Ensemble(reduce_fn=dspy.majority)\nfinal_program = ensemble.compile([program1, program2, program3])\n```\n\n## Best Practices\n\n1. **Test modules independently** - Validate each module before composition\n2. **Handle failures gracefully** - Use try/except in parallel composition\n3. **Balance cost vs accuracy** - Ensembles are expensive (N × cost)\n4. **Optimize composed programs** - Use BootstrapFewShot or MIPROv2 on final composition\n5. **Module reusability** - Design modules to work in multiple compositions\n\n## Limitations\n\n- Ensemble increases cost linearly with module count\n- Voting strategies may not work for all output types\n- Sequential composition amplifies latency\n- Error propagation in chains can be hard to debug\n- Parallel composition requires careful state management\n\n## Official Documentation\n\n- **DSPy Documentation**: https://dspy.ai/\n- **DSPy GitHub**: https://github.com/stanfordnlp/dspy\n- **Modules Guide**: https://dspy.ai/learn/programming/modules/","tags":["dspy","advanced","module","composition","skills","omidzamani","agent-skills","claude-code","claude-skills","llm","prompt-optimization","rag"],"capabilities":["skill","source-omidzamani","skill-dspy-advanced-module-composition","topic-agent-skills","topic-claude-code","topic-claude-skills","topic-dspy","topic-llm","topic-prompt-optimization","topic-rag"],"categories":["dspy-skills"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/OmidZamani/dspy-skills/dspy-advanced-module-composition","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add OmidZamani/dspy-skills","source_repo":"https://github.com/OmidZamani/dspy-skills","install_from":"skills.sh"}},"qualityScore":"0.487","qualityRationale":"deterministic score 0.49 from registry signals: · indexed on github topic:agent-skills · 74 github stars · SKILL.md body (8,285 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-05-02T06:55:43.918Z","embedding":null,"createdAt":"2026-04-18T22:14:07.992Z","updatedAt":"2026-05-02T06:55:43.918Z","lastSeenAt":"2026-05-02T06:55:43.918Z","tsv":"'/dspy-custom-module-design/skill.md':103 '/dspy-evaluation-suite/skill.md':117 '/dspy-signature-designer/skill.md':110 '/learn/programming/modules/':853 '/stanfordnlp/dspy':848 '0.7':316 '1':148,274,459,754 '10':603 '2':242,243,249,466,763 '3':309,339,382,473,657,703,772 '4':480,544,782 '5':276,471,793 'accuraci':93,776 'advanc':3,45 'amplifi':822 'answer':178,183,186,247,261,266,269,345,375,419,428,434,436,474,500,509,515,538,563,568,571,633,642 'answer_pred.answer':510,516 'approach':72 'arg':350,353 'ask':14 'attempt':254,287,293,312 'balanc':773 'base':688 'basicqa':176,206,209,212,259,290,307,561,585,588 'best':296,344,374,752 'better':407 'bool':442 'bootstrap':701 'bootstrapfewshot':627,691,787 'branch':88 'build':37,77 'care':836 'caus':534 'chain':385,827 'class':175,258,278,301,400,415,430,447,560,573,629,644 'combin':22,151 'compar':73,251,291,314,325 'comparison':133 'comparisonpipelin':279,365 'compil':218,704 'complet':323,327,332,347,356 'complex':38,50,82 'compos':16,49,127,138,141,784 'composit':5,31,47,128,384,762,771,792,802,821,834 'comput':371 'confid':444,521 'consensus':69 'context':421,424,503,635,638,666,672,673 'cost':774,781,806 'count':810 'creat':188,711 'custom':100 'debug':832 'def':281,317,455,485,580,589,651,661 'defin':104,169,395 'demo':702 'demonstr':198 'desc':271 'descript':121,137 'design':96,102,109,796 'differ':74,202,719 'divers':725 'document':840,842 'dspi':2,17,42,44,51,99,107,114,160,257,394,554,623,841,844 'dspy-advanced-module-composit':1 'dspy-custom-module-design':98 'dspy-evaluation-suit':113 'dspy-signature-design':106 'dspy.ai':843,852 'dspy.ai/learn/programming/modules/':851 'dspy.chainofthought':208,289,477,584,659 'dspy.configure':165,360,524,679 'dspy.inputfield':185,268,410,425,427,437,439,570,639,641 'dspy.lm':167,362,526,681 'dspy.majority':225,745 'dspy.module':124,140,280,449,575,646 'dspy.multichaincomparison':26,306 'dspy.outputfield':187,270,414,429,443,446,572,643 'dspy.predict':205,211,463,483,587 'dspy.prediction':514 'dspy.retrieve':469,655 'dspy.signature':177,260,402,417,432,562,631 'dspy.teleprompt':162,625 'e':609,614 'ensembl':20,28,55,89,131,149,156,164,213,221,222,226,234,237,628,712,741,742,777,804 'ensemble.compile':228,748 'error':579,824 'evalu':111,115 'ex':694 'ex.answer':697 'exampl':620 'except':606,607 'execut':490 'expens':779 'explain':369 'f':373,378,537,611 'factoid':182,265,567 'fail':613 'failur':548,765 'fallback':81,545,550,576 'field':331 'final':746,791 'first':685 'float':445 'fn':224,744 'forward':318,486,590,662 'generat':284,321,418,475,632 'generateansw':416,478,630,660 'get':724 'github':845 'github.com':847 'github.com/stanfordnlp/dspy':846 'goal':48 'grace':766 'guid':850 'handl':547,764 'hard':830 'import':159,163,256,393,553,555,622,626 'improv':92 'increas':805 'independ':757 'init':282,456,581,652 'input':118,119 'instanc':191 'k':470,656 'keyword':352 'lambda':693 'latenc':823 'len':601 'lightn':535 'limit':803 'linear':807 'list':123 'll':200 'lm':166,361,525,680 'log':556 'logger':557 'logger.error':610 'logging.getlogger':558 'm':292,308 'manag':838 'max':700 'may':813 'mention':27 'method':90 'metric':692 'miprov2':789 'modul':4,18,30,41,46,63,97,101,122,125,144,386,551,756,760,794,797,809,849 'multi':40,84,143,389,451 'multi-modul':39,142 'multi-step':83,388,450 'multichaincomparison':57,250,340 'multipl':23,71,152,189,252,285,322,714,801 'multistrategyqa':645,684 'must':297,328 'n':780 'name':559 'need':35,68 'number':310 'offici':839 'often':272 'openai/gpt-4o-mini':168,363,527,682 'optim':21,56,157,216,678,686,690,715,722,783 'optimized/compiled':194 'optimizer.compile':706,727,732,737 'output':134,135,818 'parallel':770,833 'pass':298,346 'passag':495,499,504,669 'pattern':64 'perform':112 'phase':147,248,381,543 'pipelin':33,79,364,367,454 'posit':349 'pr':43 'practic':753 'pred':501,695 'pred.answer':699 'predictor':203 'primari':612 'print':244,372,377,536 'product':619,647 'program':24,52,139,145,153,190,195,219,227,235,238,689,716,747,785 'program1':204,229,726,749 'program2':207,230,731,750 'program3':210,231,736,751 'propag':825 'python':158,255,392,552,621 'qa':648,683,705,707,728,733,738 'qualiti':435 'quantum':370 'queri':412,460,498 'queryrewrit':401,464 'question':179,184,239,262,267,320,334,335,357,358,368,405,409,423,426,438,488,493,494,505,506,511,512,532,564,569,592,596,597,617,618,637,640,664,668,674,675 'rag':453,528,531 'rang':338 'rational':379 'rationale/reasoning':330 'reason':59,75,253,286 'reduc':223,743 'refin':411,491 'refined.refined':497 'relat':94 'requir':835 'result':236,366,530,594,605 'result.answer':245,376,539,599,602 'result.is':541 'result.rationale':380 'retriev':408,467,650 'return':354,513,604,615,670 'reusabl':795 'rewrit':403,461 'robust':78 'robustqa':574 'seed':720 'select':295 'self':283,319,457,487,582,591,653,663 'self.compare':305,355 'self.cot':288,333 'self.fallback':586,616 'self.generate':476,502,658,671 'self.primary':583,595 'self.retrieve':468,496,654,667 'self.rewrite':462,492 'self.validate':482,508 'sequenti':32,62,132,383,489,820 'sequentialrag':448,529 'short':181,264,566 'signatur':105,108,171,300,396 'simpl':197 'skill':7,95 'skill-dspy-advanced-module-composition' 'source-omidzamani' 'state':837 'step':85,390,399,452,458,465,472,479 'str':130,413,665 'strategi':76,546,577,812 'string':304 'suit':116 'synthes':341 'synthesi':60 'task':174 'temperatur':315 'test':755 'togeth':220 'topic-agent-skills' 'topic-claude-code' 'topic-claude-skills' 'topic-dspy' 'topic-llm' 'topic-prompt-optimization' 'topic-rag' 'trace':696 'train':717 'trainset':708,709,729,730,734,735,739,740 'tri':593 'try/except':768 'type':120,129,136,819 'usag':359,523,676 'use':10,19,25,53,67,154,201,232,767,786 'user':13 'valid':433,441,481,507,518,520,540,542,758 'validateansw':431,484 'validation.confidence':522 'validation.is':519 'vote':29,150,246,811 'vs':775 'word':277 'work':799,815 'workflow':86,146,391","prices":[{"id":"fb386e89-bfc1-41ce-9efe-b5fba2210997","listingId":"068166a0-1544-4e34-a8d0-3ea8402e3a81","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"OmidZamani","category":"dspy-skills","install_from":"skills.sh"},"createdAt":"2026-04-18T22:14:07.992Z"}],"sources":[{"listingId":"068166a0-1544-4e34-a8d0-3ea8402e3a81","source":"github","sourceId":"OmidZamani/dspy-skills/dspy-advanced-module-composition","sourceUrl":"https://github.com/OmidZamani/dspy-skills/tree/master/skills/dspy-advanced-module-composition","isPrimary":false,"firstSeenAt":"2026-04-18T22:14:07.992Z","lastSeenAt":"2026-05-02T06:55:43.918Z"}],"details":{"listingId":"068166a0-1544-4e34-a8d0-3ea8402e3a81","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"OmidZamani","slug":"dspy-advanced-module-composition","github":{"repo":"OmidZamani/dspy-skills","stars":74,"topics":["agent-skills","claude-code","claude-skills","dspy","llm","prompt-optimization","rag"],"license":"mit","html_url":"https://github.com/OmidZamani/dspy-skills","pushed_at":"2026-02-21T12:49:43Z","description":"Collection of Claude Skills for DSPy framework - program language models, optimize prompts, and build RAG pipelines systematically","skill_md_sha":"92d6b5d764e0d1517a55982f0fe982544b007159","skill_md_path":"skills/dspy-advanced-module-composition/SKILL.md","default_branch":"master","skill_tree_url":"https://github.com/OmidZamani/dspy-skills/tree/master/skills/dspy-advanced-module-composition"},"layout":"multi","source":"github","category":"dspy-skills","frontmatter":{"name":"dspy-advanced-module-composition","description":"This skill should be used when the user asks to \"compose DSPy modules\", \"use Ensemble optimizer\", \"combine multiple programs\", \"use dspy.MultiChainComparison\", mentions \"ensemble voting\", \"module composition\", \"sequential pipelines\", or needs to build complex multi-module DSPy programs with ensemble patterns or multi-chain comparison."},"skills_sh_url":"https://skills.sh/OmidZamani/dspy-skills/dspy-advanced-module-composition"},"updatedAt":"2026-05-02T06:55:43.918Z"}}