Використовуй можливості Google Gemini AI для створення резюме документів у NestJS.

Ми будемо інтегрувати API Google Gemini в наш додаток на NestJS, щоб завантажувати документи, і штучний інтелект генеруватиме їх резюме та витягуватиме ключові моменти з завантаженого документа.

Я припускаю, що ми вже знаємо, як налаштувати додаток на NestJS, тому перейдемо до створення нашого API-ключа на Google Gemini Developer console.

Перш за все, потрібно створити проєкт у Google Cloud Console. Ви можете зробити це тут: Google Cloud Console.

Після того, як ви це зробите, ви побачите список ваших проєктів, коли натиснете кнопку Get API key на Google AI Studio console.

pic

Тепер у нас є наш API-ключ

pic

Тепер час ініціалізувати Google Gemini AI у нашому додатку. Створіть файл .env у корені вашого проєкту та додайте API-ключ. Ви можете назвати його, як вам зручно. Я оберу GOOGLEAPIKEY.

Повертаємось до нашого додатку, нам потрібно встановити кілька необхідних пакетів:

npm i @nestjs/config @nestjs/platform-express @google/generative-ai

Тепер створимо новий модуль, в якому ініціалізуємо наш сервіс Google Gemini:

nest g module gemini

І

nest g service gemini

Наш модуль Gemini має виглядати ось так:

import { Global, Module } from '@nestjs/common';  
import { GeminiService } from './gemini.service';  

@Global() // Декоратор, щоб зробити модуль доступним глобально  

@Module({  
 providers: [GeminiService],  
 exports: [GeminiService],  
})  
export class GeminiModule {}

Я додав декоратор Global, щоб модуль був доступний в будь-якому модулі, без необхідності його імпортувати щоразу. (Це просто мій підхід).

В нашому файлі app.module.ts буде виглядати так:

import { Module } from '@nestjs/common';  
import { ConfigModule } from '@nestjs/config';  
import { GeminiModule } from './gemini/gemini.module';  

@Module({  
 imports: [  
 ConfigModule.forRoot({  
 isGlobal: true,  
 }),  
 GeminiModule,  
 ],  
})  
export class AppModule {}

Тепер ініціалізуємо Google generative AI у нашому сервісі Gemini ось так:

import { Injectable } from '@nestjs/common';  
import { GoogleGenerativeAI } from '@google/generative-ai';  
import { ConfigService } from '@nestjs/config';  

@Injectable()  
export class GeminiService {  
 private genAI: GoogleGenerativeAI;  

 constructor(private readonly configService: ConfigService) {  
 // Отримуємо API-ключ із змінних середовища за допомогою ConfigService  
 const apiKey = this.configService.getOrThrow('GOOGLE_API_KEY');  

 // Ініціалізуємо клієнт Google Generative AI з API-ключем  
 this.genAI = new GoogleGenerativeAI(apiKey);  
 }
// Метод для витягнення первинних інсайтів з завантаженого документа  
 async extractInsights(file: Express.Multer.File): Promise {  
 try {  
 // Отримуємо модель google, яка буде використовуватися для генерації контенту  
 const model = this.genAI.getGenerativeModel({  
 model: 'gemini-2.0-flash-exp',  
 });  

 // Витягуємо ключові інсайти з завантаженого документа  
 const result = await model.generateContent([  
 {  
 inlineData: {  
 data: file.buffer.toString('base64'),  
 mimeType: 'application/pdf',  
 },  
 },  
 'Extract key insights',  
 ]);  

 // Повертаємо текстовий результат з згенерованого контенту  
 return result.response.text();  
 } catch (error) {  
 console.error('Error generating content:', error);  
 throw new Error('Failed to extract insights');  
 }  
 }

Завантажений документ (переданий як file типу Express.Multer.File) конвертується в base64 рядок (file.buffer.toString('base64')) і поєднується з його MIME-типом (application/pdf).
Це готує документ до обробки моделлю ШІ.

Ваш код має виглядати ось так:

import { Injectable } from '@nestjs/common';  
import { GoogleGenerativeAI } from '@google/generative-ai';  
import { ConfigService } from '@nestjs/config';  

@Injectable()  
export class GeminiService {  
 private genAI: GoogleGenerativeAI;  

 constructor(private readonly configService: ConfigService) {  
 const apiKey = this.configService.getOrThrow('GOOGLE_API_KEY');  

 this.genAI = new GoogleGenerativeAI(apiKey);  
 }  

 async extractInsights(file: Express.Multer.File): Promise {  
 try {  
 const model = this.genAI.getGenerativeModel({  
 model: 'gemini-2.0-flash-exp',  
 });  

 const result = await model.generateContent([  
 {  
 inlineData: {  
 data: file.buffer.toString('base64'),  
 mimeType: 'application/pdf',  
 },  
 },  
 'Extract key insights',  
 ]);  
 return result.response.text();  
 } catch (error) {  
 console.error('Error generating content:', error);  
 throw new Error('Failed to extract insights');  
 }  
 }  
}

Тепер ми можемо викликати цей метод у модулі документів. Створимо наш модуль документів, сервіс і контролер за допомогою:

nest g module document  

nest g service document  

nest g controller document

У нашому document.service буде ось таке:

import { Injectable } from '@nestjs/common';  
import { GeminiService } from './../gemini/gemini.service';  

@Injectable()  
export class DocumentService {  
 constructor(  
 private geminiService: GeminiService, // Впроваджуємо GeminiService  
 ) {}  

 // Метод для завантаження документа, витягнення його вмісту та генерації ключових інсайтів  
 async uploadDocument(file: Express.Multer.File) {  
 try {  
 // Генеруємо інсайти за допомогою сервісу Gemini  
 const insights = await this.geminiService.extractInsights(file)  

 return {  
 data: { insights },  
 message: 'Успішно',  
 };  
 } catch (error) {  
 throw new Error('Не вдалося завантажити документ');  
 }  
 }

У нашому document.controller буде ось таке:

import {  
 Controller,  
 Post,  
 UploadedFile,  
 UseInterceptors,  
} from '@nestjs/common';  
import { DocumentService } from './document.service';  
import { FileInterceptor } from '@nestjs/platform-express';  

@Controller('document')  
export class DocumentController {  
 constructor(private documentService: DocumentService) {}  

 // POST-ендпоінт для обробки завантаження файлів  
 @Post('upload')  
 // Використовуємо FileInterceptor для обробки завантажень файлів, 'file' - це ім'я поля в form-data  
 @UseInterceptors(FileInterceptor('file'))  
 async uploadDocument(@UploadedFile() file: Express.Multer.File) {  
 return this.documentService.uploadDocument(file);  
 }  
}

Тепер час протестувати наше API. Я буду використовувати Postman.

Я завантажую своє резюме, щоб витягнути ключові інсайти та створити його резюме. В тілі запиту я надсилаю файл з ключем 'file'.

pic

Результат:

pic

І на цьому все, друзі! Успіхів.

Перекладено з: Leverage Google Gemini AI to summarize documents in NestJS