🌐 Languages: 🇺🇸 English · 🇪🇹 am · 🇸🇦 ar · 🇦🇿 az · 🇧🇬 bg · 🇧🇩 bn · 🇧🇦 bs · 🇨🇿 cs · 🇩🇰 da · 🇩🇪 de · 🇬🇷 el · 🇪🇸 es · 🇪🇪 et · 🇮🇷 fa · 🇫🇮 fi · 🇫🇷 fr · 🇮🇪 ga · 🇮🇳 gu · 🇳🇬 ha · 🇮🇱 he · 🇮🇳 hi · 🇭🇷 hr · 🇭🇺 hu · 🇮🇩 id · 🇳🇬 ig · 🇮🇹 it · 🇯🇵 ja · 🇬🇪 ka · 🇰🇭 km · 🇮🇳 kn · 🇰🇷 ko · 🇱🇹 lt · 🇱🇻 lv · 🇮🇳 ml · 🇮🇳 mr · 🇲🇾 ms · 🇲🇹 mt · 🇲🇲 my · 🇳🇵 ne · 🇳🇱 nl · 🇳🇴 no · 🇮🇳 or · 🇮🇳 pa · 🇵🇭 phi · 🇵🇱 pl · 🇵🇹 pt · 🇧🇷 pt-BR · 🇷🇴 ro · 🇷🇺 ru · 🇱🇰 si · 🇸🇰 sk · 🇸🇮 sl · 🇷🇸 sr · 🇸🇪 sv · 🇰🇪 sw · 🇮🇳 ta · 🇮🇳 te · 🇹🇭 th · 🇹🇷 tr · 🇺🇦 uk-UA · 🇵🇰 ur · 🇺🇿 uz · 🇻🇳 vi · 🇳🇬 yo · 🇨🇳 zh-CN · 🇹🇼 zh-TW
Ճշմարտության աղբյուր՝
src/lib/guardrails/Վերջին թարմացումը՝ 2026-08-29 — v3.8.51 (Video Bridge-ի տրանսկրիպտի ծագումը հայտարարում է կանչողը, և այն դեռ չի ստուգվում սերվերի կողմից — հստակեցվել է ըստ #11661-ի)
Պաշտպանիչ սահմանափակումներն ապահովում են անվտանգությունը, քաղաքականությունների կիրառումը և բովանդակության փոխակերպումները
OmniRoute-ի ու վերին մակարդակի մատակարարների միջև ընկած սահմանագծում։ Յուրաքանչյուր պաշտպանիչ սահմանափակում կարող է ստուգել (և
ըստ անհրաժեշտության մերժել, փոխակերպել կամ ծանոթագրել) հարցման օգտակար բեռները (preCall) և
վերին մակարդակի պատասխանները (postCall)։
Համակարգը գործում է fail-open սկզբունքով․ եթե պաշտպանիչ սահմանափակման կատարման ընթացքում բացառություն է առաջանում, ռեեստրը
գրանցում է սխալը և հարցումը ձախողելու փոխարեն շարունակում է հաջորդ պաշտպանիչ սահմանափակմամբ։
Արգելափակումը միշտ բացահայտ որոշում է (block: true) և երբեք՝ պատահականություն։
Ռեգիստրը ավտոմատ կերպով բեռնում է վեց պաշտպանիչ՝ ըստ առաջնահերթության ներմուծման ժամանակ
(տես registry.ts → registerDefaultGuardrails()):
| Առաջնահերթություն | Անուն | Փուլ(եր) | Ֆայլ |
|---|---|---|---|
5 |
vision-bridge |
preCall |
visionBridge.ts |
6 |
audio-bridge |
preCall |
audioBridge.ts |
7 |
video-bridge |
preCall |
videoBridge.ts |
10 |
pii-masker |
pre + post |
piiMasker.ts |
20 |
prompt-injection |
preCall |
promptInjection.ts |
95 |
credential-masker |
pre + post |
credentialMasker.ts |
Ավելի ցածր առաջնահերթության համարները գործարկվում են առաջինը։
Միջամտում է պատկեր պարունակող հարցումներին, որոնք ուղղված են ոչ տեսողական մոդելներին, և կամ վերաուղղորդում է ամբողջ հարցումը տեսողական մոդելի, կամ փոխարինում է պատկերի մասերը տեքստային նկարագրություններով, որոնք ստեղծվել են կազմաձևվող տեսողական մոդելի կողմից մինչև վերին մակարդակի կանչը։ Սա թույլ է տալիս միայն տեքստային մատակարարներին թափանցիկ կերպով մշակել բազմամոդալ բեռնվածքներ։
Հոսքը:
- Բաց թողնել, եթե թիրախային մոդելն արդեն աջակցում է տեսողությանը (բացառությամբ, եթե այն հայտնվում է
պարտադրված կամրջի ցուցակում
isVisionBridgeForcedModel)։ - Հանել պատկերի մասերը
extractImageParts(messages)-ի միջոցով (visionBridgeHelpers.ts), որը պատվիրակում է միասնական մեդիա դետեկտորինdetectMediaParts()open-sse/utils/mediaParts.ts-ում — ճշմարտության միակ աղբյուրը, որը կիսվում է կոմբո համատեղելիության զտիչի հետ։ Հանումը թույլատրվում էreplaceImageParts-ի կողմից հետ տեղադրվող ձևերի վերին մակարդակի մասերին (extract↔replace պայմանագիրը): OpenAIimage_url, Anthropic base64source.type:"base64", Anthropic URLsource.type:"url", և Responses APIinput_image։ Բույն դրված հարվածները և միայն ցուցիչ ձևերը կոմբո-զտիչի նյութ են և երբեք չեն հանվում։ Բաց թողնել, եթե ոչինչ չի գտնվել։ - Լուծել runtime կոնֆիգուրացիան
resolveVisionBridgeRuntimeSettings()-ի միջոցով (src/shared/constants/modalityBridgeDefaults.ts): նորmodalityBridge*կարգավորումների բանալիները հաղթում են; հինvisionBridge*բանալիները մնում են մեկ ցիկլի պահեստային տարբերակ (հետադարձի պատուհան)։ Բաց թողնել ցանկացած մեդիա անցումից առաջ, երբ կամուրջն անջատված է։ - Ռեժիմի ընտրիչը (
modalityBridgeVisionMode, տես ստորև աղյուսակը) որոշում է վերաուղղորդել, թե նկարագրել։ Վերաուղղորդումը վերադարձնում էmodifiedPayloadմիայնmodel-ը փոխված, գումարած մետա{ rerouted, fromModel, toModel, imagesKept }։ - Նկարագրելու ուղին. սահմանափակել պատկերները
maxImages-ով, կազմել առաջադրանքին համապատասխան հուշումը, խորհրդակցել նկարագրության քեշի հետ, կանչել տեսողական մոդելը զուգահեռաբար (Promise.allSettled), և ներարկել[Image N]: <description>տեքստային մասերը իրենց տեղում։ Ձախողված նկարագրությունը տալիս էnull, և բնօրինակ պատկերի մասը պահպանվում է (#4012) — բացառությամբ կոմբո նկարագրության ուղու, երբ յուրաքանչյուր նկարագրություն ձախողվել է, որտեղ հաստատված ոչ տեսողական վերին մակարդակը ստանում է(unavailable — no vision-capable provider connected)խրոցակ (#8430)։ - Վերադարձնել
modifiedPayload+ մետա (imagesProcessed,descriptions,processingTimeMs,visionModel)։
| Ռեժիմ | Լռելյայն | Վարքագիծ |
| ---------- | ------- | Ժառանգական հևրիստիկա, անփոփոխ (#6640/#7204): ոչ կոմբո/auto/ մոդելները վերաուղղորդվում են լավագույն տեսողական մոդելին, եթե բնօրինակ մոդելն արդեն չունի օգտագործելի հավատարմագրեր (ապա նկարագրել); կոմբո թիրախները միշտ նկարագրում են։ |
| auto | ✔ | Միշտ նկարագրել — վերաուղղորդման բլոկն ամբողջությամբ բաց է թողնվում; օգտատիրոջ ընտրած մոդելը միշտ պատասխանում է։ |
| describe | | Պարտադրել վերաուղղորդումը. հավատարմագրված մոդելի պահպանման պաշտպանիչը շրջանցվում է։ Վերաուղղորդման-թիրախային հավատարմագրի պաշտպանիչը դեռ կիրառվում է — երբ օգտագործելի տեսողական թիրախ գոյություն չունի, հարցումը անցնում է նկարագրելու, որպեսզի հում պատկերները երբեք չհասնեն միայն տեքստային backend-ին (#8430)։ |
| reroute | | |
Պարտադրված ռեժիմները կարճ միացում են կատարում մինչև ավտոմատ հևրիստիկայի գործարկումը; auto
վարքագիծը բայթ-նույնական է մինչև PR-1 պաշտպանիչին։
Լռելյայն true։ composeVisionPrompt() (visionBridgeHelpers.ts) ավելացնում է
վերջին օգտատիրոջ հաղորդագրության տեքստը (կտրված մինչև 500 նիշ) հիմնական
նկարագրության հուշմանը, ուղղորդելով նկարագրությունը դեպի այն, ինչ օգտատերն իրականում
խնդրել է (codex-vision-proxy օրինակ) և խնդրելով տեսողական մոդելին արտագրել տեսանելի
տեքստը։ Եթե դրոշակն անջատված է — կամ օգտատիրոջ տեքստ չկա — հիմնական հուշումն
օգտագործվում է անփոփոխ։
describe ինքնաշրջանի սեփական OpenAI-համատեղելի հարցումը (callVisionModelSingle()
visionBridgeHelpers.ts-ում) միշտ հարցնում է image_url.detail: "high" —
անվերապահորեն, յուրաքանչյուր զանգահարողի/մատակարարի համար, առանց որևէ հաճախորդի ազդանշանի։
Ցածր մանրամասնության նմուշառումը վատթարացնում է OCR-ի ճշգրտությունը հենց այն տեքստի-տառադարձման
խնդրի համար, որը պահանջում է այս հուշումը, ուստի describe զանգը ինքնին միշտ պահանջում է բարձր
մանրամասնություն՝ անկախ նրանից, թե ինչ մանրամասնության մակարդակ է օգտագործել սկզբնական մուտքային հարցումը։ Սա
ազդում է միայն ներքին describe հարցման մարմնի վրա. այն չի փոխում, թե ինչպես է
OmniRoute-ը փոխանցում զանգահարողի սեփական image_url.detail-ը հիմնական հարցման վրա —
այդ լռելյայնը կիրառվում է առանձին, և միայն հայտնաբերված OpenCode հաճախորդների համար,
defaultImageDetail()-ում (open-sse/handlers/chatCore/upstreamBody.ts)։
describe ինքնաշրջանի Anthropic wire-format ճյուղը չունի detail դաշտ
և չի ազդում ոչ մի լռելյայնից։
| Բանալի | Լռելյայն | Միջակայք |
|---|---|---|
modalityBridgeVisionMaxChars |
0 |
0 կամ 100–50000 |
0 (լռելյայն) նշանակում է առանց սահմանափակման — callVisionModel()-ի կողմից վերադարձված նկարագրությունը
փոխանցվում է անփոփոխ, պահպանելով առկա վարքագիծը։ 100–50000 միջակայքի ցանկացած արժեք կտրում է նկարագրությունը
… վերջածանցով, նախքան այն հետ կմիացվի որպես [Image N]: <description>
(VisionBridgeGuardrail.preCall() src/lib/guardrails/visionBridge.ts-ում)։
Բարձրացրեք սա մանրամասն OCR խնդիրների համար, որտեղ ներքևի մոդելին անհրաժեշտ է
ամբողջական տառադարձումը. իջեցրեք այն՝ զրուցող տեսողական մոդելների վրա թոքենների օգտագործումը սահմանափակելու համար։
Վահանակի դաշտը գտնվում է Vision ներդիրի Advanced վահանակում
(modality-bridge-max-chars ModalityBridgeVisionTab.tsx-ում) և ցանկացած արժեք 1-ից 99-ի միջև
սահմանափակում է մինչև 100-ի ստորին շեմը՝ թողնելով բացահայտ 0-ը
անձեռնմխելի — 0-ը ինքնին վավեր Zod արժեք է
(z.union([z.literal(0), z.number().int().min(100).max(50000)])), ոչ թե պարզապես
«չսահմանված» լռելյայն։
Հիշողության մեջ LRU + TTL քեշ նկարագրության ելքերի համար, որը կիսվում է ամբողջ գործընթացով։
Բանալին = sha256(imageRef + composedPrompt + configuredBridgeModel) երկարության-նախածանցային շրջանակով
(առանց դաշտի-սահմանի բախումների)։ Մոդելի բաղադրիչը կարգավորված կամրջի մոդելն է,
ոչ թե այն մոդելը, որն իրականում պատասխանել է — callVisionModel-ը կարող է ներքինորեն հետ ընկնել,
և յուրաքանչյուր փորձի համար բանալիավորումը կքանդեր քեշը։ Ձախողված նկարագրությունները երբեք չեն քեշավորվում։ Կարգավորումներ.
| Բանալի | Լռելյայն | Միջակայք |
|---|---|---|
modalityBridgeCacheEnabled |
true |
— |
modalityBridgeCacheTtlMinutes |
60 |
1–1440 |
modalityBridgeCacheMaxEntries |
200 |
10–5000 |
Երբ կամուրջը ինքն է բեռնում հեռավոր պատկեր — Anthropic-ի նկարագրության ինքնազանգը
և claude-wire-format base64 փոխակերպումը (ensureBase64ImagesForClaudeWire), երկուսն էլ
fetchRemoteImageAsDataUri()-ի միջոցով visionBridgeHelpers.ts-ում — ստացված տվյալների URI-ն
անցնում է normalizeDataUri()-ի միջով
(open-sse/utils/imageNormalize.ts), նախքան տեսողական մոդելի հարցման մեջ ներդրվելը։
Չափից մեծ պատկերները փոքրացվում են մինչև 2048px երկար կողմ (համապատասխանելով
OpenAI/Anthropic-ի կողմից արդեն սերվերի կողմից կիրառվող չափափոխման սահմանափակմանը), ինչը կրճատում է
վերբեռնման բայթերը/ուշացումը՝ առանց փոխելու այն, ինչ տեսնում է տեսողական մոդելը։ Չափափոխումը
օգտագործում է sharp, որը բեռնվում է դինամիկ ներմուծման միջոցով. այն հարթակում, որտեղ դրա բնիկ
երկուական ֆայլը չի բեռնվում, normalizeDataUri()-ը երբեք սխալ չի տալիս — այն հետ է ընկնում
բնօրինակ բայթերի փոխանցմանը, ուստի նկարագրության/base64-փոխակերպման
ուղին միշտ շարունակում է աշխատել։ Ոչ պատկերային բայթերը (բեռնում, որը չի վերադարձրել
վերծանվող պատկեր) նույնպես փոխանցվում են անձեռնմխելի։ Այս նորմալացումը
վերաբերում է այն պատկերներին, որոնք կամուրջը բեռնում է իր ինքնազանգի համար — այն երբեք
չի կիրառվում զանգահարողի հում փոխանցման բեռնվածքի վրա, համահունչ
միայն ընտրովի փոփոխության սկզբունքին (Կոշտ կանոն #20)։
Նոր modalityBridge* բանալիները Zod-ով վավերացվում են updateSettingsSchema-ում
(src/shared/validation/settingsSchemas.ts): modalityBridgeVisionEnabled,
modalityBridgeVisionMode, modalityBridgeVisionModel,
modalityBridgeVisionTaskAware, modalityBridgeVisionPrompt,
modalityBridgeVisionTimeout, modalityBridgeVisionMaxImages,
modalityBridgeVisionMaxChars, modalityBridgeCache* եռյակը, և
modalityBridgeAudio* խումբը, որն օգտագործվում է Audio Bridge-ի կողմից։ Միգրացիա
141_modality_bridge_settings.sql-ը պատճենում է առկա հին
visionBridge* արժեքները համապատասխան նոր բանալիներին (իդեմպոտենտ, երբեք չի վերագրում
օպերատորի կողմից սահմանված modalityBridge* արժեքը); հին բանալիները մնում են ընդունված որպես
կարդալու պահեստային տարբերակ մեկ թողարկման ցիկլի համար։
Նկարագրությամբ փոխակերպված պատասխանները կրում են
x-omniroute-modality-bridge: image->text;model=<visionModel>;parts=<n>
(կառուցված է buildModalityBridgeHeader()-ի կողմից modalityBridge/bridgeStats.ts-ում,
կնքված է withModalityBridgeHeader()-ի կողմից src/sse/handlers/chatHelpers.ts-ում)։
Վերաուղղորդված հարցումները չեն ստանում վերնագիր — բեռնվածքը անձեռնմխելի է մնացել, և մոդելի
փոխանակումն արդեն տեսանելի է պատասխանի մարմնի model դաշտում։
GET /api/modality-bridge/stats (կառավարման թույլտվություն, նույն մակարդակը, ինչ
GET /api/settings) վերադարձնում է հիշողության մեջ յուրաքանչյուր մոդալության հաշվիչները
{ attempts, successes, bridged, cacheHits, failures, totalLatencyMs, latencySamples, averageLatencyMs, lastUsedAt } vision, audio և
video-ի համար։ averageLatencyMs-ը օգտագործում է latencySamples, ոչ թե բոլոր փորձերը, որպես իր
հայտարար. ժամանակավորում չունեցող գործողությունը զրո-միլիվայրկյան նմուշ չի ստեղծում։
bridged-ը մնում է հետադարձ համատեղելի մականուն հաջող փոխակերպումների համար.
ձախողված փորձերը չեն ավելացնում այն։
Հաշվիչները վերականգնվում են գործընթացի վերագործարկման ժամանակ ըստ նախագծի
(հեռաչափություն, ոչ հաշվապահություն)։
Նվիրված վահանակի էջը /dashboard/settings/modality-bridge է։ Դրա URL-ով հասանելի Vision, Audio և Video ներդիրները պահպանում են հարցման պարամետրերը՝ միաժամանակ փոխելով tab արժեքը։
Vision ներդիրը բացահայտում է միացումը, ռեժիմը, մոդելի ընտրությունը (ներառյալ ավտոմատ լռելյայնը), առաջադրանքին համապատասխան հուշումները, ընդլայնված ժամանակի սահմանաչափերը/պատկերների/նկարագրության երկարության/քեշի սահմանաչափերը, կատարման հաշվիչները և պաշտպանված նմուշի հարցումը։ Audio ներդիրը նույնպես ակտիվ է. այն բացահայտում է միացումը, STT-միայն մոդելի ընտրիչը Auto-ով, ժամանակի սահմանաչափերը/առավելագույն կլիպի սահմանաչափերը, աուդիո հաշվիչները և input_audio նմուշի թեստը։ Video ներդիրը ֆունկցիոնալ է. այն հաղորդում է FFmpeg/ffprobe-ի կատարման վիճակը՝ չորս հստակ UI վիճակներից մեկը (unknown մինչդեռ զոնդը գործում է կամ չի կարողացել ավարտվել, restricted ոչ-loopback վահանակի հոսթի վրա, որտեղ զոնդը բաց է թողնվում հաճախորդի կողմից, unavailable զոնդավորվելուց և բացակայությունը հաստատվելուց հետո, կամ available FFmpeg/ffprobe տարբերակներով) — պահպանում է միացման/մոդելի/կադրի/տեսանյութի/ժամանակի սահմանաչափերը, զտում է մոդելի ընտրիչը տեսողական հնարավորություններ ունեցող մոդելների համար և բացահայտում է տեսանյութի հաշվիչները։
Նախկին Vision Bridge քարտը AI կարգավորումների ներքո համատեղելիության հղում է դեպի նոր էջը. այն այլևս չունի ձևի երկրորդ պատճենը։ Media Providers-ը նաև կապում է Image-to-Text և Speech-to-Text աշխատանքային հոսքերը համապատասխան Modality Bridge ներդիրներին՝ առանց առկա Speech-to-Text խաղահրապարակը հեռացնելու։
Self-loop մուտքի շրջանցում. երբ նկարագրության կանչը OmniRoute-ի սեփական /v1 self-loop-ի միջոցով է (ոչ ստանդարտ մատակարարի մոդել), ենթահարցումն ուղարկում է x-omniroute-admission-bypass: internal և վավերացվում է լուծված self-loop հավատարմագրով՝ տեղական sk_omniroute պահակը տեղական ռեժիմում, կամ օպերատորի կողմից կազմաձևված OMNIROUTE_API_KEY / ROUTER_API_KEY միջավայրի բանալին (#1350), որպեսզի REQUIRE_API_KEY=true տեղակայումները դեռ կարողանան կատարել նկարագրության կանչը։ Շրջանցումը հարգվում է միայն այդ ճշգրիտ հավատարմագրերի համար, ուստի արտաքին հաճախորդները չեն կարող օգտագործել վերնագիրը մուտքը բաց թողնելու համար։
Հին լռելյայն արժեքները գտնվում են src/shared/constants/visionBridgeDefaults.ts-ում. նոր ռեժիմի/առաջադրանքին համապատասխան/քեշի լռելյայն արժեքները և կարգավորումների լուծիչը գտնվում են src/shared/constants/modalityBridgeDefaults.ts-ում։ Պաշտպանիչ մեխանիզմը բացահայտում է deps կոնստրուկտորի տարբերակը, որպեսզի թեստերը կարողանան ներարկել կեղծ getSettings և callVisionModel իրականացումներ։
Արգելափակում է ձայն պարունակող չաթի հարցումները, նախքան դրանք կհասնեն այն թիրախին, որը հայտնի չէ, որ ընդունում է ձայնային մուտք։ Այն երբեք չի վերաուղղորդում չաթի հարցումը. ձայնային մասերը տառադարձվում են առկա OpenAI-համատեղելի բազմամաս վերջնակետի միջոցով, և ընտրված չաթի մոդելը շարունակում է տեքստային տառադարձերով։
Հոսքը.
- Լուծել
supportsAudio-նgetResolvedModelCapabilities()-ի միջոցով։ Հստակ մատակարար-ռեգիստրի մետատվյալները հաղթում են, այնուհետև ստատիկ մոդելի մետատվյալները, այնուհետև համաժամեցվածmodalities_input-ը։ Հայտարարված մուտքային ցուցակը առանցaudio-իfalseէ. ունակության ապացույցի բացակայությունը մնում էnull։ Ե՛վfalse-ը, և՛null-ը ակտիվացնում են պահպանողական կամուրջը, մինչդեռtrue-ն շրջանցում է այն։ - Լուծել
modalityBridgeAudio*կարգավորումները և արդյունահանել բաժանելի վերին մակարդակի ձայնային մասերը յուրաքանչյուր հաղորդագրությունից՝ ընդհանուրdetectMediaParts()դետեկտորի միջոցով։ Աջակցվող մետաղալարերի ձևերն են OpenAIinput_audio,audio_urlևsource.media_type: "audio/*"։ Բույն դրված ձայնը հայտնաբերվում է երթուղիավորման համար, բայց չի հեռացվում բաժանման ուղու միջոցով։ Աշխատանքը սահմանափակվում էmodalityBridgeAudioMaxClips-ով. ավելի ուշ մասերը մնում են անձեռնմխելի։ - Հարգել կազմաձևված
provider/model-ը, կամ թույլ տալselectAudioBridgeModel()-ին անցնելAUDIO_TRANSCRIPTION_PROVIDERS-ի միջով կայուն կատալոգի կարգով և ընտրել առաջին մոդելը՝ օգտագործելի ակտիվ մատակարարի հավատարմագրով։ callAudioTranscription()-ը base64/data-URI ձայնը փոխակերպում է բազմամասfile-ի, կամ ներբեռնում է հեռավորaudio_urlհանրային-միայն արտաքին պաշտպանիչի միջոցով՝ DNS ամրացմամբ և 25 ՄԲ սահմանաչափով։ Այնուհետև այն POST է անում ֆայլը և ընտրված մոդելը տեղական/v1/audio/transcriptionsself-loop-ին, վավերացվածresolveSelfLoopBearer()-ով։ Առկա տառադարձման երթուղին կատարում է սովորական հավատարմագրի որոնում, սառեցման/սահմանաչափի մշակում և մատակարարի ուղարկում։- Հաջող կանչերը փոխարինում են իրենց մասերը
[Audio N]: <transcript>-ով։ Կանչերը գործում ենPromise.allSettled-ով. անհատական ձախողումը պահպանում է այդ բնօրինակ ձայնային մասը (#4012 պայմանագիր)։ Եթե յուրաքանչյուր կանչ ձախողվում է, և թիրախը ապացուցված էsupportsAudio === false, ապա մասերը դառնում են[Audio N]: (unavailable — no STT provider connected)(#8430 պայմանագիր)։ Անհայտ թիրախի (null) դեպքում բոլոր ձախողումների արդյունքը մնում է անձեռնմխելի։ Ապացուցված տեքստային-միայն թիրախը՝ առանց օգտագործելի STT հավատարմագրի, ստանում է նույն հստակ խրոցակը՝ առանց ցանցային կանչ կատարելու։
Հաջող տառադարձերը օգտագործում են գործընթացի լայն Modality Bridge LRU/TTL քեշը։ Բանալին համատեղում է ձայնային հղումը, կայուն audio-transcription գործողության պիտակը և ընտրված STT մոդելը. ձախողումները երբեք չեն քեշավորվում։ Ձայնային փորձերը թարմացնում են ընդհանուր bridged, cacheHits, failures և lastUsedAt հաշվիչները։ Փոխակերպված պատասխանները կրում են x-omniroute-modality-bridge: audio->text;model=<sttModel>;parts=<n>; անձեռնմխելի հարցումները չեն ստանում Audio Bridge հատված։
Կատարման կարգավորումները DB-ի վրա հիմնված են և Zod-ով վավերացված.
| Key | Default | Range |
|---|---|---|
modalityBridgeAudioEnabled |
true |
— |
modalityBridgeAudioModel |
"" |
Auto կամ STT ID |
modalityBridgeAudioTimeout |
60000 |
1000–300000 |
modalityBridgeAudioMaxClips |
3 |
1–10 |
Ընդհանուր քեշը մնում է վերահսկվող modalityBridgeCacheEnabled, modalityBridgeCacheTtlMinutes և modalityBridgeCacheMaxEntries միջոցով։
Որսում է բարձր մակարդակի տեսանյութի մասեր Chat Completions messages-ում և Responses
API input-ում՝ նախքան թիրախի կանչվելը՝ առանց հայտնի բնիկ տեսանյութի աջակցության:
Աջակցվող ձևերն են՝ input_video, video_url, video_source, HTTPS URL-ներ,
և data:video/*;base64,... տվյալների URI-ներ: Տեքստում սովորական ֆայլերի անունները
չեն դիտարկվում որպես տեսանյութ:
VideoBridgeGuardrail.preCall (videoBridge.ts) ապահովում է հարցումների անցումը,
հնարավորությունների/քաղաքականության ստուգումը, ըստ հարցումների ագրեգացումը և
պատասխանի բեռնվածությունը:
Յուրաքանչյուր տեսանյութի աշխատանքը՝ ձեռքբերումը, ամբողջական արդյունքի քեշը,
կադրերի հաջորդականության նկարագրությունը (որը միաձուլում է ցանկացած կանչողի
կողմից հայտարարված աուդիո տրանսկրիպտը) և յուրաքանչյուր փորձի չափումները/ընդհատումը/մաքրումը
թաքնված է processVideoPart-ի հետևում՝ videoBridgePipeline.ts-ում, որը կանչվում է
մեկ անգամ յուրաքանչյուր տեսանյութի մասի համար preCall-ի ցիկլի ներսում:
Այդ մոդուլը նաև սահմանում է հստակ պորտերի սահմանները՝ VideoMediaBrokerPort
(բայթերի ձեռքբերում և նմուշառված կադրերի արդյունահանում), VideoAudioTranscriptionPort
(կանչողի կողմից հայտարարված աուդիո տրանսկրիպտի միաձուլում նմուշառված ենթագրերի հետ) և
VideoDrilldownPort (կադրերի մանրամասնության պահպանման սահմանը. դեռևս միացված չէ
processVideoPart-ին. այսօր միայն առանձին /api/modality-bridge/video/drilldown
երթուղին է գրում մանրամասնության գրառումներ):
Հանրային /v1 հարցումների ուղին երբեք չի ներմուծում կամ կանչում ենթապրոցես: Հեռավոր
տեսանյութերը ներբեռնվում են 50 ՄԲ սահմանաչափով. ներկառուցված base64 տեսանյութերը
ունեն պահպանողական 36 ՄԲ ապակոդավորված յուրաքանչյուր տեսանյութի սահմանաչափ, որպեսզի
մոդելը/հաղորդագրությունները/կադրավորման ծրարը մնան 50 ՄԲ հանրային JSON հարցումների
ընդունման սահմանաչափի ներսում: Ներկառուցված երկարության և ապակոդավորված չափի գնահատումները
ստուգվում են նախքան հատկացումը: HTTPS-ը պահանջվում է սկզբնական հեռավոր URL-ի և
յուրաքանչյուր վերահղման համար՝ օգտագործելով գոյություն ունեցող միայն հանրային ելքային
պաշտպանությունը DNS ամրացումով: Այնուհետև բայթերը հատում են ճշգրիտ ներքին
POST /api/modality-bridge/video/extract բրոքերի սահմանը: Այդ երթուղին և՛
LOCAL_ONLY է, և՛ SPAWN_CAPABLE, ընդունում է միայն յուրաքանչյուր պրոցեսի համար
վավերացված, վստահելի լուփբեք հարցում և երբեք չի ընդունում URL, ֆայլային համակարգի ուղի,
կատարվող ֆայլ կամ արգումենտների ցուցակ: API մարմնի չափի խողովակաշարը և հենդլերի
աճող մարմնի ընթերցիչը անկախաբար կիրառում են 50 ՄԲ բրոքերի մուտքային սահմանաչափ:
Դրա սահմանափակ հերթը միաժամանակ կատարում է մեկ արդյունահանում, թույլ է տալիս չորս
սպասվող աշխատանք և սահմանափակում է սպասվող մուտքը 100 ՄԲ-ով:
Բրոքերի ներսում ffprobe-ը կարդում է մասնավոր տեղական ֆայլ. ֆիքսված ձևաչափի
թույլատրված ցուցակը բացառում է երգացանկի և մանիֆեստի ձևաչափերը: Թույլատրված MOV-ընտանիքի
կոնտեյներների համար արտաքին MOV տվյալների հղումները մնում են անջատված լռելյայն, և
ֆիքսված հրամանը դրանք չի ընդունում: Ե՛վ ffprobe-ը, և՛ ffmpeg-ը օգտագործում են
միայն file արձանագրության սպիտակ ցուցակը, մեկ թել, ֆիքսված արգումենտների զանգվածներ,
առանց shell-ի և PATH-ից լուծված կատարվող ֆայլեր: Կցված նկարի շապիկի հոսքերը
նվագարկվող թեկնածուներ չեն: Բոլոր նվագարկվող հոսքերը պետք է բավարարեն սահմանափակումները,
և հստակ լռելյայն հոսքը նախընտրելի է մինչև դետերմինիստական ամենացածր ինդեքսի անկումը:
Տեսանյութերը սահմանափակված են 600 վայրկյանով, 8,192 պիքսելով յուրաքանչյուր չափումով և
33,554,432 աղբյուրի պիքսելներով: FFmpeg-ը նմուշառում է 1–16 միջին JPEG կադրեր,
փոքրացնում է երկար կողմը մինչև առավելագույնը 1,024 պիքսել՝ առանց փոքր մուտքերի
մեծացման, և երբեք չի ստանում URL: Նմուշառումը լռելյայն uniform է: Ընտրովի
scene_aware և փորձարարական segment_aware քաղաքականությունները կատարում են
մեկ լրացուցիչ ֆիքսված FFmpeg անցում արդեն վավերացված տեղական հոսքի վրայով,
ընտրում են սահմանափակ showinfo տեսարանի ժամանակային դրոշմներ և դետերմինիստորեն
վերադառնում են նույն միատեսակ միջին կետերին՝ դետեկտորի ձախողման, ժամանակի սպառման,
սխալ ձևավորված ելքի կամ դատարկ թեկնածուների հավաքածուի դեպքում: Սեգմենտի գիտակցված
ռեժիմը հատկացնում է միջին կետի նմուշներ՝ համաչափ վավերացված տեսարանի ինտերվալներին.
սեգմենտի գիտակցված ապացույցները և անկման վարքագիծը մանրամասնված են ստորև:
Կոշտ 16-կադրային սահմանաչափը կիրառվում է ընտրությունից հետո յուրաքանչյուր քաղաքականության
մեջ: Երբ տեսարանին գիտակցված հարցումը ունի ընդամենը մեկ կադրի բյուջե, այն օգտագործում է
ակտիվ ամբողջական տեսանյութի կամ ֆոկուսի պատուհանի միատեսակ միջին կետը և հաղորդում է
policyEffective: uniform. մեկ ընտրված տեսարանի կադրը չի կարող պահպանել երկու ժամանակային
ծայրերը: Կանչողը կարող է ընտրովիորեն տրամադրել վերջավոր ֆոկուսի պատուհան (start/end
վայրկյաններ). սահմանները սեղմվում են մեդիայի տևողությանը, շրջված կամ անվերջ պատուհանները
մերժվում են, և բոլոր նմուշառման քաղաքականությունները կատարվում են միայն նորմալացված
ինտերվալի ներսում: Արդյունքում ստացված պատուհանը ներառվում է նմուշառման մետատվյալներում
և անվստահելի նկարագրության նախածանցում, որպեսզի ներքևի մոդելները կարողանան տարբերել
կենտրոնացված հատվածը ամբողջ ժամանակացույցից:
Սեմանտիկ ենթագրերի ֆոկուսը առանձին, հստակ կարգավորում է: Լռելյայն full վերլուծության
ռեժիմը պահպանում է գոյություն ունեցող կադրի հուշումը և երբեք չի փոխանցում հարցման տեքստը
ենթագրերի մոդելին: focused ռեժիմում կամուրջը կարդում է միայն վերջին ոչ դատարկ
օգտատիրոջ կողմից ստեղծված text/input_text նույն Chat կամ Responses կոնտեյներից,
նորմալացնում է այն NFC-ին, փլուզում է կառավարման նիշերը և բացատները և սահմանափակում է
այն 500 Unicode կոդային կետերով: Դատարկ արդյունքը վերադառնում է ճշգրիտ full հուշմանը:
Օգտագործելի հուշումը սերիալիզացվում է որպես JSON հատուկ անվստահելի օգտատիրոջ համատեքստի
բլոկում և կարող է միայն առաջնահերթություն տալ դիտարկելի մանրամասներին. այն չի կարող
չեղարկել առանձին նախազգուշացումը մեդիայում տեսանելի կամ լսելի հրահանգներին հետևելու
դեմ: Տեքստային ֆոկուսը երբեք չի ենթադրում start/end կամ չի փոխում ժամանակային
նմուշառիչը:
segment_aware-ը օգտագործում է մեկ սահմանափակ նախնական վերլուծության անցում արդեն
վավերացված տեղական տեսանյութի հոսքի վրայով: Ֆիքսված ֆիլտրի շղթան նախ սանդղակավորում է
մինչև առավելագույնը 320 պիքսել լայնությամբ, հայտնաբերում է տեսարանի փոփոխությունները
և սառեցված ինտերվալները, այնուհետև նմուշառում է 1 կադր վայրկյանում՝ լղոզման, միջին
լյումայի և տարածական/ժամանակային տեղեկատվության համար: Անցումը սահմանափակված է
600 կառուցվածքային նմուշներով, մեկ FFmpeg/ֆիլտրի թելով, նույն file-միայն արձանագրության
և կոնտեյների թույլատրված ցուցակներով, 1 ՄԲ պրոցեսի ելքային սահմանաչափով և առավելագույնը
30 վայրկյանով բրոքերի ընդհանուր ընդհատման/վերջնաժամկետի ներսում: Այն երբեք չի ընդունում
հրաման, ֆիլտր, ուղի կամ URL հարցումից:
Կառուցվածքային արժեքները դետերմինիստական նմուշառման ապացույցներ են, ոչ թե իմաստային տեսանյութի ընկալում։ Դրանք չեն ենթադրում առարկաներ, գործողություններ, ենթագրեր, խոսք կամ օգտատիրոջ մտադրություն։ Տեսարանների և սառեցման սահմանները ձևավորում են հատվածներ. սառեցման ծածկույթը, լղոզումը, լուսարձակումը, տարածական մանրամասները և ժամանակավոր փոփոխությունները միայն ազդում են, թե ինչպես է բաշխվում առկա 1–16 կադրերի բյուջեն։ Ամբողջությամբ սառեցված հատվածը սահմանափակվում է մեկ կադրով, մինչդեռ չսառեցված հատվածները մրցում են մնացած բյուջեի համար։ Երբ սահմանները գերազանցում են կադրերի քանակը, պահպանվում է ժամանակացույցի միատեսակ ծածկույթը, որպեսզի արագ վաղ կտրվածքները չկարողանան թաքցնել երկար հետևող հատվածը։ Սառեցման սահմանի 1 վայրկյանի վերլուծության լուծաչափի ներսում գտնվող տեսարանների սահմանները միաձուլվում են։
Բացակայող ֆիլտրերը, սխալ ձևավորված/դատարկ ապացույցները, դետեկտորի սխալը կամ սահմանափակված նախնական վերլուծության ժամանակի սպառումը բաց են թողնում ճշգրիտ միատեսակ միջին կետի քաղաքականությանը։ Զանգահարողի ընդհատումը կամ բրոքերի վերջնաժամկետը բաց չի թողնում. այն դադարեցնում է ընթացիկ ենթապրոցեսը, կանխում է հետագա կադրերի արդյունահանումը, և մասնավոր ժամանակավոր ծառը հեռացվում է finally-ում։
scripts/perf/video-bridge-fu07-eval.ts-ը ստեղծում է դետերմինիստական իրական FFmpeg ֆիքսատորներ՝ հետ-դեդուպ ենթագրերի կանչերի խնայողությունների, խիտ շարժման բյուջեի բաշխման, լղոզման/լուսարձակման/SI-TI ապացույցների, երկար պոչով արագ կտրվածքների և աստիճանական մարման կեղծ դրական արդյունքների համար։ Այն գրանցում է նախնական վերլուծության պատի ժամանակը և, որտեղ /usr/bin/time-ը հասանելի է, երեխա CPU-ի և գագաթնակետային RSS-ի տվյալները։ Դրա որակի ստուգումները միայն կառուցվածքային օրակուլներ են։ Իրական ենթագրերի մոդելի որակը մնում է HOLD, քանի որ այս հարմարանքը չունի լիազորված վերջնակետ կամ սառեցված դատավոր։ Դրամական խնայողությունները նույնպես մնում են HOLD, եթե --caption-cost-per-call-usd-ը չի տրամադրում հստակ դրական մեկ կանչի գնահատական. սկրիպտը երբեք չի կեղծում որևէ արդյունք։
Յուրաքանչյուր կադր սահմանափակված է 4 ՄԲ-ով, բոլոր հում կադրերը միասին՝ 23 ՄԲ-ով, իսկ սերիալիզացված բրոքերի պատասխանը՝ 32 ՄԲ-ով։ Մասնավոր ժամանակավոր գրացուցակը հեռացվում է finally-ում։ OmniRoute-ը չի փաթեթավորում FFmpeg-ը և չի ընդունում հատուկ կատարվող ճանապարհ։ Ենթագրելուց առաջ կամուրջը կիրառում է պահպանողական վիզուալ կրկնօրինակման անցում. յուրաքանչյուր JPEG նվազեցվում է մինչև 16×16 գորշ երանգների բուֆեր և համեմատվում է միայն պահպանված վերջին կադրի հետ։ Մեկ կադրից ավելի պահանջվող ենթագրերի բյուջեի համար արդյունահանումը տրամադրում է սահմանափակ թեկնածուների հավաքածու՝ մինչև այդ բյուջեի կրկնապատիկը և երբեք ավելի քան 16 կադր։ Պահանջվող սահմանափակումը կիրառվում է միայն կրկնօրինակումից հետո, ընտրված առաջին և վերջին թեկնածուները պահպանվում են վերջնական նոսրացման ժամանակ, երբ բյուջեն առնվազն երկու է։ Տարբերակված grayscale-16x16-mean-cells-v2 քաղաքականությունը օգտագործում է միջին լյումա դելտայի և մանրապատկերների բջիջների հարաբերակցության ավելի մեծը, որոնց նորմալացված դելտան առնվազն 0.05 է։ Կրկնօրինակման շեմը հաստատուն 0.04 է, որն ընտրված է կանխատեսելիության համար, այլ ոչ թե բացահայտված որպես գործարկման կարգավորում։ Այս երկրորդական բարձր կոնտրաստի ազդանշանը պահպանում է փոքր շարժումները և տեսանելի տեքստի փոփոխությունները, որոնք միայն միջինի համեմատությունը կարող է թաքցնել։ Համեմատիչի կամ դեկոդերի սխալները բաց են թողնում և պահպանում ծածկույթը։ Ելքային մետատվյալները առանձնացնում են արդյունահանված թեկնածուները, հաջողությամբ օգտագործված կադրերը և հեռացված վիզուալ կրկնօրինակները։
Հստակ նշված տեսանյութի մասը կարող է պահանջել ժամանակային կոնտակտային թերթիկ։ Կամուրջը կառուցում է առավելագույնը 4 սյունակից, 16 կադրից բաղկացած JPEG ցանց։ Յուրաքանչյուր 512 պիքսելանոց բջիջը իր աղբյուրի ժամանակային դրոշմը այրում է բարձր կոնտրաստի ներքևի շերտի մեջ, մինչդեռ նույն ժամանակային դրոշմները մնում են տեքստային մետատվյալներում՝ հետագա կապի և աուդիտի համար։ Ամբողջական JPEG-ը մնում է սահմանափակված 32 ՄԲ-ով։ Եթե sharp-ը չի կարողանում վերծանել կամ կազմել ցանցը, կամուրջը վերադառնում է առանձին JPEG կադրերին. հաճախորդի ընդհատումը դեռևս տարածվում է թերթիկի գործողության միջոցով։
Խթանման ապացույցները միտումնավոր առանձնացված են սինթետիկ կոմպոզիցիայի միկրոբենչմարկից։ scripts/perf/video-bridge-contact-sheet-eval.ts-ը սահմանում է սխեմա-տարբերակված A/B հարմարանք իրական OpenAI-համատեղելի տեսողական մոդելների համար։ Այն չափում է մատակարարի կողմից հաղորդված թոքենները, վերջից-վերջ պատի ուշացումը (ներառյալ թերթիկի կոմպոզիցիան), մոդելի կանչերի քանակը և մանիֆեստով սահմանված փաստերի պահպանումը։ Հում մոդելի պատասխանները չեն գրվում զեկույցում. պահպանվում են միայն SHA-256 ամփոփագրերը և համապատասխան փաստերի ID-ները։ Հարմարանքը ցանցային կամ վճարովի մոդելի կանչ չի կատարում, եթե --execute-real-ը չի փոխանցվում և --model, OMNIROUTE_BASE_URL և OMNIROUTE_API_KEY չեն կազմաձևվում։ Առանց այդ հստակ իրական գործարկման, դրա մեքենայական ընթեռնելի վճիռը մնում է HOLD. սինթետիկ բեռնվածության/կանչերի քանակի չափումները միայն խթանման ապացույց չեն։
Զանգահարողները կարող են կցել կամընտիր transcript.cues զանգվածը աջակցվող տեսանյութի մասին, երբ նրանք արդեն ունեն համաձայնեցված տեքստ։ Յուրաքանչյուր ազդանշան պետք է պարունակի text, վերջավոր start/end միջակայք զննված տևողության ներսում և սպիտակ ցուցակում ներառված source (client, embedded կամ audio-bridge). confidence-ը լռելյայն 1 է և պետք է մնա 0-ի և 1-ի միջև։ Ճշգրիտ կրկնօրինակ ազդանշանները միաձուլվում են։ OmniRoute-ը երբեք չի սկսում տառադարձումը այս մետատվյալներից. վավերացված ազդանշանները պատճենվում են նկարագրված արդյունքի մեջ՝ աղբյուրով, վստահությամբ և միջակայքով, և ներկայացվում են որպես անվստահելի դիտարկումներ՝ կադրերի ենթագրերի կողքին։ Անվավեր, միջակայքից դուրս կամ ծագումնաբանությունից զուրկ տեքստը մերժվում է, այլ ոչ թե խառնվում ենթագրերի հոսքի մեջ։ source դաշտը ներկայումս հայտարարվում է զանգահարողի կողմից, ոչ թե սերվերի կողմից ստուգվում. OmniRoute-ը պարտադրում է, որ արժեքը լինի երեք թույլատրված տողերից մեկը, բայց դեռևս գաղտնագրորեն չի հաստատում, որ embedded կամ audio-bridge պիտակը իրականում սերվերի սեփական արդյունահանումից է։ Վերաբերվեք source-ին որպես անվստահելի հուշում, մինչև այդ ստուգումը տեղի ունենա. մի կառուցեք թույլտվության որոշումներ դրա վրա։
Առաջադեմ զանգահարողը կարող է տրամադրել արդեն թույլատրված audioTranscript հետք
նույն տեսանյութի համար։ Ֆյուժնի կարը տեսողական և ձայնային դիտարկումները
միավորում է մեկ վերջնաժամկետի և ընդհատման ազդանշանի ներքո, դրանք դասավորում է
ընդհանուր ժամանակացույցի վրա, միավորում է ճշգրիտ կրկնօրինակները և հաղորդում
մասնակի արդյունք, երբ միայն մեկ կողմն է հաջողում։ Անվավեր audioTranscript-ը
վերածվում է այդ մասնակի արդյունքի՝ տեսողական նկարագրությունը պահպանվում է, իսկ
ձայնային ճյուղը գրանցում է մաքրված ձախողման կոդ՝ ամբողջ տեսանյութը ձախողելու
փոխարեն։ Յուրաքանչյուր ճյուղի հասանելիությունը, մասնակի դրոշը և մաքրված
ձախողման կոդերը պահպանվում են նկարագրված արդյունքում, պաշտպանիչ
մետատվյալներում (audioFusionRuns/audioFusionPartials/
audioFusionFailureCodes), արդյունքների քեշի մետատվյալներում և կամրջի
ֆյուժնի հաշվիչներում։ Լռելյայն Video Bridge ուղին չի կանչում խոսքի-տեքստի
փոխակերպում կամ երկրորդ մեդիա պատճեն չի ներբեռնում. առանց այդ հստակ հետքի,
այն մնում է միայն տեսանյութ։
Տեքստի պահպանում (#12150 P1)։ Սա ավտոմատ կերպով կիրառվում է, երբ Video
Bridge-ը (ինքնին ընտրովի) ցուցադրում է տեքստի հուշում. առանձին պահպանման դրոշ
չկա։ Երբ հարցումը ցուցադրում է որևէ տեքստի հուշում (զանգահարողի կողմից
հայտարարված transcript կամ միաձուլված audioTranscript), պաշտպանիչը
նշում է այն videoBridgeObserved և ստեղծում է տեսանյութի նկարագրության
խմբագրված ստվեր՝ նույնական ցուցադրում, որում յուրաքանչյուր հուշման ազատ
տեքստային մարմինը փոխարինվում է [redacted-video-transcript]-ով, որը
ստեղծվում է կառուցվածքային հուշման դաշտը փոխարինելով նախքան տողի հավաքումը
(երբեք հարթեցված տեքստը վերլուծելով, այնպես որ ոչ մի հուշման բովանդակություն՝
թշնամական կամ սովորական, ներառյալ ] պարունակող մարմինները, ինչպիսիք են
[անլսելի]/[երաժշտություն]-ը, չի կարող պահպանվել)։ Պահպանված զանգի
մատյանի հարցման մարմինը յուրաքանչյուր տեսանյութից ստացված տեքստային մասը
փոխարինում է այդ խմբագրված ստվերով, որը համընկնում է բովանդակության
հավասարությամբ. fullText խարիսխը նորից կարդացվում է ավարտված նախնական
զանգի պաշտպանիչի բեռնվածքից, այնպես որ համընկնումը դեռևս հաջողվում է ավելի
ուշ շղթայական պաշտպանիչներից հետո (PII և հավատարմագրերի դիմակները,
առաջնահերթություններ 10/95) վերաշարադրում են նկարագրության տեքստը տեղում և
համակարգի հուշման/հանձնման/հիշողության ներարկումից հետո վերաձևում են
հաղորդագրությունների զանգվածը։ Մոդելին ուղարկված մարմինը մնում է անփոփոխ։
Դիտարկված հարցումը նաև չի լրացնում որևէ կայուն հիշողություն (ինչպես
հարցումից, այնպես էլ պատասխանից ստացված արդյունահանումը բաց է թողնվում),
այնպես որ մոդելի սեփական պատասխանը չի կարող տեքստի տեքստը արձագանքել
հիշողության մեջ։
Լրացուցիչ պահպանված պատճենները օգտագործում են նույն դիտարկված-հարցման
ազդանշանը։ Հում նախնական-պաշտպանիչի հաճախորդի-հարցման լուսանկարը, հիշողության
մեջ սպասող հարցումը և վաղ մերժված-հարցման մատյանը կառուցվածքորեն փոխարինում են
տեքստի դաշտերը տեսանյութի մասերում. խողովակաշարի փուլերի կողմից սինթեզված
տողային հուշումները և կոնտեքստի հանձնումը խմբագրվում են պահպանված-հարցման-մարմնի
ընդունիչում։ Պահպանված video_content_removed նշիչը previous_response_id
շարունակությունը ստիպում է ձախողվել փակ վիճակում, այլ ոչ թե վերակառուցել
տեքստը, որը միտումնավոր դեն էր նետվել։ Եթե դիտարկված հարցումը կորցնում է իր
մասնակի խմբագրման ստվերը մինչև մուտքագրումը, կամ նույնիսկ մի քանի տեսանյութի
ստվերներից մեկը չի համընկնում ավելի ուշ հարցման մուտացիաներից հետո,
պահպանված հարցման մարմինը ամբողջությամբ բաց է թողնվում՝ մասնակիորեն
խմբագրված տեքստը պահպանելու փոխարեն։
Դիտարկված հարցման համար մոդելի պատասխանը կարող է մեջբերել տեքստի ցանկացած
մաս՝ առանց կառուցվածքային հուշման սահմանի։ Դրա պահպանված զանգի մատյանի
responseBody-ն, հետևաբար, փոխարինվում է բացթողման նշիչով. մանրամասն
խողովակաշարի արտեֆակտը (որը կարող է ներառել վերին հոսանքի/հաճախորդի մարմինները
և հոսքի կտորները) չի պահպանվում։ Սեմանտիկ, իդեմպոտենտության և դատողության-վերարտադրման
քեշերը շրջանցում են այդ հարցման համար կարդալը և գրելը։ Պրովայդերի հարցումը և
հաճախորդի համար տեսանելի պատասխանը մնում են անփոփոխ։ Վաղ keepalive բայթերը
դատարկվում են ժամանակավոր բուֆերից, երբ մանրամասն արտեֆակտը բաց է թողնվում։
Կիրոյի սխալ ձևավորված EventStream նախազգուշացումը հաղորդում է միայն բեռնվածքի
բայթերի քանակը, երբեք դրա բովանդակությունը կամ JSON վերլուծիչի հում սխալը։
Սա չի պնդում, որ յուրաքանչյուր անկապ պրովայդերի/պլագինի ախտորոշում ստուգվել է.
ավելի լայն պահպանված-ընդունիչի մաքրումը հետևվում է #11658-ում։
Ներքին /api/modality-bridge/video/drilldown կյանքի ցիկլը առանձին,
loopback/token-ով վավերացված քեշի ենթաշերտ է։ Յուրաքանչյուր գործողություն
պահանջում է նաև կանոնական անթափանց հիմնական ID։ Նախքան արտադրական
զանգահարողի միացումը, այն պետք է ստանա այդ ID-ն վավերացված վարձակալից և
երբեք չպետք է փոխանցի հաճախորդի կողմից ընտրված արժեք։ Քեշի բանալիները այդ
հիմնականը կապում են կանոնական նիստի և տեսանյութի հղման ID-ների հետ, պահում
են միայն դրանց SHA-256-ից ստացված բանալիները և սահմանափակում են ինչպես
կարդալը, այնպես էլ ջնջելը նույն հիմնականով։ Քեշը պահում է առավելագույնը 16
ստացված JPEG կադր յուրաքանչյուր մուտքի համար, դրանք ժամկետանց է դարձնում
տասը րոպեից հետո և աջակցում է սահմանափակ start/end կարդալուն կամ
նիստի հստակ ջնջմանը։
Յուրաքանչյուր հիմնական սահմանափակված է 16 մուտքով և 64 ՄԲ կանոնական JPEG տվյալներով։ Այդ սահմանները անկախ են գլոբալ 64 մուտքի/256 ՄԲ առաստաղից. հիմնական քվոտայի ճնշումը դուրս է մղում միայն այդ հիմնականի ամենաքիչ օգտագործված մուտքերը, նախքան գլոբալ LRU դուրս մղումը դիտարկվելը։ Ժամկետանց մուտքերը մաքրվում են ինչպես հիմնական, այնպես էլ գլոբալ հաշվառումից քեշի ակտիվության ժամանակ, մինչդեռ չեղարկումը և վավերացման ձախողումը մասնակի փոխարինում չեն կատարում։
Քեշը մերժում է ոչ կանոնական Base64-ը, ավելորդ լրացումները, ոչ JPEG մեդիան,
սխալ ձևավորված կամ կտրված JPEG-ները և JPEG-ները, որոնք նախազգուշացում են
առաջացնում սահմանափակ ամբողջական պատկերի sharp ապակոդավորման ժամանակ։ Այն
վերակոդավորում է յուրաքանչյուր ընդունված պատկեր որպես կանոնական JPEG,
լայնությունը և բարձրությունը ստանում է ապակոդավորված բայթերից՝ զանգահարողի
դաշտերին վստահելու փոխարեն, և դեն է նետում ցանկացած հետևի բազմալեզու բայթեր՝
դրանք պահպանելու փոխարեն։ Միայն սահմանափակ կանոնական սեղմված բուֆերն է
գանձվում երկու քվոտաներից։ JSON լարի սահմանը ներառում է Base64-ի ծախսերը 32
ՄԲ ապակոդավորված-մուտքի առաստաղի համար։ Յուրաքանչյուր պահպանված ստացում
գրանցում է իր վավերացված JPEG ձևաչափը/լուծաչափը, նմուշառման քաղաքականությունը,
ստացման տարբերակը, ստեղծման ժամանակը, սերվերի կողմից հաշվարկված բովանդակության
հեշը և հեշավորված ծնողի հղումը, ինչպես նաև վստահելի զանգահարողի ծնողի-բովանդակության
հեշը։ Չեղարկումը ստուգվում է ասինխրոն ապակոդավորման/հեշի փուլերի միջև՝ մինչև
ատոմային քեշի հանձնումը։
Այս տրանշը դեռևս արտադրական պրոդյուսեր չի միացնում երթուղուն և չի ապահովում բազմաբնույթ տարբերակների ընտրություն: Թափանցիկ Video Bridge հարցումը ճանապարհը, հետևաբար, լրացուցիչ աշխատանք չի պահանջում, մինչդեռ վարձակալին կապված հիմնական ածանցումը և ամբողջական FU-08 բազմաբնույթ կյանքի ցիկլը մնում են հստակ հետագա աշխատանք, քան փաստաթղթավորված է որպես ամբողջական վարքագիծ:
Շրջանակները հաջորդաբար ենթագրվում են կազմաձևված Video մոդելով: Դատարկ
Video վերագրումը ժառանգում է Vision կարգավորումը. եթե երկուսն էլ դատարկ են, Vision
ավտոմատ երթուղիչը ընտրում է արդյունավետ տեսողական հնարավորություններ ունեցող մոդելը: Հաջող ենթագրերը
փոխարինում են բնօրինակ մասը կայուն [Video description: նախածանցով, որը նաև
նշում է տեքստը որպես անվստահելի մեդիայից ստացված դիտարկում և հրահանգում է ներքևի
մոդելներին չհետևել մեդիայում հայտնաբերված հրահանգներին: Շրջանակ-ենթագիր քեշի բանալիները
ներառում են JPEG բայթերը, հուշումը, ժամանակի դրոշմը և արդյունավետ մոդելը. միայն հաջող
ենթագրերը քեշավորվում են: Քեշի գրառումները պահպանում են իրական հաջող պրոդյուսեր մոդելը,
ներառյալ պահեստային մոդելը. կամուրջը հաղորդում է mixed, երբ տարբեր շրջանակներ
արտադրվել են տարբեր մոդելներով: Քեշի հիթը վերաօգտագործում է այդ պրոդյուսերի ինքնությունը
փոխարենը այն վերանշելու որպես պահանջվող երթուղային պլան: Ամբողջական տեսանյութի արդյունքի
քեշը բանալի է դրվում յուրաքանչյուր մուտքի վրա, որը փոխում է ելքը՝ հուշումը, արդյունավետ
մոդելը, նմուշառման քաղաքականությունը, շրջանակների քանակը, իմաստային վերլուծության ռեժիմը, SHA-256
նորմալացված ֆոկուսի հուշման մատնահետքը, ֆոկուսի պատուհանը, transcript,
audioTranscript և կոնտակտային թերթիկի դրոշը, այնպես որ այդ չափումներից որևէ մեկի փոփոխությունը
քեշի բացթողում է, երբեք հնացած վերաօգտագործում: Տեսողական կրկնօրինակման քաղաքականության տարբերակը, շեմը և
սահմանափակված թեկնածու-շրջանակների քանակը նույնպես հստակ են արդյունքի-քեշի բանալիում և մետատվյալներում.
քաղաքականության փոփոխությունը, հետևաբար, չի կարող վերաօգտագործել հնացած ամբողջական տեսանյութի նկարագրությունը: Արդյունքի-քեշի v4 մետատվյալները պահպանում են ռեժիմը և
մատնահետքը, երբեք հում օգտատիրոջ առաջադրանքը: Guardrail մետատվյալները հաղորդում են ինչպես
պահանջվող, այնպես էլ արդյունավետ վերլուծության ռեժիմները. պահանջվող focused ռեժիմը առանց
օգտագործելի օգտատիրոջ տեքստի հաղորդվում է որպես արդյունավետ full:
Պաշտպանիչը արդյունահանում է յուրաքանչյուր աջակցվող տեսանյութի մաս, բայց նկարագրում է ոչ ավելի, քան
modalityBridgeVideoMaxVideos: Նպատակի համար, որը ապացուցված է, որ ունի
supportsVideo === false, ձախողված և սահմանը գերազանցող տեսանյութերը դառնում են հստակ անվտանգ
տեքստային մարկերներ, այնպես որ ոչ մի հում տեսանյութ չի պահպանվում: Երբ հնարավորությունը անհայտ է, այդ մասերը
մնում են անձեռնմխելի: supportsVideo === true ունեցող նպատակները շրջանցում են կամուրջը:
Հաճախորդի հարցման ընդհատման ազդանշանը տարածվում է ներբեռնման, բրոքերի հերթի,
ենթապրոցեսների և ենթագրերի կանչերի միջոցով. ընդհատումները դադարում են տեսանյութերի միջև և երբեք չեն
ձախողվում բաց մինչև հում մեդիա:
Գործարկման կարգավորումները DB-ի կողմից ապահովված են և Zod-ով վավերացված.
| Բանալի | Լռակայուն | Միջակայք / վարքագիծ |
|---|---|---|
modalityBridgeVideoEnabled |
false |
Ընտրովի գործարկում, ընտրովի |
modalityBridgeVideoAnalysisMode |
"full" |
full պահպանում է ընդհանուր ենթագրերը. focused օգտագործում է սահմանափակ, անվստահելի վերջին օգտատիրոջ համատեքստ |
modalityBridgeVideoModel |
"" |
Ժառանգել Vision Bridge մոդելը |
modalityBridgeVideoFrameCount |
8 |
1–16 |
modalityBridgeVideoSamplingPolicy |
"uniform" |
uniform, scene_aware, կամ համաչափ segment_aware. դետեկտորի ձախողումը վերադառնում է uniform |
modalityBridgeVideoMaxVideos |
1 |
1–4 |
modalityBridgeVideoTimeout |
120000 |
1000–120000 մվ |
Ժառանգական պահպանված Video ժամանակի սահմանաչափի արժեքները 120 վայրկյանից բարձր սահմանափակվում են
բրոքերի վերջնաժամկետով. այդ սահմանից բարձր նոր կարգավորումների գրառումները մերժվում են:
GET /api/modality-bridge/video/runtime պահանջում է վստահելի դրոշմված loopback
տեղայնություն մինչև նույնականացումը կամ գործարկման ստուգումը, այնուհետև պահանջում է կառավարման
նույնականացում: Այն վերադարձնում է միայն available, մաքրված FFmpeg/ffprobe տարբերակները և ֆիքսված
պատճառ, երբ գործարկումը անհասանելի է: Ներքին արդյունահանման վերջնակետը հանրային վերբեռնման API չէ.
հերթի հագեցվածությունը վերադարձնում է 503 գումարած Retry-After, զանգողի անջատումը վերադարձնում է 499,
իսկ ֆիքսված բրոքերի վերջնաժամկետը վերադարձնում է 504: Փոխակերպված պատասխանները ավելացնում են
video->text;model=<visionModel>;parts=<videos> կենտրոնական
x-omniroute-modality-bridge վերնագրին՝ առանց Vision կամ Audio հատվածները հեռացնելու:
Աշխատում է երկու փուլերում:
preCallկլոնավորում է բեռնվածքը, անցնում էsystem,messages,inputևprompt(ներառյալ պարզ տողային տարրերը) և կիրառում էprocessPII()(@/shared/utils/inputSanitizer-ից) տողայինcontent/textդաշտերին: ԵրբPII_REDACTION_ENABLED=true, հայտնաբերված PII-ը խմբագրվում է ելքային բեռնվածքում: Սա անկախ էINPUT_SANITIZER_MODE-ից (որը միայն վերահսկում է հուշման ներարկման քաղաքականությունը): Երբ խմբագրումն անջատված է, կանչը գրանցում է հայտնաբերման քանակները՝ առանց բովանդակությունը վերագրելու:postCallխորը կլոնավորում է պատասխանը, գործարկում էsanitizePIIResponse()գումարած Responses-API-ի ձևի դիմակը (maskResponsesOutput— ընդգրկում էoutput_textևoutput[].content[].text): Եթե որևէ խմբագրում տեղի է ունենում, փոփոխված պատասխանը փոխարինում է բնօրինակը:
Պաշտպանիչը երբեք չի արգելափակում. այն միայն ծանոթագրում է (meta.detections,
meta.redacted) կամ վերագրում:
Հայտնաբերում է հակառակորդի կառուցվածքները օգտատիրոջ կողմից տրամադրված բովանդակության մեջ և կիրառում է կազմաձևված քաղաքականությունը: Վարքագիծը պայմանավորված է միջավայրի փոփոխականներով և կոնստրուկտորի ընտրանքներով:
| Կարգավորում | Միջավայրի փոփոխական | Լռելյայն | Ազդեցություն |
|---|---|---|---|
| Միացված է | INPUT_SANITIZER_ENABLED |
true |
Երբ false է, պաշտպանիչը կարճ միացում է կատարում: |
| Ռեժիմ | INJECTION_GUARD_MODE / INPUT_SANITIZER_MODE |
warn |
Ներարկման քաղաքականություն՝ block, warn կամ log: (redact-ը ընդունվում է հետադարձ համատեղելիության համար, բայց չի հեռացնում ներարկման տեքստը. PII վերաշարադրման հարցումը վերահսկվում է PII_REDACTION_ENABLED-ով:) |
| Արգելափակման շեմ | blockThreshold տարբերակ / INPUT_SANITIZER_BLOCK_THRESHOLD (փոխարինող INJECTION_GUARD_BLOCK_THRESHOLD) |
high |
Արգելափակելու համար պահանջվող նվազագույն ծանրություն: Միջինը լռելյայն դիտարկման ռեժիմում է: |
Ռեժիմի առաջնահերթություն (getMode): կանչողի options.mode →
INJECTION_GUARD_MODE DB ֆունկցիոնալության դրոշի վերասահմանում (Dashboard → Settings →
Feature Flags) → INJECTION_GUARD_MODE միջավայր → INPUT_SANITIZER_MODE միջավայր →
warn: Հետևաբար, վահանակի վերասահմանումը գերակայում է միջավայրի փոփոխականներին, այնպես որ Feature
Flags UI-ն վերահսկում է գործող պաշտպանիչը կենդանի ռեժիմում (առանց վերագործարկման): DB-ի ընթերցումը անվտանգ է.
եթե այն սխալ է տալիս, պաշտպանիչը վերադառնում է միջավայրի վրա հիմնված վարքագծին, և երբ
վերասահմանում չի սահմանվում, վարքագիծը նույնական է միայն միջավայրի լուծմանը:
Հայտնաբերման աղբյուրներ.
sanitizeRequest()@/shared/utils/inputSanitizer-ից (ընդհանուր դետեկտորի հավաքածու, որն օգտագործվում է խողովակաշարի այլ մասերում):- Ներկառուցված
DEFAULT_GUARD_PATTERNS(ներկայումսsystem_override_inlineևmarkdown_system_block, երկուսն էլhighծանրության): - Ընտրովի
customPatterns, որոնք փոխանցվում են կոնստրուկտորի ընտրանքների միջոցով (տողեր, regex, կամ{ name, pattern, severity }գրառումներ):
Երբ mode === "block" և առնվազն մեկ հայտնաբերում համապատասխանում է ծանրության
շեմին, preCall-ը վերադարձնում է { block: true, message: "Request rejected: suspicious content detected" }: warn/log ռեժիմներում պաշտպանիչը գրանցում է, բայց
թույլ է տալիս կանչը: Ընդհանուր օգնական evaluatePromptInjection()-ը նույնպես արտահանվում է
այն կանչողների համար, ովքեր պետք է գնահատեն հուշումները՝ առանց ռեգիստրի միջով անցնելու:
Սկանավորման սահման (v3.8.20). դետեկտորը ստուգում է միայն միացված հուշման տեքստի
առաջին 16 ԿԲ-ը՝ MAX_INJECTION_SCAN_BYTES = 16 * 1024 (16 384 բայթ)
src/shared/utils/inputSanitizer.ts-ում: Ե՛վ detectInjection(), և՛
evaluatePromptInjection() slice(0, MAX_INJECTION_SCAN_BYTES) նախքան օրինաչափության ցիկլը
գործարկելը: Ներարկման հրահանգները գտնվում են մուտքի վերին մասում, այնպես որ սա
սահմանափակում է regex CPU/GC-ն բազմահարյուր ԿԲ բեռնվածքների վրա՝ առանց հայտնաբերումը թուլացնելու
(տես #3932, #4041):
Գործարկվում է երկու փուլերում, լռելյայն շղթայում վերջինը (առաջնահերթություն 95):
Դիմակավորում է հայտնի API-բանալիների / գաղտնի թոքենների օրինաչափությունները ելքային բեռնվածքից
(հաղորդագրության բովանդակություն, գործիքի կանչի արգումենտներ, գործիքի արդյունքներ) և
մատակարարի պատասխանից, այնպես որ հուշման մեջ տեղադրված հավատարմագիրը (կամ գործիքի արդյունքի
կողմից արտացոլվածը) չի արտահոսում վերին մատակարարին կամ հետ չի վերադառնում հաճախորդին:
- Միայն ընտրովի, նույն կոնվենցիան, ինչ PII դիմակավորումը (Կոշտ կանոն #20-ին մոտ).
անջատված է, եթե
settings.credentialRedactionEnabled === trueկամCREDENTIAL_REDACTION_ENABLED=true: Եթե այն անջատված է, պաշտպանիչը անգործուն է. այն երբեք չի արգելափակում և երբեք չի վերաշարադրում: redactCredentials()-ը քայլում է ամբողջ բեռնվածքի/պատասխանի ծառով (walkValue(), պրոտոտիպ-աղտոտումից անվտանգ, ցիկլից անվտանգWeakSet-ի միջոցով) և փոխարինում է համընկնումները[REDACTED:<type>]տեղապահով՝ կլոնավորելով միայն այն ճյուղերը, որոնք իրականում փոխվել են:CREDENTIAL_PATTERNS-ը ներառում է LLM մատակարարի բանալիներ (OpenAI, OpenAI-proj, Anthropic, Google, Hugging Face, Replicate), VCS/SaaS թոքեններ (GitHub, Slack, Linear, Notion, npm, Postman, Discord), վճարման բանալիներ (Stripe, Square), ամպային բանալիներ (AWS մուտքի բանալի, Twilio, SendGrid, Mailgun), անձնական բանալիներ / JWT-ներ, հավատարմագիր պարունակող կապի տողեր (mongodb://user:pass@..., և այլն), և ընդհանուրAuthorization/x-api-key/api-key/apikeyվերնագրի-արժեքի օրինաչափություն: Վերնագրի տեսք ունեցող բանալիները (authorization,x-api-key,api-key,apikey) դիմակավորվում են կառուցվածքորեն (միայն արժեքը, սխեմայի նախածանցը, ինչպիսին էBearer/Basic, պահպանվում է), այլ ոչ թե ընդհանուր տեքստային regex-ի միջոցով:- Պաշտպանիչը երբեք չի արգելափակում. այն միայն վերաշարադրում է (
modifiedPayload/modifiedResponse) և ծանոթագրում է (meta.credentialsRedacted,meta.count):
Ռեգրեսիայի պաշտպանություն՝ tests/unit/credential-masker-guardrail.test.ts:
class BaseGuardrail {
enabled: boolean;
name: string;
priority: number;
constructor(name: string, options?: { enabled?: boolean; priority?: number });
async preCall(payload: unknown, context: GuardrailContext): Promise<GuardrailResult | void>;
async postCall(response: unknown, context: GuardrailContext): Promise<GuardrailResult | void>;
}
interface GuardrailResult<TValue = unknown> {
block?: boolean; // true-ը անմիջապես դադարեցնում է շղթայի կատարումը
message?: string; // ցուցադրվում է արգելափակման ժամանակ
meta?: Record<string, unknown> | null;
modifiedPayload?: TValue; // վերադարձվում է preCall-ի կողմից՝ հարցումը վերագրելու համար
modifiedResponse?: TValue; // վերադարձվում է postCall-ի կողմից՝ պատասխանը վերագրելու համար
}
interface GuardrailContext {
apiKeyInfo?: Record<string, unknown> | null;
disabledGuardrails?: string[] | null;
endpoint?: string | null;
headers?: Headers | Record<string, unknown> | null;
log?: GuardrailLog | Console | null;
method?: string | null;
model?: string | null;
provider?: string | null;
signal?: AbortSignal;
sourceFormat?: string | null;
stream?: boolean;
targetFormat?: string | null;
}Պաշտպանիչ սահմանափակումը ազդարարում է «փոփոխություն չկա»՝ վերադարձնելով կա՛մ void, կա՛մ {}, կա՛մ
{ block: false }։ modifiedPayload/modifiedResponse վերադարձնելը փոխարինում է
շղթայով դեպի հաջորդ պաշտպանիչ սահմանափակումներ փոխանցվող արժեքը։
signal?: AbortSignal-ը կանչողի կենսացիկլը փոխանցում է պաշտպանիչ սահմանափակումներին։ Հարցման ընդհատումը կանխամտածված fail-open բացառություն է․ մեդիա կամուրջները դադարեցնում են աշխատանքը և մաքրում ռեսուրսները՝ առանց չմշակված մեդիան վերականգնելու այն թիրախի համար, որը, ինչպես հայտնի է, չի աջակցում այն։
guardrailRegistry եզակի օրինակը տրամադրում է՝
register(guardrail)— ավելացնում է պաշտպանիչ սահմանափակում (կամ փոխարինում է այն ըստ նորմալացված անվան) և վերադասավորում ըստ աճողpriority-ի։clear()/list()— վարչական օժանդակ մեթոդներ։runPreCallHooks(payload, context)— հերթով մշակում է ակտիվ պաշտպանիչ սահմանափակումները, փոխանցում է payload-ըmodifiedPayload-ի միջոցով և կանգ է առնում առաջինblock: true-ի դեպքում։runPostCallHooks(response, context)— նույն հոսքը պատասխանի կողմում։resetGuardrailsForTests({ registerDefaults })— մաքրում է վիճակը և, ըստ անհրաժեշտության, վերագրանցում է լռելյայնները՝ թեստերի մաքուր մեկուսացման համար։
Երկու գործարկիչներն էլ վերադարձնում են { blocked, payload|response, results, guardrail?, message? },
որտեղ results-ը GuardrailExecutionResult գրառումների զանգված է, որոնք ներառում են
յուրաքանչյուր պաշտպանիչ սահմանափակման blocked, skipped, modified, error և meta դաշտերը,
որոնք օգտակար են հետագծման համար։
resolveDisabledGuardrails({ apiKeyInfo, body, headers })-ը հավաքում է
պաշտպանիչ սահմանափակումների անունների կրկնազերծված ցանկ, որոնք պետք է բաց թողնվեն ընթացիկ
հարցման համար։ Աղբյուրները (բոլորն ընտրովի են, բոլորը միավորվում են)՝
apiKeyInfo.disabledGuardrails- Հարցման մարմնի
disabledGuardrails(վերին մակարդակում) - Հարցման մարմնի
metadata.disabledGuardrails x-omniroute-disabled-guardrailsվերնագիր (կամ հինx-disabled-guardrails)
Արժեքները կարող են լինել տողերի զանգվածներ կամ ստորակետերով բաժանված տող․ անունները
նորմալացվում են փոքրատառ kebab-case ձևաչափի (pii_masker → pii-masker)։ Արդյունքը
context.disabledGuardrails-ի միջոցով փոխանցվում է ռեեստրին, որը բաց է թողնում
համապատասխան պաշտպանիչ սահմանափակումները (skipped: true՝ results-ում)։
src/sse/handlers/chat.ts-ով և
open-sse/handlers/chatCore.ts-ով անցնող յուրաքանչյուր հարցման համար՝
resolveDisabledGuardrails(...)-ը API բանալիից, հարցման մարմնից և վերնագրերից կազմում է բաց թողնման ցանկը։guardrailRegistry.runPreCallHooks(body, ctx)-ը պաշտպանիչ սահմանափակումները գործարկում է առաջնահերթության աճման կարգով՝- Անջատված պաշտպանիչ սահմանափակումներն արձանագրվում են որպես
skipped։ - Յուրաքանչյուր պաշտպանիչ սահմանափակման
preCall-ը կարող է վերագրել օգտակար բեռը՝ օգտագործելովmodifiedPayload։ - Առաջին
block: true-ն անմիջապես ընդհատում է շղթան, և մշակիչը վերադարձնում է պաշտպանիչ սահմանափակման մերժման պատասխան։
- Անջատված պաշտպանիչ սահմանափակումներն արձանագրվում են որպես
- Հնարավոր վերագրված օգտակար բեռը փոխանցվում է համակցված երթուղավորմանը և վերին հոսքի ուղարկմանը։
- Պատասխանը կազմելուց հետո
guardrailRegistry.runPostCallHooks(...)-ը պատասխանի վրա գործարկում է նույն շղթան։ Այստեղblock: true-ն հեռացնում է վերին հոսքի պատասխանը։
Սխալ արձակող պաշտպանիչ սահմանափակումներն արձանագրվում են error: <message>-ով և գրանցվում
logger.warn-ի միջոցով, սակայն շղթան շարունակվում է. նախագծմամբ կիրառվում է սխալի դեպքում թույլատրելու մոտեցումը։
Ներկառուցված պաշտպանիչ սահմանափակումների կողմից ընթերցվող միջավայրի փոփոխականները՝
| Փոփոխական | Օգտագործվում է | Ազդեցություն |
|---|---|---|
INPUT_SANITIZER_ENABLED |
prompt-injection |
Հայտնաբերումն ամբողջությամբ անջատելու համար սահմանեք false։ |
INPUT_SANITIZER_MODE |
prompt-injection |
Ներարկման քաղաքականությունը՝ warn, block կամ log։ Հնացած redact արժեքը չի վերագրում ներարկման տեքստը։ |
INJECTION_GUARD_MODE |
prompt-injection |
Ներարկման պաշտպանիչի ռեժիմը. նաև ՏԲ-ի գործառույթի դրոշակ է, որը գերակայում է միջավայրի փոփոխականների նկատմամբ (DB > ENV)։ |
INPUT_SANITIZER_BLOCK_THRESHOLD |
prompt-injection |
Նվազագույն խստությունը, որը մերժվում է MODE=block-ի դեպքում՝ high (լռելյայն), medium կամ low։ |
INJECTION_GUARD_BLOCK_THRESHOLD |
prompt-injection |
INPUT_SANITIZER_BLOCK_THRESHOLD-ի հնացած այլանունը։ |
PII_REDACTION_ENABLED |
pii-masker |
Երբ true է, հարցման PII-ը քողարկվում է՝ անկախ ներարկման ռեժիմից։ |
PII_RESPONSE_SANITIZATION / _MODE |
pii-masker (ներքևի հոսք) |
Կառավարում է պատասխանի կողմում քողարկիչի վարքագիծը։ |
Մոդալության կամրջի պաշտպանիչ սահմանափակումները կատարման ժամանակի կազմաձևումն ընթերցում են ՏԲ-ով ապահովվող կարգավորումների
պահոցից (getSettings()), ոչ թե միջավայրի փոփոխականներից։ Պատկերի մշակման հիմնական բանալիներն են՝
modalityBridgeVisionEnabled, modalityBridgeVisionMode,
modalityBridgeVisionModel, modalityBridgeVisionTaskAware,
modalityBridgeVisionPrompt, modalityBridgeVisionTimeout,
modalityBridgeVisionMaxImages, modalityBridgeVisionMaxChars,
modalityBridgeCacheEnabled, modalityBridgeCacheTtlMinutes և
modalityBridgeCacheMaxEntries։ Հնացած
visionBridge* բանալիներն ընդունվում են միայն որպես փաստաթղթավորված՝ մեկ ցիկլի ընթերցման
պահուստային տարբերակ. կառավարման վահանակից գրանցումները կիրառում են հիմնական բանալիները։ Լռելյայն արժեքները և պահուստային
լուծիչը գտնվում են src/shared/constants/modalityBridgeDefaults.ts-ում, իսկ հնացած
հաստատունները պահպանվում են src/shared/constants/visionBridgeDefaults.ts-ում։
Ձայնի մշակումն օգտագործում է modalityBridgeAudioEnabled, modalityBridgeAudioModel,
modalityBridgeAudioTimeout և modalityBridgeAudioMaxClips, ինչպես նաև ընդհանուր
modalityBridgeCache* կարգավորումները։ Ձայնի մշակման համար հնացած բանալիների պահուստային տարբերակ չկա, քանի որ այս
բանալիները ներդրվել են Մոդալության կամրջի սխեմայի հետ։
Տեսանյութի մշակումն օգտագործում է modalityBridgeVideoEnabled, modalityBridgeVideoAnalysisMode,
modalityBridgeVideoModel,
modalityBridgeVideoFrameCount, modalityBridgeVideoSamplingPolicy,
modalityBridgeVideoMaxVideos և
modalityBridgeVideoTimeout, ինչպես նաև ընդհանուր modalityBridgeCache* կարգավորումները։
Այն լռելյայն անջատված է, քանի որ FFmpeg/ffprobe-ը ոչ պարտադիր գործառնական
կախվածություններ են, իսկ կադրերի նկարագրությունների ստեղծումն ավելացնում է ուշացումն ու մոդելի օգտագործման արժեքը։
import { BaseGuardrail, guardrailRegistry } from "@/lib/guardrails";
class BudgetGuardrail extends BaseGuardrail {
constructor() {
super("budget", { priority: 50 });
}
async preCall(payload, ctx) {
if (ctx.apiKeyInfo?.budgetExceeded) {
return { block: true, message: "Daily budget exceeded" };
}
return { block: false };
}
}
guardrailRegistry.register(new BudgetGuardrail());Քայլեր՝
- Ստեղծեք
src/lib/guardrails/myGuardrail.ts՝ ընդլայնելովBaseGuardrail-ը։ - Իրագործեք
preCall-ը և/կամpostCall-ը։ - Կամ գրանցեք ներմուծման պահին (
registerDefaultGuardrails-ից ավելացնելով), կամ գործարկման ընթացքում կանչեքguardrailRegistry.register(...)-ը․ ռեեստրը փոխարինում է նույն նորմալացված անունն ունեցող ցանկացած նախորդ պաշտպանիչ կանոն։ - Ավելացրեք թեստեր
tests/unit/-ում (առկա օրինակներ՝tests/unit/guardrails-registry.test.ts,tests/unit/prompt-injection-guard.test.ts,tests/unit/guardrails/visionBridge.test.ts)։
Թեստերի միջև օգտագործեք resetGuardrailsForTests()՝ հայտնի վիճակից սկսելու համար։
Փոխանցեք { registerDefaults: false }՝ դատարկ ռեեստրից սկսելու և
միայն թեստավորվող պաշտպանիչ կանոնները գրանցելու համար։ Vision Bridge-ն աջակցում է կախվածությունների
ներմուծմանը (deps.getSettings, deps.callVisionModel), իսկ Audio Bridge-ը տրամադրում է
համարժեք միջերեսներ՝ կարգավորումների, հնարավորությունների, STT մոդելի ընտրության, հավատարմագրերի
ստուգումների և տրանսկրիպցիայի համար։ Հետևաբար, թեստերը կարող են ստուգել երկու հոսքերն էլ՝ առանց DB-ի
կամ ցանցային հասանելիության։
src/lib/guardrails/— իրականացումըsrc/shared/utils/inputSanitizer.ts— ընդհանուր դետեկտորը, որն ապահովում է հուշման ներարկման հայտնաբերումը և PII-ի քողարկումըsrc/shared/constants/visionBridgeDefaults.ts— Vision Bridge-ի լռելյայն արժեքները և հարկադիր կամրջման մոդելների ցանկըsrc/shared/constants/modalityBridgeDefaults.ts— Vision/Audio-ի ընդհանուր գործարկման միջավայրի լռելյայն արժեքներըdocs/architecture/RESILIENCE_GUIDE.md— ուղղահայաց շերտ (շղթայի անջատիչ, սպասման ժամանակահատվածներ)docs/reference/ENVIRONMENT.md— միջավայրի փոփոխականների ամբողջական տեղեկատուն
Ներարկման պաշտպանիչ կանոնը (createInjectionGuard / withInjectionGuard) ընդգրկում է օգտատիրոջ հուշումներ
ընդունող բոլոր երթուղիները։ Այն հաշվի է առնում INJECTION_GUARD_MODE-ը (լռելյայն՝ warn = միայն գրանցել մատյանում,
block = վերադարձնում է HTTP 400 SECURITY_001)։
| Տեսակ | Երթուղիներ | Լռելյայն ռեժիմ |
|---|---|---|
| Տեքստ (առկա) | /v1/chat/completions, /v1/completions, /v1/relay/chat/completions |
warn |
| Գեներատիվ | /v1/messages, /v1/responses, /v1/images/generations, /v1/images/edits, /v1/videos/generations, /v1/music/generations, /v1/audio/speech |
warn |
| Տվյալներ | /v1/embeddings, /v1/rerank, /v1/search, /v1/moderations |
warn |
Տեքստի արտաբերումը (extractMessageContents) ներառում է messages/input/prompt/query+documents/instructions/system։
Red-team (ամեն գիշեր, nightly-llm-security.yml)․ promptfoo-ն ստուգում է, որ յուրաքանչյուր երթուղի արգելափակում է
OWASP-LLM կորպուսը INJECTION_GUARD_MODE=block ռեժիմում, իսկ garak-ը կատարում է ստուգումներ (գաղտնիքի բացակայության դեպքում՝ բաց է թողնում)։
moderations-ը ներառված է հետևողականության համար․ արգելափակման ռեժիմն օգտագործող օպերատորները կարող են այն բացառել
resolveDisabledGuardrails-ի միջոցով։
Գիշերային աշխատանքային հոսքը (.github/workflows/nightly-llm-security.yml, cron + ձեռքով
գործարկում) ունի երկու առաջադրանք՝
promptfoo-guard(արգելափակող) — գործարկում էpromptfoo eval -c promptfooconfig.yaml-ըINJECTION_GUARD_MODE=block-ով։ Յուրաքանչյուր հակառակորդային դեպք (օրինակ՝ «անտեսիր բոլոր նախորդ հրահանգները…», DAN ոճի jailbreak-ներ) հաստատում է, որ պատասխանը պարունակում էerror.code === "SECURITY_001", այսինքն՝ պաշտպանիչ կանոնն իսկապես մերժել է հարցումը։garak(խորհրդատվական) — գործարկում է garak-ը--probes promptinject,dan,leakreplay-ով տեղային OmniRoute օրինակի (http://localhost:20128/v1) նկատմամբ։ Պայմանավորված է մատակարարի գաղտնիքի (PROMPTFOO_PROVIDER_KEY) առկայությամբ․ դրա բացակայության դեպքում առանց սխալի բաց է թողնվում և վերջում ունի|| true, ուստի այն հաշվետվություն է ներկայացնում՝ առանց CI-ն ձախողելու։
Պաշտպանիչ օգնականի (createInjectionGuard / withInjectionGuard)
ծածկույթը տարածվում է հուշում պարունակող յուրաքանչյուր /v1 երթուղու վրա․ հուշման տեքստը վերցվում է
messages/input/prompt/query+documents/instructions/system դաշտերից՝
src/shared/utils/inputSanitizer.ts-ի extractMessageContents()-ի միջոցով։