dspy-react-agent-builder

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

DSPy ReAct Agent Builder

DSPy ReAct Agent 构建器

Goal

目标

Build production-quality ReAct agents that use tools to solve complex multi-step tasks with reasoning, acting, and error handling.
构建具备推理、执行和错误处理能力,可使用工具解决复杂多步骤任务的生产级ReAct Agent。

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
  • 需要使用工具的多步骤任务
  • 搜索+推理工作流
  • 结合外部数据的复杂问答
  • 需要计算、检索或API调用的任务

Related Skills

相关Skill

  • Optimize agents: dspy-gepa-reflective
  • Define signatures: dspy-signature-designer
  • Evaluate performance: dspy-evaluation-suite
  • 优化Agent:dspy-gepa-reflective
  • 定义签名:dspy-signature-designer
  • 评估性能:dspy-evaluation-suite

Inputs

输入项

InputTypeDescription
signature
str
Task signature (e.g., "question -> answer")
tools
list[callable]
Available tools/functions
max_iters
int
Max reasoning steps (default: 20)
输入项类型描述
signature
str
任务签名(例如:"question -> answer")
tools
list[callable]
可用工具/函数
max_iters
int
最大推理步骤数(默认值:20)

Outputs

输出项

OutputTypeDescription
agent
dspy.ReAct
Configured ReAct agent
输出项类型描述
agent
dspy.ReAct
配置完成的ReAct Agent

Workflow

工作流程

Phase 1: Define Tools

阶段1:定义工具

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:
        interpreter = dspy.PythonInterpreter()
        return interpreter.execute(expression)
    except Exception as e:
        return f"Error: {e}"
工具是带有清晰文档字符串的Python函数。Agent会通过文档字符串来理解工具的功能:
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:
        interpreter = dspy.PythonInterpreter()
        return interpreter.execute(expression)
    except Exception as e:
        return f"Error: {e}"

Phase 2: Create ReAct Agent

阶段2:创建ReAct Agent

python
undefined
python
undefined

Configure LM

Configure LM

dspy.configure(lm=dspy.LM("openai/gpt-4o-mini"))
dspy.configure(lm=dspy.LM("openai/gpt-4o-mini"))

Create agent

Create agent

agent = dspy.ReAct( signature="question -> answer", tools=[search, calculate], max_iters=5 )
agent = dspy.ReAct( signature="question -> answer", tools=[search, calculate], max_iters=5 )

Use agent

Use agent

result = agent(question="What is the population of Paris plus 1000?") print(result.answer)
undefined
result = agent(question="What is the population of Paris plus 1000?") print(result.answer)
undefined

Phase 3: Production Agent with Error Handling

阶段3:具备错误处理的生产级Agent

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:
            interpreter = dspy.PythonInterpreter()
            result = interpreter.execute(expression)
            return str(result)
        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}")
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:
            interpreter = dspy.PythonInterpreter()
            result = interpreter.execute(expression)
            return str(result)
        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

Usage

agent = ResearchAgent(max_iters=6) response = agent(question="What is the capital of France and its population?") print(response.answer)
undefined
agent = ResearchAgent(max_iters=6) response = agent(question="What is the capital of France and its population?") print(response.answer)
undefined

Phase 4: Optimize with GEPA

阶段4:使用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)
ReAct Agent可通过反射优化提升性能:
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

Optimize agent

optimizer = dspy.GEPA( metric=feedback_metric, reflection_lm=dspy.LM("openai/gpt-4o"), auto="medium", enable_tool_optimization=True # Also optimize tool docstrings )
compiled = optimizer.compile(agent, trainset=trainset) compiled.save("research_agent_optimized.json", save_program=False)
undefined
optimizer = dspy.GEPA( metric=feedback_metric, reflection_lm=dspy.LM("openai/gpt-4o"), auto="medium", enable_tool_optimization=True # Also optimize tool docstrings )
compiled = optimizer.compile(agent, trainset=trainset) compiled.save("research_agent_optimized.json", save_program=False)
undefined

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)
  1. 清晰的工具文档字符串 - Agent依赖文档字符串来理解工具功能
  2. 错误处理 - 所有工具都应优雅地处理失败并返回错误信息
  3. 工具独立性 - 在添加到Agent之前,单独测试每个工具
  4. 日志记录 - 跟踪工具调用和Agent推理过程以方便调试
  5. 限制迭代次数 - 设置合理的
    max_iters
    以防止无限循环(默认值为20,但对于简单任务,5-10通常足够)

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 unnecessarily or miss necessary calls
  • Requires GEPA optimization for production quality
  • Tool execution is sequential, not parallelized
  • ReAct在搭配3-7个工具时效果最佳;工具过多会让Agent产生混淆
  • 并非所有大语言模型对工具调用的支持程度都相同(GPT-4 > GPT-3.5)
  • Agent可能会不必要地调用工具,或者遗漏必要的调用
  • 需要GEPA优化才能达到生产级质量
  • 工具执行是串行的,不支持并行化

Official Documentation

官方文档