Nhiều người dùng sẽ tương tác với các mô hình ngôn ngữ lớn lần đầu tiên thông qua chatbot. Mặc dù LLM có thể làm được nhiều việc hơn là mô phỏng các cuộc trò chuyện, nhưng đây vẫn là một kiểu tương tác quen thuộc và hữu ích. Ngay cả khi người dùng không tương tác trực tiếp với mô hình theo cách này, kiểu lời nhắc trò chuyện vẫn là một cách hiệu quả để tác động đến kết quả do mô hình AI tạo ra.
Để hỗ trợ kiểu tương tác này, Genkit cung cấp một bộ giao diện và các thành phần trừu tượng giúp bạn dễ dàng tạo các ứng dụng LLM dựa trên cuộc trò chuyện.
Trước khi bắt đầu
Trước khi đọc trang này, bạn nên làm quen với nội dung được đề cập trên trang Tạo nội dung bằng mô hình AI.
Nếu bạn muốn chạy các ví dụ về mã trên trang này, trước tiên, hãy hoàn tất các bước trong hướng dẫn Bắt đầu. Tất cả các ví dụ đều giả định rằng bạn đã cài đặt Genkit làm phần phụ thuộc trong dự án.
Thông tin cơ bản về phiên trò chuyện
Dưới đây là một ứng dụng chatbot tối giản, dựa trên bảng điều khiển:
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);
}
})();
Một phiên trò chuyện bằng chương trình này sẽ có dạng như ví dụ sau:
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?
Như bạn có thể thấy trong lượt tương tác ngắn này, khi bạn gửi tin nhắn đến một phiên trò chuyện, mô hình có thể tận dụng phiên trò chuyện đó cho đến thời điểm hiện tại trong các câu trả lời. Điều này có thể xảy ra vì Genkit thực hiện một số việc ở chế độ nền:
- Truy xuất nhật ký trò chuyện (nếu có) từ bộ nhớ (sẽ trình bày thêm về tính năng lưu trữ và bộ nhớ sau)
- Gửi yêu cầu đến mô hình, như với
generate()
, nhưng tự động đưa nhật ký trò chuyện vào - Lưu câu trả lời của mô hình vào nhật ký trò chuyện
Cấu hình mô hình
Phương thức chat()
chấp nhận hầu hết các tuỳ chọn cấu hình giống như generate()
. Cách truyền các tuỳ chọn cấu hình đến mô hình:
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,
},
});
Phiên trò chuyện có trạng thái
Ngoài việc lưu giữ nhật ký tin nhắn của một phiên trò chuyện, bạn cũng có thể lưu giữ bất kỳ đối tượng JavaScript tuỳ ý nào. Việc này có thể cho phép bạn quản lý trạng thái theo cách có cấu trúc hơn so với việc chỉ dựa vào thông tin trong nhật ký thư.
Để đưa trạng thái vào một phiên, bạn cần tạo bản sao phiên một cách rõ ràng:
interface MyState {
userName: string;
}
const session = ai.createSession<MyState>({
initialState: {
userName: 'Pavel',
},
});
Sau đó, bạn có thể bắt đầu cuộc trò chuyện trong phiên:
const chat = session.chat();
Để sửa đổi trạng thái phiên dựa trên cách cuộc trò chuyện diễn ra, hãy xác định công cụ và đưa các công cụ đó vào yêu cầu của bạn:
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');
Phiên đa luồng
Một phiên có thể chứa nhiều chuỗi trò chuyện. Mỗi luồng có một nhật ký thông báo riêng, nhưng các luồng này chia sẻ một trạng thái phiên duy nhất.
const lawyerChat = session.chat('lawyerThread', {
system: 'talk like a lawyer',
});
const pirateChat = session.chat('pirateThread', {
system: 'talk like a pirate',
});
Phiên ổn định (THỬ NGHIỆM)
Khi bạn khởi chạy một cuộc trò chuyện hoặc phiên mới, theo mặc định, cuộc trò chuyện hoặc phiên đó sẽ được định cấu hình để chỉ lưu trữ phiên trong bộ nhớ. Điều này là đủ khi phiên chỉ cần duy trì trong thời gian một lệnh gọi duy nhất của chương trình, như trong chatbot mẫu ở đầu trang này. Tuy nhiên, khi tích hợp tính năng trò chuyện LLM vào một ứng dụng, bạn thường sẽ triển khai logic tạo nội dung dưới dạng các điểm cuối API web không có trạng thái. Để các cuộc trò chuyện liên tục hoạt động trong chế độ thiết lập này, bạn cần triển khai một số loại bộ nhớ phiên có thể duy trì trạng thái trên các lệnh gọi của điểm cuối.
Để thêm tính năng lưu trữ vào một phiên trò chuyện, bạn cần triển khai giao diện SessionStore
của Genkit. Dưới đây là ví dụ về cách triển khai lưu trạng thái phiên vào các tệp JSON riêng lẻ:
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' });
}
}
Phương thức triển khai này có thể không phù hợp với các hoạt động triển khai thực tế, nhưng minh hoạ rằng việc triển khai bộ nhớ phiên chỉ cần thực hiện hai nhiệm vụ:
- Lấy đối tượng phiên từ bộ nhớ bằng mã phiên
- Lưu một đối tượng phiên nhất định, được lập chỉ mục theo mã phiên
Sau khi triển khai giao diện cho phần phụ trợ bộ nhớ, hãy truyền một thực thể của quá trình triển khai đến hàm khởi tạo phiên:
// 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(),
});