مدیر خانه هوشمند ساده هوش مصنوعی

کد این پست همه در اینجا موجود است: https://github.com/aaronblondeau/genkit-smarthome
برنامه کار را در https://smarthome.aaronblondeau.com/ مشاهده کنید
اگرچه من در تلاش هستم تا زندگی خود را از گوگل خارج کنم، اما به راه اندازی اخیر Firebase Genkit توجه کردم. من برای به دست آوردن ابزارهایی مانند LangChain برای عملکرد خوب در هنگام کار با داده های ساختاریافته تلاش کرده ام. از آنجایی که توانایی دریافت و خروجی JSON برای برنامه های هوش مصنوعی بسیار مهم است، تصمیم گرفتم Genkit را امتحان کنم. Genkit فراتر از انتظارات من بود و اکنون عضوی از جعبه ابزار فناوری من است.
در اینجا سناریویی است که من برای آزمایش Genkit استفاده کردم. تصور کنید که هم یک ترموستات هوشمند و هم یک چراغ هوشمند در دفتر خود دارید و دوست دارید بتوانید آنها را با دستورات زبان طبیعی کنترل کنید. برای مثال، «لطفاً چراغها را روی سبز تنظیم کنید». یا “لطفا دما را روی هشتاد درجه تنظیم کنید.”
برای اینکه این کار مدل زبانی به چند چیز نیاز دارد:
1) اعلان هایی که نتیجه مورد نظر را مشخص می کند.
2) فهرستی از اقدامات سطح بالایی که می توان انجام داد.
3) ابزارهایی که به استخراج داده های فرمت شده از درخواست کاربر کمک می کنند (مثلاً “هشتاد” را به 80 تبدیل کنید تا توسط دستگاه ترموستات قابل استفاده باشد).
و من به عنوان یک توسعه دهنده که روی برنامه کار می کنم این نیازها را دارم:
1) امکان تست و تکرار سریع در هر اعلان.
2) خروجی دقیق زنجیره اعلان ها و پاسخ هایی که منجر به برآورده شدن درخواست کاربر می شود.
3) امکان استفاده از چندین مدل (حتی آنهایی که به صورت محلی مانند اولاما اجرا می شوند).
4) خروجی داده های ساخت یافته قابل اعتماد از llm.
Genkit در برآوردن این نیازها کار بسیار خوبی انجام می دهد. برای توسعهدهنده، یک رابط کاربری فراهم میکند که به شما کمک میکند تا درخواستها را اجرا کنید و همچنین ورودی/خروجیهای هر مرحله را در یک گردش کار چندگانه تحلیل کنید. در اینجا یک اسکرین شات از نمونه Genkit UI من است که تمام جریان های من را نشان می دهد.
به نظر می رسد از مدل های غیر گوگل نیز پشتیبانی می شود: https://github.com/TheFireCo/genkit-plugins/tree/main
برای مدل های زبان، Genkit مفهوم Flow را ارائه می دهد. یک جریان اساساً یک دستور را با مجموعه ای از “ابزارها” یا اقداماتی که llm می تواند انجام دهد ترکیب می کند. مانند سایر چارچوبها در این فضا، از ZOD برای ارائه اطلاعات طرحواره برای ورودی و خروجی جریانها و اقدامات استفاده میشود.
به عنوان مثال در اینجا کد برای من است جریان که رنگ چراغ های اتاق را تعیین می کند. دارای یک اعلان است که به تنظیم زمینه کاری که باید انجام شود کمک می کند. همچنین دارای مجموعه ای از ابزارهایی است که می تواند از آن استفاده کند: extractColor، convertColorToHex، setLEDColor
// Primary level flow for setting the room's lighting.
export const setLightsFlow = defineFlow(
{
name: 'setLightsFlow',
inputSchema: z.object({
command: z.string().describe('The user\'s request for a lighting color change.')
}),
outputSchema: z.string(),
},
async (input) => {
const llmResponse = await generate({
prompt: `Please respond to this command to set the color of lights in the room : ${input.command}`,
model: geminiPro,
tools: [extractColor, convertColorToHex, setLEDColor],
config: standardConfig,
});
return llmResponse.text();
}
);
و در اینجا کد برای یک است عمل که مدل می تواند برای تبدیل نام رنگ ها به کدهای هگز استفاده کند. نکته واقعاً شسته و رفته در اینجا این است که شما می توانید یک جریان را در یک عمل جاسازی کنید.
// Provides the convertColorToHexFlow as a tool
export const convertColorToHex = action(
{
name: 'convertColorToHex',
description: 'Converts a color string to hex. For example, an input of "blue" outputs "0000FF"',
inputSchema: z.object({ colorString: z.string() }),
outputSchema: z.object({ hexColorCode: z.string().length(6) }),
},
async (input) => {
const response = await runFlow(convertColorToHexFlow, {
color: input.colorString
});
return response
}
);
ساده تر عمل که از طرف کاربر اقدام مشخصی انجام می دهد:
// Low level tool that sets the color of the room's lights
export const setLEDColor = action(
{
name: 'setLEDColor',
description: 'Sets the color of the room\'s lighting by sending commands to the fixture\'s bluetooth API.',
inputSchema: z.object({ hexColorCode: z.string().length(6) }),
outputSchema: z.boolean().describe('True if the color is successfully set.'),
},
async (input) => {
homeActor.send({ type: 'SETCOLOR', value: input.hexColorCode })
return true
}
);
homeActor یک ماشین حالت محدود XState است. من ایده ارائه مدل های هوش مصنوعی را با یک ماشین حالت که می توانند برای رسیدن به نتیجه دلخواه کاربر دستکاری کنند، بسیار دوست دارم. ماشین حالت من در این مثال کار زیادی انجام نمی دهد، اما من احساس می کنم که genkit+xstate یک ترکیب بسیار قدرتمند است که می خواهم بیشتر آن را بررسی کنم.
من در اینجا وارد تمام جزئیات پیاده سازی دیگر نمی شوم، اما در اینجا 3 مهم ترین چیزهایی که در اجرای پروژه یاد گرفتم وجود دارد:
- یک ساختار لایه ای از جریان ها و اقدامات ارائه دهید
Genkit به طور خودکار چندین ابزار را به ترتیب درست زمانی که برای اجرای یک فرمان مورد نیاز است اجرا می کند. با این حال، زمانی که سعی کردم جریان یکسانی مسئول چندین کار باشد، چندین خطا دریافت کردم. من پیادهسازی الگویی را انجام دادم که در آن اولین جریان به سادگی تعیین میکند که کاربر چه نوع فرمانی را داده است (چراغ در مقابل ترموستات). این جریان سطح بالا می تواند به ابزاری برای هر نوع فرمان موکول شود. این ابزارها به نوبه خود یک جریان فرعی را اجرا می کنند که مختص کار است. این چیزی است که به نظر میرسد:
- از درخواست سیستم اجتناب کنید
اسناد Genkit نحوه استفاده از درخواستهای سیستم را در اینجا شرح میدهد: https://firebase.google.com/docs/genkit/models
همانطور که من به استفاده از دستورات سیستم برای دادن زمینه به llm عادت دارم، ابتدا آنها را امتحان کردم. با این حال، جمینی یک پاسخ “فهمیده” را از هر فرمان سیستمی که زنجیره اجرا را حذف می کند، برمی گرداند. بنابراین من استفاده از دستورات سیستم را متوقف کردم و تمام زمینه خود را در اعلان اصلی هر جریان قرار دادم. مدل های دیگر احتمالاً رفتار متفاوتی دارند.
- از طرح های رشته ای ساده برای ورودی ها و خروجی ها خودداری کنید
اکثر اقدامات و جریان های من به سادگی یک تکه داده مانند “آبی” را برمی گرداند، بنابراین من در ابتدا جریان های خود را به این صورت تنظیم می کنم:
{
name: 'convertColorToHexFlow',
inputSchema: z.string(),
outputSchema: z.string().length(6),
}
این طرح مسطح منجر به جریان هایی شد که مقدار {} را به عنوان ورودی ابزارها ارائه می کرد. وقتی طرحواره ها را به شرح زیر توصیف کردم، این مشکل برطرف شد:
{
name: 'convertColorToHexFlow',
inputSchema: z.object({
color: z.string()
}),
outputSchema: z.object({
hexColorCode: z.string().length(6)
}),
}
خلاصه
Genkit را امتحان کنید. این یک چارچوب حداقلی است که به شما کمک میکند تا تمام آشفتگیهایی را که از مداخلهگر ناشی میشود مدیریت کنید.
با تشکر برای خواندن!