Архив рубрики ~Лента новостей~

Использование Yandex Embedder на JavaScript

Использование Yandex Embedder на JavaScript

В прошлом примере я рассказал о том, как можно использовать YDB в качестве векторной базы знаний. Сегодня расскажу про то, как использовать Yandex Embedder.

Но сначала несколько слов о том, почему Embedder — это очень важно.

Итак, у нас есть задача: есть некоторая внутренняя система (у моем случае — YouTrack), есть ИИ (не важно какой). Я хочу получать ответы от ИИ с использованием данных из внутренней системы. Классическое решение — это выгрузка данных из внутренней системы в RAG и использование этих данных для контекста в запросе к ИИ. В качестве RAG используется векторная база данных (например YDB). Важным моментом является то, что в контекст запроса к LLM передается не вся база — а только некоторое количество наиболее близких документов («близость» как раз определяется сравнением векторов). То есть, работает так:

  • мы пишем запрос

  • по этому запросу находим релевантные документы в RAG

  • отправляем запрос в LLM передавая найденные документы

Так вот. То, что вам ответит ИИ зависит от того, что вы найдете в RAG. А это в свою очередь зависит от того, насколько «хорошо» будут сгенерированы векторы. За генерацию векторов как раз и отвечает Embedder.

В моем прошлом примере класс сохранения данных в YDB использовал простой embedder из библиотеки ‘@xenova/transformers’ и результат поиска, если честно, был так себе. Поэтому следующей задачей стало использование уже более «правильного» Embedder-а. В моем случае, так как я в данном прототипе ориентирован на максимально использование сервисов Yandex Cloud то и выбор пал на Yandex Embedder. Доступные модели можно посмотреть в AI Studio в каталоге моделей.

af5404fbfd998e3c35a32f4524b2fe02

Нам нужна та, которая называется Yandex Text embedding (query) 1

Ниже приведен код класса для работы с Yandex Embedder:

// yandex-embedder.js export class YandexEmbedder { constructor(options = {}) { this.apiKey = options.apiKey; this.baseURL = options.baseURL; this.modelUri = options.modelUri; this.requestsPerSecond = options.requestsPerSecond || 8; this.delayBetweenRequests = 1000 / this.requestsPerSecond; this.lastRequestTime = 0; console.log(‘🔧 Yandex Embedder configured:’); console.log(‘ — Model Uri:’, this.modelUri); console.log(‘ — Base URL:’, this.baseURL); console.log(‘ — delayBetweenRequests:’, this.delayBetweenRequests + ‘ms’); } async generateEmbedding(text) { const now = Date.now(); const timeSinceLastRequest = now — this.lastRequestTime; // console.log(Date.now() + » timeSinceLastRequest: » + timeSinceLastRequest); if (timeSinceLastRequest < this.delayBetweenRequests) { const waitTime = this.delayBetweenRequests — timeSinceLastRequest; await new Promise(resolve => setTimeout(resolve, waitTime)); } // console.log(Date.now() + » After timer:»); this.lastRequestTime = Date.now(); return await this.makeRequest(text); } async makeRequest(text) { const controller = new AbortController(); try { // console.log(`🔍 Generating embedding for text: «${text.substring(0, 50)}${text.length > 50 ? ‘…’ : »}»`); const response = await fetch(this.baseURL, { method: ‘POST’, headers: { ‘Authorization’: `Api-Key ${this.apiKey}`, ‘Content-Type’: ‘application/json’ }, body: JSON.stringify({ modelUri: this.modelUri, text: text }) }); if (!response.ok) { const errorText = await response.text(); throw new Error(`Yandex API error: ${response.status} — ${errorText}`); } const data = await response.json(); if (!data.embedding) { throw new Error(‘No embedding in Yandex API response’); } // console.log(`✅ Embedding generated, dimension: ${data.embedding.length}`); return data.embedding; } catch (error) { console.error(‘❌ Error generating Yandex embedding:’, error.message); throw error; } } // Batch генерация эмбеддингов async generateEmbeddings(texts) { console.log(`🔍 Generating embeddings for ${texts.length} texts…`); const embeddings = []; for (let i = 0; i < texts.length; i++) { try { const embedding = await this.generateEmbedding(texts[i]); embeddings.push(embedding); if ((i + 1) % 10 === 0 || i === texts.length — 1) { console.log(`📊 Progress: ${i + 1}/${texts.length}`); } } catch (error) { console.error(`❌ Failed to generate embedding for text ${i + 1}:`, error.message); embeddings.push(null); } } console.log(`✅ Generated ${embeddings.filter(e => e !== null).length}/${texts.length} embeddings`); return embeddings; } }

При инициализации классу необходимо передать несколько параметров:

  • apiKey — ключ созданный для сервисного аккаунта от имени которого вы будете обращаться к сервису. Генерируется, например, в консоли Yandex Cloud

  • baseURL — URL сервиса — чаще всего это https://llm.api.cloud.yandex.net/foundationModels/v1/textEmbedding

  • modelUri — указатель на используемую модель. Чаще всего будет emb://${YourYandexCloudFolderID}/text-search-query/latest — но тоже могут быть нюансы (теоретически вы можете развернуть свою версию модели)

  • requestsPerSecond — количество запросов в сек, которые можно отправить к сервису.

Вот об этом чуть подробней. Сервис Яндекса обрабатывает не более 10-ти запросов в секунду. Так что запросы надо выстраивать в очередь. Реализация очереди может быть самой разной. Так как в моем случае проект в стадии «прототипа» — то я просто поставил таймер между запросами, но в production решении конечно надо придумывать что-то более надежное.

Могу сказать что с использованием Yandex Embedder-а качество ответов, которые стала выдавать мне программа стало прям на порядок лучше.

Надеюсь, этот пример будет кому-то полезен и съэкономит время. Только учтите — это именно пример на уровне прототипа.

Источник: habr.com

Оцените материал:

Поделиться
Понравилась статья? Расскажите другим
ВКонтакте
Читайте также
Архив рубрики ~Коротко из Telegram~ Поселил ИИ‑агента в чёлку макбука: он слушает мой день и… Архив рубрики ~Коротко из Telegram~ Немой парень впервые признался в любви СИЛОЙ МЫСЛИ — его………… Новости робототехники GM делает ставку на вычислительные технологии и искусственный интеллект, которые, по её мнению, помогут ей конкурировать с китайскими автопроизводителями. Архив рубрики ~Коротко из Telegram~ В легендарный Need for Speed: Underground 2 теперь можно поиграть… Архив рубрики ~Коротко из Telegram~ ИИ придумал пистолет, и его напечатали на 3D-принтере Однозарядный пистолет… Архив рубрики ~Коротко из Telegram~ В Швейцарии с помощью бактерий разработали печатный материал, похожий на бетон Архив рубрики ~Коротко из Telegram~ Модели искусственного интеллекта позволили России применять технологии для лучших крылатых… Архив рубрики ~Коротко из Telegram~ Преимущества использования искусственного интеллекта в медицине зависят от уровня подготовки… Архив рубрики ~Коротко из Telegram~ Почему синтаксис Nova выглядит так: 11 споров с Claude о… Архив рубрики ~Коротко из Telegram~ [Перевод] О сознании и интегрированной информации. Кристоф Кох (интервью) Сознанием… Архив рубрики ~Коротко из Telegram~ Больше половины отпечатков пальцев на терракотовых воинах оставили женщины и… Архив рубрики ~Коротко из Telegram~ В ИТМО учат роботов понимать пространство, а не просто видеть…… Архив рубрики ~Коротко из Telegram~ Теперь можно буквально заглянуть внутрь любого механизма. Claude Code научили…… Архив рубрики ~Коротко из Telegram~ PS5 снова взломали — хакер запустил меню разработчика на последней…… Архив рубрики ~Коротко из Telegram~ Поселил ИИ‑агента в чёлку макбука: он слушает мой день и… Архив рубрики ~Коротко из Telegram~ Немой парень впервые признался в любви СИЛОЙ МЫСЛИ — его………… Новости робототехники GM делает ставку на вычислительные технологии и искусственный интеллект, которые, по её мнению, помогут ей конкурировать с китайскими автопроизводителями. Архив рубрики ~Коротко из Telegram~ В легендарный Need for Speed: Underground 2 теперь можно поиграть… Архив рубрики ~Коротко из Telegram~ ИИ придумал пистолет, и его напечатали на 3D-принтере Однозарядный пистолет… Архив рубрики ~Коротко из Telegram~ В Швейцарии с помощью бактерий разработали печатный материал, похожий на бетон Архив рубрики ~Коротко из Telegram~ Модели искусственного интеллекта позволили России применять технологии для лучших крылатых… Архив рубрики ~Коротко из Telegram~ Преимущества использования искусственного интеллекта в медицине зависят от уровня подготовки… Архив рубрики ~Коротко из Telegram~ Почему синтаксис Nova выглядит так: 11 споров с Claude о… Архив рубрики ~Коротко из Telegram~ [Перевод] О сознании и интегрированной информации. Кристоф Кох (интервью) Сознанием… Архив рубрики ~Коротко из Telegram~ Больше половины отпечатков пальцев на терракотовых воинах оставили женщины и… Архив рубрики ~Коротко из Telegram~ В ИТМО учат роботов понимать пространство, а не просто видеть…… Архив рубрики ~Коротко из Telegram~ Теперь можно буквально заглянуть внутрь любого механизма. Claude Code научили…… Архив рубрики ~Коротко из Telegram~ PS5 снова взломали — хакер запустил меню разработчика на последней……