יש קטגוריות שונות של מידע שמפתחים שעובדים עם LLM עשויים לטפל בו בו-זמנית:
- קלט: מידע שרלוונטי ישירות להנחיית התגובה של ה-LLM לשיחה מסוימת. דוגמה לכך היא הטקסט שצריך לסכם.
- הקשר ליצירה: מידע שרלוונטי ל-LLM, אבל לא ספציפי לשיחה. דוגמה לכך היא השעה הנוכחית או שם המשתמש.
- הקשר הביצוע: מידע שחשוב לקוד שמקיף את הקריאה ל-LLM, אבל לא ל-LLM עצמו. דוגמה לכך היא אסימון האימות הנוכחי של המשתמש.
Genkit מספק אובייקט context
עקבי שיכול להעביר את ההקשר של היצירה וההפעלה לאורך התהליך. ההקשר הזה זמין לכל הפעולות, כולל תהליכים, כלים והנחיות.
ההקשר מועבר באופן אוטומטי לכל הפעולות שנקראות במסגרת הביצוע: ההקשר שמוענק לתהליך זמין להנחיות שמופעלות במסגרת התהליך. ההקשר שמוענק לשיטה generate()
זמין לכלים שנקראים בתוך לולאת היצירה.
למה הקשר חשוב?
מומלץ לספק ל-LLM את כמות המידע המינימלית שנדרשת לו כדי להשלים משימה. חשוב לעשות זאת מכמה סיבות:
- ככל שיש פחות מידע חיצוני ב-LLM, כך הסיכוי שהוא יבצע את המשימה בצורה טובה יותר גדל.
- אם ל-LLM צריך להעביר מידע כמו מזהי משתמשים או חשבונות לכלים, הוא עלול להיחשף לתרמיות שעלולות לגרום לדליפת מידע.
ההקשר מספק ערוץ צדדי של מידע שכל הקוד שלכם יכול להשתמש בו, אבל לא חייב להישלח ל-LLM. לדוגמה, אפשר להגביל את השאילתות של הכלי להיקף הזמין של המשתמש הנוכחי.
מבנה ההקשר
ההקשר חייב להיות אובייקט, אבל אתם יכולים להחליט מה יהיו המאפיינים שלו. בחלק מהמקרים, Genkit מאכלס את ההקשר באופן אוטומטי. לדוגמה, כשמשתמשים בסשנים מתמידים, המאפיין state
מתווסף באופן אוטומטי להקשר.
אחד מהשימושים הנפוצים ביותר בהקשר הוא לאחסון מידע על המשתמש הנוכחי. מומלץ להוסיף את הקשר האימות בפורמט הבא:
{
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
}
}
אובייקט ההקשר יכול לאחסן כל מידע שעשוי להידרש לכם במקום אחר בתהליך הביצוע.
שימוש בהקשר בפעולה
כדי להשתמש בהקשר בתוך פעולה, אפשר לגשת לעזרה בנושא הקשר שמסופקת באופן אוטומטי להגדרת הפונקציה:
זרימה
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;
});
כלי
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);
});
קובץ ההנחיה
כשמשתמשים בתבניות Dotprompt, ההקשר זמין באמצעות התחילית של המשתנה @
. לדוגמה, אפשר לגשת לאובייקט ההקשר של {auth: {name: 'Michael'}}
בתבנית ההנחיה כך:
---
input:
schema:
pirateStyle?: boolean
---
{{#if pirateStyle}}
Avast, {{@auth.name}}, how be ye today?
{{else}}
Hello, {{@auth.name}}, how are you today?
{{/if}}
מתן הקשר בזמן הריצה
כדי לספק הקשר לפעולה, מעבירים את אובייקט ההקשר כאפשרות בזמן הקריאה לפעולה.
תהליכים
const summarizeHistory = ai.defineFlow(/* ... */);
const summary = await summarizeHistory(friend.uid, {context: {auth: currentUser}});
דור
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},
});
הנחיות
const helloPrompt = ai.prompt('sayHello');
helloPrompt({pirateStyle: true}, {context: {auth: currentUser}});
העברה של הקשר ועקיפת ההגדרות
כברירת מחדל, כשמציינים הקשר, הוא מועבר באופן אוטומטי לכל הפעולות שנקראות כתוצאה מהקריאה המקורית. אם התהליך קורא לתהליכים אחרים, או אם היצירה קורא לכלים, אותו הקשר מסופק.
אם רוצים לשנות את ההקשר בתוך פעולה, אפשר להעביר אובייקט הקשר אחר שיחליף את הקיים:
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}});
});
כשהקשר מוחלף, הוא מופץ באותו אופן. בדוגמה הזו, כל הפעולות otherFlow
שתתבצעו במהלך הביצוע שלה יירשו את ההקשר שעבר שינוי.