Truyền thông tin thông qua ngữ cảnh

Có nhiều danh mục thông tin mà nhà phát triển làm việc với LLM có thể xử lý đồng thời:

  • Đầu vào: Thông tin có liên quan trực tiếp để hướng dẫn phản hồi của LLM cho một lệnh gọi cụ thể. Ví dụ về điều này là văn bản cần được tóm tắt.
  • Bối cảnh tạo: Thông tin có liên quan đến LLM, nhưng không dành riêng cho lệnh gọi. Ví dụ: thời gian hiện tại hoặc tên của người dùng.
  • Ngữ cảnh thực thi: Thông tin quan trọng đối với mã xung quanh lệnh gọi LLM nhưng không quan trọng đối với chính LLM. Ví dụ: mã xác thực hiện tại của người dùng.

Genkit cung cấp một đối tượng context nhất quán có thể truyền tải bối cảnh tạo và thực thi trong suốt quá trình. Bối cảnh này được cung cấp cho tất cả các thao tác, bao gồm cả luồng, công cụlời nhắc.

Ngữ cảnh được tự động truyền đến tất cả các hành động được gọi trong phạm vi thực thi: Ngữ cảnh được truyền đến một luồng sẽ được cung cấp cho các lời nhắc được thực thi trong luồng đó. Ngữ cảnh được truyền vào phương thức generate() có sẵn cho các công cụ được gọi trong vòng lặp tạo.

Tại sao ngữ cảnh lại quan trọng?

Theo phương pháp hay nhất, bạn nên cung cấp cho LLM lượng thông tin tối thiểu cần thiết để hoàn thành một tác vụ. Điều này rất quan trọng vì nhiều lý do:

  • LLM càng có ít thông tin không liên quan thì càng có nhiều khả năng thực hiện tốt nhiệm vụ của mình.
  • Nếu một LLM cần truyền thông tin như mã nhận dạng người dùng hoặc tài khoản đến các công cụ, thì LLM đó có thể bị lừa để rò rỉ thông tin.

Ngữ cảnh cung cấp cho bạn một kênh phụ chứa thông tin mà bất kỳ mã nào của bạn cũng có thể sử dụng nhưng không nhất thiết phải gửi đến LLM. Ví dụ: bạn có thể hạn chế các truy vấn công cụ trong phạm vi hiện có của người dùng.

Cấu trúc ngữ cảnh

Ngữ cảnh phải là một đối tượng, nhưng bạn có thể quyết định các thuộc tính của đối tượng đó. Trong một số trường hợp, Genkit sẽ tự động điền ngữ cảnh. Ví dụ: khi sử dụng phiên ổn định, thuộc tính state sẽ tự động được thêm vào ngữ cảnh.

Một trong những cách sử dụng phổ biến nhất của ngữ cảnh là lưu trữ thông tin về người dùng hiện tại. Bạn nên thêm ngữ cảnh xác thực theo định dạng sau:

{
  auth: {
    uid: "...", // the user's unique identifier
    token: {...}, // the decoded claims of a user's id token
    rawToken: "...", // the user's raw encoded id token
    // ...any other fields
  }
}

Đối tượng ngữ cảnh có thể lưu trữ mọi thông tin mà bạn có thể cần biết ở nơi khác trong luồng thực thi.

Sử dụng ngữ cảnh trong một hành động

Để sử dụng ngữ cảnh trong một thao tác, bạn có thể truy cập vào trình trợ giúp ngữ cảnh được tự động cung cấp cho định nghĩa hàm:

Dòng chảy

const summarizeHistory = ai.defineFlow({
  name: 'summarizeMessages',
  inputSchema: z.object({friendUid: z.string()}),
  outputSchema: z.string();
}, async ({friendUid}, {context}) => {
  if (!context.auth?.uid) throw new Error("Must supply auth context.");
  const messages = await listMessagesBetween(friendUid, context.auth.uid);
  const {text} = await ai.generate({
    prompt:
      `Summarize the content of these messages: ${JSON.stringify(messages)}`,
  });
  return text;
});

Công cụ

const searchNotes = ai.defineTool({
  name: 'searchNotes',
  description: "search the current user's notes for info",
  inputSchema: z.object({query: z.string()}),
  outputSchmea: z.array(NoteSchema);
}, async ({query}, {context}) => {
  if (!context.auth?.uid) throw new Error("Must be called by a signed-in user.");
  return searchUserNotes(context.auth.uid, query);
});

Tệp lời nhắc

Khi sử dụng mẫu Dotprompt, ngữ cảnh sẽ được cung cấp bằng tiền tố biến @. Ví dụ: bạn có thể truy cập đối tượng ngữ cảnh của {auth: {name: 'Michael'}} trong mẫu lời nhắc như sau:

---
input:
  schema:
    pirateStyle?: boolean
---

{{#if pirateStyle}}
Avast, {{@auth.name}}, how be ye today?
{{else}}
Hello, {{@auth.name}}, how are you today?
{{/if}}

Cung cấp ngữ cảnh trong thời gian chạy

Để cung cấp ngữ cảnh cho một hành động, bạn truyền đối tượng ngữ cảnh dưới dạng một tuỳ chọn khi gọi hành động đó.

Luồng

const summarizeHistory = ai.defineFlow(/* ... */);

const summary = await summarizeHistory(friend.uid, {context: {auth: currentUser}});

Tạo

const {text} = await ai.generate({
  prompt: "Find references to ocelots in my notes.",
  // the context will propagate to tool calls
  tools: [searchNotes],
  context: {auth: currentUser},
});

Lời nhắc

const helloPrompt = ai.prompt('sayHello');
helloPrompt({pirateStyle: true}, {context: {auth: currentUser}});

Truyền tải và ghi đè ngữ cảnh

Theo mặc định, khi bạn cung cấp ngữ cảnh, ngữ cảnh đó sẽ tự động được truyền đến tất cả các thao tác được gọi do lệnh gọi ban đầu của bạn. Nếu luồng của bạn gọi các luồng khác hoặc công cụ gọi của bạn tạo ra, thì cùng một ngữ cảnh sẽ được cung cấp.

Nếu muốn ghi đè ngữ cảnh trong một hành động, bạn có thể truyền một đối tượng ngữ cảnh khác để thay thế đối tượng hiện có:

const otherFlow = ai.defineFlow(/* ... */);

const myFlow = ai.defineFlow({
  // ...
}, (input, {context}) => {
  // override the existing context completely
  otherFlow({/*...*/}, {context: {newContext: true}});
  // or selectively override
  otherFlow({/*...*/}, {context: {...context, updatedContext: true}});
}); 

Khi ngữ cảnh được thay thế, ngữ cảnh đó sẽ được truyền theo cách tương tự. Trong ví dụ này, mọi thao tác mà otherFlow gọi trong quá trình thực thi sẽ kế thừa ngữ cảnh bị ghi đè.