CodeGym /Kurslar /ChatGPT Apps /Agent alətləri (Tools): sxemlər, marşrutlaşdırma, səhvlər...

Agent alətləri (Tools): sxemlər, marşrutlaşdırma, səhvlər

ChatGPT Apps
Səviyyə , Dərs
Mövcuddur

1. Agent aləti: əslində nədir

Əvvəlki modullarda siz artıq alətləri Apps SDK tərəfindən — ChatGPT‑nin sizin App vasitəsilə müraciət etdiyi “backend funksiyaları” kimi — görmüsünüz. İndi baxışı dəyişək: alətlərə Agents SDK‑dakı agentin gözü ilə baxaq və onun nəyi çağırmağı necə seçdiyini və səhvlərlə nə etdiyini anlayaq.

Adi backend‑də siz “endpoint”, “kontroller metodu”, “servis funksiyası” kimi kateqoriyalarda düşünməyə öyrəşmisiniz. Agent dünyasında hərəkətlərin əsas vahidi alət (tool) olur. agentin tools‑ları və mcp-tools — fərqli, baxmayaraq ki, kəsişən anlayışlardır.

Dəqiq desək: ChatGPT Agents SDK kontekstində alət — modelin icra etməyi xahiş edə biləcəyi funksiyanın təsviridir. Model özü kodu işə salmır; o, strukturlaşdırılmış sorğu (adətən JSON) yaradır, runtime (sizin kod, MCP‑server və ya Agents SDK) isə bu əməliyyatı icra edib nəticəni qaytarır.

ChatGPT Agents SDK ekosistemində alət konfiqurasiya ilə təsvir olunur: onun name, descriptionparameters (arqumentlərin JSON Schema‑sı) var. Agent bu alətlər dəstini görür, onları öz kontekstində saxlayır və reasoning prosesində hansı tool‑u hansı arqumentlərlə çağıracağına qərar verir.

Agent (və ya host kimi ChatGPT) bu siyahını alır, onu öz kontekstində “yadda saxlayır” və mühakimə (reasoning) prosesində qərar verir: istifadəçi sorğusuna hansı aləti çağırmalı və hansı arqumentlərlə. Məhz buna görə spesifikasiyalarda “tools are a contract” mantrası təkrar olunur — alətlər sizin kodunuzla model arasında kontraktdır, sadəcə “Python/TS‑də funksiya” deyil.

Klassik API ilə analogiya aparmaq olar. /api/gifts/search roudu — bu, sırf sintaksisdir: URL, metod, gövdənin formatı. search_gifts aləti isə semantikadır: “profilə və büdcəyə görə hədiyyə axtarışı”. Alətin təsviri — bu da bir növ prompt‑dur, sadəcə strukturlaşdırılmış və LLM üçün nəzərdə tutulmuş, insan üçün yox.

2. Alətlərin tipləri: LLM‑agent nə ilə məşğul ola bilər

“Hamını bacaran funksiyalar” xaosunda batmamaq üçün alətlərə bir neçə tipik kateqoriya kimi baxmaq faydalıdır. Bu, SDK‑nın formal tipizasiyası deyil, amma sizə çox kömək edəcək arxitektura düşüncə tərzidir.

Backend‑imizdə LLM‑agentlərin adətən üç mənbədən alətləri olur.

  • Yerli biznes alətləri. Bunlar sizin backend‑də yaşayan şeylərdir: DB ilə iş, domen məntiqi (filtrləmə, tövsiyələr, skorlama). Məsələn, GiftGenius üçün bizdə PostgreSQL cədvəlimizdən məhsulları çıxaran və ya “bu hədiyyə bu insana nə dərəcədə uyğun gəlir” şəxsi skorunu hesablayan alətlər ola bilər.
  • MCP‑alətləri. Burada MCP‑server alətlərin (tools) təchizatçısı kimi çıxış edir: o, funksiyaları, resursları və prompt‑ları qeydiyyatdan keçirir və onları müştəriyə (ChatGPT, LLM‑agent) verir. MCP vasitəsilə alətlər xarici API‑ləri çağırmaq, fayllarla işləmək və ya prompt şablonları təqdim etmək üçün istifadə oluna bilər.
  • İnteqrasiya alətləri. Bu, sizi qalan dünya ilə birləşdirən hər şeydir: ACP/commerce (sifarişin yaradılması və checkout), e‑poçt göndərilməsi, webhooks, CRM‑ə yazma. Belə alətlər (tools) çox vaxt daha risklidir, çünki xarici sistemlərin vəziyyətini dəyişirlər; onlara təhlükəsizlik və idemponentlik baxımından xüsusilə ciddi yanaşmaq lazımdır.

Başqa faydalı təsnifat da var — fəaliyyətin xarakterinə görə. LLM‑alətlər üzrə araşdırmalarda adətən belə ayırırlar: məlumat əldə etmə alətləri (axtarış, RAG, get_*), yan təsirli əməliyyat alətləri (create_order, send_email), xalis hesablamalar (calculate_loan) və sistem/idarəetmə (handoff_to_human, finish_task).

Bunu yadda saxlamaq üçün kiçik bir cədvələ baxmaq rahatdır.

Kateqoriya GiftGenius-də nümunə Yan təsir Risk
Data Retrieval
search_gifts, get_details
Yoxdur Aşağı
Action / Mutating
create_order, buy_gift
Bəli Yüksək
Computation
estimate_delivery_cost
Yoxdur Orta
System / Control
finish_recommendation
Yoxdur Məntiqi

Arxitektura baxımından ən vacibi: read‑only alətlər kütləvi və ucuz olmalı, mutasiya edənlər isə nadir, son dərəcə diqqətli, loglarla, idemponentliklə və çox vaxt istifadəçi təsdiqi ilə olmalıdır.

Daha çox məlumat əldə etmə və Action alətlərindən danışacağıq, çünki GiftGenius məntiqi əsasən onların üzərində qurulur.

3. JSON Schema model ilə kodunuz arasında kontrakt kimi

İndi alətin necə təsvir olunduğuna dərinə baxaq. ChatGPT Agents SDK‑da (Apps SDK‑da olduğu kimi) alət parametrlerinin təsviri üçün standart format JSON Schema‑dır: siz object tipini, onun properties sahələrini, sahələrin tiplərini, məcburi sahələri, məhdudiyyətləri və s. təsvir edirsiniz.

Mühüm məqam: JSON Schema burada təkcə və bəlkə də o qədər də validasiya barədə deyil. Bu, model üçün promptun bir hissəsidir. OpenAI‑nin alətlərin (tools) dizaynı üzrə rəsmi təlimatlarında açıq deyilir ki, agentin işi, sahələrin, onların adlarının və şərhlərinin nə qədər detallı və birmənalı təsvir olunmasından güclü asılıdır.

Artıq kurs planlarında görünən GiftGenius üçün bir nümunəyə baxaq.

{
  "name": "search_gifts",
  "description": "Alıcının tipi, maraqları və büdcəsinə görə hədiyyələri tapır.",
  "parameters": {
    "type": "object",
    "properties": {
      "recipient_type": {
        "type": "string",
        "description": "Hədiyyənin alıcısı kimdir (məsələn, 'kişi', 'qadın', 'uşaq')."
      },
      "interests": {
        "type": "array",
        "items": { "type": "string" },
        "description": "Açar maraqlar (idman, kitablar, texnologiyalar və s.)."
      },
      "budget": {
        "type": "number",
        "description": "İstifadəçinin valyutasında maksimum büdcə."
      }
    },
    "required": ["recipient_type", "budget"]
  }
}

Burada bir neçə vacib məqam var.

  • Birincisi, namedescription. Model üçün bu, ümumiyyətlə bu aləti nə vaxt istifadə etmə siqnalıdır. Semantik routing üzrə sənədlər vurğulayır ki, alətin təsviri faktiki olaraq model üçün API‑dir: onu func1 adlandırıb “nəsə faydalı edir” kimi imzalasanız, model onu nə vaxt çağıracağını anlamaya bilər. search_gifts adını qoyub, anlaşılan təsvir əlavə etsəniz, seçim daha aydın olur.
  • İkincisi, parameters. Sahələrin adları və onların təsvirləri son dərəcə vacibdir. LLM üçün recipient_type type‑dan xeyli anlaşıqlıdır. “Hədiyyənin alıcısı kimdir…” kimi yaxşı description modelə buraya məhz alıcının tipinin qoyulmalı olduğunu, məsələn, qablaşdırma formatının yox, aydın göstərir.
  • Üçüncüsü, required. Bu, təkcə sizin tərəfdə validasiya deyil, həm də model üçün ipucudur: o, məcburi sahələri doldurmağa çalışacaq, aydın olmayan konteksdə isə qeyri‑məcburi sahələri ötürəcək. Bu, “boş” və ya yanlış tool çağırışlarının sayını azaldır.

Apps SDK üzrə rəsmi təlimatlar açıq tövsiyə edir: alətləri dar, bir məsuliyyətli, aydın adlarla və təsvirlərlə edin və müxtəlif tapşırıqları birləşdirən “hədiyyələrlə bağlı hər şeyi et” tipli alətlərdən qaçın.

4. GiftGenius alətlərini dizayn edirik: sxemdən koda

GiftGenius‑umuzu götürək və demək olar bütün ssenarilərdə lazım olacaq iki əsas LLM‑agent aləti əlavə edək:

  • suggest_gifts(profile, budget) — namizədlər siyahısını verir;
  • get_gift_details(gift_id) — konkret hədiyyə üzrə detalları açır.

suggest_giftsget_gift_details — əvvəlki təsnifatda yerli biznes alətlərinin tipik nümunələridir, əsasən Data Retrieval kateqoriyasından.

suggest_gifts üçün sxem

Əvvəlcə təmiz JSON Schema ilə başlayaq, sonra bunun backend/agent runtime üçün TypeScript kodunda necə görünə biləcəyini göstərək.

{
  "name": "suggest_gifts",
  "description": "Alıcı profilinə və büdcəyə əsasən hədiyyə siyahısını seçir.",
  "parameters": {
    "type": "object",
    "properties": {
      "age": {
        "type": "integer",
        "minimum": 0,
        "maximum": 120,
        "description": "Alıcının yaşı (il ilə)."
      },
      "relationship": {
        "type": "string",
        "enum": ["friend", "coworker", "partner", "family"],
        "description": "Alıcı ilə münasibət: dost, həmkar, partnyor, ailə."
      },
      "interests": {
        "type": "array",
        "items": { "type": "string" },
        "description": "Alıcının maraqları (idman, kitablar, texnologiyalar və s.)."
      },
      "budget": {
        "type": "number",
        "minimum": 1,
        "description": "İstifadəçinin valyutasında maksimum büdcə."
      }
    },
    "required": ["budget"]
  }
}

Burada relationship üçün enum istifadə edirik ki, model "pis həmkar" kimi özbaşına sətirlər “uydurmasın” və onları koda ötürməsin. Belə səliqəli sxem dizaynı həm modelə (icazə verilən variantları görür), həm də developera (runtime‑da daha az sürpriz) kömək edir.

Tutaq ki, bizdə Node.js üzərində hansısa şərti McpServer ilə MCP‑server var. Alətin qeydiyyatı belə görünə bilər:

// MCP-server-də alətin qeydiyyatının sadələşdirilmiş nümunəsi
server.registerTool(
  {
    name: "suggest_gifts",
    description: "Profilə və büdcəyə görə hədiyyələr seçir.",
    inputSchema: suggestGiftsSchema
  },
  async (input, ctx) => {
    const gifts = await findGiftsInDb(input, ctx.userLocale);
    return { items: gifts }; // sonradan agentin görəcəyi JSON
  }
);

Kod xeyli sadələşdirilib, amma məntiq aydındır: bir yerdə — kontraktın təsviri (ad, təsvir, sxem), başqa yerdə — reallaşdırma.

get_gift_details üçün sxem

Demək olar hər bir vitrində lazım olan ikinci alət:

{
  "name": "get_gift_details",
  "description": "Hədiyyə haqqında tam məlumatı onun identifikatoruna görə alır.",
  "parameters": {
    "type": "object",
    "properties": {
      "gift_id": {
        "type": "string",
        "description": "GiftGenius bazasında hədiyyənin UUID-si."
      }
    },
    "required": ["gift_id"]
  }
}

Və oxşar qeydiyyat:

server.registerTool(
  {
    name: "get_gift_details",
    description: "Hədiyyə haqqında ətraflı məlumat qaytarır.",
    inputSchema: getGiftDetailsSchema
  },
  async ({ gift_id }) => {
    const gift = await db.gifts.findById(gift_id);
    if (!gift) return { notFound: true };
    return { gift };
  }
);

Diqqət edin: burada alətin notFound: true qaytara biləcəyini dərhal göstəririk. Bu, aşağıda danışacağımız semantik səhvlərin (biznes səhvlərinin) başlanğıcıdır. Agent “hədiyyə tapılmadı”nı görüb qərar verə bilər: məsələn, başqa id sınamaq və ya istifadəçiyə başqa məhsul seçməyi təklif etmək.

5. Agent hansı aləti çağıracağını necə seçir

İndi ən maraqlısı: marşrutlaşdırma. Ənənəvi veb‑tətbiqdə routinq sərtdir: URL → konkret kontroller. ChatGPT Apps və agentlər dünyasında alət seçimi semantik və ehtimallıdır.

Yüksək səviyyəli dövrəni belə təsvir etmək olar:

flowchart TD
  U[İstifadəçi mesajı] --> M["Model (agent)"]
  M -->|sorğunun təhlili| C{Alət lazımdır?}
  C -->|yox| T[Mətn cavabı]
  C -->|bəli| S[Alətin seçimi]
  S --> K[JSON arqumentlərinin formalaşdırılması]
  K --> R[Alətin icrası]
  R --> M2[Model nəticəni görür]
  M2 --> T2[Yekun cavab və ya növbəti addım]

Hər addımda agent bir neçə şeyi görür:

  • Birincisi, system təlimatları (agentin rolu, məhdudiyyətlər);
  • İkincisi, dialoq tarixini;
  • Və nəhayət, alətlərin (tools) siyahısını onların name, description, inputSchema ilə.

Növbəti istifadəçi mesajı gələndə model sorğunun mənasını alətlərin təsvirləri ilə (semantik uyğunlaşdırma) müqayisə edir. Əgər sorğu “dosta 50 dollara qədər hədiyyə seç” kimidirsə, suggest_gifts təsviri get_gift_details‑dən xeyli uyğun səslənəcək və agent böyük ehtimalla məhz onu seçəcək.

Rəsmi təlimatlar marşrutlaşdırmanın keyfiyyətinə güclü təsir edən iki şeyi vurğulayır.

  • Birincisi, mənaca kəsişən alətlərdən qaçmaq lazımdır: əgər sizdə eyni cür təsvir olunmuş search_giftsfind_gifts varsa, model çaşacaq.
  • İkincisi, alət üçün bir məsuliyyət prinsipinə riayət etmək lazımdır: bir tool — bir aydın tapşırıq, “hədiyyələri seç və sifariş yarat və məktub göndər” deyil.

Müxtəlif LLM‑agentlərdə alət seçimi rejiminə nəzarət mexanizmləri var: məsələn, “auto” (model özü qərar verir, alət lazımdırmı), “required” (mütləq alət çağırılmalıdır), “none” (alətlər söndürülüb). Bu, mürəkkəb workflow‑larda (çoxaddımlı ssenarilərdə) kömək edir; məsələn, müəyyən addımda siz suggest_gifts çağırılmasını məcburi etmək, modelə isə sadəcə “danışmağa” icazə verməmək istəyirsiniz.

GiftGenius‑də semantik marşrutlaşdırma nümunəsi

Agentimizin ən azı iki aləti var: suggest_giftsget_gift_details.

  1. İstifadəçi yazır: “30 dollara qədər həmkar üçün hədiyyə seç, o stolüstü oyunları sevir”.
  2. Agent görür ki, sorğuda “hədiyyə seçmək” məqsədi, büdcə və maraqlar barədə məlumat var. suggest_gifts təsviri mükəmməl uyğun gəlir — bu aləti çağırırıq.
  3. Alət beş hədiyyədən ibarət siyahı qaytarır: id, ad və qısa təsvirlərlə.
  4. İstifadəçi sonra yazır: “Üçüncü variant haqqında daha ətraflı danış”. Agent “üçüncü variant”ı əvvəlki nəticədəki id ilə uyğunlaşdırır və indi mənaca get_gift_details aləti uyğundur — o çağırılır.

Vacib məqam: heç yerdə koddə açıq‑aşkar “sorğuda “seç” sözü varsa, suggest_gifts çağır” deməmisiniz. Bunu sizin təsvirləriniz və dialoq tarixi əsasında model özü edir. Developer kimi sizin məsuliyyətiniz — seçimi həm model, həm də insan üçün aydın etməkdir.

6. Alət səhvləri: 500 yox, model üçün siqnal

Yadınızdadırsa, get_gift_details‑də artıq notFound: true göstərmişdik? Bu, agentin “çılpaq” 500 almaqdansa görməli və mənalı emal etməli olduğu biznes səhvinə nümunədir.

İndi ən ağrılı yerə keçək. Adi REST‑API‑də backendin dərinliklərində nəsə çökür — 500 Internal Server Error qaytarılır, stack trace loga yazılır — sonra istifadəçi birtəhər idarə edər. Agent halında belə yanaşma zəif işləyir.

Agents SDK üzrə praktik təlimatlar alət səhvlərinə müşahidə olunan hadisələr kimi, təkcə “yıxılma” kimi yox, yanaşmağı tövsiyə edir. Bunu tez‑tez “Error as Observation” patterni adlandırırlar.

Bircə sözlə, izahsız “dağılmamalı”, əksinə modelə nə baş verdiyini izah edən strukturlaşdırılmış cavab qaytarmalısınız ki, o, davranışını uyğunlaşdıra bilsin: sorğunu yenidən formalaşdırmaq, istifadəçidən soruşmaq, başqa aləti sınamaq və s.

Səhv tiplərini adətən üç qrupa bölürlər.

  • Arqumentlərin validasiya səhvləri. Model yalnış parametrlər yarada bilər: məcburi sahəni ötürmək, ədəd əvəzinə sətir göndərmək, icazəli dəyərləri aşmaq. Burada sxeminizi və validasiyanı təkcə istisna atmaq üçün deyil, mənalı cavab üçün də istifadə edin: məsələn, hansı sahənin yanlış olduğunu və niyəsini qaytarın.
  • Biznes səhvləri. “Məhsul tapılmadı”, “region əlçatan deyil”, “bu tip hədiyyələr üçün büdcə çox kiçikdir” kimi tam gözlənilən situasiyalar. API baxımından bunlar da səhvdir, amma onları normal cavab daxilində — aydın kod və mesajla, crash kimi yox — qaytarmaq lazımdır.
  • Sistem səhvləri. Xarici xidmət taymoutları, şəbəkə problemləri, DB nasazlıqları. Burada agentə adətən ehtiyatlı, ümumiləşdirilmiş bir mesaj kifayətdir: “xidmət müvəqqəti əlçatmazdır, sonra yenidən cəhd et”. Heç bir stack trace, cədvəl adları və təhlükəsizlik baxımından lazım olmayan digər detallara ehtiyac yoxdur.

Agents SDK üzrə rəsmi materiallar hətta failure_error_function kimi xüsusi mexanizm təklif edir ki, istisnanı sadəcə yuxarı atmaq əvəzinə, modelin görəcəyi səhv mətnini səliqəli formalaşdırasınız.

“Dost” səhvinin strukturu

Agent alətində (backendinizdə) razılaşa bilərsiniz ki, istənilən səhv məsələn belə obyekt kimi qaytarılsın:

type ToolError = {
  code: string;      // 'VALIDATION_ERROR', 'OUT_OF_STOCK', ...
  message: string;   // model üçün
  retryable: boolean;
};

Və alətin nəticəsi belə bir birləşmə kimi:

type SuggestGiftsResult =
  | {
      ok: true;
      items: GiftSummary[];
    }
  | {
      ok: false;
      error: ToolError;
    };

Model (və ya agent runtime) bu cür JSON görüb qərar verə bilər: əgər retryable: true‑dirsə, kiçik dəyişikliklərlə yenidən cəhd etmək olar; əgər səhv biznes səviyyəsindədirsə və retry edilə bilmirsə, istifadəçiyə qayıdıb nəyin səhv olduğunu izah etmək daha yaxşıdır.

7. Nümunələr: validasiya, biznes səhvi və sistem səhvi

Backend/agent alətlərimizə qayıdaq və eyni ideyaları kodda necə gerçəkləşdirə biləcəyimizə baxaq.

Validasiya səhvi

Tutaq ki, suggest_gifts alətinə gəlib, amma model nədənsə mənfi büdcə göndərib.

async function handleSuggestGifts(input: SuggestGiftsInput)
  : Promise<SuggestGiftsResult> {

  if (input.budget <= 0) {
    return {
      ok: false,
      error: {
        code: "VALIDATION_ERROR",
        message: "budget müsbət ədəd olmalıdır.",
        retryable: false
      }
    };
  }

  const items = await findGiftsInDb(input);
  return { ok: true, items };
}

Burada istisna atmaq əvəzinə, şüurlu şəkildə strukturlaşdırılmış səhv qaytarırıq. Agent sorğunu yenidən düşünə bilər: bəlkə valyutanı səhv saldığını anlayar və istifadəçidən soruşar və ya sadəcə bu büdcə ilə hədiyyə seçə bilmədiyini etiraf edər.

Biznes səhvi

İndi get_gift_details nümunəsi. Göstərilən id ilə hədiyyə sadəcə mövcud olmaya bilər.

async function handleGetGiftDetails(input: { gift_id: string }) {
  const gift = await db.gifts.findById(input.gift_id);

  if (!gift) {
    return {
      ok: false,
      error: {
        code: "GIFT_NOT_FOUND",
        message: "Bu identifikatorla hədiyyə tapılmadı.",
        retryable: false
      }
    };
  }

  return { ok: true, gift };
}

Modelin cavabında belə bir şey gözləmək olar: “Görünür, seçilən hədiyyə artıq əlçatan deyil. Oxşar kateqoriyadan bir neçə alternativ təklif edim?”. Bunun üçün agentin SQL səhvləri və stack trace görməsinə ehtiyac yoxdur — yalnız anlaşılan codemessage.

Sistem səhvi

Nəhayət, sistem səhvi nümunəsi. Tutaq ki, alətiniz bəzən “çökmə” ehtimalı olan xarici çatdırılma API‑sinə müraciət edir.

async function handleEstimateDelivery(input: EstimateDeliveryInput) {
  try {
    const eta = await callDeliveryApi(input);
    return { ok: true, eta_days: eta };
  } catch (e) {
    return {
      ok: false,
      error: {
        code: "DELIVERY_SERVICE_UNAVAILABLE",
        message: "Çatdırılma xidməti müvəqqəti əlçatmazdır.",
        retryable: true
      }
    };
  }
}

Agent belə qərar verə bilər: “Görünür, çatdırılma xidməti indi əlçatan deyil. Mən yenə də hədiyyələri göstərəcəyəm, amma dəqiq çatdırılma müddəti fərqli ola bilər. Davam etmək istəyirsiniz?”.

8. Alətlərin təhlükəsizliyi və idemponentliyi (tools baxışından qısa baxış)

Təhlükəsizlik və icazələr (permissions) haqqında tam söhbət ayrıca mövzuda olacaq, amma agent alətləri bununla o qədər sıx bağlıdır ki, tamamilə toxunmamaq olmaz.

Birincisi, oxu alətlərini və yazma (mutasiya) alətlərini ayırmaq lazımdır. Təsvirlərdə, sxemlərdə və icazələrdə hansı tools‑ların yalnız məlumat oxuduğunu və tam təhlükəsiz olduğunu, hansının isə pul çıxardığını, sifarişləri dəyişdirdiyini və s. açıq şəkildə göstərin. Agent ssenariləri üzrə sənədlər və forumlar ReadOnly və Mutating alətlərin (tools) ayrılmasından açıq danışır.

İkincisi, mutasiya edən alətlər üçün idemponentlik haqqında düşünmək lazımdır. Agent və ya MCP‑klient çağırışı təkrarlaya bilər (məsələn, şəbəkə səhvi səbəbindən) və siz create_order‑in bir əvəzinə iki sifariş yaratmasını istəmirsiniz. Buradakı tipik patternlər:

  • alət arqumenti kimi ötürülən idempotency‑key;
  • icradan əvvəl əməliyyatın mövcudluğunun yoxlanması;
  • addımların “sifariş qaralamasını yarat” və “sifarişi təsdiqlə” kimi bölünməsi.

Bunların hamısı alət kontraktını necə dizayn etdiyinizlə sıx bağlıdır: JSON Schema‑da idempotency‑key üçün sahə yoxdursa, idemponentliyi sonra əlavə etmək xeyli ağrılı olacaq.

9. Agents SDK‑ya kiçik baxış: agent runtime‑ında bu necə görünür

Bu bölmə TypeScript‑yönümlü Agents SDK ilə işləyəcək olanlar üçün kiçik icmaldır. Kursun əsas hissəsi MCP haqqındadır, amma Agents SDK alətləri necə gördüyünü və tipik tool‑un runtime‑da necə göründüyünü bilmək faydalıdır.

Rəsmi sənədlərdə adətən “funksional alət” kimi bir obyekt təsvir olunur: konfiqurasiya obyekti (və ya tool(...) kimi helper) vasitəsilə təsvir olunmuş və tiplərlə təmin edilmiş istənilən funksiya avtomatik olaraq alətə çevrilə bilər; SDK onun üçün JSON Schema və təsvir generasiya edəcək.

Konsptual səviyyədə bu, artıq müzakirə etdiyimizlə eynidir: funksiya adı, onun parametrləri və şərh/description alətin adı, sxemi və təsviri rolunu oynayır. Fərq ondadır ki, sizin yerinizə “mexaniki” işin böyük hissəsini SDK və/və ya sxemlər üçün yardımçı kitabxana (məsələn, Zod və ya JSON Schema) görür.

Şərti nümunə (psevdo‑TypeScript, sadələşdirilmiş):

type Gift = {
  id: string;
  title: string;
  // ...
};

const suggestGifts = tool({
  name: "suggest_gifts",
  description: "Alıcı tipinə və büdcəyə görə hədiyyə siyahısını seçir.",
  parameters: {
    type: "object",
    properties: {
      recipient_type: {
        type: "string",
        description: "Hədiyyənin alıcısı kimdir (məsələn, 'kişi', 'qadın', 'uşaq')."
      },
      budget: {
        type: "number",
        description: "İstifadəçinin valyutasında maksimum büdcə."
      }
    },
    required: ["recipient_type", "budget"]
  }
}, async (args: { recipient_type: string; budget: number }): Promise<Gift[]> => {
  // Daxildə — sizin domen məntiqiniz
  return findGifts(args.recipient_type, args.budget);
});

SDK (və ya sizin tool helperiniz) parameters obyektinə əsasən JSON Schema quracaq və onu agentə ötürəcək, runtime isə arqumentlərin validasiyası və marşallaşdırılması ilə məşğul olacaq. Konseptual olaraq bu, TypeScript‑də MCP‑serverində əl ilə etdiyinizlə eynidir, sadəcə indi alət birbaşa agent runtime‑ına “qoşulub”.

Burada əsas məqsəd konkret tool helperinin sintaksisini əzbərləmək deyil, fikri tutmaqdır: keyfiyyətli tipləndirmə + anlaşılan description/şərhlər = keyfiyyətli alət.

Bunların hamısını birləşdirəndə: yaxşı agent aləti — bu, dar, aydın təsvir olunmuş funksiya, düşünülmüş JSON Schema, model üçün anlaşılan təsvir və səliqəli səhv emalıdır. Semantik marşrutlaşdırma yalnız alətlər mənaca kəsişmirsə işləyəcək. Mutasiya edən əməliyyatlar isə təhlükəsiz və idemponent olmalıdır, əks halda prod‑da agent sürətlə “sürpriz” mənbəyinə çevriləcək.

10. Agent alətlərini dizayn edərkən tipik səhvlər

Səhv №1: Həddən artıq geniş “do_everything” alətləri.
Bəzən hər şeyi bir alətə — manage_gifts — yığmaq istəyirsiniz: həm hədiyyələri axtarır, həm detallarını göstərir, həm sifariş yaradır, həm də məktub göndərir. Bundan sonra model üçün çətindir: təsvir yayğın olur, semantik routing pisləşir və agent bu aləti “birdən lazım olar” deyə, sadə axtarışın gərək olduğu yerdə belə çağırmağa başlayır. Tapşırıqları bir məsuliyyəti olan ayrıca alətlərə bölmək daha yaxşıdır.

Səhv №2: Mənaca üst‑üstə düşən alətlər.
Əgər sizdə search_giftsfind_gifts var və hər ikisi “maraqlara görə hədiyyə axtarır”sa, model onların arasında təsadüfi seçim edəcək. Nəticədə davranış qeyri‑stabil olur: eyni sorğular bəzən bir tool‑a, bəzən o birinə gedir. Hər adın və təsvirin mənaca unikal “nişa” tutmasına çalışın.

Səhv №3: Zəif və ya olmayan təsvirlər və sxem sahələri.
func1 adı, “Does something” təsviri və data: string parametri — agenti “axmaqlaşdırmağın” klassik yoludur. Model telepat deyil və sizin mənbə kodunuzu oxuya bilmir. O, sxemdəki description, properties və onların descriptionlarına arxalanır. recipient_type nədir, izah etməsəniz, model təxmin edəcək və səhv edəcək.

Səhv №4: Yalnız happy‑path‑a fokuslanmaq, səhvləri görməməzliyə vurmaq.
Bir çox alət reallaşdırması belə güman edir: “Axı bizdə həmişə korrekt arqumentlər və əlçatan xidmət olacaq”. Real dünyada model asanlıqla yanlış parametrlər generasiya edir, xarici xidmətlər düşür, DB isə bəzən “timeout” deyir. Səhv formatlarını düşünməsəniz və agentə mənalı mesaj qaytarmasanız, o, davranışını düzəldə bilməyəcək və ya sakitcə çökəcək, ya da halyusinasiyaya başlayacaq.

Səhv №5: Xam 500 və stack trace‑i LLM‑ə atmaq.
REST‑API‑də biz tam stack trace‑i loglamağa öyrəşmişik ki, tez ayıklayaq. Agent kontekstində modelə ötürülən stack trace eyni anda həm faydasızdır (model sizin konkret kitabxananızdakı SQLException‑in nə olduğunu bilmir), həm də potensial təhlükəlidir (reallaşdırma detalları və bəlkə də məxfi məlumat). İstisnanı tutmaq, detallarını loga yazmaq və modelə səliqəli codemessage göndərmək xeyli faydalıdır.

Səhv №6: Mutasiya edən alətlərdə idemponentliyin olmaması.
Idempotency‑key olmayan create_order — xüsusən şəbəkə nasazlıqları və avtomatik retry şəraitində — ikiqat sifarişlərə birbaşa dəvətnamədir. Agentiniz kommersiya ssenarisində işləyirsə, pulla bağlı alətlər təkrar çağırışların əlavə tutulmalara və ya dublikatlara gətirməməsi üçün elə dizayn edilməlidir.

Səhv №7: Sxemdə və ya təsvirlərdə sirlər və texniki detalları saxlamaq.
Bəzən developer adət üzrə description‑da yazır: “Daxildə https://internal-api.example.com ünvanındakı X xidmətini çağırır”. Bu məlumat model üçün lazım deyil, istifadəçi üçün isə heç deyil. Sxemlər və təsvirlər — promptun bir hissəsidir, onlar model kontekstində yaşayır və ora daxili xidmət URL‑ləri, şəxsi cədvəl adları və xüsusilə sirləri qoymaq olmaz.

Səhv №8: Alətlərə hər şeyi ötürmək, düşünülmüş sahə dəsti əvəzinə.
“Asan olsun” deyə “istifadəçi promptunu tam sətir kimi ötürək, içəridə baxarıq” fikrinə aldanmaq asandır. Belə etsəniz, JSON Schema vasitəsilə strukturlaşdırmanın faydasını itirirsiniz: model artıq sorğunun hansı hissələrinin məntiq üçün vacib olduğunu anlamır, siz isə validasiya və prediktivliyi itirirsiniz. Sorğudan açıq sahələri (budget, interests, user_location) çıxarıb onları alət kontraktının bir hissəsi kimi təsvir etmək daha yaxşıdır.

Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION