Harness engineering: агентке басым әлемде Codex-ті пайдалану
Райан Лопополо, Technical Staff мүшесі
Соңғы бес айда біздің команда бір тәжірибе жүргізді: қолмен жазылған 0 жол кодпен бағдарламалық өнімнің ішкі бета-нұсқасын жасап, шығару.
Өнімнің күнделікті ішкі пайдаланушылары және сыртқы альфа-тестерлері бар. Ол шығарылады, жайғастырылады, бұзылады және түзетіледі. Айырмашылығы — кодтың әр жолы — қолданба логикасы, тесттер, CI конфигурациясы, құжаттама, бақыланғыштық және ішкі құралдар — Codex арқылы жазылған. Біздің бағалауымызша, мұны қолмен код жазғаннан шамамен 1/10 уақытта жасадық.
Адамдар бағыт береді. Агенттер орындайды.
Біз бұл шектеуді әдейі таңдадық, өйткені инженерлік жылдамдықты бірнеше есе арттыру үшін не қажет болса, соны құрғымыз келді. Бізде кейін миллион жол кодқа айналған нәрсені шығару үшін небәрі бірнеше апта болды. Ол үшін бағдарламалық жасақтама инженериясы командасының негізгі міндеті енді код жазу емес, орталарды жобалау, ниетті нақтылау және Codex агенттеріне сенімді жұмыс істеуге мүмкіндік беретін кері байланыс циклдарын құру болғанда не өзгеретінін түсінуіміз керек еді.
Бұл жазба — агенттер командасымен мүлде жаңа өнім құру барысында не үйренгеніміз, не бұзылғаны, не жинақталғаны және шын мәнінде тапшы жалғыз ресурсымызды — адам уақыты мен назарын — қалай барынша тиімді пайдалануға болатыны туралы.
Бос репозиторийге алғашқы commit 2025 жылдың тамыз айының соңында түсті.
Бастапқы қаңқа — репозиторий құрылымы, CI конфигурациясы, пішімдеу ережелері, пакет менеджерінің баптауы және қолданба фреймворкі — бар бірнеше шаблонға сүйеніп, GPT‑5 қолданған Codex CLI арқылы жасалды. Тіпті агенттерге репозиторийде қалай жұмыс істеуді нұсқайтын бастапқы AGENTS.md файлын да Codex өзі жазды.
Жүйеге тірек болатын алдын ала бар, адам жазған код болған жоқ. Репозиторий әуел бастан агенттің әсерімен қалыптасты.
Бес айдан кейін репозиторийде қолданба логикасы, инфрақұрылым, құралдар, құжаттама және ішкі әзірлеуші утилиталары бойынша шамамен миллион жол код бар. Осы уақыт ішінде небәрі үш инженерден тұратын шағын команда Codex-ті жүргізе отырып, шамамен 1 500 өзгеріс сұранысын ашып, біріктірді. Бұл бір инженерге күніне орта есеппен 3,5 PR-дан келеді, әрі таңғаларлығы — команда қазір жеті инженерге дейін өскен сайын өткізу қабілеті артты. Ең маңыздысы, бұл жай ғана өнімділік үшін жасалған нәтиже емес: өнімді іште жүздеген пайдаланушы, соның ішінде күнделікті белсенді ішкі power user-лар пайдаланды.
Әзірлеу үдерісі бойы адамдар ешқашан тікелей код қоспады. Бұл команда үшін негізгі философияға айналды: қолмен жазылған код жоқ.
Адамның қолмен код жазбауы жүйелерге, қаңқаға және иінкүшке бағытталған инженерлік жұмыстың басқа түрін енгізді.
Алғашқы ілгерілеу біз күткеннен баяу болды, бірақ бұл Codex-тің қауқарсыздығынан емес, ортаның жеткілікті нақтыланбағанынан болды. Агентте жоғары деңгейлі мақсаттарға ілгерілеу үшін қажет құралдар, абстракциялар және ішкі құрылым жетіспеді. Біздің инженерлік командамыздың негізгі жұмысы агенттерге пайдалы жұмыс істеуге мүмкіндік беру болды.
Іс жүзінде бұл тереңдік бойынша жұмыс істеуді білдірді: үлкенірек мақсаттарды кішірек құрылыс блоктарына бөлу (дизайн, код, шолу, тест және т.б.), агентке сол блоктарды құруға көмексөз беру және оларды күрделірек міндеттерді ашу үшін пайдалану. Бірдеңе сәтсіз болса, шешім ешқашан дерлік «көбірек тырыс» болған жоқ. Ілгерілеудің жалғыз жолы Codex-ке жұмысты орындату болғандықтан, адам инженерлері әрдайым міндетке кірісіп: «қандай мүмкіндік жетіспейді және оны агент үшін әрі түсінікті, әрі орындатылатын етіп қалай жасаймыз?» деп сұрады.
Адамдар жүйемен түгелге жуық көмексөздер арқылы әрекеттеседі: инженер тапсырманы сипаттайды, агентті іске қосады және оған өзгеріс сұранысын ашуға мүмкіндік береді. PR-ды соңына дейін жеткізу үшін біз Codex-ке өз өзгерістерін жергілікті түрде өзі шолуды, жергілікті ортада да, бұлтта да қосымша нақты агенттік шолулар сұратуды, адам не агент берген кез келген кері байланысқа жауап беруді және барлық агент-рецензенттер қанағаттанғанша циклмен итерациялауды нұсқаймыз (іс жүзінде бұл Ralph Wiggum Loop(жаңа терезеде ашылады)). Codex контекст жинау үшін біздің стандартты әзірлеу құралдарымызды тікелей пайдаланады (gh, жергілікті скрипттер және репозиторийге ендірілген дағдылар), сондықтан адамдарға CLI-ге көшіру-қою қажет емес.
Адамдар өзгеріс сұраныстарын шолуы мүмкін, бірақ бұл міндетті емес. Уақыт өте келе біз шолу жұмысының дерлік бәрін агенттен агентке өңделетін жаққа ығыстырдық.
Код өткізу қабілеті артқан сайын, біздің тар орын адам QA сыйымдылығы болды. Тұрақты шектеу адам уақыты мен назары болғандықтан, қолданба UI-ы, журналдар және қолданба метрикалары сияқты нәрселерді Codex үшін тікелей оқылатын ету арқылы агентке көбірек мүмкіндік қосудың жолдарын іздедік.
Мысалы, қолданбаны әр git worktree үшін жүктелетін еттік, сонда Codex әр өзгеріс үшін бір дананы іске қосып, жүргізе алады. Сондай-ақ Chrome DevTools Protocol-ды агент runtime-ына жалғап, DOM snapshot-тармен, скриншоттармен және навигациямен жұмыс істеуге арналған дағдылар жасадық. Бұл Codex-ке қателерді қайта шығаруға, түзетулерді растауға және UI мінез-құлқы туралы тікелей пайым жасауға мүмкіндік берді.

Біз дәл осылай бақыланғыштық құралдары үшін де істедік. Журналдар, метрикалар және трассалар Codex-ке кез келген worktree үшін уақытша болатын жергілікті бақыланғыштық стегі арқылы ұсынылады. Codex сол қолданбаның толық оқшауланған нұсқасында жұмыс істейді — оның журналдары мен метрикаларын қоса алғанда, олар тапсырма аяқталған соң жойылады. Агенттер LogQL арқылы журналдарды, PromQL арқылы метрикаларды сұрата алады. Осы контекст қолжетімді болғанда, «service іске қосылуы 800ms-тен аз уақытта аяқталсын» немесе «осы төрт маңызды пайдаланушы жолындағы ешбір span екі секундтан аспасын» сияқты көмексөздер орындалатын болады.
Біз бір Codex іске қосуының бір тапсырмада алты сағаттан да ұзақ жұмыс істейтінін жиі көреміз (көбіне адамдар ұйықтап жатқанда).
Контексті басқару — агенттерді үлкен әрі күрделі міндеттерде тиімді етудегі ең үлкен қиындықтардың бірі. Біз үйренген ең алғашқы сабақтардың бірі қарапайым болды: Codex-ке 1 000 беттік нұсқаулық емес, карта беріңіз.
Біз «бір үлкен AGENTS.md(жаңа терезеде ашылады)» тәсілін қолданып көрдік. Ол болжамды түрде сәтсіз болды:
- Контекст — тапшы ресурс. Үлкен нұсқаулық файл тапсырманы, кодты және маңызды құжаттарды ығыстырып жібереді — сондықтан агент не негізгі шектеулерді жіберіп алады, не дұрыс емес нәрселерді оңтайландыра бастайды.
- Тым көп нұсқау нұсқау емеске айналады. Бәрі «маңызды» болғанда, ештеңе маңызды болмай қалады. Агенттер әдейі бағыт алудың орнына жергілікті pattern-matching жасайды.
- Ол бірден ескіреді. Монолитті нұсқаулық ескірген ережелер зиратына айналады. Агенттер ненің әлі рас екенін ажырата алмайды, адамдар оны қолдауды қояды, ал файл байқатпай тартымды кедергіге айналады.
- Тексеру қиын. Біртұтас блок механикалық тексерістерге (қамту, өзектілік, иелік, айқас сілтемелер) қолайлы емес, сондықтан ауытқу сөзсіз.
Сондықтан AGENTS.md-ті энциклопедия ретінде қарастырудың орнына, біз оны мазмұндар кестесі ретінде қарастырамыз.
Репозиторийдің білім қоры шындықтың негізгі көзі ретінде қарастырылатын құрылымдалған docs/ каталогында тұрады. Қысқа AGENTS.md (шамамен 100 жол) контекстке енгізіледі және негізінен карта қызметін атқарады, басқа жердегі тереңірек шындық көздеріне сілтемелер береді.
Дизайн құжаттамасы тексеру күйін және агентке басым жұмыс қағидаларын анықтайтын негізгі ұстанымдар жиынын қоса отырып, каталогталып, индекстеледі. Архитектура құжаттамасы(жаңа терезеде ашылады) домендер мен пакет қабатталуының жоғарғы деңгейлі картасын береді. Сапа құжаты әр өнім домені мен архитектуралық қабатты бағалап, уақыт өте келе олқылықтарды қадағалайды.
Жоспарлар бірінші дәрежелі артефакттар ретінде қарастырылады. Кіші өзгерістер үшін уақытша жеңіл жоспарлар пайдаланылады, ал күрделі жұмыс репозиторийге commit етілетін progress және decision log-тары бар орындау жоспарларында(жаңа терезеде ашылады) тіркеледі. Белсенді жоспарлар, аяқталған жоспарлар және белгілі техникалық қарыздың бәрі нұсқаланып, бір жерде орналасады, бұл агенттерге сыртқы контекстке сүйенбей жұмыс істеуге мүмкіндік береді.
Бұл біртіндеп ашуды қамтамасыз етеді: агенттер шағын, тұрақты кіру нүктесінен бастайды және оларға келесі қай жерден іздеу керегі үйретіледі, алдын ала бәрімен бастырылып тасталмайды.
Біз мұны механикалық түрде күштейміз. Арнайы линтерлер мен CI жұмыстары білім қорының өзекті, айқас байланысқан және дұрыс құрылымдалғанын тексереді. Қайталанатын «doc-gardening» агенті нақты код мінез-құлқын көрсетпейтін ескірген немесе мәнін жоғалтқан құжаттаманы сканерлеп, түзету өзгеріс сұраныстарын ашады.
Код базасы дамыған сайын, Codex-тің дизайн шешімдеріне арналған қаңқасы да бірге дамуы керек болды.
Репозиторий толықтай агент жасағандықтан, ол ең алдымен Codex-тің түсініктілігіне оңтайландырылған. Командалар жаңа инженерлік қызметкерлер үшін кодтың навигациясын жақсартуға ұмтылатыны сияқты, біздің адам инженерлеріміздің мақсаты агенттің бүкіл бизнес доменін тікелей репозиторийдің өзінен түсінуіне мүмкіндік беру болды.
Агент тұрғысынан алғанда, ол іске қосылған кезде контекст ішінде қол жеткізе алмайтын кез келген нәрсе іс жүзінде жоқ. Google Docs-та, чат ағындарында немесе адамдардың санасында тұратын білім жүйе үшін қолжетімсіз. Репозиторий ішіндегі, нұсқаланатын артефакттар (мысалы, код, markdown, схемалар, орындалатын жоспарлар) — оның көре алатыны осы ғана.

Уақыт өте келе репозиторийге барған сайын көбірек контекст енгізу қажет екенін түсіндік. Команданы белгілі бір архитектуралық паттернге келістірген сол Slack талқылауы ма? Егер агент оны таба алмаса, ол агент үшін дәл үш айдан кейін келген жаңа қызметкерге белгісіз болатындай дәрежеде оқылмайды.
Codex-ке көбірек контекст беру дегеніміз — агенттің ой қорытуы үшін дұрыс ақпаратты ұйымдастырып, қолжетімді ету, оны ретсіз нұсқаулармен басып тастау емес. Жаңа командатасыңызды өнім қағидаларына, инженерлік нормаларға және команда мәдениетіне (эмодзи талғамдарын қоса) қалай бейімдесеңіз, агентке де осы ақпаратты беру жақсырақ сәйкестендірілген нәтиже береді.
Бұл қырынан қарау көптеген ымыраларды айқындады. Біз репозиторий ішінде толық игеріліп, пайымдала алатын тәуелділіктер мен абстракцияларға басымдық бердік. Көбіне «жалықтырғыш» деп сипатталатын технологияларды агенттерге модельдеу оңайырақ, өйткені олар композицияланғыш, api-ы тұрақты және training set-те жақсырақ ұсынылған. Кейбір жағдайларда жалпыға қолжетімді кітапханалардың көмескі жоғары ағынды мінез-құлқын айналып өткеннен гөрі, функционалдың ішкі жиындарын агенттің қайта іске асыруы арзанырақ болды. Мысалы, жалпы p-limit стиліндегі пакетті қосудың орнына, біз concurrency бар map-with-concurrency көмекшімізді өзіміз іске асырдық: ол біздің OpenTelemetry instrumentation-пен тығыз біріктірілген, 100% тест қамтуына ие және біздің runtime күткендей дәл жұмыс істейді.
Жүйенің көбірек бөлігін агент тікелей тексеріп, растап және өзгерте алатын түрге көшіру иінкүшті арттырады — тек Codex үшін емес, код базасында жұмыс істеп жатқан басқа агенттер үшін де (мысалы, Aardvark).
Құжаттаманың өзі толықтай агент жасаған код базасының тұтастығын сақтамайды. Іске асырудың әр қадамын микробасқармай, инварианттарды күштеп орындату арқылы біз агенттерге іргетасты бұзбай тез жеткізуге мүмкіндік береміз. Мысалы, біз Codex-тен шекрада дерек пішіндерін parse етуді(жаңа терезеде ашылады) талап етеміз, бірақ мұның нақты қалай болатынын нұсқамаймыз (модельге Zod ұнайтын сияқты, бірақ біз дәл сол кітапхананы талап етпедік).
Агенттер қатаң шекаралары мен болжамды құрылымы бар(жаңа терезеде ашылады) орталарда ең тиімді, сондықтан біз қолданбаны қатаң архитектуралық модельдің айналасында құрдық. Әр бизнес домені қатаң тексерілетін тәуелділік бағыттары және рұқсат етілетін шектеулі қырлар жиынымен бекітілген қабаттар жиынына бөлінеді. Бұл шектеулер custom lint-тер (әрине, Codex жасаған!) және құрылымдық тесттер арқылы механикалық түрде орындатылады.
Төмендегі диаграмма ережені көрсетеді: әр бизнес доменінің ішінде (мысалы, App Settings) код тек бекітілген қабаттар жиыны арқылы ғана «алға» тәуелді бола алады (Types → Config → Repo → Service → Runtime → UI). Көлденең concerns (auth, connectors, telemetry, feature flags) бір ғана айқын интерфейс арқылы кіреді: Providers. Бұдан басқаның бәріне тыйым салынады және ол механикалық түрде орындатылады.

Мұндай архитектураны әдетте сізде жүздеген инженер болғанша кейінге қалдырасыз. Кодтаушы агенттермен бұл ерте қажет шартқа айналады: жылдамдықты тозусыз немесе архитектуралық ауытқусыз қамтамасыз ететін нәрсе — осы шектеулер.
Іс жүзінде біз бұл ережелерді custom lint-тер және құрылымдық тесттермен, сондай-ақ аз ғана «талғам инварианттарымен» күштеп орындатамыз. Мысалы, құрылымдалған logging-ті, schema және type атаулау конвенцияларын, файл көлемі шектерін және платформаға тән сенімділік талаптарын custom lint-термен статикалық түрде күштейміз. Lint-тер custom болғандықтан, қате хабарламаларын агент контекстіне түзету нұсқауларын енгізетіндей етіп жазамыз.
Адамға басым жұмыс ағынында бұл ережелер ұсақшыл немесе шектейтін болып көрінуі мүмкін. Агенттермен олар көбейткішке айналады: бір рет кодталса, бірден барлық жерде қолданылады.
Сонымен қатар біз шектеулердің қай жерде маңызды, қай жерде маңызды емес екенін айқын көрсетеміз. Бұл үлкен инженерлік платформа ұйымын басқаруға ұқсайды: шекараларды орталықтан күштеп орындат, жергілікті жерде автономияға жол бер. Сіз шекараларға, дұрыстыққа және қайта өндірілуге қатты мән бересіз. Сол шекаралардың ішінде командаларға — не агенттерге — шешімдердің қалай өрнектелетініне қатысты елеулі еркіндік бересіз.
Нәтижедегі код әрдайым адам стилдік қалауларына сәйкес келе бермейді, және бұл қалыпты. Нәтиже дұрыс, сүйемелдеуге болатын және болашақ агент іске қосулары үшін түсінікті болса, ол межеден өтеді.
Адам талғамы жүйеге үздіксіз кері беріледі. Шолу пікірлері, рефакторинг өзгеріс сұраныстары және пайдаланушыға көрінетін қателер құжаттама жаңартулары ретінде тіркеледі немесе тікелей құралдарға кодталады. Құжаттама жеткіліксіз болғанда, біз ережені кодқа көтереміз
Codex-тің өткізу қабілеті артқан сайын, көптеген дәстүрлі инженерлік нормалар кері әсер ете бастады.
Репозиторий ең аз бөгейтін merge gate-термен жұмыс істейді. Өзгеріс сұраныстары қысқа өмір сүреді. Тесттегі кездейсоқ ақаулар көбіне прогресті шексіз тоқтатудың орнына, кейінгі іске қосудармен түзетіледі. Агент өткізу қабілеті адам назарынан әлдеқайда асатын жүйеде түзетулер арзан, ал күту қымбат.
Төмен өткізу қабілеті бар ортада бұл жауапсыздық болар еді. Мұнда бұл көбіне дұрыс ымыра.
Код базасын Codex агенттері жасайды дегенде, біз код базасындағының бәрін меңзейміз.
Агенттер мыналарды жасайды:
- Өнім коды мен тесттер
- CI конфигурациясы мен релиз құралдары
- Ішкі әзірлеуші құралдары
- Құжаттама мен дизайн тарихы
- Бағалау harness-тері
- Шолу пікірлері мен жауаптар
- Репозиторийдің өзін басқаратын скрипттер
- Өндірістік dashboard анықтама файлдары
Адамдар әрдайым цикл ішінде қалады, бірақ бұрынғыдан басқа абстракция қабатында жұмыс істейді. Біз жұмысты басымдыққа қоямыз, пайдаланушы пікірін acceptance criteria-ға аударамыз және нәтижелерді тексереміз. Агент қиналғанда, оны белгі ретінде қабылдаймыз: не жетіспейтінін — құралдар ма, guardrail-дар ма, құжаттама ма — анықтап, оны репозиторийге қайта енгіземіз, әрқашан түзетуді Codex-тің өзіне жаздырамыз.
Агенттер біздің стандартты әзірлеу құралдарымызды тікелей пайдаланады. Олар шолу пікірлерін алады, inline жауап береді, жаңартуларды push етеді және көбіне өз өзгеріс сұраныстарын squash етіп, merge жасайды.
Әзірлеу циклінің көбірек бөлігі — тестілеу, валидация, шолу, кері байланысты өңдеу және қалпына келтіру — жүйенің өзіне тікелей кодталған сайын, репозиторий жақында Codex жаңа мүмкіндікті басынан аяғына дейін жүргізе алатын маңызды шектен өтті.
Енді агент бір ғана көмексөз бойынша мыналарды істей алады:
- Код базасының ағымдағы күйін тексеру
- Хабарланған қатені қайта шығару
- Ақауды көрсететін видео жазу
- Түзетуді іске асыру
- Қолданбаны жүргізіп, түзетуді тексеру
- Шешімді көрсететін екінші видео жазу
- Өзгеріс сұранысын ашу
- Агент пен адам берген кері байланысқа жауап беру
- Build ақауларын анықтап, түзету
- Пайым қажет болғанда ғана адамға эскалациялау
- Өзгерісті merge жасау
Бұл мінез-құлық осы репозиторийдің нақты құрылымы мен құралдарына қатты тәуелді, сондықтан ұқсас инвестициясыз жалпыланады деп санауға болмайды — кем дегенде, әзірге.
Агенттің толық автономиясы жаңа мәселелерді де әкеледі. Codex репозиторийде бұрыннан бар паттерндерді — тіпті біркелкі емес не оңтайлы емес болса да — қайталайды. Уақыт өте бұл міндетті түрде ауытқуға әкеледі.
Бастапқыда адамдар мұны қолмен түзеді. Біздің команда әр жұма сайын «AI slop»-ты тазалауға уақыт бөлетін (аптаның 20%-ы). Әрине, бұл ауқымдала алмады.
Сондықтан біз «алтын қағидалар» деп атайтын нәрсені тікелей репозиторийге кодтай бастадық және қайталанатын тазалау үдерісін құрдық. Бұл — болашақ агент іске қосулары үшін код базасын түсінікті әрі бірізді ұстайтын пікірлі, механикалық ережелер. Мысалы: (1) инварианттарды орталықтандыру үшін қолдан жасалған көмекшілерден гөрі ортақ utility пакеттерін қалаймыз, және (2) деректерді «YOLO-стилімен» түртпейміз — шекараларды тексереміз немесе typed SDK-ларға сүйенеміз, сонда агент болжанған пішіндерге байқаусызда сүйеніп құра алмайды. Белгілі бір тұрақты кестемен бізде ауытқуларды сканерлейтін, сапа бағаларын жаңартатын және нысаналы рефакторинг өзгеріс сұраныстарын ашатын бірқатар фондық Codex міндеттері бар. Олардың көбін бір минутқа жетпей шолып, automerge жасауға болады.
Бұл garbage collection сияқты жұмыс істейді. Техникалық қарыз жоғары пайызды несие сияқты: оны жинақтатып, ауыр серпіндермен шешкеннен гөрі, үнемі шағын қадамдармен азайтып отырған дұрыс. Адам талғамы бір рет тіркеледі де, кейін кодтың әр жолында үздіксіз орындатылады. Бұл сондай-ақ жаман паттерндерді код базасына күндер не апталар бойы жайылдырмай, күн сайын ұстап, шешуге мүмкіндік береді.
Бұл стратегия әзірге OpenAI ішіндегі іске қосу мен қабылдауға дейін жақсы жұмыс істеді. Нақты пайдаланушыларға арналған нақты өнім құру біздің инвестицияларымызды шынайылыққа бекітіп, ұзақ мерзімді сүйемелдеуге бағыт беруге көмектесті.
Біз әлі білмейтін нәрсе — толықтай агент жасаған жүйеде архитектуралық тұтастық жылдар бойы қалай дамитыны. Біз әлі де адам пайымы ең көп иінкүшті қай жерде беретінін және сол пайымды қалай кодтау керек екенін үйреніп жатырмыз, сонда ол жинақтала береді. Сондай-ақ модельдер уақыт өте келе күшейе берген сайын бұл жүйе қалай дамитынын да білмейміз.
Айқын болғаны: бағдарламалық жасақтама жасау әлі де тәртіпті талап етеді, бірақ бұл тәртіп енді кодтың өзінен гөрі қаңқада көбірек көрінеді. Код базасының тұтастығын сақтайтын құралдар, абстракциялар және кері байланыс циклдары барған сайын маңызды болып келеді.
Қазір біздің ең қиын міндеттеріміз агенттерге мақсатымызды орындауға көмектесетін орталарды, кері байланыс циклдарын және басқару жүйелерін жобалауға шоғырланған: ауқымды түрде күрделі әрі сенімді бағдарламалық жасақтаманы құру және қолдау.
Codex сияқты агенттер бағдарламалық жасақтама өмірлік циклінің үлкенірек бөліктерін өз мойнына алған сайын, бұл сұрақтар одан да маңызды болады. Алғашқы сабақтарымыздың бір бөлігін бөлісу сізге күш-жігеріңізді қайда салу керегін пайымдауға көмектеседі деп үміттенеміз, сонда жай ғана бірдеңелерді құра аласыз.


