Building the Agent End to End
From Design to Code
Now you will implement your agent using your design doc.
Step 1: Set Up Your Tools
Implement or connect each tool. Make sure each tool works.
Anatomy of a tool:
def search_tool(query, num_results=5):
"""Search the web.
Args:
query: Search terms
num_results: How many results to return
Returns:
List of dicts with 'title', 'snippet', 'url'
"""
# Your implementation
results = api_call(query, num_results)
return results
def fetch_webpage_tool(url):
"""Fetch and parse a web page.
Args:
url: The URL to fetch
Returns:
Dict with 'title', 'text', 'url'
"""
# Your implementation
page = fetch_and_parse(url)
return page
Register your tools:
tools = {
"search": search_tool,
"fetch": fetch_webpage_tool,
"summarize": summarize_tool
}
Test each tool:
# Test search
result = search_tool("python programming")
print(result) # Should be a list of dicts
# Test fetch
result = fetch_webpage_tool("https://example.com")
print(result) # Should be a dict with 'text' key
Step 2: Wire the Orchestration Loop
Implement the core loop: think, act, observe, repeat.
For agentic loop pattern:
def run_agent(query):
state = AgentState(query)
conversation = []
# System message tells the model what tools are available
system_message = f"""You are a research assistant. You have these tools:
- search: Search the web for information
- fetch: Get the full text of a webpage
- summarize: Summarize a text
Use these tools to answer the user's question: {query}
"""
for iteration in range(max_iterations):
# Think: Ask the model what to do next
response = model.chat(
system=system_message,
messages=conversation
)
# Parse the response to extract tool call
if "<tool_use>" in response:
tool_call = parse_tool_call(response)
tool_name = tool_call["name"]
params = tool_call["params"]
# Act: Call the tool
if tool_name not in tools:
result = {"error": f"Unknown tool: {tool_name}"}
else:
result = tools[tool_name](**params)
# Observe: Add to conversation
conversation.append({
"role": "assistant",
"content": response
})
conversation.append({
"role": "user",
"content": f"Tool {tool_name} returned: {json.dumps(result)}"
})
state.iteration_count += 1
else:
# Model returned a final answer
return response
return "Max iterations reached"
For predefined workflow pattern:
def run_agent_workflow(query):
state = AgentState(query)
# Step 1: Search
print("Step 1: Searching for sources...")
sources = search_tool(query, num_results=3)
state.sources = [s["url"] for s in sources]
# Step 2: Fetch and read
print("Step 2: Reading sources...")
for url in state.sources:
content = fetch_webpage_tool(url)
state.add_source(url, content["text"])
# Step 3: Summarize
print("Step 3: Summarizing findings...")
all_text = " ".join(state.facts.values())
summary = summarize_tool(all_text)
return summary
Step 3: Add State Management
Keep track of what the agent has done.
class AgentState:
def __init__(self, query):
self.query = query
self.sources = []
self.facts = {}
self.iteration_count = 0
self.total_cost = 0.0
def get_summary(self):
return f"Query: {self.query}, Sources found: {len(self.sources)}, Cost: ${self.total_cost:.2f}"
# Track state throughout the agent run
state = AgentState("What is machine learning?")
for iteration in range(max_iterations):
state.iteration_count += 1
# ... run agent step ...
print(state.get_summary())
Step 4: Add Error Handling
Do not let the agent crash. Handle errors gracefully.
from enum import Enum
class ToolError(Exception):
pass
def call_tool_safe(tool_name, params):
try:
if tool_name not in tools:
return {"error": f"Unknown tool: {tool_name}"}
result = tools[tool_name](**params)
if result is None:
return {"error": f"{tool_name} returned None"}
return result
except Exception as e:
return {"error": f"{tool_name} failed: {str(e)}"}
Step 5: Add Guardrails
Add the safety limits you designed.
class CircuitBreaker:
def __init__(self, max_iterations=15, max_cost=1.0):
self.max_iterations = max_iterations
self.max_cost = max_cost
self.iteration_count = 0
self.total_cost = 0.0
def check(self, cost):
self.iteration_count += 1
self.total_cost += cost
if self.iteration_count > self.max_iterations:
raise Exception(f"Max iterations ({self.max_iterations}) exceeded")
if self.total_cost > self.max_cost:
raise Exception(f"Cost limit (${self.max_cost}) exceeded")
# Use in agent loop
cb = CircuitBreaker(max_iterations=15, max_cost=1.0)
for iteration in range(100):
# ... call tool ...
cost = calculate_cost(result)
cb.check(cost)
Step 6: Test with Example Inputs
Run your agent on real examples. Does it work?
Good test input: "Find articles about renewable energy and summarize them."
Bad test input: "Tell me everything about everything." (too vague)
# Test your agent
query = "Find information about renewable energy"
result = run_agent(query)
print(f"Result: {result}")
print(f"State: {state.get_summary()}")
Tools for Building
LangGraph (https://langchain-ai.github.io/langgraph/) Structured orchestration. Define nodes and edges. Supports agentic loops and workflows.
OpenAI Assistants API (https://platform.openai.com/docs/assistants) Built-in agent framework. Tools are defined in JSON. The API handles the loop.
Anthropic tool use Use Claude with tool_use blocks for agent orchestration.
Common Issues and Fixes
Issue: Tool calls are not parsed correctly. Fix: Add print statements to see what the model returned. Adjust the parsing logic.
Issue: The agent picks the wrong tool. Fix: Rewrite tool descriptions. Make them more specific. Add examples.
Issue: The agent loops or gets stuck. Fix: Add max iteration limit. Add error messages that tell the model to try something different.
Issue: Outputs are too long or too short. Fix: Add constraints to the system message ("Keep responses under 100 words").
Issue: Agent is too expensive. Fix: Add cost cap. Reduce num_results in search. Use a cheaper model.
Checklist: Implementation Complete
- All tools are implemented and tested
- Orchestration loop is working
- State is tracked correctly
- Error handling is in place
- Guardrails are implemented
- Agent works on test inputs
- Cost is within budget
- Iteration count is under limit
Once you pass all checks, move to testing and evaluation.
Discussion
Sign in to comment. Your account must be at least 1 day old.