CodeGym /Kurslar /ChatGPT Apps /Agentin yaddaşı və vəziyyəti: session vs persistent, chec...

Agentin yaddaşı və vəziyyəti: session vs persistent, checkpoints

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

1. Agentə niyə ümumiyyətlə ayrıca yaddaş lazımdır

Bu hissə 12‑ci modulun agentlər barədə əvvəlki dərslərinə söykənir: orada artıq baza arxitekturasını, run‑dövrünü və alətləri müzakirə etmişdik; burada fokus yaddaş və vəziyyətdədir.

Veb tətbiqləri ilə analogiyanı davam etdirsək, LLM burada mürəkkəb «mətn proqramlarını» icra edə bilən çox ağıllı CPU kimidir. Agentin vəziyyəti isə RAM və SSD kombinasiyasıdır: sessiyanın qısamüddətli məlumatları və uzunmüddətli anbar.

Klassik ChatGPT çatında, sizin kodunuz olmadan, «yaddaş» modelin cari sorğuda gördüyü system/user/assistant/tool mesajlar siyahısından ibarətdir. Agent üçün bu kifayət deyil, çünki:

  • mürəkkəb proseslərin gedişatını xatırlamalıdır: workflow‑un hansı addımı keçilib, hansı hədiyyə variantları artıq süzülüb, istifadəçi nəyi təsdiqləyib;
  • istifadəçi haqqında uzunmüddətli faktları bilməlidir: üstünlüklər, çatdırılma ünvanı, əvvəlki sifarişlərin tarixi;
  • sistem nasazlıqlarına davamlı olmalıdır: server hədiyyə seçimi ortasında çökərsə, istifadəçi hər şeyi yenidən yazmamalıdır.

Bunların hamısını yalnız prompt‑kontekstdə saxlamağa çalışsanız, tez bir zamanda kontekst pəncərəsinin limitinə dirənəcək və eyni faktlar üçün token xərci ödəyəcəksiniz. Paralel olaraq təhlükəsizliyi riskə atırsınız: çoxlu lazımsız məlumatlar mütəmadi olaraq modelə gedir. Ona görə də agent sistemlərində həmişə açıq vəziyyət olur — mesajlar tarixindən kənarda yaşayan və sizin tərəfinizdən idarə olunan obyekt(lər).

2. Agentin vəziyyət qatları: kontekst, session, persistent

Qatlara bölməklə başlayaq. Agentin adətən minimum üç səviyyəli «yaddaşı» var:

  1. Mesajlar tarixi (dialogue context).
  2. Sessiya vəziyyəti (session state).
  3. Uzunömürlü vəziyyət (persistent state).

Bu anlayışları bir yerə qatmayın.

Mesajlar tarixi: «çirkli yaddaş»

Mesajlar tarixi — LLM‑in hər addımda gördüyüdür: system təlimatları, istifadəçi sorğuları, agent cavabları, alətlərin nəticələri.

Üstünlüyü ondadır ki, bunu əllə aparmalı deyilsiniz — Agents SDK və platformanın özü bunu Session/Conversation obyektləri vasitəsilə üzərinə götürür.

Çatışmazlığı — «çirkli» yaddaşdır: orada çoxlu artıq söz, təkrar və təsadüfi istifadəçi məlumatları var. Bu məlumatlar token baxımından bahalıdır və zəif strukturludur. Artıq süzülmüş 200 hədiyyə elementinin siyahısının hər dəfə modelə plain‑text kimi oxudulmasını istəmirsiniz.

Session state: işçi qısamüddətli yaddaş

Session vəziyyəti agentin bir sessiyası/söhbəti çərçivəsində yaşayan strukturlu obyektdir. Frontend inkişafçıları üçün yaxşı analogiya — tab açıq olduğu müddətdə yaşayan useState və ya Redux‑store.

Orada belə şeylər yaşayır:

  • prosesin cari addımı (məsələn, "collecting_profile" və ya "filtering_candidates");
  • alətlərin nəticələrinin müvəqqəti keşləri;
  • sessiya parametrləri: lokal, seçilmiş kanal, «istifadəçi şərtləri təsdiqlədi» kimi bayraqlar.

Bu vəziyyət agentin yanında — Redis‑də, in‑memory KV anbarında və ya konkret SDK‑nın daxili SessionService vasitəsilə saxlanıla bilər. Əsas — bunların hamısını system‑prompt‑a soxmağa çalışmamaqdır.

Persistent state: uzunmüddətli məlumatlar

Persistent vəziyyət uzun yaşayır: sessiyalar, checkout‑lar, cihazlar arasında. Bu istifadəçi profili, onun sifarişləri, saxlanmış istək‑siyahıları, tənzimləmələrdir.

Açar fikir: agent persistent məlumatları sehrlə «xatırlamır», onları alətlər vasitəsilə «oxuyur» — məsələn, get_user_profile, get_past_orders. Agent daxilində heç bir gizli qlobal dəyişən yoxdur; həmişə açıq çağırış.

Müqayisəli cədvəl

Qat Harada yaşayır Həyat dövrü Məlumat nümunələri
Messages Session / SDK / OpenAI Bir run / dialoq system/user/tool mesajları
Session state KV / SessionService / Redis Sessiya yaşadığı müddətcə workflow addımı, müvəqqəti keşlər
Persistent DB (Postgres/NoSQL/ACP backend) Sessiyalar və dialoqlar arasında profil, sifarişlər, saxlanmış siyahılar

3. Session state: nədir və necə saxlamaq olar

Təsəvvür edin ki, GiftGenius agenti çoxaddımlı bir prosesi aparır:

  1. Hədiyyəni alacaq şəxs üzrə profil toplayır.
  2. Namizəd siyahısı yaradır.
  3. Onları büdcə, çatdırılma, region üzrə süzür.
  4. Son seçim toplusunu hazırlayır.

Proses zamanı o, istifadəçi ilə daim ünsiyyətdədir və alətləri çağırır. «Məhz bu hədiyyə seçimi sessiyasının gedişatı» ilə bağlı olan hər şey məntiqli olaraq session‑state‑də saxlanılmalıdır.

GiftGenius üçün sessiya vəziyyəti strukturunun nümunəsi

TypeScript‑də sessiya vəziyyəti tipini təsvir edək:

// Bir "hədiyyə seçimi" çərçivəsində vəziyyət
export type GiftSessionState = {
  step:
    | "collecting_profile"
    | "generating_candidates"
    | "filtering"
    | "finalizing";

  // alıcının profilinin qaralaması
  profileDraft?: {
    recipientType?: string;
    ageRange?: string;
    interests?: string[];
    dislikes?: string[];
  };

  // backend-dən alınmış namizəd məhsulların id-ləri
  candidateIds?: string[];

  // istifadəçinin seçdiyi hədiyyə
  selectedGiftId?: string;

  // texniki bayraqlar
  locale?: string;
};

Burada biz qəsdən məhsulların bütöv obyektlərini yox, yalnız onların ID‑lərini qoyuruq. Tam məlumatlar DB‑də yaşasın; lazım olduqda agent get_gift_details(gift_id) alətini çağırır.

Agents SDK‑də Session (konseptual olaraq)

Bir çox agent SDK‑sında sessiya abstraksiyası var; o, mesajlar tarixinin saxlanmasını özü üzərinə götürür və əlavə olaraq structured‑state saxlamağa imkan verir. Psevdo‑kodda bu təxminən belə görünə bilər:

import { createRunner, OpenAIConversationsSession } from "@openai/agents";
// tip GiftSessionState yuxarıdakı nümunədən

const session = new OpenAIConversationsSession<GiftSessionState>({
  sessionId: "chatgpt-thread-id-or-random",
});

const runner = createRunner({ agent });

const result = await runner.run({
  session,
  input: "50$-dək həmkar üçün hədiyyə istəyirəm",
});

SDK pərdə arxasında:

  • bu sessiya üçün mesajlar tarixini çıxaracaq;
  • yeni istifadəçi mesajını əlavə edəcək;
  • modelə və alətlərə ötürəcək;
  • yenilənmiş vəziyyəti (o cümlədən session.state) geri saxlayacaq.

Siz isə session.state ilə adi obyekt kimi işləyirsiniz.

Session‑state‑in alətlərdən yenilənməsi

Tipik nümunə: nəyisə hesablayan alət eyni zamanda sessiya vəziyyətini yeniləyir. Məsələn, istifadəçi cavablarından alıcı profilini toplayan alət:

export async function updateProfileDraft(
  session: GiftSessionState,
  answers: { questionId: string; value: string }
): Promise<GiftSessionState> {
  const next: GiftSessionState = { ...session };

  if (!next.profileDraft) {
    next.profileDraft = {};
  }

  if (answers.questionId === "interests") {
    next.profileDraft.interests = answers.value.split(",").map((s) => s.trim());
  }

  // ...digər sahələr

  next.step = "generating_candidates";
  return next;
}

Burada alətə SDK‑dakı bütün Session‑u deyil, yalnız onun state‑ini (tipi GiftSessionState) veririk. Real kodda belə arqumenti currentState adlandırmaq məntiqlidir ki, Session obyektindən qarışdırılmasın.

Agent bu aləti çağırır, yeni vəziyyət obyektini alır və onu geri session.state‑ə yazır.

4. Persistent state: agentin uzunmüddətli yaddaşı

İndi xatırlayaq ki, GiftGenius təkcə bir çatda işləmir. İstifadəçi bir həftə sonra başqa cihazdan qayıdıb belə deyə bilər: «Keçən dəfəki eyni dost üçün hədiyyə seç, amma büdcə artırılıb».

Bu məlumat session‑state‑də deyil, persistent anbarında yaşamalıdır: DB‑də, commerce‑/ACP‑backend‑də (commerce qatını ayrıca modulda müzakirə edəcəyik) və s.

Persistent model nümunəsi

DB‑də alıcı profilinin modelini təsvir edək (sadələşdirilmiş, TypeScript tipi kimi):

// DB-də saxlanılan
export type RecipientProfile = {
  id: string;
  userId: string;
  label: string; // "marketinqdən həmkar"
  recipientType: string;
  ageRange?: string;
  interests: string[];
  dislikes: string[];
  lastUsedAt: string; // ISO tarixi
};

Və repozitoriy (hələlik sadə Map olsun — realda ORM/SQL qatını edərdiniz):

const profiles = new Map<string, RecipientProfile>();

export const RecipientRepo = {
  async findByUser(userId: string): Promise<RecipientProfile[]> {
    return [...profiles.values()].filter((p) => p.userId === userId);
  },

  async save(profile: RecipientProfile): Promise<void> {
    profiles.set(profile.id, profile);
  },
};

Agent persistent‑ə alətlər vasitəsilə müraciət edir

Vacibdir ki, agent birbaşa DB‑yə yox, tools vasitəsilə çıxsın. Beləliklə, o «təmiz» bir varlıq kimi qalır: bir yerdə — LLM və planlaşdırma məntiqi, başqa yerdə — inteqrasiya realizasiyaları.

Məsələn, get_recipient_profiles aləti:

export async function getRecipientProfilesTool(input: {
  userId: string;
}): Promise<{ profiles: RecipientProfile[] }> {
  const profiles = await RecipientRepo.findByUser(input.userId);

  return {
    profiles,
  };
}

Agent alətin təsvirində oxuyur: «cari istifadəçi üçün saxlanmış alıcı profillərini almaq üçün bu tool‑dan istifadə et». Onu nə vaxt çağıracağını özü qərar verir.

Nəticə: session‑state konkret söhbətin gedişi və ağrısız itirilə bilən müvəqqəti keşlər haqqındadır. Persistent məlumatlar isə sessiyaları və cihazları aşmalıdır: profillər, sifarişlər, istək‑siyahıları. Agent onları həmişə alətlər vasitəsilə oxuyur, «sehrlə xatırlamır».

5. Session və persistent run‑dövründə birlikdə necə işləyir

İndi hər şeyi ümumi sxemdə toplayaq. Agentin run‑dövrünün hər addımında qısa ardıcıllıq var:

  1. sessionId üzrə session‑state‑i çıxarırıq.
  2. Lazım gələrsə, DB‑dən uyğun persistent məlumatları alətlərlə yükləyirik.
  3. Model üçün konteksti formalaşdırırıq (messages + strukturlu vəziyyət).
  4. Model qərar verir: mətnlə cavab verir, yoxsa alətləri çağırır.
  5. Alətlər ya session‑state‑i, ya da persistent məlumatları (DB vasitəsilə) yeniləyir.
  6. Yeni session vəziyyətini saxlayırıq və lazım gələrsə, checkpoint yaradırıq (buna aşağıda baxacağıq).
  7. İstifadəçiyə cavabı qaytarırıq.

Sxem mermaid‑də:

flowchart TD
    A[İstifadəçi daxilini al] --> B["Session-i yüklə (state + messages)"]
    B --> C{Persistent məlumatlara ehtiyac var?}
    C -- Bəli --> D[Alətləri çağır: get_user_profile, get_recipient_profiles]
    C -- Xeyr --> E[LLM üçün konteksti formalaşdır]
    D --> E
    E --> F["Modeli (LLM) çağır"]
    F --> G{Model tool çağırmaq istəyir?}
    G -- Bəli --> H[Tool-u icra et, session/persistent-i yenilə]
    G -- Xeyr --> I[Yekun cavabı hazırla]
    H --> J[Checkpoint yarat və Session-u saxla]
    I --> J
    J --> K[İstifadəçiyə cavab]

Belə dövr agentin davranışını təkrarlana bilən edir: hər addımda model çağırışından əvvəl hansı vəziyyətin olduğunu və sonra nə dəyişdiyini açıq bilirik.

6. Checkpoints: agentin vəziyyətinin şəkilləri

Checkpoints — prosesin mühüm addımında agentin saxlanmış «vəziyyət şəkilləri»dir. Bu sadəcə «cari session‑state» deyil, xarici anbarda yazılmış faktdır: N‑ci addımda bizdə belə state, belə alət nəticələri, belə istifadəçi girişi var idi.

Nəyə görə lazımdırlar:

  • səhvlərdən və çökmələrdən sonra bərpa;
  • istifadəçi üçün «sonra davam et» imkanı;
  • sazlama: problemli run‑un təkrarlanabilməsi;
  • audit: məsələn, sifariş yaratmazdan əvvəl agentin dəqiq nə etdiyini görmək.

Adətən checkpoint‑ə nələr daxildir

Tipik checkpoint bunları saxlayır:

  • identifikatorlar: runId, userId, workflowId, stepId;
  • o anda olan sessiya vəziyyəti;
  • persistent obyektlərin əsas identifikatorları (məsələn, sifariş qaralamasının id‑si);
  • meta məlumatlar: yaradılma vaxtı, agent versiyası.

Bütün dialoq mətnini ora daşımaq vacib deyil. Aşağıda, yaddaş gigiyenası bölməsində, nələri saxlamağa dəyər, nələri yox — buna qayıdacağıq.

Session‑a link və ya addımların qısa xülasəsini saxlamaq daha yaxşıdır.

7. GiftGenius üçün checkpoint‑ləri layihələndiririk

Hədiyyə seçimi prosesimizi götürək və harada checkpoint istədiyimizi qərarlaşdıraq. Məsələn:

  • alıcı profili toplandıqdan sonra;
  • namizədlər generasiya edilib ilkin filtrasiya olunduqdan sonra;
  • istifadəçiyə son seçimi təklif etməzdən əvvəl.

Checkpoint və workflow vəziyyəti üçün tiplər

Workflow vəziyyətini təsvir edək (çox oxşardır GiftSessionState‑ə, amma bu artıq checkpoint‑lər üçün «slipokdur»):

export type GiftWorkflowStep =
  | "profile_collected"
  | "candidates_generated"
  | "filtered"
  | "final_choice_made";

export type GiftCheckpoint = {
  id: string;
  runId: string;
  userId: string;

  step: GiftWorkflowStep;

  // session vəziyyətinin o hissəsi,
  // bərpa üçün bizə lazım olan
  sessionState: GiftSessionState;

  // hansı namizəd id-ləri generasiya olunmuşdu
  candidateIds: string[];

  createdAt: string; // ISO
  agentVersion: string;
};

Checkpoint anbarı (sadələşdirilmiş)

Hələlik həqiqi DB əvəzinə sadə Map düzəldək:

const checkpoints = new Map<string, GiftCheckpoint>();

export const GiftCheckpointRepo = {
  async save(cp: GiftCheckpoint) {
    checkpoints.set(cp.id, cp);
  },

  async findByRun(runId: string): Promise<GiftCheckpoint[]> {
    return [...checkpoints.values()].filter((c) => c.runId === runId);
  },

  async findLastByUser(userId: string): Promise<GiftCheckpoint | undefined> {
    return [...checkpoints.values()]
      .filter((c) => c.userId === userId)
      .sort((a, b) => b.createdAt.localeCompare(a.createdAt))[0];
  },
};

Agent kodundan checkpoint yaratmaq

Vacib addımdan sonra çağırdığımız helper təsəvvür edək:

import { randomUUID } from "crypto";

export async function createCheckpoint(params: {
  runId: string;
  userId: string;
  step: GiftWorkflowStep;
  sessionState: GiftSessionState;
  candidateIds: string[];
}) {
  const checkpoint: GiftCheckpoint = {
    id: randomUUID(),
    runId: params.runId,
    userId: params.userId,
    step: params.step,
    sessionState: params.sessionState,
    candidateIds: params.candidateIds,
    createdAt: new Date().toISOString(),
    agentVersion: "v1.3.0",
  };

  await GiftCheckpointRepo.save(checkpoint);
}

Agent lazım olan anda belə çağırır:

await createCheckpoint({
  runId,
  userId,
  step: "filtered",
  sessionState,
  candidateIds,
});

Bərpa zamanı biz:

  1. runId və ya userId üzrə son checkpoint‑i tapırıq.
  2. checkpoint.sessionState‑dən session.state‑i bərpa edirik.
  3. Lazım gələrsə, candidateIds üzrə DB‑dən təzə məlumatları çəkirik.

8. Session, persistent və checkpoints texniki olaraq harada saxlanılır

İnfrastruktur səviyyəsində adətən üç müxtəlif sinif anbarınız olur:

  • In‑memory — dev/demos üçün, sürətli, amma müvəqqəti yaddaş.
  • Redis (və ya başqa KV‑store) — session vəziyyəti üçün.
  • Relyasion/NoSQL DB — persistent məlumatlar və checkpoint‑lər üçün.

Lokal inkişaf üçün in‑memory store

Lokal dev rejimi üçün sadə in‑memory store kifayətdir. Məsələn, sessiyalar üçün TTL‑li mini‑anbar:

type StoredSession<T> = {
  state: T;
  expiresAt: number;
};

const sessions = new Map<string, StoredSession<GiftSessionState>>();

export function saveSession(sessionId: string, state: GiftSessionState) {
  sessions.set(sessionId, {
    state,
    expiresAt: Date.now() + 30 * 60 * 1000, // 30 dəqiqə
  });
}

export function loadSession(sessionId: string): GiftSessionState | undefined {
  const stored = sessions.get(sessionId);
  if (!stored) return undefined;
  if (stored.expiresAt < Date.now()) {
    sessions.delete(sessionId);
    return undefined;
  }
  return stored.state;
}

Belə şey local dev üçün əladır, amma prodda horizontal miqyaslama (bir neçə instans) zamanı işləməyəcək.

Session‑state üçün Redis

Prodakşnda session vəziyyətini Redis‑də saxlamaq rahatdır:

  • sürətli yazma/oxuma;
  • TTL «qutudan» hazırdır;
  • xidmətin bütün instansları üçün əlçatandır.

Psevdo‑nümunə (sadələşdirilmiş):

// Redis müştərisi üçün örtük
export async function saveSessionToRedis(
  sessionId: string,
  state: GiftSessionState
) {
  const json = JSON.stringify(state);
  await redis.set(`session:${sessionId}`, json, "EX", 60 * 30); // 30 dəqiqə
}

export async function loadSessionFromRedis(
  sessionId: string
): Promise<GiftSessionState | undefined> {
  const json = await redis.get(`session:${sessionId}`);
  return json ? (JSON.parse(json) as GiftSessionState) : undefined;
}

Persistent və checkpoint‑lər üçün Postgres/digər DB

Persistent vəziyyət və checkpoint‑lər artıq «ciddi» obyektlərdir; onlar üçün tranzaksiyalar, miqrasiyalar, indekslər və s. vacibdir. Onları Postgres, MySQL, Firestore və s. kimi sistemlərdə yerləşdirirlər.

Arxitektura nümunəsi sadədir:

  • session Redis‑də TTL ilə;
  • persistent və checkpoints DB‑də TTL olmadan (və ya biznesə bağlı retention siyasəti ilə).

9. Yaddaş gigiyenası: ölçülər, məxfilik, məsuliyyətin bölünməsi

Agent yaddaşı yalnız «obyekti hara isə qoyduq və getdik» deyil. Pulunuza və yuxunuza qənaət edən bir neçə vacib qayda var.

Hər şeyi messages‑ə yığmayın

Mesajlar tarixi bahalı resursdur:

  • onun uzunluğu modelə sorğunun dəyərinə ciddi təsir edir;
  • adətən orada çox «səs‑küy» olur.

Bu səbəbdən:

  • faktları tarixdən mümkün qədər tez strukturlu vəziyyətə çıxarmağa çalışın;
  • tarixin köhnə hissələri üçün summarization istifadə edin;
  • əgər checkpoint‑lərdə mətn tarixini saxlayırsınızsa, bunu modelə göndəriləndən ayrı edin.

Privacy və PII

Xüsusən commerce ssenariləri üçün həssas məlumatları onların düşməməli olduğu yerlərdə saxlamamaq önəmlidir. Yaddaş arxitekturası sənədləri PII məlumatlarının messages və ya checkpoint‑lərdə təmizlənmədən saxlanmamasını birbaşa vurğulayır.

Praktik qaydalar:

  • agentin işi üçün gərək deyilsə, email/telefon/ünvanı birbaşa session‑state‑ə qoymayın;
  • loglara və checkpoint‑lərə xam sətirlər əvəzinə identifikatorlar (userId, recipientProfileId) yazmağa çalışın;
  • PII‑ni bir neçə addım boyunca ötürmək lazımdırsa — persistent anbarda ayrıca qorunan sahələrdən istifadə edin, state‑də isə yalnız açarı verin.

Biznes məlumatları ilə dialoq loqunun ayrılması

Yaxşı nümunə — state‑i «təmiz», messages‑i «çirkli» yaddaş hesab etməkdir.

Yəni:

  • biznes obyektləri (profillər, sifarişlər, səbətlər) həmişə DB‑də yaşayır;
  • state/checkpoint‑lər prosesin bərpası üçün zəruri olan minimumu saxlayır;
  • loqlar/çat tarixi ayrı saxlanılır (məsələn, vektor anbarında) və analitika üçün istifadə olunur, amma hər model sorğusuna qarışdırılmır.

10. Mini‑praktika: nəyi saxlayardınız?

Yaddaş qatları arasındakı fərqi möhkəmləndirmək üçün bir anlıq nəzəriyyədən ayrılıb konkret keysi düşünək. Kod yazmaq şərt deyil — kağızda və ya beyninizdə strukturları təsəvvür etmək kifayətdir.

Təsəvvür edin ki, sizin GiftGenius agentiniz istifadəçi ilə belə dialoq aparıb:

  • İstifadəçi: «Tərtibatçı həmkar üçün hədiyyə lazımdır, büdcə 50$‑dəkdir, o stolüstü oyunları və kofeini sevir».
  • Agent: bir neçə dəqiqləşdirici sual verir.
  • İstifadəçi: «O, fincanları sevmir və artıq dəftərlərlə doludur».
  • Agent: 10 ideyadan ibarət siyahı yaradır, istifadəçi birini seçir, amma deyir: «Sonra qayıdıb hamısını rəsmiləşdirəcəyəm».

Düşünün:

  1. 30 dəqiqəyə ölə bilən session‑state‑ə nəyi qoyardınız?
  2. İstifadəçi bir həftə sonra qayıda bilsin deyə persistent anbarına nə gedərdi?
  3. İdeya seçildikdən, amma sifariş rəsmiləşmədən əvvəl checkpoint necə görünərdi?

Uyğun TypeScript tiplərini və funksiyaları — saveSessionState, savePersistentState, createGiftIdeaCheckpoint — bu mühazirədəki nümunələrə bənzər şəkildə qaralamağa çalışın. İstəsəniz, elə yuxarıdakı nümunələrə bənzər tipləri və funksiyaları birbaşa redaktorda yazın — bu, növbəti mühazirəyə qədər yaxşı bir mini‑checkpoint olacaq.

11. Agent yaddaşı ilə işləyərkən tipik səhvlər

Səhv №1: hər şeyi yalnız mesajlar tarixində saxlamağa çalışmaq.
İnkişafçı sevinir: «Axı model bütün dialoqu onsuz da görür, niyə əlavə state uyduraq ki?». Nəticədə bir neçə on mesajdan sonra kontekst pəncərəsi zibili ilə dolur, token xərci yeni MacBook qiymətinə çıxır, və agentin davranışı qeyri‑stabil olur — o, sadəcə mühüm köhnə faktları görmür. Bu problemi limitləri artırmaqla deyil, session‑state və persistent anbarını açıq şəkildə ayırmaqla həll etmək lazımdır.

Səhv №2: session və persistent‑i bir obyektə qarışdırmaq.
Bəzən böyük bir AgentState varlığı yaradıb hər şeyi ora yığmaq və olduğu kimi DB‑yə saxlamaq cazibədar görünür. Bu zaman konkret söhbətin müvəqqəti məlumatları ilə istifadəçinin uzunmüddətli məlumatları arasındakı sərhəd bulanır. Belə hekayələr başlayır: «deploydan sonra bütün sessiyalar sirli şəkildə keçən ilin məlumatlarından bərpa olundu» və ya «bir istifadəçinin sessiyası təsadüfən özgə persistent profilini götürdü». Səviyyələri şüurlu şəkildə ayırın.

Səhv №3: checkpoint‑lərdə həddindən artıq çox şey saxlamaq.
Tez‑tez edilən səhv — alət cavablarının bütün JSON‑unu, dialoqun bütün tarixini, inteqrasiya xam məlumatlarını və s. checkpoint‑ə yazmaqdır. Bir neçə həftəlik istismardan sonra checkpoint bazası ölçüsüz şişir, ehtiyat nüsxələr saat çəkir və DB sorğuları yavaşıyır. Checkpoint‑də prosesə davam etmək üçün həqiqətən lazım olan faktlar və minimum meta məlumatlar yaşamalıdır.

Səhv №4: session‑state üçün TTL və təmizləməni unutmaq.
Əgər session vəziyyətlərinin ömrü yoxdursa, Dev Mode‑dakı hər təsadüfi istifadəçi eksperimenti Redis‑də əbədi qalır. Bir neçə aydan sonra monitorinqə baxırsınız və yaddaşı yeyən «unudulmuş» sessiyalar dağını görürsünüz. Session səviyyəsini açıq TTL ilə, persistent səviyyəsini isə düşünülmüş retention siyasəti ilə layihələndirmək lazımdır.

Səhv №5: PII‑ni state və checkpoint‑lərdə ehtiyac olmadan saxlamaq.
Xüsusilə təhlükəlidir ki, email, ünvan, kart nömrəsi düşünmədən session‑state‑ə qoyulur, sonra bu obyekt loglara seriyallaşdırılır, analitikaya və checkpoint‑lərə axır. Bu, tənzimləmə və təhlükəsizlik baxımından ciddi risklər yaradır. Daha yaxşısı, təhlükəsiz identifikatorları saxlamaq və lazım gəldikdə ayrıca qorunan alətlər vasitəsilə onları real məlumatlara həll etməkdir.

Səhv №6: checkpoint‑lərdən bərpa strategiyasının olmaması.
Bəzi komandalar checkpoint yazırlar, amma agentin onlardan dəqiq necə bərpa olunacağını düşünmürlər. Nəticədə «nə isə səhv gedəndə» inkişafçılar gözəl JSON‑larla dolu cədvələ baxırlar, amma run‑u onlar üzrə rekonstruksiya etməyi bacaran kodları yoxdur. Bərpa ssenarisi olmayan checkpointing — bahalı logdur, etibarlılıq aləti deyil.

Səhv №7: agentin konkret anbar realizasiyasına sərt bağlılığı.
Əgər agent kodu birbaşa Redis/Postgres‑ə gedirsə, onu köçürmək, test etmək və inkişaf etdirmək çətinləşir. Arxitektura dəyişəndə (məsələn, MCP resursları və ya ayrıca state xidməti yarananda) agent məntiqini yenidən qazımaq lazım gələcək. Çox daha yaxşıdır ki, agent yalnız Session abstraksiyasını və alət dəstini görsün, alətlər isə məlumatların dəqiq harada yerləşdiyini bilsin.

1
Tapşırıq
ChatGPT Apps, səviyyə, dərs
Bağlanıb
“Survey Agent” üçün TTL-li yaddaşdaxili (in-memory) sesiya vəziyyəti
“Survey Agent” üçün TTL-li yaddaşdaxili (in-memory) sesiya vəziyyəti
1
Tapşırıq
ChatGPT Apps, səviyyə, dərs
Bağlanıb
Persistent user profile kimi "uzunmüddətli yaddaş", yalnız tools vasitəsilə əlçatandır
Persistent user profile kimi "uzunmüddətli yaddaş", yalnız tools vasitəsilə əlçatandır
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION