Useimmat ohjelmistoarkkitehtuurit olettavat, että järjestelmä on staattinen. DiSE olettaa, että järjestelmä on elossa.
Huomaa: Tämä on osa 4 "Cooking with DiSE" -sarjassa. Katso Osa 1, Osa 2: Valmistuneet oppisopimuskoulut, ja Osa 3: Epäluotettavat jumalat Tämä artikkeli on arkkitehtuurin yleiskatsaus - ja nyt meillä on toimiva C#-toteutus: Enimmäkseen lucid.bottihavaitseminen.
Avainkäsite: Käyttäytyminen Roting. Arkkitehtuuri mahdollistaa uuden kategorian, jossa ilmaisimien ja oppimisjärjestelmien läpinäkyvät, säädettävissä olevat "tiimit" refleksiivisesti reitillä, joka perustuu opittuihin käyttäytymismalleihin, ei staattisiin sääntöihin. YARP Gateway, botit eivät koskaan saavuta takaosaasi. Tai käytä keskiohjelmistoa rakentaaksesi käyttäytymisreitityksen suoraan sovelluskerrokseen.
Vuosien ajan olemme rakentaneet ohjelmistoja, kuten kellotöitä: syöttöjä, ulostuloja, sääntöjä, putkistoja, testejä, käyttöönottoa.
Nykyaikaiset järjestelmät, erityisesti tekoälyä käyttävät, eivät kuitenkaan enää käyttäydy kuin kellot. Ne käyttäytyvät kuin ekosysteemit:
Staattinen arkkitehtuuri ei pysy mukana, yksi reikä täytetään, kolme ilmestyy, yksi kynnys viritetään, jokin muu murtuu. Reagoit aina, et koskaan mukautu.
DiSE-arkkitehtuuri (Directed Synthetic Evolution) kohtelee ohjelmistoja tavalla, jolla biologit kohtelevat organismeja: se on asia, jonka täytyy mukautua, korjata itseään ja parantua paineen alla.
Perinteinen arkkitehtuuri:
flowchart LR
B[Build] --> S[Ship] --> P[Patch] --> B
style B stroke:#6366f1,stroke-width:2px
style P stroke:#ef4444,stroke-width:2px
DiSE-arkkitehtuuri:
flowchart LR
P[Perceive] --> E[Evaluate] --> M[Mutate] --> S[Select] --> P
style P stroke:#10b981,stroke-width:2px
style M stroke:#f59e0b,stroke-width:2px
style S stroke:#6366f1,stroke-width:2px
DiSE-järjestelmällä on neljä olennaista käytöstä:
Käyttäytyminen Mitä se tekee Biologisesti vastaava |-----------|--------------|----------------------| | Havaintokyky Kerää signaaleja ympäristöstä Sensuroivat elimet | Arvioi Tulossignaalit päämääriä vastaan Hermosto | Mutaatti Luo strategioiden muunnelmia Geneettistä mutaatiota | Valitse Pidä mikä toimii, hylkää se, mikä ei ole luonnonvalintaa
Tämä ei ole metafora, vaan kirjaimellisesti se, miten järjestelmäsi kehittyy ajan myötä älykkäämmäksi.
Enimmäkseen lucid.bottihavaitseminen on DiSE-periaatteiden ensimmäinen C#-toteutus. Jäljitetään arkkitehtuuri:
Järjestelmässä käytetään liitutauluorkesteri - ilmaisimet antavat näyttöä yhteisestä tilasta ja laukaisevat muut ilmaisimet signaalien kertyessä:
// Detectors emit contributions (evidence), not verdicts
public sealed record DetectionContribution
{
public required string DetectorName { get; init; }
public required string Category { get; init; }
// Positive = bot signal, Negative = human signal
public required double ConfidenceDelta { get; init; }
public double Weight { get; init; } = 1.0;
public required string Reason { get; init; }
public BotType? BotType { get; init; }
// Signals for triggering other detectors
public ImmutableDictionary<string, object> Signals { get; init; }
}
Useita ilmaisimia käynnissä rinnakkaisaalloissaJärjestelmä havaitsee ympäristön monien linssien kautta:
// Wave 0: All detectors with no trigger conditions run in parallel
// Wave N: Detectors whose triggers are now satisfied run in parallel
while (waveNumber < MaxWaves && !cancellationToken.IsCancellationRequested)
{
var readyDetectors = availableDetectors
.Where(d => !ranDetectors.Contains(d.Name))
.Where(d => CanRun(d, state.Signals))
.ToList();
await ExecuteWaveAsync(readyDetectors, state, aggregator, ...);
// Check for early exit on high confidence
if (aggregator.ShouldEarlyExit)
break;
}
Näyttö aggregoidaan päätökseksi sigmoid-muunnoksen avulla – näin saadaan aikaan vahvoja signaaleja suuripainoisilta ilmaisimilta:
private (double botProbability, double confidence) CalculateWeightedScore()
{
var weighted = _contributions
.Where(c => c.Weight > 0)
.Select(c => (delta: c.ConfidenceDelta, weight: c.Weight))
.ToList();
var weightedSum = weighted.Sum(w => w.delta * w.weight);
// Sigmoid maps any real number to (0, 1)
// Strong human signal (-3) → ~5% bot probability
// Neutral (0) → 50% bot probability
// Strong bot signal (+3) → ~95% bot probability
var botProbability = 1.0 / (1.0 + Math.Exp(-weightedSum));
return (botProbability, confidence);
}
Arvioinnissa ei ole kyse yhdestä ainoasta mallista, joka tekee päätöksen. painotettu konsensus Useita erikoistunnistimia - ja ratkaisevaa on, että kun tekoäly ei ole käynnissä, todennäköisyys on kiristetty liiallisen itseluottamuksen välttämiseksi:
// CRITICAL: Clamp probability when AI hasn't run
var botProbability = aiRan
? rawBotProbability
: Math.Clamp(rawBotProbability, 0.20, 0.80);
Järjestelmä ei aina suorita kaikkia ilmaisimia. Kun varhainen näyttö on varma, se lähtee nopeasti:
// Early exit on verified bots (good or bad)
public static DetectionContribution VerifiedGoodBot(
string detector, string botName, string reason) => new()
{
DetectorName = detector,
Category = "Verification",
ConfidenceDelta = 0,
TriggerEarlyExit = true,
EarlyExitVerdict = EarlyExitVerdict.VerifiedGoodBot
};
Tuotannossa korkean luottamuksen pyynnöt poistuvat alle 10 ms Kun vain 2-3 ilmaisinta on samaa mieltä, täysi putki kulkee vain epävarmoja tapauksia varten.
Havaittajat voivat epäonnistua. Järjestelmä suojaa itseään:
// Circuit breaker per detector
private void RecordFailure(string detectorName)
{
var state = _circuitStates.GetOrAdd(detectorName, _ => new CircuitState());
state.FailureCount++;
state.LastFailure = DateTimeOffset.UtcNow;
if (state.FailureCount >= CircuitBreakerThreshold)
{
state.State = CircuitBreakerState.Open;
// Detector disabled until reset time passes
}
}
Epäonnistuneet ilmaisimet poistetaan väliaikaisesti käytöstä. Jäähdytyksen jälkeen niitä kokeillaan uudelleen (puolittain auki). Valintapainetta infrastruktuurin tasolla.
Kun järjestelmä havaitsee suurella varmuudella, se oppii julkaisemalla oppimistapahtumabussiin:
private void PublishLearningEvent(AggregatedEvidence result, ...)
{
var eventType = result.BotProbability >= 0.8
? LearningEventType.HighConfidenceDetection
: LearningEventType.FullDetection;
_learningBus.TryPublish(new LearningEvent
{
Type = eventType,
Confidence = result.Confidence,
Label = result.BotProbability >= 0.5,
Metadata = new Dictionary<string, object>
{
["botProbability"] = result.BotProbability,
["categoryBreakdown"] = result.CategoryBreakdown,
["contributingDetectors"] = result.ContributingDetectors
}
});
}
Tämä syöttää painokauppaan päivittäen heuristisen ilmaisimen opittuja painoja ajan myötä.
DiSE käyttää yhden ainoan "AI-aivon" sijasta kerrostettua kognitiota:
flowchart TB
subgraph Fast["Fast Path (< 100ms)"]
H[Static Heuristics]
D[Detectors]
ML[Learned Heuristic Model]
end
subgraph Slow["Slow Path (Async)"]
LLM[Ollama LLM]
end
subgraph Learn["Learning Layer"]
W[Weight Store]
Rep[Reputation]
end
Fast --> |escalate uncertain| Slow
Slow --> |label| Learn
Learn --> |update weights| Fast
style Fast stroke:#10b981,stroke-width:2px
style Slow stroke:#6366f1,stroke-width:2px
style Learn stroke:#f59e0b,stroke-width:2px
Layer Speed, Purpose Bot Detection -esimerkki |-------|-------|---------|----------------------| | Staattinen heuristiikka Aistinvaraiset vastaukset Tunnetut bot UA -mallit | Ilmaisimet Trait-havainnointi Pääanalyysi, IP-tarkastukset | Opittu heuristiseksi Dynaaminen luokitus Logistinen regressio oppineine painoineen | LLM 50-500 ms Syvällinen päättely Uusia malleja analysoidaan | Oppiminen Taustaa Muistinmuodostus Painon päivitykset, maineen muutokset
Avainymmärrys: järjestelmä oppii omat painonsa reaaliajassa. Ulkopuolisia ML-malleja ei tarvita. Heuristinen ilmaisin alkaa järkevillä oletuksilla ja kehittyy havainnointipalautteen perusteella.
Tulevaisuus: ONNX-mallit, joissa on RAG ja upotus, suunnitellaan v2:lle. Nykyisen heuristisen mallin tuotos toimii merkittynä koulutustietona tulevaan mallikoulutukseen. Arkkitehtuurilla on jo "geneettiset" esineet (osuudet, painot, signaalit), jotka tekevät ohjatun synteettisen evoluution lisäämisestä yksinkertaista - se on suunniteltu lisäpisteeksi.
Tämä heijastaa biologista kognitiota:
Sen sijaan, että järjestelmä lähettäisi ulkoisen ML-mallin, se oppii oman luokittajansa käyttämällä yksinkertaista logistista regressiota, jossa on dynaamista ominaisuutta:
public class HeuristicDetector : IDetector
{
// Default weights - sensible starting points
private static readonly Dictionary<string, float> DefaultWeights = new()
{
// Human-like patterns (negative = more likely human)
["hdr:accept-language"] = -0.6f,
["hdr:referer"] = -0.4f,
["fp:received"] = -0.7f, // Fingerprint = strong human signal
["fp:legitimate"] = -0.8f,
// Bot indicators (positive = more likely bot)
["ua:contains_bot"] = 0.9f,
["ua:headless"] = 0.8f,
["ua:selenium"] = 0.7f,
["ua:curl"] = 0.6f,
["accept:wildcard"] = 0.4f,
};
private (bool IsBot, double Probability) RunInference(Dictionary<string, float> features)
{
// Simple linear model: score = bias + Σ(feature * weight)
float score = _bias;
foreach (var (featureName, featureValue) in features)
{
var weight = _weights.TryGetValue(featureName, out var w)
? w
: DefaultNewFeatureWeight;
score += featureValue * weight;
}
// Sigmoid gives us probability
var probability = 1.0 / (1.0 + Math.Exp(-score));
return (probability > 0.5, probability);
}
}
Ominaisuudet poimitaan dynaamisesti pyynnöstä ja kootuista todisteista:
public static class HeuristicFeatureExtractor
{
public static Dictionary<string, float> ExtractFeatures(
HttpContext context,
AggregatedEvidence evidence)
{
var features = new Dictionary<string, float>();
// Request metadata
features["req:header_count"] = Math.Min(headers.Count / 20f, 1f);
features["req:cookie_count"] = Math.Min(cookies.Count / 10f, 1f);
// Header presence
features["hdr:accept-language"] = headers.ContainsKey("Accept-Language") ? 1f : 0f;
// UA patterns (dynamic - only present if detected)
if (ua.Contains("bot")) features["ua:contains_bot"] = 1f;
if (ua.Contains("selenium")) features["ua:selenium"] = 1f;
// Detector results (named by actual detector)
foreach (var contrib in evidence.Contributions)
features[$"det:{contrib.DetectorName}"] = contrib.ConfidenceDelta;
// Client-side fingerprint - STRONG human signal
if (hasFingerprint)
{
features["fp:received"] = 1f;
features["fp:legitimate"] = 1f;
}
return features;
}
}
Uudet ominaisuudet saavat automaattisesti oletuspainot ja oppivat ajan myötä. Järjestelmä selvittää, mikä on tärkeää.
Painot pysyvät SQLitessä ja päivittyvät eksponentiaalisen liikkuvan keskiarvon avulla:
public class SqliteWeightStore : IWeightStore
{
public async Task RecordObservationAsync(
string signatureType,
string signature,
bool wasBot,
double detectionConfidence,
CancellationToken ct = default)
{
// EMA update: weight = weight * (1 - α) + new_value * α
var alpha = 0.1; // Learning rate
var weightDelta = wasBot ? detectionConfidence : -detectionConfidence;
var sql = @"
INSERT INTO learned_weights (signature_type, signature, weight, ...)
VALUES (@type, @sig, @delta, ...)
ON CONFLICT(signature_type, signature) DO UPDATE SET
weight = weight * (1 - @alpha) + @delta * @alpha,
confidence = MIN(1.0, confidence + @conf * 0.01),
observation_count = observation_count + 1,
last_seen = @now
";
await ExecuteAsync(sql, ...);
}
}
Tämä on mutaatio havainnon kauttaJokainen havainnointi opettaa järjestelmälle jotain. Ajan myötä painot lähentyvät optimaalisia arvoja tiettyihin liikennemalleihin.
DiSE:ssä LLM-hallusinaatio ei ole ötökkä, vaan evoluution generatiivinen substraatti.
Korkean lämpötilan LLM, joka ehdottaa kymmenen muunnelmaa havaintosäännöstä, ei "hallusinoi" – se on Genomin muuntaminen järjestelmän kuvaus:
public async Task<List<DetectionRule>> GenerateMutationsAsync(DetectionContext context)
{
var prompt = $"""
Given this traffic pattern:
{JsonSerializer.Serialize(context)}
Generate 5 variant detection rules that might catch similar patterns.
Return JSON array of rules with: pattern, weight, confidence.
Be creative. Some variants should be strict, some lenient.
""";
var response = await _ollama.GenerateAsync(new GenerateRequest
{
Model = "gemma3:1b",
Prompt = prompt,
Options = new RequestOptions { Temperature = 0.9 } // High creativity
});
return ParseRules(response.Response);
}
Mutaatiot arvioidaan historiallisten tietojen perusteella:
public async Task<DetectionRule?> SelectFittestAsync(
List<DetectionRule> mutations,
List<LabeledRequest> testData)
{
var results = new List<(DetectionRule Rule, double Fitness)>();
foreach (var rule in mutations)
{
var tp = testData.Count(r => rule.Matches(r) && r.IsBot);
var fp = testData.Count(r => rule.Matches(r) && !r.IsBot);
var fn = testData.Count(r => !rule.Matches(r) && r.IsBot);
// F1 score as fitness
var precision = tp / (double)(tp + fp);
var recall = tp / (double)(tp + fn);
var f1 = 2 * (precision * recall) / (precision + recall);
results.Add((rule, f1));
}
return results.OrderByDescending(r => r.Fitness).First().Rule;
}
Vain vahvimmat selviytyvät tuotantoon. Tämä muuttaa LLM:t hauraasta chatbotista evolutionaariset toimijat.
DiSE:n keskiössä on poliittinen järjestelmä - nimetyt konfiguraatiot, jotka määrittelevät, miten havainnointi käyttäytyy:
{
"Policies": {
"fastpath": {
"Description": "Fast path + Heuristic for sync decisions",
"FastPath": ["UserAgent", "Header", "Ip", "Behavioral", "ClientSide", "Inconsistency", "VersionAge"],
"AiPath": ["Heuristic"],
"EscalateToAi": true,
"EarlyExitThreshold": 0.15,
"ImmediateBlockThreshold": 0.90,
"Weights": {
"ClientSide": 0.2,
"Heuristic": 1.5
},
"Transitions": [
{ "WhenRiskExceeds": 0.5, "WhenRiskBelow": 0.85, "GoTo": "demo" }
]
},
"demo": {
"Description": "Full pipeline sync for demonstration",
"FastPath": [],
"AiPath": [],
"BypassTriggerConditions": true,
"ForceSlowPath": true
}
}
}
Politiikassa määritellään:
Järjestelmä voi Siirtyminen politiikasta toiseen kesken pyynnönEpävarmat pikajuoksutulokset yltyvät täyteen demoputkeen. adaptiivinen reititys - genomi reagoi todisteisiin reaaliajassa.
Et lähetä staattisia konfiguraatioita, vaan lähetät Käyttäytymislajit että sopeutuu liikenteeseen.
Jokainen diSE-järjestelmä optimoituu kuntoiluun:
public class FitnessEvaluator
{
public double Evaluate(GenomeConfig genome, EvaluationData data)
{
var fpRate = data.FalsePositives / (double)data.TotalHumans;
var fnRate = data.FalseNegatives / (double)data.TotalBots;
var latency = data.P99LatencyMs;
var cost = data.AiCallsPerRequest * _config.CostPerAiCall;
// Multi-objective fitness
return 1.0
- (fpRate * _config.FalsePositivePenalty) // Don't block humans
- (fnRate * _config.FalseNegativePenalty) // Don't miss bots
- (latency / _config.MaxLatencyMs) // Stay fast
- (cost / _config.MaxCostPerRequest); // Stay cheap
}
}
Emme optimoi tarkkuutta yksin, vaan optimoimme selviytyminen dynaamisessa ympäristössä.
Liikaa tekoälyä → kalliiksi, huono latenssi. Liian vähän tekoälyä → uusien hyökkäysten heikkoa havaitsemista. Liian aggressiivinen → väärät positiiviset, vihaiset käyttäjät. Liian lempeä → bottitulvat.
Järjestelmän on löydettävä vakaa tasapaino.
Kypsä DiSE-järjestelmä siirtää tekoälyn pois kuumalta polulta:
flowchart TB
subgraph Early["Early Stage"]
AI1[AI handles most cases]
end
subgraph Middle["Middle Stage"]
AI2[AI handles edge cases]
H1[Heuristics handle common cases]
end
subgraph Mature["Mature Stage"]
AI3[AI teaches and mutates]
H2[Heuristics handle almost everything]
M[Memory provides context]
end
Early --> Middle --> Mature
style Early stroke:#ef4444,stroke-width:2px
style Middle stroke:#f59e0b,stroke-width:2px
style Mature stroke:#10b981,stroke-width:2px
Ajan myötä:
Tekoälystä tulee:
Ei juoksuriippuvuus, vaan mukautuva rakennusteline.
• • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • YARP GatewayTämä arkkitehtuuri mahdollistaa jotain uutta: Käyttäytymisreititys.
Perinteinen reititys on staattinen: polku → backend. Käyttäytymisen reititys on refleksiivistä: liikenteen ominaisuudet → dynaamiset reitityspäätökset.
flowchart LR
subgraph Gateway["YARP Gateway"]
D[Detector Team]
P[Policy Engine]
R[Router]
end
Traffic[Traffic] --> D
D --> P
P --> R
R -->|Human| App[Your App]
R -->|Bot| Block[403]
R -->|Uncertain| Challenge[Challenge]
R -->|Learning| Queue[Async Analysis]
style Gateway stroke:#10b981,stroke-width:2px
Avainkäsitteet:
Kyse ei ole vain "robottihavaitsemisesta reunalla". Kyseessä on uusi reititysalkukanta, jossa liikennevirtaa muokkaavat opitut käyttäytymismallit, eivät vain staattiset säännöt.
Useimmat insinöörikulttuurit pelkäävät:
DiSE käyttää näitä rakennusmateriaalit.
Staattinen järjestelmä sammuu ja kehittyvät järjestelmät selviävät.
Jokainen teollisuudenala, joka on tekemisissä vastustajien, ajelehtimisen tai mittakaavapaineiden kanssa, tarvitsee lopulta tämänkaltaisia arkkitehtuureja:
Haluan tehdä selväksi, mitä tämä ei ole:
DiSE on kontrolloitu, selittävä evoluutio:
Se johtuu siitä, että ohjattu Evoluutio - ohjattu, ei satunnainen.
Enimmäkseen lucid.bottihavaitseminen toteuttaa nämä periaatteet:
dotnet add package Mostlylucid.BotDetection
builder.Services.AddBotDetection();
app.UseBotDetection();
Määritä tuotanto oppimisella:
{
"BotDetection": {
"BotThreshold": 0.7,
"Policies": {
"default": {
"FastPath": ["UserAgent", "Header", "Ip", "Behavioral", "ClientSide", "Inconsistency", "VersionAge"],
"AiPath": ["Heuristic", "Llm"],
"EscalateToAi": true,
"EarlyExitThreshold": 0.85
}
},
"AiDetection": {
"Provider": "Heuristic",
"Heuristic": {
"Enabled": true,
"LoadLearnedWeights": true,
"EnableWeightLearning": true,
"LearningRate": 0.01
}
}
}
}
Heuristinen ilmaisin oppii jokaisesta pyynnöstä ja päivittää painonsa vastaamaan liikennekuvioitasi.
DiSE Architecture on siirtyminen ohjelmistoista koneina ohjelmistoihin eliönä.
Se on seuraavien arkkitehtuuri:
Staattinen arkkitehtuuri ei pysy dynaamisen ympäristön tahdissa. Hyökkääjät kehittyvät, käyttäjät kehittyvät ja vaatimukset kehittyvät.
Myös järjestelmien on kehityttävä.
Jos haluat järjestelmiä, jotka vain kulkevat, rakenna ne vanhalla tavalla. Jos haluat järjestelmiä, jotka Selviytykää - Rakenna ne DiSE:n kanssa.
© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.