از زمانی که OpenAI یک API رسمی برای ChatGPT در مارس 2023 منتشر کرد، بسیاری از توسعه دهندگان و کارآفرینان علاقه مند به ادغام آن در کارهای تجاری خود هستند.
اما برخی از موانع مهم وجود دارد که انجام این کار را برای آنها دشوار می کند:
- OpenAI یک API ساده بدون حالت برای ChatGPT ارائه می دهد. توسعهدهنده باید تاریخچه و زمینه هر مکالمه را در حافظه پنهان یا پایگاه داده مدیریت شده توسط برنامه پیگیری کند. توسعه دهنده همچنین باید کلیدهای API را مدیریت و محافظت کند. کدهای نمونه زیادی وجود دارد که با منطق تجاری برنامه ارتباطی ندارد.
- رابط کاربری “طبیعی” برای برنامه ChatGPT API یک چت رشته ای است. اما ایجاد یک “واسط کاربری چت” در یک چارچوب وب یا برنامه سنتی دشوار است. در واقع، متداولترین رابط کاربری چت در حال حاضر در برنامههای پیامرسانی مانند Slack، Discord و حتی انجمنها (به عنوان مثال، GitHub Discussions) وجود دارد. ما به یک راه ساده برای اتصال پاسخ های ChatGPT API به یک سرویس پیام رسانی موجود نیاز داریم.
در این مقاله، من به شما نشان خواهم داد که چگونه یک ربات GitHub بدون سرور ایجاد کنید. این ربات به کاربران GitHub اجازه می دهد تا با ChatGPT و یکدیگر در مسائل GitHub چت کنند. میتوانید آن را با پرسیدن یک سؤال امتحان کنید، یا با گذاشتن نظر به یک رشته مکالمه دیگر بپیوندید. به عبارت دیگر، این پروژه از رابط کاربری پیامهای موضوعی GitHub Issues به عنوان رابط کاربری چت خود استفاده میکند.
شکل 1. آموزش Rust با ChatGPT. به https://github.com/second-state/chat-with-chatgpt/issues/31 مراجعه کنید
ربات یک تابع بدون سرور است که در Rust نوشته شده است. فقط مثال را وارونه کنید، فورک خود را روی flows.network اعمال کنید و آن را طوری پیکربندی کنید که با مخازن GitHub و کلیدهای OpenAI خود هم کنش داشته باشد. در عرض 10 دقیقه یک ربات GitHub کاملا کاربردی خواهید داشت. نیازی به راه اندازی وب سرور یا وب هوک برای GitHub API یا سرور کش / پایگاه داده نیست.
چگونه از فورک روی مخزن تمپلیت استفاده کنیم
ابتدا از فورک روی این مخزن تمپلیت از GitHub استفاده کنید. فایل src/lib.rs حاوی برنامه ربات است (همچنین به عنوان تابع جریان شناخته می شود). تابع run() پس از راه اندازی فراخوانی می شود. به issue_comment گوش می دهد و رویدادها را از owner/repo مخزن GitHub گسیل می کند. این رویدادها زمانی منتشر می شوند که یک کامنت شماره جدید یا یک شماره جدید در مخزن ایجاد شود.
#[no_mangle]
#[tokio::main(flavor = "current_thread")]
pub async fn run() {
// Setup variables for
// ower: GitHub org to install the bot
// repo: GitHub repo to install the bot
// openai_key_name: Name for your OpenAI API key
// All the values can be set in the source code or as env vars
listen_to_event(&owner, &repo, vec!["issue_comment", "issues"], |payload| {
handler(&owner, &repo, &openai_key_name, payload)
})
.await;
}
تابع handler() رویدادهای دریافت شده توسط listen_to_event() را پردازش می کند. اگر رویداد یک کامنت جدید در یک issue باشد، ربات ChatGPT API OpenAI را فراخوانی می کند تا متن کامنت را به یک مکالمه موجود که توسط issue.number مشخص شده است اضافه کند. پاسخی از ChatGPT دریافت میکند و کامنتی را در این شماره اضافه میکند.
تابع flow در اینجا به طور خودکار و شفاف سابقه مکالمه را با ChatGPT API در یک حافظه محلی مدیریت می کند. کلید OpenAI API نیز در حافظه محلی ذخیره می شود تا به جای قرار دادن متن مخفی در کد منبع، کلید را بتوان با نام رشته ای در openai_key_name شناسایی کرد.
EventPayload::IssueCommentEvent(e) => {
if e.comment.user.r#type != "Bot" {
if let Some(b) = e.comment.body {
if let Some(r) = chat_completion (
openai_key_name,
&format!("issue#{}", e.issue.number),
&b,
&ChatOptions::default(),
) {
if let Err(e) = issues.create_comment(e.issue.number, r.choice).await {
write_error_log!(e.to_string());
}
}
}
}
}
اگر رویداد یک issue جدید باشد، تابع flow مکالمه جدیدی را ایجاد میکند که توسط issue.number شناسایی میشود و از ChatGPT درخواست پاسخ میدهد.
EventPayload::IssuesEvent(e) => {
if e.action == IssuesEventAction::Closed {
return;
}
let title = e.issue.title;
let body = e.issue.body.unwrap_or("".to_string());
let q = title + "\n" + &body;
if let Some(r) = chat_completion (
openai_key_name,
&format!("issue#{}", e.issue.number),
&q,
&ChatOptions::default(),
) {
if let Err(e) = issues.create_comment(e.issue.number, r.choice).await {
write_error_log!(e.to_string());
}
}
}
نحوه استقرار تابع flow بدون سرور
همانطور که می بینیم، کد تابع جریان، API های SDK را برای انجام عملیات پیچیده فراخوانی می کند. مثلا:
- تابع listen_to_event() یک URL webhook را از طریق GitHub API ثبت میکند تا زمانی که رویدادهای خاصی در GitHub رخ میدهند، تابع handler() فراخوانی شود.
- تابع chat_completion() از ChatGPT API را با کلید API نامگذاری شده و تاریخچه / زمینه گذشته مکالمه مشخص شده فراخوانی می کند. کلید API و تاریخچه مکالمه در کش Redis ذخیره می شوند.
سرور وب هوک و کش Redis هر دو سرویس های خارجی هستند که SDK به آنها وابسته است.به این معنی که تابع flow باید در یک محیط میزبان مدیریت شده اجرا شود که چنین خدمات خارجی را ارائه می دهد. Flows.network یک میزبانPaaS (پلتفرم به عنوان سرویس) برای SDKهای تابع جریان است.
به منظور استقرار تابع جریان در flows.network، کافی است کد منبع آن را به PaaS وارد کنید.
ابتدا از حساب GitHub خود وارد flows.network شوید. مخزن GitHub فورک زده خود را که حاوی کد منبع تابع جریان است وارد کنید و “With Environment Variables” را انتخاب کنید.
توجه داشته باشید که این مخزن GitHub نیست که میخواهید ربات را در آن مستقر کنید. این مخزن کد منبع تابع flow فورک زده شما است.
شکل 2. مخزن GitHub را که از تمپلیت تابع جریان جدا کرده اید در flows.network وارد کنید.
متغیرهای محیطی را طوری مقداردهی کنید که تابع flow را روی نام کلید OpenAI API (open_ai_key) و مخزن GitHub (owner و repo) قرار دهند.
owner گیت هاب و متغیرهای repo در اینجا به مخزن GitHub اشاره می کنند که می خواهید ربات را در آنجا مستقر کنید، نه مخزن کد تابع flow.
شکل 3. متغیرهای محیطی را برای مخزن GitHub که میخواهید ربات را در آنجا مستقر کنید، و همچنین نام کلید OpenAI API را مقداردهی کنید.
Flows.network کد منبع را واکشی می کند و کد منبع Rust را با استفاده از زنجیره ابزار بار استاندارد در بایت کد Wasm می سازد. سپس تابع جریان Wasm را در WasmEdge Runtime اجرا می کند.
نحوه اتصال تابع Flow به GitHub و OpenAI
در حالی که تابع flow نیاز به اتصال به OpenAI و APIهای GitHub دارد، کد منبع کلیدهای API، نشانههای دسترسی یا منطق OAUTH ندارد. SDK های تابع جریان، تعامل توسعه دهندگان با سرویس های خارجی SaaS API را آسان و ایمن کرده اند.
Flows.network کشف می کند که تابع جریان نیاز به اتصال به OpenAI و GitHub API دارد. گردش کار UI را برای توسعه دهندگان ارائه می دهد:
- وارد GitHub شوید، اجازه دسترسی به رویدادها را بدهید و تابع جریان را به عنوان وب هوک برای دریافت آن رویدادها ثبت کنید.
- یک کلید OpenAI API را با نام openai_key_name متصل کنید.
شکل 4. سرویس های خارجی مورد نیاز تابع جریان متصل شده و سبز می شوند.
هنگامی که APIهای SaaS خارجی متصل و مجاز شدند، در داشبورد تابع flow سبز می شوند. تابع flow اکنون رویدادهایی را که برای آن listen_to_event() دریافت می کند. همچنین دسترسی شفاف به Redis برای کلید OpenAI API نامگذاری شده و زمینه مکالمه حافظه پنهان برای پشتیبانی از تابع chat_completion() SDK خواهد داشت.
در ادامه
ربات GitHub تنها یکی از انواع رباتهایی است که flows.network میتواند پشتیبانی کند. با اتصال تابع جریان به یک کانال Slack، می توانید ChatGPT را برای شرکت در بحث گروهی خود دریافت کنید. در اینجا یک نمونه از یک ربات ChatGPT مبتنی بر Slack آورده شده است.
شکل 5. ربات Slack ChatGPT
مثال دیگر این است که ChatGPT به سوالات حقوقی در یک کانال Slack پاسخ دهد. تابع flow ، سوال قانونی را با یک اعلان آماده می کند.
https://github.com/flows-network/robo-lawyer
شکل 6. ربات روبو لویر Slack
علاوه بر GitHub و Slack، بسیاری از محصولات SaaS وجود دارند که میتوانید از طریق API آنها در flows.network ادغام کنید.
در حالی که نمونه توابع جریان در Rust نوشته شده است، هدف ما پشتیبانی از SDKهای تابع جریان مبتنی بر جاوا اسکریپت است. به عبارت دیگر، توابع SDK پلتفرم مانند listen_to_event() و chat_completion() یک نسخه جاوا اسکریپت خواهند داشت. تابع جریان جاوا اسکریپت در داخل WasmEdge Runtime در پلت فرم flows.network از طریق ماژول WasmEdge-QuickJS اجرا می شود.