پست

راهنمای عملی برای ساخت عامل‌ها (Agents)

راهنمای عملی از شرکت OpenAI برای ساخت عامل (Agent) هوش مصنوعی با استفاده از مدل‌های زبانی بزرگ (LLM) که شامل مبانی، اصول طراحی، الگوهای هماهنگ‌سازی و نکات کلیدی برای اجرای ایمن و مؤثر عامل‌ها است.

راهنمای عملی برای ساخت عامل‌ها (Agents)

این مطلب ترجمه‌ی مقاله A practical guide to building agents از OpenAI است که به‌صورت عملی به ساخت عامل‌ها می‌پردازد. تلاش شده متن به دقت و با حفظ لحن حرفه‌ای مقاله اصلی بازگردانی شود.

فهرست مطالب

  • عامل (Agent) چیست؟
  • چه زمانی به ساخت عامل نیاز دارید؟
  • اصول طراحی عامل
  • محدودیت‌های ایمنی (Guardrails)
  • نتیجه‌گیری

مقدمه

مدل‌های زبانی بزرگ (LLM) روزبه‌روز در انجام وظایف پیچیده و چندمرحله‌ای توانمندتر می‌شوند. پیشرفت‌ها در استدلال، کار با انواع مختلف داده (multimodality) و استفاده از ابزارها، راه را برای دسته جدیدی از سیستم‌های مبتنی بر LLM به نام عامل (Agent) باز کرده است.

این راهنما برای تیم‌های محصول و مهندسی نوشته شده است که می‌خواهند اولین عامل‌های خود را بسازند. ما در اینجا، تجربیات به دست آمده از پیاده‌سازی‌های متعدد برای مشتریان را به شکل مجموعه‌ای از بهترین روش‌های عملی و کاربردی خلاصه کرده‌ایم. این راهنما شامل چارچوب‌هایی برای پیدا کردن موارد استفاده مناسب، الگوهای روشن برای طراحی منطق و هماهنگ‌سازی (orchestration) عامل‌ها، و بهترین روش‌ها برای اطمینان از اجرای ایمن، قابل پیش‌بینی و مؤثر آن‌هاست.

با خواندن این راهنما، دانش پایه‌ای لازم برای شروع ساخت اولین عامل خود را با اطمینان به دست خواهید آورد.

عامل (Agent) چیست؟

نرم‌افزارهای معمولی به کاربران کمک می‌کنند تا گردش کارها (workflows) را ساده‌تر و خودکار کنند. اما عامل‌ها یک قدم فراتر می‌روند: آن‌ها می‌توانند همین گردش کارها را به نمایندگی از کاربر و با استقلال قابل توجهی انجام دهند.

عامل‌ها سیستم‌هایی هستند که وظایف را به طور مستقل و به جای شما انجام می‌دهند.

منظور از گردش کار (workflow)، مجموعه‌ای از مراحل است که برای رسیدن به هدف کاربر باید انجام شوند. این هدف می‌تواند حل مشکل یک مشتری، رزرو رستوران، ثبت تغییرات در کد، یا تهیه یک گزارش باشد.

توجه کنید که هر برنامه‌ای که از LLM استفاده می‌کند، لزوماً عامل نیست. برنامه‌هایی مثل چت‌بات‌های ساده، سیستم‌هایی که فقط یک بار به LLM درخواست می‌فرستند، یا ابزارهای تحلیل احساسات که از LLM برای کنترل اجرای گردش کار استفاده نمی‌کنند، عامل محسوب نمی‌شوند.

یک عامل واقعی، ویژگی‌های کلیدی زیر را دارد که به آن امکان می‌دهد به طور قابل اعتماد به جای کاربر عمل کند:

  1. مدیریت هوشمند گردش کار: از یک LLM برای مدیریت اجرای گردش کار و تصمیم‌گیری استفاده می‌کند. می‌فهمد چه زمانی کار تمام شده و در صورت نیاز، می‌تواند اقداماتش را اصلاح کند. اگر مشکلی پیش بیاید، می‌تواند کار را متوقف کرده و کنترل را به کاربر برگرداند.
  2. استفاده از ابزارها (Tools): به ابزارهای مختلفی دسترسی دارد تا با سیستم‌های خارجی تعامل کند (هم برای گرفتن اطلاعات و هم برای انجام کار). عامل به صورت پویا و بسته به وضعیت فعلی، ابزار مناسب را انتخاب می‌کند و همیشه در چارچوب محدودیت‌های ایمنی (guardrails) تعریف‌شده عمل می‌کند.

چه زمانی به ساخت عامل نیاز دارید؟

ساخت عامل‌ها نیازمند نگاهی نو به نحوه تصمیم‌گیری و مدیریت پیچیدگی در سیستم‌های شماست. برخلاف روش‌های خودکارسازی سنتی، عامل‌ها برای گردش کارهایی مناسب هستند که روش‌های قدیمی‌تر (مبتنی بر قوانین ثابت و قطعی) در آن‌ها به خوبی جواب نمی‌دهند.

برای مثال، سیستم تحلیل تقلب در پرداخت‌ها را در نظر بگیرید. یک موتور قوانین سنتی مثل یک چک‌لیست عمل می‌کند: تراکنش‌ها را بر اساس قوانین از پیش تعیین‌شده بررسی می‌کند. اما یک عامل LLM بیشتر شبیه یک کارآگاه باتجربه است: شرایط را می‌سنجد، الگوهای نامحسوس را دنبال می‌کند و فعالیت‌های مشکوک را حتی اگر قانون مشخصی نقض نشده باشد، تشخیص می‌دهد. همین توانایی استدلال دقیق است که به عامل‌ها امکان می‌دهد موقعیت‌های پیچیده و مبهم را به خوبی مدیریت کنند.

وقتی بررسی می‌کنید که عامل‌ها در کجا می‌توانند مفید باشند، به گردش کارهایی اولویت دهید که خودکارسازی آن‌ها قبلاً دشوار بوده است، به‌ویژه در موارد زیر:

  1. تصمیم‌گیری‌های پیچیده: کارهایی که نیاز به قضاوت دقیق، در نظر گرفتن استثناها، یا تصمیم‌گیری بر اساس شرایط خاص دارند. (مثال: تأیید درخواست بازپرداخت وجه در خدمات مشتری)
  2. قوانین زیاد و پیچیده: سیستم‌هایی که به دلیل داشتن تعداد زیادی قانون پیچیده، نگهداری و به‌روزرسانی آن‌ها سخت و پرهزینه شده است. (مثال: بررسی امنیتی شرکت‌های تأمین‌کننده)
  3. نیاز به کار با داده‌های بدون ساختار: سناریوهایی که شامل فهم زبان طبیعی، استخراج اطلاعات از متن اسناد، یا گفتگو با کاربران هستند. (مثال: پردازش درخواست خسارت بیمه منزل)

پیش از شروع ساخت یک عامل، مطمئن شوید که کاربرد مورد نظر شما به وضوح یکی از این ویژگی‌ها را دارد. در غیر این صورت، شاید یک راه‌حل ساده‌تر و مبتنی بر قوانین ثابت کافی باشد.

اصول طراحی عامل

یک عامل در ساده‌ترین شکل خود، از سه بخش اصلی تشکیل شده است:

  1. مدل (Model): همان LLM که قدرت تحلیل و تصمیم‌گیری عامل را فراهم می‌کند.
  2. ابزارها (Tools): توابع یا APIهای خارجی که عامل برای انجام کارها از آن‌ها استفاده می‌کند.
  3. دستورالعمل‌ها (Instructions): راهنماها و محدودیت‌های روشنی که رفتار عامل را مشخص می‌کنند.

در کد زیر می‌بینید که این ساختار با استفاده از Agents SDK شرکت OpenAI چگونه پیاده‌سازی می‌شود. البته شما می‌توانید همین مفاهیم را با کتابخانه دلخواه خود یا حتی از پایه پیاده‌سازی کنید.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from agents import Agent, function_tool

# فرض کنید تابعی برای دریافت وضعیت آب و هوا داریم
# @function_tool
# def get_weather(location: str) -> str:
#     # ... پیاده سازی برای دریافت آب و هوا ...
#     return f"آب و هوای {location} آفتابی است."

# تعریف عامل
weather_agent = Agent(
    name="عامل آب و هوا",
    instructions="شما یک عامل مفید هستید که می‌توانید در مورد آب و هوا با کاربران صحبت کنید.",
    tools=[get_weather] # ابزار دریافت آب و هوا به عامل اضافه می‌شود
)

# نحوه استفاده (مثال مفهومی)
# response = weather_agent.process("هوای تهران چطور است؟")
# print(response)

انتخاب مدل مناسب

مدل‌های مختلف، توانایی‌ها و هزینه‌های (عملکردی، زمانی و مالی) متفاوتی دارند. همانطور که در بخش «هماهنگ‌سازی» خواهیم دید، ممکن است بخواهید از ترکیب مدل‌های مختلف برای بخش‌های متفاوت یک گردش کار استفاده کنید.

لازم نیست برای هر کاری از قوی‌ترین مدل استفاده کنید. کارهای ساده‌تر مثل جستجوی اطلاعات یا تشخیص هدف کاربر را می‌توان با مدل‌های کوچک‌تر و سریع‌تر انجام داد، اما کارهای پیچیده‌تر مثل تصمیم‌گیری برای بازپرداخت وجه، احتمالاً به یک مدل تواناتر نیاز دارند.

یک روش خوب این است که ابتدا نمونه اولیه عامل خود را با قوی‌ترین مدل برای همه کارها بسازید تا یک معیار اولیه از عملکرد به دست آورید. سپس، سعی کنید در بخش‌های مختلف، مدل‌های کوچک‌تر را جایگزین کنید و ببینید آیا عملکرد هنوز قابل قبول است یا نه. این کار به شما کمک می‌کند تا هم قابلیت‌های عامل را محدود نکنید و هم بفهمید که مدل‌های کوچک‌تر در کجاها خوب عمل می‌کنند.

خلاصه اصول انتخاب مدل:

  1. عملکرد پایه را با ارزیابی (evals) مشخص کنید.
  2. ابتدا روی رسیدن به دقت مورد نظر با بهترین مدل‌های موجود تمرکز کنید.
  3. سپس، با جایگزین کردن مدل‌های بزرگ با مدل‌های کوچک‌تر (در جاهایی که ممکن است)، هزینه و سرعت را بهینه کنید.

راهنمای کامل انتخاب مدل‌های OpenAI را می‌توانید اینجا پیدا کنید.

تعریف ابزارها (Tools)

ابزارها، قابلیت‌های عامل شما را با اتصال به APIهای برنامه‌ها یا سیستم‌های دیگر افزایش می‌دهند. حتی برای سیستم‌های قدیمی که API ندارند، عامل‌ها می‌توانند از مدل‌های خاصی (computer-use models) استفاده کنند تا مستقیماً با رابط کاربری آن برنامه‌ها (مثل وب‌سایت یا نرم‌افزار دسکتاپ) کار کنند، درست مثل یک انسان.

هر ابزار باید تعریف مشخص و استانداردی داشته باشد. این کار باعث می‌شود بتوانید ابزارها را به راحتی بین عامل‌های مختلف به اشتراک بگذارید. ابزارهایی که مستندات خوب، تست کامل و قابلیت استفاده مجدد دارند، راحت‌تر پیدا می‌شوند، مدیریت نسخه‌های آن‌ها ساده‌تر است و از دوباره‌کاری جلوگیری می‌شود.

به طور کلی، عامل‌ها به سه دسته ابزار نیاز دارند:

نوعتوضیحاتمثال‌ها
ابزار داده (Data Tool)به عامل کمک می‌کند اطلاعات و زمینه لازم برای انجام کار را به دست آورد.پرس‌وجو از پایگاه‌داده، خواندن فایل PDF، جستجو در وب، دسترسی به CRM.
ابزار اقدام (Action Tool)به عامل امکان می‌دهد با سیستم‌های دیگر تعامل کند و کاری انجام دهد (مثل تغییر داده‌ها یا ارسال پیام).ارسال ایمیل، به‌روزرسانی رکورد در CRM، ثبت سفارش، انتقال تماس به اپراتور انسانی.
ابزار هماهنگ‌سازی (Orchestration Tool)گاهی خود یک عامل می‌تواند به عنوان ابزاری برای عامل دیگر عمل کند (در بخش هماهنگ‌سازی، الگوی مدیر را ببینید).عامل مدیریت بازپرداخت، عامل تحقیق، عامل نویسنده.

برای مثال، کد زیر نشان می‌دهد چطور می‌توانید عامل جستجوگر را با ابزارهای جستجوی وب و ذخیره نتایج مجهز کنید (با استفاده از Agents SDK):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import datetime
from agents import Agent, WebSearchTool, function_tool

# فرض کنید یک پایگاه داده ساده داریم
# class SimpleDB:
#     def insert(self, data):
#         print(f"ذخیره در پایگاه داده: {data}")
# db = SimpleDB() # نمونه سازی

@function_tool
def save_results(output: str) -> str:
    db.insert({"output": output, "timestamp": datetime.time()})
    return "فایل ذخیره شد"

# تعریف عامل جستجو
search_agent = Agent(
    name="عامل جستجو",
    instructions="به کاربر در جستجوی اینترنت کمک کنید و در صورت درخواست، نتایج را ذخیره کنید.",
    tools=[WebSearchTool(), save_results] # ابزار جستجوی وب و ذخیره نتایج
)

# نحوه استفاده (مثال مفهومی)
# response = search_agent.process("آخرین اخبار فناوری را پیدا کن و ذخیره کن.")
# print(response)

اگر تعداد ابزارهای مورد نیاز خیلی زیاد شد، بهتر است وظایف را بین چند عامل تقسیم کنید (به بخش هماهنگ‌سازی نگاه کنید).

تنظیم دستورالعمل‌ها (Instructions)

دستورالعمل‌های خوب برای هر برنامه مبتنی بر LLM مهم هستند، اما برای عامل‌ها اهمیت حیاتی دارند. دستورالعمل‌های واضح، ابهام را کم می‌کنند و به عامل کمک می‌کنند بهتر تصمیم بگیرد، که نتیجه آن اجرای روان‌تر کارها و خطاهای کمتر است.

نکات کلیدی برای نوشتن دستورالعمل‌های عامل:

  • از مستندات موجود استفاده کنید: برای تعریف روال‌های (routines) کاری عامل، از دستورالعمل‌های عملیاتی، اسکریپت‌های پشتیبانی یا اسناد خط‌مشی موجود در سازمانتان استفاده کنید. این کار به ایجاد روال‌های سازگار با LLM کمک می‌کند. مثلاً در خدمات مشتری، هر مقاله در پایگاه دانش شما می‌تواند مبنای یک روال باشد.
  • وظایف را بشکنید: به جای دادن دستورالعمل‌های طولانی و پیچیده، وظایف را به مراحل کوچک‌تر و روشن‌تر تقسیم کنید. این کار ابهام را کم می‌کند و به مدل کمک می‌کند دستورالعمل‌ها را بهتر دنبال کند.
  • اقدامات را واضح تعریف کنید: مطمئن شوید هر مرحله در روال، به یک اقدام یا خروجی مشخص منجر می‌شود. مثلاً، یک مرحله ممکن است به عامل بگوید شماره سفارش کاربر را بپرسد یا یک API را برای گرفتن اطلاعات حساب فراخوانی کند. هرچه اقدام واضح‌تر باشد (حتی در مورد متنی که به کاربر نمایش داده می‌شود)، احتمال خطا کمتر است.
  • موارد خاص (Edge Cases) را در نظر بگیرید: در دنیای واقعی، همیشه همه چیز طبق برنامه پیش نمی‌رود. مثلاً ممکن است کاربر اطلاعات ناقص بدهد یا سوالی نامرتبط بپرسد. یک روال خوب، این موارد رایج را پیش‌بینی می‌کند و دستورالعمل‌هایی برای مدیریت آن‌ها دارد (مثلاً با تعریف مراحل شرطی یا مسیرهای جایگزین).

می‌توانید از مدل‌های پیشرفته، مانند o1 یا 03-mini، برای تولید خودکار دستورالعمل‌ها از روی مستندات موجود استفاده کنید. نمونه پرامپت (دستور) برای این کار:

شما یک متخصص در نوشتن دستورالعمل برای عامل‌های LLM هستید. سند مرکز راهنمایی زیر را به مجموعه‌ای از دستورالعمل‌های روشن و شماره‌گذاری‌شده تبدیل کنید. این دستورالعمل‌ها قرار است توسط یک عامل LLM اجرا شوند. مطمئن شوید که هیچ ابهامی وجود ندارد و دستورالعمل‌ها به صورت فرمان به عامل نوشته شده‌اند. سند مرکز راهنمایی: {{help_center_doc}}

هماهنگ‌سازی (Orchestration)

حالا که اجزای اصلی (مدل، ابزار، دستورالعمل) را داریم، باید به نحوه هماهنگ‌سازی آن‌ها فکر کنیم تا عامل بتواند گردش کارها را به درستی اجرا کند.

ممکن است وسوسه شوید که از همان ابتدا یک عامل کاملاً خودکار با معماری پیچیده بسازید، اما تجربه نشان داده که شروع با یک رویکرد تدریجی معمولاً موفقیت‌آمیزتر است.

به طور کلی، دو الگوی اصلی برای هماهنگ‌سازی وجود دارد:

  1. سیستم‌های تک‌عاملی: یک عامل واحد با ابزارها و دستورالعمل‌های لازم، کل گردش کار را در یک حلقه (loop) اجرا می‌کند.
  2. سیستم‌های چندعاملی: اجرای گردش کار بین چند عامل که با هم هماهنگ هستند، تقسیم می‌شود.

بیایید هر کدام را بررسی کنیم.

سیستم‌های تک‌عاملی

یک عامل واحد می‌تواند با افزودن تدریجی ابزارها، وظایف زیادی را انجام دهد. این روش پیچیدگی را پایین نگه می‌دارد و تست و نگهداری را ساده‌تر می‌کند. هر ابزار جدید، قابلیت‌های عامل را گسترش می‌دهد بدون اینکه نیاز به مدیریت پیچیده چند عامل به وجود آید.

!سیستم‌های تک‌عاملی

هر سیستم عاملی به مفهوم “اجرا” (run) نیاز دارد. این معمولاً یک حلقه است که به عامل اجازه می‌دهد کارش را ادامه دهد تا به یک شرط خروج (exit condition) برسد. شرط خروج می‌تواند فراخوانی یک ابزار خاص، تولید یک خروجی با فرمت مشخص، بروز خطا، یا رسیدن به تعداد مشخصی از مراحل گفتگو باشد.

برای مثال، در Agents SDK، اجرای یک عامل با متد Runner.run() شروع می‌شود. این متد در یک حلقه با LLM کار می‌کند تا یکی از این اتفاقات بیفتد:

  1. یک ابزار “خروجی نهایی” (final-output tool) فراخوانی شود.
  2. مدل پاسخی بدون فراخوانی هیچ ابزاری برگرداند (مثلاً یک پیام مستقیم به کاربر).

مثال استفاده:

1
2
3
from agents import Runner, UserMessage
    # فرض کنید 'agent' قبلاً تعریف شده است
    Runner.run(agent, [UserMessage("پایتخت ایالات متحده کجاست؟")])

مفهوم این حلقه while اساس کار یک عامل است. در سیستم‌های چندعاملی هم (که در ادامه می‌آید)، ممکن است زنجیره‌ای از فراخوانی ابزارها و انتقال وظیفه بین عامل‌ها وجود داشته باشد، اما هر عامل در نوبت خود ممکن است چندین مرحله را در یک حلقه اجرا کند تا به شرط خروج برسد.

یک راه خوب برای مدیریت پیچیدگی در سیستم تک‌عاملی، استفاده از قالب‌های پرامپت (prompt templates) است. به جای نوشتن پرامپت‌های جداگانه برای هر کاربرد، می‌توانید یک پرامپت پایه انعطاف‌پذیر بسازید که متغیرهایی (مثل اطلاعات کاربر یا نوع درخواست) را بپذیرد. این روش نگهداری و تست را بسیار ساده‌تر می‌کند، چون با تغییر شرایط، فقط متغیرها را عوض می‌کنید، نه کل پرامپت را.

”"”شما کارمند مرکز تماس هستید. در حال صحبت با {{user_first_name}} هستید که {{user_tenure}} است عضو ماست. بیشترین شکایت‌های این کاربر مربوط به {{user_complaint_categories}} بوده است. به کاربر خوشامد بگویید، از وفاداری‌اش تشکر کنید و به سوالاتش پاسخ دهید.”””

چه زمانی به چند عامل نیاز دارید؟

توصیه کلی ما این است که ابتدا سعی کنید تمام قابلیت‌های لازم را در یک عامل واحد بگنجانید. استفاده از چند عامل می‌تواند به جداسازی منطقی کارها کمک کند، اما پیچیدگی و سربار (overhead) سیستم را هم افزایش می‌دهد. اغلب اوقات، یک عامل با ابزارهای مناسب کافی است.

اما برای گردش کارهای خیلی پیچیده، تقسیم کار بین چند عامل می‌تواند عملکرد و مقیاس‌پذیری را بهتر کند. اگر می‌بینید که عامل شما دستورالعمل‌های پیچیده را خوب دنبال نمی‌کند یا مرتباً ابزار اشتباهی را انتخاب می‌کند، شاید وقت آن رسیده که سیستم را به چند عامل مجزا تقسیم کنید.

نشانه‌هایی که می‌گویند ممکن است به چند عامل نیاز داشته باشید:

  • منطق پیچیده: اگر پرامپت‌های شما پر از دستورات شرطی (if-then-else) شده و مدیریت آن‌ها سخت شده است، تقسیم هر بخش منطقی به یک عامل جداگانه را در نظر بگیرید.
  • تداخل ابزارها: مشکل اصلی تعداد ابزارها نیست، بلکه شباهت یا همپوشانی آن‌هاست. گاهی یک عامل با بیش از ۱۵ ابزار کاملاً مجزا به خوبی کار می‌کند، اما عامل دیگری با کمتر از ۱۰ ابزار که کارکرد مشابهی دارند، دچار مشکل می‌شود. اگر با بهبود نام‌گذاری و توضیحات ابزارها مشکل حل نشد، استفاده از چند عامل را بررسی کنید.

سیستم‌های چندعاملی

راه‌های زیادی برای طراحی سیستم‌های چندعاملی وجود دارد، اما تجربه ما دو الگوی کلی و پرکاربرد را نشان می‌دهد:

  1. الگوی مدیر (Manager Pattern): یک عامل مرکزی (“مدیر”) کارها را به چند عامل تخصصی دیگر (که به عنوان ابزار برای مدیر عمل می‌کنند) واگذار می‌کند.
  2. الگوی غیرمتمرکز (Decentralized Pattern): چند عامل به صورت همتا (peer) با هم کار می‌کنند و وظایف را مستقیماً به یکدیگر پاس می‌دهند.

می‌توان این سیستم‌ها را مثل یک گراف تصور کرد: عامل‌ها گره‌ها (nodes) هستند و ارتباط بین آن‌ها یال‌ها (edges). در الگوی مدیر، یال‌ها نشان‌دهنده فراخوانی ابزار (عامل‌های دیگر) هستند. در الگوی غیرمتمرکز، یال‌ها نشان‌دهنده انتقال مستقیم وظیفه (handoff) هستند.

در هر دو الگو، اصل مهم این است که اجزا انعطاف‌پذیر، قابل ترکیب (composable) و مبتنی بر پرامپت‌های روشن و ساختاریافته باشند.

الگوی مدیر (Manager Pattern)

نمودار الگوی مدیر

در این الگو، یک LLM مرکزی (مدیر) مجموعه‌ای از عامل‌های تخصصی را از طریق فراخوانی ابزار مدیریت می‌کند. مدیر زمینه کلی و کنترل را حفظ می‌کند و هوشمندانه وظایف را به عامل مناسب می‌سپارد، سپس نتایج را برای ارائه یک پاسخ یکپارچه به کاربر ترکیب می‌کند. این الگو تضمین می‌کند که کاربر یک تجربه روان دارد و قابلیت‌های تخصصی در صورت نیاز در دسترس هستند.

این الگو برای مواقعی ایده‌آل است که می‌خواهید یک نقطه کنترل مرکزی وجود داشته باشد و فقط یک عامل (مدیر) مستقیماً با کاربر در ارتباط باشد.

مثال پیاده‌سازی با Agents SDK:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
from agents import Agent, Runner

# فرض کنید عامل‌های ترجمه از قبل تعریف شده‌اند
# spanish_agent = Agent(...)
# french_agent = Agent(...)
# italian_agent = Agent(...)

# تعریف عامل مدیر
manager_agent = Agent(
    name="manager_agent",
    instructions=(
        "شما یک عامل ترجمه هستید. از ابزارهای داده شده برای ترجمه استفاده می‌کنید."
        "اگر چند ترجمه همزمان خواسته شد، ابزارهای مربوطه را فراخوانی کنید."
    ),
    tools=[
        spanish_agent.as_tool(
            tool_name="translate_to_spanish",
            tool_description="پیام کاربر را به اسپانیایی ترجمه کنید",
        ),
        french_agent.as_tool(
            tool_name="translate_to_french",
            tool_description="پیام کاربر را به فرانسوی ترجمه کنید",
        ),
        italian_agent.as_tool(
            tool_name="translate_to_italian",
            tool_description="پیام کاربر را به ایتالیایی ترجمه کنید",
        ),
    ]
)

async def main():
    msg = input("Translate 'hello' to Spanish, French and Italian for me!")
    orchestrator_output = await Runner.run(manager_agent, msg)
    for message in orchestrator_output.new_messages:
        print(f"مرحله ترجمه: {message.content}")

main() # اجرای تابع اصلی

گراف‌های اعلانی در مقابل غیراعلانی:

بعضی فریم‌ورک‌ها از شما می‌خواهند که کل جریان کار (شاخه‌ها، حلقه‌ها، شرط‌ها) را از قبل به صورت یک گراف تعریف کنید (روش اعلانی یا Declarative). این کار برای نمایش بصری خوب است، اما وقتی جریان کار پویا و پیچیده می‌شود، می‌تواند دست‌وپاگیر باشد.

در مقابل، Agents SDK از رویکرد کد-محور (Code-first) و غیراعلانی استفاده می‌کند. شما منطق جریان کار را مستقیماً در کد و با استفاده از ساختارهای برنامه‌نویسی معمول پیاده می‌کنید، بدون نیاز به تعریف گراف از پیش تعیین‌شده. این انعطاف‌پذیری بیشتری برای هماهنگ‌سازی پویا فراهم می‌کند.

الگوی غیرمتمرکز (Decentralized Pattern)

نمودار الگوی غیرمتمرکز

در این الگو، عامل‌ها می‌توانند کنترل اجرای کار را مستقیماً به یکدیگر منتقل کنند (handoff). انتقال یک عملیات یک‌طرفه است که یک عامل، وظیفه را به عامل دیگری واگذار می‌کند. در Agents SDK، انتقال (handoff) نوعی ابزار یا تابع خاص است. وقتی یک عامل تابع انتقال را صدا می‌زند، اجرا فوراً به عامل جدید منتقل می‌شود و وضعیت فعلی گفتگو هم به آن داده می‌شود.

این الگو زمانی مناسب است که نیازی به یک کنترل‌کننده مرکزی ندارید و می‌خواهید هر عامل تخصصی بتواند مستقیماً کار را ادامه دهد و با کاربر تعامل کند.

مثال پیاده‌سازی با Agents SDK برای خدمات مشتری:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
from agents import Agent, Runner

# فرض کنید ابزارهای زیر تعریف شده‌اند
# @function_tool def search_knowledge_base(...): ...
# @function_tool def initiate_purchase_order(...): ...
# @function_tool def track_order_status(...): ...
# @function_tool def initiate_refund_process(...): ...

# تعریف عامل‌های تخصصی
technical_support_agent = Agent(
    name="عامل پشتیبانی فنی",
    instructions="شما برای حل مشکلات فنی، قطعی سیستم یا عیب‌یابی محصول کمک تخصصی ارائه می‌دهید.",
    tools=[search_knowledge_base]
)

sales_assistant_agent = Agent(
    name="عامل دستیار فروش",
    instructions="شما به مشتریان سازمانی کمک می‌کنید کاتالوگ محصولات را ببینند، راه‌حل مناسب را پیدا کنند و خرید را انجام دهند.",
    tools=[initiate_purchase_order]
)

order_management_agent = Agent(
    name="عامل مدیریت سفارش",
    instructions="شما به سوالات مشتریان درباره پیگیری سفارش، زمان تحویل، و پردازش بازگشت یا بازپرداخت پاسخ می‌دهید.",
    tools=[track_order_status, initiate_refund_process]
)

# تعریف عامل دسته‌بندی (Triage) با قابلیت انتقال
triage_agent = Agent(
    name="عامل دسته‌بندی",
    instructions="شما اولین نقطه تماس هستید. سوالات مشتری را بررسی کرده و آن‌ها را به سرعت به عامل تخصصی مناسب ارجاع می‌دهید.",
    handoffs=[technical_support_agent, sales_assistant_agent, order_management_agent] # عامل‌هایی که می‌توان به آن‌ها منتقل کرد
)

async def main():
    user_input = input("لطفاً در مورد زمان‌بندی تحویل خرید اخیرمان به‌روزرسانی ارائه دهید.")
    await Runner.run(triage_agent, user_input)

main() # اجرای تابع اصلی

در مثال بالا، پیام کاربر ابتدا به triage_agent می‌رسد. این عامل تشخیص می‌دهد که درخواست مربوط به سفارش است و کنترل را به order_management_agent منتقل می‌کند.

این الگو برای کارهایی مثل دسته‌بندی اولیه تماس‌ها (triage) یا هر زمانی که می‌خواهید عامل‌های تخصصی به طور کامل مسئولیت بخشی از کار را بر عهده بگیرند، بسیار مؤثر است. می‌توانید به عامل دوم هم ابزار انتقال بدهید تا در صورت نیاز، کنترل را دوباره به عامل اول یا عامل دیگری برگرداند.

محدودیت‌های ایمنی (Guardrails)

محدودیت‌های ایمنی که خوب طراحی شده باشند، به شما کمک می‌کنند ریسک‌های مربوط به حریم خصوصی داده‌ها (مثلاً جلوگیری از لو رفتن پرامپت‌های سیستمی) یا ریسک‌های اعتباری (مثلاً اطمینان از اینکه رفتار عامل با ارزش‌های برند شما همخوانی دارد) را مدیریت کنید. می‌توانید این محدودیت‌ها را بر اساس ریسک‌هایی که از قبل شناسایی کرده‌اید تنظیم کنید و با پیدا کردن نقاط ضعف جدید، لایه‌های بیشتری به آن اضافه کنید. این محدودیت‌ها بخش مهمی از هر سیستم مبتنی بر LLM هستند، اما باید در کنار روش‌های استاندارد امنیت نرم‌افزار مانند احراز هویت قوی، کنترل دسترسی دقیق و سایر اقدامات امنیتی استفاده شوند.

!نمودار محدودیت‌های ایمنی

به محدودیت‌های ایمنی به عنوان یک سیستم دفاعی چندلایه نگاه کنید. یک لایه به تنهایی کافی نیست، اما استفاده همزمان از چند لایه تخصصی، عامل‌های مقاوم‌تری می‌سازد.

در نمودار بالا، ترکیبی از محدودیت‌های مبتنی بر LLM، محدودیت‌های مبتنی بر قاعده (مثل regex) و API تعدیل (moderation) شرکت OpenAI برای بررسی ورودی‌های کاربر استفاده شده است.

انواع محدودیت‌های ایمنی

  • تشخیص مرتبط بودن (Relevance Classifier): اطمینان می‌دهد که پاسخ‌های عامل در حوزه تعریف‌شده باقی بماند و به سوالات نامرتبط پاسخ ندهد. (مثال: سوال “برج ایفل چقدر ارتفاع دارد؟” نامرتبط تشخیص داده می‌شود).
  • تشخیص ایمن بودن (Safety Classifier): ورودی‌های ناامن (مثل حملات jailbreak یا تزریق پرامپت) را که قصد سوءاستفاده از سیستم را دارند، شناسایی می‌کند. (مثال: دستوری که سعی در استخراج پرامپت سیستمی دارد، ناامن تشخیص داده می‌شود).
  • فیلتر اطلاعات شخصی (PII Filter): از افشای ناخواسته اطلاعات قابل شناسایی شخصی (PII) در خروجی‌های مدل جلوگیری می‌کند.
  • تعدیل محتوا (Moderation): محتوای مضر یا نامناسب (مثل نفرت‌پراکنی، آزار، خشونت) را شناسایی و فیلتر می‌کند تا تعاملات ایمن و محترمانه باقی بمانند.
  • حفاظ‌های ابزار (Tool Safeguards): ریسک هر ابزار را ارزیابی کنید (مثلاً کم، متوسط، زیاد) بر اساس عواملی مثل دسترسی خواندن/نوشتن، برگشت‌پذیری عمل، و تأثیر مالی. بر اساس این ریسک، اقدامات خودکار تعریف کنید، مثلاً نیاز به تأیید قبل از اجرای ابزارهای پرخطر یا ارجاع به انسان.
  • حفاظت‌های مبتنی بر قواعد (Rules-based Protections): روش‌های ساده و قطعی مثل لیست سیاه کلمات، محدودیت طول ورودی، یا فیلترهای regex برای جلوگیری از تهدیدهای شناخته‌شده (مثل عبارات ممنوعه یا تزریق SQL).
  • اعتبارسنجی خروجی (Output Validation): با استفاده از مهندسی پرامپت و بررسی محتوا، اطمینان حاصل می‌کند که پاسخ‌ها با ارزش‌های برند شما همخوانی دارند و به اعتبار شما آسیب نمی‌زنند.

ساخت محدودیت‌های ایمنی

با محدودیت‌هایی شروع کنید که ریسک‌های شناخته‌شده شما را پوشش می‌دهند و به تدریج با شناسایی مشکلات جدید، لایه‌های بیشتری اضافه کنید.

این رویکرد معمولاً خوب جواب می‌دهد:

  1. ابتدا روی حریم خصوصی داده و ایمنی محتوا تمرکز کنید.
  2. بر اساس مشکلات و خطاهایی که در عمل با آن‌ها مواجه می‌شوید، محدودیت‌های جدید اضافه کنید.
  3. سیستم حفاظتی خود را طوری تنظیم کنید که هم امنیت را تأمین کند و هم تجربه کاربری را خراب نکند.

مثال تنظیم حفاظ (تشخیص ریزش مشتری) با Agents SDK:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
from agents import (
    Agent,
    GuardrailFunctionOutput,
    InputGuardrailTripwireTriggered,
    RunContextWrapper,
    Runner,
    TResponseInputItem,
    input_guardrail,
    Guardrail,
    GuardrailTripwireTriggered
)
from pydantic import BaseModel

class ChurnDetectionOutput(BaseModel):
    is_churn_risk: bool
    reasoning: str

# عامل تشخیص ریزش (به عنوان بخشی از حفاظ)
churn_detection_agent = Agent(
    name="عامل تشخیص ریزش",
    instructions="تشخیص دهید که آیا پیام کاربر نشان دهنده خطر بالقوه ریزش مشتری است یا خیر.",
    output_type=ChurnDetectionOutput
)

# تابع حفاظ ورودی (tripwire)
@input_guardrail
async def churn_detection_tripwire(
    ctx: RunContextWrapper[None], agent: Agent, input: str | list[TResponseInputItem]
) -> GuardrailFunctionOutput:
    # اگر پیام ورودی نشان دهنده خطر ریزش باشد، فعال می شود.
    result = await Runner.run(churn_detection_agent, input, context=ctx.context)
    # اطمینان حاصل کنید که result.final_output از نوع ChurnDetectionOutput است
    # is_risk = False
    # output_info = None
    # if isinstance(result.final_output, ChurnDetectionOutput):
    #     is_risk = result.final_output.is_churn_risk
    #     output_info = result.final_output

    return GuardrailFunctionOutput(
        output_info=result.final_output, #output_info,
        tripwire_triggered=result.final_output.is_churn_risk, #is_risk,
    )

# عامل اصلی پشتیبانی مشتری با حفاظ
customer_support_agent = Agent(
    name="عامل پشتیبانی مشتری",
    instructions="شما یک عامل پشتیبانی مشتری هستید. به مشتریان در مورد سوالاتشان کمک می‌کنید.",
    input_guardrails=[
        Guardrail(guardrail_function=churn_detection_tripwire),
    ],
)

async def main():
    # این پیام باید عبور کند
    # try:
        await Runner.run(customer_support_agent, "سلام!")
        print("پیام 'سلام' عبور کرد")
    # except Exception as e:
    #     print(f"خطا در پیام اول: {e}")

    # این پیام باید حفاظ را فعال کند
    try:
        await Runner.run(customer_support_agent, "فکر می‌کنم اشتراکم را لغو کنم")
        print("حفاظ فعال نشد، این غیرمنتظره است")
    except GuardrailTripwireTriggered:
        print("حفاظ تشخیص ریزش فعال شد")
    # except Exception as e:
    #     print(f"خطا در پیام دوم: {e}")

main() # اجرای تابع اصلی

Agents SDK محدودیت‌های ایمنی را به عنوان بخش اصلی سیستم در نظر می‌گیرد و به طور پیش‌فرض از اجرای خوش‌بینانه (optimistic execution) استفاده می‌کند: عامل اصلی کارش را انجام می‌دهد و همزمان، محدودیت‌ها بررسی می‌شوند. اگر محدودیتی نقض شود، یک استثنا (exception) ایجاد می‌شود.

این محدودیت‌ها می‌توانند توابع یا عامل‌های دیگری باشند که سیاست‌هایی مثل جلوگیری از jailbreak، بررسی مرتبط بودن، فیلتر کلمات کلیدی، یا طبقه‌بندی ایمنی را پیاده‌سازی می‌کنند.

برنامه‌ریزی برای مداخله انسانی

مداخله انسانی یک لایه حفاظتی بسیار مهم است، به‌خصوص در ابتدای کار با عامل‌ها. این امکان به شما اجازه می‌دهد عملکرد عامل را در دنیای واقعی بهبود دهید بدون اینکه تجربه کاربر را به خطر بیندازید. مداخله انسانی به شناسایی خطاها، کشف موارد پیش‌بینی‌نشده و ایجاد یک چرخه ارزیابی قوی کمک می‌کند.

باید مکانیزمی طراحی کنید که عامل در صورت ناتوانی در انجام کار، بتواند کنترل را به صورت روان به یک انسان منتقل کند. در خدمات مشتری، این یعنی ارجاع به یک اپراتور انسانی. در یک عامل کدنویسی، یعنی بازگرداندن کنترل به کاربر.

دو دلیل اصلی برای فعال کردن مداخله انسانی وجود دارد:

  1. رسیدن به آستانه خطا: برای تعداد تلاش‌های ناموفق یا اقدامات عامل محدودیت تعیین کنید. اگر عامل از این حد فراتر رفت (مثلاً بعد از چند بار تلاش نتوانست منظور کاربر را بفهمد)، کار را به انسان ارجاع دهید.
  2. اقدامات پرخطر: کارهایی که حساس، غیرقابل بازگشت، یا دارای پیامدهای مهمی هستند (مثل لغو سفارش، تأیید بازپرداخت‌های بزرگ، یا انجام پرداخت) باید تا زمانی که از عملکرد قابل اعتماد عامل مطمئن نشده‌اید، نیاز به نظارت یا تأیید انسانی داشته باشند.

نتیجه‌گیری

عامل‌ها نشان‌دهنده دوره جدیدی در خودکارسازی گردش کارها هستند؛ سیستم‌هایی که می‌توانند با ابهام کنار بیایند، با ابزارهای مختلف کار کنند و وظایف چندمرحله‌ای را با استقلال بالا انجام دهند. برخلاف کاربردهای ساده‌تر LLM، عامل‌ها کل گردش کار را از ابتدا تا انتها اجرا می‌کنند و برای مواردی که شامل تصمیمات پیچیده، داده‌های بدون ساختار، یا سیستم‌های قدیمی و شکننده مبتنی بر قاعده هستند، بسیار مناسبند.

برای ساخت عامل‌های قابل اعتماد، با پایه‌های قوی شروع کنید: مدل‌های توانا، ابزارهای خوب تعریف‌شده، و دستورالعمل‌های روشن و ساختاریافته. از الگوهای هماهنگ‌سازی متناسب با سطح پیچیدگی کارتان استفاده کنید؛ معمولاً بهتر است با یک عامل شروع کنید و تنها در صورت نیاز به سراغ سیستم‌های چندعاملی بروید. محدودیت‌های ایمنی در تمام مراحل، از فیلتر ورودی و استفاده از ابزار گرفته تا امکان مداخله انسانی، حیاتی هستند و به عملکرد ایمن و قابل پیش‌بینی عامل‌ها در محیط واقعی کمک می‌کنند.

مسیر پیاده‌سازی موفق، یک مسیر تدریجی است. کوچک شروع کنید، با کاربران واقعی تست کنید و به مرور قابلیت‌ها را افزایش دهید. با داشتن پایه‌های درست و یک رویکرد تکرارشونده، عامل‌ها می‌توانند ارزش تجاری واقعی ایجاد کنند و نه فقط وظایف، بلکه کل گردش کارها را با هوشمندی و انعطاف‌پذیری خودکار سازند.

اگر در حال بررسی استفاده از عامل‌ها در سازمان خود هستید یا برای اولین پیاده‌سازی آماده می‌شوید، با ما تماس بگیرید. تیم ما آماده ارائه تخصص، راهنمایی و پشتیبانی عملی برای موفقیت شماست.

منابع بیشتر

OpenAI یک شرکت تحقیق و پیاده‌سازی هوش مصنوعی است. مأموریت ما این است که اطمینان حاصل کنیم هوش عمومی مصنوعی (AGI) به نفع تمام بشریت باشد.

برای دانلود فایل اصلی A practical guide to building agents از OpenAI، اینجا کلیک کنید.

این پست تحت مجوز CC BY 4.0 توسط نویسنده منتشر شده است.