正在加载,请稍候…

OpenAI API Integration: Chat Completions, Streaming, and Function Calling

Integrate OpenAI API into your application. Learn chat completions, streaming responses, function calling, embeddings, and cost optimization strategies.

OpenAI API Integration Guide

Setup

import OpenAI from 'openai';

const openai = new OpenAI({
  apiKey: process.env.OPENAI_API_KEY,
  timeout: 30000,
  maxRetries: 3,
});

Chat Completions

async function chat(userMessage: string): Promise<string> {
  const response = await openai.chat.completions.create({
    model: 'gpt-4o',
    messages: [
      {
        role: 'system',
        content: 'You are a helpful assistant that answers questions concisely.',
      },
      {
        role: 'user',
        content: userMessage,
      },
    ],
    temperature: 0.7,
    max_tokens: 1000,
  });

  return response.choices[0].message.content ?? '';
}

// Multi-turn conversation
interface Message {
  role: 'system' | 'user' | 'assistant';
  content: string;
}

class ChatSession {
  private messages: Message[] = [];

  constructor(systemPrompt: string) {
    this.messages = [{ role: 'system', content: systemPrompt }];
  }

  async send(userMessage: string): Promise<string> {
    this.messages.push({ role: 'user', content: userMessage });

    const response = await openai.chat.completions.create({
      model: 'gpt-4o',
      messages: this.messages,
    });

    const assistantMessage = response.choices[0].message.content ?? '';
    this.messages.push({ role: 'assistant', content: assistantMessage });

    return assistantMessage;
  }
}

Streaming Responses

// Stream completions for better UX
async function streamChat(userMessage: string, onChunk: (text: string) => void): Promise<void> {
  const stream = await openai.chat.completions.create({
    model: 'gpt-4o',
    messages: [{ role: 'user', content: userMessage }],
    stream: true,
  });

  for await (const chunk of stream) {
    const content = chunk.choices[0]?.delta?.content;
    if (content) {
      onChunk(content);
    }
  }
}

// Next.js API route with streaming
export async function POST(req: Request) {
  const { message } = await req.json();

  const stream = await openai.chat.completions.create({
    model: 'gpt-4o',
    messages: [{ role: 'user', content: message }],
    stream: true,
  });

  const readable = new ReadableStream({
    async start(controller) {
      for await (const chunk of stream) {
        const text = chunk.choices[0]?.delta?.content || '';
        controller.enqueue(new TextEncoder().encode(text));
      }
      controller.close();
    },
  });

  return new Response(readable, {
    headers: { 'Content-Type': 'text/plain; charset=utf-8' },
  });
}

Function Calling (Tool Use)

const tools: OpenAI.Chat.ChatCompletionTool[] = [
  {
    type: 'function',
    function: {
      name: 'get_weather',
      description: 'Get current weather for a city',
      parameters: {
        type: 'object',
        properties: {
          city: { type: 'string', description: 'City name' },
          unit: { type: 'string', enum: ['celsius', 'fahrenheit'] },
        },
        required: ['city'],
      },
    },
  },
];

async function chatWithTools(userMessage: string): Promise<string> {
  const messages: OpenAI.Chat.ChatCompletionMessageParam[] = [
    { role: 'user', content: userMessage }
  ];

  const response = await openai.chat.completions.create({
    model: 'gpt-4o',
    messages,
    tools,
    tool_choice: 'auto',
  });

  const assistantMessage = response.choices[0].message;
  messages.push(assistantMessage);

  // Handle tool calls
  if (assistantMessage.tool_calls) {
    for (const toolCall of assistantMessage.tool_calls) {
      const args = JSON.parse(toolCall.function.arguments);
      let result: unknown;

      if (toolCall.function.name === 'get_weather') {
        result = await getWeather(args.city, args.unit);
      }

      messages.push({
        role: 'tool',
        tool_call_id: toolCall.id,
        content: JSON.stringify(result),
      });
    }

    // Get final response with tool results
    const finalResponse = await openai.chat.completions.create({
      model: 'gpt-4o',
      messages,
    });
    return finalResponse.choices[0].message.content ?? '';
  }

  return assistantMessage.content ?? '';
}

Embeddings

async function embed(texts: string[]): Promise<number[][]> {
  const response = await openai.embeddings.create({
    model: 'text-embedding-3-small',
    input: texts,
  });
  return response.data.map(d => d.embedding);
}

function cosineSimilarity(a: number[], b: number[]): number {
  const dot = a.reduce((sum, ai, i) => sum + ai * b[i], 0);
  const normA = Math.sqrt(a.reduce((sum, ai) => sum + ai * ai, 0));
  const normB = Math.sqrt(b.reduce((sum, bi) => sum + bi * bi, 0));
  return dot / (normA * normB);
}

Cost Optimization

// Track token usage
const response = await openai.chat.completions.create({ /* ... */ });
const { prompt_tokens, completion_tokens, total_tokens } = response.usage!;
console.log(`Tokens used: ${total_tokens} (cost: ~${total_tokens / 1000 * 0.005})`);

// Use cheaper models for simple tasks
const model = userMessage.length < 100 ? 'gpt-4o-mini' : 'gpt-4o';

// Cache repeated requests
const cache = new Map<string, string>();
async function cachedChat(message: string): Promise<string> {
  const key = hashMessage(message);
  if (cache.has(key)) return cache.get(key)!;
  const result = await chat(message);
  cache.set(key, result);
  return result;
}

Always implement retry logic and cost monitoring when building production LLM applications.