оптемизируй и улучши код // Подключение необходимых библиотек
const axios = require('axios');
const cheerio = require('cheerio');
const fs = require('fs');
const natural = require('natural');
const tf = require('@tensorflow/tfjs-node-gpu'); // Использование GPU версии TensorFlow

// Функция для поиска случайных статей на Википедии
async function fetchRandomWikiTitle() {
    try {
        const response = await axios.get('https://ru.wikipedia.org/wiki/Special:Random');
        return response.request.res.responseUrl;
    } catch (error) {
        console.error("Ошибка при запросе случайной статьи:", error);
    }
}

// Функция для получения заголовка и текста статьи по её URL
async function fetchWikiArticle(url) {
    try {
        const response = await axios.get(url);
        const $ = cheerio.load(response.data);

        const title = $('#firstHeading').text().trim();
        const paragraphs = [];
        $('p').each((i, element) => {
            const text = $(element).text();
            if (text.length > 50) paragraphs.push(text);
        });

        const article = paragraphs.join(' ');
        return { title, article };
    } catch (error) {
        console.error("Ошибка при запросе статьи:", error);
    }
}

// Загрузка указанного количества статей и сохранение в JSON
async function getWikiArticles(count) {
    const articles = [];
    console.log(`Загружается ${count} статей с Википедии...`);

    for (let i = 0; i < count; i++) {
        const url = await fetchRandomWikiTitle();
        console.log(`Загружается статья: ${url}`);
        const articleData = await fetchWikiArticle(url);
        if (articleData) {
            articles.push({ url, title: articleData.title, article: articleData.article });
        }
    }

    fs.writeFileSync('bd.json', JSON.stringify(articles, null, 2));
    console.log(`Загрузка завершена. Статьи сохранены в "bd.json".`);
}

// Загрузка статей из bd.json
function loadArticlesFromJson() {
    try {
        const data = fs.readFileSync('bd.json', 'utf8');
        return JSON.parse(data);
    } catch (error) {
        console.error("Ошибка при чтении 'bd.json':", error);
        return [];
    }
}

// Токенизация и обработка текста для модели
function preprocessData(articles) {
    const tokenizer = new natural.WordTokenizer();
    const allTokens = articles.map(articleObj => tokenizer.tokenize(articleObj.article.toLowerCase()));
    const vocabulary = [...new Set(allTokens.flat())];
    const wordIndex = {};
    vocabulary.forEach((word, index) => wordIndex[word] = index + 1);

    const data = allTokens.map(tokens => ({
        tokenIndexes: tokens.map(token => wordIndex[token] || 0),
        label: Math.random() > 0.5 ? 1 : 0
    }));

    const maxLength = Math.max(...data.map(d => d.tokenIndexes.length));
    const inputs = data.map(d => {
        const padded = [...d.tokenIndexes];
        while (padded.length < maxLength) padded.push(0);
        return padded.slice(0, maxLength);
    });

    const labels = data.map(d => d.label);
    return { inputs, labels, wordIndex };
}

// Создание модели TensorFlow
function createModel(inputShape) {
    const model = tf.sequential();
    model.add(tf.layers.dense({ units: 128, activation: 'relu', inputShape }));
    model.add(tf.layers.dropout({ rate: 0.2 }));
    model.add(tf.layers.dense({ units: 64, activation: 'relu' }));
    model.add(tf.layers.dropout({ rate: 0.2 }));
    model.add(tf.layers.dense({ units: 1, activation: 'sigmoid' }));
    model.compile({ optimizer: 'adam', loss: 'binaryCrossentropy', metrics: ['accuracy'] });
    return model;
}

// Обучение модели
async function trainModel(model, inputs, labels) {
    const xs = tf.tensor2d(inputs);
    const ys = tf.tensor2d(labels, [labels.length, 1]);

    console.log("Обучение модели на GPU...");
    await model.fit(xs, ys, { epochs: 1000, batchSize: 32, validationSplit: 0.2 });
    console.log("Модель обучена.");
}

// Функция для поиска смыслового контекста
function extractContext(article, questionTokens) {
    const tokenizer = new natural.SentenceTokenizer();
    const sentences = tokenizer.tokenize(article);
    const relevantSentences = [];

    sentences.forEach(sentence => {
        const sentenceTokens = new natural.WordTokenizer().tokenize(sentence.toLowerCase());
        const matchingTokens = questionTokens.filter(token => sentenceTokens.includes(token));

        if (matchingTokens.length > 0) {
            relevantSentences.push(sentence);
        }
    });

    return relevantSentences;
}

// Поиск релевантных частей статьи и формирование единого ответа
function generateUnifiedAnswer(question, articles) {
    const tokenizer = new natural.WordTokenizer();
    const questionTokens = tokenizer.tokenize(question.toLowerCase());

    let combinedContext = '';

    articles.forEach(article => {
        const context = extractContext(article.article, questionTokens);
        if (context.length > 0) {
            combinedContext += context.join(' ') + ' ';
        }
    });

    if (combinedContext.length === 0) {
        return "Не найдено релевантной информации.";
    }

    return combinedContext.trim();
}

// Функция для поиска релевантных статей
function findRelevantArticles(question, articles) {
    const tokenizer = new natural.WordTokenizer();
    const questionTokens = tokenizer.tokenize(question.toLowerCase());

    return articles.map(article => {
        const articleTokens = tokenizer.tokenize(article.article.toLowerCase());
        const intersection = articleTokens.filter(token => questionTokens.includes(token));
        return { ...article, relevance: intersection.length / questionTokens.length };
    }).sort((a, b) => b.relevance - a.relevance).slice(0, 5); // Сокращаем до 5 наиболее релевантных
}

// Главная функция
async function main() {
    const command = process.argv[2];
    const count = parseInt(process.argv[3]);

    if (command === '/getwiki') {
        if (!isNaN(count)) await getWikiArticles(count);
        else console.log("Укажите количество статей: /getwiki <количество>");
    } else if (command === '/getNR') {
        const articles = loadArticlesFromJson();
        if (!articles.length) return console.log("Нет статей для обучения. Используйте /getwiki.");

        const { inputs, labels } = preprocessData(articles);
        const model = createModel([inputs[0].length]);
        await trainModel(model, inputs, labels);
        await model.save('file://./model');
        console.log("Модель сохранена в './model'.");
    } else if (command === '/ask') {
        const question = process.argv.slice(3).join(' ');
        if (!question) return console.log("Введите вопрос: /ask <вопрос>");

        const articles = loadArticlesFromJson();
        const relevantArticles = findRelevantArticles(question, articles);

        if (relevantArticles.length === 0) {
            console.log("Не найдено подходящих статей.");
        } else {
            const unifiedAnswer = generateUnifiedAnswer(question, relevantArticles);
            console.log("Ответ:");
            console.log(unifiedAnswer);
        }
    } else {
        console.log("Доступные команды: /getwiki <количество>, /getNR, /ask <вопрос>");
    }
}

main();