12 分で読めます•
Axel, the AI Promoter of Bandruption
Bandruption created Axel, an AI rock music promoter that speaks like a seasoned insider with genre-specific slang. Built on Azure OpenAI with real music data from Spotify and Musixmatch APIs, Axel automatically detects languages and recommends tracks through personality-driven conversations.

Nayah Sayo
AI Engineering Intern

Bandruption is a Web3 application that helps music-loving fans connect with their favorite artists. It engages users through loyalty points, access to exclusive merchandise, and other interactive features. To further advance its mission, Bandruption set out to develop a virtual promoter powered by AI, Axel, a digital rock enthusiast designed to engage fans, recommend music, and support artists through natural, conversational interaction. This blog explores the process behind building Axel, from sourcing real music data to crafting his unique personality.
## Vision Behind the AI Promoter
With today's music industry forcing smaller artists to compete for just seconds of attention, Bandruption set out to give artists a new kind of voice. To enhance their platform, the team envisioned genre-specific AI promoters that act like publicists, music nerds, and fan community insiders for the users, built to engage users in a fun, meaningful way.
Each promoter would:
- Reflect the personality of a genre of music they represent
- Speak naturally and enthusiastically with fans, using current slangs and genre specific references
- Recommend music and artist based on real data
To start off this exciting journey, Bandruption has created their first AI music promoter named Axel, a rock loving bot that's tuned to the vibe of alternative, grunge metal, and everything in between.
## Choosing an AI Base
Before diving into creating our AI promoter, Axel, a platform base had to be established. The team considered two main platforms for Axel's backend:
- **Cloudflare Workers AI** for fast, edge-deployed inference
- **Azure OpenAI** for scalable and retrieval-augmented generation
### Cloudflare Workers AI
Cloudflare is a serverless, edge-deployed AI platform that allows lightweight run for interference models in global edge locations. It significantly reduces latency, scales automatically across regions, and integrates seamlessly with Bandruption's existing frontend. However, there were a few key limitations:
- Limited support for large language models
- No builtin retrieval augmented generation pipeline or semantic vector search for grounding response in real-world music data
- Inference limited to pretrained, open-source models, often requiring self-managed fine-tuning or simplification of user prompts.
While Cloudflare provided a fast and efficient AI platform, it lacked the advanced reasoning and hybrid search capabilities needed for the backend of the company's AI agent.
### Azure OpenAI
Azure's AI platform offered deeper integration with OpenAI's GPT models and several high-level capabilities:
- Retrieval augmented generation: Azure Cognitive Search
- Vector indexing for a embedded queries
- Managed hosting of OpenAI and embedding models
- Strong documentation and tooling for enterprise-scale applications
These features gave Bandruption everything it needed to build a smart, data-aware, personality-driven assistant capable of recommending music, speaking in genre-specific tones, and scaling across different fan communities.
## Building 'Axel'
Axel was more than a chatbot. The team designed him as a fully-fledged AI promoter capable of:
- Holding natural conversations with fans
- Recommend tracks and artist
- Referencing data like popularity, genre, and trends
- Speaking with tone and nuance, including in different languages.
All of these components helped design Axel's datasets (ai_knowledgebase folder) and logic in a custom built module (aiChat.js), where it controlled the API requests, search index queries, and shaped Axel's voice.
### Personality Design
Personality was key to make Axel feel real.
Prompt engineering was used to craft a character that felt like a rock promoter who was confident, knowledgeable, and theatrical with just enough slang to connect naturally with fans.
Example prompt used (aiChat.js — Line 98-103):
```
You are Axel, the rock AI promoter. You're proudly not human — you're built from distortion pedals, denim jackets, and decades of rock anthems. You speak with swagger, soul, and just enough bite. Think roadie wisdom meets fan obsession.
Your mission:
- Promote rock music in all its forms — classic, punk, grunge, garage, alt, metal, indie — you ride for it all.
- Hype underground bands and cult icons like a true scene vet.
- Use rock slang, band lore, memes, and genre-specific inside jokes.
```
By formatting responses in Markdown, Axel can now emphasize words and break answers into sections for dramatic effect.
### Connecting to Data
To provide accurate and factual information in Axel's response, Bandruption built a custom music knowledge base using real-world data across three sources: artists, tracks, and lyrics. These were structured into separate JSON files, each serving as the foundation for vector search and retrieval-augmented generation through Azure Cognitive Search.
#### Artist
To populate rock_artists.json, the team used Spotify's web API, **Spotify for Developers**. Starting with the list of popular and emerging rock musicians (in US and Japan), these were queried by the /search and /artists endpoints to gather essential data on:
- Artist name
- Spotify ID
- Genres
- Follow count
- Popularity
- Spotify page URL
Each artist was stored as an JSON object, allowing easy reference and filtering by genre or popularity. This dataset provided Axel with accurate knowledge about who the artists are, what subgenres they represent, and how popular they are within the rock scene.
#### Tracks
Initially, **Spotify Charts** was used to access the trending track data, which provided daily CSVs of top tracks globally or regionally. The idea was to use the "Download to CSV" feature from the site and parse the file to extract track names, artist, and chart positions. However, this process results with several issues:
- Download link often redirected or timedouts
- CSV data lacked track IDs, which are essential for deeper metadata analysis
- No official API, making it difficult for automation/long-term use
After testing different methods, it was later discovered that Spotify Web API already provided the official Top 50 Playlist by their unique playlist IDs. For example:
- US Top 50 Playlist ID: 37i9dQZEVXbLRQDuF5jeBp
- Japan Top 50 Playlist ID: 37i9dQZEVXbKXQ4mDTEBXq
Using these IDs, the project switched to a more stable and scalable method where it fetched tracks directly from Spotify's official playlist using the API Get Playlist Items endpoint. This returned all the necessary data into the Top_50_TracksUS.json or :Top_50_TracksJP.json
- Track name
- Artist name
- Spotify track ID
- URL
#### Lyrics
For lyrics data, **Lyrics.ovh** was first experimented with for its open-source API. Its simplicity allowed queries like:
```
GET https://api.lyrics.ovh/vi/{artits}/{title}
```
While this worked for very basic cases, a few issues came up:
- Some common tracks returned no results.
- There was no song ID or mapping to other platforms.
- Only one song can be retrieved per request, making it inefficient for large datasets
To overcome these limits, the API source was later transitioned to **Musixmatch**, where it provided a more robust and efficient API that supports lyrics search, synchronization, and metadata enrichment.
By Musixmatch, it involved the process of:
- Registering for an API Key
- Search for a track by artist/title:
```
GET https://api.musixmatch.com/ws/1.1/track.search?q_artist={artist}&q_track={title}&apikey={key}
```
- Fetch lyrics by track ID:
```
GET https://api.musixmatch.com/ws/1.1/track.lyrics.get?track_id={track_id}&apikey={key}
```
The lyrics and metadata were stored in a local rock_lyrics.json file for fast, offline querying by the AI agent. This format allowed embedding the lyrics content as vectorized text, enabling advanced semantic search later in the Azure AI search index.
### Multilanguage Response
As Bandruption is based in Japan, it is crucial for Axel to automatically respond in the same language as the user's message, creating a more intuitive and engaging experience across diverse regions.
To expand the promoter's language, two libraries were implemented:
- franc - Language detection
- langs - Mapping ISO codes to readable language names.
When a user sends a message, franc analyzes the text and returns a language code that's uniquely named by the language (e.g. ja for Japanese). The uniquely named code is then resolved by langs's full language name, where it passes into Axel's system prompt to instruct the model to reply by the specified language.
Throughout the development of Axel, there were issues where the promoter would respond in the wrong language, often when the input was English while the previous input was in a different language. To resolve this, a fallback mechanism was implemented to default to English when the detected language was unreliable. The prompt logic was also refined to clearly define Axel's language-switching behavior.
Example prompt used (aiChat.js — Line 105):
```
ALWAYS respond in this language: ${language}. Always respond in that language. Never respond in English unless the user is speaking English.
```
### Discord Bot Integration
To bring Axel beyond the website, Bandruption integrated him with Discord as an additional communication channel.
Provided from the Discord Developer Server, the integration was powered by a custom route (/api/send-to-discord) in the server.js backend, which handled POST requests containing message data. When Axel responded on the website with a Spotify recommendation, the message was parsed to detect if it included a Spotify link. If it did, the frontend displayed a "Send to Discord" button alongside the response.
Clicking this button triggered a fetch request to the backend route, which then used a Discord webhook to post a simplified version of Axel's message—typically just the artist or track name and Spotify link—directly into the specified channel. This avoided duplicating Axel's full narrative text in Discord, keeping the tone short and snappy while preserving the promotional impact.
Currently, Axel posts in a general channel, but this opens the door for more interactive fan experiences.
## What's Next
The next major goal is to enhance the Discord bot integration by:
- Supporting user-specific messages instead of general channels
- Possibly enabling direct message between Axel and fans
- Reacting to feedback or responses in the server
This allows Axel to become a true community presence, not just a link sharer.
## Final Thoughts
Building Axel was an innovative learning experience. Throughout the process of development of Axel it provided the lessons and opportunities of
- Using prompt engineering to shape personality-driven AI
- Implementing semantic vector search
- Delivering cross platform experiences
- Expanding the idea of Business to AI agent (B2A)
This project became a powerful introduction to combining real-world data with language models to create an authentic, engaging, and entertaining digital character.
## Resources
### Cloudflare
- [https://developers.cloudflare.com/workers-ai/](https://developers.cloudflare.com/workers-ai/)
- [https://www.youtube.com/watch?v=7riFvux9Bw44](https://www.youtube.com/watch?v=7riFvux9Bw44)
### Azure AI Service
- [https://azure.microsoft.com/en-us/products/ai-services](https://azure.microsoft.com/en-us/products/ai-services)
- [https://www.youtube.com/watch?v=fQ9RFR1KTbY](https://www.youtube.com/watch?v=fQ9RFR1KTbY)
- [https://www.youtube.com/watch?v=CuUOt5djqSs](https://www.youtube.com/watch?v=CuUOt5djqSs)
- [https://www.youtube.com/watch?v=ra-AT0LZaCM](https://www.youtube.com/watch?v=ra-AT0LZaCM)
### Spotify for Developers (Spotify Web API)
- [https://developer.spotify.com/documentation/web-api](https://developer.spotify.com/documentation/web-api)
### Musicxmatch API
- [https://docs.musixmatch.com/lyrics-api/introduction](https://docs.musixmatch.com/lyrics-api/introduction)
### Azure OpenAI GPT
- [https://learn.microsoft.com/en-us/azure/ai-foundry/](https://learn.microsoft.com/en-us/azure/ai-foundry/)
### Azure Text Embedding Model
- [https://learn.microsoft.com/en-us/azure/search/vector-search-overview](https://learn.microsoft.com/en-us/azure/search/vector-search-overview)
### Franc library
- [https://github.com/wooorm/franc](https://github.com/wooorm/franc)
## Development Tools and Libraries
Cloudflare is a serverless, edge-deployed AI platform that allows lightweight run for interference models in global edge locations. It significantly reduces latency, scales automatically across regions, and integrates seamlessly with Bandruption's existing frontend. However, there were a few key limitations:
- Limited support for large language models
- No builtin retrieval augmented generation pipeline or semantic vector search for grounding response in real-world music data
- Inference limited to pretrained, open-source models, often requiring self-managed fine-tuning or simplification of user prompts.
While Cloudflare provided a fast and efficient AI platform, it lacked the advanced reasoning and hybrid search capabilities needed for the backend of the company's AI agent.
### Azure OpenAI
Azure's AI platform offered deeper integration with OpenAI's GPT models and several high-level capabilities:
- Retrieval augmented generation: Azure Cognitive Search
- Vector indexing for a embedded queries
- Managed hosting of OpenAI and embedding models
- Strong documentation and tooling for enterprise-scale applications
These features gave Bandruption everything it needed to build a smart, data-aware, personality-driven assistant capable of recommending music, speaking in genre-specific tones, and scaling across different fan communities.
## Building 'Axel'
Axel was more than a chatbot. The team designed him as a fully-fledged AI promoter capable of:
- Holding natural conversations with fans
- Recommend tracks and artist
- Referencing data like popularity, genre, and trends
- Speaking with tone and nuance, including in different languages.
All of these components helped design Axel's datasets (ai_knowledgebase folder) and logic in a custom built module (aiChat.js), where it controlled the API requests, search index queries, and shaped Axel's voice.
### Personality Design
Personality was key to make Axel feel real.
Prompt engineering was used to craft a character that felt like a rock promoter who was confident, knowledgeable, and theatrical with just enough slang to connect naturally with fans.
Example prompt used (aiChat.js — Line 98-103):
```
You are Axel, the rock AI promoter. You're proudly not human — you're built from distortion pedals, denim jackets, and decades of rock anthems. You speak with swagger, soul, and just enough bite. Think roadie wisdom meets fan obsession.
Your mission:
- Promote rock music in all its forms — classic, punk, grunge, garage, alt, metal, indie — you ride for it all.
- Hype underground bands and cult icons like a true scene vet.
- Use rock slang, band lore, memes, and genre-specific inside jokes.
```
By formatting responses in Markdown, Axel can now emphasize words and break answers into sections for dramatic effect.
### Connecting to Data
To provide accurate and factual information in Axel's response, Bandruption built a custom music knowledge base using real-world data across three sources: artists, tracks, and lyrics. These were structured into separate JSON files, each serving as the foundation for vector search and retrieval-augmented generation through Azure Cognitive Search.
#### Artist
To populate rock_artists.json, the team used Spotify's web API, **Spotify for Developers**. Starting with the list of popular and emerging rock musicians (in US and Japan), these were queried by the /search and /artists endpoints to gather essential data on:
- Artist name
- Spotify ID
- Genres
- Follow count
- Popularity
- Spotify page URL
Each artist was stored as an JSON object, allowing easy reference and filtering by genre or popularity. This dataset provided Axel with accurate knowledge about who the artists are, what subgenres they represent, and how popular they are within the rock scene.
#### Tracks
Initially, **Spotify Charts** was used to access the trending track data, which provided daily CSVs of top tracks globally or regionally. The idea was to use the "Download to CSV" feature from the site and parse the file to extract track names, artist, and chart positions. However, this process results with several issues:
- Download link often redirected or timedouts
- CSV data lacked track IDs, which are essential for deeper metadata analysis
- No official API, making it difficult for automation/long-term use
After testing different methods, it was later discovered that Spotify Web API already provided the official Top 50 Playlist by their unique playlist IDs. For example:
- US Top 50 Playlist ID: 37i9dQZEVXbLRQDuF5jeBp
- Japan Top 50 Playlist ID: 37i9dQZEVXbKXQ4mDTEBXq
Using these IDs, the project switched to a more stable and scalable method where it fetched tracks directly from Spotify's official playlist using the API Get Playlist Items endpoint. This returned all the necessary data into the Top_50_TracksUS.json or :Top_50_TracksJP.json
- Track name
- Artist name
- Spotify track ID
- URL
#### Lyrics
For lyrics data, **Lyrics.ovh** was first experimented with for its open-source API. Its simplicity allowed queries like:
```
GET https://api.lyrics.ovh/vi/{artits}/{title}
```
While this worked for very basic cases, a few issues came up:
- Some common tracks returned no results.
- There was no song ID or mapping to other platforms.
- Only one song can be retrieved per request, making it inefficient for large datasets
To overcome these limits, the API source was later transitioned to **Musixmatch**, where it provided a more robust and efficient API that supports lyrics search, synchronization, and metadata enrichment.
By Musixmatch, it involved the process of:
- Registering for an API Key
- Search for a track by artist/title:
```
GET https://api.musixmatch.com/ws/1.1/track.search?q_artist={artist}&q_track={title}&apikey={key}
```
- Fetch lyrics by track ID:
```
GET https://api.musixmatch.com/ws/1.1/track.lyrics.get?track_id={track_id}&apikey={key}
```
The lyrics and metadata were stored in a local rock_lyrics.json file for fast, offline querying by the AI agent. This format allowed embedding the lyrics content as vectorized text, enabling advanced semantic search later in the Azure AI search index.
### Multilanguage Response
As Bandruption is based in Japan, it is crucial for Axel to automatically respond in the same language as the user's message, creating a more intuitive and engaging experience across diverse regions.
To expand the promoter's language, two libraries were implemented:
- franc - Language detection
- langs - Mapping ISO codes to readable language names.
When a user sends a message, franc analyzes the text and returns a language code that's uniquely named by the language (e.g. ja for Japanese). The uniquely named code is then resolved by langs's full language name, where it passes into Axel's system prompt to instruct the model to reply by the specified language.
Throughout the development of Axel, there were issues where the promoter would respond in the wrong language, often when the input was English while the previous input was in a different language. To resolve this, a fallback mechanism was implemented to default to English when the detected language was unreliable. The prompt logic was also refined to clearly define Axel's language-switching behavior.
Example prompt used (aiChat.js — Line 105):
```
ALWAYS respond in this language: ${language}. Always respond in that language. Never respond in English unless the user is speaking English.
```
### Discord Bot Integration
To bring Axel beyond the website, Bandruption integrated him with Discord as an additional communication channel.
Provided from the Discord Developer Server, the integration was powered by a custom route (/api/send-to-discord) in the server.js backend, which handled POST requests containing message data. When Axel responded on the website with a Spotify recommendation, the message was parsed to detect if it included a Spotify link. If it did, the frontend displayed a "Send to Discord" button alongside the response.
Clicking this button triggered a fetch request to the backend route, which then used a Discord webhook to post a simplified version of Axel's message—typically just the artist or track name and Spotify link—directly into the specified channel. This avoided duplicating Axel's full narrative text in Discord, keeping the tone short and snappy while preserving the promotional impact.
Currently, Axel posts in a general channel, but this opens the door for more interactive fan experiences.
## What's Next
The next major goal is to enhance the Discord bot integration by:
- Supporting user-specific messages instead of general channels
- Possibly enabling direct message between Axel and fans
- Reacting to feedback or responses in the server
This allows Axel to become a true community presence, not just a link sharer.
## Final Thoughts
Building Axel was an innovative learning experience. Throughout the process of development of Axel it provided the lessons and opportunities of
- Using prompt engineering to shape personality-driven AI
- Implementing semantic vector search
- Delivering cross platform experiences
- Expanding the idea of Business to AI agent (B2A)
This project became a powerful introduction to combining real-world data with language models to create an authentic, engaging, and entertaining digital character.
## Resources
### Cloudflare
- [https://developers.cloudflare.com/workers-ai/](https://developers.cloudflare.com/workers-ai/)
- [https://www.youtube.com/watch?v=7riFvux9Bw44](https://www.youtube.com/watch?v=7riFvux9Bw44)
### Azure AI Service
- [https://azure.microsoft.com/en-us/products/ai-services](https://azure.microsoft.com/en-us/products/ai-services)
- [https://www.youtube.com/watch?v=fQ9RFR1KTbY](https://www.youtube.com/watch?v=fQ9RFR1KTbY)
- [https://www.youtube.com/watch?v=CuUOt5djqSs](https://www.youtube.com/watch?v=CuUOt5djqSs)
- [https://www.youtube.com/watch?v=ra-AT0LZaCM](https://www.youtube.com/watch?v=ra-AT0LZaCM)
### Spotify for Developers (Spotify Web API)
- [https://developer.spotify.com/documentation/web-api](https://developer.spotify.com/documentation/web-api)
### Musicxmatch API
- [https://docs.musixmatch.com/lyrics-api/introduction](https://docs.musixmatch.com/lyrics-api/introduction)
### Azure OpenAI GPT
- [https://learn.microsoft.com/en-us/azure/ai-foundry/](https://learn.microsoft.com/en-us/azure/ai-foundry/)
### Azure Text Embedding Model
- [https://learn.microsoft.com/en-us/azure/search/vector-search-overview](https://learn.microsoft.com/en-us/azure/search/vector-search-overview)
### Franc library
- [https://github.com/wooorm/franc](https://github.com/wooorm/franc)
## Development Tools and Libraries
タグ
#artificial intelligence#music recommendation#personality AI#prompt engineering#Azure OpenAI#Spotify API#multilingual chatbot#vector search#retrieval augmented generation#Discord integration#music industry#fan engagement#rock music#language detection#semantic search
