يقدّم الإصدار 1.0 من Genkit العديد من تحسينات الميزات التي تحسّن الأداء بشكل عام، كما يتضمّن بعض التغييرات الأساسية. إذا كنت تعمل على تطوير التطبيقات باستخدام الإصدار 0.9 من Genkit، عليك تعديل رمز تطبيقك عند الترقية إلى أحدث إصدار من Genkit. يوضّح هذا الدليل أهم التغيُّرات ويشرح كيفية نقل تطبيقاتك الحالية بسلاسة.
واجهات برمجة التطبيقات التجريبية
نحن بصدد طرح قناة تجريبية غير مستقرة لواجهة برمجة التطبيقات، وسنترك واجهات برمجة تطبيقات جلسة المحادثة وGenkit في إصدار تجريبي بينما نواصل تحسينها. على وجه التحديد، تتوفّر الدوالّ التالية حاليًا في مساحة الاسم beta
:
ai.chat
ai.createSession
ai.loadSession
ai.currentSession
ai.defineFormat
ai.defineInterrupt
القديم:
import { genkit } from 'genkit';
const ai = genkit({...})
const session = ai.createSession({ ... })
جديد:
import { genkit } from 'genkit/beta';
const ai = genkit({...})
const session = ai.createSession({ ... })
القديم:
import { runFlow, streamFlow } from 'genkit/client';
جديد:
import { runFlow, streamFlow } from 'genkit/beta/client';
نقدّم لك حزمة @genkit-ai/express
الجديدة
تحتوي هذه الحزمة الجديدة على أدوات تسهّل إنشاء خادم Express.js باستخدام Genkit. يمكنك الاطّلاع على مزيد من التفاصيل حول هذا الموضوع على هذه الصفحة.
تم نقل startFlowServer
من جزء من عنصر genkit إلى حزمة
@genkit-ai/express
الجديدة هذه. لاستخدام startFlowServer، عليك
تعديل عمليات الاستيراد.
القديم:
const ai = genkit({ ... });
ai.startFlowServer({
flows: [myFlow1, myFlow2],
});
جديد:
import { startFlowServer } from '@genkit-ai/express';
startFlowServer({
flows: [myFlow1, myFlow2],
});
التغييرات في المسارات
هناك عدة تغييرات على مسارات الإحالات الناجحة في الإصدار 1.0:
- تم دمج
ai.defineStreamingFlow
فيai.defineFlow
، - تم استبدال
onFlow
بـonCallGenkit
، - تم نقل
run
إلىai.run
، - تم إجراء تغييرات على طريقة استخدام المصادقة.
تم نقل الدالة run
لوحدات التتبّع المخصّصة إلى جزء من العنصر genkit
، استخدِم ai.run
لتشغيلها بدلاً من ذلك.
القديم:
ai.defineFlow({name: 'banana'}, async (input) => {
const step = await run('myCode', async () => {
return 'something'
});
})
جديد:
ai.defineFlow({name: 'banana'}, async (input) => {
const step = await ai.run('myCode', async () => {
return 'something'
});
})
تمت إزالة ai.defineStreamingFlow
، استخدِم ai.defineFlow
بدلاً منه. بالإضافة إلى ذلك، تم نقل
streamingCallback
إلى حقل داخل الوسيطة الثانية لدالة
flow، وأصبح يُعرف الآن باسم sendChunk
.
القديم:
const flow = ai.defineStreamingFlow({name: 'banana'}, async (input, streamingCallback) => {
streamingCallback({chunk: 1});
})
const {stream} = await flow()
for await (const chunk of stream) {
// ...
}
جديد:
const flow = ai.defineFlow({name: 'banana'}, async (input, {context, sendChunk}) => {
sendChunk({chunk: 1});
})
const {stream, output} = flow.stream(input);
for await (const chunk of stream) {
// ...
}
تم تغيير اسم مصادقة FlowAuth إلى context. يمكنك الوصول إلى المصادقة كحقل داخل السياق:
القديم:
ai.defineFlow({name: 'banana'}, async (input) => {
const auth = getFlowAuth();
// ...
})
جديد:
ai.defineFlow({name: 'banana'}, async (input, { context }) => {
const auth = context.auth;
})
تم نقل onFlow
إلى حزمة firebase-functions/https
وتمت إعادة تسميتها إلى
onCallGenkit
. يعرض المقتطف التالي مثالاً على كيفية استخدامه.
قديم
import { onFlow } from "@genkit-ai/firebase/functions";
export const generatePoem = onFlow(
ai,
{
name: "jokeTeller",
inputSchema: z.string().nullable(),
outputSchema: z.string(),
streamSchema: z.string(),
},
async (type, streamingCallback) => {
const { stream, response } = await ai.generateStream(
`Tell me a longish ${type ?? "dad"} joke.`
);
for await (const chunk of stream) {
streamingCallback(chunk.text);
}
return (await response).text;
}
);
جديد:
import { onCallGenkit } from "firebase-functions/https";
import { defineSecret } from "firebase-functions/params";
import { genkit, z } from "genkit";
const apiKey = defineSecret("GOOGLE_GENAI_API_KEY");
const ai = genkit({
plugins: [googleAI()],
model: gemini15Flash,
});
export const jokeTeller = ai.defineFlow(
{
name: "jokeTeller",
inputSchema: z.string().nullable(),
outputSchema: z.string(),
streamSchema: z.string(),
},
async (type, { sendChunk }) => {
const { stream, response } = ai.generateStream(
`Tell me a longish ${type ?? "dad"} joke.`
);
for await (const chunk of stream) {
sendChunk(chunk.text);
}
return (await response).text;
}
);
export const tellJoke = onCallGenkit({ secrets: [apiKey] }, jokeTeller);
تمت إزالة سياسات المصادقة من defineFlow
. أصبح التعامل مع سياسات المصادقة
يعتمد الآن على الخادم.
القديم:
export const simpleFlow = ai.defineFlow(
{
name: 'simpleFlow',
authPolicy: (auth, input) => {
// auth policy
},
},
async (input) => {
// Flow logic here...
}
);
يعرض المقتطف التالي مثالاً على معالجة المصادقة في Express.
جديد:
import { UserFacingError } from 'genkit';
import { ContextProvider, RequestData } from 'genkit/context';
import { expressHandler, startFlowServer } from '@genkit-ai/express';
const context: ContextProvider<Context> = (req: RequestData) => {
return {
auth: parseAuthToken(req.headers['authorization']),
};
};
export const simpleFlow = ai.defineFlow(
{
name: 'simpleFlow',
},
async (input, { context }) => {
if (!context.auth) {
throw new UserFacingError("UNAUTHORIZED", "Authorization required.");
}
if (input.uid !== context.auth.uid) {
throw new UserFacingError("UNAUTHORIZED", "You may only summarize your own profile data.");
}
// Flow logic here...
}
);
const app = express();
app.use(express.json());
app.post(
'/simpleFlow',
expressHandler(simpleFlow, { context })
);
app.listen(8080);
// or
startFlowServer(
flows: [withContextProvider(simpleFlow, context)],
port: 8080
);
لمزيد من التفاصيل، يُرجى الرجوع إلى مستندات المصادقة.
يعرض المقتطف التالي مثالاً على معالجة المصادقة في Cloud Functions لـ Firebase:
import { genkit } from 'genkit';
import { onCallGenkit } from 'firebase-functions/https';
const ai = genkit({ ... });;
const simpleFlow = ai.defineFlow({
name: 'simpleFlow',
}, async (input) => {
// Flow logic here...
});
export const selfSummary = onCallGenkit({
authPolicy: (auth, data) => auth?.token?.['email_verified'] && auth?.token?.['admin'],
}, simpleFlow);
الطلبات
لقد أجرينا العديد من التغييرات والتحسينات على الطلبات.
يمكنك تحديد نماذج منفصلة للطلبات ورسائل النظام:
const hello = ai.definePrompt({
name: 'hello',
system: 'talk like a pirate.',
prompt: 'hello {{ name }}',
input: {
schema: z.object({
name: z.string()
})
}
});
const { text } = await hello({name: 'Genkit'});
بدلاً من ذلك، يمكنك تحديد طلبات متعدّدة الرسائل في حقل الرسائل:
const hello = ai.definePrompt({
name: 'hello',
messages: '{{ role "system" }} talk like a pirate. {{ role "user" }} hello {{ name }}',
input: {
schema: z.object({
name: z.string()
})
}
});
بدلاً من نماذج الطلبات، يمكنك استخدام دالة:
ai.definePrompt({
name: 'hello',
prompt: async (input, { context }) => {
return `hello ${input.name}`
},
input: {
schema: z.object({
name: z.string()
})
}
});
يمكنك الوصول إلى السياق (بما في ذلك معلومات المصادقة) من داخل الطلب:
const hello = ai.definePrompt({
name: 'hello',
messages: 'hello {{ @auth.email }}',
});
لا تتطلّب دوالّ البث await
.
القديم:
const { stream, response } = await ai.generateStream(`hi`);
const { stream, output } = await myflow.stream(`hi`);
جديد:
const { stream, response } = ai.generateStream(`hi`);
const { stream, output } = myflow.stream(`hi`);
توفّر Embed نوع إرجاع جديدًا
لقد أضفنا إمكانية استخدام النماذج المتعدّدة الوسائط. بدلاً من عرض سوى متجه تضمين واحد، تعرض دالة Embed مصفوفة من عناصر التضمين، يحتوي كل منها على مَعلمة تضمين وبيانات وصفية.
القديم:
const response = await ai.embed({embedder, content, options}); // returns number[]
جديد:
const response = await ai.embed({embedder, content, options}); // returns Embedding[]
const firstEmbeddingVector = response[0].embedding; // is number[]