正在加载,请稍候…

OpenAI API 集成:聊天补全、流式响应与函数调用

学习如何将 OpenAI API 集成到应用中,涵盖聊天补全、流式响应、函数调用、嵌入向量及成本优化策略。

OpenAI API 集成:聊天补全、流式响应与函数调用

OpenAI API 集成指南

设置

import OpenAI from 'openai';

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

OpenAI API 集成:聊天补全、流式响应与函数调用示意图

聊天补全

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 ?? '';
}

// 多轮对话
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;
  }
}

OpenAI API 集成:聊天补全、流式响应与函数调用示意图

流式响应

// 流式补全以获得更好的用户体验
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 路由实现流式响应
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' },
  });
}

OpenAI API 集成:聊天补全、流式响应与函数调用示意图

函数调用(工具使用)

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);

  // 处理工具调用
  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),
      });
    }

    // 获取包含工具结果的最终响应
    const finalResponse = await openai.chat.completions.create({
      model: 'gpt-4o',
      messages,
    });
    return finalResponse.choices[0].message.content ?? '';
  }

  return assistantMessage.content ?? '';
}

嵌入向量

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);
}

成本优化

// 跟踪 token 使用量
const response = await openai.chat.completions.create({ /* ... */ });
const { prompt_tokens, completion_tokens, total_tokens } = response.usage!;
console.log(`使用的 token 数:${total_tokens}(成本:约 ${total_tokens / 1000 * 0.005})`);

// 简单任务使用更便宜的模型
const model = userMessage.length < 100 ? 'gpt-4o-mini' : 'gpt-4o';

// 缓存重复请求
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;
}

在构建生产级 LLM 应用时,务必实现重试逻辑和成本监控。