Миграция с версии 0.5

В Genkit 0.9 представлен ряд кардинальных изменений наряду с улучшениями функций, улучшающими общую функциональность. Если вы разрабатываете приложения с помощью Genkit 0.5, вам потребуется обновить код приложения при обновлении до последней версии. В этом руководстве описаны наиболее существенные изменения и предложены шаги по плавной миграции существующих приложений.

Краткое руководство

Следующие шаги помогут вам быстро перейти с Genkit 0.5 на Genkit 0.9. Дополнительную информацию об этих изменениях можно найти в подробном журнале изменений ниже.

1. Установите новый интерфейс командной строки.

  • Удалите старый CLI

    npm uninstall -g genkit && npm uninstall genkit
  • Установите новый интерфейс командной строки

    npm i -D genkit-cli

2. Обновите свои зависимости

  • Удалите отдельные основные пакеты Genkit.

    npm uninstall @genkit-ai/ai @genkit-ai/core @genkit-ai/dotprompt @genkit-ai/flow
  • Установите новый консолидированный пакет genkit .

    npm i --save genkit
  • Обновите все версии плагина (пример ниже)

    npm upgrade @genkit-ai/firebase
    

3. Измените импорт

  • Удалить импорт для отдельных основных пакетов Genkit.

    import {  } from '@genkit-ai/ai';
    import {  } from '@genkit-ai/core';
    import {  } from '@genkit-ai/flow';
    
  • Удалить импорт zod

    import * as z from 'zod';
    
  • Импортировать genkit и zod из genkit

    import { z, genkit } from 'genkit';
    

4. Обновите свой код

Удалите блоки configureGenkit.

Конфигурация Genkit теперь выполняется для каждого экземпляра. Телеметрия и ведение журнала настраиваются глобально и отдельно от экземпляра Genkit.

  • Замените configureGenkit блоками ai = genkit({...}) . Оставьте только конфигурацию плагина.

    import { genkit } from 'genkit';
    
    const ai = genkit({ plugins: [...]});
    
  • Настройте телеметрию с помощью EnableFirebaseTelemetry или EnableGoogleCloudTelemetry.

    Для Firebase:

    import { enableFirebaseTelemetry } from '@genkit-ai/firebase';
    
    enableFirebaseTelemetry({...});
    

    Для Google Cloud:

    import { enableGoogleCloudTelemetry } from '@genkit-ai/google-cloud';
    
    enableGoogleCloudTelemetry({...});
    
  • Установите уровень ведения журнала самостоятельно

    import { logger } from 'genkit/logging';
    
    logger.setLogLevel('debug');
    

Дополнительные сведения о настройке телеметрии и ведения журналов см. в документации по мониторингу и ведению журнала .

Дополнительные сведения о настройке экземпляра Genkit см. в документации по началу работы .

Перенос действий Genkit, которые будут вызываться из экземпляра genkit

Действия (потоки, инструменты, средства извлечения, индексаторы и т. д.) определяются для каждого экземпляра. Прочтите журнал изменений, чтобы узнать обо всех функциях, которые вам нужно будет изменить, но вот пример некоторых распространенных.

import { genkit } from 'genkit';
import { onFlow } from '@genkit-ai/firebase/functions';

const ai = genkit({ plugins: [...]});

// Flows and tools are defined on the specific genkit instance
// and are directly callable.
const sampleFlow = ai.defineFlow(...);
const sampleTool = ai.defineTool(...);

async function callMyFlow() {
  // Previously, text output could accessed via .text()
  // Now it is either .output() or .text
  return await sampleFlow().output();
}

// onFlow now takes the Genkit instance as first argument
// This registers the flow as a callable firebase function
onFlow(ai, ...);
const flows = [ sampleFlow, ... ];
// Start the flow server to make the registered flows callable over HTTP
ai.startFlowServer({flows});

5. Запустите его

# run the DevUI and your js code
genkit start -- <command to run node>
# run a defined flow
genkit flow:run <flowName>

Журнал изменений

1. Изменения интерфейса командной строки

Интерфейс командной строки (CLI) претерпел значительные обновления в Genkit 0.9. Команда запуска Genkit изменилась, а CLI был выделен в отдельный пакет, который теперь необходимо устанавливать отдельно.

Чтобы установить CLI:

npm i -g genkit-cli

В команду genkit start были внесены некоторые изменения:

Запускает код вашего приложения Genkit + пользовательский интерфейс Dev:

genkit start -- [start command]
genkit start -- tsx src/index.ts
genkit start -- go run main.go

Также поддерживается режим просмотра:

genkit start -- tsx --watch src/index.ts

Запускает ТОЛЬКО код вашего приложения в режиме разработки Genkit:

genkit start --noui -- <start command>
genkit start --noui -- tsx src/index.ts

Запускает ТОЛЬКО пользовательский интерфейс разработчика:

genkit start

Раньше команда genkit start запускала одновременно пользовательский интерфейс разработки и код вашего приложения. Если у вас есть конвейеры CI/CD, использующие эту команду, вам может потребоваться обновить конвейер.

Пользовательский интерфейс разработчика будет напрямую взаимодействовать с сервером потоков, чтобы выяснить, какие потоки зарегистрированы, и позволит вам напрямую вызывать их с помощью примеров входных данных.

2. Упрощенные пакеты и импорт

Раньше библиотеки Genkit были разделены на несколько модулей, которые нужно было устанавливать и импортировать по отдельности. Эти модули теперь объединены в единый импорт. Кроме того, модуль Zod теперь реэкспортируется Genkit.

Старый:

npm i @genkit-ai/core @genkit-ai/ai @genkit-ai/flow @genkit-ai/dotprompt

Новый:

npm i genkit

Старый:

import {  } from '@genkit-ai/ai';
import {  } from '@genkit-ai/core';
import {  } from '@genkit-ai/flow';
import * as z from 'zod';

Новый:

import { genkit, z } from 'genkit';

Плагины Genkit по-прежнему необходимо устанавливать и импортировать по отдельности.

3. Настройка Генкита

Раньше инициализация Genkit выполнялась один раз глобально путем вызова функции configureGenkit . Ресурсы Genkit (потоки, инструменты, подсказки и т. д.) будут автоматически подключены к этой глобальной конфигурации.

Genkit 0.9 представляет экземпляры Genkit , каждый из которых инкапсулирует конфигурацию. См. следующие примеры:

Старый:

import { configureGenkit } from '@genkit-ai/core';

configureGenkit({
  telemetry: {
    instrumentation: ...,
    logger: ...
  }
});

Новый:

import { genkit } from 'genkit';
import { logger } from 'genkit/logging';
import { enableFirebaseTelemetry } from '@genkit-ai/firebase';

logger.setLogLevel('debug');
enableFirebaseTelemetry({...});

const ai = genkit({ ... });

Давайте разберемся:

  • configureGenkit() был заменен на genkit() , и он возвращает настроенный экземпляр Genkit а не настраивает конфигурации глобально.
  • Функция инициализации Genkit теперь находится в пакете genkit .
  • Ведение журнала и телеметрия по-прежнему настраиваются глобально с использованием собственных явных методов. Эти конфигурации применяются единообразно для всех экземпляров Genkit .

4. Определение потоков и явный запуск сервера потоков

Теперь, когда у вас есть настроенный экземпляр Genkit , вам нужно будет определить свои потоки. Все основные методы API, предназначенные для разработчиков, такие как defineFlow , defineTool и onFlow , теперь вызываются через этот экземпляр.

Это отличается от предыдущего способа, при котором потоки и инструменты регистрировались глобально.

Старый:

import { defineFlow, defineTool, onFlow } from '@genkit-ai/core';

defineFlow(...);
defineTool(...);

onFlow(...);

Новый:

// Define tools and flows
const sampleFlow = ai.defineFlow(...);
const sampleTool = ai.defineTool(...);

// onFlow now takes the Genkit instance as first argument
// This registers the flow as a callable firebase function
onFlow(ai, ...);  

const flows = [ sampleFlow, ... ];
// Start the flow server to make the registered flows callable over HTTP
ai.startFlowServer({flows});

На данный момент все потоки, которые вы хотите сделать доступными, должны быть явно зарегистрированы в массиве flows выше.

5. Инструменты и подсказки должны быть определены статически.

В более ранних версиях Genkit вы могли динамически определять инструменты и подсказки во время выполнения, непосредственно из потока.

В Genkit 0.9 такое поведение больше не разрешено. Вместо этого вам необходимо определить все действия и потоки вне выполнения потока (т. е. статически).

Это изменение обеспечивает более строгое разделение определений действий и выполнения.

Если какой-либо код вашего кода определен динамически, его необходимо реорганизовать. В противном случае во время выполнения потока будет выдана ошибка.

❌ НЕЛЬЗЯ:

const flow = defineFlow({...}, async (input) => {
  const tool = defineTool({...});
  await tool(...);
});

✅ ДЕЛАТЬ:

const tool = ai.defineTool({...});

const flow = ai.defineFlow({...}, async (input) => {
  await tool(...);
});

6. Новый API для потоковых потоков

В Genkit 0.9 мы упростили синтаксис определения потока потоковой передачи и его вызова.

Во-первых, defineFlow и defineStreamingFlow были разделены. Если у вас есть поток, предназначенный для потоковой передачи, вам придется обновить свой код, чтобы определить его с помощью defineStreamingFlow .

Во-вторых, вместо вызова отдельных функцийstream stream() и response() , поток и ответ теперь являются значениями, возвращаемыми непосредственно из потока. Это изменение упрощает потоковую передачу.

Старый:

import { defineFlow, streamFlow } from '@genkit-ai/flow';

const myStreamingFlow = defineFlow(...);
const { stream, output } = await streamFlow(myStreamingFlow, ...);

for await (const chunk of stream()) {
  console.log(chunk);
}

console.log(await output());

Новый:

const myStreamingFlow = ai.defineStreamingFlow(...);
const { stream, response } = await myStreamingFlow(...);

for await (const chunk of stream) {
  console.log(chunk);
}

console.log(await response);

7. Методы класса GenerateResponse заменены свойствами-получателями.

Раньше вы имели доступ к структурированному выводу или тексту ответа с помощью методов класса, таких как output() или text() .

В Genkit 0.9 эти методы были заменены свойствами-геттерами. Это упрощает работу с ответами.

Старый:

const response = await generate({ prompt: 'hi' });
console.log(response.text());

Новый:

const response = await ai.generate('hi');
console.log(response.text);

То же самое относится и к output :

Старый:

console.log(response.output());

Новый:

console.log(response.output);

8. Уничтожение поколения кандидатов

Genkit 0.9 упрощает обработку ответов, удаляя атрибут candidates . Раньше ответы могли содержать несколько кандидатов, с которыми нужно было обращаться явно. Теперь только первый кандидат возвращается непосредственно в плоском ответе.

Любой код, который обращается к кандидатам напрямую, больше не будет работать.

Старый:

const response = await generate({
 messages: [ { role: 'user', content: ...} ]
});
console.log(response.candidates); // previously you could access candidates directly

Новый:

const response = await ai.generate({
 messages: [ { role: 'user', content: ...} ]
});
console.log(response.message); // single candidate is returned directly in a flat response

9. Генерация API — улучшения Multi-Turn

Для многоходовых разговоров старый метод toHistory() был заменен messages , что еще больше упрощает обработку истории разговоров.

Старый:

const history = response.toHistory();

Новый:

const response = await ai.generate({
 messages: [ { role: 'user', content: ...} ]
});
const history = response.messages;

10. Оптимизированный API чата

В Genkit 0.9 API чата был переработан для упрощения управления сеансами и взаимодействия. Вот как вы можете использовать его как для синхронного, так и для потокового чата:

import { genkit } from 'genkit';
import { gemini15Flash, googleAI } from '@genkit-ai/googleai';

const ai = genkit({
 plugins: [googleAI()],
 model: gemini15Flash,
});

const session = ai.createSession({ store: firestoreSessionStore() });
const chat = await session.chat({ system: 'talk like a pirate' });

let response = await chat.send('hi, my name is Pavel');
console.log(response.text()); // "hi Pavel, I'm llm"

// continue the conversation
response = await chat.send("what's my name");
console.log(response.text()); // "Pavel"

// can stream
const { response, stream } = await chat.sendStream('bye');
for await (const chunk of stream) {
 console.log(chunk.text());
}
console.log((await response).text());

// can load session from the store
const prevSession = await ai.loadSession(session.id, { store });
const prevChat = await prevSession.chat();
await prevChat.send('bye');