dspy-react-agent-builder
This skill should be used when the user asks to "create a ReAct agent", "build an agent with tools", "implement tool-calling agent", "use dspy.ReAct", mentions "agent with tools", "reasoning and acting", "multi-step agent", "agent optimization with GEPA", or needs to build production agents that use tools to solve complex tasks.
git clone --depth 1 https://github.com/OmidZamani/dspy-skills /tmp/dspy-react-agent-builder && cp -r /tmp/dspy-react-agent-builder/skills/dspy-react-agent-builder ~/.claude/skills/dspy-react-agent-builderSKILL.md
# DSPy ReAct Agent Builder
## Goal
Build production-quality ReAct agents that use tools to solve complex multi-step tasks with reasoning, acting, and error handling.
## When to Use
- Multi-step tasks requiring tool use
- Search + reasoning workflows
- Complex question answering with external data
- Tasks needing calculation, retrieval, or API calls
## Related Skills
- Optimize agents: [dspy-gepa-reflective](../dspy-gepa-reflective/SKILL.md)
- Connect MCP tools: [dspy-mcp-tool-integration](../dspy-mcp-tool-integration/SKILL.md)
- Configure native tool calling: [dspy-adapters-multimodal](../dspy-adapters-multimodal/SKILL.md)
- Define signatures: [dspy-signature-designer](../dspy-signature-designer/SKILL.md)
- Evaluate performance: [dspy-evaluation-suite](../dspy-evaluation-suite/SKILL.md)
## Inputs
| Input | Type | Description |
|-------|------|-------------|
| `signature` | `str` | Task signature (e.g., "question -> answer") |
| `tools` | `list[callable]` | Available tools/functions |
| `max_iters` | `int` | Max reasoning steps (default: 20) |
## Outputs
| Output | Type | Description |
|--------|------|-------------|
| `agent` | `dspy.ReAct` | Configured ReAct agent |
## Workflow
### Phase 1: Define Tools
Tools are Python functions with clear docstrings. The agent uses docstrings to understand tool capabilities:
```python
import dspy
def search(query: str) -> list[str]:
"""Search knowledge base for relevant information.
Args:
query: Search query string
Returns:
List of relevant text passages
"""
retriever = dspy.ColBERTv2(url='http://20.102.90.50:2017/wiki17_abstracts')
results = retriever(query, k=3)
return [r['text'] for r in results]
def calculate(expression: str) -> float:
"""Safely evaluate mathematical expressions.
Args:
expression: Math expression (e.g., "2 + 2", "sqrt(16)")
Returns:
Numerical result
"""
try:
with dspy.PythonInterpreter() as interpreter:
return interpreter.execute(expression)
except Exception as e:
return f"Error: {e}"
```
### Phase 2: Create ReAct Agent
```python
# Configure LM
dspy.configure(lm=dspy.LM("openai/gpt-4o-mini"))
# Create agent
agent = dspy.ReAct(
signature="question -> answer",
tools=[search, calculate],
max_iters=5
)
# Use agent
result = agent(question="What is the population of Paris plus 1000?")
print(result.answer)
```
### Phase 3: Production Agent with Error Handling
```python
import dspy
import logging
logger = logging.getLogger(__name__)
class ResearchAgent(dspy.Module):
"""Production agent with error handling and logging."""
def __init__(self, max_iters: int = 5):
self.max_iters = max_iters
self.agent = dspy.ReAct(
signature="question -> answer",
tools=[self.search, self.calculate, self.summarize],
max_iters=max_iters
)
def search(self, query: str) -> list[str]:
"""Search for relevant documents."""
try:
retriever = dspy.ColBERTv2(
url='http://20.102.90.50:2017/wiki17_abstracts'
)
results = retriever(query, k=5)
return [r['text'] for r in results]
except Exception as e:
logger.error(f"Search failed: {e}")
return [f"Search unavailable: {e}"]
def calculate(self, expression: str) -> str:
"""Evaluate mathematical expressions safely."""
try:
with dspy.PythonInterpreter() as interpreter:
return str(interpreter.execute(expression))
except Exception as e:
logger.error(f"Calculation failed: {e}")
return f"Error: {e}"
def summarize(self, text: str) -> str:
"""Summarize long text into key points."""
try:
summarizer = dspy.Predict("text -> summary: str")
return summarizer(text=text[:1000]).summary
except Exception as e:
logger.error(f"Summarization failed: {e}")
return "Summarization unavailable"
def forward(self, question: str) -> dspy.Prediction:
"""Execute agent with error handling."""
try:
return self.agent(question=question)
except Exception as e:
logger.error(f"Agent failed: {e}")
return dspy.Prediction(answer=f"Error: {e}")
# Usage
agent = ResearchAgent(max_iters=6)
response = agent(question="What is the capital of France and its population?")
print(response.answer)
```
### Phase 4: Optimize with GEPA
ReAct agents benefit from reflective optimization:
```python
from dspy.evaluate import Evaluate
def feedback_metric(example, pred, trace=None, pred_name=None, pred_trace=None):
"""Provide textual feedback for GEPA."""
is_correct = example.answer.lower() in pred.answer.lower()
score = 1.0 if is_correct else 0.0
feedback = "Correct." if is_correct else f"Expected '{example.answer}'. Check tool selection."
return dspy.Prediction(score=score, feedback=feedback)
# Optimize agent
optimizer = dspy.GEPA(
metric=feedback_metric,
reflection_lm=dspy.LM("openai/gpt-4o"),
auto="medium"
)
compiled = optimizer.compile(agent, trainset=trainset)
compiled.save("research_agent_optimized.json", save_program=False)
```
## Best Practices
1. **Clear tool docstrings** - Agent relies on docstrings to understand tool capabilities
2. **Error handling** - All tools should handle failures gracefully and return error messages
3. **Tool independence** - Test each tool separately before adding to agent
4. **Logging** - Track tool calls and agent reasoning for debugging
5. **Limit iterations** - Set reasonable `max_iters` to prevent infinite loops (default is 20, but 5-10 often sufficient for simpler tasks)
## Limitations
- ReAct works best with 3-7 tools; too many tools confuse the agent
- Not all LMs support tool calling equally well (GPT-4 > GPT-3.5)
- Agent may call tools unnecessarilyUse this skill when you need to QA audit and fix a plugin skill file. Provides a methodology for verifying skill content against official documentation, fixing issues in-place, and producing verification reports.
This skill should be used when the user asks to "choose a DSPy adapter", "use JSONAdapter", "use XMLAdapter", "enable native function calling", "send images, audio, or files to DSPy", mentions `dspy.ChatAdapter`, `dspy.JSONAdapter`, `dspy.XMLAdapter`, `dspy.Image`, `dspy.Audio`, `dspy.File`, structured outputs, or multimodal DSPy signatures.
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.
This skill should be used when the user asks to "use BetterTogether", "combine prompt optimization and fine-tuning", "sequence DSPy optimizers", "run prompt then weight optimization", mentions `dspy.BetterTogether`, strategy strings such as "p -> w -> p", or needs to compose multiple DSPy teleprompters into an evaluated optimization sequence.
This skill should be used when the user asks to "bootstrap few-shot examples", "generate demonstrations", "use BootstrapFewShot", "optimize with limited data", "create training demos automatically", mentions "teacher model for few-shot", "10-50 training examples", or wants automatic demonstration generation for a DSPy program without extensive compute.
This skill should be used when the user asks to "create custom DSPy module", "design a DSPy module", "extend dspy.Module", "build reusable DSPy component", mentions "custom module patterns", "module serialization", "stateful modules", "module testing", or needs to design production-quality custom DSPy modules with proper architecture, state management, and testing.
This skill should be used when the user asks to "debug DSPy programs", "trace LLM calls", "monitor production DSPy", "use MLflow with DSPy", mentions "inspect_history", "custom callbacks", "observability", "production monitoring", "cost tracking", or needs to debug, trace, and monitor DSPy applications in development and production.
This skill should be used when the user asks to "build local DSPy retrieval", "use dspy.Embedder", "use dspy.Embeddings", "save an embeddings index", "add FAISS retrieval", mentions semantic search, hosted embeddings, local embedding models, `EmbeddingsWithScores`, or needs a DSPy retriever over an application-owned text corpus.