Как ChatGPT и TypeScript становятся лучшими друзьями
Представьте: вы пишете код на TypeScript, и вдруг ваш сервис обретает суперсилу — способность понимать и генерировать человеческий текст. ChatGPT API делает это реальностью. В этой статье мы не просто подключим API — мы построим полноценный модуль для общения с нейросетью, который будет устойчивым, типизированным и готовым к продакшену.
Если вы думаете, что интеграция AI — это что-то из области фантастики или удел гигантов вроде Google, спешу вас обрадовать: OpenAI предоставляет простой REST API, а TypeScript с его строгой типизацией делает работу с ним безопасной и предсказуемой. Давайте разбираться на практике.
Подготовка окружения: что нужно установить
Прежде чем писать код, убедимся, что у вас есть всё необходимое. Для работы с ChatGPT API на TypeScript понадобится:
- Node.js версии 18 или выше (рекомендую 20 LTS)
- npm или yarn для управления пакетами
- API-ключ OpenAI — получите его на platform.openai.com
- Редактор кода (VS Code, WebStorm — любой удобный)
Создадим новый проект и установим зависимости:
mkdir chatgpt-typescript
cd chatgpt-typescript
npm init -y
npm install openai dotenv
npm install -D typescript @types/node ts-node
Обратите внимание: мы используем официальный SDK от OpenAI, который отлично дружит с TypeScript. Пакет dotenv понадобится для безопасного хранения API-ключа.
Настройка TypeScript и переменных окружения
Создадим файл tsconfig.json с базовыми настройками:
{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"lib": ["ES2020"],
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
},
"include": ["src/**/*"]
}
Теперь создадим файл .env в корне проекта:
OPENAI_API_KEY=ваш_супер_секретный_ключ
Важно: добавьте .env в .gitignore, чтобы случайно не закоммитить ключ в репозиторий!
Пишем первый запрос к ChatGPT на TypeScript
Создадим папку src и файл index.ts. Начнём с простого: отправим сообщение и получим ответ.
import OpenAI from 'openai';
import dotenv from 'dotenv';
dotenv.config();
const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
});
async function chatWithGPT(prompt: string): Promise<string> {
try {
const response = await openai.chat.completions.create({
model: 'gpt-4',
messages: [
{ role: 'system', content: 'Ты — полезный ассистент.' },
{ role: 'user', content: prompt },
],
temperature: 0.7,
max_tokens: 500,
});
return response.choices[0]?.message?.content || 'Нет ответа';
} catch (error) {
console.error('Ошибка при запросе к ChatGPT:', error);
throw error;
}
}
// Использование
(async () => {
const answer = await chatWithGPT('Расскажи короткую шутку про программистов');
console.log('ChatGPT говорит:', answer);
})();
Запустим код командой npx ts-node src/index.ts. Если всё настроено правильно, вы увидите ответ от нейросети. Обратите внимание на типизацию: TypeScript автоматически подсказывает структуру объекта response, что делает разработку комфортной.
Разбор ключевых параметров
- model:
gpt-4— самая умная модель на сегодня. Для экономии можно использоватьgpt-3.5-turbo. - messages: массив с историей диалога. Первое сообщение с ролью
systemзадаёт поведение ассистента. - temperature: от 0 до 2. Чем выше, тем креативнее (но менее точные) ответы.
- max_tokens: лимит на длину ответа (включая и ваш запрос).
Создаём продвинутый клиент для ChatGPT
Простой запрос — это здорово, но в реальном проекте нужно больше. Давайте построим класс, который будет управлять диалогом, хранить историю и обрабатывать ошибки.
import OpenAI from 'openai';
import dotenv from 'dotenv';
dotenv.config();
interface ChatMessage {
role: 'system' | 'user' | 'assistant';
content: string;
}
class ChatGPTClient {
private openai: OpenAI;
private conversationHistory: ChatMessage[] = [];
constructor(apiKey?: string) {
this.openai = new OpenAI({
apiKey: apiKey || process.env.OPENAI_API_KEY,
});
}
setSystemPrompt(prompt: string): void {
this.conversationHistory = [
{ role: 'system', content: prompt },
];
}
async sendMessage(userMessage: string): Promise<string> {
this.conversationHistory.push({ role: 'user', content: userMessage });
try {
const response = await this.openai.chat.completions.create({
model: 'gpt-4',
messages: this.conversationHistory,
temperature: 0.8,
max_tokens: 1000,
});
const assistantReply = response.choices[0]?.message?.content || '';
this.conversationHistory.push({ role: 'assistant', content: assistantReply });
return assistantReply;
} catch (error: any) {
if (error.status === 429) {
throw new Error('Превышен лимит запросов. Подождите немного.');
}
if (error.status === 401) {
throw new Error('Неверный API-ключ. Проверьте .env файл.');
}
throw new Error(`Ошибка OpenAI: ${error.message}`);
}
}
getHistory(): ChatMessage[] {
return [...this.conversationHistory];
}
clearHistory(): void {
this.conversationHistory = [];
}
}
// Пример использования
const client = new ChatGPTClient();
client.setSystemPrompt('Ты — эксперт по TypeScript. Отвечай кратко и с примерами кода.');
(async () => {
const reply1 = await client.sendMessage('Как объявить тип для объекта?');
console.log('Ответ 1:', reply1);
const reply2 = await client.sendMessage('А для массива?');
console.log('Ответ 2:', reply2);
})();
Этот класс решает несколько проблем:
- Хранит историю — нейросеть помнит контекст беседы.
- Типизирует ошибки — вы точно знаете, что пошло не так.
- Позволяет менять системный промпт — гибкость для разных сценариев.
Потоковая передача: получаем ответ по частям
Когда ChatGPT генерирует длинный ответ, ждать целиком — скучно. Используем стрими