Introduction
In this tutorial, you'll learn how to build a custom feed algorithm using the AT Protocol (atproto) and Claude AI, inspired by Bluesky's new Attie app. You'll create a simple AI-powered feed customization system that can analyze user preferences and suggest content accordingly. This tutorial demonstrates how to leverage Bluesky's open protocol and Anthropic's Claude API to build personalized content experiences.
Prerequisites
- Basic understanding of Python programming
- Access to an Anthropic Claude API key
- Basic knowledge of REST APIs and HTTP requests
- Python libraries: requests, json, and datetime
- Bluesky account with API access (optional but recommended)
Step 1: Set Up Your Development Environment
Install Required Libraries
First, create a virtual environment and install the necessary packages:
python -m venv bluesky_env
source bluesky_env/bin/activate # On Windows: bluesky_env\Scripts\activate
pip install requests python-dotenv
Why: Creating a virtual environment isolates your project dependencies, preventing conflicts with other Python projects. The requests library will handle API communications, and python-dotenv helps manage environment variables securely.
Configure Environment Variables
Create a .env file in your project directory:
ANTHROPIC_API_KEY=your_actual_api_key_here
ATPROTO_SERVER=https://bsky.social
Why: Storing API keys in environment variables keeps them secure and prevents accidental exposure in version control systems.
Step 2: Connect to AT Protocol
Create AT Protocol Client
Create a file called atproto_client.py:
import requests
import json
from dotenv import load_dotenv
import os
load_dotenv()
class ATProtoClient:
def __init__(self):
self.server = os.getenv('ATPROTO_SERVER')
self.api_key = os.getenv('ANTHROPIC_API_KEY')
self.session = requests.Session()
def get_user_feed(self, user_did, limit=25):
url = f"{self.server}/xrpc/app.bsky.feed.getFeed"
params = {'feed': user_did, 'limit': limit}
response = self.session.get(url, params=params)
return response.json()
def get_post_content(self, post_uri):
url = f"{self.server}/xrpc/app.bsky.feed.getPostThread"
params = {'uri': post_uri}
response = self.session.get(url, params=params)
return response.json()
Why: This client handles communication with Bluesky's AT Protocol endpoints, allowing you to fetch user feeds and post details programmatically.
Step 3: Implement Claude AI Integration
Create AI Feed Analyzer
Create a file called ai_analyzer.py:
import requests
import json
from typing import List, Dict
class ClaudeFeedAnalyzer:
def __init__(self, api_key: str):
self.api_key = api_key
self.base_url = "https://api.anthropic.com/v1/messages"
def analyze_content_preferences(self, posts: List[Dict], user_profile: str) -> Dict:
prompt = f"""
Analyze these posts and user profile to determine content preferences:
User Profile: {user_profile}
Posts to analyze:
{json.dumps(posts, indent=2)}
Return a JSON object with:
- primary_topics: List of main topics
- content_tone: Positive, Neutral, or Negative
- preferred_engagement: High, Medium, Low
- suggested_feed_rules: List of rules for customizing feed
"""
headers = {
"x-api-key": self.api_key,
"anthropic-version": "2023-06-01",
"content-type": "application/json"
}
payload = {
"model": "claude-3-haiku-20240307",
"max_tokens": 1000,
"messages": [
{"role": "user", "content": prompt}
]
}
response = requests.post(self.base_url, headers=headers, json=payload)
return response.json()
Why: This class integrates with Claude to analyze user behavior and content preferences, providing insights that can be used to customize feed algorithms.
Step 4: Build Feed Customization Engine
Create Main Application
Create feed_customizer.py:
import json
from atproto_client import ATProtoClient
from ai_analyzer import ClaudeFeedAnalyzer
from dotenv import load_dotenv
import os
load_dotenv()
def main():
# Initialize clients
atproto = ATProtoClient()
claude = ClaudeFeedAnalyzer(os.getenv('ANTHROPIC_API_KEY'))
# Simulate fetching user data
user_did = "did:plc:example_user"
user_profile = "Tech enthusiast interested in AI, programming, and open source"
# Fetch recent posts
print("Fetching user feed...")
feed_data = atproto.get_user_feed(user_did, limit=10)
# Extract post content
posts = []
for post in feed_data.get('feed', []):
post_content = atproto.get_post_content(post['post']['uri'])
posts.append({
'uri': post['post']['uri'],
'text': post_content.get('thread', {}).get('post', {}).get('record', {}).get('text', ''),
'author': post_content.get('thread', {}).get('post', {}).get('author', {}),
'timestamp': post_content.get('thread', {}).get('post', {}).get('record', {}).get('createdAt', '')
})
# Analyze preferences with Claude
print("Analyzing content preferences...")
analysis = claude.analyze_content_preferences(posts, user_profile)
# Display results
print("\nFeed Analysis Results:")
print(json.dumps(analysis, indent=2))
# Generate custom feed rules
rules = analysis.get('content', {}).get('suggested_feed_rules', [])
print("\nSuggested Feed Rules:")
for rule in rules:
print(f"- {rule}")
if __name__ == "__main__":
main()
Why: This main application orchestrates the entire process, from fetching data through AT Protocol to analyzing it with Claude and generating actionable insights.
Step 5: Run the Application
Execute the Feed Customization System
Run your application:
python feed_customizer.py
Why: This executes the entire feed customization workflow, demonstrating how to integrate AT Protocol with AI analysis to create personalized content experiences.
Step 6: Extend Functionality
Add Real-time Feed Updates
Enhance your system with real-time updates:
import time
from datetime import datetime
class RealTimeFeedCustomizer:
def __init__(self, atproto_client, claude_analyzer):
self.atproto = atproto_client
self.claude = claude_analyzer
def monitor_feed_changes(self, user_did, interval_minutes=5):
while True:
print(f"{datetime.now()}: Checking for feed updates...")
# Implement your feed update logic here
time.sleep(interval_minutes * 60)
Why: Real-time monitoring allows your system to continuously adapt to user behavior and preferences, creating a truly dynamic feed experience.
Summary
This tutorial demonstrated how to build a feed customization system using Bluesky's AT Protocol and Anthropic's Claude AI. You learned to create an AT Protocol client, integrate Claude for content analysis, and build a feed customization engine. The system can analyze user behavior, understand content preferences, and generate personalized feed rules - similar to what Bluesky's Attie app accomplishes. This foundation can be extended to create more sophisticated personalization algorithms, content recommendation systems, or even complete social media client applications.



