Зеҳн
Агентҳои зеҳни сунъӣ

Китоб дар бораи он, ки агентҳои зеҳни сунъӣ чӣ гуна кор мекунанд, чӣ гуна онҳоро бояд сохт ва чӣ гуна бехатар ва боэътимод ба кор андохт: давраи «мулоҳиза — амал — мушоҳида», абзорҳо, меъмориҳо, хотира, арзёбӣ ва иҷрои бехатар.

Агенти Зеҳнӣ · 20 октябри 2026 · 17 саҳифа

БарномасозӣТехнология
Аз аввал хондан

Боби 12. Хотираи агент: чӣ гуна нигоҳдории пойдори маълумот агентҳоро ба системаҳои рушдёбанда табдил медиҳад

Боби 12. Хотираи агент: чӣ гуна нигоҳдории пойдори маълумот агентҳоро ба системаҳои рушдёбанда табдил медиҳад

Дар оғози ин китоб фаҳмидед, ки агентҳо ҷоду нестанд: онҳо мошинҳои ҳолатие мебошанд, ки бо диққат тарҳрезӣ шудаанд. Дар ин боб, ки ба хотираи агент бахшида шудааст, ин боз ҳам равшантар мешавад. Азбаски агентҳо худ аз худ чизеро дар хотир нигоҳ намедоранд, хотираро бояд махсус ба онҳо илова кунед. Хотира пулест байни агенти бехабаре, ки ҳатто номи дар оғози суҳбат гуфтаатонро дар хотир намедорад, ва системаи стратегии чандқадамае, ки афзалиятҳои шуморо медонад ва кори худро бар асоси онҳо пеш мебарад.

Барои нишон додани рафтори агентҳои бехотира аз як муоширати одӣ оғоз мекунем. Мо бо LangGraph агенте сохтем ва суҳбатро аз он оғоз кардем, ки номи худро гуфтем (Никол — номи муаллифи китоби аслӣ) ва фаҳмондем: дар бораи хотираи агентҳо як боб менависем. Ҷавобаш чунин буд:

Салом, Никол. Дар навиштани бобатон дар бораи хотираи агентҳои зеҳни сунъӣ бароятон комёбӣ мехоҳам.

Баъд, дарҳол пурсидем: «Номи ман чист?» Ӯ чунин ҷавоб дод:

Аз ин суҳбат номи шуморо намедонам. Агар бигӯед, ки шуморо чӣ ном гирам, ҳамон номро истифода мебарам.

Дар назари аввал ин хандаовар менамояд, аммо маҳз ҳамин мисол нишон медиҳад, ки хотира барои агентҳо то чӣ андоза муҳим аст. Системаи агентии шумо вобаста ба навъи хотира ба таври гуногун рафтор мекунад. Зеро хотира танҳо он нест, ки агентҳо барои нигоҳдорӣ ва бозёбии маълумот аз системаи файлӣ чӣ гуна истифода мебаранд; масъала ин аст, ки онҳо маълумотро байни суҳбатҳо чӣ гуна нигоҳ медоранд ва афзалиятҳои корбар, дастурҳо ё заминаи лоиҳаро чӣ гуна аз худ мекунанд ё фаромӯш месозанд. Маҳз ҳамин ба системаи агентӣ имкони рушд медиҳад. Бе хотира ҳар муошират аз сифр оғоз мешавад. Бо хотира система метавонад заминаро ҷамъ оварад, маълумоти нигоҳдоштаро бо мурури замон нав кунад ва ба корбарон, равандҳои корӣ ва муҳитҳо мутобиқ шавад — ба шарте ки хотира дуруст санҷида ва нигоҳубин карда шавад.

То ин ҷо аллакай медонед, ки мо бо шумо рӯирост суҳбат мекунем. Аз ин рӯ, барои пешгирӣ аз нофаҳмӣ аз оғоз равшан мегӯем: ин боб дар бораи тавлиди тақвиятёфта бо бозёбӣ — RAG — нест. Ҳарчанд RAG-ро метавон яке аз роҳҳои илова кардани хотира ба агентҳо донист, он танҳо як равиш аст. RAG ба агент имкон медиҳад, ки маълумоти дахлдорро аз анбори беруна бозёбӣ кунад, аммо худ аз худ ба агент пайвастагии кор ё огоҳӣ аз муоширатҳои гузашта намедиҳад. Хотира дар системаҳои агентӣ мафҳуми васеътар аст. Он метавонад ҳолати кӯтоҳмуддати суҳбат, маълумоти дарозмуддати нигоҳдошташуда, афзалиятҳои корбар, натиҷаҳои мобайнӣ ва ҳатто рафторҳои азхудшударо дар бар гирад. Новобаста аз он ки татбиқ тавассути пойгоҳҳои додаҳои векторӣ, системаҳои файлӣ, воситаҳои сабти нуқтаҳои назоратӣ ё ҳолати сохторёфта анҷом меёбад, ғоя як аст: агент бояд маълумотро дар байни қадамҳо нигоҳ дошта, дубора истифода бурда тавонад. Ҷадвали 12.1 навъҳои хотираи ин бобро нишон медиҳад.

Ҷадвали 12.1. Навъҳои хотира дар системаҳои агентӣ

Навъи хотираЧиро нигоҳ медорадЧаро муҳим аст
Хотираи кӯтоҳмуддат (хотираи корӣ)Ҳолати ҷории суҳбат, паёмҳои охирин, қадамҳои мобайнӣБа агент имкон медиҳад, ки дар доираи як муошират пайдарҳам ва ҳамоҳанг бимонад ва байни қадамҳо заминаро гум накунад
Хотираи дарозмуддатМаълумоти байни ҷаласаҳо нигоҳдошташуда, аз ҷумла афзалиятҳои корбар, муоширатҳои гузашта ё донишҳои сабтшудаПайвастагии байни суҳбатҳо ва шахсисозиро бо мурури замон таъмин мекунад
Хотираи рӯйдодӣ (эпизодӣ)Муоширатҳо ё рӯйдодҳои мушаххаси гузашта, масалан суҳбатҳо, қарорҳо ва натиҷаҳои пешинаБа агент имкон медиҳад, ки воқеаҳои гузаштаро ба ёд оварда, онҳоро ҳамчун заминаи мулоҳизаҳои оянда истифода барад
Хотираи маъноӣ (семантикӣ)Дониши умумӣ, далелҳо, ҳуҷҷатҳо, намоишҳои векторӣ ё маълумоти сохторёфта дар бораи ҷаҳонЗаминаи воқеӣ ва дониши соҳавӣ медиҳад; дастрасӣ ба он аксаран тавассути механизмҳои бозёбӣ, монанди RAG, сурат мегирад
Хотираи тартиби амал (процедурӣ)Қолабҳо, дастурҳо, равандҳои корӣ ё рафторҳои азхудшудаИҷрои пайвастаи вазифаҳо ва беҳбудиро бо мурури замон таъмин мекунад, бе он ки дар ҳар қадам мантиқ аз нав таъриф шавад

Умуман, хотираро метавон ба ду бахш ҷудо кард: кӯтоҳмуддат ва дарозмуддат. Хотираи кӯтоҳмуддат ҳолати суҳбати шумост: масалан, паёмҳо, воситаи сабти нуқтаҳои назоратӣ ё thread_id — шиносаи суҳбат (дар бораи онҳо дар поён муфассалтар мегӯем). Маҳз ҳамин ба агент имкон медиҳад, ки дар доираи як муошират пайдарҳам амал кунад. Хотираи дарозмуддат далелҳои маъноӣ, намунаҳои рӯйдодӣ ва дастурҳои тартиби амалро дар анбори алоҳида нигоҳ медорад. Ин ба агент имкон медиҳад, ки дониш ва рафторро байни муоширатҳо ҳифз кунад. Одатан, барои ҳолати агент ба як «курсии сепоя» ниёз доред:

  • Кӯтоҳмуддат: ҳоло чӣ рӯй медиҳад — паёмҳо ва риштаҳои суҳбат.
  • Дарозмуддат: система чӣ медонад — далелҳои маъноӣ — ва аз таҷриба чӣ дар хотир дорад — рӯйдодҳои гузашта.
  • Тартиби амал: корбарон ба системаи агентӣ гуфтаанд, ки чӣ гуна рафтор кунад — дастурҳо.

Агар яке аз ин пояҳо набошад, система ноустувор мешавад: заминаро фаромӯш мекунад, дониш намерасад ё номуназзам рафтор мекунад. Дар бахшҳои баъдӣ бо ҳар навъи муҳими хотираи агент шинос мешавед. Барои ин дар анбори китоби аслӣ дафтари интерактивие бо номи ch10_agent_memory_langgraph.ipynb омода кардаем. Одатан, мо тарафдори як дафтари азим барои омӯзондани ҳамаи мафҳумҳои боб нестем. Аммо барои навъҳои хотира ин муфид аст: метавонед кори ҳар навъро бинед ва онҳоро бо ҳам муқоиса кунед. Ҳамчунин меомӯзед, ки қабати хидмати хотираро чӣ гуна созмон диҳед, нигоҳубини дурусти хотира — хулосасозӣ ва фишурдасозӣ — чӣ гуна анҷом меёбад ва фазоҳои ном дар барномаҳои дорои чанд муштарӣ чӣ гуна истифода мешаванд.

Бахши охирини боб нишон медиҳад, ки хотира дар системаҳои чанд агентӣ интихоби огоҳонаи тарҳрезист. Маҳаллӣ, муштарак ё омехта будани хотира мустақиман муайян мекунад, ки агентҳо чӣ гуна ҳамоҳанг мешаванд, чӣ қадар заминаро нигоҳ медоранд ва то чӣ андоза метавонанд бе дур шудан аз ҳамдигар ба таври боэътимод тахассус пайдо кунанд. Аз ин рӯ, хотира дар муҳандисии агентҳо интихоби муҳими тарҳрезӣ мешавад: он ҳам ба дониши система ва ҳам ба тарзи рушди он бо мурури замон таъсир мерасонад.

Хотираи кӯтоҳмуддат ва бозгашт ба ҳолатҳои гузашта

Хотираи кӯтоҳмуддат ҳолати иҷроест, ки ба агент имкон медиҳад дар доираи як риштаи суҳбат ҳамоҳанг бимонад. Дар LangGraph ин кор одатан тавассути checkpointer, яъне воситаи сабти нуқтаҳои назоратӣ, анҷом меёбад: он ҳолати мобайниро байни қадамҳо нигоҳ медорад. Нуқтаи назоратӣ (checkpoint) мисли нуқтаи захира (save point) дар бозии компютерӣ аст: ҳолати ҷорӣ сабт мешавад ва баъдтар метавон аз ҳамон ҷо идома дод ё ба он баргашт. Ин аз даврзании такрорӣ пешгирӣ карда, пайвастагии занҷираи мулоҳизаро нигоҳ медорад.

Ришта (thread) як суҳбати алоҳида аст, ки шиносаи худро — thread_id — дорад. Ҳамон thread_id — идомаи ҳамон суҳбат; thread_id-и нав — суҳбати нав аз сифр. Мо бо checkpointer ва thread_id аллакай дар боби 6 шинос шудем, вақте агенти обу ҳаворо месохтем.

Эзоҳ. Дар бахшҳои минбаъдаи ин боб танҳо порчаҳои муҳими кодро барои ҳар мафҳум нишон медиҳам ва функсияҳои ёрирасону дигар воситаҳои хизматиро намеорам.

Татбиқи хотираи кӯтоҳмуддат осон аст. Намунаи 12.1 танзими ҳадди ақали checkpointer ва анборро нишон медиҳад. Checkpointer ҳолати ришта, аз ҷумла паёмҳо ва қиматҳои мобайнии графро нигоҳ медорад; анбор бошад, барои хотираи дарозмуддат истифода мешавад. Анбор ҳар сабтро ба намоиши векторӣ (embedding) табдил медиҳад — рӯйхати рақамҳое, ки маънои матнро ифода мекунад. Ба шарофати он сабтҳоро аз рӯи маъно ҷустуҷӯ кардан мумкин аст, на танҳо аз рӯи калимаҳои якхела.

Намунаи 12.1. Танзими checkpointer ва анбор

def build_checkpointer(*, serde=None):  # serde — тарзи табдили ҳолат барои нигоҳдорӣ; одатан лозим нест
    return InMemorySaver(serde=serde) if serde is not None else InMemorySaver()

def build_store() -> InMemoryStore: 
    def embed_texts(texts: list[str]) -> list[list[float]]:
        return safe_embed_documents(list(texts))

    return InMemoryStore(
        index={
            "embed": embed_texts,
            "dims": EMBEDDING_DIMS, 
            "fields": ["mem_ix"],  # кадом майдони сабт барои ҷустуҷӯ индекс мешавад
        }
    )

CHECKPOINTER = build_checkpointer() 
STORE = build_store()

Шарҳи код:

  • Намунаи checkpointer месозад ва дар сурати зарурат сериализаторро ба он медиҳад.
  • Анбореро дар хотираи оперативӣ бо индекси ҷустуҷӯ бар асоси намоишҳои векторӣ месозад.
  • Шумораи андозаҳои намоиши векториро, ки индекси анбор истифода мекунад, муайян мекунад.
  • Checkpointer-еро месозад, ки граф истифода мебарад.

Дар ин намуна ҳама чиз дар хотираи оперативии компютер нигоҳ дошта мешавад ва пас аз бастани барнома гум мешавад. Дар системаи воқеӣ ба ҷойи он пойгоҳи додаҳо, масалан SQLite ё PostgreSQL, истифода мешавад.

Тафсилот дар охири боб: «Checkpointer дар муҳити истеҳсолӣ» (қисми «Барои хонандагони пешрафта»).

Намунаи 12.2 графи ҳадди ақалеро месозад, ки бо checkpointer ҳолатро байни қадамҳои як ришта нигоҳ медорад. Ин осонтарин роҳ барои дидани кори хотираи кӯтоҳмуддат аст. Намуна ба он чи дар боби 6 дидем, такя мекунад: граф аз гиреҳҳо ва канорҳо иборат аст ва checkpointer ҳангоми compile ба граф дода мешавад.

Намунаи 12.2. Нигоҳ доштани ҳолати граф дар як ришта

class PS(TypedDict):
    foo: str
    bar: Annotated[list[str], add]  # қиматҳои нав ба рӯйхат илова мешаванд, ҷои кӯҳнаро намегиранд

def node_a(state: PS):
    return {"foo": "a", "bar": ["a"]}

def node_b(state: PS):
    return {"foo": "b", "bar": ["b"]}

ps_wf = StateGraph(PS) 
ps_wf.add_node(node_a)
ps_wf.add_node(node_b)
ps_wf.add_edge(START, "node_a")
ps_wf.add_edge("node_a", "node_b")
ps_wf.add_edge("node_b", END)

persist_demo = ps_wf.compile(checkpointer=InMemorySaver()) 
ps_cfg: RunnableConfig = {"configurable": {"thread_id": "persistence-mini-demo"}} 
persist_demo.invoke({"foo": "", "bar": []}, ps_cfg)
print("Checkpoint count:", len(list(persist_demo.get_state_history(ps_cfg))))

Шарҳи код:

  • Барои намунаи хурди нигоҳдории ҳолат графи ҳолат месозад.
  • Графро бо checkpointer-и дар хотираи оперативӣ ҷойгиршуда компилятсия мекунад.
  • Шиносаи риштаро медиҳад, то таърихи нуқтаҳои назоратии ин иҷро ҷудо бошад.
  • Таърихи ҳолатҳои сабтшударо аз checkpointer боз мехонад.

Иҷрои граф бо сабти нуқтаҳои назоратӣ имкон медиҳад, ки системаро ба ақиб баргардонед, тағйир диҳед ва аз он шоха созед. Инро time travel, яъне «сафар дар замон», меноманд. Он яке аз муфидтарин имкониятҳои ислоҳи хатоҳоест, ки бар асоси ҳолати кӯтоҳмуддати дорои нуқтаҳои назоратӣ сохта шудааст. Расми 12.1 ин мафҳумро нишон медиҳад.

Сафар дар замон бо нуқтаҳои назоратӣ

Расми 12.1. Иҷро бо нуқтаҳои назоратӣ бозгашт, тағйирдиҳӣ ва шохасозиро имконпазир мекунад.

Тафсилот дар охири боб: «Сафар дар замон дар код: шохасозӣ ва иҷрои дубора» (қисми «Барои хонандагони пешрафта»).

Сафар дар замон ба шумо ёрӣ медиҳад, ки иҷрои хаттиро ба графи ҳолатҳои дорои версияҳо табдил диҳед. Дар он метавонед роҳҳои мулоҳизаро ислоҳ кунед, қарорҳои алтернативиро бисанҷед ё натиҷаҳои пешинаро бозтавлид намоед. Ҳамчунин метавонед аз ин имконият барои санҷиши ҷараёни қабули қарорҳо истифода баред.

Сояи хотира аз гузашта

Бозгашт ба ҳолатҳои гузашта танҳо ҳолати суҳбатро ба ақиб мебарад, на анбори хотираи дарозмуддатро. Бояд ошкоро тарҳрезӣ кунед, ки хотира версиябандӣ шавад, ба ҳолати пешина баргардад ё бетағйир монад.

Дар ин бахш дидед, ки сабти нуқтаҳои назоратӣ барқарорсозӣ ва санҷиши таърихи иҷроиро имконпазир мекунад. Аммо шумо мехоҳед агентҳо байни ҷаласаҳо низ пайвастагӣ дошта бошанд: маълумоти дахлдорро бо мурури замон нигоҳ доранд, ба корбарон ва равандҳои корӣ мутобиқ шаванд ва аз муоширатҳои пешина истифода бурда омӯзанд, ба ҷойи он ки ҳар дафъа аз сифр оғоз кунанд.

Хотираи дарозмуддат: табдил додани агент ба мутахассиси ботаҷриба

Бе хотираи дарозмуддат агент ҳар муоширатро аз сифр оғоз мекунад. Бо чунин хотира, ӯ мисли касе рафтор мекунад, ки ин корро қаблан анҷом додааст. Хотираи дарозмуддат ба агент пайвастагии байни ҷаласаҳо медиҳад ва агентҳои беҳолатро ба системаҳои рушдёбанда табдил медиҳад. Ҷадвали 12.2 хотираи кӯтоҳмуддат ва дарозмуддатро муқоиса мекунад.

Ҷадвали 12.2. Муқоисаи хотираи кӯтоҳмуддат ва дарозмуддат

ҶанбаХотираи кӯтоҳмуддатХотираи дарозмуддат
ТаърифЗамина дар доираи як иҷро ё ҷаласа, аз ҷумла ҳолати мулоҳизаХотираи пойдор байни ҷаласаҳо, ки донишҳои гузаштаро фаро мегирад
Унсурҳои асосӣОбъекти ҳолати ҷорӣ, нақшаи фаъол, натиҷаҳои охирини абзорҳо, ҳисобкунакҳои давр, занҷираи муваққатии мулоҳизаҚарорҳои гузашта, натиҷаҳои пешина, афзалиятҳои азхудшуда, сабтҳои санҷишӣ, муоширатҳои гузашта
ДоираЯк иҷро ё ҷаласаБайни ҷаласаҳо
ҲадафНигоҳ доштани пайдарҳамӣ ва пешгирӣ аз даврзанӣ ҳангоми иҷроТаъмини пайвастагӣ, мутобиқшавӣ ва омӯзиш бо мурури замон
ПойдорӣМуваққатист; агар махсус сабт нашавад, пас аз иҷро аз даст меравадБа қабати нигоҳдории пойдор ниёз дорад
Истифодаҳои маъмулДаврҳои ReAct, пайгирии иҷрои абзорҳо, мулоҳизаи чандқадама, гузаришҳои банақшагирПайгирии афзалиятҳои корбар, равандҳои тӯлонӣ, ёварони шахсӣ, ҳифзи дониши ташкилот
Шаклҳои нокомӣНабудани пайвастагӣ байни ҷаласаҳо, имкони маҳдуди санҷиши таърих, халал дар равандҳои тӯлонӣНигоҳдории нодуруст ё санҷиданашуда, варам кардани хотира, маълумоти кӯҳна ё пур аз ҷузъиёти нолозим

Хотираи тартиби амал ва хотираи рӯйдодӣ махсусан муҳиманд, зеро онҳо ба беҳтар шудани агент мусоидат мекунанд. Хотираи рӯйдодӣ ба агент имкон медиҳад, ки натиҷаи кори гузаштаро таҳлил кунад; хотираи тартиби амал дастур медиҳад, ки аз ин пас корҳоро чӣ гуна беҳтар анҷом диҳад. Расми 12.2 ин се навъи хотира — тартиби амал, рӯйдодӣ ва маъноӣ — ро барои як агенти барноманавис паҳлуи ҳам муқоиса мекунад.

Се навъи хотира

Расми 12.2. Хотираи рӯйдодӣ — «чӣ рӯй дод», хотираи тартиби амал — «ҳоло корҳоро чӣ гуна беҳтар анҷом медиҳем» ва хотираи маъноӣ — «чӣ медонем».

Ҷадвали 12.3 ин се навъи хотираро муфассалтар муқоиса мекунад.

Ҷадвали 12.3. Муқоисаи хотираи рӯйдодӣ, тартиби амал ва маъноӣ

ҶанбаХотираи рӯйдодӣХотираи тартиби амалХотираи маъноӣ
ТаърифСабтҳои муоширатҳо ва рӯйдодҳои гузаштаСтратегияҳо, рафторҳо ва беҳбудиҳои азхудшудаДониши умумиятёфта ва далелҳо дар бораи ҷаҳон
Меҳвари таваҷҷуҳЧӣ рӯй додЧӣ гуна амал кардан ё беҳтар шуданЧӣ дуруст аст ё маълум мебошад
Унсурҳои асосӣМуоширатҳои гузашта, пайи суҳбатҳо, иҷрои вазифаҳоНақшаҳои такмилёфта, қоидаҳои навшуда, қолабҳои беҳтари истифодаи абзорҳоДалелҳо, мафҳумҳо, дониши сохторёфта, хулосаҳои бадастомада
ҲадафБа ёд овардан ва пайгирӣ кардани рӯйдодҳои пешинаТаъмини мутобиқшавӣ ва беҳбуди иҷроМулоҳиза бар асоси дониши ҷамъшуда
НигоҳдорӣДар шакли таърихи муошират ё сабтҳоДар шакли қоидаҳо, дастурҳо ё рафтори навшудаи системаДар пойгоҳҳои дониш, анборҳои векторӣ ё хотираи сохторёфта
Истифодаҳои маъмулТаърихи суҳбат, пайи санҷишӣ, ислоҳи рафтори агентТакмили стратегия, омӯзиши тақвиятӣ, беҳтар кардани интихоби абзорТақвияти бозёбӣ, такя ба дониш, мулоҳизаи далелмеҳвар
Шаклҳои нокомӣАз ҳад мутобиқ шудан ба муоширатҳои гузашта, ба ёд овардани маълумоти номувофиқТақвияти рафтори камсамар, набудани санҷишДониши кӯҳна ё нодуруст, далелҳои сохта ё пур аз маълумоти нолозим

Аммо ин навъҳои хотира интизом ва идоракунии нигоҳдориро талаб мекунанд. Аз ҳамин сабаб, дертар дар бахши «Нигоҳубини хотира: чӣ гуна хотираи агентро мувофиқ ва оқилона нигоҳ дорем» мефаҳмонем, ки хотираи агентро чӣ гуна кӯтоҳ ва ба мавзуъ мувофиқ нигоҳ доштан мумкин аст.

Хотираи дарозмуддат дар анбори хотира (store) нигоҳ дошта мешавад. Дар анбор ҳар сабт дар фазои ном (namespace) ҷойгир мешавад. Фазои номро мисли ҷузвдон (папка) дар компютер тасаввур кунед: масалан, «ташкилот / корбар / навъи хотира». Ҳамин тавр, хотираи ҳар корбар аз хотираи корбари дигар ва далелҳо аз рӯйдодҳо ҷудо мемонанд.

Тафсилот дар охири боб: «Фазоҳои ном ва қабати хидматии хотира» (қисми «Барои хонандагони пешрафта»).

Хотираи рӯйдодӣ

Хусусияти ҷолиби хотираи рӯйдодӣ дар он аст, ки агентро аз як абзори беҳаракат ба иҷрокунандаи огоҳ табдил медиҳад. Бе хотираи рӯйдодӣ агент бар асоси маълумоти умумӣ тахмин мезанад. Аммо вақте як намунаи муваффақи шабеҳи гузаштаро бозмеёбад, ба равиши чанднамунавӣ — few-shot — мегузарад (яъне ба модел намунаҳои тайёри ҳалли вазифаҳои шабеҳ нишон дода мешаванд) ва метавонад таърихи худро ҳамчун додаи омӯзишӣ истифода барад. Хотираи рӯйдодӣ воқеаҳои мушаххаси гузашта, монанди вазифаҳо ва натиҷаҳои онҳоро нигоҳ медорад.

Тафсилот дар охири боб: «Амалҳои хотираи рӯйдодӣ дар код» (қисми «Барои хонандагони пешрафта»).

Хотираи рӯйдодӣ ба агент ёрӣ медиҳад, ки воқеаҳои пешинаро ба ёд орад, аммо ҳар хотираи муҳим рӯйдод нест. Баъзе маълумот воқеаи гузашта набуда, далели нисбатан устувор дар бораи корбар, муҳит ё соҳаи вазифа аст. Дар ҳамин ҷо хотираи маъноӣ лозим мешавад.

Хотираи маъноӣ

Хотираи маъноӣ аз хотираи рӯйдодӣ фарқ мекунад: он далелҳоро нигоҳ медорад, на таҷрибаҳоро. Забони писандидаи корбар, воҳидҳои ченаки интихобкардааш ё танзимоти маҳсулот рӯйдод нестанд. Онҳо далелҳои пойдоре мебошанд, ки агент бояд дар суҳбатҳои оянда низ ба ёд оварда тавонад.

Тафсилот дар охири боб: «Амалҳои хотираи маъноӣ дар код» (қисми «Барои хонандагони пешрафта»).

Бозёбии маъноӣ бояд танҳо далелҳоеро бор кунад, ки ба дархости ҷорӣ бештар мувофиқанд. Ин ба агент пайвастагии байни ҷаласаҳо медиҳад, бе он ки тамоми суҳбати пешина дубора ворид карда шавад. Хотираи маъноӣ ба агент мегӯяд, ки чӣ дуруст аст, аммо танҳо далелҳо намефаҳмонанд, ки чӣ гуна рафтор кунад. Агар система бояд минбаъд ба раванди муайяни корӣ, қоидаи шаклбандӣ ё тартиби бехатарӣ риоя кунад, ин ба хотираи тартиби амал тааллуқ дорад.

Хотираи тартиби амал

Хотираи тартиби амалро метавон дастури зиндаи агенти шумо донист. Фарқ дар он аст, ки дар ин ҳолат агент воқеан аз дастур истифода мебарад — бар хилофи бисёр одамон. Дар нармафзори анъанавӣ барои тағйир додани рафтори система навсозии кодро нашр мекунед. Дар агенти дорои хотира корбар метавонад бигӯяд: «Аз ин пас ба дастури шаклбандии XYZ риоя кун», ва ҳолати тартиби амали система нав мешавад. Ба агент танҳо нагуфтаанд, ки чӣ кунад: ӯ раванди нави кориро аз худ кардааст. Хотираи тартиби амал ёрӣ медиҳад, ки дастурҳо аз чизи ихтиёрӣ ба маълумоте табдил ёбанд, ки ҳангоми иҷро мунтазам бозёбӣ ва татбиқ мешавад.

Коди амалҳои хотираи тартиби амал ва намунаи муттаҳиде, ки ҳар се навъи хотираро якҷо истифода мебарад, дар охири боб, дар қисми «Барои хонандагони пешрафта», оварда шудаанд.

Хотираро ҳифз кунед

Хотираи пойдор метавонад маълумоти шахсии корбарро дар бар гирад, бинобар ин онро мисли ҳар пойгоҳи додаҳои дигар ҳифз мекунанд, масалан рамзгузорӣ мекунанд. Хатари дигар заҳролудсозии хотира аст: агар матни беэътимод ё зараровар ба хотира навишта шавад, агент онро баъдтар ҳамчун дониши боэътимоди худ бармегардонад ва ба он бовар мекунад. Аз ин рӯ, на ҳар чизеро, ки агент мебинад, бояд дар хотира нигоҳ дошт.

Тафсилот дар охири боб: «Сериализатсия, рамзгузорӣ ва заҳролудсозии хотира» ва «Заҳролудсозии хотира танҳо тазриқи дастур ба промпт нест» (қисми «Барои хонандагони пешрафта»).

Пас аз он ки агент метавонад далелҳо, рӯйдодҳо ва дастурҳоро байни риштаҳо нигоҳ дорад, масъалаи навбатӣ он нест, ки чӣ гуна бештар дар хотир нигоҳ дорад, балки он аст, ки чӣ гуна интихобан дар хотир нигоҳ дорад. Хотирае, ки беинтизом меафзояд, аз маълумоти нолозим ва зиддиятҳо пур мешавад ва дубора ба модел ворид кардани он торафт гаронтар мегардад.

Нигоҳубини хотира: чӣ гуна хотираи агентро мувофиқ ва оқилона нигоҳ дорем

Ҳамин ки агент қобилияти дар хотир нигоҳ доштан пайдо мекунад, масъалаи навбатӣ муайян кардани он аст, ки чиро бояд ҳифз кунад. Хотирае, ки беинтизом калон мешавад, пур аз маълумоти нолозим ва кӯҳна мегардад ва дар ниҳоят зарар мерасонад. Баъзе масъалаҳои нигоҳубин ба ҳолати кӯтоҳмуддат дахл доранд, масалан калон шудани матни суҳбат дар як ришта. Дигар масъалаҳо ба хотираи дарозмуддат марбутанд: далелҳои такрорӣ, зиддиятҳо ё афзалиятҳои кӯҳна. Расми 12.3 мафҳуми умумии сиёсати нигоҳдории хотираро нишон медиҳад; ҷадвали 12.4 ҳар механизмро муфассалтар шарҳ медиҳад.

Ҷадвали 12.4. Сиёсатҳои нигоҳдории хотира

МеханизмШарҳНамунаҳо
Поккунӣ бар асоси вақтХориҷ кардани маълумот аз рӯи синни онНигоҳ доштани маълумоти N рӯзи охир
Нигоҳдорӣ бар асоси аҳамиятНигоҳ доштани танҳо сабтҳои пурарзишНигоҳ доштани хатоҳо, қоидавайронкуниҳо ва рӯйдодҳои эътимоднок; хориҷ кардани сабтҳои камаҳамият
ФишурдасозӣКам кардани ҳаҷми хотира бо ҳифзи маълумоти асосӣХулоса кардани рӯйдодҳо

Нигоҳубини хотира

Расми 12.3. Идоракунии хотира аз варам кардани он ва ҷамъшавии ғаразҳо пешгирӣ мекунад.

Масалан, агар суҳбат дар як ришта хеле дароз шавад, паёмҳои кӯҳнаро бо хулосаи кӯтоҳи онҳо иваз мекунем. Агент чизи муҳимро — афзалиятҳо ва қарорҳои корбарро — нигоҳ медорад, аммо ҳар дафъа тамоми суҳбатро ба модел намефиристад.

Тафсилот дар охири боб: «Хулосасозии риштаи фаъол дар код» (қисми «Барои хонандагони пешрафта»).

Паҳншавии хатои хотира

Хотира бетараф нест. Он метавонад ғараз ва хатоҳоро тақвият диҳад. Агар маълумоти нодуруст ҳамчун ҳақиқат сабт шавад, мулоҳизаҳои оянда хаторо бештар мекунанд. Аз ҳамин сабаб, хотира пеш аз нигоҳдории пойдор бояд санҷида шавад.

Бо хотираи дарозмуддат низ ҳамин тавр рафтор мекунем. Сабтҳои такрориро ба як сабт якҷо мекунем. Далелҳои кӯҳнаи зиддиятнокро хориҷ мекунем: масалан, агар корбар аввал намуди торик ва баъдтар намуди равшани интерфейсро интихоб карда бошад, танҳо интихоби навтарин мемонад. Пеш аз навиштан месанҷем, ки матн маълумоти ҳассос — рақами корти пардохтӣ, калиди API ва монанди инҳо — надошта бошад: сирру паролҳо набояд ба хотираи агент роҳ ёбанд.

Тафсилот ва коди ин амалҳо дар охири боб: «Нигоҳубини хотираи дарозмуддат дар код» (қисми «Барои хонандагони пешрафта»).

То ин ҷо навъҳои хотира ва тарзи нигоҳдорӣ, бозёбӣ ва нигоҳубини онҳоро баррасӣ кардед. Аммо дар системаҳои чанд агентӣ саволи дигар низ ба ҳамин андоза муҳим аст: хотира дар куҷо ҷойгир аст ва кадом агентҳо ба он дастрасӣ доранд? Зеро хотира танҳо масъалаи нигоҳдорӣ нест; он интихоби меъморӣ ҳам мебошад.

Топологияи хотира: тарҳрезии хотира дар системаҳои чанд агентӣ

Дар системаи як агентӣ тарҳрезии хотира аллакай муҳим аст, аммо дар системаи чанд агентӣ аҳамияти ҳалкунанда пайдо мекунад. Тарзи тақсим кардани хотира байни агентҳо муайян мекунад, ки система мисли ташкилоти ҳамоҳанг рафтор мекунад ё мисли маҷмӯи қисмҳои сустпайваст. Агар ҳамаи агентҳо як хотираро бе интихоб муштарак истифода баранд, равзанаи замина зуд аз маълумоти нолозими агентҳои дигар пур мешавад. Агар ҳамаи агентҳо бо хотираи комилан ҷудогона кор кунанд, фаҳмиши муштаракро аз даст медиҳанд ва аз ҳам дур мешаванд. Ин мувозинат ба се топологияи маъмули хотира меорад. Расми 12.4 хотираи маҳаллӣ ва муштаракро муқоиса мекунад, расми 12.5 бошад, ҳар ду навъро дар як меъмории омехта муттаҳид месозад.

Хотираи маҳаллӣ ва муштарак

Расми 12.4. Дар тарафи чап ҳар ду агент хотираи алоҳида доранд; дар тарафи рост ҳар се агент маълумоти худро ба як анбори муштараки хотира менависанд.

Хотираи омехта

Расми 12.5. Хотираи омехта мустақилияти маҳаллиро бо қабати муштараки таъмини мувофиқат якҷо мекунад ва дар системаҳои истеҳсолӣ барои густариш мувофиқтар аст.

Ба таври сода, се роҳ ҳаст. Дар хотираи маҳаллӣ ҳар агент дафтарчаи худро дорад: заминааш тоза аст, вале агентҳо метавонанд аз корҳои ҳамдигар бехабар монанд. Дар хотираи муштарак ҳамаи агентҳо дар як дафтар менависанд: ҳама як чизро медонанд, вале дафтар зуд аз маълумоти нолозим пур мешавад. Дар хотираи омехта ҳар агент дафтарчаи худро дорад ва танҳо натиҷаҳои муҳимро ба дафтари умумӣ менависад; аксари системаҳои истеҳсолӣ ҳамин роҳро интихоб мекунанд.

Саволи дигар ин аст, ки оё зер агент даъватҳои пешинаро дар хотир нигоҳ медорад: оё ӯ мисли ҳисобкунак (калкулятор) ҳар дафъа аз нав оғоз мекунад ё мисли дафтарча ҳар навбатро ба ёддоштҳои пешина илова мекунад.

Тафсилот дар охири боб: «Топологияҳои хотира ва зер агентҳо: тафсилот ва код» (қисми «Барои хонандагони пешрафта»).

Хотира санҷиш мехоҳад

Системаҳои хотира аксаран то замоне ки дар шароити воқеӣ озмоиш нашаванд, дурусткор менамоянд. Бе санҷиши ошкор агентҳо метавонанд далелҳои дахлдорро бозёбӣ карда натавонанд, ҳангоми хулосасозӣ ё фишурдасозӣ маълумотро аз даст диҳанд ё маълумоти кӯҳнаву зиддиятнокро пешниҳод кунанд. Рафтори хотираро ҳамеша дар чанд навбати муошират ва қолабҳои воқеии истифода бисанҷед, то бовар ҳосил кунед, ки маълумоти сабтшуда дастрас ва дуруст мемонад.

Хулоса

Дар ин боб дидед, ки маҳз хотира агентро аз абзори вокунишкунанда ба системае табдил медиҳад, ки метавонад пайвастагиро байни қадамҳо, ҷаласаҳо ва равандҳои корӣ нигоҳ дорад.

Барои сохтани ин асос навъҳои муҳими хотираро дар системаҳои агентӣ омӯхтед: хотираи кӯтоҳмуддат ва дарозмуддат. Хотираи кӯтоҳмуддат тавассути ҳолат ва сабти нуқтаҳои назоратӣ ҳамоҳангии агентро дар як ришта нигоҳ медорад. Хотираи дарозмуддат ин пайвастагиро ба воситаи далелҳои сабтшуда, рӯйдодҳои пешина ва дастурҳои рафторӣ байни ҷаласаҳо густариш медиҳад. Дар ин доираи васеътар хотираи маъноӣ он чиро медонем, нигоҳ медорад; хотираи рӯйдодӣ он чиро рӯй додааст, сабт мекунад; хотираи тартиби амал бошад, муайян мекунад, ки система минбаъд чӣ гуна рафтор кунад.

Ҳамчунин дидед, ки илова кардани хотира танҳо масъалаи нигоҳдорӣ нест, балки масъалаи меъморӣ ва истифодаи амалӣ ҳам мебошад. Checkpointer-ҳо нигоҳдории ҳолат, иҷрои дубора ва бозгашт ба ҳолатҳои гузаштаро дар дохили ришта имконпазир мекунанд. Имкони охирин барои ислоҳи хатоҳои системаи агентӣ ёрӣ медиҳад. Фазоҳои ном ва қабатҳои хидматӣ хотираи дарозмуддатро дар системаҳои чандкорбара қобили истифода месозанд. Нигоҳубини хотира тавассути хулосасозӣ, фишурдасозӣ, санҷиш ва назорати зиддиятҳо мувофиқати маълумоти нигоҳдоштаро таъмин мекунад. Бе ин чораҳо хотира зуд аз маълумоти нолозим ва кӯҳна пур мешавад ва ба ҷойи фоида зарар мерасонад.

Ниҳоят, омӯхтед, ки хотира дар системаҳои чанд агентӣ интихоби тарҳрезист. Маҳаллӣ, муштарак ё омехта будани он муайян мекунад, ки агентҳо чӣ гуна ҳамоҳанг мешаванд, чӣ қадар заминаро бо худ мебаранд ва то чӣ андоза метавонанд бе дур шудан аз ҳамдигар ба таври боэътимод тахассус пайдо кунанд. Аз ҳамин сабаб, хотира яке аз фишангҳои асосии тарҳрезӣ дар муҳандисии агентҳост: он ҳам он чиро система медонад ва ҳам тарзи рушди онро шакл медиҳад.

Чиро бояд дар ёд дошт

  • LLM худ аз худ чизеро дар хотир нигоҳ намедорад: хотираро барои агент мо бояд махсус созем.
  • Хотираи кӯтоҳмуддат — ин суҳбати ҷорӣ, яъне як ришта (thread_id) аст, ки checkpointer нигоҳ медорад. Хотираи дарозмуддат дар анбор нигоҳ дошта мешавад ва байни ҷаласаҳо боқӣ мемонад.
  • Хотираи дарозмуддат се навъ дорад: рӯйдодӣ («чӣ рӯй дод»), маъноӣ («чӣ медонем») ва тартиби амал («чӣ гуна рафтор кунем»).
  • Хотираро бояд нигоҳубин кард: такрорҳоро якҷо кунед, суҳбатҳои дарозро хулоса кунед, далелҳои кӯҳнаро хориҷ кунед ва ҳеҷ гоҳ сирру паролҳоро нигоҳ надоред. Вагарна хотира аз маълумоти нолозим пур мешавад ва метавонад заҳролуд шавад.

Барои хонандагони пешрафта

Ин қисм барои хониши аввал ҳатмӣ нест. Дар он тафсилоти техникӣ, формулаҳо ва коди пурра оварда шудаанд. Агар китобро бори аввал мехонед, метавонед онро гузаронед ва ба боби навбатӣ гузаред.

Checkpointer дар муҳити истеҳсолӣ

Дар муҳити истеҳсолӣ бояд ба ҷойи нигоҳдорӣ дар хотираи оперативӣ аз зерсохтори пойдор истифода баред. Намунаи 12.3 ду варианти истеҳсолиро нишон медиҳад.

Намунаи 12.3. Checkpointer дар муҳити истеҳсолӣ

conn = sqlite3.connect("checkpoints.db", check_same_thread=False)
CHECKPOINTER_PROD = SqliteSaver(conn)

CHECKPOINTER_PROD = PostgresSaver.from_conn_string(os.environ["DATABASE_URL"])
CHECKPOINTER_PROD.setup()

Сафар дар замон дар код: шохасозӣ ва иҷрои дубора

Намунаи 12.4 нишон медиҳад, ки нуқтаҳои назоратии гузаштаро чӣ гуна санҷед, аз ҳолати пешина шоха созед ва иҷрои барномаро аз он нуқта дубора оғоз кунед.

Намунаи 12.4. Шохасозӣ ва иҷрои дубора аз нуқтаи назоратии пешина

tt_graph = ps_wf.compile(checkpointer=InMemorySaver())   # ҳамон графи намунаи 12.2
tt_cfg: RunnableConfig = {"configurable": {"thread_id": "time-travel-mini"}}
tt_graph.invoke({"foo": "", "bar": []}, tt_cfg)

before_b = next(s for s in tt_graph.get_state_history(
                tt_cfg) if s.next == ("node_b",)) 
forked = tt_graph.update_state(before_b.config,
         {"foo": "forked"}, as_node="node_a") 
continued = tt_graph.invoke(None, forked)
print("Fork continue:", continued)

replay_cfg = {
    "configurable": {
        "thread_id": "time-travel-mini",
        "checkpoint_id": before_b.config["configurable"]["checkpoint_id"],
    }
}
print("Replay:", tt_graph.invoke(None, replay_cfg))

Шарҳи код:

  • Ҳамон графи намунаи 12.2-ро бо риштаи нав ва сабти нуқтаҳои назоратӣ компилятсия мекунад.
  • Аз таърихи сабтшуда нуқтаи назоратии пешинаро интихоб мекунад.
  • Аз ҳамон ҳолати пешина навсозие месозад, ки шохаи навро ба вуҷуд меорад.
  • Иҷроро аз ҳолати нуқтаи назоратии шохаи нав идома медиҳад.
  • Иҷроро аз рӯи шиносаи нуқтаи назоратии мушаххас такрор мекунад.

Ҳангоми иҷрои код натиҷаи зерин ҳосил мешавад, ки дар он шохасозӣ ва иҷрои дубораи графро равшан мебинед:

Fork continue: {'foo': 'b', 'bar': ['a', 'b']}
Replay: {'foo': 'b', 'bar': ['a', 'b']}

Фазоҳои ном ва қабати хидматии хотира

Мафҳуми дигари муҳим фазои ном (namespace) аст. Ҳамин ки аз як ришта берун меравед, хотира ба масъалаи сатҳи барнома табдил меёбад. Ба шумо роҳе лозим аст, ки хотираро ба корбари дуруст вобаста кунед, навъҳои гуногуни хотираро ҷудо нигоҳ доред ва амалҳои хондан, навиштан ё пок кардани маълумоти сабтшударо дастрас созед. Дар ҳамин ҷо бояд барои идоракунии хотираи агент фазоҳои номро ҷорӣ кунед. Намунаи 12.5 функсияҳои ёрирасони фазои номро татбиқ мекунад, ки хотираро аз рӯи корбар, ташкилот ва навъи хотира ҷудо мекунанд.

Намунаи 12.5. Маҳдуд кардани доираи хотираи дарозмуддат аз рӯи корбар, ташкилот ва навъ

NS_SEMANTIC = "semantic"
NS_EPISODIC = "episodic"
NS_PROCEDURAL = "procedural"
NS_PROFILE = "profile" 
SHARED_SEGMENT = "_shared"

@dataclass(frozen=True)
class AppContext: 
    org_id: str
    user_id: str
    is_admin: bool = False

def ns_user(ctx: AppContext, kind: str) -> tuple[str, str, str]: 
    return (_safe_segment(ctx.org_id), _safe_segment(ctx.user_id), kind)

def ns_org_shared(org_id: str, kind: str) -> tuple[str, str, str]: 
    return (_safe_segment(org_id), SHARED_SEGMENT, kind)

def ns_profile_user(ctx: AppContext) -> tuple[str, str, str]:
    return ns_user(ctx, NS_PROFILE)

Шарҳи код:

  • Номҳои фазоҳои номеро муайян мекунад, ки дар тамоми анбор истифода мешаванд.
  • Заминаи барномаро эълон мекунад, ки барои муайян кардани доираи хотира лозим аст.
  • Барои хотираи хусусии корбар кортежи фазои ном месозад.
  • Барои хотираи муштараки ташкилот кортежи фазои ном месозад.

Дар системаи чандкорбара хотира бояд ҳам аз рӯи корбар ва ҳам аз рӯи навъ ҷудо шавад. Бо ин роҳ далелҳои корбар, рӯйдодҳои пешина ва дастурҳои тартиби амал ба як тӯдаи аз ҳам фарқнашаванда табдил намеёбанд.

Шиносаи корбарро санҷед

Бовар ҳосил кунед, ки user_id аз JWT ё ҷаласаи тасдиқшудаи аутентификатсия гирифта мешавад ва танҳо сатри фиристодаи тарафи муштарӣ нест. Агар user_id аз тарафи муштарӣ ояд, ҳар касе, ки он сатрро сохтакорӣ мекунад, метавонад ба хотира маълумот нависад.

Пас аз ҷудо кардани хотира ба фазоҳои ном, дастрасӣ ба анборро дар қабати хурди хидматӣ фаро гиред. Ин намегузорад, ки хондану навиштани мустақими анбор дар тамоми граф пароканда шавад. Ҳамчунин баъдтар дастрас кардани ҳамин амалҳои хотираро тавассути интерфейси барнома ё API осон мекунад. Намунаи 12.6 қабати сабуки хидматиеро нишон медиҳад, ки амалҳои маъноӣ, рӯйдодӣ ва тартиби амалро пушти як интерфейси устувор муттаҳид мекунад.

Намунаи 12.6. Фарогирии дастрасӣ ба хотира дар қабати хидматӣ

class UserMemoryService:
    def __init__(self, store: BaseStore): 
        self.store = store

    def list_semantic(self, ctx: AppContext, limit: int = 50):
        return semantic_list_items(self.store, ctx, limit=limit) 

    def list_episodic(self, ctx: AppContext, limit: int = 50):
        return episodic_list_items(self.store, ctx, limit=limit) 

    def upsert_semantic(self, ctx: AppContext, key: str,
                        fact: str, extra: dict | None = None) -> None:
        semantic_upsert_fact(self.store, ctx, key, fact, extra) 

    def set_procedural(self, ctx: AppContext, instructions: str) -> None:
        procedural_set_instructions(self.store, ctx, instructions) 

MEMORY = UserMemoryService(STORE)

Шарҳи код:

  • Намунаи муштараки анборро дар объекти хидмат нигоҳ медорад.
  • Гирифтани рӯйхати хотираи маъноиро ба функсияҳои ёрирасони маъноӣ месупорад.
  • Гирифтани рӯйхати хотираи рӯйдодиро ба функсияҳои ёрирасони рӯйдодӣ месупорад.
  • Навиштани хотираи маъноиро ба функсияҳои ёрирасони маъноӣ месупорад.
  • Навсозии тартиби амалро ба функсияҳои ёрирасони дахлдор месупорад.

Дар API-и қабати барнома ин методҳоро тавассути FastAPI ё Next.js дастрас кунед, то корбарон хотираро идора кунанд. Гиреҳҳои агент ҳамон функсияҳои ёрирасонро даъват мекунанд. Ҳамин тавр, як татбиқ доред ва мантиқи қисмҳои гуногун аз ҳам дур намешавад.

Сабтҳои такрориро роҳ надиҳед

Ҳангоми навиштани далелҳо ба хотираи агент нусхаҳои такрориро сарфи назар кунед. Дар акси ҳол, афзалиятҳо ва заминаи такрорӣ аз як ҷаласа то ҷаласаи дигар беохир ҷамъ мешаванд.

Акнун, ки қабатҳои нигоҳдорӣ омодаанд, граф метавонад ҳолати кӯтоҳмуддати checkpointer-ро бо хотираи дарозмуддати анбор якҷо кунад. Натиҷа барномаест, ки ҳам дар дохили як ришта ҳамоҳанг мемонад ва ҳам дониши дахлдорро дар бораи корбар аз як ришта ба риштаи дигар мебарад.

Амалҳои хотираи рӯйдодӣ дар код

Намунаи 12.7. Амалҳои ҷудогонаи хотираи рӯйдодӣ

def episodic_search(store: BaseStore, ctx: AppContext,
                    query: str, *, limit: int = 3):
    return list(
        store.search(ns_user(ctx, NS_EPISODIC), query=query, limit=limit) 
    )

def episodic_record_event(
    store: BaseStore, ctx: AppContext, task: str,
    outcome: str, *, memory_key: str | None = None
) -> str:
    key = memory_key or str(uuid.uuid4()) 
    ts, oc = task.strip(), outcome.strip()
    zw = "\u200c"  # аломати ноаён (zero-width non-joiner): матнро аз калид дар майдони индексшаванда ҷудо мекунад
    store.put(
        ns_user(ctx, NS_EPISODIC),
        key,
        {
            "task": ts,
            "outcome": oc,
            "mem_ix": f"{ts}\n{oc}{zw}key:{key}", 
            "created_at": _utc_now_z(),
        },
    )
    return key

Шарҳи код:

  • Дар фазои номи хотираи рӯйдодӣ воқеаҳои шабеҳи гузаштаро меҷӯяд.
  • Калиди пешниҳодшударо дубора истифода мебарад ё барои рӯйдод UUID-и нав месозад.
  • Аз вазифа, натиҷа ва калид матни индексшавандаи рӯйдодро месозад.
  • Калидеро бармегардонад, ки барои нигоҳдории рӯйдод истифода шудааст.

Амалҳои хотираи маъноӣ дар код

Намунаи 12.8. Амалҳои ҷудогонаи хотираи маъноӣ

def semantic_search(
    store: BaseStore, ctx: AppContext, query: str, *, limit: int = 6
):
    return list(
        store.search(ns_user(ctx, NS_SEMANTIC), query=query, limit=limit) 
    )

def semantic_upsert_fact(
    store: BaseStore,
    ctx: AppContext,
    key: str,
    fact: str,
    extra: dict | None = None,
    *,
    transient: bool = False,
    projection_of: str | None = None,
) -> None:
    text = validate_durable_memory_text(fact) 
    ex = dict(extra or {})
    if projection_of:
        ex.setdefault("source_type", "profile_projection")
        ex["projection_of"] = projection_of
    elif transient or key.startswith(SEMANTIC_TRANSIENT_PREFIX):
        ex.setdefault("source_type", "transient_capture") 

    zw = "\u200c"  # аломати ноаён (zero-width non-joiner): матнро аз калид дар майдони индексшаванда ҷудо мекунад
    payload = {
        "fact": text,
        "mem_ix": f"{text}{zw}key:{key}", 
        "updated_at": _utc_now_z(),
        **ex,
    }
    store.put(ns_user(ctx, NS_SEMANTIC), key, payload)

Шарҳи код:

  • Дар фазои номи хотираи маъноӣ бо матни дархост ва маҳдудияти шумораи натиҷаҳо ҷустуҷӯ мекунад.
  • Матни далелро пеш аз нигоҳдорӣ месанҷад.
  • Агар сабт ба далели аз профил гирифташуда вобаста набошад, онро ҳамчун маълумоти муваққатан сабтшуда аломат мегузорад.
  • Барои сатри анбор матни ягонаи индексшаванда месозад.
  • Маълумоти маъноиро ба фазои номи хотираи маъноии ҳамон корбар менависад.

Амалҳои хотираи тартиби амал дар код

Хотираи тартиби амал дастурҳои рафториеро нигоҳ медорад, ки тарзи кори агентро муайян мекунанд. Намунаи 12.9 функсияҳои ёрирасони сохторёфтаи ин хотираро барои хондан, навиштан ва оғозсозии пешфарз татбиқ мекунад.

Намунаи 12.9. Амалҳои ҷудогонаи хотираи тартиби амал

def procedural_get_item(store: BaseStore, ctx: AppContext):
    return store.get(ns_user(ctx, NS_PROCEDURAL), PROFILE_AGENT_INSTRUCTIONS) 

def procedural_put_structured(store: BaseStore,
                              ctx: AppContext, fields: dict[str, str]) -> None:
    now = _utc_now_z()
    cur = procedural_read_structured(store, ctx) 
    for k in ("style", "workflow", "safety", "task_policies"):
        if k in fields and fields[k] is not None:
            cur[k] = str(fields[k]).strip() 
    cur["updated_at"] = now
    store.put(ns_user(ctx, NS_PROCEDURAL), PROFILE_AGENT_INSTRUCTIONS, cur) 

def procedural_ensure_default(store: BaseStore, ctx: AppContext) -> None:
    if procedural_get_item(store, ctx) is None:
        procedural_set_instructions(
            store,
            ctx,
            "Be concise and helpful. Prefer bullet points for comparisons.",
        )

Шарҳи код:

  • Сабти тартиби амалро аз фазои номи дахлдори корбар мехонад.
  • Пеш аз навсозӣ ҳолати сохторёфтаи ҷории тартиби амалро бор мекунад.
  • Танҳо майдонҳои сохторёфтаи пешниҳодшударо иваз мекунад.
  • Сабти навшудаи тартиби амалро ба анбор менависад.
  • Агар дастури пешина набошад, сабти тартиби амалро бо қиматҳои ибтидоӣ месозад.

Дастури пешфарзи англисии дохили код чунин маъно дорад: «Кӯтоҳ ва муфид ҷавоб деҳ. Барои муқоисаҳо аз рӯйхати нишонадор истифода бурданро авлотар дон».

Намунаи муттаҳид: агенти дорои хотираи маъноӣ, рӯйдодӣ ва тартиби амал

Пас аз баррасии ҷудогонаи хотираи маъноӣ, рӯйдодӣ ва тартиби амал, дидани як намунаи муттаҳид муфид аст. Намунаи 12.10 функсияи хурди ёрирасони иҷро ва пайдарпаии муоширатҳоро байни корбарон, риштаҳо ва доираҳои гуногун нишон медиҳад. Ин намуна ҳолати кӯтоҳмуддат, далелҳои маъноӣ, воқеаҳои рӯйдодӣ, хотираи умумиташкилотӣ, санҷиш тавассути фармонҳо, хулосасозӣ ва фишурдасозии маъноиро ба ҳам мепайвандад.

Намунаи 12.10. Иҷрои агенти дорои хотираи муттаҳид байни риштаҳо ва корбарон

def run_turn(thread: str, org: str, user: str, text: str, *, is_admin: bool = False):
    cfg: RunnableConfig = {"configurable": {"thread_id": thread}} 
    return agent_app.invoke(
        {"messages": [HumanMessage(content=text, id=str(uuid.uuid4()))]}, 
        cfg,
        context=AppContext(org_id=org, user_id=user, is_admin=is_admin), 
    )

ORG = "acme"
USER_A = "alice"
USER_B = "bob"
THREAD = "demo-thread-1"

run_turn(THREAD, ORG, USER_A,
         "remember: I use dark mode and prefer US English") 
run_turn(THREAD, ORG, USER_A,
         "episode: billing dispute | issued pro-rata credit after tier mismatch") 
out = run_turn(THREAD, ORG, USER_A, "What preferences should the UI use?")
print(out["messages"][-1].content[:600])

run_turn(
    THREAD,
    ORG,
    USER_A,
    """Company policy: customer-facing answers must include
    the disclaimer 'Prices may change.'""",
    is_admin=True, 
)

out2 = run_turn("demo-thread-2", ORG, USER_B,
                "What is our customer-facing disclaimer rule?") 
print("--- new thread (Bob) ---")
print(out2["messages"][-1].content[:600])

print(run_turn(THREAD, ORG, USER_A,
      "/memory list")["messages"][-1].content[:1200]) 
run_turn(THREAD, ORG, USER_A, "/thread summarize") 
run_turn(THREAD, ORG, USER_A, "remember: I want metric units everywhere")
run_turn(THREAD, ORG, USER_A, "/memory compact") 
print(run_turn(THREAD, ORG, USER_A, "/memory list")["messages"][-1].content[:1200])

Шарҳи код:

  • Барои иҷро бо нуқтаҳои назоратӣ танзимоти дорои шиносаи ришта месозад.
  • Вуруди корбарро ба HumanMessage табдил медиҳад ва барои паём шиноса месозад.
  • Заминаи барномаро медиҳад, ки барои қарорҳои марбут ба фазои ном ва иҷозати дастрасӣ истифода мешавад.
  • Навиштани хотираи маъноиро тавассути ҷараёни ягонаи агент мефиристад.
  • Навиштани хотираи рӯйдодиро тавассути ҳамон ҷараёни агент мефиристад.
  • Навбати муоширатро дорои иҷозати маъмурӣ аломат мегузорад, то хотираи умумиташкилотӣ сабт шавад.
  • Барои корбари дигар дар ҳамон ташкилот риштаи нав оғоз мекунад.
  • Фармони бо / оғозшавандаро даъват мекунад, ки ҳолати ҷории хотираро рӯйхат мекунад.
  • Матни суҳбати риштаи фаъолро бо шакли хулосашуда иваз мекунад.
  • Сабтҳои хотираи маъноиро ба як намоиши муттаҳид фишурда мекунад.

Иҷрои код амалҳои гуногунро нишон медиҳад. Он афзалиятҳои системаро муқаррар мекунад: масалан, истифодаи намуди торики интерфейс ва намоиши муҳтаво бо англисии амрикоӣ. Дар хотираи рӯйдодӣ сабт мешавад, ки баҳси ҳисоббаробаркунӣ ба миён омада буд ва пас аз ошкор шудани номувофиқии сатҳи тарофа, ба ҳисоби муштарӣ маблағи мутаносиб ворид карда шуд. Дар хотираи тартиби амал система дар хотир медорад, ки бояд кӯтоҳ ва муфид бошад ва барои муқоисаҳо аз рӯйхати нишонадор истифода кунад.

Маънои паёмҳои намунавии код: «Дар хотир дор: ман намуди торикро истифода мебарам ва англисии амрикоиро меписандам»; «Рӯйдод: баҳси ҳисоббаробаркунӣ | пас аз номувофиқии сатҳи тарофа маблағи мутаносиб ба ҳисоб гузаронида шуд»; «Интерфейс бояд кадом афзалиятҳоро истифода барад?»; «Қоидаи ширкат: ҷавобҳои ба муштарӣ пешниҳодшаванда бояд огоҳии “Нархҳо метавонанд тағйир ёбанд”-ро дар бар гиранд»; «Қоидаи огоҳии мо барои муштариён чист?»; «Дар хотир дор: мехоҳам дар ҳама ҷо воҳидҳои метрӣ истифода шаванд».

Сериализатсия, рамзгузорӣ ва заҳролудсозии хотира

Хотираи пойдорро бояд на танҳо пеш аз навиштан санҷид, балки ҳифз ҳам кард. Ин махсусан вақте муҳим аст, ки нуқтаҳои назоратӣ заминаи ҳассоси корбар, ҳолати мобайнӣ ё натиҷаҳои абзорҳоро дошта метавонанд. Намунаи 12.11 нишон медиҳад, ки сериализатори рамзгузоришударо чӣ гуна ба checkpointer пайваст кунед. Ин механизми нигоҳдории нуқтаҳои назоратиро васеъшаванда нигоҳ медорад ва ҳангоми мавҷуд будани калиди дуруст истифодаи сериализатори дорои рамзгузориро имконпазир месозад.

Намунаи 12.11. Истифодаи сериализатори рамзгузоришуда барои нигоҳдории нуқтаҳои назоратӣ

from langgraph.checkpoint.serde.base import CipherProtocol
from langgraph.checkpoint.serde.encrypted import EncryptedSerializer

print("Extensibility:", CipherProtocol, "->", EncryptedSerializer)
key_hex = os.getenv("LANGGRAPH_AES_KEY", "") 

if len(key_hex) == 64 and re.fullmatch(r"[0-9a-fA-F]+", key_hex): 
    try:
        serde = EncryptedSerializer.from_pycryptodome_aes() 
        enc_cp = InMemorySaver(serde=serde) 

        g = StateGraph(PS)
        g.add_node(node_a)
        g.add_node(node_b)
        g.add_edge(START, "node_a")
        g.add_edge("node_a", "node_b")
        g.add_edge("node_b", END)

        enc_graph = g.compile(checkpointer=enc_cp) 
        enc_graph.invoke({"foo": "", "bar": []},
                        {"configurable": {"thread_id": "encrypted-demo"}})
        print("Encrypted checkpointer round-trip: OK") 
    except Exception as exc:
        print("Encrypted demo skipped:", exc)
else:
    print("""Set LANGGRAPH_AES_KEY (64 hex chars) to
          exercise EncryptedSerializer.from_pycryptodome_aes().""")

Шарҳи код:

  • Калиди рамзгузориро аз муҳит мехонад.
  • Мавҷудияти калид ва мувофиқати онро ба шакли шонздаҳии интизоршаванда месанҷад.
  • Сериализатори рамзгузоришударо бар асоси AES месозад.
  • Сериализаторро ба checkpointer медиҳад.
  • Графро бо checkpointer-и рамзгузоришуда компилятсия мекунад.
  • Як даври навиштану хонданро аз роҳи нуқтаҳои назоратии рамзгузоришуда иҷро мекунад.

Заҳролудсозии хотира танҳо тазриқи дастур ба промпт нест

Мақолаи «Аз вуруди беэътимод то хотираи боэътимод» (From Untrusted Input to Trusted Memory) нишон медиҳад, ки чаро заҳролудсозии хотира ба модели алоҳидаи таҳдид ниёз дорад. Хатар фақат дар он нест, ки агент як бор дастури зараровареро мебинад. Хатар ҳамчунин дар он аст, ки муҳтавои беэътимод ба хотира навишта мешавад ва баъдтар ҳамчун заминаи боэътимод бармегардад. Мақола барои озмоиши ҳамлаҳои заҳролудсозии хотира MPBench-ро муаррифӣ карда, як қонунияти муҳимро нишон медиҳад: агентҳое, ки маълумотро ба хотира бисёр менависанд ва аз он зиёд бозмеёбанд, метавонанд барои ҳамла осонтар шаванд. Ҳимояҳои мавҷуда аз тазриқи дастур ба промпт низ ин мушкилро пурра фаро намегиранд, зеро ҳамла аз промпт ба ҳолати пойдори агент мегузарад.

Хулосасозии риштаи фаъол дар код

Намунаи 12.12 усули нигоҳубини хотираи кӯтоҳмуддатро татбиқ мекунад: матни тӯлонии суҳбатро бо паёми мухтасари хулосавӣ иваз мекунад. Ин афзоиши ҳолатро дар дохили як ришта кам мекунад ва ҳамзамон қарорҳо ва афзалиятҳои корбарро, ки барои навбатҳои ояндаи муошират муҳиманд, нигоҳ медорад.

Намунаи 12.12. Хулосасозӣ ва фишурда кардани риштаи фаъол

def summarize_thread_messages(
    messages: list[BaseMessage],
    *,
    drop_command: HumanMessage | None = None,
) -> dict:
    msgs = _ensure_msg_ids(list(messages)) 
    body = [m for m in msgs if m is not drop_command] 
    transcript = (chr(10)).join(
                  f"{m.type}: {m.content}" for m in body if isinstance(
                   getattr(m, "content", None), str)
                  ) 
    summary = memory_llm.invoke( 
        [
            SystemMessage(
                content=(
                    """Summarize the conversation for future context in
                    <=8 bullet points. Preserve user preferences and
                    decisions. No preamble."""
                )
            ),
            HumanMessage(content=transcript),
        ]
    ).content
    removes = [RemoveMessage(id=m.id) for m in msgs if m.id] 
    new_human = HumanMessage(
        id=str(uuid.uuid4()),
        content="Prior conversation (summarized):" + chr(10) + str(summary), 
    )
    return {"messages": removes + [new_human]}

Шарҳи код:

  • Пеш аз сохтани фармонҳои хориҷкунӣ бовар ҳосил мекунад, ки ҳамаи паёмҳо шиноса доранд.
  • Худи фармони хулосасозиро аз муҳтавое, ки хулоса мешавад, хориҷ мекунад.
  • Паёмҳои боқимондаи риштаро ба як сатри матнии суҳбат табдил медиҳад.
  • Модели хотираро барои сохтани хулосаи мухтасари суҳбат даъват мекунад.
  • Барои паёмҳои мавҷуда амалҳои RemoveMessage месозад.
  • Хулосаро дар HumanMessage-и ҷойгузин мегузорад.
  • Навсозиеро бармегардонад, ки паёмҳои кӯҳнаро хориҷ карда, паёми хулосаро мегузорад.

Дастури хулосасозии дохили код чунин аст: «Суҳбатро барои заминаи оянда дар на бештар аз 8 банди нишонадор хулоса кун. Афзалиятҳо ва қарорҳои корбарро нигоҳ дор. Муқаддима нанавис». Матни паёми ҷойгузин маънои «Суҳбати пешина — хулосашуда»-ро дорад.

Нигоҳубини хотираи дарозмуддат дар код

Намунаи 12.13 фишурдасозии хотираи дарозмуддатро татбиқ мекунад: сабтҳои хурди сершумори маъноиро ба як намоиши муттаҳид мепайвандад. Ин вақте муфид аст, ки хотираи маъноӣ пур аз маълумоти нолозим, такрорӣ ё аз ҳад пора-пора мешавад ва ворид кардани самараноки он ба замина душвор мегардад.

Намунаи 12.13. Фишурда кардани хотираи маъноӣ ба як сабти муттаҳид

def semantic_compact_consolidated(
    store: BaseStore, ctx: AppContext, llm, *, list_limit: int = 200
) -> tuple[str, int]:
    items = semantic_list_items(store, ctx, limit=list_limit) 
    if not items:
        return "No semantic memories to compact.", 0

    nl = chr(10)
    facts = nl.join(f"- ({it.key}) {it.value.get('fact', it.value)}"
                    for it in items)
    merged = llm.invoke( 
        [
            SystemMessage(
                content=(
                    """Merge these user-specific facts into one structured
                        profile (markdown bullets). De-duplicate aggressively.
                        Drop stale contradictions keeping the newest updated_at
                        if present."""

                )
            ),
            HumanMessage(content=facts),
        ]
    ).content

    zw = "\u200c"  # аломати ноаён (zero-width non-joiner): матнро аз калид дар майдони индексшаванда ҷудо мекунад
    m = str(merged)
    store.put(
        ns_user(ctx, NS_SEMANTIC),
        CONSOLIDATED_KEY, 
        {
            "fact": merged,
            "mem_ix": f"{m[:6000]}{zw}key:{CONSOLIDATED_KEY}",
            "updated_at": _utc_now_z(),
            "source": "compact",
        },
    )

    deleted = 0
    for it in items:
        if it.key == CONSOLIDATED_KEY:
            continue
        store.delete(tuple(it.namespace), it.key) 
        deleted += 1

    return str(merged), deleted

Шарҳи код:

  • Сабтҳои хотираи маъноиро, ки номзади фишурдасозӣ мебошанд, бор мекунад.
  • Сабтҳои ҷории маъноиро барои муттаҳидсозӣ ба як блоки матнӣ табдил медиҳад.
  • Моделро барои муттаҳидсозӣ ва нест кардани такрорҳо даъват мекунад.
  • Натиҷаи якҷошударо зери калиди хотираи маъноии муттаҳид нигоҳ медорад.
  • Пас аз навиштани сабти муттаҳид, сабтҳои пешинаи маъноиро пок мекунад.
  • Матни муттаҳидшударо ҳамроҳи шумораи сабтҳои покшуда бармегардонад.

Дастури дохили код чунин маъно дорад: «Ин далелҳои марбут ба корбарро ба як профили сохторёфта, дар шакли бандҳои Markdown, муттаҳид кун. Такрорҳоро то ҳадди имкон хориҷ кун. Зиддиятҳои кӯҳнаро бартараф соз ва агар updated_at мавҷуд бошад, маълумоти навтаринро нигоҳ дор». Агар маълумоте барои фишурдасозӣ набошад, паём мегӯяд: «Хотираи маъноие барои фишурдасозӣ нест».

Намунаи 12.14 санҷиши пеш аз навиштани хотираи пойдорро татбиқ мекунад. Ин барои пешгирӣ аз сабт шудани муҳтавои ошкоро ҳассос ё нодурустсохтор ба анбори дарозмуддат ёрӣ медиҳад.

Намунаи 12.14. Санҷиши муҳтавои хотираи пойдор пеш аз нигоҳдорӣ

def validate_durable_memory_text(
    text: str, *,
    max_chars: int = MEMORY_CONTENT_MAX_CHARS) -> str:
    t = (text or "").strip() 

    if len(t) > max_chars:
        raise ValueError(f"Memory content exceeds max length ({max_chars}).") 
    if re.search(r"\b\d{3}-\d{2}-\d{4}\b", t):
        raise ValueError("Refusing possible SSN-like pattern in durable memory.") 
    if re.search(r"\b(?:\d[ -]*?){13,19}\b", re.sub(r"\s+", " ", t)):
        raise ValueError("""Refusing possible payment-card-like
                         digit run in durable memory.""")
    low = t.lower()
    if "-----begin" in low and "private key" in low:
        raise ValueError("Refusing possible PEM private key material.")
    if re.search(r"\bAKIA[0-9A-Z]{16}\b", t):
        raise ValueError("Refusing possible AWS access key ID in durable memory.")
    if re.search(r"\bsk-[A-Za-z0-9]{20,}\b", t):
        raise ValueError("Refusing possible API secret pattern in durable memory.")
    return t

Шарҳи код:

  • Матни воридшавандаи хотираро пеш аз санҷиш ба шакли яксон меорад.
  • Сабтҳоеро рад мекунад, ки аз маҳдудияти танзимшудаи ҳаҷм калонтаранд.
  • Муҳтавоеро рад мекунад, ки ба қолабҳои маълуми маълумоти ҳассос мувофиқат мекунад.
  • Агар ҳамаи санҷишҳо гузаранд, матни санҷидашударо бармегардонад.

Паёмҳои хато дар код аз зиёд будани дарозии муҳтаво ё аз эҳтимоли мавҷуд будани рақами суғуртаи иҷтимоии ИМА — SSN, рақами корти пардохтӣ, калиди хусусии PEM, шиносаи калиди дастрасии AWS ё сирри API хабар медиҳанд ва нигоҳдории онҳоро рад мекунанд.

Намунаи 12.15 ҳангоми татбиқи навсозиҳо чанд қоидаи нигоҳубини хотираи дарозмуддатро амалӣ мекунад: бартараф кардани зиддиятҳо, ивазкунӣ аз рӯи гурӯҳ, пешгирӣ аз такрор, ҳадди ақали эътимод ва маҳдудияти шумораи далелҳо.

Намунаи 12.15. Татбиқи навсозиҳои сохторёфта бо назорати зиддиятҳо ва такрорҳо

def apply_updates(
    current_memory: dict[str, Any],
    update: MemoryUpdateOutput,
    *,
    fact_confidence_threshold: float = 0.7,
    max_facts: int = 100,
    thread_id: str | None = None,
) -> dict[str, Any]:
    mem = copy.deepcopy(current_memory)
    mem.setdefault("facts", []) 

    remove = set(update.factsToRemove) 
    for nf in update.newFacts:
        remove.update(x for x in (nf.supersedes_fact_ids or []) if x)
    if remove:
        mem["facts"] = [f for f in mem.get("facts",
                       []) if f.get("id") not in remove] 

    replace_cats: set[str] = set()
    for nf in update.newFacts:
        c = (nf.category or "context").strip().lower() or "context"
        if CATEGORY_COMBINE_MODE.get(c, "accumulate") == "replace":
            replace_cats.add(c)
    if replace_cats:
        mem["facts"] = [
            f
            for f in mem.get("facts", [])
            if str(f.get("category",
            "context") or "context").strip().lower() not in replace_cats
            ] 

    existing_keys = {
        k for k in (_fact_key(str(
        f.get("content", ""))) for f in mem.get("facts", [])) if k
        } 

    for fact in update.newFacts:
        conf = _coerce_confidence(fact.confidence, 0.5)
        if conf < fact_confidence_threshold:
            continue 
        content = fact.content.strip()
        if not content:
            continue
        fk = _fact_key(content)
        if fk and fk in existing_keys:
            continue 
        mem.setdefault("facts", []).append(
            {
                "id": f"fact_{uuid.uuid4().hex[:10]}",
                "content": content,
                "confidence": conf,
            }
        ) 

    facts = mem.get("facts", [])
    if len(facts) > max_facts:
        mem["facts"] = sorted(
            facts, key=lambda f: _coerce_confidence(
            f.get("confidence"), 0.0), reverse=True
            )[:max_facts] 

    return mem

Шарҳи код:

  • Агар рӯйхати далелҳо ҳанӯз набошад, онро месозад.
  • Аз шиносаҳои далелҳое оғоз мекунад, ки ошкоро барои хориҷкунӣ нишон дода шудаанд.
  • Пеш аз илова кардани далелҳои нав, далелҳои ивазшударо хориҷ мекунад.
  • Далелҳои кӯҳнаи гурӯҳҳоеро хориҷ мекунад, ки барои онҳо ҳолати ивазкунӣ танзим шудааст.
  • Барои ошкор кардани такрорҳо калидҳои матнии яксоншуда месозад.
  • Далелҳои наверо, ки ба ҳадди ақали эътимод намерасанд, сарфи назар мекунад.
  • Далелҳои наверо, ки калиди матнии яксоншудаашон аллакай мавҷуд аст, сарфи назар мекунад.
  • Далели нави қабулшударо ба хотира илова мекунад.
  • Рӯйхати далелҳоро то ҳадди аксари танзимшуда кӯтоҳ мекунад.

Хатари такрор шудани шиносаҳо

Дар системаҳои хеле калон истифодаи сатрҳои шонздаҳии кӯтоҳшуда, монанди uuid.uuid4().hex[:10], аз ҷиҳати назариявӣ метавонад ба якхела баромадани шиносаҳо оварда расонад. Барои анборҳои алоҳидаи хотира ин одатан мушкил нест, аммо ҳангоми афзоиш то миллионҳо сабт ин интихобро бояд зери назорат гирифт.

Қарор дар бораи нигоҳдории хотира хароҷоти иловагии ҳамзамон дорад

Агар барои муайян кардани он ки «оё инро бояд дар хотира нигоҳ дошт?» аз LLM истифода баред, дар ҳар қадами агент як даъвати иловагии ҳамзамони LLM анҷом мешавад. Танҳо дар як даври одии панҷқадамаи ReAct ин маънои панҷ даъвати пинҳонии иловагиро танҳо барои идоракунии хотира дорад. Шумораи даъватҳои LLM-ро ду баробар кардаед, вале касе инро намебинад, зеро он ба зерсохтор тааллуқ дорад, на ба мулоҳиза.

Равиши асосёфта ба ифодаҳои мунтазам — regex — ё қоидаҳо аз ин хароҷот пурра канорагирӣ мекунад: қолабҳое монанди номҳои ашхосу ташкилотҳо, афзалиятҳои ошкори корбар ва натиҷаҳои сохторёфтаро ҷустуҷӯ карда, онҳоро мувофиқи қоидаҳои муайян сабт кунед. Ин равиш дар ҳолатҳои ғайримаъмул осебпазир аст, аммо барои LLM хароҷоти иловагӣ надорад, таъхири иловагӣ намеорад ва пешгӯишаванда аст. Шумо дақиқ медонед, ки чӣ ва барои чӣ нигоҳ дошта мешавад.

Ҷадвали 12.5 мувозинати байни дақиқӣ ва хароҷоти равишҳои гуногуни нигоҳдории хотираро ба таври умум нишон медиҳад.

Ҷадвали 12.5. Муқоисаи равишҳои нигоҳдории хотира

РавишДаъватҳои иловагӣДақиқӣХароҷот
Regex / қоидаҳо0Тақрибан 70%Ройгон
Монандии намоишҳои векторӣ0, аммо ҳисоббарории модел дар GPU лозим астТақрибан 85%Кам
Таснифгари хурд, танҳо рамзгузор — encoder-only0, аммо ҳисоббарории модел дар GPU лозим астТақрибан 90%Кам то миёна
LLM-и мукаммал ҳамчун доварДар ҳар қадам 1 даъвати LLMТақрибан 95%Ҳисоби хароҷотро ду баробар мекунад

Майли ба LLM супурдани саволи «чиро дар хотир нигоҳ дорам?» ҳамон майлест, ки агентҳоро дар дигар ҷойҳо низ гарон мекунад. Бо вуҷуди ин, моделҳои ҳамандозаи BERT барои баҳодиҳии мувофиқати маълумот ба хотира метавонанд арзон, зуд ва дар бисёр ҳолатҳо муфид бошанд. Пас аз regex, LLM-и мукаммал метавонад қадами осонтари навбатӣ намояд, зеро сатҳи миёна каме кори бештари зерсохторӣ мехоҳад. Бо ин ҳама, равиши зинавӣ аксаран қисми зиёди фоидаи амалиро бо ҳиссаи хурди хароҷот медиҳад: regex барои додаҳои сохторёфта, монандии векторӣ барои мувофиқати бозёбӣ, таснифгарҳои танҳо рамзгузор барои қарорҳои сабуки хотира ва LLM-довар танҳо барои ҳолатҳои номуайяни дорои аҳамияти баланд.

Намунаи 12.16 гузариши мувофиқсозиро бо қоидаҳои қатъӣ татбиқ мекунад. Он барои қолабҳои маълуми зиддият далелҳои кӯҳнатари ба ҳам мухолифи профилро хориҷ мекунад.

Намунаи 12.16. Хориҷ кардани далелҳои кӯҳнаи зиддиятнок бо қоидаҳои қатъӣ

def deterministic_reconcile_profile_facts(memory: dict) -> dict:
    mem = copy.deepcopy(memory)
    facts = [f for f in (mem.get("facts") or []) if isinstance(f, dict)]
    to_remove: set[str] = set() 

    pairs = [
        (
            re.compile(r"\b(dark mode|dark theme|dark ui)\b", re.I),
            re.compile(r"\b(light mode|light theme|light ui)\b", re.I),
        ),
    ] 

    for i, fa in enumerate(facts):
        for j, fb in enumerate(facts):
            if j <= i:
                continue
            for pa, pb in pairs:
                if pa.search(str(fa.get(
                    "content", ""))) and pb.search(str(fb.get("content", ""))):
                    ia = _parse_iso_utc(fa.get(
                         "updatedAt")) or _parse_iso_utc(fa.get("createdAt"))
                    ib = _parse_iso_utc(fb.get(
                         "updatedAt")) or _parse_iso_utc(fb.get("createdAt"))
                    older = fb if ia and ib and ib < ia else fa 
                    oid = older.get("id")
                    if oid:
                        to_remove.add(str(oid)) 

    if to_remove:
        mem["facts"] = [f for f in facts if str(f.get("id")) not in to_remove] 
    return mem

Шарҳи код:

  • Маҷмӯаеро месозад, ки шиносаҳои барои хориҷкунӣ нишондодашударо ҷамъ мекунад.
  • Қолабҳои зиддиятро муайян мекунад, ки ҳангоми мувофиқсозӣ санҷида мешаванд.
  • Бо истифода аз вақтҳои мавҷуда далели кӯҳнатарро интихоб мекунад.
  • Шиносаи далели кӯҳнатарро ба маҷмӯаи хориҷкунӣ илова мекунад.
  • Рӯйхати далелҳоро бе сабтҳои ишорашуда аз нав месозад.

Дар код зиддияти афзалияти намуди торик ва намуди равшани интерфейс санҷида мешавад.

Топологияҳои хотира ва зер агентҳо: тафсилот ва код

Ҳар топология барои ҳамоҳангсозӣ, самаранокӣ ва рафтори система натиҷаҳои гуногун дорад. Бартариҳо ва маҳдудиятҳои муҳимтарин чунинанд.

Хотираи маҳаллии ҳар агент

Дар ин тарҳ ҳар агент хотираи худро мустақилона нигоҳ медорад. Одатан ин бо маҳдуд кардани хотира ба худи агент амалӣ мешавад: масалан, тавассути фазоҳои номи махсуси агент ё анборҳои ҷудогона. Бартарии ин равиш модулӣ будани он аст. Ҳар агент бо заминаи тоза ва мутамарказ кор мекунад ва ҳолати номарбути агентҳои дигар ба он таъсир намерасонад. Ин маълумоти нолозимро кам карда, истифодаи равзанаи заминаро самаранок нигоҳ медорад. Аммо ҷудосозӣ арзиши худро дорад. Агентҳо метавонанд бо мурури замон аз ҳам дур шуда, дар бораи ҳамон система ё вазифа тасаввуроти дохилии ба ҳам номувофиқ пайдо кунанд. Дониш такрор мешавад ва ҳамоҳангсозӣ душвортар мегардад.

Хотираи умумии муштарак

Дар тарҳи хотираи муштарак ҳамаи агентҳо аз як анбор мехонанд ва ба он менависанд. Ин дар тамоми система як манбаи ягонаи ҳақиқат ба вуҷуд меорад. Агентҳо метавонанд ба далелҳои муштарак, қарорҳои пешина ва ҳолати умумӣ дастрасӣ дошта бошанд, ки мулоҳиза ва ҳамоҳангсозии мувофиқро имконпазир мекунад. Аммо ин равиш мушкилоти нав ҳам меорад. Хотираи муштарак метавонад зуд аз маълумоти нолозим пур шавад, зеро агентҳои гуногун навъҳои гуногуни маълумот илова мекунанд. Бе полоиши қатъӣ агентҳо аз зарурат бештар замина мегиранд. Ин сифати маълумоти муфидро паст карда, аз ҳисоби аз ҳад калон шудани равзанаи замина истифодаи токенҳоро зиёд мекунад. Илова бар ин, ҳамзамонсозӣ мураккабтар мешавад. Хондану навиштани ҳамзамон коркарди бодиққат мехоҳад, то зиддият ва ҳолати номувофиқ ба вуҷуд наояд. Хотираи умумӣ мувофиқатро беҳтар мекунад, аммо аксаран аз ҳисоби самаранокӣ ва равшанӣ.

Меъмории омехтаи хотира

Аксари системаҳои истеҳсолӣ равиши омехтаеро истифода мебаранд, ки хотираи маҳаллӣ ва муштаракро ба ҳам меорад. Ҳар агент барои мулоҳиза, ҳолати мобайнӣ ва заминаи махсуси вазифа хотираи маҳаллии худро нигоҳ медорад. Қабати муштараки хотира бошад, дастрасӣ ба дониши сатҳи система, далелҳои пойдор ва сабтҳои ҳамоҳангсозиро таъмин мекунад. Ин барои қолабҳои гуногуни системаҳои чанд агентӣ муфид аст. Дар системаҳои дорои нозир агенти ҳамоҳангсоз метавонад ба натиҷаҳои хулосашудаи зер агентҳои тахассусӣ ниёз дошта бошад. Дар гурӯҳҳои ҳамсатҳ агентҳо метавонанд бозёфтҳои интихобшуда ё натиҷаҳои қисмиро бо ҳам мубодила кунанд. Дар системаҳои тӯдашакл аксаран қадами алоҳидаи ҷамъбаст ё фишурдасозӣ лозим аст, то натиҷаҳои сершумори маҳаллӣ ба шакле оварда шаванд, ки қисми боқимондаи система воқеан аз он истифода карда тавонад.

Мафҳумҳои агентӣ аз чаҳорчӯба вобаста нестанд

Ин мафҳумҳо танҳо ба LangGraph хос нестанд. Ҳар чаҳорчӯбаи агентӣ ё ҳамоҳангсози фармоишӣ ҳамин ғояҳоро тавассути мафҳумҳои абстрактии гуногун татбиқ мекунад: нигоҳдории ҳолат, маҳдуд кардани доираи хотира ва қабатҳои ҳамоҳангсозӣ.

Дар системаҳои чанд агентӣ яке аз муҳимтарин қарорҳои тарҳрезӣ ин аст, ки оё агенти мутахассис чизеро байни даъватҳо дар хотир нигоҳ медорад ё не. Ин масъала аз он ки чӣ гуна маълумот дар хотира сабт мешавад, мустақил аст. Он муайян мекунад, ки мутахассис мисли даъвати нави абзор рафтор мекунад ё мисли агенти пойдоре, ки дар тӯли вақт пайвастагии худро дорад. Ҷадвали 12.6 се ҳолати асосии нигоҳдории ҳолатро муқоиса мекунад. Ба таври сода: зер агенти бе хотира мисли ҳисобкунак (калкулятор) аст — ҳар дафъа аз нав ҳисоб мекунад ва чизе дар ёд намегузорад; зер агенти per-thread мисли дафтарча аст, ки ҳар навбат ба ёддоштҳои пешина илова мешавад.

Ҷадвали 12.6. Ҳолатҳои нигоҳдории ҳолат ва рафтори агент

ҲолатРафтори хотираРафтори агент
Барои ҳар даъват — Per-invocation (None)Байни даъватҳо хотира надорадМисли функсияи беҳолат амал мекунад
Барои ҳар ришта — Per-thread (True)Хотира байни даъватҳо ҷамъ мешавадМисли агенти пойдори дорои таърих амал мекунад
Беҳолат — Stateless (False)Нигоҳдории пойдор ё барқарорсозӣ надорадТанҳо иҷро; бе таваққуфҳои идорашаванда ё нигоҳдории ҳолат

Намунаҳои 12.17 то 12.19 тарҳи хурди омехтаеро бо ҳамоҳангсоз ва мутахассиси дохилии ҳисоббаробаркунӣ нишон медиҳанд. Ҳамоҳангсоз ба иҷрокунанда танҳо навбати ҷории муоширатро медиҳад. Ин заминаи иҷрокунандаро ҷудо нигоҳ медорад. Дар системаҳои чанд агентӣ ин муҳим аст, зеро фиристодани тамоми таърихи агенти болоӣ маълумоти нолозим ворид мекунад. Ягона фарқ байни се иҷро ҳолати нигоҳдории хотираи иҷрокунанда мебошад.

Зерграфҳои дохилӣ

Ин мафҳуми умумӣ буда, танҳо ба LangGraph хос нест. LangGraph онро тавассути параметри checkpointer дастрас мекунад. Дар ин ҷо метавонед муайян кунед, ки оё зерграфи шумо — зер агент — дархостҳоро мустақилона коркард мекунад ё не. Ин, масалан, вақте муҳим аст, ки агентҳои барноманависи шумо суҳбати чанднавбатӣ доранд ва бояд фаҳманд, ки кадом файлҳоро аллакай санҷида ё таҳрир кардаанд. Аммо дар хотир доред: checkpointer=True танҳо барои зерграфҳои дохилӣ дуруст аст. Онро барои графи решавӣ истифода бурдан мумкин нест; дар ин ҳолат хато ба вуҷуд меояд.

Намунаи 12.17 агенти бо корбар муошираткунандаро ифода мекунад. Диққат диҳед: он ба иҷрокунанда танҳо навбати ҷориро медиҳад ва тамоми таърихи суҳбатро намефиристад.

Намунаи 12.17. Сохтани ҳолати агенти болоӣ

class ParentState(TypedDict): 
    current_input: str
    answer: str

def make_parent_app(worker_app): 
    def call_worker(state: ParentState, config: RunnableConfig): 
        out = worker_app.invoke(
            {"messages": [HumanMessage(
             content=state["current_input"])]}, 
             config=config, 
        )
        return {"answer": out["messages"][-1].content} 

    builder = StateGraph(ParentState) 
    builder.add_node("call_worker", call_worker)
    builder.add_edge(START, "call_worker")
    return builder.compile(checkpointer=InMemorySaver())

Шарҳи код:

  • Ҳолати ҳадди ақали ҳамоҳангсозро муайян мекунад, ки танҳо вуруди ҷорӣ ва ҷавоби баргаштаро дорад.
  • Графи болоиро месозад, ки даъвати иҷрокунандаро фаро мегирад.
  • Гиреҳеро эълон мекунад, ки навбати ҷориро ба иҷрокунанда мефиристад.
  • Танҳо вуруди ҷориро ба иҷрокунанда медиҳад ва ҷудоии заминаро таъмин мекунад.
  • Аз ҳамон танзимоти иҷро истифода мебарад, то даъвати иҷрокунанда ба риштаи фаъол пайваста монад.
  • Паёми охирини иҷрокунандаро гирифта, ҳамчун ҷавоби агенти болоӣ нигоҳ медорад.
  • Аз схемаи ҳолати ҳамоҳангсоз графи болоиро месозад.
  • Агенти болоиро бо checkpointer компилятсия мекунад, то графи беруна дар доираи ҳар ришта ҳолати пойдор дошта бошад.

Ин тарҳ ҷудоии заминаро таъмин мекунад. Иҷрокунанда танҳо он чизеро мебинад, ки ҳамоҳангсоз ошкоро медиҳад. Баъдан агенти мутахассисро муайян мекунед. Ин агент кӯшиш мекунад, ки заминаро аз таърихи паёмҳои худ барқарор кунад. Намунаи 12.18 ҳамин тарҳро муайян мекунад.

Намунаи 12.18. Муайян кардани ҳолати иҷрокунанда

class WorkerState(TypedDict): 
    messages: Annotated[list, add_messages]

def billing_worker_node(state: WorkerState): 
    human_texts = [
        m.content.lower()
        for m in state["messages"]
        if isinstance(m, HumanMessage) 
    ]

    issue = "duplicate" if any(
        "charged twice" in t for t in human_texts) else None 
    tier = "pro" if any("pro plan" in t for t in human_texts) else None
    action = "refund" if any("refund" in t for t in human_texts) else None

    msg_count = len(state["messages"]) 
    answer = f"Msgs: {msg_count} | Known: {issue}, {tier}, {action}" 
    return {"messages": [AIMessage(content=answer)]}

Шарҳи код:

  • Ҳолати иҷрокунандаро ҳамчун таърихи паёмҳое муайян мекунад, ки бо мурури замон зиёд мешавад.
  • Гиреҳи мутахассисро татбиқ мекунад, ки заминаро аз таърихи дохилии худ барқарор мекунад.
  • Танҳо паёмҳои инсонро интихоб мекунад, то иҷрокунанда ба вурудҳои пешинаи корбар такя кунад, на ба ҷавобҳои худаш.
  • Аз таърихи паёмҳои иҷрокунанда далелҳои одии ҳисоббаробаркуниро ҷудо мекунад.
  • Мешуморад, ки дар ҳолати дохилии худи иҷрокунанда чанд паём дида мешавад.
  • Натиҷаро тавре шакл медиҳад, ки ҳам таърихи намоён ва ҳам дониши нигоҳдоштаро санҷида тавонед.
  • Ҷавоби иҷрокунандаро ба ҳолати паёмҳои худи ӯ илова мекунад.

Дар код ибораи charged twice маънои «маблағ ду бор гирифта шудааст», pro plan маънои «тарофаи Pro» ва refund маънои «баргардондани маблағ»-ро дорад. duplicate мушкили пардохти такрорӣ, tier сатҳи тарофа ва action амали дархостшударо ифода мекунанд.

Иҷрокунанда заминаи умумиро намегирад. Ӯ танҳо он чизеро медонад, ки дар ҳолати паёмҳои худаш мавҷуд аст. Акнун танҳо як чизро тағйир медиҳед: иҷрокунанда ҳолати худро то чӣ муддат дар хотир нигоҳ дорад. Намунаи 12.19 нишон медиҳад, ки ин кор чӣ гуна анҷом меёбад.

Намунаи 12.19. Сохтани иҷрокунанда

def build_worker(mode: str): 
    builder = StateGraph(WorkerState)
    builder.add_node("billing_worker", billing_worker_node)
    builder.add_edge(START, "billing_worker")

    if mode == "per_invocation":
        return builder.compile() 

    if mode == "per_thread":
        return builder.compile(checkpointer=True) 

    if mode == "stateless":
        return builder.compile(checkpointer=False) 

    raise ValueError(f"Unknown mode: {mode}")

Шарҳи код:

  • Ҳамон графи иҷрокунандаро месозад ва танҳо ҳолати нигоҳдории маълумотро тағйир медиҳад.
  • Иҷрокунандаро тавре компилятсия мекунад, ки ҳар даъват аз ҳолати нав оғоз шавад.
  • Иҷрокунандаро ҳамчун зерграфи дохилӣ компилятсия мекунад, ки ҳолати худро байни даъватҳои ҳамон ришта нигоҳ медорад.
  • Иҷрокунандаро бе дастгирии нуқтаҳои назоратӣ компилятсия мекунад.
  • Аз номҳои нодурусти ҳолати нигоҳдорӣ пешгирӣ мекунад.

Ин кори иҷрокунандаро дигар намекунад. Танҳо муайян мекунад, ки ӯ даъватҳои пешинаро дар хотир нигоҳ дорад ё не. Ҳангоми иҷрои коди ин бахш ба ду чиз дар натиҷаҳои дафтари интерактивӣ диққат диҳед:

  • Msgs нишон медиҳад, ки зер агент дар таърихи дохилии худ чанд паём мебинад.
  • Known нишон медиҳад, ки зер агент кадом далелҳоро байни навбатҳои муошират нигоҳ дошта тавонист.

Ҷадвали 12.7 натиҷаҳои кодро нишон дода, муқоиса мекунад. Танҳо зер агенти дорои ҳолати per-thread таърихи дохилии худро байни навбатҳо ҷамъ мекунад. Ҳолатҳои per-invocation ва stateless ҳар дафъа аз нав оғоз мекунанд. Аз ин рӯ, онҳо танҳо он чизеро медонанд, ки дар вуруди ҷорӣ ҳаст. Дар намунаҳои одӣ stateless ва per-invocation аз берун монанд менамоянд. Аммо stateless имкониятҳои вобаста ба нуқтаҳои назоратиро низ аз байн мебарад: масалан, таваққуфҳои идорашаванда — интизори вуруди корбар мондан дар миёнаи иҷро — ва барқарорсозӣ аз ҳолати пойдор.

Ҷадвали 12.7. Муқоисаи натиҷаҳои код

ҲолатНавбати 1Навбати 2Навбати 3
Барои ҳар даъват — Per-invocationАз пардохти такрорӣ хабар дорадPro-ро медонад ва пардохти такрориро фаромӯш мекунадБаргардондани маблағро медонад ва ҷузъиёти пешинаро фаромӯш мекунад
Барои ҳар ришта — Per-threadАз пардохти такрорӣ хабар дорадҲам пардохти такрорӣ ва ҳам Pro-ро медонадПардохти такрорӣ, Pro ва баргардондани маблағро медонад
Беҳолат — StatelessАз пардохти такрорӣ хабар дорадPro-ро медонадБаргардондани маблағро медонад

Дар ин намунаи хотираи омехта ҳамоҳангсоз заминаи маҳдуд ва идорашавандаро нигоҳ медорад, дар ҳоле ки иҷрокунанда метавонад, вобаста ба интихоб, пайвастагии маҳаллии худро ҳифз кунад. Дар системаҳои чанд агентии шумо ҳамин қарори тарҳрезӣ муайян мекунад, ки зер агент мисли абзори беҳолат рафтор мекунад ё мисли мутахассиси дорои хотираи пойдор.

пешина
аз 17
навбатӣ