Olen rakentanut StyloFlowin, koska olen kirjoittanut jatkuvasti sama malli toistuvasti: osatekijät, jotka reagoivat siihen, mitä ennen tapahtuneita tapahtumia on tapahtunut , esittävät luottamusta osoittavat pisteet M SK2 ja joskus niiden on edettävä kalliimpiin analyyseihin . Nykyiset työflow-moottorit halusivat, että ajattelen DAG:ien tai valtioiden koneiston osalta MSC4 halusin ajatella signaaleja MST5
PANEE MERKILLE: StyloFlow ei ole vielä valmis tuote; koska rakenn lucidRAGia ja StyloBotta IM SK2 lisäisin puuttuvia ominaisuuksia ja polttoin API:tä sekä Stylo Fllowissa että äskettäin käytössä olevassa järjestelmässä . SeMSC4 on edelleen aktiivisessa kehityksessäMST5 mutta voitte yrittää sen ja antaa palautettaMSR6 päivitän sitä myöhemmin täällä MSL7 esimerkiksi SignalSink-asiat muuttuvat äskeiseen v-järjestelmäänMSSK8 jotta se olisi MSSK9 luettavissa vainMS')
StyloFlow on signaali-, - -johtoinen orkesterikirjasto, joka vastaa miten minä ajattelen asioiden käsittely Tietotekniikkaan perustuvat putkiputket: komponentit ilmoittavat, mitä ne tuottavat ja mitä ne tarvitsevat
Tämä on infrastruktuurin energiaa ilmeinenRAG - ristiinenM SK1modal-grafti RAG-väline, joka yhdistää DocSummarizer (asiakirjat DataSummarizer (rakennetut tiedot ImageSummarizer (kuvat, ) yhtenäiseen kysymykseen,-tietografiikan visualisointiin perustuvan korotusjärjestelmän avulla, Stylobot ( kehitetty bot-suojajärjestelmä ) ja toteuttaa Vähennetty RAG malli.

Lähde: GitHub - StyloFlow
StyloFlow on työ prototypi signaalin ohjaavasta orkestraatiomallista- API ja muoto kehittyvät, kun laadin lucidRAG:tä ja Stylobot:ta, mutta tässä kuvatut täytäntöönpanoa koskevat semantiikat ja muodot ovat kohdalta toteavat merkinnätM SK1 ensimmäisinä merkintöinä-luokkakohtaiset tosiasiat , luottamukselliset merkinnänmuodotMSC4johtoinen laajentuminenMST5 ja eskalaatio rakenteelliseksi muodoksiMSSK6
Tämä ei ole uusi DSL- tai työflow-kieli. täytäntöönpanon semantiikka signaaleja ympäröivä järjestelmä, luottamus järjestelmään, , ja rajattu syvennys järjestelmäään,. Nykyään järjestelmä toimii menettelyssä, jossa on rajallinen rinnakkaisvaikutus,M SK4 Huomenna järjestelmä jakaa reittejä laitteiden välille pitäen samalla viestit vakaana rajana.
Kuten useimmat työflow-moottorit näyttävät, tämä on '.
// ❌ Traditional: Hardcoded dependencies
public async Task ProcessDocumentAsync(string path)
{
var text = await ExtractTextAsync(path);
var chunks = await ChunkTextAsync(text);
var embeddings = await GenerateEmbeddingsAsync(chunks);
var entities = await ExtractEntitiesAsync(chunks);
await StoreEverythingAsync(embeddings, entities);
}
Tämä toimii kunnes:
Päädytte joko:
StyloFlow rakentuu mostlylucid.ephemeral - rajattuun kirjastoon, jäljitettävän async-toiminnon suorittamiseenM SK2
Lyhyt yhteenveto siitä, mitä ephemeral tarjoaa:
// Bounded concurrent processing with full visibility
var coordinator = new EphemeralWorkCoordinator<DocumentJob>(
async (job, operation, ct) => {
await ProcessAsync(job, ct);
operation.Signal("document.processed");
},
new EphemeralOptions { MaxConcurrency = 4 });
// Enqueue work
await coordinator.EnqueueAsync(new DocumentJob(filePath));
// Full observability
Console.WriteLine($"Active: {coordinator.ActiveCount}");
Console.WriteLine($"Completed: {coordinator.TotalCompleted}");
Tärkeimmät ephemerien hyödyt:
Lisätietoja, Tuli ja Don't täysin unohtamatta.
Tämä orkesterimalli laajentaa väliaikaista järjestelmään:
Tässä ”'” on keskeinen arkkitehtuurin muutos – :
graph TD
subgraph Traditional["❌ Traditional: Hardcoded"]
T1[Component A] -->|calls| T2[Component B]
T2 -->|calls| T3[Component C]
T3 -->|calls| T4[Component D]
end
subgraph StyloFlow["✅ StyloFlow: Signal-Driven"]
S1[Component A]
S2[Component B]
S3[Component C]
S4[Component D]
SS[Signal Sink]
S1 -.emits.-> SS
S2 -.emits.-> SS
S3 -.emits.-> SS
SS -.triggers.-> S2
SS -.triggers.-> S3
SS -.triggers.-> S4
end
style T1 stroke:#ff6b6b
style T2 stroke:#ff6b6b
style T3 stroke:#ff6b6b
style T4 stroke:#ff6b6b
style S1 stroke:#51cf66
style S2 stroke:#51cf66
style S3 stroke:#51cf66
style S4 stroke:#51cf66
style SS stroke:#339af0
Osat eivät koskaan kutsu toisiaan toisiinsa. Ne lähettävät signaaleja ja reagoivat niihinM SK1
Viestit ovat tosiasioita siitä, mitä tapahtui, ei käskyjä tai tapahtumia, . ne ovat muodostettavissa,', ne ovat muuttumattomia,,, ne on timestamped,M SK4, ja niissä on luottamuksellisia pisteitä.., kukin atomi omistaa signaalinsa.
public record Signal
{
public required string Key { get; init; } // "document.chunked"
public object? Value { get; init; } // Optional payload
public double Confidence { get; init; } = 1.0; // 0.0 to 1.0
public required string Source { get; init; } // Which component
public DateTime Timestamp { get; init; }
public Dictionary<string, object>? Metadata { get; init; }
}
Critical architectural point: SignalSink on pysyvä historiallinen näkemys
Signalsinkki tarjotaan kyselynä kaikkiin operaatioihin kaikki koordinaattorit, jotka ovat sen kanssa samaa mieltä. signaalit pysyvät koko koordinaattorin elinkaaren ajan - kun operaatio karkottaa koordinaattorinsa, signaali jää pyyhkäisyyn asti kunnes se on käsin puhdistettu
// Create a shared signal sink (no parameters, signals persist)
var sink = new SignalSink();
// Coordinators manage operation lifetime, NOT signal lifetime
var coordinator = new EphemeralWorkCoordinator<string>(
ProcessAsync,
new EphemeralOptions
{
MaxConcurrency = 8,
MaxTrackedOperations = 100, // Operations evict after this
MaxOperationLifetime = TimeSpan.FromMinutes(5), // Or after this time
Signals = sink // Share the persistent view
});
// Operations emit via their emitter
public async Task ProcessAsync(string docId, SignalEmitter emitter, CancellationToken ct)
{
// Store actual data externally (cache, database, blob storage)
await cache.SetAsync($"doc-{docId}", documentData);
// Signal carries a REFERENCE, not the data
emitter.Emit("document.chunked", key: docId); // Key references external data
}
// SignalSink is readonly - it cannot alter signals
// Signals persist until their operation evicts from the coordinator
SignalSink tarjoaa kahta koordinointimallia:
1. PushM SK1pohjainen (Subscribe):
// Subscribe to the sink for push notifications
sink.Subscribe(signal => {
if (signal.Is("document.chunked"))
{
// React immediately - signal includes OperationId
Console.WriteLine($"Op {signal.OperationId} chunked doc at {signal.Timestamp}");
}
});
// Returns IDisposable for cleanup
using var subscription = sink.Subscribe(HandleSignal);
2. PullM SK1perustainen (kysymys):
// Get all signals for a specific operation
var opSignals = sink.GetOpSignals(operationId);
// Detect if any operation has emitted a signal
if (sink.Detect("embeddings.generated"))
{
// At least one operation has generated embeddings
}
// Sense all signals matching a condition
var recentErrors = sink.Sense(s =>
s.Signal.StartsWith("error.") &&
s.Timestamp > DateTimeOffset.UtcNow.AddMinutes(-5)
);
// Get operation summary from its signal history
var summary = sink.GetOp(operationId);
Console.WriteLine($"Operation ran for {summary?.Duration}");
Miksi tämä on tärkeää:
Keskeinen suunnitteluperiaate: Suuret tiedot tallennetaan (asiakirjoihin , kuvia, vektoreihinM SK3 kaseissa tai tietokantoihinMSC4 signaalit sisältävät vain viittauksia, kuten "cache://doc-123" tai operatiiviset avaimet.
Esimerkki koordinoinnista:
// Operation emits signal via ISignalEmitter interface
public async Task ProcessAsync(Item item, ISignalEmitter emitter, CancellationToken ct)
{
// Emit to the sink
emitter.Emit("processing.started");
await DoWorkAsync(item, ct);
emitter.Emit("processing.completed");
}
// Wave checks if it should run by querying sink
public bool ShouldRun(string path, AnalysisContext ctx)
{
// Pull pattern: query the sink via context
return ctx.Detect("document.chunked");
}
// UI subscribes to sink for reactive updates
sink.Subscribe(signal => {
if (signal.Signal.StartsWith("document."))
{
// Push pattern: react immediately
UpdateProgressUI(signal);
}
});
Escalation tapahtuu kahdella tasolla:
// Pattern 1: Intra-coordinator escalation (wave checks signals)
public bool ShouldRun(string path, AnalysisContext ctx)
{
var quality = ctx.GetSignal("quality.score");
return quality?.Confidence < 0.7; // Only run if quality is low
}
// Pattern 2: Inter-coordinator escalation (atom routes to another coordinator)
// Option A: Explicit escalation signal
typed.Raise("escalate.to.expensive", payload, key: "doc-123");
// Option B: EscalatorAtom examines signals and decides
new EscalatorAtomOptions<T> {
ShouldEscalate = evt => evt.Payload.Confidence < 0.7
}
Useat koordinaattorit toimivat itsenäisesti. EscalatorAtom seuraa signaaleja yhdestä koordinaattorista ja siirtää työnsä toiseen, kun se on tarpeen
Tämän , -teorian taustalla on Rajoitettu hämärän taustan vetäminen.
Kriittinen: Viestit ovat yhteensovittamista koskevia tapahtumia, ei tiedonsiirtoaM SK1 suuret tiedot (asiakirjat , kuvatMSC4 sisällytyksetMST5 olisi säilytettävä ulkoisessa talletustilassa
// ❌ BAD: Carrying data in signals (memory pressure, boxing)
var imageBytes = await ProcessImageAsync(input);
emitter.Emit("image.processed", metadata: new { Data = imageBytes });
// ✅ GOOD: Store externally, signal the reference
var imageBytes = await ProcessImageAsync(input);
var cacheKey = $"processed/{docId}";
await cache.SetAsync(cacheKey, imageBytes);
emitter.Emit("image.processed", key: cacheKey);
// Later: Retrieve when needed
if (sink.Detect("image.processed"))
{
var signals = sink.GetOpSignals(operationId);
var imageKey = signals.FirstOrDefault(s => s.Signal == "image.processed")?.Key;
if (imageKey != null)
{
var bytes = await cache.GetAsync<byte[]>(imageKey);
}
}
Parhaat käytännöt:
"cache://key", "blob://container/file", "db://table/id"Manifestit julistavat sopimukset. erillään täytäntöönpanosta. Tämä erottelu on olemassa, joten voitte ymmärtää työprosessia ilman koodin lukemistaM SK1 ja muuttaa toimeenpanojärjestystä ilman uudelleenkompiointia.
name: BotDetector
priority: 10 # Lower runs first
enabled: true
# What kind of component is this?
taxonomy:
kind: analyzer # sensor|analyzer|proposer|gatekeeper
determinism: probabilistic
persistence: ephemeral
# When should this run?
triggers:
requires:
- signal: http.request.received
condition: exists
# What does it produce?
emits:
on_complete:
- key: bot.detected
confidence_range: [0.0, 1.0]
conditional:
- key: bot.escalation.needed
when: confidence < 0.7
# Resource limits
lane:
name: fast # fast|normal|slow|llm
max_concurrency: 8
budget:
max_duration: 100ms
# Configuration values
defaults:
confidence:
bot_detected: 0.6
timing:
timeout_ms: 100
Edut:
Samalla kun YAML-manifestit voidaan kirjoittaa käsillä, StyloFlow sisältää visuaalisen työflow builderin, joka antaa mahdollisuuden suunnitella signaalia-johdettuja työfloweja käyttämällä modulaarisia menetelmiä

UI tarjoaa:
Näin on helppoa kokeilla erilaisia työflow-muodon muotoja kirjoittamatta YAML:tä käsin, ja samalla voida täysin valvoa tuotettua kokoonpanoa.
Valve on yhteensopiva analyysivaihe. Tämä yhteys on olemassa tehdäksemme ", pitäisikö meidän käyttää ?" ensimmäiseen class-päätökseen, ei täytäntöönpanon yksityiskohta, joka on kirjattu ehdolliseen logiikkaan
public interface IContentAnalysisWave
{
string Name { get; }
int Priority { get; } // Higher runs first
bool Enabled { get; set; }
// Quick filter - avoid expensive work
bool ShouldRun(string contentPath, AnalysisContext context);
// Do the analysis
Task<IEnumerable<Signal>> AnalyzeAsync(
string contentPath,
AnalysisContext context,
CancellationToken ct);
}
Yksinkertainen aaltoesimerkki:
public class FileTypeWave : IContentAnalysisWave
{
public string Name => "FileType";
public int Priority => 100;
public bool Enabled { get; set; } = true;
public bool ShouldRun(string path, AnalysisContext ctx)
{
// Skip if we already know the type
return ctx.GetSignal("file.type") == null;
}
public async Task<IEnumerable<Signal>> AnalyzeAsync(
string path,
AnalysisContext ctx,
CancellationToken ct)
{
var extension = Path.GetExtension(path);
var mimeType = GetMimeType(extension);
return new[]
{
new Signal
{
Key = "file.type",
Value = mimeType,
Confidence = 1.0,
Source = Name
}
};
}
}
Aaltokoordinointi:
Euroopan unionin WaveCoordinator kulkee aaltoja ensisijaisessa järjestyksessä:
var coordinator = new WaveCoordinator(waves, profile);
var context = new AnalysisContext();
var results = await coordinator.ExecuteAsync(filePath, context, ct);
// All signals from all waves
foreach (var signal in context.GetAllSignals())
{
Console.WriteLine($"{signal.Key}: {signal.Value}");
}
Kilpailureitittejä:
Vaivat kulkevat reitillä, joilla on erilaisia toistensa raja-arvoja:
| Reitti SSK1 Tavoite | Kilpailu S | |||
|---|---|---|---|---|
fast |
Lyhyt tarkastukset | |||
normal |
Standardikäsittely parsointi, chunkkiminenM SK3 | 8 | ||
io |
IM SK1O-suuntainen (fiili lukee, API-puhelut | |||
llm |
Kultavia LLM-puheluja |
Tämä estää kalliiden operaatioiden jarruttavan halpoja.
Tässä on täydellinen kuva
graph TB
subgraph Input["Input Layer"]
REQ[HTTP Request]
FILE[File Upload]
JOB[Background Job]
end
subgraph Ephemeral["Ephemeral Layer"]
COORD[Work Coordinator]
OPS[Operations<br/>own signals]
SINK[SignalSink<br/>read-only view]
end
subgraph StyloFlow["StyloFlow Layer"]
MAN[Manifests]
WAVE[Wave Coordinator]
ATOMS[Atoms<br/>own signals]
end
subgraph Execution["Execution"]
FAST[Fast Lane]
NORM[Normal Lane]
LLM[LLM Lane]
end
subgraph Output["Output"]
RES[Results]
ESCAL[Escalation]
STORE[Persistence]
end
REQ --> COORD
FILE --> COORD
JOB --> COORD
COORD --> OPS
SINK -.queries.-> OPS
WAVE -.reads.-> SINK
MAN -.configures.-> WAVE
WAVE --> ATOMS
ATOMS --> FAST
ATOMS --> NORM
ATOMS --> LLM
SINK -.queries.-> FAST
SINK -.queries.-> NORM
SINK -.queries.-> LLM
SINK -.read for.-> RES
SINK -.read for.-> ESCAL
SINK -.read for.-> STORE
style COORD stroke:#339af0
style SINK stroke:#339af0
style WAVE stroke:#51cf66
style ATOMS stroke:#51cf66
Yhdyskunta
Oikeusmalli: Jokainen operaatio/atomilla on omat signaalinsa.SignaaliSink tarjoaa luettavan merkinnänM SK2onnillisesti kaikkiin operaatioihin nähden .Signaaleja voidaan syventää MSC4kopioida, ) tai kuunnella, ♫(varmistaa poistamisen jälkeen,♫), mutta omistama luettelo on ulkoisesti muuttamaton,♫ .
Nykyinen toteutusmalli: Yhteinen-prosessiM SK1 rajattu samanaikaisuus , havaittavissa olevat operaatiot LRU:n karkottamisen kanssa
Tuleva toteutusmalli: Reittien jakautuminen eri koneisiin, SignalSink-kysymykset etäoperaatiot, atomit toteutetaan eri hosteilla . Viestit pysyvät vakaana rajana -, ne, ', ovat jo serialisoitavissa, M SK2, ajoitetut, , ja itsenäiset, MSL4, sisältävät, MLS5, omistusmalli ei muuta, MKL6 eikä MKL7
in-prosessin täytäntöönpano vahvistaa semantiikan.
Katsotaan, miten lucidRAG käyttää StyloFlowa:
Taakko 1: Alkuvaiheen havaitseminen
public class FileTypeDetectorWave : IContentAnalysisWave
{
public int Priority => 100; // Run first
public async Task<IEnumerable<Signal>> AnalyzeAsync(...)
{
var extension = Path.GetExtension(path);
return new[]
{
new Signal
{
Key = "file.extension",
Value = extension,
Source = "FileTypeDetector"
}
};
}
}
Taajuus 2:laatiminen (mahdollistetaan asiakirjallaM SK2laajentaminen)
// In manifest:
// triggers:
// requires:
// - signal: file.extension
// condition: in
// value: [".pdf", ".docx", ".md"]
public class ChunkingWave : ConfiguredComponentBase, IContentAnalysisWave
{
public int Priority => 80;
public async Task<IEnumerable<Signal>> AnalyzeAsync(...)
{
var chunks = await ChunkDocumentAsync(path);
ctx.SetCached("chunks", chunks); // Share with other waves
return new[]
{
new Signal
{
Key = "document.chunked",
Value = chunks.Count,
Source = Name
}
};
}
}
Taakko 3: Sisällyttäminen | ( | asiakirjan nojalla pyydetty |. | suljettu |
public class EmbeddingWave : ConfiguredComponentBase, IContentAnalysisWave
{
public int Priority => 60;
public bool ShouldRun(string path, AnalysisContext ctx)
{
// Only run if chunking succeeded
return ctx.GetSignal("document.chunked") != null;
}
public async Task<IEnumerable<Signal>> AnalyzeAsync(...)
{
var chunks = ctx.GetCached<List<Chunk>>("chunks");
var embeddings = await GenerateEmbeddingsAsync(chunks);
ctx.SetCached("embeddings", embeddings);
return new[]
{
new Signal
{
Key = "embeddings.generated",
Value = embeddings.Count,
Source = Name
}
};
}
}
Taakko 4: Entity Extraction (parallel with embeddingM SK2
public class EntityExtractionWave : ConfiguredComponentBase, IContentAnalysisWave
{
public int Priority => 60; // Same as embedding - runs in parallel
public async Task<IEnumerable<Signal>> AnalyzeAsync(...)
{
var chunks = ctx.GetCached<List<Chunk>>("chunks");
// Use deterministic IDF scoring, not LLM per chunk
// (See Reduced RAG pattern)
var entities = await ExtractEntitiesAsync(chunks);
return new[]
{
new Signal
{
Key = "entities.extracted",
Value = entities.Count,
Confidence = CalculateConfidence(entities),
Source = Name
}
};
}
}
Tason 5: Laaduntarkastus
public class QualityCheckWave : ConfiguredComponentBase, IContentAnalysisWave
{
public int Priority => 40; // After embedding + entities
public async Task<IEnumerable<Signal>> AnalyzeAsync(...)
{
var embeddingSignal = ctx.GetSignal("embeddings.generated");
var entitySignal = ctx.GetSignal("entities.extracted");
var embeddingCount = (int)embeddingSignal.Value;
var entityConfidence = entitySignal.Confidence;
var quality = CalculateQuality(embeddingCount, entityConfidence);
var signals = new List<Signal>
{
new Signal
{
Key = "quality.score",
Value = quality,
Source = Name
}
};
// Trigger escalation if quality is poor
if (quality < GetParam<double>("quality_threshold", 0.7))
{
signals.Add(new Signal
{
Key = "escalation.needed",
Value = "low_quality_document",
Source = Name
});
}
return signals;
}
}
Tämän lähestymistavan hyödyt:
Tämä on Vähennetty RAG toimintamalli: päättäväinen ekstrahointi etupäässäM SK1 synteesissä käytettävät LLM-yhdisteet
Stylobot on kehittynyt robotin havaitsemisjärjestelmä, jossa käytetään StyloFlow-järjestelmää monivaiheisen uhan analysoimiseen.
Muodot 1: FanM SK1Out
Yksi signaali käynnistää useat aaltot:
graph LR
S1[document.uploaded] --> W1[ChunkingWave]
S1 --> W2[MetadataWave]
S1 --> W3[LanguageDetectionWave]
W1 -.signal.-> S2[document.chunked]
W2 -.signal.-> S3[metadata.extracted]
W3 -.signal.-> S4[language.detected]
style S1 stroke:#339af0
style S2 stroke:#339af0
style S3 stroke:#339af0
style S4 stroke:#339af0
style W1 stroke:#51cf66
style W2 stroke:#51cf66
style W3 stroke:#51cf66
Pattern 2: Sekuentiaalinen riippuvuus
Vaivat odottavat aikaisempia signaaleja:
graph LR
W1[ExtractWave] -.signal.-> S1[text.extracted]
S1 --> W2[ChunkWave]
W2 -.signal.-> S2[text.chunked]
S2 --> W3[EmbedWave]
W3 -.signal.-> S3[embeddings.generated]
style S1 stroke:#339af0
style S2 stroke:#339af0
style S3 stroke:#339af0
style W1 stroke:#51cf66
style W2 stroke:#51cf66
style W3 stroke:#51cf66
Muodot 3: Poikkeuksellinen leviäminen
Erilaiset aaltot toimivat signaalien perusteella:
graph TD
W1[DetectorWave] -.signal.-> S1{confidence}
S1 -->|< 0.4| W2[RejectWave]
S1 -->|0.4-0.7| W3[EscalateWave]
S1 -->|> 0.7| W4[AcceptWave]
W2 -.signal.-> S2[rejected]
W3 -.signal.-> S3[escalated]
W4 -.signal.-> S4[accepted]
style S1 stroke:#ffd43b
style S2 stroke:#ff6b6b
style S3 stroke:#ff922b
style S4 stroke:#51cf66
style W1 stroke:#339af0
style W2 stroke:#ff6b6b
style W3 stroke:#ff922b
style W4 stroke:#51cf66
Muodot 4: Yhdentäminen
Useat signaalit käynnistävät yhden aalton:
graph LR
W1[Wave A] -.signal.-> S1[a.complete]
W2[Wave B] -.signal.-> S2[b.complete]
W3[Wave C] -.signal.-> S3[c.complete]
S1 --> T{All Ready?}
S2 --> T
S3 --> T
T -->|Yes| W4[AggregatorWave]
W4 -.signal.-> S4[aggregation.complete]
style S1 stroke:#339af0
style S2 stroke:#339af0
style S3 stroke:#339af0
style S4 stroke:#51cf66
style T stroke:#ffd43b
style W4 stroke:#51cf66
StyloFlow tukee eskalointia kahdella tasolla:
Esimerkki lucidRAG:stä: Ensimmäistä kertaa suoritetaan nopean entisiteetin ekstrakointi. Jos laatu M SK2 0.7, EscalatorAtom vie asiakirjan kalliiseen LLM:n viimeistelykoordinaattoriinMSC4 Tämä säästää SSK5x kustannuksia välttämällä kalliita LLM-puheluja korkealaatuisista extraktoinnistaMNK6
Tämä ei ole helppoa-käynnisohjeita; seM SK2 on pienintä esimerkkiä siitä, miten malli sopii yhteen
Asetus:
dotnet add package StyloFlow.Complete
Conceptual entry point:
// 1. Define a wave
public class MyAnalysisWave : IContentAnalysisWave
{
public string Name => "MyAnalysis";
public int Priority => 50;
public bool Enabled { get; set; } = true;
public bool ShouldRun(string path, AnalysisContext ctx) => true;
public async Task<IEnumerable<Signal>> AnalyzeAsync(
string path,
AnalysisContext ctx,
CancellationToken ct)
{
// Your analysis logic here
var result = await AnalyzeAsync(path);
return new[]
{
new Signal
{
Key = "my.signal",
Value = result,
Confidence = 1.0,
Source = Name
}
};
}
}
// 2. Register waves
var waves = new List<IContentAnalysisWave>
{
new MyAnalysisWave(),
new AnotherWave(),
};
// 3. Create coordinator
var coordinator = new WaveCoordinator(
waves,
CoordinatorProfile.Default);
// 4. Execute
var context = new AnalysisContext();
var results = await coordinator.ExecuteAsync(filePath, context);
// 5. Read signals
foreach (var signal in context.GetAllSignals())
{
Console.WriteLine($"{signal.Key}: {signal.Value} ({signal.Confidence})");
}
Ilmoituksen kanssa:
// Load manifests from directory
var loader = new FileSystemManifestLoader("./manifests");
var manifests = await loader.LoadAllAsync();
// Build waves from manifests
var waves = manifests
.Where(m => m.Enabled)
.OrderBy(m => m.Priority)
.Select(m => WaveFactory.Create(m))
.ToList();
var coordinator = new WaveCoordinator(waves, profile);
Täydelliset esimerkit, ovat StyloFlow GitHub-tietokanta.
Yksi StyloFlow-':n keskeisistä ominaisuuksista on työvirran löytäminen - voitte ymmärtää koko putken vain lukemalla manifestit . ei tarvita koodipyyntiä
Tässä on ”'” eli lucidRAG:n todellinen manifest-luettelorakenne.
manifests/
├── 01-file-type-detector.yaml
├── 02-chunking.yaml
├── 03-embedding.yaml
├── 04-entity-extraction.yaml
├── 05-quality-check.yaml
└── 06-escalation.yaml
01-tietokanta
name: FileTypeDetector
priority: 100
enabled: true
description: Detects file type from extension
taxonomy:
kind: sensor
determinism: deterministic
persistence: ephemeral
triggers:
requires:
- signal: document.uploaded
condition: exists
emits:
on_start:
- file.detection.started
on_complete:
- key: file.extension
type: string
confidence_range: [1.0, 1.0]
- key: file.mime_type
type: string
confidence_range: [1.0, 1.0]
lane:
name: fast
max_concurrency: 16
budget:
max_duration: 10ms
02-chunking
name: ChunkingWave
priority: 80
enabled: true
description: Splits documents into semantic chunks
taxonomy:
kind: extractor
determinism: deterministic
persistence: ephemeral
input:
accepts:
- document.pdf
- document.docx
- document.markdown
required_signals:
- file.extension
triggers:
requires:
- signal: file.extension
condition: in
value: [".pdf", ".docx", ".md", ".txt"]
emits:
on_complete:
- key: document.chunked
type: integer
confidence_range: [1.0, 1.0]
- key: chunks.cached
type: boolean
lane:
name: normal
max_concurrency: 8
budget:
max_duration: 30s
defaults:
chunking:
max_chunk_size: 512
overlap: 50
respect_boundaries: true
03-embedding
name: EmbeddingWave
priority: 60
ires:
- signal: file.extension
condition: in
value: [".pdf", ".docx", ".md", ".txt"]
emits:
on_complete:
- key: document.chunked
type: integer
confidence_range: [1.0, 1.0]
- key: chunks.cached
type: boolean
lane:
name: normal
max_concurrency: 8
budget:
max_duration: 30s
defaults:
chunking:
max_chunk_size: 512
overlap: 50
respect_boundaries: true
03-embedding
name: EmbeddingWave
priority: 60
enabled: true
description: Generates ONNX embeddings for chunks
taxonomy:
kind: embedder
determinism: deterministic
persistence: cached
input:
required_signals:
- document.chunked
- chunks.cached
triggers:
requires:
- signal: document.chunked
condition: ">"
value: 0
emits:
on_complete:
- key: embeddings.generated
type: integer
confidence_range: [1.0, 1.0]
lane:
name: normal
max_concurrency: 4
budget:
max_duration: 2m
max_cost: 0.0 # Local ONNX model
defaults:
embedding:
model: all-MiniLM-L6-v2
batch_size: 32
04-
name: EntityExtractionWave
priority: 60 # Same as embedding - runs in parallel
enabled: true
description: Extracts entities using IDF scoring
taxonomy:
kind: extractor
determinism: deterministic
persistence: persisted
input:
required_signals:
- document.chunked
triggers:
requires:
- signal: document.chunked
condition: ">"
value: 0
emits:
on_complete:
- key: entities.extracted
type: integer
confidence_range: [0.0, 1.0] # Confidence varies
lane:
name: normal
max_concurrency: 8
budget:
max_duration: 1m
defaults:
entity:
min_idf_score: 2.5
min_frequency: 2
max_entities: 100
05-
name: QualityCheckWave
priority: 40
enabled: true
description: Validates extraction quality
taxonomy:
kind: gatekeeper
determinism: deterministic
persistence: ephemeral
input:
required_signals:
- embeddings.generated
- entities.extracted
triggers:
requires:
- signal: embeddings.generated
condition: ">"
value: 0
- signal: entities.extracted
condition: exists
emits:
on_complete:
- key: quality.score
type: double
confidence_range: [0.0, 1.0]
conditional:
- key: escalation.needed
when: quality.score < 0.7
lane:
name: fast
max_concurrency: 16
defaults:
quality:
min_embeddings: 5
min_entity_confidence: 0.5
threshold: 0.7
06-eskalaatio
name: EscalationWave
priority: 20
enabled: true
description: Improves low-quality extractions using LLM
taxonomy:
kind: proposer
determinism: probabilistic
persistence: persisted
input:
required_signals:
- escalation.needed
triggers:
requires:
- signal: escalation.needed
condition: exists
skip_when:
- signal: budget.exhausted
emits:
on_complete:
- key: escalation.complete
type: boolean
- key: entities.improved
type: integer
confidence_range: [0.7, 1.0]
lane:
name: llm
max_concurrency: 2 # Expensive
budget:
max_duration: 30s
max_tokens: 4000
max_cost: 0.05
defaults:
llm:
model: gpt-4o-mini
temperature: 0.1
prompt_template: entity_extraction
Näihin tietokantoihin katsoessanne, tiedätte välittömästi:
Ei tarvitse lukea koodia. Työflow on itsenäinen
Edellä mainitut esimerkit osoittavat, että täysin julistavat YAML,-alukset voivat myös olla koodi-pohjaiset atomit asiakirjoissa viitataan
name: CustomAnalyzer
priority: 50
enabled: true
description: Custom analysis logic
# Reference a code-based atom implementation
implementation:
assembly: MyProject.Analyzers
type: MyProject.Analyzers.CustomAnalyzerWave
method: AnalyzeAsync
# The manifest still declares the contract
taxonomy:
kind: analyzer
determinism: probabilistic
triggers:
requires:
- signal: data.ready
emits:
on_complete:
- key: analysis.complete
confidence_range: [0.0, 1.0]
lane:
name: normal
max_concurrency: 4
# Configuration values passed to the atom
defaults:
threshold: 0.75
max_iterations: 10
C# täytäntöönpano
public class CustomAnalyzerWave : ConfiguredComponentBase, IContentAnalysisWave
{
public async Task<IEnumerable<Signal>> AnalyzeAsync(
string path,
AnalysisContext ctx,
CancellationToken ct)
{
// Access manifest config
var threshold = GetParam<double>("threshold", 0.75);
var maxIterations = GetParam<int>("max_iterations", 10);
// Custom logic here
var result = await PerformComplexAnalysis(path, threshold, maxIterations);
return new[]
{
new Signal
{
Key = "analysis.complete",
Value = result.Score,
Confidence = result.Confidence,
Source = Name
}
};
}
}
Edut:
Tämä hybridinen lähestymistapa antaa teille deklaratiivisen työvirran havainnon ja säilyttää samalla monimutkaisen logiikan säilytettävissä C#.
Manifesttirakenne tekee visualisointien luomisesta merkityksetöntä:
graph TD
DOC[document.uploaded] --> FT[FileTypeDetector<br/>Priority: 100<br/>Lane: fast]
FT --> EXT[file.extension]
EXT --> CH[ChunkingWave<br/>Priority: 80<br/>Lane: normal]
CH --> CHUNKED[document.chunked]
CHUNKED --> EMB[EmbeddingWave<br/>Priority: 60<br/>Lane: normal]
CHUNKED --> ENT[EntityExtractionWave<br/>Priority: 60<br/>Lane: normal]
EMB --> EMBGEN[embeddings.generated]
ENT --> ENTEX[entities.extracted]
EMBGEN --> QC[QualityCheckWave<br/>Priority: 40<br/>Lane: fast]
ENTEX --> QC
QC --> QSCORE[quality.score]
QC -.conditional.-> ESC_NEED[escalation.needed]
ESC_NEED -.-> ESC[EscalationWave<br/>Priority: 20<br/>Lane: llm]
ESC --> ESC_DONE[escalation.complete]
style DOC stroke:#339af0
style FT stroke:#51cf66
style CH stroke:#51cf66
style EMB stroke:#51cf66
style ENT stroke:#51cf66
style QC stroke:#ffd43b
style ESC stroke:#ff922b
Tämä diagramma on luotu YAML:n manifesteista - ei käsikirjoitusta .
Yksi StyloFlowin odottamatonta ominaisuutta on se, että se luo järjestelmän LLM:t voivat perustella turvallisesti.
Suurin osa pyrkimyksistä käyttää LLM:itä puutteiden korjaamiseen tai järjestelyyn epäonnistuu, koska järjestelmä, johon ne pudottivat, on hämärä.
StyloFlow tekee päinvastaista. Se paljastaa nimenomaiset, muuttamattomat tosiasiat siitä, mitä tapahtui, milloin ja missä luottamuksessa
Tämä tekee Code LLM:istä aidosti hyödyllisiä — ei toimijoina, vaan analysaattorit.
StyloFlowissa, LLM ei koskaan
Sen sijaan , annetaan SignalSink -näkymä ja esitti kysymyksiä, kuten:
Esimerkki input-koodiin LLM:
{
"operation": "doc-123",
"signals": [
{ "key": "document.chunked", "value": 12, "confidence": 1.0, "source": "ChunkingWave" },
{ "key": "entities.extracted", "value": 4, "confidence": 0.42, "source": "EntityWave" },
{ "key": "quality.score", "value": 0.39, "source": "QualityCheckWave" },
{ "key": "escalation.needed", "source": "QualityCheckWave" }
]
}
Se' ei ole pöytäkirjavirta perusteluperusta.
Kode LLM voi nyt:
Kaikki ilman, että uskotaan lopettaa mikä tahansa.
Perinteinen "LLM debugging" yrittää toistaa maailman
"HereM SK1s the code and some logs , what went wrong?"
StyloFlowin parannuskeino on yksinkertaisempi:
"Tämä on tarkka järjestelmätilanne, jota havaittiin
Koska signaalit ovat muuttamattomia ja omia, ei ole tarpeen toistaa mitään.
LLM:n syyt tosiasioihin, joihin jo luotatte.
Tämä toimii vain tiukkojen rajojen vuoksi:
Ei ole palautusketjua, jossa LLM " päättää seuraavasta askeleestaM SK1 . Useimmissa tapauksissa se ehdottaa selvennyksiä tai konfigurointiehdotuksia siitä, että inhimillinen SSK4 tai deterministinen politiikka) voidaan soveltaa myöhemmin
Tämä epäsymmetria on tahallinen.
Kun viestit,luottamus,, ja tulokset ovat selvät,M SK2 te pöytäkirja myöhemmin:
Mikään näistä ei edellytä sitä, että LLM:n pitäisi johtaa järjestelmää.
LLM:stä tulee diagnoosilinssi, ei valvonta pinta-alaa
StyloFlow ei ainoastaan varmista todennäköisten järjestelmien turvallisuutta
Se tekee niistä kirjallinen — ihmisille
Se, että ' eroaa toisistaan
Vain yksi näistä mittakaavaista.
1. Julkilausuma koostumus
Osat ilmoittavat sopimuksensa. (pyynnöt, ,signaalit,,budjetti,M SK3, eivät ole niiden riippuvuussuhteet.. Järjestelmä määrittelee toimeenpanojärjestyksen.
2. Tavallisesti havaittavissa
Jokainen toimenpide on signaali.
3. Adaptiivinen täytäntöönpano
Luottamuspisteet johtavat laajentumiseen ilman selvää reittijohdon logiikkaa. välttää kalliit vaiheet tarpeettomissa tapauksissa , syvenee epävarmassa vaiheessaM SK2 lopettaa varhaisessa vaiheessa korkealla tasollaMSC3 luottamuksenpuutteet. Valvontavirrat syntyvät signaalimuodon perusteellaMST5
4. testauskelpoisuus ilman mokkipuitteita
Mock-signaalit, ei osiaM SK1
var context = new AnalysisContext();
context.AddSignal(new Signal
{
Key = "document.chunked",
Value = 10,
Confidence = 1.0,
Source = "Test"
});
var wave = new EmbeddingWave();
var results = await wave.AnalyzeAsync(path, context, ct);
Assert.Single(results);
Assert.Equal("embeddings.generated", results.First().Key);
5. Lisääntyvä monimutkaisuus
Aloitetaan yksinkertaisesti:
var coordinator = new EphemeralWorkCoordinator<Job>(ProcessAsync);
Lisätään signaaleja tarpeen mukaan:
new EphemeralOptions { Signals = signalSink }
Lisätään aaltoja moniin vaiheisiin-stage
var waveCoordinator = new WaveCoordinator(waves, profile);
Lisätään manifestit julistavaan konfigurointiin:
name: MyWave
triggers: [...]
emits: [...]
Tässä on täydellinen lucidRAG (ks. yksityiskohtaiset koodiesimerkit kohdassa "Use Case
document.uploaded merkkifile.extension merkkitext.extracted merkkidocument.chunked merkkiembeddings.generated merkkientities.extracted merkkiquality.score merkkiescalation.complete merkkistorage.complete merkkiUI tilaautuu SignalSink-järjestelmään todellisen -aikaisen edistyksen ajantasaistuksia varten (push pattern):
// Subscribe to sink for push notifications
signalSink.Subscribe(signal => {
if (signal.Key.StartsWith("document."))
{
await _hub.Clients.User(userId)
.SendAsync("DocumentProgress", new
{
stage = signal.Key,
progress = CalculateProgress(signal),
operationId = signal.OperationId
});
}
});
Tai käyttäkää pull-mallia, jos haluatte äänestää
// Query SignalSink for document progress (pull pattern)
var documentSignals = signalSink.GetSignals()
.Where(s => s.Key.StartsWith("document.") &&
s.Timestamp > lastCheck);
foreach (var signal in documentSignals)
{
UpdateProgressUI(signal);
}
Keskeinen kohta: Olette allekirjoittanut sinkin (, joka katselee kaikkia atomeja ), ei yksittäisiä operaatioita M SK2 Atomien omat signaalit ; sinkki antaa push-mahdollisuuksia
Näin lucidRAG käsitellään asiakirjoja, ,-tietoja,,-tietoja ja kuvia yhtenäisen signaalin välityksellä, DocSummarizer, DataSummarizer, ja ImageSummarizer Yhden kokoonpanon alla.
Tässä on täydellinen Stylobot (katso yksityiskohtaista koodia "EskalationM SK2 Nopeasta kattavaan"):
bot.detected merkki luottamuksellisestibot.detected merkkibot.detected merkkiTärkein etu–:–luottamukseen perustuvan kasvun vauhdittuminen –.
// ❌ Traditional: Every request gets expensive analysis
var reputation = await CheckIpAsync(ip);
var behavior = await AnalyzeBehaviorAsync(session); // Even if IP is known bad
var llmScore = await LlmAnalysisAsync(conversation); // Always expensive
// ✅ StyloFlow: Waves run based on confidence signals
// BehaviorAnalysis only runs if confidence is ambiguous (0.4-0.7)
// LLM analysis only runs if still unsure after behavior check
Kustannusten jakautuminen: IP-tarkastusta koskevat kustannukset $0 ja käynnistetään 100% ajanjaksostaM SK2 käyttäytymistä koskeva analyysi käynnisttyy 30% M( epäselviä tapauksia). LLM-analyysi käynnissä m5% ( edelleen epäselvääMSC8 kokonaiskustannuksia pyynnöstä kohti $0.0001 vs naiivi "LLM kaikkiM SK1 $0.002 (20xsäästöt
| Merkintö | StyloFlow | väliaikainen | ilmanvirta | ||||||
|---|---|---|---|---|---|---|---|---|---|
| Koordinointi | signaaliM SK1johtoinen | RPC-pohjainen \ | DAG - pohjainen | ||||||
| Julkilausuma | ✅ YAML-manifestit | ||||||||
| ehdollinen | ✅ signaalipyynnöt SSK2 \✅ olosuhteet \ | ✅ Pohjoaminen \ | Escalaatio | ✅ AsennettuM SK2 sisällytetty | \❌ käsikirja SSK5 | ❌ käsikirjojen sisällyttäminen | |||
| Näkyvyys | ✅ signaalijälje | \✅ Työflow-historia | \ ✅ | Tehtävien pöytäkirjat | \✅ | täytäntöönpanohistoria | |||
| Talousarvion valvonta | ✅ TokenM SK2kustannusten rajat | ||||||||
| Paikallinen toimeenpano | ✅ Menettelyssä SSK2 | \ ❌ \Välittävä ryhmittymä | ❌ \ Välitettävä rymittymä | |||||||
| Kilpailureittejä | ✅ NopeutettuM SK2Normalinen/LLM SSK4 \❌ käsikirja | ✅ Pohja-alueet | SSK9 | Palvelun rajat |
Missä tämä malli sopii luonnollisesti
't ( ja voitti
Nämä ovat luonnollisia lisäyksiä malliin, ei sitoumuksia konkreettiseen täytäntöönpanoon.
Kun semantiikka vakautetaan lucidRAG:n ja Stylobotin kehittämisen avulla, nämä mallit ovat elinkelpoisia.
1. Opiminen signaaleista
Seuraa, mitkä eskalaatioreittit toimivat parhaiten:
// Did the LLM escalation improve accuracy?
// Learn to skip it if behavioral analysis is sufficient
2. Kustannusten optimointi
Historialliseen suorituskykyyn perustuva automaattinen reittien määrittäminen:
// If a "slow" wave completes quickly, promote to "normal"
3.Signaalipalautus
Virheet poistetaan pelaamalla uudelleen signaalijärjestelmiä:
var replay = SignalReplay.FromFile("trace.jsonl");
await coordinator.ReplayAsync(replay);
4. monimuotoinenM SK1koordinointi
Jatkakaa reittejä laitteiden välillä pitäen viestit keskitettyinä.
Keskeinen näkemys on tämä: AI-järjestelmissä – , – jokaisella komponentilla on luottamus.
Perinteiset työflowt edellyttävät menestystä
Viestit antavat tämän luonnollisesti:
// Multiple detectors vote
var signals = context.GetSignals("bot.detected");
// Aggregate by confidence
var verdict = signals
.OrderByDescending(s => s.Confidence)
.First();
// Or majority vote
var isBot = signals
.Count(s => (bool)s.Value) > signals.Count() / 2;
// Or weighted average
var score = signals
.Sum(s => (bool)s.Value ? s.Confidence : -s.Confidence)
/ signals.Count();
Tästä syystä StyloFlow toimii hyvin Vähennetty RAG Each extraction stage produces a confidence score, and synthesis only when confidence is high enough
Toimenpidemalli:
Miksi signaalit ovat tärkeitä:
Työrakenteet:
Aiheita koskevat artiklat:
Lähdekoodi: GitHub - StyloFlow
Perinteiset työflow-moottorit pyytävät ilmoittamaan mitä seuraavaksi tapahtuu. Tämä malli pyytää osia ilmoittamaan mitä ne tuottavat ja mitä he tarvitsevat, sallii sen jälkeen, että signaalit koordinoivat toimeenpanoa
Avainsiirto: merkinnät erottuvat, luottamukselliset ohjauksetM SK1 reit suojaavat.
Kyse ei ole siitä, että valitaan StyloFlow tilapäisen tai Airflown kautta.
Jos te rakennatte AI:n, / ja ML:n putkia, missä
...siten nämä täytäntöönpanoa koskevat semantiikat saattavat sopia teidän mielipiteenne mukaan
Euroopan unionin väliaikainen kirjasto on vakaa perusta. StyloFlow lisää signaalia-johdetun orkesterivyöhykkeen yläpuolelleM SK2 Molemmat kehittyvät lucidRAG:n ja Stylobotin todellisen käytön kautta
Kysymyksiin tai palautteisiin, voi tutustua GitHub-tietokanta.
© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.