आकलन

आकलन, टेस्टिंग का एक तरीका है. इससे आपको एलएलएम के जवाबों की पुष्टि करने और यह पक्का करने में मदद मिलती है कि वे आपकी क्वालिटी से जुड़ी शर्तों को पूरा करते हैं.

Firebase Genkit, प्लग इन की मदद से तीसरे पक्ष के आकलन टूल के साथ काम करता है. साथ ही, इसमें बेहतरीन निगरानी की सुविधाएं भी होती हैं. इन सुविधाओं से, एलएलएम की मदद से काम करने वाले ऐप्लिकेशन की रनटाइम स्थिति के बारे में अहम जानकारी मिलती है. Genkit टूल की मदद से, इनपुट, आउटपुट, और बीच के चरणों की जानकारी के साथ-साथ डेटा अपने-आप निकाला जा सकता है. इससे एलएलएम के जवाबों की क्वालिटी का आकलन किया जा सकता है. साथ ही, अपने सिस्टम के बिल्डिंग ब्लॉक की परफ़ॉर्मेंस को भी समझा जा सकता है.

आकलन के टाइप

Genkit, दो तरह के आकलन के साथ काम करता है:

  • अनुमान पर आधारित आकलन: इस तरह का आकलन, पहले से तय किए गए इनपुट के कलेक्शन के आधार पर किया जाता है. साथ ही, इससे जुड़े आउटपुट की क्वालिटी का आकलन किया जाता है.

    यह आकलन का सबसे आम टाइप है. यह ज़्यादातर इस्तेमाल के उदाहरणों के लिए सही है. इस तरीके से, हर बार होने वाले आकलन के लिए सिस्टम के असल आउटपुट की जांच की जाती है.

    नतीजों को देखकर, मैन्युअल तरीके से क्वालिटी का आकलन किया जा सकता है. इसके अलावा, आकलन को ऑटोमेट करने के लिए, आकलन करने वाली मेट्रिक का इस्तेमाल किया जा सकता है.

  • रॉ आकलन: इस तरह के आकलन में, किसी भी अनुमान के बिना इनपुट की क्वालिटी का सीधे आकलन किया जाता है. आम तौर पर, इस तरीके का इस्तेमाल मेट्रिक का इस्तेमाल करके, ऑटोमेटेड आकलन के साथ किया जाता है. आकलन के लिए सभी ज़रूरी फ़ील्ड (उदाहरण के लिए, input, context, output, और reference) इनपुट डेटासेट में मौजूद होनी चाहिए. यह तब काम आता है, जब आपके पास किसी बाहरी सोर्स से डेटा आता है.उदाहरण के लिए, आपके प्रोडक्शन ट्रैस से इकट्ठा किया गया डेटा. साथ ही, आपको इकट्ठा किए गए डेटा की क्वालिटी का निष्पक्ष तरीके से आकलन करना हो.

    ज़्यादा जानकारी के लिए, इस पेज का बेहतर इस्तेमाल सेक्शन देखें.

इस सेक्शन में, Genkit का इस्तेमाल करके अनुमान के आधार पर आकलन करने का तरीका बताया गया है.

तुरंत शुरू करना

सेटअप

  1. किसी मौजूदा Genkit ऐप्लिकेशन का इस्तेमाल करें या [शुरू करने के लिए](शुरू करने के लिए) गाइड का पालन करके नया ऐप्लिकेशन बनाएं.
  2. रेड, ऐंबर, ग्रीन (आरएजी) मॉडल का इस्तेमाल करके, किसी ऐप्लिकेशन का आकलन करने के लिए, नीचे दिया गया कोड जोड़ें. इस गाइड के लिए, हम डमी रीट्रिवर का इस्तेमाल करते हैं, जो हमेशा एक ही दस्तावेज़ दिखाता है. ```js import { genkit, z, Document } from "genkit"; import { googleAI, gemini15Flash, gemini15Pro, } from "@genkit-ai/googleai"; // Initialize Genkit export const ai = genkit ({ plugins: [ googleAI(), ] }); // Dummy retriever that always returns the same docs export const dummyRetriever = ai.defineRetriever( { name: "dummyRetriever", }, async (i) => { const facts = [ "Dog is man's best friend", "Dogs have evolved and were domesticated from wolves", ]; // Just return facts as documents. return { documents: facts.map((t) => Document.fromText(t)) }; } ); // A simple question-answering flow export const qaFlow = ai.defineFlow({ name: 'qaFlow', inputSchema: z.string(), outputSchema: z.string(), }, async (query) => { const factDocs = await ai.retrieve({ retriever: dummyRetriever, query, options: { k: 2 }, }); const llmResponse = await ai.generate({ model: gemini15Flash, prompt: `Answer this question with the given context ${query}`, docs: factDocs, }); return llmResponse.text; } ); ```
  3. (ज़रूरी नहीं) अपने ऐप्लिकेशन में, आकलन के दौरान इस्तेमाल करने के लिए, आकलन मेट्रिक जोड़ें. इस गाइड में, `genkitEval` प्लग इन की `MALICIOUSNESS` मेट्रिक का इस्तेमाल किया गया है. ```js import { genkitEval, GenkitMetric } from "@genkit-ai/evaluator"; import { gemini15Pro } from "@genkit-ai/googleai"; export const ai = genkit ({ plugins: [ ... // Add this plugin to your Genkit initialization block genkitEval({ judge: gemini15Pro, metrics: [GenkitMetric.MALICIOUSNESS], }), ] }); ``` **ध्यान दें:** ऊपर दिए गए कॉन्फ़िगरेशन के लिए, [`@genkit-ai/evaluator`](https://www.npmjs.com/package/@genkit-ai/evaluator) पैकेज इंस्टॉल करना ज़रूरी है. ```posix-terminal npm install @genkit-ai/evaluator ```
  4. Genkit ऐप्लिकेशन शुरू करें ```posix-terminal genkit start -- ```

डेटासेट बनाना

डेटासेट बनाएं, ताकि हम अपने फ़्लो का आकलन करने के लिए, उन उदाहरणों का इस्तेमाल कर सकें.

  1. http://localhost:4000 पर जाकर, डेवलपर यूज़र इंटरफ़ेस (यूआई) खोलें. इसके बाद, डेटासेट पेज खोलने के लिए, डेटासेट बटन पर क्लिक करें.

  2. डेटासेट बनाने का डायलॉग बॉक्स खोलने के लिए, डेटासेट बनाएं बटन पर क्लिक करें.

    a. अपने नए डेटासेट के लिए datasetId दें. इस गाइड में myFactsQaDataset का इस्तेमाल किया गया है.

    b. Flow डेटासेट टाइप चुनें.

    c. पुष्टि करने के लिए टारगेट फ़ील्ड को खाली छोड़ें और सेव करें पर क्लिक करें

  3. आपका नया डेटासेट पेज दिखेगा, जिसमें खाली डेटासेट दिखेगा. इसमें उदाहरण जोड़ने के लिए, यह तरीका अपनाएं:

    a. उदाहरण एडिटर पैनल खोलने के लिए, उदाहरण जोड़ें बटन पर क्लिक करें.

    b. सिर्फ़ input फ़ील्ड को भरना ज़रूरी है. input फ़ील्ड में "Who is man's best friend?" डालें और अपने डेटासेट में उदाहरण जोड़ने के लिए, सेव करें पर क्लिक करें.

    c. ज़्यादा उदाहरण जोड़ने के लिए, (a) और (b) चरण दोहराएं. इस गाइड में, डेटासेट में इन उदाहरण के इनपुट जोड़े गए हैं:

    "Can I give milk to my cats?"
    "From which animals did dogs evolve?"
    

    इस चरण के आखिर तक, आपके डेटासेट में ऊपर बताई गई वैल्यू के साथ तीन उदाहरण होने चाहिए.

आकलन चलाना और नतीजे देखना

फ़्लो का आकलन शुरू करने के लिए, डेवलपर यूज़र इंटरफ़ेस (यूआई) में Evaluations टैब पर क्लिक करें. इसके बाद, नया आकलन चलाएं बटन पर क्लिक करके, आकलन शुरू करें.

  1. किसी फ़्लो का आकलन करने के लिए, Flow रेडियो बटन चुनें.

  2. आकलन करने के लिए, टारगेट फ़्लो के तौर पर qaFlow चुनें.

  3. इवैलुएशन के लिए इस्तेमाल करने के लिए, टारगेट डेटासेट के तौर पर myFactsQaDataset चुनें.

  4. (ज़रूरी नहीं) अगर आपने Genkit प्लग इन का इस्तेमाल करके, कोई एवैल्यूएटर मेट्रिक इंस्टॉल की है, तो इन मेट्रिक को इस पेज पर देखा जा सकता है. वे मेट्रिक चुनें जिनका इस्तेमाल आपको इस आकलन के साथ करना है. यह पूरी तरह से ज़रूरी नहीं है: इस चरण को छोड़ने पर भी, आकलन के नतीजे दिखेंगे. हालांकि, इनमें कोई मेट्रिक नहीं होगी.

  5. आखिर में, आकलन शुरू करने के लिए आकलन करें पर क्लिक करें. जिस फ़्लो को टेस्ट किया जा रहा है उसके हिसाब से, इसमें कुछ समय लग सकता है. आकलन पूरा होने के बाद, आपको नतीजे देखने के लिए एक लिंक के साथ, 'जांच पूरी हो गई' मैसेज दिखेगा. समीक्षा की जानकारी वाले पेज पर जाने के लिए, लिंक पर क्लिक करें.

इस पेज पर, अपने आकलन की जानकारी देखी जा सकती है. इसमें ओरिजनल इनपुट, निकाला गया कॉन्टेक्स्ट, और मेट्रिक (अगर कोई हो) शामिल है.

मुख्य कॉन्सेप्ट

शब्दावली

  • इवैलुएशन: इवैलुएशन एक ऐसी प्रोसेस है जिसमें सिस्टम की परफ़ॉर्मेंस का आकलन किया जाता है. Genkit में, ऐसा सिस्टम आम तौर पर Genkit प्राइमिटिव होता है, जैसे कि कोई फ़्लो या कोई मॉडल. आकलन, अपने-आप हो सकता है या मैन्युअल (मनुष्य की ओर से किया गया आकलन) हो सकता है.

  • एक साथ कई अनुमान अनुमान लगाने का मतलब है, किसी फ़्लो या मॉडल पर इनपुट चलाकर, उससे जुड़ा आउटपुट पाना. एक साथ कई इनपुट पर अनुमान लगाने की प्रोसेस को बल्क इंफ़रेंस कहते हैं.

  • मेट्रिक आकलन मेट्रिक एक ऐसी शर्त होती है जिस पर किसी अनुमान को स्कोर दिया जाता है. उदाहरण के लिए, सटीक होना, भरोसेमंद होना, नुकसान पहुंचाने वाला होना, आउटपुट अंग्रेज़ी में होना वगैरह.

  • डेटासेट डेटासेट, उदाहरणों का एक कलेक्शन होता है. इसका इस्तेमाल, अनुमान के आधार पर किए जाने वाले आकलन के लिए किया जाता है. आम तौर पर, डेटासेट में input और वैकल्पिक reference फ़ील्ड होते हैं. reference फ़ील्ड से, आकलन के अनुमान वाले चरण पर असर नहीं पड़ता है. हालांकि, इसे किसी भी आकलन मेट्रिक में बिना किसी बदलाव के पास किया जाता है. Genkit में, डेवलपर यूज़र इंटरफ़ेस (यूआई) की मदद से डेटासेट बनाया जा सकता है. Genkit में दो तरह के डेटासेट होते हैं: फ़्लो डेटासेट और मॉडल डेटासेट.

स्कीमा की पुष्टि करना

डेटासेट के टाइप के आधार पर, डेवलपर यूज़र इंटरफ़ेस (यूआई) में स्कीमा की पुष्टि करने की सुविधा मिलती है:

  • फ़्लो डेटासेट, Genkit ऐप्लिकेशन में मौजूद फ़्लो के हिसाब से, डेटासेट के input और reference फ़ील्ड की पुष्टि करते हैं. स्कीमा की पुष्टि करना ज़रूरी नहीं है. इसे सिर्फ़ तब लागू किया जाता है, जब टारगेट फ़्लो पर स्कीमा तय किया गया हो.

  • मॉडल डेटासेट में स्कीमा अपने-आप बन जाता है. यह string और GenerateRequest, दोनों तरह के इनपुट टाइप के साथ काम करता है. स्ट्रिंग की पुष्टि करने की सुविधा से, आसान टेक्स्ट प्रॉम्प्ट का आकलन करने का एक आसान तरीका मिलता है. वहीं, GenerateRequest की मदद से, इस्तेमाल के बेहतर उदाहरणों (जैसे, मॉडल पैरामीटर, मैसेज का इतिहास, टूल वगैरह) को पूरा कंट्रोल मिलता है. GenerateRequest का पूरा स्कीमा, हमारे एपीआई के रेफ़रंस दस्तावेज़ों में देखा जा सकता है.

इस्तेमाल किए जा सकने वाले एवैल्यूअर

Genkit के एवैल्यूएटर

Genkit में कुछ नेटिव एवैल्यूएटर शामिल हैं. ये RAGAS से प्रेरित हैं. इनकी मदद से, आपको शुरुआत करने में मदद मिलेगी:

  • सटीक होना -- इससे पता चलता है कि जनरेट किए गए जवाब में दिए गए कॉन्टेक्स्ट के हिसाब से तथ्यों का सही होना
  • जवाब कितना काम का है -- इससे पता चलता है कि जनरेट किया गया जवाब, दिए गए प्रॉम्प्ट के लिए कितना काम का है
  • नुकसान पहुंचाने के इरादे से बनाया गया कॉन्टेंट -- इससे यह पता चलता है कि जनरेट किए गए कॉन्टेंट का मकसद किसी को धोखा देना, नुकसान पहुंचाना या उसका गलत इस्तेमाल करना है या नहीं

एवैल्यूएटर प्लग इन

Genkit, प्लग इन की मदद से अन्य एवैल्यूएटर के साथ काम करता है. जैसे, Vertex के रैपिड एवैल्यूएटर, जिन्हें VertexAI प्लग इन की मदद से ऐक्सेस किया जा सकता है.

बेहतर इस्तेमाल के लिए

सीएलआई का इस्तेमाल करके आकलन करना

Genkit CLI, आकलन करने के लिए एक बेहतर एपीआई उपलब्ध कराता है. यह सुविधा खास तौर पर उन एनवायरमेंट में काम आती है जहां डेवलपर यूज़र इंटरफ़ेस (यूआई) उपलब्ध नहीं होता. जैसे, सीआई/सीडी वर्कफ़्लो में.

Genkit सीएलआई, आकलन के लिए तीन मुख्य निर्देश देता है: eval:flow, eval:extractData, और eval:run.

eval:flow निर्देश

eval:flow कमांड, इनपुट डेटासेट पर अनुमान के आधार पर आकलन करता है. यह डेटासेट, JSON फ़ाइल के तौर पर या अपने Genkit रनटाइम में मौजूदा डेटासेट का रेफ़रंस देकर दिया जा सकता है.

# Referencing an existing dataset
genkit eval:flow qaFlow --input myFactsQaDataset
# or, using a dataset from a file
genkit eval:flow qaFlow --input testInputs.json

यहां testInputs.json, ऑब्जेक्ट का एक कलेक्शन होना चाहिए. इसमें input फ़ील्ड और reference फ़ील्ड (ज़रूरी नहीं) शामिल होना चाहिए. जैसे:

[
  {
    "input": "What is the French word for Cheese?",
  },
  {
    "input": "What green vegetable looks like cauliflower?",
    "reference": "Broccoli"
  }
]

अगर आपके फ़्लो को पुष्टि की ज़रूरत है, तो --auth आर्ग्युमेंट का इस्तेमाल करके इसकी जानकारी दी जा सकती है:

genkit eval:flow qaFlow --input testInputs.json --auth "{\"email_verified\": true}"

डिफ़ॉल्ट रूप से, eval:flow और eval:run निर्देश, आकलन के लिए सभी उपलब्ध मेट्रिक का इस्तेमाल करते हैं. कॉन्फ़िगर किए गए एवैल्यूअर के सबसेट पर चलाने के लिए, --evaluators फ़्लैग का इस्तेमाल करें और नाम के हिसाब से एवैल्यूअर की सूची दें. सूची में, एवैल्यूअर के नामों को कॉमा लगाकर अलग करें:

genkit eval:flow qaFlow --input testInputs.json --evaluators=genkit/faithfulness,genkit/answer_relevancy

localhost:4000/evaluate पर जाकर, डेवलपर यूज़र इंटरफ़ेस (यूआई) में, अपने आकलन के नतीजे देखे जा सकते हैं.

eval:extractData और eval:run निर्देश

रॉ इवैल्यूएशन की सुविधा देने के लिए, Genkit ऐसे टूल उपलब्ध कराता है जिनकी मदद से, ट्रेस से डेटा निकाला जा सकता है और निकाले गए डेटा पर इवैल्यूएशन मेट्रिक चलाई जा सकती हैं. उदाहरण के लिए, यह तब मददगार होता है, जब आप आकलन के लिए किसी दूसरे फ़्रेमवर्क का इस्तेमाल कर रहे हों या आउटपुट क्वालिटी की स्थानीय तौर पर जांच करने के लिए, किसी दूसरे एनवायरमेंट से अनुमान इकट्ठा कर रहे हों.

Genkit फ़्लो को एक साथ चलाया जा सकता है. साथ ही, उसमें एक यूनीक लेबल जोड़ा जा सकता है. इसका इस्तेमाल, इवैल्यूएशन डेटासेट निकालने के लिए किया जा सकता है. रॉ आकलन डेटासेट, आकलन मेट्रिक के लिए इनपुट का एक कलेक्शन होता है. इसमें कोई अनुमान लगाने से पहले कोई कार्रवाई नहीं की जाती.

अपने टेस्ट इनपुट पर फ़्लो चलाएं:

genkit flow:batchRun qaFlow testInputs.json --label firstRunSimple

इवैलुएशन का डेटा निकालें:

genkit eval:extractData qaFlow --label firstRunSimple --output factsEvalDataset.json

एक्सपोर्ट किए गए डेटा का फ़ॉर्मैट, पहले दिखाए गए डेटासेट फ़ॉर्मैट से अलग है. इसकी वजह यह है कि इस डेटा का इस्तेमाल, सीधे तौर पर आकलन करने वाली मेट्रिक के साथ किया जाता है. इसके लिए, अनुमान लगाने की कोई प्रक्रिया नहीं अपनानी पड़ती. यहां निकाले गए डेटा का सिंटैक्स दिया गया है.

Array<{
  "testCaseId": string,
  "input": any,
  "output": any,
  "context": any[],
  "traceIds": string[],
}>;

डेटा एक्सट्रैक्टर, अपने-आप रिट्रिवर ढूंढता है और जनरेट किए गए दस्तावेज़ों को कॉन्टेक्स्ट कलेक्शन में जोड़ता है. eval:run कमांड का इस्तेमाल करके, निकाले गए इस डेटासेट पर, आकलन मेट्रिक चलाई जा सकती हैं.

genkit eval:run factsEvalDataset.json

डिफ़ॉल्ट रूप से, eval:run उन सभी एवैल्यूएटर के लिए चलता है जिन्हें कॉन्फ़िगर किया गया है. eval:flow की तरह ही, eval:run के नतीजे, localhost:4000/evaluate पर मौजूद डेवलपर यूज़र इंटरफ़ेस (यूआई) के आकलन वाले पेज पर दिखते हैं.

कस्टम एक्सट्रैक्टर

Genkit, आकलन करते समय ज़रूरी फ़ील्ड (input, output, और context) को निकालने के लिए, सही डिफ़ॉल्ट लॉजिक उपलब्ध कराता है. हालांकि, आपको इन फ़ील्ड के लिए, डेटा निकालने के लॉजिक पर ज़्यादा कंट्रोल की ज़रूरत पड़ सकती है. Genkit, कस्टम एक्सट्रैक्टर की मदद से ऐसा करता है. eval:extractData और eval:flow निर्देशों में इस्तेमाल करने के लिए, कस्टम एक्सट्रैक्टर दिए जा सकते हैं.

सबसे पहले, तैयारी के तौर पर, हमारे qaFlow उदाहरण में एक सहायक चरण जोड़ें:

export const qaFlow = ai.defineFlow({
    name: 'qaFlow',
    inputSchema: z.string(),
    outputSchema: z.string(),
  },
  async (query) => {
    const factDocs = await ai.retrieve({
      retriever: dummyRetriever,
      query,
      options: { k: 2 },
    });
    const factDocsModified = await run('factModified', async () => {
        // Let us use only facts that are considered silly. This is a 
        // hypothetical step for demo purposes, you may perform any 
        // arbitrary task inside a step and reference it in custom 
        // extractors.
        //
        // Assume you have a method that checks if a fact is silly
        return factDocs.filter(d => isSillyFact(d.text));
    });

    const llmResponse = await ai.generate({
      model: gemini15Flash,
      prompt: `Answer this question with the given context ${query}`,
      docs: factDocs,
    });
    return llmResponse.text;
  }
);

इसके बाद, इस फ़्लो का आकलन करते समय factModified चरण के आउटपुट का इस्तेमाल करने के लिए, कस्टम एक्सट्रैक्टर कॉन्फ़िगर करें.

अगर आपके पास कस्टम एक्सट्रैक्टर को कॉन्फ़िगर करने के लिए, कोई टूल्स-कॉन्फ़िगरेशन फ़ाइल नहीं है, तो अपने प्रोजेक्ट रूट में genkit-tools.conf.js नाम की एक फ़ाइल जोड़ें.

cd /path/to/your/genkit/app
touch genkit-tools.conf.js

टूल्स कॉन्फ़िगरेशन फ़ाइल में, यह कोड जोड़ें:

module.exports = {
  evaluators: [
    {
      actionRef: '/flow/qaFlow',
      extractors: {
        context: { outputOf: 'factModified' },
      },
    },
  ],
};

यह कॉन्फ़िगरेशन, Genkit टूल के डिफ़ॉल्ट एक्सट्रैक्टर को बदल देता है. खास तौर पर, इस फ़्लो का आकलन करते समय, context के तौर पर क्या माना जाए, यह बदल देता है.

फिर से आकलन करने पर पता चलता है कि अब कॉन्टेक्स्ट, factModified चरण के आउटपुट के तौर पर पॉप्युलेट हो गया है.

genkit eval:flow qaFlow --input testInputs.json

आकलन करने वाले एक्सट्रैक्टर इस तरह से तय किए जाते हैं:

  • evaluators फ़ील्ड, EvaluatorConfig ऑब्जेक्ट का कलेक्शन स्वीकार करता है. इन ऑब्जेक्ट का दायरा, flowName से तय होता है
  • extractors एक ऑब्जेक्ट है, जो एक्सट्रैक्टर के बदलावों के बारे में बताता है. फ़िलहाल, extractors में [input, output, context] कुंजियों का इस्तेमाल किया जा सकता है. वैल्यू के लिए ये टाइप इस्तेमाल किए जा सकते हैं:
    • string - यह चरण का नाम होना चाहिए, जिसे स्ट्रिंग के तौर पर बताया गया हो. इस चरण का आउटपुट, इस पासकोड के लिए निकाला जाता है.
    • { inputOf: string } या { outputOf: string } - ये ऑब्जेक्ट, किसी चरण के खास चैनलों (इनपुट या आउटपुट) को दिखाते हैं. उदाहरण के लिए, { inputOf: 'foo-step' } इस कुंजी के लिए, चरण foo-step का इनपुट निकालेगा.
    • (trace) => string; - ज़्यादा सुविधा के लिए, ऐसा फ़ंक्शन दिया जा सकता है जो Genkit ट्रैक को स्वीकार करता है और any-टाइप की वैल्यू दिखाता है. साथ ही, इस फ़ंक्शन में डेटा निकालने का लॉजिक भी तय किया जा सकता है. TraceData के सटीक स्कीमा के लिए, genkit/genkit-tools/common/src/types/trace.ts देखें.

ध्यान दें: इन सभी एक्सट्रैक्टर के लिए, निकाला गया डेटा, एक्सट्रैक्टर के हिसाब से होता है. उदाहरण के लिए, अगर context: { outputOf: 'foo-step' } का इस्तेमाल किया जाता है और foo-step ऑब्जेक्ट का कलेक्शन दिखाता है, तो निकाला गया कॉन्टेक्स्ट भी ऑब्जेक्ट का कलेक्शन होता है.

एलएलएम का इस्तेमाल करके टेस्ट डेटा को सिंथेटिक बनाना

यहां एक फ़्लो का उदाहरण दिया गया है, जिसमें संभावित उपयोगकर्ता के सवाल जनरेट करने के लिए PDF फ़ाइल का इस्तेमाल किया गया है.

import { genkit, run, z } from "genkit";
import { googleAI, gemini15Flash } from "@genkit-ai/googleai";
import { chunk } from "llm-chunk"; // npm i llm-chunk
import path from "path";
import { readFile } from "fs/promises";
import pdf from "pdf-parse"; // npm i pdf-parse

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

const chunkingConfig = {
  minLength: 1000, // number of minimum characters into chunk
  maxLength: 2000, // number of maximum characters into chunk
  splitter: "sentence", // paragraph | sentence
  overlap: 100, // number of overlap chracters
  delimiters: "", // regex for base split method
} as any;

async function extractText(filePath: string) {
  const pdfFile = path.resolve(filePath);
  const dataBuffer = await readFile(pdfFile);
  const data = await pdf(dataBuffer);
  return data.text;
}

export const synthesizeQuestions = ai.defineFlow(
  {
    name: "synthesizeQuestions",
    inputSchema: z.string().describe("PDF file path"),
    outputSchema: z.array(z.string()),
  },
  async (filePath) => {
    filePath = path.resolve(filePath);
    // `extractText` loads the PDF and extracts its contents as text.
    const pdfTxt = await run("extract-text", () => extractText(filePath));

    const chunks = await run("chunk-it", async () =>
      chunk(pdfTxt, chunkingConfig)
    );

    const questions: string[] = [];
    for (var i = 0; i < chunks.length; i++) {
      const qResponse = await ai.generate({
        model: gemini15Flash,
        prompt: {
          text: `Generate one question about the text below: ${chunks[i]}`,
        },
      });
      questions.push(qResponse.text);
    }
    return questions;
  }
);

इसके बाद, इस निर्देश का इस्तेमाल करके डेटा को फ़ाइल में एक्सपोर्ट किया जा सकता है और उसका इस्तेमाल, आकलन के लिए किया जा सकता है.

genkit flow:run synthesizeQuestions '"my_input.pdf"' --output synthesizedQuestions.json