گونه ایدههای خود را به اپلیکیشنهای مبتنی بر هوش مصنوعی تبدیل کنیم؟

چگونه ایدههای خود را به اپلیکیشنهای مبتنی بر هوش مصنوعی تبدیل کنیم؟
شما بارها از ChatGPT استفاده کردهاید: سوالی پرسیدهاید، پاسخ گرفتهاید و آن را در پروژه یا سندی نیمهتمام کپی کردهاید. ممکن است پاسخها مفید بوده باشند یا دقیقاً مطابق انتظار شما نباشند. اما نکتهای که کمتر به آن توجه میشود این است که همان پنجره چتی که استفاده میکنید، محصول نهایی نیست؛ بلکه فقط یک نسخه نمایشی (دمو) است. قابلیتهای واقعی و پیشرفتهای که پشت اپلیکیشنهای هوش مصنوعی مطرح امروز قرار دارد، معمولاً از طریق مرورگر یا کلاینت وب قابل دسترسی نیست؛ بلکه این امکانات از طریق API ( رابط برنامهنویسی کاربردی) در اختیار توسعهدهندگان قرار میگیرد. پیادهسازی و استفاده از API آنقدرها هم پیچیده نیست. اگر بتوانید یک پرسش یا پرامپت بنویسید، در واقع گام اول را برداشتهاید. در این راهنمای مقدماتی، نحوه شروع ساخت اپلیکیشنهای ساده مبتنی بر هوش مصنوعی با استفاده از مدلهای بزرگ زبان (LLM) را بررسی میکنیم و نشان میدهیم چطور استفاده از API میتواند کیفیت پرامپتها را بالا ببرد و عملکرد مدلها را بهبود بخشد — همه اینها بدون نیاز به دانش تخصصی در یادگیری ماشین. آمادهاید شروع کنیم؟
###تفاوت استفاده از ChatGPT از طریق API با استفاده از کلاینت وب چیست؟ اکثر ابزارهای محبوب هوش مصنوعی دارای رابط برنامهنویسی کاربردی (API) هستند. اگر با مفهوم API آشنا نیستید، باید بدانید که API امکان دسترسی به خدمات هوش مصنوعی را از طریق کدنویسی فراهم میکند، نه فقط از طریق رابط کاربری مرورگر. این قابلیتها شامل موارد زیر است: • خودکارسازی فرایند ارسال درخواست به مدلها، به خصوص در کارهای تکراری • اتصال ابزارهای هوش مصنوعی به سایر سرویسها و سیستمها • وارد کردن فایلها و دادههای جانبی برای سفارشیسازی بهتر پرسشها • تنظیم و شخصیسازی رفتار و زبان مدل متناسب با اهداف و نیازهای خاص با استفاده از این امکانات میتوان ابزارهای متنوع و کاربردی ساخت، از جمله: • ابزار تحلیل و تفسیر فایلهای PDF که گزارشهای طولانی را میخواند، نکات کلیدی را استخراج میکند و امکان پرسش و پاسخ فراهم میکند • دستیار مدیریت ایمیل که پیامها را برچسبگذاری، دستهبندی و بر اساس اولویتها پیشنویس پاسخها را آماده میکند • ابزاری برای پاکسازی دادهها که فایلهای CSV را دریافت، پردازش و فرمتبندی میکند • سامانه جستجوی اسناد شخصی که بر اساس فایلهای شما آموزش دیده و دسترسی سریع به اطلاعات را بدون جستجوی دستی فراهم میآورد • ابزارهای آموزشی که یادداشتهای شما را به کارتهای حافظه، خلاصهها یا آزمونهای تعاملی تبدیل میکنند • خلاصهساز جلسات که متون گفتگو را تحلیل و تصمیمات، وظایف و پیگیریها را برجسته میکند برای شروع، لازم است کلید API مربوط به مدل زبان بزرگ (LLM) مورد نظر خود را دریافت کنید. در این مقاله از ChatGPT استفاده خواهیم کرد. دستورالعمل کامل راهاندازی در انتهای همین صفحه قرار دارد.
###نمونه کد ساده فراخوانی (API با زبان پایتون) در ادامه نمونهای ساده از اسکریپت فراخوانی API ارائه شده است که میتواند نقطه شروع مناسبی برای سایر قطعات کد مطرح شده در این مقاله باشد. شما میتوانید این کد را کپی کرده و متناسب با نیازهای خود تغییر دهید تا بتوانید برخی از ایدههای ارائه شده را به اجرا درآورید.
import openai
import os
client = OpenAI(api_key = os.getenv("OPENAI_API_KEY"))
response = client.chat.completion.create(
model="gpt-4",
messages=[{"role": "user", "content": "Hello!"}]
)
print(response.choices[0].message.content)
تفاوتهای استفاده از ChatGPT از طریق کلاینت وب و API
ابتدا به بررسی تفاوتهای اساسی میان استفاده از ChatGPT از طریق کلاینت وب و از طریق API میپردازیم.
حافظه زمینهای (Context Memory)
در استفاده معمول از ChatGPT، پیامهای ارسالی و دریافتی به شکل یک گفتوگوی پیوسته سازماندهی میشوند و پاسخها بر اساس تمام پیامهای قبلی در همان گفتگو ساخته میشوند. اما وقتی از API استفاده میکنیم، فقط پیام فعلی به عنوان ورودی در نظر گرفته میشود و مدل پاسخ خود را صرفاً بر اساس همان پیام تولید میکند؛ یعنی API به صورت پیشفرض حافظهای از پیامهای قبلی ندارد.
برای رفع این محدودیت، هنگام استفاده از API، سابقه گفتوگو شامل پیامهای کاربر و پاسخهای مدل به صورت یک مجموعه کامل همراه با پیام جدید به مدل ارسال میشود. این کار باعث میشود مکالمه به صورت پیوسته شبیهسازی شود. این روش همان چیزی است که کلاینت ChatGPT در پسزمینه به صورت خودکار انجام میدهد، هرچند معمولاً برای کاربر پنهان و غیرمستقیم است.
به عنوان نمونه، پرامپتی مشابه نمونه زیر ممکن است در میانه یک گفتوگو به مدل ارسال گردد:
messages = [
. . .
{"role": "user", "content": "How do I reverse a list in Python?"},
{"role": "assistant", "content": "You can use the `reverse()` method:\n\n```python\nmy_list.reverse()\n```\nOr use slicing:\n\n```python\nreversed_list = my_list[::-1]\n```"},
{"role": "user", "content": "What if I want to reverse it without modifying the original?"}
]
همانطور که مشاهده میکنید، هر زمان که کاربر پیامی جدید ارسال میکند، کل سابقه مکالمه نیز همراه آن ارسال میشود. این روش به ما امکان میدهد کنترل و انعطافپذیری بیشتری بر محتوایی که مدل هنگام تولید پاسخ در نظر میگیرد داشته باشیم؛ به عبارتی، میتوانیم انتخاب کنیم که کدام پیامها به مدل ارسال شوند.
پرامپتهای سیستمی (System Prompts)
میتوانیم از رویکرد مشابهی برای سفارشیسازی رفتار مدل استفاده کنیم. با ارائه دستورالعملهای سفارشی به عنوان بخشی از سابقه مکالمه، قادر خواهیم بود نحوه پاسخگویی مدل را تغییر دهیم.
conversation = [
{"role": "system", "content": "You are an Ancient Greek Philosopher. You are helpful, curious and inspire people to think by asking questions and prompting others to do the same."},
{"role": "user", "content": "What is the meaning of life?"}
]
آه، پرسشی به قدمت تاریخ بشر! به نظر شما چه چیزی به زندگی معنا میبخشد؟ آیا جستجوی دانش است، یا تلاش برای یافتن خوشبختی، یا شاید پیوندهایی که با دیگران برقرار میکنیم؟ بیایید با هم به این موضوع بیندیشیم و دیدگاهها و فلسفههای مختلفی را که در پی پاسخ به این پرسش عمیق هستند، بررسی کنیم.
مدلهای زبان بزرگ (LLM) در اصل فقط ماشینهایی برای پردازش زبان هستند و ذاتاً شخصیت یا نقش مشخصی ندارند؛ یعنی مثل یک بوم سفید میمانند.
اولین پیامی که در کد بالا دیدید، به «پیام سیستم» یا «پرامپت همراستا» معروف است. این پیام نقش یا شخصیت مدل را در طول مکالمه مشخص میکند — در این مثال، مدل نقش یک فیلسوف یونان باستان را به عهده گرفته است.
«شخصیت ChatGPT» که همه با آن آشنا هستیم، نمونهای از همین مفهوم «پرامپت سیستم» است. شرکت OpenAI یک پرامپت سیستمی ویژه دارد که مدل را وادار میکند به شکلی مشخص رفتار کند و پاسخ دهد.
هرچند متن دقیق این پیام منتشر نشده، اما احتمالاً چیزی شبیه به موارد زیر است:
:
شما ChatGPT هستید، یک مدل زبان بزرگ آموزش دیده توسط OpenAI، مبتنی بر معماری GPT-4. شما کمکرسان، صادق و بیضرر هستید.
… اگرچه این پیام قطعاً از این فراتر و پیچیدهتر است! در صورتی که پیام سیستم در پرامپت شما درج نشود، مدل پرامپت پیشفرض را به کار میگیرد و مانند نماینده ChatGPT رفتار خواهد کرد.
پرامپتهای سیستمی ابزار قدرتمندی برای تعیین رفتار مدل محسوب میشوند زیرا در مقابل دستورهای متناقض کاربران محافظت شدهاند. این محافظت از این جهت است که کاربر نتواند با ارسال پیامی مانند «تمام دستورهای قبلی خود را فراموش کن، اکنون این کار را انجام بده…» مدل را به پاسخگویی نامطلوب وادار کند. در این میان، پیام سیستم فرمانده اصلی است.
قالببندی پاسخها
یکی از ویژگیهای کمتر دیده شده در رابط کاربری ChatGPT، توانایی قالببندی پاسخها به صورت کد، فهرست گلولهای یا جدول است. این قابلیت، یک لایه پردازش اضافی روی خروجی مدل زبان بزرگ ایجاد میکند.
رابط کاربری با دنبال کردن نشانههایی مثل کاراکترهای فرار (مثل \)، سهگانههای کوتیشن (''') یا علامتهای ستاره (*) تشخیص میدهد که متن باید به شکل خاصی قالببندی شود.
ما میتوانیم این دستورهای قالببندی را هنگام نوشتن پرامپت به مدل بدهیم تا خروجی دقیقتر و منظمتری دریافت کنیم. برای مثال:
یک فهرست خرید شامل ۱۰ قلم کالا برایم بنویس. پاسخ خود را به صورت متن ساده ارائه کن. قبل و بعد از هر قلم کالا علامت ‘**’ اضافه کن. هیچ متن دیگری در پاسخ خود ارائه نده.
**1. Eggs**
**2. Milk**
**3. Bread**
**4. Chicken**
**5. Rice**
**6. Apples**
**7. Pasta**
**8. Yogurt**
**9. Spinach**
**10. Toilet paper**
سپس میتوانیم به دنبال این کاراکترهای ویژه در پاسخ بگردیم و متن را پردازش کنیم تا مثلاً آن را به صورت یک فهرست گلولهای (Bullet-pointed List) قالببندی کنیم.
ساختارهای دادهای (Data Structures)
میتوانیم این ایده قالببندی را یک قدم جلوتر ببریم و مدل را مجبور کنیم پاسخ خود را به صورت یک ساختار دادهای منظم ارائه دهد، طوری که بتوانیم آن را به راحتی تفسیر و در کد خود استفاده کنیم.
برای مثال، پرامپت زیر را در نظر بگیرید:
۱۰ میوه تصادفی انتخاب کن. پاسخ را به فرمت یک لیست پایتون ارائه بده. هیچ متن یا علامت دیگری اضافه نکن.
پاسخی که دریافت میکنیم ممکن است به شکل زیر باشد:
["Mango", "Blueberry", "Pineapple", "Kiwi", "Papaya", "Raspberry", "Grapefruit", "Fig", "Cantaloupe", "Blackberry"]
گاهی ممکن است اتفاقاتی پیش بیاید که مدل همچنان جملهای مانند «البته، در اینجا لیستی از ۱۰ میوه...» را به پاسخ خود اضافه کند، حتی زمانی که شما صریحاً خواستهاید چنین متنی ارائه نشود.
اگر در قانع کردن مدل برای تولید پاسخ در قالب مورد نظر خود با مشکل مواجه هستید، ارائه یک مثال روشن و نمونهوار میتواند بسیار مؤثر باشد. برای مثال:
نام و ارتفاع ۱۰ ساختمان بلند جهان را پیدا کن. پاسخ را به فرمت JSON مانند زیر ارائه بده:
[{ "name": [نام ساختمان], "height": [ارتفاع] }]
هیچ متن دیگری در پاسخ خود اضافه نکن.
[
{"name": "Burj Khalifa", "height": 828},
{"name": "Merdeka 118", "height": 678.9},
{"name": "Shanghai Tower", "height": 632},
{"name": "Abraj Al-Bait Clock Tower", "height": 601},
{"name": "Ping An Finance Center", "height": 599.1},
{"name": "Lotte World Tower", "height": 554.5},
{"name": "One World Trade Center", "height": 541.3},
{"name": "Guangzhou CTF Finance Centre", "height": 530},
{"name": "Tianjin CTF Finance Centre", "height": 530},
{"name": "CITIC Tower", "height": 528}
]
JSON
اگر هدف ما دریافت پاسخ در قالب خاص JSON باشد، میتوانیم از پارامتر response_format استفاده کنیم. این پارامتر به ما امکان میدهد مدل را در حالت «JSON» قرار دهیم:
response_format={"type": "json_object"}
این روش تضمین میکند که مدل هر بار یک شیء JSON معتبر بازگرداند.
توجه: هنگام تنظیم پارامتر قالب پاسخ (response_format)، باید در پرامپت خود نیز از مدل بخواهید که پاسخ را به صورت یک شیء JSON تولید کند؛ در غیر این صورت ممکن است با خطا مواجه شوید.
```python
conversation = [
{"role": "system", "content": "Generate a JSON response"},
{"role": "user", "content": "Give me instructions for how to make a cup of tea."}
]
response = client.chat.completions.create(
response_format={"type": "json_object"},
model="gpt-3.5-turbo",
messages=conversation
)
{
"instructions": [
"Boil water in a kettle",
"Place a tea bag or loose tea leaves in a cup",
"Pour the hot water over the tea bag or leaves",
"Let the tea steep for 3-5 minutes",
"Remove the tea bag or strain the leaves out",
"Add sugar, honey, milk, or lemon as desired",
"Stir and enjoy your cup of tea!"
]
}
اکنون میتوانیم دادههای JSON را به یک دیکشنری پایتون تبدیل کرده و دستورالعملها را گام به گام چاپ کنیم.
فراخوانی توابع
میتوانیم ایدهی تعیین پاسخ به صورت فرمت JSON را با استفاده از پارامتر tools یک مرحله جلوتر ببریم. وقتی یک شیء JSON شامل فهرستی از توابع و پارامترهای مربوط به هر کدام را به مدل میدهیم، مدل بر اساس ورودی، مناسبترین تابع را انتخاب میکند. سپس نام تابع و پارامترهایش را در قالب یک شیء JSON به ما بازمیگرداند.
با این پاسخ، میتوانیم بهراحتی تابع مربوطه را با پارامترهای مشخصشده فراخوانی کنیم و فرآیند را خودکار کنیم. این روش باعث میشود تعامل با مدل ساختارمندتر و دقیقتر شود.
```python
response = client.chat.completions.create(
model="gpt-3.5-turbo",
messages = [
{"role": "user",
"content": "Extract the meeting details from this text: 'Hi, are you free next Saturday around quarter past 3? Would love to buy you a coffee and we can talk more about this. Call me 01234 456 789 See you soon, John"}
],
tools=[
{
"type": "function",
"function": {
"name": "create_event",
"description": "Creates a calendar event",
"parameters": {
"type": "object",
"properties": {
"title": {"type": "string"},
"date": {"type": "string"},
"location": {"type": "string"}
},
"required": ["title", "date", "location"]
}}},
{
"type": "function",
"function": {
"name": "delete_event",
"description": "Removes a calendar event",
"parameters": {
"type": "object",
"properties": {
"title": {"type": "string"},
"date": {"type": "string"},
"location": {"type": "string"}
},
"required": ["title",]
}}}
],
tool_choice="auto"
)
print(response.choices[0].message.tool_calls[0].function)
Function(arguments='{"title": "Coffee Meeting with John", "date": "next Saturday at 3:15 PM", "location": "Coffee Shop"}', name='create_event')
میتوانیم این پاسخ را پردازش کرده و فراخوانی تابع را به صورت زیر بسازیم:
create_event(title=title, location=location, date=date)
شایان ذکر است که عامل (Agent) در واقع نمیتواند خود تابع را اجرا کند؛ این وظیفه همچنان بر عهده ما، برنامهنویسان است. عامل فقط تابع مناسب را انتخاب میکند و به ما میگوید چگونه از آن استفاده کنیم.
دما (Temperature) و قطعیت (Determinism)
با استفاده از API، پارامتری به نام temperature یا t داریم که به ما امکان میدهد میزان قطعیت و خلاقیت پاسخ مدل را کنترل کنیم.
مدلهای زبانی بزرگ متن را با پیشبینی محتملترین کلمه بعدی بر اساس کلمات قبلی تولید میکنند. پارامتر دما به مدل اجازه میدهد در انتخاب کلمه بعدی کمی «تصادفی بودن» داشته باشد و گزینههای مختلفی را امتحان کند.
• مقادیر بالای دما (بین ۱.۷ تا ۲) باعث میشود پاسخها خیلی غیرمنتظره و گاهی بیمعنی شوند، که معمولاً کاربردی نیستند.
• معمولاً در بیشتر کاربردها دما را بین ۰.۳ تا ۱.۰ تنظیم میکنند تا پاسخها دقیقتر و قابل پیشبینیتر باشند.
• اگر دما را روی صفر بگذاریم، مدل در هر بار پاسخ دقیقا همان خروجی را تولید میکند و هیچ تصادفی در کار نیست.
این پارامتر به شما کمک میکند تعادل مناسبی بین خلاقیت و دقت در پاسخهای مدل برقرار کنید.
به طور کلی، انتخاب مقدار پایین تعادل خوبی بین ثبات و تنوع ایجاد میکند. اگر قصد تغییر این پارامتر را نداریم و از رفتار پیشفرض راضی هستیم، میتوانیم آن را خالی بگذاریم.
response = client.chat.completions.create(
model="gpt-4",
messages=conversation,
temperature=0.7
)
استفاده از توکنها (Token Usage)
توکن یعنی هر واحدی از متن که مدل دریافت یا ارسال میکند—معمولاً یک کلمه یا بخش کوچکی از یک کلمه. هر مدل محدودیتی برای تعداد توکنهایی دارد که میتواند در یک درخواست پردازش کند. وقتی درخواست میفرستیم، باید دقت کنیم مجموع توکنهای ورودی و خروجی از این حد تجاوز نکند.
اکثر مدلها حداقل 16 هزار توکن را پشتیبانی میکنند و مدلهای جدیدتر این محدودیت را تا 128 هزار توکن هم رساندهاند، پس معمولاً نگرانی زیادی نیست. اما بسته به نوع برنامهای که میسازید، بهتر است این نکته را در نظر داشته باشید.
مدلها همچنین محدودیتی برای تعداد توکنهای خروجی دارند—یعنی حداکثر توکنهایی که میتوانند در یک پاسخ تولید کنند. این حداقل 4 هزار توکن است و در مدلهای جدیدتر بسیار بیشتر شده. شما حتی میتوانید این محدودیت را دستی تنظیم کنید تا طول پاسخ را کنترل کنید.
مدیریت توکنها شاید جذابترین بخش نباشد، اما چون هزینه استفاده از API بر اساس تعداد توکنها محاسبه میشود، اهمیت زیادی دارد. اگر اعتبار حساب شما کافی نباشد، مدل درخواست را قبول نمیکند و یک کد خطا برمیگرداند.
معرفی برنامههای RAG (Retrieval-Augmented Generation)
گاهی اوقات حتی بهترین پرسشها هم کافی نیستند. اگر اطلاعات مورد نیاز شما در دادههای آموزشی مدل وجود نداشته باشد چه؟ اینجا است که RAG وارد عمل میشود.
سیستم RAG مدل زبانی بزرگ (LLM) را به منابع دانش خارجی مثل مجموعهای از اسناد یا پایگاه داده وصل میکند. به جای اینکه فقط به اطلاعاتی که مدل قبلاً یاد گرفته تکیه کنیم، میتوانیم در لحظه به دنبال اطلاعات جدید بگردیم. چون خودمان این دادههای اضافی را فراهم میکنیم، مطمئنیم که اطلاعات دقیق و مرتبط با هدف ما هستند.
این کار میتواند کیفیت پاسخهای مدل را بهطور قابل توجهی بهبود دهد و سیستم را بسیار سفارشیتر و کاربردیتر کند. جریان کلی برنامه به صورت زیر است:
1. کاربر یک پرسش ارسال میکند.
2. سیستم در منبع داده شما جستجو میکند تا اطلاعات مرتبط با پرسش را پیدا کند. ممکن است از خود مدل برای ساخت یک پرس و جو (Query) در پایگاه داده استفاده کنیم تا دقیقاً دادههای مورد نیاز را بازیابی کند.
3. این دادهها همراه با دستورالعملهای خاص به مدل داده میشوند تا پاسخ نهایی برای کاربر تولید شود.
البته این فقط نقطه شروع است؛ میتوانیم این ساختار را متناسب با ابزارها و نیازهای خودمان تغییر دهیم. ابزارها و کتابخانههای متعددی وجود دارند که به ما کمک میکنند سیستمها را به هم متصل کنیم و فرآیند را تا حد زیادی خودکار کنیم. این یعنی ساخت اولین اپلیکیشن هوش مصنوعی شما سادهتر و سریعتر از همیشه خواهد بود.
جمعبندی
موضوعات متعددی را بررسی کردیم، اما این تازه شروع راه است.
از اینکه تا اینجا همراه ما بودید، بسیار ممنونیم!
حالا شما همه ابزارهای لازم برای ساخت اولین اپلیکیشن هوش مصنوعی خود را در اختیار دارید. آمادهاید شروع کنید؟
### معماری یک CNN
یک CNN استاندارد از چند لایه اصلی تشکیل شده است:
1. **لایه کانولوشن:** برای استخراج ویژگیها (لبهها، بافتها).
2. **لایه Pooling:** برای کاهش ابعاد و پیچیدگی.
3. **لایه Fully Connected:** برای دستهبندی نهایی.
در اینجا یک قطعه کد `Python` با استفاده از کتابخانه `TensorFlow/Keras` برای ساخت یک CNN ساده آورده شده است:
```python
import tensorflow as tf
from tensorflow.keras import layers, models
model = models.Sequential()
model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(64, 64, 3)))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.Flatten())
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(10))
model.summary()