# स्टिलियोबोट रिलीज शृंखला

*आप एक डिटेक्टर का परीक्षण कैसे कर सकते हैं जिसका उत्तर सीखते समय बदलना चाहिए।*

[<img src="/articleimages/stylobot-logo.svg" alt="StyloBot" width="120" />](https://www.stylobot.net)

> **स्टिलियोबोट रिलेस शृंखला**
> 
> 1. [**व्यवहार, पहचान नहीं**](/blog/stylobot-fingerprint): क्यों StyloBot ग्राहक व्यवहारिक रूप से मॉडल करता है
> 2. [**व्यवहार-Aware ASP.NET UI**](/blog/behaviour-aware-ux): सर्वर\-\ऐसे पता लगाने के परिणाम पर सतह दे दिया
> 3. [**लंबे समय तक चलाने वाले नेट सेवाओं में असीमित विकास का पता लगाना और स्थिर करना**](/blog/stylobot-release-reliability): विश्वसनीयता अनुशासन जो उत्पादन में इंजन को नीरस बनाए रखता है
> 4. [**व्यवहार-Aware TypeScript UI**](/blog/typescript-sdk): Express , Fastify, और ब्राउज़र घटक
> 5. [**साइडकार वास्तुकला**](/blog/sidecar-architecture): कैसे पता लगाने की इंजन गैर--.NET स्टाक से जुड़ता है
> 6. [**तेजी से सीखना**](/blog/stylobot-release-learning)अनुकूलन सीखने की प्रणाली
> 7. **उस चीज़ का परीक्षण जो सफल नहीं हो रही है**: सत्यापन अनुशासन
> 8. [**स्टिलियोएक्सट्रैक्ट - एक स्थानीय सीखने के HTML को मार्कडाउन रूपांतरक में**](/blog/stylobot-release-styloextract): एचटीएमएल\→\मार्कडाउन परत जो डिटेक्टर के साथ जोड़ता है\,\walker bug lucidVIEW पकड़ा\M SK3\ और कुत्तेfood लूप कि यह ईमानदार बना

<!--category-- ASP.NET, StyloBot, Bot Detection, Testing, Architecture -->
<datetime class="hidden">2026-06-01T10:30</datetime>

विश्वसनीयता अनुशासन [असीमित विकास का पता लगाना और स्थिर करना](/blog/stylobot-release-reliability); में अनुकूलन सीखने की प्रणाली [तेजी से सीखना](/blog/stylobot-release-learning); स्रोत पर [github.comM SK1scottgal/stylobot](https://github.com/scottgal/stylobot).

[TOC]

---


## आप कुछ सीखता है कि कैसे परीक्षण करते हैं

स्टिलोबोट के पीछे यह असंतोषजनक सवाल है और यह र्थातिक नहीं है

एक पारंपरिक परीक्षण पीन एक प्रकार्य को जगह पर रखता है: इनपुट X आउटपुट Y को लौटाता है। [तेजी से सीखना](/blog/stylobot-release-learning).)

अनुरोध के लिए निर्णायक 20, तब, अनुरोध का एक फ़ंक्शन नहीं है | 20. | यह अनुरोधों का एक फंक्शन है \ 1 | से लेकर \20. | इसलिए परीक्षण लक्ष्य किसी भी अनुरोध का नहीं है

कि बाहर नियम `Assert.Equal`एक परीक्षण पूछ सकता है सवाल अब नहीं है "does request X return verdict Y?" यह बन जाता है \"given this class of behaviorM SK4 does the system converge to the right answer

सबसे करीब .NET एनालॉग हैं [सत्यापित करें](https://github.com/VerifyTests/Verify) और [एफएसचेक](https://github.com/fscheck/FsCheck), लेकिन BDF का कोई भी नहीं है।

## एक व्यवहारिक परिभाषा, तीन सत्यापन प्रणालियां

एक BDF फ़ाइल को इस पेलने योग्य बनाता है कि चाल एक परीक्षण मामला नहीं है *निष्पादनीय व्यवहार संविदा*, क्लाइंट वर्ग के व्यवहार का एक परिभाषा

1. **फिर से चलाया गया** एकीकरण यंत्र के माध्यम से-,-एक समय पर वास्तविक वाद्यकार के खिलाफ एक अनुरोध-,-सिग्नल पकड़ने के लिए-M SK2-प्रवाह रिग्रेसन यूनिट सूट नहीं देख सकता है
2. **à¤aà¥à¤°à¥à¤** अधीन [एमएसके0](https://k6.io/)कई समवर्ती आभासी उपयोगकर्ता एक ही परिभाषा से ताजा समय निकालते हैं
3. **लेखापरीक्षित** संकेतों के खिलाफ एक वास्तविक रन वास्तव में मापित है

```mermaid
flowchart TD
    classDef def fill:none,stroke:#3b82f6,stroke-width:2px
    classDef rig fill:none,stroke:#a855f7,stroke-width:2px
    classDef out fill:none,stroke:#22c55e,stroke-width:2px

    BDF["BDF behavioural definition<br/>clientProfile · timingProfile<br/>requests · evidence · labels"]:::def

    Replay["Integration replay<br/>slim form · real orchestrator<br/>cache disabled · identity reset"]:::rig
    K6["k6 load harness<br/>full form · re-sampled per VU<br/>burst + jitter"]:::rig
    Calibration["Calibration audit<br/>claimed evidence<br/>vs measured signals"]:::rig

    Signals["Signal-flow regressions caught<br/>merged ev.Signals reaches<br/>dashboard · persistence · threat report"]:::out
    Metrics["Load envelope verified<br/>latency · detection_rate<br/>burst_detected"]:::out
    Drift["Calibration drift surfaced<br/>stale claims · aged signatures<br/>moved detection surface"]:::out

    BDF --> Replay --> Signals
    BDF --> K6 --> Metrics
    BDF --> Calibration --> Drift
```

रीग्रेसन, लोड, और कैलिब्रेसन सामान्यतः तीन सत्य के तीन स्रोतों से तीन परीक्षण प्रणालियां होती हैं जो अलग-अलग बहती है।

## क्यों इकाई परीक्षण असफल वर्ग छोड़ देते हैं

इस काम के पहले संस्करण में प्रति प्रति सैकड़ों प्रति детектор इकाई परीक्षण होते थे नमूने संदर्भों और कैनड हेडर से।

वाद्यकार अंशदानों को एक एकल में मिलाता है `ev.Signals` शब्दकोश जो नीचे की ओर उपभोक्ताओं के लिए (dashboard, persistence `primary_signature` विलयित सतह से कोई भी असफलता नहीं होती है।

यह एक hypothetical नहीं है [संविदा दस्तावेज़](https://github.com/scottgal/stylobot/blob/main/docs/architecture/signal-contracts.md) इस रीग्रेसन को ठीक से रिकॉर्ड करता है: एक परिवर्तन जो एकल संकेतों को बंद कर देता है " उत्पादन में छह दिन के लिए जीवित रहा है हालांकि 1957 यूनिट परीक्षणों को पास करने के बाद |" |क्योंकि \" |यूनिट जाँचों की संभाव्यता और योगदान गणनाओं पर साबित होती है `evidence.Signals`."

एकीकरण परीक्षण पर [`BdfReplayTests.Integration.cs`](https://github.com/scottgal/stylobot/blob/main/src/Mostlylucid.BotDetection.Orchestration.Tests/Integration/BdfReplayTests.Integration.cs) यह क्यों मौजूद है के बारे में प्रत्यक्ष है

> यह रिग मौजूद है क्योंकि विफल वर्ग यह पकड़ता है ( stream उपभोक्ताओं के `ev.Signals` जब वाद्यकार गाड़ना संकेतों को बंद करता है तब चुपचाप ह्रास करता है

एक फ़ंक्शन नहीं है, यह एक पाइपलाइन है जिसका मूल्य जो भी किसी भी योगदानकर्ता को चलाने के बाद विलयन से निकलता है।

## BDF: एक व्यवहारिक परिभाषा

एक BDF (Behavioural Definition Format) फ़ाइल यह वर्णन करता है कि कैसे *वर्ग* क्लाइंट व्यवहारों का,, एक की नियत प्लेबैक नहीं है. स्कीमा के रोचक भाग सांख्यिकीय हैं:, एक क्लाइन्ट प्रोफ़ाइल जो वितरण पहचान अभिग्रहण करता है,, एक समय प्रोफाइल जो एक विस्फोट को परिभाषित करता है--,- जिटर नमूना लेने नियम के बजाय नियत देरी के साथ,, व्यवहार संकेतों पर भारित पूर्वानुमानों का एक साक्ष्य समुच्चय, और एक विश्वास पूर्व. यहाँ एक वास्तविक हस्ताक्षर है[`bot-signatures/python-requests-bdf.json`](https://github.com/scottgal/stylobot/blob/main/bot-signatures/python-requests-bdf.json)):

```json
{
  "scenarioName": "python-requests-bdf",
  "scenario": "A bot/scraper using python-requests/2.31.0 with specific behavior patterns.",
  "confidence": 0.85,

  "clientProfile": {
    "userAgent": "python-requests/2.31.0",
    "cookieMode": "none",
    "headerCompleteness": "minimal",
    "clientHintsPresent": false,
    "robotsConsulted": false
  },

  "timingProfile": {
    "burstRequests": 10,
    "delayAfterMs":      { "min":   20, "max":   150 },
    "pauseAfterBurstMs": { "min":  500, "max":  2000 }
  },

  "requests": [
    { "method": "GET",  "path": "/",                "expectedStatusAny": [200,301,302], "expectedOutcome": "indexing", "successCondition": "any 2xx" },
    { "method": "HEAD", "path": "/admin",           "expectedStatusAny": [200,403],     "expectedOutcome": "indexing", "successCondition": "any 2xx" },
    { "method": "GET",  "path": "/api/data?page=1", "expectedStatusAny": [200,403],     "expectedOutcome": "indexing", "successCondition": "any 2xx" },
    { "method": "GET",  "path": "/api/data?page=2", "expectedStatusAny": [200,403],     "expectedOutcome": "indexing", "successCondition": "any 2xx" },
    { "method": "GET",  "path": "/api/data?page=3", "expectedStatusAny": [403,404],     "expectedOutcome": "indexing", "successCondition": "any 4xx" }
  ],

  "labels": ["Scraper", "RobotsIgnore"],

  "evidence": [
    { "signal": "interval_ms_p95", "op": "<", "value": 200,           "weight": 0.35 },
    { "signal": "requestInterval", "op": "<", "value": "burst <150ms", "weight": 0.70 }
  ],

  "patterns":  { "requestInterval": "burst <150ms" },
  "reasoning": "The bot/scraper uses python-requests/2.31.0 to access various endpoints, including the root path and admin pages, while also enumerating API paths and testing different HTTP methods."
}
```

अधिकतर सतह सांख्यिकीय है *परिभाषा* एक परीक्षण स्क्रिप्ट के बजाय [`docs/bdf-v2-schema.json`](https://github.com/scottgal/stylobot/blob/main/docs/bdf-v2-schema.json).)

**`confidence` एक पूर्व है** 0.85 says "this should land highM SK2confidence bot when the system is healthy". The rig does not check the matured score equals 0.85; it checks the verdict lands on the bot side of the boundary

**`clientProfile` क्लाइंट का एक वर्ग है** `cookieMode: none` एक है *श्रेणी* व्यवहार के (कुछ कुकी बर्तन नहीं `headerCompleteness: minimal` यह कहता है "इस क्लाइंट से एक अनुरोध केवल क्या curl लेता है\ -\ वर्ग लाइब्रेरी सेट करता है\",\ एक तथ्य के बारे में अनुरोधों की जनसंख्या इस क्लाइन्ट के बाहर निकला देता है\ ,\ एक स्थिर हेडर सूची नहीं\ .\ k\ 6\ परिवर्तक इन को चलाने के समय हेडर बंडल्स में materializes *क़रीब* क्लाइंट का

**`timingProfile` एक नमूना नियम है** `burstRequests: 10` अधिक `delayAfterMs: {min: 20, max: 150}` अधिक `pauseAfterBurstMs: {min: 500, max: 2000}` एक जेनेरेटर को परिभाषित करता है : दस अनुप्रयोगों के साथ यूनिफ़ॉर्मिक | - | \ 20 में संभाव्य अंतर |150 | ms | , | फिर एक यूनिफॉर्मी | МSK5 | का संभावित पलायन | एमएसके6 | से | मीएसके7 |ms | मएसके8 | दोहराएँ |एमएसके9 | एक ही बीडीएफ दो बार फिर से बजाया जाता है दो भिन्न अनुरोध धाराओं को एक ही सांख्यिकीय वितरण के साथ उत्पन्न करता है

**`evidence` संकेतों पर एक भारित प्रारूप है** प्रत्येक प्रविष्टि एक फार्म का दावा है `signal OP value, weight w`. `{signal: "interval_ms_p95", op: "<", value: 200, weight: 0.35}` यह कहता है " इस परिदृश्य के लिए pM SK1 inter\-\request अंतराल 200\ms\,\के नीचे होना चाहिए और यह निर्णय का 0.35\value है।

**`labels` वर्गीकरण हैं** `[Scraper, RobotsIgnore]` क्या वर्ग है कि लोड हार्नेस में सिर्फ (run में लेबल ड्राइव सिनारियो चयन के लिए सिनार्यो को उत्पन्न किया गया था `Scraper` परिदृश्य-, exclude `RobotsIgnore`बिना किसी की सिनारियो नामों पर एक रेगेक्स लिखने के

**`requests` क्या क्लाइंट करता है वर्णन करें, नहीं क्या आगे होना चाहिए** `expectedStatusAny: [200, 403]` या तो एक सफल फ़ैच या एक पूर्ण ब्लॉक को सहन करता है, क्योंकि दोनों ही एक दुश्मनी पथ जांच के वैध उत्पादन हैं `expectedOutcome: indexing` है *क्लाइंट* (एपीआई पृष्ठों को आंकलित करें `successCondition: "any 4xx"` पर `/api/data?page=3` क्लाइंट है ' के लिए हैरिस्टिक्स | " | इस काम को किया |": | एक स् scraper जो तीसरे पृष्ठ पर \4 |xx प्राप्त करता है अपने नामांकन कार्य में सफल हो रहा है | ( | यह चट्टान का पता चला है \). | BDF क्या क्लाइन्ट करने की कोशिश कर रही है और क्या सिस्टम इसके बारे में क्या करना चाहिए के बीच असमानता captures

### एक BDF और एक centroid: एक ही विचार, उल्टा

शब्द *परिभाषा* भार है। -; carrying; ,; और यह StyloBot के केंद्र में अवधारणा से बीडीएफ को जोड़ता है। **केंद्रक**: संदर्भ बिन्दुओं में से [व्यवहार, पहचान नहीं](/blog/stylobot-fingerprint)क्लाइंट के एक वर्ग के लिए प्रत्येक एक सीखा Anchor है जो समान रूप से चलता है

एक बीडीएफ एक ही बात वर्णित करता है ( एक क्लाइंट का वर्ग | ) | के साथ भूमिका उल्टी |. | केंद्रक है **पहचानकर्ता**यह पूछता है " क्या यह अनुरोध उस वर्ग की तरह दिखता है **जनरेटर**यह उत्तर देता है

इंजन [`SignatureToBdfMapper`](https://github.com/scottgal/stylobot/blob/main/src/Mostlylucid.BotDetection/Behavioral/SignatureToBdfMapper.cs) दो को जोड़ता है: यह वास्तविक ट्रैफिक से पकड़ा गया व्यवहारिक हस्ताक्षर लेता है और इसे एक BDF के रूप में बाहर लिख देता है जिसे आप पढ़ सकते हैं और फिर से चला सकता है

तो [`bot-signatures/`](https://github.com/scottgal/stylobot/tree/main/bot-signatures) कोर्पस केवल एक परीक्षण फिक्सचर नहीं है, यह व्यवहारिक परिभाषाओं का लाइब्रेरी है।`ministral-3:3b`डिरेक्ट्री के अनुसार , 's README

एक संकुचित ह्य- हृdown रिप्ले रूप के नीचे रहता है [`test-suites/{bots,humans,adversarial}/*.bdf.json`](https://github.com/scottgal/stylobot/tree/main/test-suites) केवल रखना `requests[].method/path/headers/delayAfter` और एक मज़बूत `expectedDetection`यह उपसंचय एकल रिप्ले से वितरण व्यवहार को संश्लेषित करने का कोई तरीका नहीं है।

## रिप्ले अंतबिंदु वास्तविक वाद्यकार के माध्यम से चला जाता है

एकीकरण रीग प्रत्येक परिदृश्य को पोस्ट करता है `POST /bot-detection/bdf-replay/replay`एक अंतिम बिन्दु जो उत्पाद में रहता है[`BdfReplayEndpoints.cs`](https://github.com/scottgal/stylobot/blob/main/src/Mostlylucid.BotDetection/Endpoints/BdfReplayEndpoints.cs)), परीक्षण परियोजना में नहीं है `IDetectionOrchestrator` डीआई से चलाता है और जो भी ऑरेक्स्टरेटर वर्तमान में पंजीकृत है `DetectionPolicy.Default`पिछले संस्करण में एक विशिष्ट वाद्यकार को हार्डकोड किया गया और वैकल्पिक पथ में मास्केड रिग्रेसन

चूंकि अंतिम बिन्दु उत्पाद में रहता है, यह एक उत्पाद सतह की तरह घेरा जाता है `BdfReplay` डिफ़ॉल्ट से बंद है जब सक्षम किया जाता है `X-BdfReplay-Api-Key` हेडर और एक प्रति अनुप्रयोग को पास करें।

```mermaid
flowchart LR
    classDef test fill:none,stroke:#3b82f6,stroke-width:2px
    classDef proc fill:none,stroke:#a855f7,stroke-width:2px
    classDef out fill:none,stroke:#22c55e,stroke-width:2px

    Test["BDF replay rig<br/>authenticated with API key"]:::test --> Endpoint["Product replay endpoint<br/>identity reset · cache disabled"]:::proc
    Endpoint --> Orch["Current DI-registered<br/>orchestrator"]:::proc
    Orch --> Signals["Merged ev.Signals"]:::proc
    Signals --> Assert["Contract assertions<br/>verdict · signal probes<br/>convergence bound"]:::out
```

एक जानबूझकर नीति अधिरोहित करें

```csharp
var replayPolicy = Policies.DetectionPolicy.Default with
{
    SignatureCache = Policies.DetectionPolicy.Default.SignatureCache with { Enabled = false }
};
```

कैश's Skip पथ एक प्राथमिक हस्ताक्षर का एक विश्वसनीय कैशित निर्णय है एक बार पूरी तरह से अनुरूपी पार करता है [तेजी से सीखना](/blog/stylobot-release-learning)एक यंत्र के मापने की सूक्ष्मता और संकेत प्रवाह का पता लगाने के लिए यह प्रति-- request व्यवहार यंत्र को स्थापित करने की कोशिश करता है छिपाता है

Scenarios are also isolated from each other. Each scenario gets a unique synthetic IP derived from a deterministic xxHash of its name (a `192.0.x.y` आरएफसी से पता 5737 टीईएसटी | - | नेट रेंज |), | इसलिए उपनेट | МSK3 | स्तर की प्रसिद्धि कभी भी परिदृश्यों के बीच रक्तस्राव नहीं करता है `POST /bot-detection/bdf-replay/reset-identity` प्रत्येक प्राक्कलन से पहले अंगुलियों की छाप भंडार को छोटा करने के लिए ; बिना उस , प्राक्किलन एन ने अंगुलों की छाप प्राक्कलीन उत्पन्न की है और प्रति \- प्रायोगिक स्थिरता बयान क्रमबद्ध हो जाते हैं

## किसी non-deterministic सतह पर दावा

रीग प्रत्येक परिदृश्य पर तीन सिद्धांत करता है

**परिपक्व निर्णायक, per नहीं -request verdict** बोट सिनारियो का दावा `last.Actual.IsBot` सही है; मानव परिदृश्यों का दावा करता है *बहुसंख्यक* मानव के रूप में वर्गीकृत अनुरोधों की . प्रत्येक व्यक्तिगत अनुरोध पर दावा करता है कि drift trajectory से दूर आर्कटाइप एङ्कर से जोड़ने के लिए परीक्षण होगा ; आराम करने के लिए

```csharp
// Some heuristics legitimately escalate on outlier rates; assert majority human, not all.
var humanCount = response.Results.Count(r => r.Actual is { IsBot: false });
var botCount = response.Results.Count - humanCount;
Assert.True(humanCount >= botCount,
    $"{response.ScenarioName}: {botCount}/{response.Results.Count} requests classified as bot, " +
    $"expected majority human. Last verdict: {last.Actual!.RiskBand} prob={last.Actual.BotProbability:F2}");
```

**नामित संकेत प्रॉब्स, संकेत गणना नहीं करता है** संकेत प्रवाह एक कुंजी के प्रति जांच किया जाता है।

```csharp
Assert.True(probes.TryGetValue(SignalKeys.PrimarySignature, out var hasSig) && hasSig,
    $"{scenarioName}: {SignalKeys.PrimarySignature} missing from ev.Signals — " +
    "RequestPersistenceService skips persistence, dashboard fingerprint table goes blank");
```

त्रुटि संदेश परीक्षण है

**bound convergence** मेटास्टेबल अंगुठा छाप मिलाने वाला स्थिर पहचान के लिए शोरयुक्त सदिश को हल करता है। `ceil(N/2)` भिन्न अंगुलियों की छाप

```csharp
var distinctFps = withFingerprints
    .Select(r => r.Actual!.IdentityFingerprintId!)
    .Distinct(StringComparer.OrdinalIgnoreCase)
    .Count();
var allowed = Math.Max(1, (int)Math.Ceiling(response.Results.Count / 2.0));
Assert.True(distinctFps <= allowed,
    $"{scenarioName}: {distinctFps} distinct fingerprints across {response.Results.Count} requests " +
    $"(allowed {allowed}). The matcher isn't converging — every request is allocating new, suggesting " +
    "vector composition is unstable or LooseThreshold is unreachable.");
```

`ceil(N/2)` कोई जादू नहीं है. यह एक नीति को एनकोड करता है। *हर* अनुरोध एक regression है

सभी तीन नमूने एक गुण साझा करते हैं-: वे संविदा पर मानते हैं कि व्यवहार को पूरा करने के लिए किया जाना चाहिए।

## दबाव के तहत एक ही कॉर्पस लोड करें

एक बीडीएफ फ़ाइल सिर्फ JSON है [`scripts/convert-bdf-to-k6-v2.csx`](https://github.com/scottgal/stylobot/blob/main/scripts/convert-bdf-to-k6-v2.csx) हस्ताक्षरों की निर्देशिका पढ़ता है और एक k6 स्क्रिप्ट जारी करता है कि *नमूने* प्रत्येक हस्ताक्षर's वितरण प्रति वीयू प्रति पुनरावृत्ति

पुनः-samples उस वाक्य में वास्तविक कार्य कर रहा है। `clientProfile` और `timingProfile` एक जीवंत जनरेटर के रूप में. प्रत्येक वीयू पुनरावृत्ति एक हस्ताक्षर चुनता है `headerCompleteness` और `clientHintsPresent` फ्लैग्स, अपने से मिलते हुए एक कुकी बर्तन संलग्न करता है `cookieMode`, लेता है `robots.txt` अगर `robotsConsulted` सही है, फिर नए प्रति खींचता है `delayAfterMs.min..max` और एक नए inter-burst pause से `pauseAfterBurstMs.min..max`Two VUs running the same signature emit two different request streams with the same statistical distribution, which is exactly what the detection pipeline is supposed to recognize as one *क़रीब* क्लाइंट का

```javascript
// Main test function - each VU picks random scenario and replays with burst/jitter.
// Multiple VUs running concurrently provide natural request interleaving.
export default function() {
    const sig = signatures[Math.floor(Math.random() * signatures.length)];
    // ... robots.txt, cookie jar, header bundle built from sig.clientProfile ...

    for (let i = 0; i < sig.requests.length; i++) {
        const req = sig.requests[i];
        const url = `${TARGET_URL}${req.path}`;
        const headers = buildHeaders(req.headers || {}, sig.clientProfile);
        const res = http.request(req.method, url, null, params);

        if (sig.timingProfile) {
            if (requestCount < sig.timingProfile.burstRequests) {
                sleep(randomBetween(
                    sig.timingProfile.delayAfterMs.min / 1000,
                    sig.timingProfile.delayAfterMs.max / 1000));
            } else {
                sleep(randomBetween(
                    sig.timingProfile.pauseAfterBurstMs.min / 1000,
                    sig.timingProfile.pauseAfterBurstMs.max / 1000));
                requestCount = 0;
                burstRate.add(1);
            }
        }
    }
}
```

शीर्षक गुण: **सहीता के लिए आप कसौटी आप निष्पादन के लिए कसौट है**There is no "integration tests pass but production traffic doesn’t *हैं* ट्रैफिक जेनरेटर

मापदंड बीडीएफ सतह के साथ एक ही भाषा बोलते हैं

मापन करता है क्या
|---|---|
| `bot_scenarios` / `human_scenarios` प्रति परिदृश्य वर्ग गणक
| `detection_rate` | किनारे पर चिह्नित बॉट के fraction
| `interval_ms` | InterM SK1request gap trend; checks the timing profile holds under load
| `sensitive_path_rate` | अनुरोधों की hitting भिन्नता `/admin`, `/api`डॉट फ़ाइलें
| `burst_detected` समय प्रोफाइल से व्युत्पन्न बर्स्ट boundary hits
| `http_req_duration` p के लिए मानक लैटेंसी हिस्टोग्राम

इन पर थ्रेसहोल्ड लोड आवरण के लिए एक निष्पादनीय स्पेक्ट बन जाते हैं

```javascript
thresholds: {
    http_req_duration: ['p(95)<1000'],
    http_req_failed: ['rate<0.1'],
    'detection_rate': ['rate>0.3'],
},
```

एक रीफेक्टर जो लोड के तहत पता लगाने की सहीता को रीग्रेज़ करता है `detection_rate`. प्रतिकारक जो विवाद यात्राओं के तहत एक धीमी पथ लाता है `http_req_duration p95`. एक ही स्रोत डेटा

## कैलिब्रेसन: एक ही फ़ाइल का तीसरा उपयोग

इस बिन्दु पर बीडीएफ ने पहले से ही दो कार्य किए हैं-एमएसके0, यह वाद्यकार को जांचा है-एम एसके1, फिर से बजाने के तहत सिग्नल संविदा, एमएसके2 और k के तहत वास्तविक लोड उत्पन्न किया गया है। तीसरा उपयोग मैं सबसे रोचक पाया है, क्योंकि यहाँ BDF के विरुद्ध जाँच किया जाता है *स्वयं*.

प्रत्येक साक्ष्य प्रविष्टि एक फार्म का दावा है `signal OP value, weight w`. एक हस्ताक्षर को फिर से बजाया गया है एक बार \( \under loopback या k \ 6), \ सिस्टम ने एक ही संकेतों के लिए मापित वितरण तैयार किया है `interval_ms_p95 < 200` दावे मापित p95. के विरुद्ध जांच योग्य है `cookie_count >= 2` वास्तव में ले जाया गया अनुरोध की कुकी गणना के साथ जांच योग्य है `header_count >= 8` उन शीर्षिकाओं के खिलाफ जांच की जा सकती है जो उतरे हैं `evidence` में सूचीबद्ध हैं [BDF v2 स्कीमा](https://github.com/scottgal/stylobot/blob/main/docs/bdf-v2-schema.json): `interval_ms_p95`, `interval_ms_p50`, `sensitive_path_rate`, `error_rate`, `burst_detected`, `header_count`, `cookie_count`.)

जब माप किया गया दावा से विभेद करता है, हस्ताक्षर Calibration के बाहर drifted हो गया है . Either it was overspecified for the system it was authored against, or the system has moved underneath itM SK3 Both are usefulMSC4 first says reMsko5generate the signature from observationMsco6 the second says a refactor moved the detection surface in a way no functional test would catchMSKO7

 `python-requests-bdf.json` पहले दिखाया गया एक छोटा सी प्रत्यक्ष उदाहरण है कि क्यों लेखापरीक्षा की जरूरत है सभी `value` (`"burst <150ms"`) जहां स्कीमा को एक संख्या की आवश्यकता है `requestInterval` एक मॉडल ने लिखा है कि पंक्ति, एमएसके1 और कोई इकाई परीक्षण इसे अस्वीकार नहीं करता।

यह बीडीएफ को एक रिग्रेसन आर्टिफैक्ट से एक कैलिब्रेसन आर्टिफेक्ट में बदलता है. `bot-signatures/` LLM - detector पाइपलाइन के एक पहले संस्करण के विरुद्ध उत्पन्न किया गया था ; उनके साक्ष्य दावा क्या एन्कोड *कि* संस्करण सोचा गया कि प्रत्येक क्लाइंट परिवार को अलग करता है. पुनः- आज चल रहे कैलिब्रेशन आपको बताता है कि कौन सी दावे अभी भी धारण कर रहे हैं और कौन सा पुराना हो चुका है।

## गैर--–निर्धारित प्रणाली के परीक्षण के लिए छह नियम

Non-deterministic systems do not require nonM SK1de deterministic tests; they require differently *निर्मित* patterns that work for StyloBot generalize

1. **इनपुट को एक वितरण के रूप में परिभाषित करें** ए `timingProfile` न्यूनतम के साथ/max छिद्र एक जेनेरेटर है।
2. **संविदा को भारित प्रारूपों के रूप में अभिव्यक्त करें** `evidence` à¤à¥à¤°à¥à¤`interval_ms_p95 < 200`), बिन्दु मान नहीं है
3. **गंतव्य पर प्रतिस्थापित करें** उन प्रणालियों के लिए जिनके राज्य एक एंगलियों की छाप है जो पहले के आर्किटिप से बह रही है।
4. **सम्मिलित सतह जांचें, अवयव नहीं** विफल वर्ग नमूने पकड़ नहीं कर सकते वह है जहां घटक अलग-अलग सही हैं लेकिन संरचना कुछ छोड़ देता है
5. **रूपान्तरण को बांड करें, इसे ठीक नहीं करें** एक संगमकर्ता जो एक स्थिर पहचान के लिए शोरात्मक इनपुट को हल करता है कभी-कभी आबंटित करेगा।
6. **इनपुट प्रारूप रीग के माध्यम से साझा करें** जब परिदृश्य एक स्क्रिप्ट के बजाय निष्पादनीय व्यवहारिक संविदा है, तो एक ही फ़ाइल रिग्रेसन यंत्र चलाता है।

## जहाँ यह जारी श्रृंखला में फिट करता है

[असीमित विकास का पता लगाना और स्थिर करना](/blog/stylobot-release-reliability) स्मृति सीमाबद्ध [तेजी से सीखना](/blog/stylobot-release-learning) दोहरा पता लगाना सस्ता किया गया है।

विधि एक कोर्पस है।

तो यह जवाब है " कैसे आप संभवतः StyloBot की तरह कुछ परीक्षण कर सकते हैं-?" आप इसे बर्खास्त नहीं करते हैं, . आप ट्रैफिक के एक वर्ग को परिभाषित करता है।

---


*बीडीएफ रिप्ले रीग में रहता है [`BdfReplayTests.Integration.cs`](https://github.com/scottgal/stylobot/blob/main/src/Mostlylucid.BotDetection.Orchestration.Tests/Integration/BdfReplayTests.Integration.cs). स्लीम रिप्ले सिनारियो नीचे हैं [`test-suites/{bots,humans,adversarial}/*.bdf.json`](https://github.com/scottgal/stylobot/tree/main/test-suites)पूर्ण सांख्यिकी हस्ताक्षरों के साथ ; `clientProfile`, `timingProfile`, `evidence`) के नीचे हैं [`bot-signatures/*.json`](https://github.com/scottgal/stylobot/tree/main/bot-signatures). के रूपांतरक है [`scripts/convert-bdf-to-k6-v2.csx`](https://github.com/scottgal/stylobot/blob/main/scripts/convert-bdf-to-k6-v2.csx). रिप्ले अंतबिंदु है कि दोनों रिग का उपयोग किया जाता है [`BdfReplayEndpoints.cs`](https://github.com/scottgal/stylobot/blob/main/src/Mostlylucid.BotDetection/Endpoints/BdfReplayEndpoints.cs). संकेत संविदा इन परीक्षणों की रक्षा documented में है [`docs/architecture/signal-contracts.md`](https://github.com/scottgal/stylobot/blob/main/docs/architecture/signal-contracts.md). सभी स्रोत पर [github.comM SK1scottgal/stylobot](https://github.com/scottgal/stylobot). लाइव इंजन [stylobot.net](https://www.stylobot.net).*