ایجاد جلسات چت مداوم

بسیاری از کاربران شما برای اولین بار از طریق ربات‌های گفتگو با مدل‌های زبان بزرگ تعامل خواهند داشت. اگرچه LLM ها توانایی بسیار بیشتر از شبیه سازی مکالمات را دارند، اما همچنان یک سبک آشنا و مفید از تعامل است. حتی زمانی که کاربران شما به این شکل مستقیماً با مدل تعامل نخواهند کرد، سبک مکالمه اعلان راهی قدرتمند برای تأثیرگذاری بر خروجی تولید شده توسط یک مدل هوش مصنوعی است.

برای پشتیبانی از این سبک تعامل، Genkit مجموعه‌ای از رابط‌ها و انتزاع‌ها را ارائه می‌کند که ساخت برنامه‌های LLM مبتنی بر چت را برای شما آسان‌تر می‌کند.

قبل از شروع

قبل از خواندن این صفحه، باید با محتوای پوشش داده شده در صفحه تولید محتوا با مدل‌های هوش مصنوعی آشنا شوید.

اگر می خواهید نمونه کدهای موجود در این صفحه را اجرا کنید، ابتدا مراحل راهنمای شروع کار را کامل کنید. همه مثال ها فرض می کنند که شما قبلاً Genkit را به عنوان یک وابستگی در پروژه خود نصب کرده اید.

اصول جلسه چت

در اینجا یک برنامه چت بات مینیمال، مبتنی بر کنسول وجود دارد:

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

import { createInterface } from "node:readline/promises";

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

(async () => {
  const chat = ai.chat();
  console.log("You're chatting with Gemini. Ctrl-C to quit.\n");
  const readline = createInterface(process.stdin, process.stdout);
  while (true) {
    const userInput = await readline.question("> ");
    const { text } = await chat.send(userInput);
    console.log(text);
  }
})();

یک جلسه گفتگو با این برنامه چیزی شبیه به مثال زیر است:

You're chatting with Gemini. Ctrl-C to quit.

> hi
Hi there! How can I help you today? 

> my name is pavel
Nice to meet you, Pavel! What can I do for you today? 

> what's my name?
Your name is Pavel! I remembered it from our previous interaction. 

Is there anything else I can help you with?

همانطور که از این تعامل کوتاه مشاهده می کنید، زمانی که شما پیامی را به یک جلسه چت ارسال می کنید، مدل می تواند از جلسه تا کنون در پاسخ های خود استفاده کند. این امکان پذیر است زیرا Genkit چند کار را در پشت صحنه انجام می دهد:

  • سابقه چت را، در صورت وجود، از فضای ذخیره‌سازی بازیابی می‌کند (در ادامه بیشتر درباره ماندگاری و ذخیره‌سازی بیشتر)
  • درخواست را به مدل ارسال می کند، مانند generate() ، اما به طور خودکار تاریخچه چت را درج می کند
  • پاسخ مدل را در تاریخچه چت ذخیره می کند

پیکربندی مدل

متد chat() اکثر گزینه‌های پیکربندی مشابه generate() را می‌پذیرد. برای ارسال گزینه های پیکربندی به مدل:

const chat = ai.chat({
  model: gemini15Pro,
  system:
    "You're a pirate first mate. Address the user as Captain and assist " +
    "them however you can.",
  config: {
    temperature: 1.3,
  },
});

جلسات چت دولتی

علاوه بر ماندگاری تاریخچه پیام یک جلسه چت، می‌توانید هر شیء دلخواه جاوا اسکریپت را نیز حفظ کنید. انجام این کار به شما امکان می دهد وضعیت را به روشی ساختارمندتر مدیریت کنید و سپس فقط بر اطلاعات موجود در تاریخچه پیام تکیه کنید.

برای گنجاندن حالت در یک جلسه، باید یک جلسه را به صراحت نمونه برداری کنید:

interface MyState {
  userName: string;
}

const session = ai.createSession<MyState>({
  initialState: {
    userName: 'Pavel',
  },
});

سپس می توانید یک چت را در جلسه شروع کنید:

const chat = session.chat();

برای تغییر وضعیت جلسه بر اساس نحوه باز شدن چت، ابزارهایی را تعریف کنید و آنها را با درخواست های خود اضافه کنید:

const changeUserName = ai.defineTool(
  {
    name: 'changeUserName',
    description: 'can be used to change user name',
    inputSchema: z.object({
      newUserName: z.string(),
    }),
  },
  async (input) => {
    await ai.currentSession<MyState>().updateState({
      userName: input.newUserName,
    });
    return 'changed username to ${input.newUserName}';
  }
);
const chat = session.chat({
  model: gemini15Pro,
  tools: [changeUserName],
});
await chat.send('change user name to Kevin');

جلسات چند رشته ای

یک جلسه می تواند شامل چندین موضوع چت باشد. هر رشته تاریخچه پیام مخصوص به خود را دارد، اما آنها در یک حالت جلسه مشترک هستند.

const lawyerChat = session.chat('lawyerThread', {
  system: 'talk like a lawyer',
});
const pirateChat = session.chat('pirateThread', {
  system: 'talk like a pirate',
});

تداوم جلسه (EXPERIMENTAL)

هنگامی که یک چت یا جلسه جدید را راه اندازی می کنید، به طور پیش فرض برای ذخیره جلسه فقط در حافظه پیکربندی شده است. این زمانی کافی است که جلسه فقط برای مدت یک فراخوانی از برنامه شما باقی بماند، همانطور که در چت بات نمونه از ابتدای این صفحه وجود دارد. با این حال، هنگام ادغام چت LLM در یک برنامه، معمولاً منطق تولید محتوای خود را به عنوان نقاط پایانی وب API بدون حالت اجرا می‌کنید. برای اینکه چت‌های دائمی تحت این تنظیمات کار کنند، باید نوعی ذخیره‌سازی جلسه را پیاده‌سازی کنید که بتواند حالت را در سراسر فراخوانی نقاط پایانی شما حفظ کند.

برای افزودن ماندگاری به جلسه چت، باید رابط SessionStore Genkit را پیاده سازی کنید. در اینجا یک نمونه پیاده سازی است که وضعیت جلسه را در فایل های JSON جداگانه ذخیره می کند:

class JsonSessionStore<S = any> implements SessionStore<S> {
  async get(sessionId: string): Promise<SessionData<S> | undefined> {
    try {
      const s = await readFile(`${sessionId}.json`, { encoding: 'utf8' });
      const data = JSON.parse(s);
      return data;
    } catch {
      return undefined;
    }
  }

  async save(sessionId: string, sessionData: SessionData<S>): Promise<void> {
    const s = JSON.stringify(sessionData);
    await writeFile(`${sessionId}.json`, s, { encoding: 'utf8' });
  }
}

این پیاده‌سازی احتمالاً برای استقرارهای عملی کافی نیست، اما نشان می‌دهد که پیاده‌سازی ذخیره‌سازی جلسه فقط باید دو کار را انجام دهد:

  • یک شی جلسه را با استفاده از شناسه جلسه آن از فضای ذخیره سازی دریافت کنید
  • یک شی جلسه داده شده را که با شناسه جلسه آن نمایه شده است، ذخیره کنید

هنگامی که رابط کاربری ذخیره سازی پشتیبان خود را پیاده سازی کردید، نمونه ای از پیاده سازی خود را به سازنده های جلسه ارسال کنید:

// To create a new session:
const session = ai.createSession({
  store: new JsonSessionStore(),
});

// Save session.id so you can restore the session the next time the
// user makes a request.
// If the user has a session ID saved, load the session instead of creating
// a new one:
const session = await ai.loadSession(sessionId, {
    store: new JsonSessionStore(),
});