Building with AI Agents: A Practical Guide Inspired by Spotify & Anthropic
Overview
The recent live conversation between Spotify and Anthropic engineers highlighted a major shift in software development: the rise of agentic development. Instead of coding every decision path, developers now orchestrate autonomous AI agents that plan, execute, and adapt. This tutorial distills key insights from that event into a hands-on guide for building your own AI agents. You'll learn how to design agent workflows, integrate with APIs (like Spotify's), and avoid common pitfalls — all while keeping control and observability.

Prerequisites
Before we begin, ensure you have:
- Basic understanding of Python (or any modern programming language)
- Familiarity with REST APIs and JSON
- An OpenAI or Anthropic API key (for the language model component)
- Python 3.8+ installed locally
pippackages:requests,pydantic,asyncio
Optionally, a Spotify Developer account to experiment with their API endpoints (not required for the core agent logic).
Step-by-Step Guide to Agentic Development
Step 1: Define Your Agent's Goal and Scope
Every agent starts with a clear objective. During the Spotify x Anthropic live session, they demonstrated an agent that curates playlists based on user mood. Your first task is to write a short prompt that describes the agent's purpose, constraints, and output format. Example:
"You are a playlist curator agent. Given a user's current mood (e.g., happy, sad, energetic), recommend 10 songs with title, artist, and a short reason. Use the Spotify API to fetch real data."
Store this as a system message in your LLM call.
Step 2: Build the Core Agent Loop
Create a Python script that repeatedly calls the LLM with conversation history. The LLM will output either a final answer or a tool-call instruction. Use Pydantic models to parse structured tool calls.
from pydantic import BaseModel
from typing import Literal
class ToolCall(BaseModel):
name: str
arguments: dict
class AgentResponse(BaseModel):
content: str | None = None
tool_call: ToolCall | None = None
In the loop, send the history to the LLM, parse the response, and if a tool call is detected, execute it and feed the result back.
Step 3: Implement Tool Functions
Tools are the agent's hands in the world. For a Spotify agent, you might need:
search_track(query: str) -> listget_artist_info(artist_id: str) -> dictcreate_playlist(name: str, tracks: list) -> str
Each function should include a docstring that the LLM can understand. Example using requests:
def search_track(query: str) -> list:
"""Search Spotify for tracks matching query. Returns up to 5 results."""
headers = {"Authorization": f"Bearer {access_token}"}
params = {"q": query, "type": "track", "limit": 5}
resp = requests.get("https://api.spotify.com/v1/search", headers=headers, params=params)
return resp.json().get("tracks", {}).get("items", [])
Register all tools in a dictionary so the agent can look them up by name.
Step 4: Orchestrate the Reasoning Loop
Create an asynchronous loop that:
- Appends the user query to the message history.
- Calls the LLM (e.g., GPT-4 or Claude) with the system prompt and history.
- If the response contains a function call, execute it and append the result.
- Repeat until the LLM returns a final text answer or reaches a max iteration limit (e.g., 10).
async def run_agent(user_input: str) -> str:
messages = [{"role": "system", "content": SYSTEM_PROMPT}]
messages.append({"role": "user", "content": user_input})
for _ in range(MAX_ITERATIONS):
response = await llm_call(messages)
if response.content:
return response.content
# handle tool call
result = execute_tool(response.tool_call)
messages.append({"role": "assistant", "content": None, "tool_calls": [...]})
messages.append({"role": "tool", "tool_call_id": ..., "content": json.dumps(result)})
return "Agent exceeded iteration limit."
This pattern mirrors what the Spotify team demonstrated: an agent that reasons, acts, and learns from intermediate results.

Step 5: Add Observability and Safety
Anthropic's engineers emphasized the need for monitoring. Log every LLM call, tool execution, and decision. Use structured logging:
import structlog
logger = structlog.get_logger()
async def execute_tool(tool_call):
logger.info("Executing tool", name=tool_call.name, arguments=tool_call.arguments)
try:
result = TOOL_REGISTRY[tool_call.name](**tool_call.arguments)
logger.info("Tool succeeded", result=result)
return result
except Exception as e:
logger.error("Tool failed", error=str(e))
return {"error": str(e)}
Set rate limits and budget constraints to prevent runaway costs. Also, implement a “human-in-the-loop” for sensitive actions like writing files or deleting data.
Common Mistakes
1. Over‑engineering the Prompt
Many beginners write extremely long system prompts with contradictory rules. Keep it concise: define the agent's role, available tools, and output format. Let the LLM reason naturally.
2. Ignoring Tool Error Handling
When an API call fails (e.g., Spotify rate-limits), the agent should receive a clear error message and try an alternative approach (e.g., fallback search). Always return structured errors.
3. Infinite Loops
Without a maximum iteration limit, an agent can loop forever calling the same tool. Enforce a counter and force finalization after, say, 10 steps.
4. Not Validating Tool Arguments
The LLM may generate invalid arguments (e.g., missing required fields). Use Pydantic models to validate arguments before execution, and return a validation error to the agent so it can self‑correct.
5. Missing Context Management
As the conversation grows, the token count can explode. Implement truncation strategies: summarize older messages or drop less relevant ones while preserving the user's goal and key results.
Summary
Agentic development transforms static programs into autonomous problem‑solvers. By following the Spotify x Anthropic blueprint, you can build an agent that plans, uses tools, and iterates until it reaches a useful outcome. Start small — one agent, one clear goal — then add tools and constraints. Monitor everything, handle errors gracefully, and always keep a human in the loop for critical actions. The future of software is cooperative: you code the framework, the agent codes the path.
Related Articles
- Building Rock-Solid UIs for Real-Time Streaming Content
- Pausing Apple Watch Activity Rings in watchOS 26: Your Complete Q&A Guide
- Mastering Hypertension Monitoring on Apple Watch with watchOS 26: A Complete Setup Guide
- Everything You Need to Know About Avatar: Fire and Ash Hitting Disney Plus
- Apple Watch Series 11 Hits Record Low of $399 on Amazon – M5 MacBook Air and AirPods Also Slashed
- Top Picks: 4 Must-Watch Paramount+ Movies for Your Week (May 11–17)
- Best Apple Deals: M5 MacBook Air, iPad Air, MacBook Pro, and Apple Watch Series 11 at Record Low Prices
- Avatar: Fire and Ash Disney+ Release Date Announced – Everything You Need to Know