使用NestJS与Fastify集成OpenAI API

848 阅读2分钟

1. 引言

在现代应用开发中,对性能和可扩展性的要求越来越高。NestJS作为一个强大的Node.js框架,能够高效地构建服务端应用,而Fastify以其出色的性能表现,特别适合处理高并发的请求。结合这两者,我们可以创建一个响应迅速且功能强大的应用,集成OpenAI API实现智能对话功能。

2. 项目搭建

2.1 安装NestJS和Fastify

首先,确保你已安装Node.js环境。使用Nest CLI创建新项目:

npm install -g @nestjs/cli
nest new openai-fastify-app
cd openai-fastify-app

在项目根目录中,安装Fastify及相关包:

npm install @nestjs/platform-fastify fastify

同时,安装用于HTTP请求的axios和用于环境变量管理的dotenv

npm install axios dotenv

2.2 配置项目结构

项目结构应如下所示:

openai-fastify-app/
│
├── src/
│   ├── app.module.ts
│   ├── main.ts
│   ├── openai/
│   │   ├── openai.controller.ts
│   │   ├── openai.service.ts
│   │   └── dto/
│   │       └── create-chat.dto.ts
│   └── ...
└── .env

3. 配置环境变量

在项目根目录中创建.env文件,存储OpenAI API密钥:

OPENAI_API_KEY=your_openai_api_key

main.ts中加载环境变量:

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { FastifyAdapter, NestFastifyApplication } from '@nestjs/platform-fastify';
import * as dotenv from 'dotenv';

dotenv.config(); // 加载环境变量

async function bootstrap() {
  const app = await NestFactory.create<NestFastifyApplication>(AppModule, new FastifyAdapter());
  await app.listen(3000);
}
bootstrap();

4. 创建OpenAI服务

4.1 生成OpenAI服务

运行命令生成OpenAI服务:

nest generate service openai

4.2 编写服务逻辑

openai.service.ts中,编写与OpenAI API交互的逻辑:

import { Injectable, InternalServerErrorException } from '@nestjs/common';
import axios from 'axios';

@Injectable()
export class OpenAIService {
  private readonly apiKey: string = process.env.OPENAI_API_KEY;
  private readonly apiUrl: string = 'https://api.openai.com/v1/chat/completions';

  async getChatResponse(prompt: string): Promise<string> {
    try {
      const response = await axios.post(
        this.apiUrl,
        {
          model: 'gpt-3.5-turbo',
          messages: [{ role: 'user', content: prompt }],
        },
        {
          headers: {
            'Authorization': `Bearer ${this.apiKey}`,
            'Content-Type': 'application/json',
          },
        }
      );
      return response.data.choices[0].message.content; // 返回生成的文本
    } catch (error) {
      console.error('Error communicating with OpenAI:', error);
      throw new InternalServerErrorException('Unable to fetch response from OpenAI');
    }
  }
}

5. 创建控制器

5.1 生成控制器

运行命令生成控制器:

nest generate controller openai

5.2 定义API路由

openai.controller.ts中定义处理用户输入的路由:

import { Controller, Post, Body } from '@nestjs/common';
import { OpenAIService } from './openai.service';
import { CreateChatDto } from './dto/create-chat.dto';

@Controller('openai')
export class OpenAIController {
  constructor(private readonly openAIService: OpenAIService) {}

  @Post('chat') // 定义POST请求路由
  async chat(@Body() createChatDto: CreateChatDto): Promise<{ response: string }> {
    const { prompt } = createChatDto;
    const response = await this.openAIService.getChatResponse(prompt);
    return { response }; // 返回OpenAI生成的响应
  }
}

5.3 创建DTO

dto文件夹中创建create-chat.dto.ts,定义请求体的数据结构:

import { IsString } from 'class-validator';

export class CreateChatDto {
  @IsString()
  prompt: string;
}

6. 更新模块

确保在app.module.ts中导入OpenAI服务和控制器:

import { Module } from '@nestjs/common';
import { OpenAIService } from './openai/openai.service';
import { OpenAIController } from './openai/openai.controller';

@Module({
  imports: [],
  controllers: [OpenAIController],
  providers: [OpenAIService],
})
export class AppModule {}

7. 启动应用

使用以下命令启动NestJS应用:

npm run start

8. 测试API

使用Postman或类似工具向http://localhost:3000/openai/chat发送POST请求,JSON请求体如下:

{
  "prompt": "Hello, how can I integrate OpenAI with NestJS?"
}

如果一切正常,响应将类似于:

{
  "response": "To integrate OpenAI with NestJS, you can create a service that communicates with the OpenAI API..."
}

9. 性能优化与安全性

9.1 Fastify的优势

Fastify具有高性能和低开销的特点,特别适合处理大量请求。通过使用Fastify,你可以在高并发场景下提升应用的响应速度。

9.2 安全性考虑

在与OpenAI API交互时,确保API密钥的安全性至关重要。以下是一些最佳实践:

9.2.1 使用环境变量管理

确保API密钥不在代码中硬编码,而是通过环境变量存储。

9.2.2 访问控制

设置允许访问API的IP地址,使用API网关(如AWS API Gateway)管理流量。

9.2.3 速率限制

实现请求速率限制,防止API滥用。可以使用Fastify的fastify-rate-limit插件:

npm install fastify-rate-limit

main.ts中注册速率限制插件:

import fastifyRateLimit from 'fastify-rate-limit';

async function bootstrap() {
  const app = await NestFactory.create<NestFastifyApplication>(AppModule, new FastifyAdapter());
  app.register(fastifyRateLimit, {
    max: 100, // 每个IP每分钟最多请求次数
    timeWindow: '1 minute',
  });
  await app.listen(3000);
}

9.3 启用请求压缩

通过启用请求和响应的压缩,可以提高数据传输速度,减小带宽使用:

npm install fastify-compress

main.ts中注册压缩插件:

import fastifyCompress from 'fastify-compress';

async function bootstrap() {
  const app = await NestFactory.create<NestFastifyApplication>(AppModule, new FastifyAdapter());
  app.register(fastifyCompress);
  await app.listen(3000);
}

10. 扩展功能

10.1 用户上下文管理

可以通过管理用户的上下文信息,使对话更加自然。例如,存储用户的历史对话,在后续请求中引用上下文。

10.2 反馈机制

为用户提供反馈机制,让他们能够对AI的回答进行评价。你可以在控制器中添加反馈路由,记录用户的反馈。

@Post('feedback')
async feedback(@Body() feedbackDto: FeedbackDto): Promise<void> {
  // 记录反馈的逻辑
}

10.3 多语言支持

利用OpenAI的翻译能力,增加多语言支持,用户可以选择输入语言和输出语言。

10.4 任务自动化

结合OpenAI的生成能力,可以自动生成日常工作报告、邮件草稿等,提升工作效率。

11. 未来的应用前景

结合NestJS、Fastify与OpenAI的能力,未来的应用可能包括:

11.1 智能客服

构建智能客服系统,能够回答常见问题,提供全天候支持。

11.2 个性化推荐

使用用户行为数据和OpenAI生成个性化内容,如电商产品推荐。

11.3 教育辅助

在教育平台中,提供智能学习助手,根据学生需求生成学习材料。

11.4 医疗应用

开发医疗辅助工具 ,能够根据患者输入生成健康建议或解答医学问题,帮助医生做出更准确的决策。

12. 结论

通过将NestJS、Fastify和OpenAI API结合,我们构建了一个高效的智能应用。在这篇文章中,我们详细介绍了项目的配置、OpenAI服务的实现、API的路由设置、性能优化以及潜在的扩展功能。随着AI技术的快速发展,NestJS和Fastify的结合将为开发者提供一个强大的平台,助力创建更加智能和响应迅速的应用。

13. 代码完整性

为了方便你进行参考,这里是完整的代码结构:

main.ts

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { FastifyAdapter, NestFastifyApplication } from '@nestjs/platform-fastify';
import * as dotenv from 'dotenv';
import fastifyCompress from 'fastify-compress';
import fastifyRateLimit from 'fastify-rate-limit';

dotenv.config();

async function bootstrap() {
  const app = await NestFactory.create<NestFastifyApplication>(AppModule, new FastifyAdapter());
  app.register(fastifyCompress);
  app.register(fastifyRateLimit, {
    max: 100,
    timeWindow: '1 minute',
  });
  await app.listen(3000);
}
bootstrap();

openai.service.ts

import { Injectable, InternalServerErrorException } from '@nestjs/common';
import axios from 'axios';

@Injectable()
export class OpenAIService {
  private readonly apiKey: string = process.env.OPENAI_API_KEY;
  private readonly apiUrl: string = 'https://api.openai.com/v1/chat/completions';

  async getChatResponse(prompt: string): Promise<string> {
    try {
      const response = await axios.post(
        this.apiUrl,
        {
          model: 'gpt-3.5-turbo',
          messages: [{ role: 'user', content: prompt }],
        },
        {
          headers: {
            'Authorization': `Bearer ${this.apiKey}`,
            'Content-Type': 'application/json',
          },
        }
      );
      return response.data.choices[0].message.content;
    } catch (error) {
      console.error('Error communicating with OpenAI:', error);
      throw new InternalServerErrorException('Unable to fetch response from OpenAI');
    }
  }
}

openai.controller.ts

import { Controller, Post, Body } from '@nestjs/common';
import { OpenAIService } from './openai.service';
import { CreateChatDto } from './dto/create-chat.dto';

@Controller('openai')
export class OpenAIController {
  constructor(private readonly openAIService: OpenAIService) {}

  @Post('chat')
  async chat(@Body() createChatDto: CreateChatDto): Promise<{ response: string }> {
    const { prompt } = createChatDto;
    const response = await this.openAIService.getChatResponse(prompt);
    return { response };
  }
}

dto/create-chat.dto.ts

import { IsString } from 'class-validator';

export class CreateChatDto {
  @IsString()
  prompt: string;
}

app.module.ts

import { Module } from '@nestjs/common';
import { OpenAIService } from './openai/openai.service';
import { OpenAIController } from './openai/openai.controller';

@Module({
  imports: [],
  controllers: [OpenAIController],
  providers: [OpenAIService],
})
export class AppModule {}

14. 进一步学习资源

如果你希望更深入地了解NestJS、Fastify和OpenAI API,可以参考以下资源:

通过这些资源,你可以掌握更高级的用法,优化你的应用,并探索更多的可能性。