Агенттің параллель тармақтарын көз жұмып біріктіруге болмайды
Агенттің параллель тармақтарына әртүрлі merge ережелері керек: фактілер үшін reducer, аудит үшін оқиғалар журналы және шешімдер үшін нақты конфликтілер.

Параллель тармақтар әрқайсысы тапсырманың өз бөлігімен жұмыс істегенде агенттің уақытын үнемдейді. Мәселе біріктіру нүктесінде басталады. Екі тармақ бір объектіні бір уақытта өзгертсе, қарапайым merge жауаптардың келу ретін бизнес логикасына айналдырады. Бұл тиімсіз шешім: желі, кезек және модель кідірісі код шешуі тиіс мәселені шешіп кетеді.
Тармақтары бар агент күйінің өзгеру режимдері үш түрлі. Бір өзгерістерді жинауға болады, кейбірін тек нұсқа сәйкес келгенде қабылдау керек, ал үшіншілері бөлек шешімді талап етеді. Reducer, оқиғалар журналы және нақты конфликт бірін-бірі алмастыратын паттерндер емес, осы үш түрлі жағдайға арналған құралдар. Оларды бір merge_state() ішіне араластырған команда көбіне деректердің үнсіз жоғалуына, сыртқы әрекеттердің қайталануына немесе талдауға келмейтін инциденттерге тап болады.
Бір объект бір сөздікке тең емес
Күй объектісі JSON-ға сериализацияланатындықтан ғана оны қарапайым сөздік деп санауға болмайды. Оның өрістерінің семантикасы әртүрлі, ал бір ғана merge алгоритмі бұл семантиканы сақтай алмайды.
Қаражатты қайтару өтінімін елестетіңіз. Агент параллель түрде саясатты тексеру, төлемді іздеу, тәуекелді бағалау және операторға жауап дайындау тармақтарын іске қосады. Барлығы бір өтінімнің 41-ревизиясын оқиды. Бірнеше секундтан кейін олар мынадай жаңартулар қайтарады:
- саясатты тексеру табылған ережені қосады;
- төлемді іздеу транзакция идентификаторын қосады;
- тәуекел
risk_level = highмәнін қояды; - жауап дайындау тармағы
decision = approveұсынады.
Алғашқы екі өзгеріс тәуелсіз. Оларды мағына жоғалтпай біріктіруге болады. Соңғы екеуін автоматты түрде бірдей түсіндіруге болмайды. Тәуекел деңгейі мақұлдауға тыйым салуы мүмкін, ал жауап тармағының шешімі көбіне толық емес көрініске сүйенеді. Егер reducer өрістерді жай ғана біріктірсе, объект қарама-қайшы күйге түседі. Алгоритм соңғы жаңартуды таңдаса, өтінім қай тармақтың кейін аяқталғанына тәуелді болады.
Өрістерді техникалық string, array немесе object түріне емес, операция сипатына қарай бөлген дұрыс:
- жинақталатын фактілер: сілтемелер, табылған құжаттар, диагностика хабарламалары;
- алмастырылатын мәндер: жеткізу мекенжайы, таңдалған модель, тапсырманың ағымдағы иесі;
- инварианттары бар шешімдер: лимит, төлем күйі, әрекетке рұқсат, есептен шығарылатын сома;
- жанама әсерлер: жіберілген хат, жасалған аударым, шақырылған сыртқы API.
Массив әрдайым жинақталатын, ал жол әрдайым алмастырылатын бола бермейді. Мысалы, status жол сияқты көрінеді, бірақ closed -> approved ауысуына тыйым салынуы мүмкін. approvers тізімі массив сияқты көрінеді, алайда оны жай біріктіру бір келісушіні қайта қосуы ықтимал. Дерек түрі операциялардың үйлесімді екенін көрсетпейді.
LangGraph құжаттамасы механизмді нақты сипаттайды: reducer сол жақтағы жинақталған мән мен оң жақтағы жаңа жаңартуды алады да, күйдің келесі мәнін қайтарады. Reducer көрсетілмесе, жаңарту өрісті қайта жазады. Бұл графтың орындалуына ыңғайлы модель, бірақ ол домендік ережелерді сіз үшін қоспайды.
Reducer тек үйлесімді операциялар үшін қауіпсіз
Reducer-ді жаңартуларды қолдану реті рұқсат етілген нәтижені өзгертпейтін немесе реттілік ережесін әдейі анықтаған жерде қолданған жөн. Агент тармақтары үшін мұны бірнеше мысалмен тексеру жеткіліксіз. Операцияның қасиеттерін тексеру керек.
Параллель күйге арналған жақсы reducer әдетте үш қасиетке ұмтылады: ассоциативтілік, коммутативтілік және идемпотенттілік. Ассоциативтілік жаңартуларды топтастыру нәтиже өзгермейтінін білдіреді. Коммутативтілік тәуелсіз тармақтардың реті маңызды емес екенін көрсетеді. Идемпотенттілік жаңарту қайта жеткізілгенде екінші әсер пайда болмайтынын білдіреді.
Сандарды қосу ассоциативті әрі коммутативті, бірақ идемпотентті емес. Сондықтан орындаушы тайм-ауттан кейін нәтиже жеткізілуін қайталауы мүмкін болса, токендер немесе әрекеттер санауышын old + delta операциясымен ойланбай жаңартуға болмайды. Идентификаторлар жиыны әдетте қолайлырақ: бар элементті қайта қосу жиынды өзгертпейді.
Төменде әр жазбада тұрақты id болуы тиіс дәлелдерді жинайтын reducer берілген:
from typing import Iterable
def merge_evidence(left: list[dict], right: Iterable[dict]) -> list[dict]:
by_id = {item['id']: item for item in left}
for item in right:
existing = by_id.get(item['id'])
if existing is None:
by_id[item['id']] = item
elif existing != item:
raise ValueError(f"evidence id collision: {item['id']}")
return [by_id[item_id] for item_id in sorted(by_id)]
Бұл код жиі еленбейтін маңызды әрекетті орындайды. Ол бір идентификаторы бар екі түрлі жазбаны татуластыруға тырыспайды. Бірдей id әртүрлі мазмұнмен келсе, бұл протокол қатесін, идентификаторды қайта пайдалануды немесе тармақтың толық детерминирленбегенін білдіреді. Жазбалардың бірін үнсіз таңдау merge түріне жасырылған дерек жоғалту болар еді.
Төменде reducer тек кейбір өрістерге орынды болатын күй үлгісі:
state = {
'case_id': 'refund-918',
'revision': 41,
'evidence': [],
'warnings': [],
'payment_id': None,
'risk_level': None,
'decision': None,
'effects': []
}
evidence және warnings үшін идентификаторлар бойынша біріктіруді орнатуға болады. payment_id өрісін бір рет қана жазуға рұқсат берген немесе жаңа мәннің ескі мәнмен сәйкес болуын талап еткен дұрыс. risk_level үшін ереже шкалаға байланысты: деңгейлер шынымен реттелген болса, max reducer-ін қолдануға болады. Бірақ деңгейлер әртүрлі саясаттардан немесе бірдей анықталмаған модельдерден келсе, бұл қауіпті. decision үшін әдетте автоматты reducer болмайды.
Кең тараған қате барлық нәрсені «соңғы жазба жеңеді» қағидасына сыйғызу. Бұл практикалық көрінеді, өйткені код бір жолдан тұрады. Бірақ ол өзгерістің себебін бұрмалайды: соңғы аяқталған тармақ көбірек дерек көрген, басымдығы жоғары немесе шешім қабылдауға өкілетті болған деген сөз емес. last write wins кейбір пайдаланушы қалаулары мен кэштерге жарайды. Агент әрекет жасайтын күй үшін бұл ереже әдепкі баптау емес, нақты атауы бар ерекшелік болуы керек.
CRDT автоматты біріктіру идеясын әрі қарай дамытады: мұндай құрылымдар оптимистік репликацияға есептелген және өздерінің merge ережелері бойынша репликалардың бір күйге келуін қамтамасыз етеді. Бұл жиындар, санауыштар және бірлесіп өңделетін деректер үшін пайдалы. Бірақ CRDT қайтарымды бір уақытта мақұлдап, қаржылық дауды жабуға бола ма екенін түсінбейді. Бұл сұрақ деректер құрылымының математикасында емес, домен ережелерінде жатыр.
Патч пен өзгеріс ниетін шатастырмаңыз
Патч тармақ қалаған соңғы нәтижені қалай көргенін хабарлайды. Оқиға тармақ қандай әрекет ұсынатынын және оны қандай негізге сүйеніп жасағанын көрсетеді. Конфликт кезінде осы айырмашылық нәтижені түсіндіріп, түзете алатыныңызды анықтайды.
Екі жазбаны салыстырыңыз:
{
"decision": "approve"
}
және
{
"event_id": "01JQ2D7W0XK8P7FJ3T9N",
"case_id": "refund-918",
"expected_revision": 41,
"type": "refund_approval_proposed",
"actor": "policy_branch",
"reason_codes": ["within_window", "payment_found"],
"evidence_ids": ["policy-77", "payment-19"]
}
Бірінші нұсқа «неге?» деген сұрақты өшіреді. Екіншісі авторды, ревизияны, ниетті және дәлелдерді сақтайды. Тәуекел тармағы бұғаттауды ұсынғанда, жүйе екі жол мәнін жай ғана соқтығыстырмай, екі ұсынысты салыстыра алады.
Оқиғалар журналы «оқиғалар архитектурасы CRUD-тан заманауи» болғандықтан қажет емес. Ол өзгерістер тарихы талаптың бір бөлігі болғанда керек: аудит, күйді қалпына келтіру, қате шешімді талдау, ереже түзетілгеннен кейін қайта өңдеу немесе бір объектінің бірнеше көрінісі. Мартин Фаулер event sourcing-ті күйдің барлық өзгерістерін оқиғалар тізбегі ретінде сақтау деп сипаттайды. Microsoft бұл миграциялар, схемалар, сұраулар және бәсекелес жазбаларды өңдеу үшін өзіндік құны бар күрделі паттерн екенін ескертеді.
Агент тармақтары үшін журнал екі жағдайда ерекше пайдалы. Біріншісі, объект реттелетін процестен өтсе, мысалы кредит тексерісі, медициналық бағыттау немесе сатып алуды келісу. Екіншісі, тармақ әрекет ұсынса, ал бөлек компонент оны өзекті күйде тексерсе. Екі жағдайда да журнал «не болды?» дегенді ғана емес, «не ұсынылды?» дегенді де сақтайды.
Мұндай журналға арналған ең аз жазба келісімшарты мынадай:
{
"event_id": "evt_8f6b0c1d",
"stream_id": "refund-918",
"expected_version": 41,
"run_id": "run_2026_04_17_031",
"branch_id": "risk_review",
"type": "risk_assessed",
"payload": {
"level": "high",
"reason_codes": ["merchant_mismatch"]
},
"causation_id": "cmd_2a16e9",
"idempotency_key": "run_2026_04_17_031:risk_review:1"
}
expected_version ағынды бұрын өзгерген объектінің үстінен жазудан қорғайды. causation_id оқиғаны қандай команда шақырғанын көрсетеді. idempotency_key қайталанған жеткізуден қорғайды. run_id және branch_id екі параллель іске қосылымды бір тармақтың қайталанған әрекетінен ажыратады.
Журнал reducer-лерді жоймайды. Ол біріктіру орнын өзгертеді. Тармақтар тәуелсіз оқиғаларды append-only ағынға жаза алады, ал проектор ағымдағы көріністі құрады: дәлелдер жиыны, тәуекелдің ағымдағы бағасы, күтіп тұрған конфликтілер. Күй snapshot-ы шындық бар жалғыз орын емес, туынды артефактке айналады.
Конфликт бөлек нәтиже болуы керек
Екі тармақ үйлеспейтін өзгерістер ұсынса, жүйе конфликтіні логтарға жасырып немесе уақыт бойынша жеңімпаз таңдамай, оны дерек ретінде қайтаруы керек.
Кез келген бір мезеттегі жаңартуды конфликт деп атауға болмайды. Екі тармақ әртүрлі сілтемелерді қатар қосып, бөлек өрістерді толтырып немесе әртүрлі дәлелдермен бір шешімді ұсына алады. Конфликт жүйе объект инварианттарын сақтай отырып екі өзгерісті де қабылдай алмаған кезде басталады.
Қайтару өтінімдері үшін инварианттар мынадай болуы мүмкін:
- расталған жоғары тәуекел автоматты мақұлдауға тыйым салады;
- қайтару сомасы расталған төлем сомасынан аспайды;
- ақша нақты жіберілгеннен кейін шешімді өтемдік процестісіз өзгертуге болмайды;
- бір төлемді екі рет қайтаруға болмайды.
merge() орнына классификация функциясы болғаны пайдалы. Ол өзекті күй мен тармақ ұсынысын алып, үш нәтиженің бірін қайтарады: accepted, rejected немесе conflict.
def classify_proposal(current: dict, proposal: dict) -> dict:
if proposal['expected_revision'] != current['revision']:
return {
'status': 'conflict',
'reason': 'stale_revision',
'current_revision': current['revision']
}
if proposal['type'] == 'refund_approval_proposed':
if current.get('risk_level') == 'high':
return {
'status': 'conflict',
'reason': 'approval_conflicts_with_high_risk',
'required_inputs': ['risk_assessment', 'human_override_or_rejection']
}
return {'status': 'accepted'}
return {'status': 'rejected', 'reason': 'unknown_proposal_type'}
Мұндағы conflict сөзі жүйе істен шықты дегенді білдірмейді. Ол автоматтандыру өз өкілеттігінің шегіне жеткенін көрсетеді. Одан әрі жаңа snapshot бойынша қайта бағалау, басымдығы жоғары тармақ, детерминирленген домен ережесі немесе операторға беру қолданылуы мүмкін. Бірақ таңдау протоколда көрінуі керек.
Нақты конфликт модель сапасына да пайдалы. Егер тармақ жоғары тәуекел кезінде үнемі мақұлдауды ұсынса, нақты қате класын көріп, промптты, құралдарды немесе кіріс деректерін түзете аласыз. Код өрісті жай ғана қайта жазса, бұл заңдылық модельдің «ерекше жауаптарының» арасында жоғалады.
Конфликтіні шешуді модельдің өзіне шектеусіз бермеңіз. Модель түсіндірме мәтінін ұсына алады, жетіспейтін дәлелдерді жинай алады немесе даудың түрін жіктей алады. Бірақ ақша лимитін, қолжетімділік ережесін немесе орындалып қойған сыртқы әсерді жалғыз өзі жоймауы тиіс. Мұндай әрекетке құқықты кәдімгі код тексеретін домендік саясат анықтайды.
Нұсқа объектіні қорғайды, бірақ ережені алмастырмайды
Оптимистік нұсқа тек бір сұраққа жауап береді: тармақ оқығаннан кейін объект өзгерді ме? Ол нұсқа сәйкес келгеннің өзінде өзгеріске рұқсат бар ма дегенді айтпайды.
A және B тармақтары 41-ревизияны оқыды делік. A оқиғаны сәтті қосып, ағын 42-ревизияға өтті. B expected_version = 41 мәнімен өз оқиғасын қосуға тырысады. Қойма жазбаны қабылдамайды. Бұл дұрыс: B ескі snapshot негізінде қорытынды жасады.
Одан кейін B-ні механикалық түрде қайталауға болмайды. Алдымен B 42-ревизияны алуы, шешімінің алғышарттары өзгергенін тексеруі және жаңа ұсыныс қалыптастыруы керек. Егер A маңызды емес түсініктеме қосса, B сол әрекетті қайта ұсына алады. Егер A лимитті, күйді немесе тәуекелді өзгертсе, B қорытындысын қайта есептеуі тиіс.
Microsoft құжаттамасында бұл сценарий бір ағынмен қатар жұмыс істеу мысалында талданады: оптимистік бәсекелес қолжетімділікті бақылау оқу сәтінен кейін ағын өзгерсе, append әрекетін қабылдамайды, ал өңдеуші күйді қайта оқып, ережелерді қайта тексеріп, содан кейін ғана операцияны қайталауы керек. Бұл агенттік оркестраторларда жиі кездесетін соқыр retry-ден дұрыс.
Нұсқа бірнеше объект арасындағы конфликтіні де ұстамайды. Мысалы, бір тармақ клиент лимитін резервтейді, ал екіншісі сол лимитті пайдаланатын басқа тапсырысты бір уақытта жасайды. Әр ағынның жергілікті нұсқасы дұрыс болуы мүмкін, бірақ жалпы сома ережені бұзады. Мұндай жағдайда ортақ келісімділік шекарасы бар агрегат, транзакция, резервтеу немесе өтем процесі қажет. Бір JSON құжатына арналған ұқыпты reducer объектілер арасындағы инвариантты шеше алмайды.
Ақауды продакшенге жетпей талдаңыз
Кәдімгі ақау сырттай зиянсыз көрінеді. Команда application объектісін жасап, төрт тармақты іске қосады және әрқайсысына жартылай сөздік қайтаруға рұқсат береді. Оркестратор жаңартуларды дайын болған сайын қолданады. Тесттер өтеді, өйткені stub жауаптары үнемі бір ретпен келеді.
Продакшенде policy_check тармағы бірінші аяқталып, мынаны қайтарады:
{
"status": "approved",
"notes": ["policy permits automatic approval"]
}
Бір секундтан кейін fraud_check тармағы мынаны қайтарады:
{
"status": "manual_review",
"notes": ["device fingerprint mismatch"]
}
Код кәдімгі сөздік жаңартуын қолданады. Келу ретіне қарай соңғы status не approved, не manual_review болады. Әзірлеуші бөлек reducer жазбаса, notes тізімі де ауыстырылады. Орындау журналында екі жауап көрінеді, ал соңғы объектіде біреуі ғана қалады. Кейін хат жіберу тармағы approved күйін оқып, оператор оңай қайтара алмайтын әрекетті орындайды.
Түзету max функциясын жолдық күйлерге қолдану немесе хат жіберер алдында тағы бір кідіріс қосу емес. Келісімшартты өзгерту керек.
- Тексеру тармақтары соңғы
statusмәнін жазбай, фактілер мен ұсыныстар жариялайды. - Бір домендік өңдеуші барлық маңызды фактілерді алып, ауысу ережелерін қолданады.
- Үйлеспейтін ұсыныстар болса, өңдеуші себептері мен дәлелдері бар конфликт объектісін жасайды.
- Сыртқы әрекет тармағы тек бөлек
approval_confirmedоқиғасынан кейін іске қосылады.
Осыдан кейін алғашқы екі тармақ қанша қажет болса, сонша параллель жұмыс істей алады. Олар status жазу құқығы үшін таласпайды. Олар бір иеге тиесілі шешімге кіріс деректерін береді.
Мұндай иенің бөлек микросервис болуы шарт емес. Ол сол workflow ішіндегі функция болуы мүмкін. Маңыздысы, инварианттары бар өрістерді өзгерту құқығы тек соған берілуі керек. Өкілеттіктерді бөлу кездейсоқ патчтың қайтарылмайтын әрекетті іске қосуы мүмкін орындар санын азайтады.
Аралас схема көбіне таза идеологиядан жақсы
Агенттік қолданбалардың көпшілігіне әр қадам үшін толық event sourcing те, бір алып reducer де қажет емес. Практикалық схема үш тәсілді өз шекарасында қолданады.
Қысқа мерзімді техникалық деректерді іске қосылымның кәдімгі күйінде сақтаңыз: аралық үзінділер, іздеу нәтижелері, құралдар трассировкасы, маршрутизаторға арналған уақытша нұсқаулар. Бұл деректерді сақтау саясаты бойынша өшіруге болады, ал ескі snapshot-тың жоғалуы бизнес тарихын өзгертпейді.
Тәуелсіз жинақтарды reducer арқылы біріктіріңіз: құжат сілтемелері, бірегей ескертулер, параллель іздеу нәтижелері, сыртқы әсері жоқ метрикалар. Әр reducer үшін дубликат болғанда, бірдей идентификаторлардың мазмұны сәйкес келмегенде және жеткізу реті өзгергенде не болатынын сипаттаңыз.
Шешімді түсіндіретін немесе салдары бар оқиғаларды журналға жазыңыз: лимит ұсынысы, тексерісті растау, орындаушы тағайындау, мақұлдау, болдырмау, төлемге сұрау. Аудитор модельдің шикі логтарын оқымай-ақ тізбекті қалпына келтіруі керек болса, журнал әсіресе орынды.
Екі шындық қатар өмір сүре алмайтын операциялар үшін нақты конфликт бөліңіз. Мұндай конфликтіні «LLM қатесіне» жібермеңіз. Бұл жеке күйі, SLA-сы және иесі бар қалыпты домендік нәтиже.
Әртүрлі провайдерлердің модельдері үшін шақырудың техникалық бағытын және домендік оқиғаны бөлек сақтаған пайдалы. Модель жауабы, модель идентификаторы, промпт нұсқасы және құрал метадеректері сапаны талдау үшін керек. Бірақ refund_approval_proposed оқиғасы модель атауына тәуелді болмауы тиіс. Әйтпесе провайдерді ауыстырғанда предметтік тарихты орындау бөлшектерімен ластайсыз.
AI Router әртүрлі модельдерге сұрауларды бағыттау кезінде қолданыстағы OpenAI-үйлесімді клиентті сақтауға көмектеседі, бірақ бірыңғай endpoint күйді біріктіру келісімшартын алмастырмайды. base_url мәнін өзгерту оқиғаларыңыздың, ревизияларыңыздың және конфликтілеріңіздің мағынасын өзгертпеуі керек.
Merge келісімшартын бизнес логикасы сияқты тестілеңіз
Тек бір реттіліктегі күтілетін нәтижені тексеретін тест параллель workflow туралы дерлік ештеңе айтпайды. Сізге ауыстыру, қайталау және ескірген жазбалар тесті қажет.
Reducer үшін жаңартулар жиынын жасап, барлық шағын реттіліктерден өткізіңіз. Реттілік тәуелсіз деп мәлімдеген жерде нәтиже бірдей болуы керек. Содан кейін бір жаңартуды екі рет қайталаңыз. Егер reducer идемпотентті болмаса, тест мұны бекітіп, келісімшарт дубликаттардың неге мүмкін емес екенін немесе оларды қалай сүзетініңізді түсіндіруі тиіс.
Оқиғалар ағыны үшін «оқыды, жарыста жеңілді, қайта оқыды» сценарийін тексеріңіз. 41-ревизияға команда беріп, қатарлас оқиға қосыңыз, append қабылданбағанына көз жеткізіңіз, содан кейін қайта есептеу 42-ревизияны пайдаланатынын тексеріңіз. Бұл тек сәтті retry тесті болмауы керек: ең маңыздысы, ескі ниет қайта қаралмай өтіп кетпеуі тиіс.
Конфликтілер үшін шешімдер кестесін жазыңыз. Ол қарапайым, бірақ шығарылымнан кейінгі әзірлеушілер арасындағы даулардың алдын алады:
| Ағымдағы күй | Тармақ ұсынысы | Нәтиже |
|---|---|---|
risk_level = high | approve | conflict |
risk_level = low | approve | accepted |
decision = paid | cancel | rejected немесе өтем |
| ревизия өзгерді | кез келген шешім | conflict: stale_revision |
Соңында сыртқы әсерлерді шешімнен бөлек тестілеңіз. approval_confirmed өңдеушісі кезек ақауынан кейін бір жазбаны екі рет алуы мүмкін. Ол idempotency_key арқылы хатты жібергенін немесе аударым жасағанын анықтауы тиіс. «Дубликат күтілмейді» деген болжам қорғаныс емес. Дубликаттар жүйе жартылай ақаудан кейін қалпына келгенде пайда болады.
Конфликтіні error өрісіне жасырмаңыз
error өрісі тасымалдау қателеріне, жарамсыз JSON-ға және қолжетімсіз құралға жарайды. Күй конфликтісінің мағынасы басқа: жүйе пішіні дұрыс екі нәтиже алды, бірақ оларды бірге қабылдай алмайды.
Конфликтіні қате жолына салсаңыз, мониторинг оны техникалық ақау деп санайды, команда тапсырманы шексіз қайталай бастайды, ал оператор шешім үшін не жетіспейтінін көрмейді. Адамға көрсетуге және бағдарламалық түрде өңдеуге болатын құрылым жасаңыз:
{
"conflict_id": "conf_41d9",
"stream_id": "refund-918",
"status": "open",
"kind": "decision_vs_risk",
"current_revision": 42,
"proposals": [
"evt_policy_110",
"evt_risk_221"
],
"required_action": "human_review",
"resolution": null
}
Шешім қабылданғаннан кейін конфликт болмағандай тарихты қайта жазбаңыз. Шешім оқиғасын қосыңыз: шешімді кім қабылдады, қандай ережеге сүйенді, қандай ұсыныстар қабылданбады және өтемдік әрекетті іске қосу керек пе. Сезімтал процестерде бұл із кейде status-тың соңғы мәнінен де маңызды.
Параллельдік тармақтар тәуелсіз фактілерді бір уақытта жинағанда тиімді. Әр тармақ объектінің соңғы күйін жариялауға құқық алған кезде ол қауіпті болады. Шынымен жинақталатын деректер үшін reducer қолданыңыз. Тарих маңызды жерде ниеттерді оқиға ретінде жазыңыз. Ал ережелер екі жаңартуды бірге қабылдауға мүмкіндік бермейтін нүктеде конфликтіні сақтап, жүйені оны ашық түрде шешуге мәжбүрлеңіз.
Жиі қойылатын сұрақтар
Агент күйі үшін reducer қашан жеткілікті?
Reducer операцияны біріктірудің анық ережесі болғанда қолайлы: мысалы, бірегей сілтемелерді қосу, диагностика жазбаларын біріктіру немесе тәуелсіз фактілерді жинау. Егер тармақтар бағаны, лимитті, бекіту күйін немесе бизнес мәні бар басқа өрісті өзгертсе, reducer жеңімпазды үнсіз таңдамауы керек.
Агент тармақтарында last write wins неге жарамайды?
Өйткені тармақтар көбіне жұмыс басталғанға дейін бір snapshot-ты көреді. Кейін келген жауап жеткізу уақытына байланысты дұрысырақ болып кетпейді. Егер өзгерістің ревизиясы мен ниетін сақтамасаңыз, жүйе конфликт контекстін жоғалтады.
Әр агенттік workflow үшін event sourcing керек пе?
Жоқ. Оқиғалар журналы аудит, күйді қайта құру, шешім себептерін талдау немесе объектінің қатаң нұсқалануы қажет болғанда орынды. Тәуелсіз өрістерді қысқа мерзімді параллель өңдеу үшін ол көбіне пайдасынан гөрі көбірек код пен кідіріс әкеледі.
Агент жүйесіндегі шынайы конфликт деп нені санау керек?
Конфликт екі өзгерісті домен ережесін бұзбай немесе ерікті таңдау жасамай бірге қабылдау мүмкін болмаған кезде пайда болады. Екі түрлі тегті қосу әдетте үйлесімді, ал бір өтінімге «мақұлдау» және «қабылдамау» шешімдері нақты ережені немесе адам қатысуын талап етеді.
Өзгеріс жазбасында қандай өрістер болуы керек?
Объект идентификаторын, бастапқы ревизияны, іске қосылым идентификаторын, тармақты, операция түрін, пайдалы жүктемені және жасалу уақытын қосыңыз. Сыртқы әсері бар әрекеттер үшін идемпотенттілік кілті мен растайтын деректерге сілтемені де сақтаңыз.
Конфликтіден кейін тармақты автоматты түрде қайталауға бола ма?
Қайта іске қосу тек өзекті күйді қайта оқып, инварианттарды қайта тексергеннен кейін пайдалы. Ескі патчты жай ғана қайта жіберуге болмайды: ол басқа ревизия үшін жасалған және өзектілігін жоғалтқан шешімді бекітіп қоюы мүмкін.
Тармақтарды біріктіруді идемпотентті етуге бола ма?
Болады, егер әр жазбада тұрақты идентификатор болып, өңдеуші сол жазбаны қайта алған кезде нәтижені өзгертпесе. Идемпотенттілік төлемдер, хаттар, тикеттер жасау және қайталанған әрекетті түзету қымбат болатын кез келген операция үшін әсіресе маңызды.
Қауіпсіз merge енгізуді неден бастау керек?
Алдымен өрістерді түріне қарай бөліңіз: жинақталатын, алмастырылатын және шешімді қажет ететін өрістер. Содан кейін reducer-ді тек жинақталатын өрістерге қолданыңыз, алмастырылатын өрістер үшін нұсқа тексерісін енгізіңіз, ал даулы шешімдерді бөлек конфликт өңдеушісіне жіберіңіз.
CRDT нақты конфликтілерді шешуді алмастыра ма?
CRDT алдын ала анықталған ережелер бойынша репликалардың автоматты түрде үйлесуіне болатын деректерге пайдалы, мысалы жиындар мен кейбір санауыштарға. Бірақ олар қайтарымды бір уақытта мақұлдап, төлем дауын жабуға бола ма деген сұрақты шешпейді. Бұл деректер құрылымының емес, бизнес ережесінің мәселесі.
LLM API шлюзі күй конфликтілерін мен үшін шеше ала ма?
AI Router арқылы қолданыстағы SDK мен промпттарды сақтап, тек base_url мәнін OpenAI-үйлесімді endpoint-ке өзгертуге болады. Бірақ күй ережелерін қолданбаның өзінде жобалау керек. Модельдер шлюзі екі бизнес әрекетінің үйлесімділігін сіз оны күй келісімшартында көрсетпейінше шеше алмайды.