Build / AI /

AI API Connections

Connect Node.js and TypeScript applications to modern AI APIs using official SDK clients and secure environment authentication.

TL;DR

  1. Initialize official SDK clients using secure process.env credential keys.
  2. Specify explicit max_tokens limits to avoid unexpected generation costs.
  3. Extract generated response text from the choices or content array.

Client Initialization

    OpenAI Client

    Instantiate official OpenAI client with environment credentials.

    import OpenAI from 'openai';
    
    const openai = new OpenAI({
      apiKey: process.env.OPENAI_API_KEY,
    });
    Anthropic Client

    Initialize Anthropic SDK client reading standard environment keys.

    import Anthropic from '@anthropic-ai/sdk';
    
    const anthropic = new Anthropic({
      apiKey: process.env.ANTHROPIC_API_KEY,
    });
    Request Timeout

    Configure explicit request timeout using AbortSignal controllers.

    const ctrl = new AbortController();
    const t = setTimeout(() => ctrl.abort(), 15000);
    // Pass { signal: ctrl.signal } to request

Standard Message Payloads

    OpenAI Chat Payload

    Send standard chat messages array with role definitions.

    const res = await openai.chat.completions.create({
      model: 'gpt-4o',
      messages: [
        { role: 'system', content: 'Be concise.' },
        { role: 'user', content: 'Define closure.' }
      ],
      max_tokens: 250,
    });
    Anthropic Message Payload

    Send Anthropic messages with separate top-level system parameter.

    const res = await anthropic.messages.create({
      model: 'claude-3-5-sonnet-20241022',
      max_tokens: 250,
      system: 'Be concise.',
      messages: [{ role: 'user', content: 'Define DNS' }]
    });
    Temperature Setting

    Tune randomness between deterministic logic and creative generation.

    const deterministic = { temperature: 0.1 };
    const creative = { temperature: 0.8 };
    // Low temperature preserves factual accuracy

Response Parsing

    Extract OpenAI Text

    Read generated text from first completion choice safely.

    const msg = res.choices[0]?.message;
    const text = msg?.content ?? '';
    const finishReason = res.choices[0]?.finish_reason;
    Extract Claude Text

    Parse content blocks from Anthropic message response.

    const block = res.content[0];
    const text = block?.type === 'text'
      ? block.text
      : '';
    const stopReason = res.stop_reason;
    Token Usage Accounting

    Log input and output token consumption for cost accounting.

    const u = res.usage!;
    const inTokens = u.prompt_tokens;
    const outTokens = u.completion_tokens;
    console.log(`Used: ${inTokens} in / ${outTokens} out`);

Universal Provider Abstraction

    Unified Message Type

    Define portable message interface across all model providers.

    interface ChatMessage {
      role: 'system' | 'user' | 'assistant';
      content: string;
    }
    Adapter Interface

    Contract for executing vendor-agnostic chat completions.

    interface LLMAdapter {
      complete(msgs: ChatMessage[]): Promise<string>;
    }
    Factory Resolver

    Resolve active model provider based on runtime configuration.

    function getLLM(p: 'openai' | 'claude'): LLMAdapter {
      return p === 'openai'
        ? new OpenAIAdapter()
        : new ClaudeAdapter();
    }

Tips

  1. Store secret API credentials inside private process.env variables rather than committing raw authentication tokens to version control.
  2. Implement a universal adapter interface to swap between OpenAI and Anthropic models without altering core application logic.

Warnings

  1. Never expose secret API keys like OPENAI_API_KEY inside client-side browser code or public single-page script bundles.
  2. Avoid calling AI APIs synchronously without passing an AbortSignal timeout to prevent hanging connections indefinitely.

In Practice

FAQ