Skip to main content

Multi-Step Agent Workflow

Complex agent that uses multiple tools to accomplish multi-part tasks.

Python Implementation

import requests

# Create multi-tool agent
create_response = requests.post(
"http://localhost/api/v1/agent/configs",
headers={"Authorization": "Bearer YOUR_API_KEY"},
json={
"name": "multi_tool_agent",
"display_name": "Multi-Step Assistant",
"description": "Uses RAG, web search, and code execution for comprehensive analysis",
"category": "analysis",
"system_prompt": "You are a multi-step research and analysis assistant. Use available tools to gather information, process data, and provide comprehensive answers. Break complex tasks into smaller steps and use tools efficiently. Always track your progress and explain your reasoning.",
"model": "gpt-4",
"temperature": 0.3,
"builtin_tools": ["rag_search", "web_search", "code_execution"],
"tool_choice": "required", # Force tool usage
"max_iterations": 8,
"tool_resources": {
"code_execution": {
"timeout": 60,
"allowed_libraries": ["pandas", "numpy", "matplotlib", "seaborn"]
}
}
}
)

agent_id = create_response.json()["id"]

# Complex query requiring multiple tools
query = """
I need to:
1. Search our internal documentation for API configuration details
2. Get the latest developments in AI from web search
3. Analyze a sample sales dataset to identify trends
4. Create a visualization of the trends

Provide a comprehensive report with citations.
"""

response = requests.post(
"http://localhost/api/v1/agent/chat",
headers={"Authorization": "Bearer YOUR_API_KEY"},
json={
"agent_id": agent_id,
"message": query
}
)

result = response.json()
print(f"Response: {result['response']}")

print(f"\nTool execution trace:")
for tool_call in result.get("tool_calls", []):
print(f"Step: {tool_call['tool_name']}")
print(f" Parameters: {tool_call.get('parameters', {})}")
print(f" Status: {tool_call['status']}")
if "result" in tool_call:
print(f" Result: {tool_call['result']}")

Workflow Breakdown

Agent searches internal documentation:

# Agent will execute this automatically
rag_search_query = "API configuration documentation"

Response:

{
"tool_calls": [
{
"tool_name": "rag_search",
"parameters": {
"query": "API configuration",
"collection_name": "documentation",
"top_k": 5
},
"result": {
"found": 3,
"results": [
{
"document_id": "doc-123",
"content": "Go to Settings in the web interface and click 'API Keys'...",
}
]
},
"status": "success"
}
]
}

Agent searches for current information:

web_search_query = "latest AI developments 2024"

Response:

{
"tool_calls": [
{
"tool_name": "web_search",
"parameters": {
"query": web_search_query,
"max_results": 5
},
"result": {
"found": 5,
"results": [
{
"title": "AI Breakthrough in December 2024",
"url": "https://example.com/article",
"snippet": "Researchers achieved..."
}
]
},
"status": "success"
}
]
}

Step 3: Data Analysis

Agent processes the dataset:

analysis_query = """
Analyze this dataset and provide insights:
- Load the sales data
- Calculate key metrics (mean, median, std dev)
- Identify trends and patterns
- Generate summary statistics
- Suggest visualizations
"""

Response:

{
"tool_calls": [
{
"tool_name": "code_execution",
"parameters": {
"code": "analysis_query"
},
"result": {
"output": "Sales statistics calculated...",
"data_points": 100,
"visualizations": 2,
"insights": [
"Sales trend is upward",
"Average sale: $1500"
]
},
"status": "success"
}
]
}

Step 4: Synthesis

Agent combines all tool results into final answer:

{
"response": "Here's a comprehensive report based on your request:\n\n\n" +
"## API Configuration\n\n" +
"According to our internal documentation, API keys can be created via the web interface or programmatically. Key settings include model access, budget limits, and permissions. The system generates keys with the 'en_' prefix for easy identification.\n\n\n" +
"## AI Developments\n\n" +
"Recent AI developments include breakthroughs in language models and applications. For example, in December 2024, significant advancements were announced in areas like...\n\n" +
"## Data Analysis\n\n" +
"The sales dataset shows an upward trend with an average of $1,500/month and standard deviation of $250. Recommendations include focusing on Q4 marketing activities and customer retention programs.\n\n\n" +
"Sources:\n" +
"- Internal documentation (Section: API Configuration)\n" +
"- Web search (Section: AI Developments)\n\n" +
"- Sales data analysis (Section: Data Analysis)"
}

Tool Orchestration

Agent automatically decides which tools to use and in which order:

# Agent's reasoning (in response)
reasoning = "To answer this query, I'll:\n" +
"1. Search our documentation for API configuration details\n" +
"2. Search the web for latest AI developments\n" +
"3. Analyze the provided sales data\n" +
"Each tool will provide information that I'll synthesize into a comprehensive answer."

Tool Choice Strategy

StrategyWhen to Use
autoGeneral purpose
requiredData analysis
noneSimple Q&A

Advanced Patterns

Parallel Tool Execution

Execute independent tools in parallel:

import asyncio
import requests

async def execute_tools_parallel():
tools = [
{
"tool_name": "rag_search",
"parameters": {"query": "API configuration"}
},
{
"tool_name": "web_search",
"parameters": {"query": "AI news 2024"}
}
]

# Execute tools in parallel
tasks = [
asyncio.create_task(requests.post, url, headers, json=tool)
for tool in tools
]

results = await asyncio.gather(*tasks)

for result in results:
print(f"Tool: {result.json()['tool_name']}")
print(f"Status: {result.json()['status']}")

Conditional Tool Chains

Use results from one tool to inform the next:

# Step 1: Search
rag_results = execute_tool("rag_search", {
"query": "competitor pricing"
})

# Step 2: Conditional action
if not rag_results["results"]:
# No docs found, use web search instead
web_results = execute_tool("web_search", {
"query": "competitor pricing"
)
else:
# Docs found, get additional info with web search
web_results = execute_tool("web_search", {
"query": f"{rag_results['query']} latest pricing"
})

Error Handling

Tool Failure Handling

def execute_with_retry(tool_config, max_retries=3):
for attempt in range(max_retries):
try:
response = requests.post(
"http://localhost/api/v1/tools/execute",
headers={"Authorization": "Bearer YOUR_API_KEY"},
json=tool_config
)

if response.status_code == 200:
return response.json()

except Exception as e:
print(f"Attempt {attempt + 1} failed: {e}")
if attempt < max_retries - 1:
time.sleep(2 ** attempt)
else:
raise Exception("Max retries exceeded")

Best Practices

System Prompt Design

Provide clear guidance for multi-step tasks:

Good:

"""
You are a multi-step research and analysis assistant. Your capabilities include:

1. Information Retrieval
- Use RAG search to find relevant internal documents
- Use web search for current information
- Use code execution to process data

2. Analysis
- Process and analyze data using code execution
- Generate insights and statistics
- Create visualizations

3. Synthesis
- Combine information from all tools
- Provide comprehensive, well-structured answers
- Cite all sources clearly

When multi-step tasks are required, break them down into logical steps. Use tools efficiently and track your progress. Always explain your reasoning to the user.
"""

Tool Usage Optimization

  • Batch Independent Tools: When tools don't depend on each other, execute in parallel
  • Minimize Round Trips: Provide all context needed upfront
  • Cache Results: Cache expensive tool outputs (web search, RAG results)
  • Filter Results: Reduce data passed to LLM by setting appropriate thresholds

Performance Considerations

  • Timeout Management: Set appropriate timeouts per tool
  • Resource Limits: Be aware of code execution memory and compute limits
  • Cost Awareness: Track usage of web search and external APIs

Next Steps