การสร้างเนื้อหาด้วยโมเดล AI

หัวใจสำคัญของ Generative AI คือโมเดล AI ปัจจุบันตัวอย่างโมเดล Generative ที่โดดเด่นที่สุด 2 รายการ ได้แก่ โมเดลภาษาขนาดใหญ่ (LLM) และโมเดลการสร้างรูปภาพ โมเดลเหล่านี้จะรับอินพุตที่เรียกว่าพรอมต์ (โดยปกติแล้วจะเป็นข้อความ รูปภาพ หรือทั้ง 2 อย่างรวมกัน) และสร้างเอาต์พุตเป็นข้อความ รูปภาพ หรือแม้แต่เสียงหรือวิดีโอ

ผลลัพธ์ของโมเดลเหล่านี้น่าเชื่อถืออย่างน่าประหลาดใจ LLM จะสร้างข้อความที่ดูเหมือนว่ามนุษย์เขียนขึ้น และโมเดลการสร้างรูปภาพสามารถสร้างรูปภาพที่ใกล้เคียงกับรูปถ่ายจริงหรืออาร์ตเวิร์กที่มนุษย์สร้างขึ้น

นอกจากนี้ LLM ยังพิสูจน์แล้วว่าสามารถทำงานได้มากกว่าการสร้างข้อความธรรมดา

  • การเขียนโปรแกรมคอมพิวเตอร์
  • การวางแผนงานย่อยที่จำเป็นต่องานขนาดใหญ่
  • การจัดระเบียบข้อมูลที่ไม่เป็นระเบียบ
  • ทำความเข้าใจและดึงข้อมูลสารสนเทศออกจากชุดข้อความ
  • ติดตามและดําเนินกิจกรรมอัตโนมัติตามคําอธิบายกิจกรรมที่เป็นข้อความ

มีโมเดลมากมายให้คุณเลือกใช้จากผู้ให้บริการหลายราย โมเดลแต่ละรูปแบบจะมีจุดแข็งและจุดอ่อนเป็นของตัวเอง และโมเดลหนึ่งอาจทำงานอย่างใดอย่างหนึ่งได้ดี แต่ทำงานอย่างอื่นได้ไม่ดีนัก แอปที่ใช้ Generative AI มักจะได้รับประโยชน์จากการใช้โมเดลหลายแบบที่แตกต่างกัน ทั้งนี้ขึ้นอยู่กับงานที่ทำอยู่

ในฐานะนักพัฒนาแอป คุณมักไม่โต้ตอบกับโมเดล Generative AI โดยตรง แต่จะใช้ผ่านบริการที่มีให้บริการเป็น Web API แม้ว่าบริการเหล่านี้มักจะมีฟังก์ชันการทำงานที่คล้ายกัน แต่บริการทั้งหมดก็ให้บริการผ่าน API ที่ต่างกันและไม่เข้ากันได้ หากต้องการใช้บริการหลายรูปแบบ คุณต้องใช้ SDK ที่เป็นกรรมสิทธิ์ของแต่ละบริการ ซึ่งอาจใช้ร่วมกันไม่ได้ และหากต้องการอัปเกรดจากรุ่นหนึ่งเป็นรุ่นล่าสุดที่มีประสิทธิภาพมากที่สุด คุณอาจต้องสร้างการผสานรวมนั้นใหม่ทั้งหมด

Genkit แก้ปัญหานี้ด้วยอินเทอร์เฟซเดียวที่แยกรายละเอียดการเข้าถึงบริการโมเดล Generative AI ที่อาจเป็นไปได้ออก โดยมีการใช้งานที่สร้างไว้ล่วงหน้าหลายรายการ การสร้างแอปที่ทำงานด้วยระบบ AI โดยอิงตาม Genkit จะช่วยลดความซับซ้อนของกระบวนการเรียกใช้ Generative AI ครั้งแรก และช่วยให้คุณรวมโมเดลหลายรายการเข้าด้วยกันหรือสลับโมเดลหนึ่งกับอีกโมเดลหนึ่งได้อย่างง่ายดายเมื่อมีโมเดลใหม่เกิดขึ้น

ก่อนเริ่มต้น

หากต้องการเรียกใช้ตัวอย่างโค้ดในหน้านี้ ให้ทําตามขั้นตอนในคู่มือการเริ่มต้นใช้งานก่อน ตัวอย่างทั้งหมดจะถือว่าคุณได้ติดตั้ง Genkit ไว้เป็น Dependency ในโปรเจ็กต์แล้ว

รุ่นที่ Genkit รองรับ

Genkit ได้รับการออกแบบให้ยืดหยุ่นพอที่จะใช้บริการโมเดล Generative AI ใดก็ได้ ไลบรารีหลักจะกำหนดอินเทอร์เฟซทั่วไปสำหรับการทำงานกับโมเดล และปลั๊กอินโมเดลจะกำหนดรายละเอียดการใช้งานสำหรับการทำงานกับโมเดลที่เฉพาะเจาะจงและ API ของโมเดลนั้น

ทีม Genkit ดูแลรักษาปลั๊กอินสำหรับการทำงานกับโมเดลที่ Vertex AI, Google Generative AI และ Ollama ให้บริการ

  • ครอบครัว LLM ของ Gemini ผ่านปลั๊กอิน Vertex AI ของ Google Cloud
  • ครอบครัว LLM ของ Gemini ผ่านปลั๊กอิน AI ของ Google
  • โมเดลการสร้างรูปภาพ Imagen2 และ Imagen3 ผ่าน Vertex AI ของ Google Cloud
  • ครอบครัว LLM ของ Claude 3 จาก Anthropic ผ่านสวนโมเดลของ Google Cloud Vertex AI
  • Gemma 2, Llama 3 และโมเดลแบบเปิดอื่นๆ อีกมากมายผ่านปลั๊กอิน Ollama (คุณต้องโฮสต์เซิร์ฟเวอร์ Ollama ด้วยตนเอง)

นอกจากนี้ ยังมีปลั๊กอินที่ชุมชนรองรับหลายรายการซึ่งมีอินเทอร์เฟซสำหรับโมเดลเหล่านี้

คุณดูข้อมูลเพิ่มเติมได้โดยค้นหาแพ็กเกจที่ติดแท็ก genkit-model ใน npmjs.org

กำลังโหลดและกําหนดค่าปลั๊กอินโมเดล

คุณต้องโหลดและกำหนดค่าปลั๊กอินโมเดลก่อนจึงจะใช้ Genkit เพื่อเริ่มสร้างเนื้อหาได้ หากคุณมาจากคู่มือการเริ่มต้นใช้งาน แสดงว่าคุณได้ทำขั้นตอนนี้ไปแล้ว หรือดูคำแนะนำเริ่มต้นใช้งานหรือเอกสารประกอบของปลั๊กอินแต่ละรายการ แล้วทำตามขั้นตอนในเอกสารประกอบก่อนดำเนินการต่อ

เมธอด generate()

ใน Genkit อินเทอร์เฟซหลักที่คุณใช้โต้ตอบกับโมเดล Generative AI คือเมธอด generate()

การเรียกใช้ generate() ที่ง่ายที่สุดจะระบุรูปแบบที่ต้องการใช้และพรอมต์ข้อความ ดังนี้

import { gemini15Flash, googleAI } from '@genkit-ai/googleai';
import { genkit } from 'genkit';

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

(async () => {
  const { text } = await ai.generate(
    'Invent a menu item for a pirate themed restaurant.'
  );
  console.log(text);
})();

เมื่อคุณเรียกใช้ตัวอย่างสั้นๆ นี้ ระบบจะพิมพ์ข้อมูลการแก้ไขข้อบกพร่องบางส่วน ตามด้วยเอาต์พุตของการเรียกใช้ generate() ซึ่งมักจะเป็นข้อความ Markdown ดังตัวอย่างต่อไปนี้

## The Blackheart's Bounty

**A hearty stew of slow-cooked beef, spiced with rum and molasses, served in a
hollowed-out cannonball with a side of crusty bread and a dollop of tangy
pineapple salsa.**

**Description:** This dish is a tribute to the hearty meals enjoyed by pirates
on the high seas. The beef is tender and flavorful, infused with the warm spices
of rum and molasses. The pineapple salsa adds a touch of sweetness and acidity,
balancing the richness of the stew. The cannonball serving vessel adds a fun and
thematic touch, making this dish a perfect choice for any pirate-themed
adventure.

เรียกใช้สคริปต์อีกครั้งและคุณจะได้รับเอาต์พุตที่ต่างกัน

ตัวอย่างโค้ดก่อนหน้านี้ส่งคําขอการสร้างไปยังโมเดลเริ่มต้นซึ่งคุณระบุไว้เมื่อกําหนดค่าอินสแตนซ์ Genkit

นอกจากนี้ คุณยังระบุรูปแบบสําหรับการเรียก generate() รายการเดียวได้ด้วย โดยทำดังนี้

const { text } = await ai.generate({
  model: gemini15Pro,
  prompt: 'Invent a menu item for a pirate themed restaurant.',
});

ตัวอย่างนี้ใช้การอ้างอิงโมเดลที่ส่งออกโดยปลั๊กอินโมเดล อีกทางเลือกหนึ่งคือการระบุโมเดลโดยใช้ตัวระบุสตริง ดังนี้

const { text } = await ai.generate({
  model: 'googleai/gemini-1.5-pro-latest',
  prompt: 'Invent a menu item for a pirate themed restaurant.',
});

ตัวระบุสตริงของโมเดลมีลักษณะดังนี้ providerid/modelid โดยรหัสผู้ให้บริการ (ในกรณีนี้คือ googleai) จะระบุปลั๊กอิน และรหัสโมเดลเป็นตัวระบุสตริงเฉพาะปลั๊กอินสำหรับโมเดลเวอร์ชันที่เฉพาะเจาะจง

ปลั๊กอินโมเดลบางรายการ เช่น ปลั๊กอิน Ollama ให้สิทธิ์เข้าถึงโมเดลต่างๆ หลายสิบรายการ จึงไม่ได้ส่งออกข้อมูลอ้างอิงโมเดลแต่ละรายการ ในกรณีเหล่านี้ คุณจะระบุโมเดลให้กับ generate() ได้โดยใช้ตัวระบุสตริงของโมเดลเท่านั้น

ตัวอย่างเหล่านี้ยังแสดงให้เห็นถึงประเด็นสำคัญอีกอย่างหนึ่งด้วย เมื่อคุณใช้ generate() เพื่อเรียกใช้โมเดล Generative AI การเปลี่ยนโมเดลที่ต้องการใช้ก็เพียงแค่ส่งค่าอื่นไปยังพารามิเตอร์โมเดล การใช้ generate() แทน SDK รูปแบบเนทีฟจะช่วยให้คุณมีความยืดหยุ่นในการใช้รูปแบบต่างๆ หลายรูปแบบในแอปและเปลี่ยนรูปแบบในอนาคตได้ง่ายขึ้น

จนถึงตอนนี้คุณได้เห็นเพียงตัวอย่างการเรียกใช้ generate() ที่ง่ายที่สุดเท่านั้น อย่างไรก็ตาม generate() ยังมีอินเทอร์เฟซสำหรับการโต้ตอบขั้นสูงเพิ่มเติมกับ Generative Models ซึ่งคุณจะเห็นได้ในส่วนถัดไป

พรอมต์ของระบบ

บางรุ่นรองรับพรอมต์ของระบบ ซึ่งจะให้คำสั่งแก่โมเดลเกี่ยวกับวิธีตอบกลับข้อความจากผู้ใช้ คุณสามารถใช้พรอมต์ของระบบเพื่อระบุบุคลิกที่คุณต้องการให้โมเดลใช้ น้ำเสียงของคำตอบ รูปแบบของคำตอบ และอื่นๆ

หากโมเดลที่ใช้รองรับข้อความแจ้งของระบบ คุณสามารถระบุข้อความแจ้งได้โดยใช้พารามิเตอร์ system ดังนี้

const { text } = await ai.generate({
  system: 'You are a food industry marketing consultant.',
  prompt: 'Invent a menu item for a pirate themed restaurant.',
});

พารามิเตอร์ของโมเดล

ฟังก์ชัน generate() จะใช้พารามิเตอร์ config ซึ่งคุณสามารถระบุการตั้งค่าที่ไม่บังคับซึ่งควบคุมวิธีที่โมเดลสร้างเนื้อหาได้ ดังนี้

const { text } = await ai.generate({
  prompt: 'Invent a menu item for a pirate themed restaurant.',
  config: {
    maxOutputTokens: 400,
    stopSequences: ['<end>', '<fin>'],
    temperature: 1.2,
    topP: 0.4,
    topK: 50,
  },
});

พารามิเตอร์ที่รองรับจะขึ้นอยู่กับแต่ละโมเดลและ Model API อย่างไรก็ตาม พารามิเตอร์ในตัวอย่างก่อนหน้านี้เป็นพารามิเตอร์ที่ใช้ได้กับเกือบทุกโมเดล ต่อไปนี้เป็นคําอธิบายพารามิเตอร์เหล่านี้

พารามิเตอร์ที่ควบคุมความยาวเอาต์พุต

maxOutputTokens

LLM ทำงานกับหน่วยที่เรียกว่าโทเค็น โดยปกติแล้วโทเค็นจะจับคู่กับลําดับอักขระที่เฉพาะเจาะจง แต่ก็ไม่จําเป็น เมื่อคุณส่งพรอมต์ไปยังโมเดล ขั้นตอนแรกๆ อย่างหนึ่งของโมเดลคือการแยกคำสตริงพรอมต์ออกเป็นลำดับโทเค็น จากนั้น LLM จะสร้างลำดับโทเค็นจากอินพุตที่แบ่งออกเป็นโทเค็น สุดท้าย ระบบจะแปลงลำดับโทเค็นกลับเป็นข้อความ ซึ่งเป็นเอาต์พุตของคุณ

พารามิเตอร์โทเค็นเอาต์พุตสูงสุดจะกําหนดจํานวนโทเค็นที่จะสร้างโดยใช้ LLM โมเดลแต่ละโมเดลอาจใช้ตัวแยกวิเคราะห์ที่แตกต่างกัน แต่หลักการง่ายๆ คือให้ถือว่าคําภาษาอังกฤษคําเดียวประกอบด้วยโทเค็น 2-4 รายการ

ตามที่ระบุไว้ก่อนหน้านี้ โทเค็นบางรายการอาจไม่ได้แมปกับลําดับอักขระ ตัวอย่างหนึ่งคือ มักจะมีโทเค็นที่บ่งบอกถึงจุดสิ้นสุดของลำดับ เช่น เมื่อ LLM สร้างโทเค็นนี้ ก็จะหยุดสร้างโทเค็นเพิ่มเติม ดังนั้นจึงเป็นไปได้และมักเป็นเช่นนั้นที่ LLM จะสร้างโทเค็นน้อยกว่าจำนวนสูงสุดเนื่องจากสร้างโทเค็น "หยุด"

stopSequences

คุณสามารถใช้พารามิเตอร์นี้เพื่อตั้งค่าโทเค็นหรือลําดับโทเค็นที่จะระบุจุดสิ้นสุดของเอาต์พุต LLM เมื่อสร้างขึ้น โดยทั่วไปแล้ว ค่าที่ถูกต้องที่จะใช้ที่นี่จะขึ้นอยู่กับวิธีฝึกโมเดล และมักจะกำหนดโดยปลั๊กอินโมเดล อย่างไรก็ตาม หากคุณได้แจ้งให้โมเดลสร้างคําสั่งหยุดอีกชุดหนึ่ง คุณอาจระบุคําสั่งดังกล่าวได้ที่นี่

โปรดทราบว่าคุณกําลังระบุลําดับอักขระ ไม่ใช่โทเค็น ในกรณีส่วนใหญ่ คุณจะระบุลำดับอักขระที่ตัวแยกวิเคราะห์ของโมเดลแมปกับโทเค็นเดียว

พารามิเตอร์ที่ควบคุม "ครีเอทีฟโฆษณา"

พารามิเตอร์ temperature, top-p และ top-k จะควบคุมระดับ "ความคิดสร้างสรรค์" ของโมเดลร่วมกัน ด้านล่างนี้คือคำอธิบายสั้นๆ เกี่ยวกับความหมายของพารามิเตอร์เหล่านี้ แต่สิ่งสำคัญที่ควรทราบคือพารามิเตอร์เหล่านี้ใช้เพื่อปรับลักษณะของเอาต์พุต LLM ค่าที่เหมาะสมสําหรับตัวแปรเหล่านี้จะขึ้นอยู่กับเป้าหมายและค่ากําหนดของคุณ และอาจพบได้ผ่านการทดสอบเท่านั้น

temperature

LLM เป็นเครื่องคาดการณ์โทเค็นโดยพื้นฐาน สำหรับลำดับโทเค็นหนึ่งๆ (เช่น พรอมต์) LLM จะคาดคะเนความน่าจะเป็นที่โทเค็นแต่ละรายการในคลังคำศัพท์จะปรากฏในลำดับถัดไป อุณหภูมิคือปัจจัยการปรับขนาดที่ใช้ในการหารการคาดการณ์เหล่านี้ก่อนที่จะนอร์มาไลซ์ให้เป็นความน่าจะเป็นระหว่าง 0 ถึง 1

ค่าอุณหภูมิต่ำซึ่งอยู่ระหว่าง 0.0 ถึง 1.0 จะขยายความแตกต่างของความเป็นไปได้ระหว่างโทเค็นต่างๆ ส่งผลให้โมเดลมีแนวโน้มที่จะสร้างโทเค็นที่ประเมินแล้วว่าไม่น่าจะเกิดขึ้นน้อยลง ซึ่งมักถูกมองว่าเป็นเอาต์พุตที่ไม่ค่อยสร้างสรรค์ แม้ว่าในทางเทคนิคแล้ว 0.0 จะไม่ใช่ค่าที่ถูกต้อง แต่โมเดลจํานวนมากจะถือว่าค่านี้บ่งบอกว่าโมเดลควรทํางานแบบมีลําดับขั้นตอนที่แน่นอน และพิจารณาเฉพาะโทเค็นที่เป็นไปได้มากที่สุดรายการเดียว

ค่าอุณหภูมิสูง (ค่ามากกว่า 1.0) จะบีบอัดความแตกต่างของความน่าจะเป็นระหว่างโทเค็น ส่งผลให้โมเดลมีแนวโน้มที่จะสร้างโทเค็นที่ก่อนหน้านี้ประเมินว่าไม่น่าจะเกิดขึ้น ซึ่งมักถูกมองว่าเป็นเอาต์พุตที่สร้างสรรค์มากขึ้น Model API บางรายการกำหนดอุณหภูมิสูงสุด ซึ่งมักจะเป็น 2.0

topP

Top-p คือค่าระหว่าง 0.0 ถึง 1.0 ที่ควบคุมจํานวนโทเค็นที่เป็นไปได้ซึ่งคุณต้องการให้โมเดลพิจารณา โดยระบุความน่าจะเป็นสะสมของโทเค็น ตัวอย่างเช่น ค่า 1.0 หมายความว่าให้พิจารณาโทเค็นที่เป็นไปได้ทั้งหมด (แต่ยังคงคํานึงถึงความน่าจะเป็นของโทเค็นแต่ละรายการ) ค่า 0.4 หมายความว่าให้พิจารณาเฉพาะโทเค็นที่เป็นไปได้มากที่สุด ซึ่งความน่าจะเป็นทั้งหมดจะเท่ากับ 0.4 และยกเว้นโทเค็นที่เหลือไม่ให้พิจารณา

topK

Top-k คือค่าจำนวนเต็มซึ่งควบคุมจำนวนโทเค็นที่เป็นไปได้ที่คุณต้องการให้โมเดลพิจารณาด้วย แต่ครั้งนี้จะระบุจำนวนโทเค็นสูงสุดอย่างชัดเจน การระบุค่า 1 หมายความว่าโมเดลควรทํางานอย่างมีลําดับ

ทดสอบพารามิเตอร์ของโมเดล

คุณสามารถทดสอบผลของพารามิเตอร์เหล่านี้ที่มีต่อเอาต์พุตที่สร้างขึ้นจากชุดค่าผสมของโมเดลและพรอมต์ต่างๆ โดยใช้ UI สําหรับนักพัฒนาซอฟต์แวร์ เริ่ม UI ของนักพัฒนาซอฟต์แวร์ด้วยคำสั่ง genkit start แล้วระบบจะโหลดโมเดลทั้งหมดที่กําหนดโดยปลั๊กอินที่กําหนดค่าไว้ในโปรเจ็กต์โดยอัตโนมัติ คุณสามารถลองพรอมต์และค่าการกําหนดค่าต่างๆ ได้อย่างรวดเร็วโดยไม่ต้องทําการเปลี่ยนแปลงเหล่านี้ในโค้ดซ้ำๆ

เอาต์พุตที่มีโครงสร้าง

เมื่อใช้ Generative AI เป็นคอมโพเนนต์ในแอปพลิเคชัน คุณมักจะต้องการเอาต์พุตในรูปแบบอื่นที่ไม่ใช่ข้อความธรรมดา แม้ว่าคุณจะสร้างเนื้อหาเพื่อแสดงต่อผู้ใช้เท่านั้น คุณก็จะได้รับประโยชน์จาก Structured Data เพื่อนำเสนอเนื้อหาให้น่าสนใจยิ่งขึ้นต่อผู้ใช้ แต่สำหรับการใช้งาน Generative AI ขั้นสูงขึ้น เช่น การใช้เอาต์พุตของโมเดลแบบเป็นโปรแกรม หรือการส่งเอาต์พุตของโมเดลหนึ่งไปยังอีกโมเดลหนึ่ง คุณต้องใช้ Structured Output

ใน Genkit คุณสามารถขอเอาต์พุตที่มีโครงสร้างจากโมเดลได้โดยระบุสคีมาเมื่อเรียกใช้ generate()

import { z } from 'genkit'; // Import Zod, which is re-exported by Genkit.
const MenuItemSchema = z.object({
  name: z.string(),
  description: z.string(),
  calories: z.number(),
  allergens: z.array(z.string()),
});

const { output } = await ai.generate({
  prompt: 'Invent a menu item for a pirate themed restaurant.',
  output: { schema: MenuItemSchema },
});

สคีมาเอาต์พุตของโมเดลจะระบุโดยใช้ไลบรารี Zod นอกจากภาษาคำจำกัดความสคีมาแล้ว Zod ยังมีการตรวจสอบประเภทรันไทม์ด้วย ซึ่งช่วยเติมเต็มช่องว่างระหว่างประเภท TypeScript แบบคงที่กับผลลัพธ์ที่คาดเดาไม่ได้ของโมเดล Generative AI Zod ช่วยให้คุณเขียนโค้ดที่เชื่อถือได้ว่าการเรียกใช้ generate ที่ประสบความสําเร็จจะแสดงผลลัพธ์ที่สอดคล้องกับประเภท TypeScript ของคุณเสมอ

เมื่อคุณระบุสคีมาใน generate() แล้ว Genkit จะทําสิ่งต่างๆ ต่อไปนี้เบื้องหลัง

  • เพิ่มคำแนะนำเพิ่มเติมเกี่ยวกับรูปแบบเอาต์พุตที่ต้องการลงในพรอมต์ นอกจากนี้ การดำเนินการนี้ยังมีผลข้างเคียงในการระบุให้โมเดลทราบว่าคุณต้องการสร้างเนื้อหาแบบใด (เช่น ไม่เพียงแนะนำรายการเมนูเท่านั้น แต่ยังสร้างคำอธิบาย รายการสารก่อภูมิแพ้ และอื่นๆ ด้วย)
  • แยกวิเคราะห์เอาต์พุตของโมเดลให้เป็นออบเจ็กต์ JavaScript
  • ยืนยันว่าเอาต์พุตเป็นไปตามสคีมา

หากต้องการรับเอาต์พุตที่มีโครงสร้างจากการเรียกใช้ generate ที่สำเร็จ ให้ใช้พร็อพเพอร์ตี้ output ของออบเจ็กต์การตอบกลับ ดังนี้

if (output) {
  const { name, description, calories, allergens } = output;
}

การจัดการข้อผิดพลาด

โปรดทราบว่าในตัวอย่างก่อนหน้านี้ พร็อพเพอร์ตี้ output อาจเป็น null กรณีนี้อาจเกิดขึ้นเมื่อโมเดลสร้างเอาต์พุตที่ไม่เป็นไปตามสคีมาไม่สําเร็จ กลยุทธ์ที่ดีที่สุดในการจัดการกับข้อผิดพลาดดังกล่าวจะขึ้นอยู่กับกรณีการใช้งานของคุณ แต่เคล็ดลับทั่วไปมีดังนี้

  • ลองใช้อุปกรณ์รุ่นอื่น โมเดลต้องสร้างเอาต์พุตเป็น JSON ได้จึงจะสร้าง Structured Data ได้ LLM ที่มีประสิทธิภาพมากที่สุด เช่น Gemini และ Claude นั้นมีความอเนกประสงค์มากพอที่จะทําเช่นนี้ได้ แต่โมเดลขนาดเล็ก เช่น โมเดลในเครื่องบางรายการที่คุณจะใช้กับ Ollama อาจสร้างเอาต์พุตที่มีโครงสร้างได้อย่างไม่น่าเชื่อถือ เว้นแต่จะได้รับการฝึกมาโดยเฉพาะ

  • ใช้ประโยชน์จากความสามารถในการบังคับของ Zod: คุณสามารถระบุในสคีมาว่า Zod ควรพยายามบังคับประเภทที่ไม่เป็นไปตามข้อกำหนดให้กลายเป็นประเภทที่ระบุโดยสคีมา หากสคีมามีประเภทพื้นฐานอื่นๆ นอกเหนือจากสตริง การใช้การบังคับของ Zod จะช่วยลดจํานวนgenerate()ข้อผิดพลาดที่คุณพบได้ MenuItemSchema เวอร์ชันต่อไปนี้ใช้การเปลี่ยนประเภทเพื่อแก้ไขสถานการณ์โดยอัตโนมัติเมื่อโมเดลสร้างข้อมูลแคลอรี่เป็นสตริงแทนตัวเลข

    const MenuItemSchema = z.object({
      name: z.string(),
      description: z.string(),
      calories: z.coerce.number(),
      allergens: z.array(z.string()),
    });
    
  • ลองเรียกใช้ generate() อีกครั้ง หากโมเดลที่คุณเลือกสร้างเอาต์พุตที่เป็นไปตามข้อกำหนดได้เพียงนานๆ ครั้ง คุณอาจจัดการกับข้อผิดพลาดนี้เหมือนกับจัดการกับข้อผิดพลาดของเครือข่าย และลองส่งคำขออีกครั้งโดยใช้กลยุทธ์การลดจำนวนการทดสอบแบบค่อยเป็นค่อยไป

อุปกรณ์การสตรีม

เมื่อสร้างข้อความจำนวนมาก คุณสามารถปรับปรุงประสบการณ์ของผู้ใช้ด้วยการนำเสนอเอาต์พุตขณะที่สร้างขึ้น ซึ่งก็คือการสตรีมเอาต์พุต ตัวอย่างที่เห็นได้ชัดของการทำงานแบบสตรีมมิงคือแอปแชท LLM ส่วนใหญ่ ผู้ใช้สามารถอ่านคำตอบของโมเดลต่อข้อความของตนขณะที่ระบบกำลังสร้างคำตอบ ซึ่งจะช่วยปรับปรุงการตอบสนองที่รับรู้ของแอปพลิเคชันและเพิ่มความสมจริงของการแชทกับคู่สนทนาที่ฉลาด

ใน Genkit คุณสามารถสตรีมเอาต์พุตได้โดยใช้เมธอด generateStream() ไวยากรณ์ของเมธอดนี้คล้ายกับเมธอด generate() ดังนี้

const { response, stream } = await ai.generateStream(
  'Suggest a complete menu for a pirate themed restaurant.'
);

ออบเจ็กต์การตอบกลับมีพร็อพเพอร์ตี้ stream ซึ่งคุณใช้เพื่อวนซ้ำเอาต์พุตสตรีมมิงของคำขอขณะที่สร้างขึ้นได้ ดังนี้

for await (const chunk of stream) {
  console.log(chunk.text);
}

นอกจากนี้ คุณยังดูเอาต์พุตทั้งหมดของคำขอได้เช่นเดียวกับคำขอที่ไม่ใช่สตรีมมิง โดยทำดังนี้

const completeText = (await response).text;

นอกจากนี้ สตรีมมิงยังทำงานร่วมกับเอาต์พุตที่มีโครงสร้างได้ด้วย

const MenuSchema = z.object({
  starters: z.array(MenuItemSchema),
  mains: z.array(MenuItemSchema),
  desserts: z.array(MenuItemSchema),
});

const { response, stream } = await ai.generateStream({
  prompt: 'Suggest a complete menu for a pirate themed restaurant.',
  output: { schema: MenuSchema },
});

for await (const chunk of stream) {
  // `output` is an object representing the entire output so far.
  console.log(chunk.output);
}

// Get the completed output.
const { output } = await response;

เอาต์พุตที่มีโครงสร้างแบบสตรีมจะทำงานแตกต่างจากข้อความแบบสตรีมเล็กน้อย โดยพร็อพเพอร์ตี้ output ของข้อมูลโค้ดตอบกลับคือออบเจ็กต์ที่สร้างจากการรวบรวมข้อมูลโค้ดที่สร้างขึ้นจนถึงตอนนี้ ไม่ใช่ออบเจ็กต์ที่แสดงถึงข้อมูลโค้ดเดียว (ซึ่งอาจไม่ถูกต้องหากใช้เพียงอย่างเดียว) ข้อมูล Structured Output แต่ละกลุ่มจะแทนที่กลุ่มก่อนหน้า

ตัวอย่างเช่น เอาต์พุต 5 รายการแรกจากตัวอย่างก่อนหน้านี้อาจมีลักษณะดังนี้

null

{ starters: [ {} ] }

{
  starters: [ { name: "Captain's Treasure Chest", description: 'A' } ]
}

{
  starters: [
    {
      name: "Captain's Treasure Chest",
      description: 'A mix of spiced nuts, olives, and marinated cheese served in a treasure chest.',
      calories: 350
    }
  ]
}

{
  starters: [
    {
      name: "Captain's Treasure Chest",
      description: 'A mix of spiced nuts, olives, and marinated cheese served in a treasure chest.',
      calories: 350,
      allergens: [Array]
    },
    { name: 'Shipwreck Salad', description: 'Fresh' }
  ]
}

อินพุตหลายโมดัล

ตัวอย่างที่คุณเห็นจนถึงตอนนี้ใช้สตริงข้อความเป็นพรอมต์ของโมเดล แม้ว่าวิธีนี้จะยังคงเป็นวิธีกระตุ้นโมเดล Generative AI ที่พบบ่อยที่สุด แต่โมเดลจำนวนมากก็ยอมรับสื่ออื่นๆ เป็นพรอมต์ได้เช่นกัน พรอมต์สื่อมักใช้ร่วมกับพรอมต์ข้อความที่สั่งให้โมเดลดำเนินการบางอย่างกับสื่อ เช่น ใส่คำบรรยายแทนเสียงรูปภาพหรือถอดเสียงไฟล์บันทึกเสียง

ความสามารถในการรับอินพุตสื่อและประเภทสื่อที่คุณใช้ได้จะขึ้นอยู่กับโมเดลและ API ของโมเดลนั้นๆ ทั้งหมด ตัวอย่างเช่น โมเดลซีรีส์ Gemini 1.5 ยอมรับรูปภาพ วิดีโอ และเสียงเป็นพรอมต์ได้

หากต้องการระบุพรอมต์สื่อให้กับโมเดลที่รองรับ ให้ส่งอาร์เรย์ที่ประกอบด้วยส่วนสื่อและส่วนข้อความแทนการส่งพรอมต์ข้อความธรรมดาไปยัง generate ดังนี้

const { text } = await ai.generate([
  { media: { url: 'https://example.com/photo.jpg' } },
  { text: 'Compose a poem about this image.' },
]);

ในตัวอย่างข้างต้น คุณได้ระบุรูปภาพโดยใช้ URL ของ HTTPS ที่เข้าถึงได้แบบสาธารณะ นอกจากนี้ คุณยังส่งข้อมูลสื่อได้โดยตรงด้วยการเข้ารหัสเป็น URL ข้อมูล เช่น

import { readFile } from 'node:fs/promises';
const b64Data = await readFile('photo.jpg', { encoding: 'base64url' });
const dataUrl = `data:image/jpeg;base64,${b64Data}`;

const { text } = await ai.generate([
  { media: { url: dataUrl } },
  { text: 'Compose a poem about this image.' },
]);

โมเดลทั้งหมดที่รองรับอินพุตสื่อจะรองรับทั้ง URL ข้อมูลและ URL HTTPS ส่วนปลั๊กอินบางรุ่นจะรองรับแหล่งที่มาของสื่ออื่นๆ ด้วย เช่น ปลั๊กอิน Vertex AI ยังให้คุณใช้ URL ของ Cloud Storage (gs://) ได้ด้วย

การสร้างสื่อ

จนถึงตอนนี้ ตัวอย่างส่วนใหญ่ในหน้านี้เกี่ยวข้องกับการสร้างข้อความโดยใช้ LLM อย่างไรก็ตาม Genkit ยังใช้กับโมเดลการสร้างรูปภาพได้ด้วย การใช้ generate() กับโมเดลการสร้างรูปภาพนั้นคล้ายกับการใช้ LLM ตัวอย่างเช่น หากต้องการสร้างรูปภาพโดยใช้โมเดล Imagen2 ผ่าน Vertex AI ให้ทำดังนี้

  1. Genkit ใช้ URL data: เป็นรูปแบบเอาต์พุตมาตรฐานสำหรับสื่อที่สร้างขึ้น รูปแบบนี้เป็นรูปแบบมาตรฐานที่มีไลบรารีมากมายที่พร้อมจัดการ ตัวอย่างนี้ใช้แพ็กเกจ data-urls จาก jsdom

    npm i --save data-urls
    npm i --save-dev @types/data-urls
  2. หากต้องการสร้างรูปภาพและบันทึกลงในไฟล์ ให้เรียกใช้ generate() โดยระบุรูปแบบการสร้างรูปภาพและประเภทสื่อของรูปแบบเอาต์พุต ดังนี้

    import { imagen3Fast, vertexAI } from '@genkit-ai/vertexai';
    import parseDataURL from 'data-urls';
    import { genkit } from 'genkit';
    
    import { writeFile } from 'node:fs/promises';
    
    const ai = genkit({
      plugins: [vertexAI({ location: 'us-central1' })],
    });
    
    (async () => {
      const { media } = await ai.generate({
        model: imagen3Fast,
        prompt: 'photo of a meal fit for a pirate',
        output: { format: 'media' },
      });
    
      if (media === null) throw new Error('No media generated.');
    
      const data = parseDataURL(media.url);
      if (data === null) throw new Error('Invalid "data:" URL.');
    
      await writeFile(`output.${data.mimeType.subtype}`, data.body);
    })();
    

ขั้นตอนถัดไป

ดูข้อมูลเพิ่มเติมเกี่ยวกับ Genkit

  • ในฐานะนักพัฒนาแอป วิธีหลักที่คุณส่งผลต่อเอาต์พุตของโมเดล Generative AI คือการใช้พรอมต์ อ่านการจัดการพรอมต์เพื่อดูวิธีที่ Genkit ช่วยคุณพัฒนาพรอมต์ที่มีประสิทธิภาพและจัดการพรอมต์เหล่านั้นในโค้ดเบส
  • แม้ว่า generate() จะเป็นหัวใจสำคัญของแอปพลิเคชันทุกแอปพลิเคชันที่ทำงานด้วย Generative AI แต่แอปพลิเคชันในชีวิตจริงมักจะต้องมีการดำเนินการเพิ่มเติมก่อนและหลังการเรียกใช้โมเดล Generative AI Genkit จึงนําเสนอแนวคิดโฟลว์ ซึ่งกําหนดไว้เหมือนฟังก์ชัน แต่เพิ่มฟีเจอร์อื่นๆ เช่น การสังเกตการณ์และการปรับใช้งานที่ง่ายขึ้น ดูข้อมูลเพิ่มเติมได้ที่การกําหนดเวิร์กโฟลว์

การใช้งาน LLM ขั้นสูง

  • วิธีหนึ่งในการปรับปรุงความสามารถของ LLM คือการแสดงรายการวิธีที่ LLM สามารถขอข้อมูลเพิ่มเติมจากคุณ หรือขอให้คุณดำเนินการบางอย่าง การดำเนินการนี้เรียกว่าการเรียกใช้เครื่องมือหรือการเรียกใช้ฟังก์ชัน โมเดลที่ได้รับการฝึกฝนให้รองรับความสามารถนี้จะตอบสนองต่อพรอมต์ด้วยการตอบกลับที่มีการจัดรูปแบบเป็นพิเศษ ซึ่งจะบ่งบอกให้แอปพลิเคชันที่เรียกใช้ทราบว่าควรดำเนินการบางอย่างและส่งผลลัพธ์กลับไปยัง LLM พร้อมกับพรอมต์เดิม Genkit มีฟังก์ชันไลบรารีที่ทําทั้งการสร้างพรอมต์และองค์ประกอบลูปการเรียกใช้การตอบกลับของการติดตั้งใช้งานเครื่องมือแบบอัตโนมัติ ดูข้อมูลเพิ่มเติมได้ในการเรียกใช้เครื่องมือ
  • การสร้างที่เพิ่มการดึงข้อมูล (RAG) เป็นเทคนิคที่ใช้เพื่อนำข้อมูลเฉพาะโดเมนมาใส่ไว้ในเอาต์พุตของโมเดล ซึ่งทำได้โดยการแทรกข้อมูลที่เกี่ยวข้องลงในพรอมต์ก่อนที่จะส่งต่อไปยังโมเดลภาษา การใช้งาน RAG อย่างสมบูรณ์ต้องใช้เทคโนโลยีหลายอย่างร่วมกัน ได้แก่ โมเดลการสร้างการฝังข้อความ ฐานข้อมูลเวกเตอร์ และโมเดลภาษาขนาดใหญ่ ดูการสร้างที่เพิ่มการดึงข้อมูล (RAG) เพื่อดูวิธีที่ Genkit ลดความซับซ้อนของกระบวนการประสานองค์ประกอบต่างๆ เหล่านี้

การทดสอบเอาต์พุตของโมเดล

ในฐานะวิศวกรซอฟต์แวร์ คุณคุ้นเคยกับระบบแบบกำหนดตายตัวที่อินพุตเดียวกันจะให้เอาต์พุตเดียวกันเสมอ อย่างไรก็ตาม เนื่องจากโมเดล AI เป็นแบบความน่าจะเป็น เอาต์พุตจึงอาจแตกต่างกันไปตามความแตกต่างเล็กๆ น้อยๆ ในอินพุต ข้อมูลการฝึกของโมเดล และแม้แต่ความน่าจะเป็นที่พารามิเตอร์ต่างๆ เช่น อุณหภูมิ จงใจสร้างขึ้น

ผู้ประเมินของ Genkit เป็นวิธีการที่มีโครงสร้างเพื่อประเมินคุณภาพของคำตอบ LLM โดยใช้กลยุทธ์ที่หลากหลาย อ่านเพิ่มเติมในหน้าการประเมิน