Мазмұнға өту
2026 ж. 07 қаң.·6 мин оқу

OpenAI-мен үйлесімді провайдерлерге арналған контракттық тесттер

OpenAI-мен үйлесімді провайдерлерге арналған контракттық тесттер релизге дейін streaming, tools, embeddings және қате пішіміндегі ақауларды бір сағат ішінде табуға көмектеседі.

OpenAI-мен үйлесімді провайдерлерге арналған контракттық тесттер

Неге «OpenAI-мен үйлесімді» ұсақ-түйекте бұзылады

«OpenAI-мен үйлесімді» деген жазу көбіне бір ғана нәрсені білдіреді: провайдердің эндпоинті ұқсас, ал өрістері таныс. Команда песочницада бір қысқа сұраным жіберіп тұрғанда, айырмашылық онша білінбейді. Ақаулар кейінірек, дәл сол код продқа шыққанда және жауаптың ұсақ бөлшектеріне тірелгенде басталады.

Бірдей сұраным әртүрлі JSON қайтара алады. Бір жерде usage соңында келеді, бір жерде мүлде жоқ. Бір провайдерде finish_reason SDK күткен жерде тұрады, басқасында құрылым сәл ығысқан, сонда парсер бірден құлайды.

Streaming-пен одан да қиын. Қысқа жауаптарда ағын қалыпты көрінеді, ал ұзын жауаптарда ортасынан үзіліп қалуы, оқиғаларды басқа ретпен жіберуі немесе қызметтік өрістерді мәтінмен араластыруы мүмкін. Нәтижесінде интерфейс қатып қалады, жауапты жинау логикасы мәтіннің бір бөлігін жоғалтады, ал токен санауы қате жібере бастайды.

Tools-та айырмашылықтар әдетте бірден байқалмайды. Провайдер функция шақырулары қолдаулы деп жазады, бірақ функция атауы бір өрісте, аргументтері басқа өрісте келеді, ал кейде аргументтер мүлде бос болады. Агент құрал таңдалғанын көреді, бірақ оны орындай алмайды.

Embeddings қателігі ең тыныш болуы мүмкін. Сұраным сәтті өтеді, сандар массиві қайтады, тек өлшемі индекс немесе көрші сервис күткеннен басқаша болып шығады. Бұл әсіресе миграция алдында жағымсыз: команда тек base_url-ды ауыстырып, қалған кодқа тимейміз деп ойлайды.

Қателер де сырттай ғана ұқсас. Мәтін түсінікті болуы мүмкін, бірақ кодтар, ішкі құрылым және өрістердің өзі соншалықты әртүрлі, сондықтан ретрай, фолбэк және rate limit өңдеу біртүрлі жұмыс істей бастайды. Сондықтан OpenAI API үйлесімділігін уәде емес, контракттық тесттермен тез тексерілетін гипотеза деп қараған дұрыс.

Қандай шақырулар жиыны жеткілікті

Егер сіз тек base_url-ды ауыстырсаңыз, үлкен стенд керек емес. Алғашқы прогон үшін бес шақыру жеткілікті. Олар үйлесімділік қай жерде тек сөз жүзінде екенін тез көрсетеді.

Минималды жиын әдетте мынадай:

  1. Қалыпты chat completion streamingсіз. Ол базалық жауапты тексереді: рөл, мәтін, finish_reason, usage және JSON-ның жалпы пішіні.
  2. Сол сұраным streaming-пен. Мұнда chunk-тар қалай келетінін, delta бар-жоғын, токендер реті бұзылмайтынын және ағын дұрыс аяқталатынын көресіз.
  3. tools және міндетті tool_choice бар шақыру. Провайдерлер схеманы жиі қабылдайды, бірақ arguments, tool_call_id немесе тоқтау себебін әртүрлі қайтарады.
  4. embeddings сұранымы вектор ұзындығын тексерумен. Егер вектор өлшемі модельдер арасында ауысып тұрса немесе күткенге сай келмесе, іздеу мен ранжирлеу кейін тыныш бұзылады.
  5. Әдейі қате сұраным. Мысалы, жоқ модель немесе бұзылған параметр. Мұндай тест жауап коды, error құрылымы және хабарлама мәтінін тексеру үшін керек.

Мұндай шақыруларды мүмкін болған жерде бір ғана тесттік модельде іске қосқан дұрыс. Сонда мәселе провайдерден бе, модельден бе, әлде сіздің қаптаудан ба — тезірек түсініледі. tools пен embeddings үшін кейде бөлек модель керек болады, бұл қалыпты.

Алдын ала нені сәттілік деп санайтыныңызды бекітіңіз. Қалыпты чат үшін бұл «жай ғана қандай да бір мәтін алдық» емес, нақты өрістер жиыны. Streaming үшін бұл «ағын келді» емес, бірінші chunk-тан финалдық stop-сигналға дейінгі толық цикл. Ал қате үшін бұл «сервер жауап берді» емес, клиентіңіз оқи алатын пішін.

Мұндай жиын бір кеште жиналады және релизден кейін бірнеше күнді үнемдейді.

Тесттерді бір кеште қалай жинауға болады

Кішкентайдан бастаңыз: бір каталог, бірнеше JSON-файл және қарапайым іске қосу скрипті. Әр сценарий үшін барлық провайдерде бірдей payload пайдаланыңыз. Егер сұраным мәтінін, параметрлерді және модельді бірден өзгертсеңіз, нақты нені сындырғаныңызды түсінбей қаласыз.

Жауапқа әсер ететіннің бәрін бекітіңіз: model, temperature, max_tokens, tool_choice және жауап пішімі. Тіпті температураның сәл өзгеше болуы салыстыруды тез бұзады. Контракттық тесттер үшін бұл негізгі ереже.

Жақсы минималды жиынға chat completions шақыруы, tools-сіз бір сұраным, streaming-пен бір сұраным, функция аргументі күтілетін бір tools-сценарийі, қысқа мәтінге арналған бір embeddings сұранымы және қателерді тексеруге арналған әдейі қате сұраным кіреді.

Екі нәтижені бөлек сақтаңыз. Біріншісі — провайдердің барлық өрістері, chunk-собыялары мен қате кодымен бірге толық шикі жауабы. Екіншісі — жауапты өзіңіздің ішкі схемаңызға келтіретін нормаланған нәтиже. Егер бірдеңе дұрыс болмаса, шикі жауап себепті көрсетеді, ал нормаланған нұсқа провайдерлерді тез салыстыруға көмектеседі.

200 статусы ештеңе дәлелдемейді. Скрипт схеманы тексеруі керек: choices бар ма, finish_reason келді ме, tool_call типі сәйкес пе, embedding бос емес пе, сіз күткен жерде message.content бар ма. Қателерге де осы талаптар жүреді: HTTP-код, error өрісі, details құрылымы.

Егер команда тек base_url-ды ауыстырса, жинақты екі рет іске қосыңыз: ауыстырмас бұрын және ауыстырғаннан кейін. AI Router сияқты шлюз үшін бұл әсіресе ыңғайлы: адресін api.airouter.kz-ке ауыстырып, сол SDK мен сол промпттарды қалдырасыз да, парсердің, проксидің және клиент логикасының мінезін тез салыстырасыз.

Streaming-ті қолмен қарамай қалай тексеруге болады

Streaming-ті консольде көзбен шолғаннан гөрі, тестпен ұстаған дұрыс. Бір қысқа сценарий провайдердің артық chunk жіберетінін, жауаптың соңын жоғалтатынын немесе оқиғалар пішімін өзгертіп, клиентті үнсіз бұзатынын тез көрсетеді.

Мұндай тест үшін бір қарапайым промпт пен streamingсіз бір қалыпты сұраным жеткілікті. Итогтық мәтін қайталануға жақын болу үшін temperature: 0 қойыңыз. Содан кейін қалыпты жауап пен жиналған ағынды салыстырыңыз.

Нені өлшеген дұрыс:

  • жауапқа қанша chunk келді;
  • бірінші chunk пен бірінші токенге дейін қанша уақыт өтті;
  • delta ішіндегі өрістер реті;
  • бос chunk-тардың бар-жоғы;
  • finish_reason келуі.

Қалыпты ағынның басында әдетте ассистенттің рөлі келеді, содан кейін мәтін бөліктері delta.content ішінде беріледі, ал соңында finish_reason шығады. Егер рөл кеш келсе, content role-дан бұрын түссе немесе ағын финалдық сигналсыз үзіліп қалса, клиент коды біртүрлі жұмыс істей бастайды: интерфейс қатып қалады, жауапты жинау логикасы бұзылады, ретрайлар босқа іске қосылады.

Бос chunk-тарды да қате немесе кем дегенде бөлек ескерту ретінде санаған дұрыс. Кейде провайдер оларды қалыпты оқиғалардың арасында жібереді, бұл аса қорқынышты емес. Ал бос chunk-тен кейін ағын жабылып, финал мүлде келмесе, мәселе басқа.

Жеке тест жиналған streaming-жауапты streamingсіз қалыпты жауаппен салыстыруы керек. Барлық delta.content біріктірілгеннен кейінгі соңғы жолды салыстырыңыз. Бірдей промпт пен бірдей параметрлерде мәтін қатты айырылса, мәселе көбіне модельде емес, провайдердің ағынды қалай бөліп, жеткізетінінде болады.

Тағы бір жиі ақау тасымалдау қабатына байланысты. Провайдер үйлесімділік бар дейді, бірақ SSE-пішімді өзгертеді. Мұны модель қатесінен бөлек белгілеу керек, араластырмаған дұрыс. Егер клиент стандартты data бар SSE events күтсе, ал өзіне тән орам алса, ағын формалды түрде бар, бірақ SDK оны түсінбейді.

Жақсы streaming-тест қысқа есеппен аяқталады: қанша chunk келді, бірінші токен уақытында келді ме, role мен delta қандай ретпен келді, соңғы мәтін жиналды ма және finish_reason жетті ме. Әдетте бұл провайдерді продқа қосуға бола ма, жоқ па — бірнеше минутта түсінуге жеткілікті.

Tools көбіне қай жерде бұзылады

Эмбеддингтерді миграцияға дейін тексеріңіз
AI Router арқылы векторлардың өлшемін, ретін және типтерін миграцияға дейін салыстырыңыз.

Tools-пен ақаулар тез көрінеді: провайдер сұранымды қабылдайды, бірақ модель басқа функция атауын қайтарады, JSON аргументтерінің пішімін өзгертеді немесе шақырудың орнына жай мәтіндік жауап жазады. Тесттік чатта бұл төзуге болады. Продта мұндай ығысу тізбектің келесі қадамын бұзады.

Алдымен сіздің кодыңыз не күтетінін және нақты не келгенін салыстырыңыз. Функция атауы әріпке дейін дәл келуі керек. Аргументтерді JSON ретінде талдап, типтері бойынша тексеріңіз: жол, сан, массив, міндетті өрістер. tool_call_id-ды бөлек сақтап, кейін функция нәтижесін келесі сұранымға берсеңіз, міндетті түрде салыстырыңыз.

Бір функциясы бар бір сценарий көп нәрсе дәлелдемейді. Екінші сценарий қосыңыз, онда модельге атауы ұқсас екі функция қолжетімді болсын. Дәл сондай тест жиі қызық мінезді ашады: бір провайдер дұрыс емес функцияны таңдайды, екіншісі шақырулар ретін ауыстырады, үшіншісі tool call-ды кәдімгі мәтінмен араластырады.

Модель «қазір функцияны шақырамын» деп жазып, бірақ іс жүзінде шақырмайтын жағдайды да бөлек ұстаңыз. Мұндай жауап шынайы көрінеді, сондықтан оны көзбен өткізіп жіберу оңай. Тест мәтінді емес, tool_call-дың нақты бар-жоғын тексеруі керек.

Схеманы әдейі бұзу да пайдалы. properties ішінде жоқ required өрісін көрсетіңіз немесе модельден аргументті қате типте қайтаруды сұраңыз. Қалыпты сервер тез арада 400 беріп, түсінікті қате мәтінін қайтарады. Әлсіз үйлесімділік басқаша көрінеді: сервер қоқысты үнсіз қабылдайды да, кодыңыз жауаптан кейін ғана құлайды.

Егер сіз тек base_url-ды ауыстырсаңыз, tools көбіне жалған үйлесімділік сезімін береді. Мұнда бір сәтті шақырудың өзі өте аз нәрсе айтады.

Embeddings ішінде неге қараймыз

Embeddings chat completion-ге қарағанда бәсең бұзылады. Сұраным өтеді, статус 200, журналдар тыныш, ал база бойынша іздеу кенеттен түсініксіз сәйкестіктерді көрсете бастайды. Сондықтан жауап келді ме, жоқ па дегенді ғана тексеру аз. Жауап қарапайым және шекаралық жағдайларда бірдей жұмыс істейтінін қарау керек.

Алдымен вектор ұзындығына қараңыз. Бірдей мәтін әр прогонда бірдей өлшемдегі вектор қайтаруы керек. Бүгін модель 1536 сан беріп, ертең 3072 берсе, векторлық индекс формалды түрде құламаса да, қате істей бастайды.

Сосын ретін тексеріңіз. Егер бірнеше кірісі бар батч жіберсеңіз, нәтижелер сол тәртіппен қайтуы керек. Әйтпесе команда бір жолдың embedding-ін басқа карточкаға оңай жазып қоюы мүмкін. Мұндай қателерді әдетте іздеудегі біртүрлі релеванттылықтан ғана байқайды.

Тест жиынына қысқа сөйлем, бос жол, лимитке жақын ұзын мәтін, бірнеше кірісі бар батч және бірдей мәтінді қайталау керек. Бос жол мен ұзын мәтін жай ғана формальдылық үшін емес. Бір провайдер түсінікті қате береді, екіншісі бос енгізуге вектор қайтарады, үшіншісі мәтінді үнсіз қысқартады. Кез келген нұсқа жарамды, егер ол әрдайым қайталанып, тест оны ұстаса. Егер мінез сұранымнан сұранымға өзгеріп тұрса, іздеу, дедупликация және ұсыныстарда кездейсоқ ақаулар аласыз.

Дерек типтерін де бөлек тексеріңіз. Вектор "0.123" сияқты жол емес, сандар массиві болып келуі керек. Көзге айырмашылық ұсақ көрінгенімен, кейін бұл сериализацияны, ұқсастық метрикаларын және базаға жүктеуді бұзады.

Тағы бір пайдалы тест — пакетке жауап беру уақыты. Бір кіріс пен 8 немесе 16 жолдан тұратын батч үшін кідірісті өлшеңіз. Егер батч жеке сұраныммен шамалас жылдам болса, бұл жақсы белгі. Егер кідіріс бірнеше есе өссе, провайдер, сірә, әр элементті жеке өңдеп жатыр, ал үлкен ағын кезінде есеп пен уақыт тез бақылаудан шығады.

Егер сіз провайдерге тікелей қолжетімділікті және сол шақыруды AI Router арқылы салыстырсаңыз, мұндай жиын қай жерде мінез өзгеше екенін, ал қай жерде тип, тәртіп және вектор өлшемі бойынша бәрі сәйкес келетінін бірден көрсетеді.

Қате пішімін қалай салыстырамыз

Қателер интеграцияны қарапайым жауаптан жиірек бұзады. Провайдер адал түрде 401 немесе 429 қайтара алады, бірақ body ішіне клиентіңіз күткен JSON емес нәрсе салуы мүмкін. Соның салдарынан ретрайлар, алерттер және құлау өңдегіштері біртүрлі істейді.

Алдымен екі нәрсені салыстырыңыз: HTTP-код пен error.type өрісі. Код сізге қандай ақау класы келгенін айтады, ал error.type клиенттің логиканы тармақтауына керек. Егер код 429, ал қате типі кәдімгі invalid_request_error сияқты болса, үйлесімсіздік табылды деген сөз.

Қате мәтінін де қараңыз, бірақ логиканы соған құрмаңыз. Тұжырымдар жиі өзгереді: бір провайдер invalid api key жазады, екіншісі authentication failed дейді, үшіншісі жоба немесе аймақ атын қосады. Адам үшін бұл пайдалы, ал код үшін — нашар сүйеніш.

Минималды прогонды бірнеше тексеруге бөлуге болады: қате немесе бос кілт үшін 401, лимиттер үшін 429, бұзылған JSON немесе белгісіз модель үшін 400, және сервер JSON емес, HTML не plain text қайтаратын бөлек сценарий.

Соңғысы көп адамды айналып өтеді. Ал бекер. Аралық қабат 502 Bad Gateway бар HTML қайтарса, ал error өрісі бар JSON күтетін клиент парсингте-ақ құлайды. Мұндай ақауды журналдан оқу қиын, өйткені ол бастапқы себепті бүркемелейді.

Егер SDK rate limit header-лерін оқыса, оларды да тексеріңіз. Кейбір клиенттер нақты header-лердегі сандарды күтеді де, келесі қайталау уақытының өзін есептейді. Егер header жоғалса, қайта атанса немесе бос келсе, ретрай кезегі тез сырғиды.

Провайдерді ауыстырмас бұрынғы мысал

Алдымен ағынды тексеріңіз
Релизге дейін AI Router арқылы chunk-тар реті мен финалдық сигналды көріңіз.

Команда тек base_url-ды ауыстырып, бәрі бұрынғыдай қалады деп күтеді. Қағаз жүзінде бұл қисынды: OpenAI-мен үйлесімді API, сол SDK, сол промпттар. Шындықта айырмашылық көбіне бірінші прогонның өзінде-ақ көрінеді.

Әуелі әзірлеушілер қарапайым chat completion-ді streamingсіз өткізеді. Жауап келеді, тест жасыл, миграцияға аз қалды деген жалған сезім пайда болады. Бірнеше минуттан кейін streaming қосылады, бірінші chunk күтпеген пішінде келеді, ал клиент толық жауап жиналмай жатып-ақ құлайды.

Келесі болып tools шақыруы өтеді. Модель аргументтерді объект ретінде емес, ішінде JSON бар жол ретінде қайтарады. Парсер бір пішімді күтті, басқасын алды, сондықтан бизнес-логика тоқтайды. Содан кейін embeddings кезегі келеді: сұраным сәтті, статус 200, қате жоқ, бірақ вектор өлшемі іздеу индексі есептелген мөлшерге сәйкес келмейді. Іздеу бірден құламайды, бірақ жай ғана қисық нәтиже бере бастайды.

Сондықтан қысқа тест жиыны ұзақ демодан пайдалырақ. Қарапайым чат, сол сұранымның streaming нұсқасы, бір tool call, бір embeddings сұранымы және бір қате сұраным командаға релизге дейінгі нақты жұмыс тізімін береді.

Командалар көбіне қай жерде қателеседі

Ең жиі қате қарапайым: команда HTTP 200 көріп, үйлесімділік расталды деп ойлайды. Шын мәнінде жауап бұзылған JSON, артық өріс, бос choices немесе үзіліп қалған streaming ағынымен келуі мүмкін. Сұраным формалды түрде сәтті, ал қосымша жауапты талдағанда құлайды.

Екінші тұзақ — әртүрлі модельдерді бір контракт сияқты салыстыру. Егер бір тест GPT-тектес модельде, ал екіншісі әлсіз open weights модельде жүрсе, tools, embeddings немесе қате пішіміндегі айырмашылықтар ештеңе дәлелдемейді. Бірдей сценарийлерді мүмкіндігінше жақын модельдерде салыстыру керек.

Тағы бір жаман әдет — шикі жауапты сақтамау. «пайдалану қатесі шықты» деңгейіндегі журналдар мардымсыз. Толық raw response керек: headers, body, stream бөлігі ретімен, қате коды, request id, жауап уақыты. Әйтпесе талқылау тез арада болжауға айналады.

Әртүрлі мәселе класстарын бірден ажыратқан да дұрыс. Желілік ақау, таймаут және қосылымның үзілуі — бір әңгіме. Жауап схемасының үйлеспеуі, tools мінезінің оғаштығы, embeddings-тегі айырмашылықтар немесе қате пішімінің басқа болуы — мүлде басқа. Егер провайдер 502 қайтарса немесе қосылым үзіліп қалса, контракт кінәлі емес. Ал егер ол тұрақты түрде tool_calls-ты басқа түрде берсе немесе SSE оқиғаларын бұзса, бұл нағыз үйлесімсіздік.

Тағы бір типтік кемшілік: тек сәтті сценарийді ғана сынау. Прод мінсіз сұранымда емес, модельге жарамсыз tool келгенде, input тым ұзын болғанда немесе лимитке тірелгенде бұзылады. Сондықтан минималды жиынға жаман жағдайлар да кіруі керек: 400, 401, 429, 500, бос tool result, бірнеше токеннен кейін stream-нің үзілуі.

Қосылмас бұрынғы қысқа чек-лист

AI Router арқылы тесттерді іске қосыңыз
API мекенжайын ғана ауыстырып, SDK мен промпттарды өзгертпей жауаптарды салыстырыңыз.

Алғашқы сұранымнан бұрын провайдердің уәдесін оқи бергеннен гөрі, бірдей тексерулер жиынын өткізу пайдалырақ. OpenAI-мен үйлесімді API-да көбіне модельдің өзі емес, оның айналасындағы детальдар — stream chunk-тары, tools, embeddings және қате body — бұзылады.

Бірнеше қарапайым нәрсені тексеріңіз:

  • барлық прогонда бірдей payload қолданыңыз;
  • streaming, tools, embeddings және қателерді бөлек тексеріңіз;
  • тестті модель мәтініне емес, жауап схемасына сүйеніп құлатын етіңіз;
  • қай айырмашылықты клиент көтереді, қайсысын көтермейді — алдын ала бекітіңіз;
  • нәтижені күнмен, модельмен және провайдермен бірге сақтаңыз.

Бұл жалықтыратын нәрсе сияқты естіледі, бірақ мұндай минимум нақты ақауларды өте тез ұстайды. Бір провайдер streaming кезінде қалыпты мәтін қайтарып, бірақ chunk-тардың бірінде қызметтік өрісті түсіріп жіберуі мүмкін. Басқасы chat completions-қа адал жауап береді, бірақ tool_calls пішімін өзгертеді. Үшіншісі embeddings береді, тек вектор өлшемі индекс күткенінен басқаша болады.

Қателермен де дәл солай. Егер тест error.type, error.message және HTTP-код өрістерін күтсе, ол үйлесімсіздікті секундтар ішінде ұстайды. Егер тек хабарлама мәтінін салыстырсаңыз, мәселені продтағы алғашқы құлауға дейін байқамай қалуыңыз мүмкін.

Команда ішінде допусктерді бөлек келісіп алыңыз. Streaming-тегі бос delta көбіне кедергі келтірмейді. Ал tool_calls-тың жоғалуы немесе массив пішімінің өзгеруі — критикалық. Бұл ережелерді бірден жазып қойған дұрыс, әйтпесе бір инженер прогонды сәтті деп белгілейді, ал екіншісі сол провайдерді кері қайтарады.

Алғашқы прогонымнан кейін не істеу керек

Бірінші прогон әдетте айырмашылықтарды табады. Көбіне бұл қатты бұзылу емес, схеманың ұсақ ығысуы: бір провайдерде tool_calls басқа жерде тұрады, екіншісінде embeddings артық орамада келеді, үшіншісінде 429 қатесі жауап body-сінде мәтіні бар кәдімгі 500 сияқты көрінеді. Мұндай нәрселерді бүкіл қосымшаға шашпай, бірден адаптерде түзеген дұрыс.

Егер жауап пішімі кодыңыз күтетін нәрсемен сәйкес келмесе, жұқа нормализация қабатын қосыңыз. Ол streaming, tools, embeddings және қателерді бизнес-логикаға түспей тұрып бір түрге келтірсін. Жұмысы аса қызық емес, бірақ тез ақталады: кейін провайдерді ауыстыру сервисіңіздің жартысын бұзбайды.

Алғашқы түзетулерден кейін тест жиынын CI-ға көшіріңіз. Оны әр модель, провайдер және SDK нұсқасы ауысар алдында іске қосыңыз. «Біраз ғана үйлесімді» API бар бір релиз командаға бір күнді оңай жеп қояды, әсіресе мәселе тек streaming кезінде немесе tools шақырғанда байқалса.

Тек сәтті жауапты тексеру ештеңеге кепілдік бермейді. Rate limits пен timeouts үшін бөлек прогондар қалдырыңыз. Кем дегенде төрт нәрсені тексерген дұрыс: 429 күтілген кодпен және қате body-сімен келе ме, клиент таймауты қайталау сұранымын бұза ма, streaming үзілістен кейін болжамды түрде аяқтала ма, ал 5xx пен валидация қателері пішімі бойынша бөлек пе.

Егер команда әртүрлі провайдерді біртұтас endpoint арқылы, мысалы AI Router арқылы өткізсе, бәріне бірдей контракттық тесттер жинағын қолданыңыз. AI Router-дың мұнда практикалық пайдасы бар: провайдерді бір OpenAI-мен үйлесімді эндпоинт арқылы ауыстырып, айырмашылық маршруттан ба, әлде өз клиентіңізден бе — тез көре аласыз.

Бәрін бірден қамтуға тырыспаңыз. Ең жиі ақауларды ұстайтын 10-15 шақырудан тұратын шағын жиыннан бастаңыз. Кейін оны өз сценарийлеріңізге қарай кеңейтіңіз: ұзын контекст, бос embeddings, сұранымды тоқтату, 503-тен кейін қайталау, бір жауапта бірнеше tools. Сонда командада мысалдар мұрағаты емес, кез келген ауысудың алдындағы қалыпты сақтандырғыш пайда болады.

Жиі қойылатын сұрақтар

OpenAI-мен үйлесімді API үшін контракттық тесттер нені тексереді?

Контракттық тесттер модель мәтінінің сапасын емес, API жауабының пішінін тексереді. Олар релизге дейін usage, finish_reason, streaming-собыялар, tool_calls, embeddings және қате мәтініндегі ауытқуларды ұстайды.

Провайдерді бірінші тексеру үшін қандай сұранымдар жеткілікті?

Бастау үшін бес шақыру жеткілікті: қалыпты chat completion, сол сұранымның streaming нұсқасы, қатаң tool_choice бар tools шақыруы, embeddings сұранымы және әдейі қате сұраным. Мұндай жиын провайдердің OpenAI API-ға қаншалықты ұқсайтынын тез көрсетеді.

Неліктен 200 статус әлі де үйлесімділікті дәлелдемейді?

Өйткені 200 OK сервердің HTTP қатесі жоқ екенін ғана білдіреді. Ал JSON сіздің SDK күткен пішінге сәйкес келмеуі мүмкін, немесе ағын finish_reason-ға жетпей үзіліп қалуы ықтимал.

Streaming-ті қолмен қарамай қалай тез тексеруге болады?

Ең оңай тәсіл — бірдей промптты екі рет жіберу: бір рет streamingсіз, бір рет streamingпен. Сосын delta.content-ті біріктіріп, соңғы мәтінді салыстырыңыз, сондай-ақ оқиғалар реті, бос chunk-тар және финалдық тоқтау сигналы дұрыс келгенін тексеріңіз.

Tools көбіне қай жерде бұзылады?

tools ішінде көбіне функция атауы, arguments пішіні және tool_call-дың өзі бөлініп кетеді. Модель функцияны шақырамын деп жазуы мүмкін, бірақ шын мәнінде шақырмайды, не болмаса JSON аргументтерін жол түрінде қайтарады, ал оны сіздің кодыңыз оқи алмайды.

Embeddings шынымен үйлесімді екенін қалай білуге болады?

Алдымен вектор ұзындығына, батч ішіндегі нәтижелер ретіне және деректер типіне қараңыз. Егер өлшемі ауысып тұрса, реттілік өзгерсе немесе сандар жол болып келсе, іздеу мен ранжирлеу күтпеген нәтиже береді.

Қандай қателерді ең алдымен тестілеу керек?

Алдымен 400, 401, 429 және кем дегенде бір 5xx не JSON емес жауапты бөлек тексеріңіз. Клиент HTTP кодын, error.type пен error.message-ті, қажет болса rate limit header-лерін де дұрыс оқуы керек.

Тесттерден raw response сақтау керек пе?

Иә, шикі жауапты толық сақтаңыз: body, headers, code, stream chunk-тары мен жауап уақыты. Raw response болмаса, команда әдетте ақаудың нақты орнын емес, тек белгісін талқылайды.

Тек base_url-ды қашан қауіпсіз ауыстыруға болады?

Тек бірдей контракттық тесттерді ауыстыруға дейін де, кейін де өткізіп шыққан соң ғана. Егер сіз base_url-ды api.airouter.kz-ке ауыстырып, сол SDK мен промпттарды қалдырсаңыз, тесттер парсер мен клиент логикасы мұны көтере ме, жоқ па — тез көрсетеді.

Провайдер жартылай үйлесімді болып, жауаптар сәл ғана өзгерсе не істеу керек?

Алдымен API мен бизнес-логика арасында жұқа нормализация қабатын қосыңыз. Содан кейін табылған айырмашылықтарды тесттермен бекітіп, оларды модель, провайдер немесе SDK ауысар алдында CI-де іске қосыңыз.