An AI-powered multi-agent system that creates personalized Spotify playlists through natural conversation. Built on the Fetch.ai uagents framework, accessible via ASI:One chat.
A user chats with the orchestrator on ASI:One. The orchestrator β powered by an LLM β decides which specialized agents to involve based on the request. Each agent handles one part of the playlist creation process:
User: "make me a chill playlist for studying"
Orchestrator (LLM-powered)
|
|-- decides: need user's taste --> SpotifyAgent
|-- decides: analyze taste --> TasteAgent
|-- decides: parse request --> ContextAgent
|-- decides: find songs --> DiscoveryAgent
|-- decides: build playlist --> PlaylistAgent
|
v
User gets a playlist + it's created on their Spotify account
The orchestrator doesn't follow a fixed pipeline β it reasons about each request:
- "make me a playlist based on my taste" -> runs all 5 agents
- "give me Frank Ocean and Tyler the Creator songs" -> skips Spotify/Taste, goes straight to Context -> Discovery -> Playlist
- "edm playlist" -> skips Spotify/Taste, searches by genre
| Agent | Role | Port |
|---|---|---|
| Orchestrator | LLM-powered router, decides which agents to call and in what order | 8003 |
| SpotifyAgent | Fetches user's top 15 artists and top 50 tracks from Spotify | 8004 |
| TasteAgent | Uses LLM to analyze the user's listening profile β genres, energy, vibe | 8005 |
| ContextAgent | Uses LLM to parse the user's request β mood, activity, genre, artists, playlist name, track count | 8006 |
| DiscoveryAgent | Searches Spotify for tracks based on taste + context, with artist-level filtering | 8007 |
| PlaylistAgent | Formats the playlist and creates it on the user's Spotify account | 8008 |
| Auth Server | Handles per-user Spotify OAuth so each user connects their own account | 9999 |
- Python 3.12
- A Spotify Developer app (https://developer.spotify.com/dashboard)
- An OpenAI API key
- An Agentverse account (https://agentverse.ai)
- An ASI:One account (https://asi1.ai)
cp .env.example .envFill in your .env:
ORCHESTRATOR_SEED_PHRASE=<random string>
SPOTIFY_SEED_PHRASE=<random string>
TASTE_SEED_PHRASE=<random string>
CONTEXT_SEED_PHRASE=<random string>
DISCOVERY_SEED_PHRASE=<random string>
PLAYLIST_SEED_PHRASE=<random string>
SPOTIFY_CLIENT_ID=<from Spotify Developer Dashboard>
SPOTIFY_CLIENT_SECRET=<from Spotify Developer Dashboard>
SPOTIFY_REDIRECT_URI=http://127.0.0.1:9999/callback
OPENAI_API_KEY=<your key>
python3.12 -m venv .venv
source .venv/bin/activate
pip install -r agents/requirements.txt
pip install spotipy openai google-genai.venv/bin/python get_spotify_token.pyThis opens your browser, you log into Spotify, and the token + refresh token auto-save to .env. The refresh token doesn't expire, so future runs auto-refresh without the browser.
Each agent runs in its own terminal from the project root:
make orchestrator
make spotify
make taste
make context
make discovery
make playlist
make auth- Open each agent's inspector URL (printed in the terminal when it starts)
- Click Connect on each one
- Select Mailbox
- On the orchestrator's inspector, click Go to Agent Profile
- Click Chat with Agent
make me a chill playlist for studying
give me 20 hype workout songs
create a playlist of Frank Ocean and Tyler the Creator named "vibez"
edm playlist, 15 songs, named "rave mode"
generate a sad playlist based on my music taste
- Fetch.ai uagents β agent framework, Agentverse registration, ASI:One chat
- Spotify Web API β user profiles, track search, playlist creation
- OpenAI GPT-4o-mini β orchestrator routing, taste analysis, context parsing
- spotipy β Spotify SDK
- Python 3.12
- Agentic orchestration: The orchestrator uses an LLM to decide which agents to call, not a hardcoded pipeline. It can skip agents, and tracks call history to prevent loops.
- Per-user OAuth: Each user connects their own Spotify account via the auth server. Tokens are stored per user and auto-refresh.
- Failsafe design: Every agent falls back gracefully β expired tokens auto-refresh, API failures fall back to mock data, LLM failures fall back to keyword parsing.