In today’s world of AI-powered applications, integrating large language models into your backend services has become increasingly important. Let’s explore how to integrate Claude, Anthropic’s advanced AI model, with a Node.js application. I’ll share what I learned while implementing this integration in a production environment.
The Context
The integration uses Node.js, so we’ll stick to the JavaScript/TypeScript ecosystem. After researching various approaches, I found that Anthropic provides an official Node.js client library that makes the integration straightforward. The library handles authentication, rate limiting, and proper formatting of requests to Claude’s API.
First, let’s install the necessary dependency:
npm install @anthropic-ai/sdk
# or if you're using yarn
yarn add @anthropic-ai/sdk
BashGetting Started
I like to approach development incrementally. Here’s how to set up a basic integration with Claude:
const { Anthropic } = require('@anthropic-ai/sdk');
// Initialize the client with your API key
const anthropic = new Anthropic({
apiKey: process.env.ANTHROPIC_API_KEY,
});
async function askClaude(prompt) {
try {
const message = await anthropic.messages.create({
model: 'claude-3-sonnet-20240229',
max_tokens: 1024,
messages: [{
role: 'user',
content: prompt
}]
});
return message.content[0].text;
} catch (error) {
console.error('Error calling Claude:', error);
throw error;
}
}
JavaScriptLet’s break down the key components:
- We import the Anthropic SDK and initialize it with our API key.
- The
askClaude
function creates a new message using Claude’s chat API. - We specify the model (in this case, Claude 3 Sonnet) and set a max token limit.
- The response includes the AI’s reply in the content field.
Building a Simple Express API
Let’s create a simple REST API that uses Claude:
const express = require('express');
const { Anthropic } = require('@anthropic-ai/sdk');
const app = express();
app.use(express.json());
const anthropic = new Anthropic({
apiKey: process.env.ANTHROPIC_API_KEY,
});
app.post('/api/chat', async (req, res) => {
try {
const { prompt } = req.body;
const message = await anthropic.messages.create({
model: 'claude-3-sonnet-20240229',
max_tokens: 1024,
messages: [{
role: 'user',
content: prompt
}]
});
res.json({
response: message.content[0].text
});
} catch (error) {
console.error('Error:', error);
res.status(500).json({
error: 'Failed to process request'
});
}
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
JavaScriptHandling Multi-Turn Conversations
One of Claude’s powerful features is its ability to maintain context in conversations. Here’s how to implement a stateful chat:
class ConversationManager {
constructor() {
this.anthropic = new Anthropic({
apiKey: process.env.ANTHROPIC_API_KEY,
});
this.conversations = new Map();
}
async continueConversation(sessionId, userMessage) {
let conversation = this.conversations.get(sessionId) || [];
// Add user's message to the conversation history
conversation.push({
role: 'user',
content: userMessage
});
try {
const response = await this.anthropic.messages.create({
model: 'claude-3-sonnet-20240229',
max_tokens: 1024,
messages: conversation
});
// Add Claude's response to the conversation history
conversation.push({
role: 'assistant',
content: response.content[0].text
});
// Update the conversation in our store
this.conversations.set(sessionId, conversation);
return response.content[0].text;
} catch (error) {
console.error('Error in conversation:', error);
throw error;
}
}
}
JavaScriptBest Practices and Error Handling
When working with Claude in production, consider these best practices:
- Rate Limiting: Implement rate limiting to avoid hitting API limits:
const rateLimit = require('express-rate-limit');
const apiLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100 // limit each IP to 100 requests per windowMs
});
app.use('/api/', apiLimiter);
JavaScript2. Environment Variables: Keep your API key secure using environment variables:
require('dotenv').config();
if (!process.env.ANTHROPIC_API_KEY) {
throw new Error('ANTHROPIC_API_KEY is required');
}
JavaScript3. Timeout Handling: Add timeouts to prevent hanging requests:
const timeout = require('connect-timeout');
app.use(timeout('30s'));
app.use(haltOnTimedout);
function haltOnTimedout(req, res, next) {
if (!req.timedout) next();
}
JavaScriptConclusion
Integrating Claude with Node.js opens up powerful possibilities for building AI-enhanced applications. The official SDK makes it straightforward to get started, while proper error handling and best practices ensure your integration is production-ready.
Remember to:
- Keep your API keys secure
- Implement proper error handling
- Consider rate limiting for production use
- Handle conversation state appropriately
- Monitor API usage and costs
The code examples provided here should give you a solid foundation for building your own Claude-powered applications with Node.js.