Building AI Features with OpenAI API

Add AI capabilities to your apps. A practical guide to the OpenAI API.

Getting Started

Sign up at platform.openai.com, get an API key.

npm install openai
const OpenAI = require('openai');

const openai = new OpenAI({
  apiKey: process.env.OPENAI_API_KEY
});

Basic Chat Completion

async function chat(userMessage) {
  const response = await openai.chat.completions.create({
    model: 'gpt-4-turbo-preview',
    messages: [
      { role: 'system', content: 'You are a helpful assistant.' },
      { role: 'user', content: userMessage }
    ]
  });
  
  return response.choices[0].message.content;
}

// Usage
const answer = await chat('What is JavaScript?');

Conversation History

Maintain context across messages:

const conversationHistory = [
  { role: 'system', content: 'You are a helpful coding assistant.' }
];

async function chat(userMessage) {
  conversationHistory.push({ role: 'user', content: userMessage });
  
  const response = await openai.chat.completions.create({
    model: 'gpt-4-turbo-preview',
    messages: conversationHistory
  });
  
  const assistantMessage = response.choices[0].message.content;
  conversationHistory.push({ role: 'assistant', content: assistantMessage });
  
  return assistantMessage;
}

Streaming Responses

For better UX, stream tokens as they arrive:

async function streamChat(userMessage, onToken) {
  const stream = await openai.chat.completions.create({
    model: 'gpt-4-turbo-preview',
    messages: [{ role: 'user', content: userMessage }],
    stream: true
  });
  
  for await (const chunk of stream) {
    const token = chunk.choices[0]?.delta?.content || '';
    onToken(token);
  }
}

// Usage
await streamChat('Tell me a story', (token) => {
  process.stdout.write(token);
});

Practical Use Cases

Content Summarization

async function summarize(text) {
  return chat(`Summarize this in 2-3 sentences:\n\n${text}`);
}

Code Explanation

async function explainCode(code) {
  return chat(`Explain this code in simple terms:\n\n\`\`\`\n${code}\n\`\`\``);
}

Classification

async function classify(text, categories) {
  return chat(
    `Classify this text into one of these categories: ${categories.join(', ')}.\n\n` +
    `Text: ${text}\n\n` +
    `Respond with just the category name.`
  );
}

Cost Management

Track token usage:

const response = await openai.chat.completions.create({
  model: 'gpt-4-turbo-preview',
  messages: [{ role: 'user', content: 'Hello' }]
});

console.log('Tokens used:', response.usage);
// { prompt_tokens: 10, completion_tokens: 15, total_tokens: 25 }

Use cheaper models when possible:

  • `gpt-4-turbo-preview` - Smartest, most expensive
  • `gpt-3.5-turbo` - Cheaper, still capable
  • `gpt-3.5-turbo-instruct` - For simple completions

Error Handling

try {
  const response = await openai.chat.completions.create({/*...*/});
} catch (error) {
  if (error.status === 429) {
    // Rate limited - implement backoff
  } else if (error.status === 401) {
    // Invalid API key
  } else {
    // Other error
  }
}

Best Practices

1. **Never expose API key** - Server-side only 2. **Set max_tokens** - Prevent runaway costs 3. **Validate user input** - Prevent prompt injection 4. **Cache responses** - Same question = same answer 5. **Handle rate limits** - Implement exponential backoff

AI features are now table stakes. This is just the beginning.

Back to Journal