Uno dei modi più facili per far fallire un sistema AI è lasciarlo ricordare troppo.
La maggior parte degli approcci "context handlingM SK1 si riduce a uno dei due errori:
Entrambi gli approcci sono costosi, opaco, e instabili a lungo termineM SK2
C'è un modello migliore - che riflette il modo in cui i sistemi biologici scalano la cognizione .
Io lo chiamo. Dragging Contexto Fuzzy Constrained (CFCD
Dragging Contexto Fuzzy Constrained è un modello in cui i modelli probabilistici propongono ciò che è saliente, ma solo le regole deterministiche sono autorizzate a portare avanti quella salienza per influenzare il ragionamento futuro o la generazione.
O più chiaramente:
I modelli possono notare. L'ingegneria decide cosa rimane.
Questa è la stessa divisione filosofica. Fuzzinesse limitata e MoM Fuzzy Constretto - è stato applicato lungo il L'asse del tempo Invece di L'asse decisionale..
I LLM non "ricordate". Hanno uno schemaM SK2combaciano con i tokensMSC3
Quando trattiamo il contesto come " solo più testoM SK1 otteniamo:
Le finestre del contesto più lunghe non lo risolvono. Rimangono solo in ritardo il fallimento.
La vera domanda non è Quanto? Il contesto per mantenere, ma:
Cosa merita di sopravvivere?
CFCD impone una separazione dura:
| Role | Permessa di essere flessibileM SK2 | Permetteta di diventare un limite futuro? |
|---|---|---|
| Detezione della salinità | Sì | No S |
| Promozione del contesto | No | Sì M |
| Generazione | Sì | No S |
| Conservazione dell'ancora (ledger) | No | Sì S |
La probabilità può suggerire. Il determinismo decide cosa viene spinto avanti.
Significa determinista: Gli stessi input + la stessa politica ⇒ gli stessi ancor. Potete ancora usare i punteggi probabilistici; li fate semplicemente passare attraverso una promozione fissaM SK2funzioni di decommissione (MMRMST4 RRFMSV5 regole di votoMSS6
La CFCD è il modo in cui si ottengono i benefici del contesto senza pagare il prezzo del contesto.
Questo fallisce perché:
Il punto di vista chiave: La rilevazione della salienza non richiede un LLM.. Si può usare il ML deterministico (embeddings, TFM SK3IDFMSC4 BMMska5 per trovare ciò che contaMske6 e poi restringere l'LLM per vedere solo quello che è la selezione sopravvissuta.
DocSummarizer Implementa questo:
Il LLM non vede mai il documento completo. Genera intorno agli ancori, non attraverso loroM SK2
// From DocSummarizer: SegmentExtractor.cs
public class SegmentExtractor
{
private readonly OnnxEmbeddingService _embeddingService; // ML, not LLM
public async Task<ExtractionResult> ExtractAsync(string docId, string markdown)
{
// 1. Parse document into typed segments
var segments = ParseToSegments(docId, markdown);
// 2. For large docs: semantic pre-filtering with multi-anchor approach
// - Guaranteed coverage: first/last sentences per section, constraints
// - BM25 candidate generation with pseudo-query from TF-IDF terms
// - Topic anchors via k-means clustering on sample embeddings
if (segments.Count > _config.MaxSegmentsToEmbed)
{
(segmentsToEmbed, centroid) = await SemanticPreFilterAsync(segments, targetCount);
}
else
{
await GenerateEmbeddingsAsync(segments);
centroid = CalculateCentroid(segments);
}
// 3. Score by salience using MMR (deterministic)
// Salience = lambda * sim(segment, centroid) * position_weight * content_weight
// - (1 - lambda) * max_sim(segment, higher_ranked_segments)
ComputeSalienceScores(segments, centroid, contentType);
// 4. Return top-K as anchors for synthesis
var topBySalience = segments
.OrderByDescending(s => s.SalienceScore)
.Take(Math.Max(_config.FallbackBucketSize, targetCount))
.ToList();
return new ExtractionResult
{
AllSegments = segments,
TopBySalience = topBySalience,
Centroid = centroid,
ContentType = contentType
};
}
/// <summary>
/// Greedy MMR selection: balances relevance with diversity
/// </summary>
private void ComputeSalienceScores(List<Segment> segments, float[] centroid, ContentType contentType)
{
var candidates = new HashSet<Segment>(segments.Where(s => s.Embedding != null));
var ranked = new List<Segment>();
// Pre-compute centroid similarities with content-type adjustments
foreach (var segment in candidates)
{
var baseSim = CosineSimilarity(segment.Embedding!, centroid);
var contentWeight = ComputeContentTypeWeight(segment, contentType);
segment.SalienceScore = baseSim * segment.PositionWeight * contentWeight;
}
// Greedy MMR: pick best, penalise similar, repeat
while (candidates.Count > 0)
{
var best = candidates
.Select(c => new {
Segment = c,
Score = _config.MmrLambda * c.SalienceScore
- (1 - _config.MmrLambda) * MaxSimToRanked(c, ranked)
})
.OrderByDescending(x => x.Score)
.First();
best.Segment.SalienceScore = 1.0 - ((double)ranked.Count / segments.Count);
ranked.Add(best.Segment);
candidates.Remove(best.Segment);
}
}
}
Perché il risultato è un Raccolta in classifica, si può adattare il numero di ancori al modello di sintesi durante l'attivazione.
public class AdaptiveSynthesizer
{
public int ComputeAnchorBudget(ModelProfile model, ExtractionResult extraction)
{
// Larger context windows → more anchors
var baseTokenBudget = model.ContextWindow / 4; // Reserve 25% for output
// More powerful models → can handle more complex synthesis
var complexityMultiplier = model.Tier switch
{
ModelTier.Small => 0.5, // tinyllama: fewer, simpler anchors
ModelTier.Medium => 1.0, // llama3.2:3b: standard
ModelTier.Large => 1.5, // llama3.1:8b+: more context, nuanced synthesis
_ => 1.0
};
var anchorBudget = (int)(baseTokenBudget * complexityMultiplier / _avgTokensPerSegment);
// Never exceed what we have
return Math.Min(anchorBudget, extraction.TopBySalience.Count);
}
public async Task<Summary> SynthesizeAsync(
ExtractionResult extraction,
ModelProfile model)
{
var budget = ComputeAnchorBudget(model, extraction);
// Take top-K from already-ranked segments
var anchors = extraction.TopBySalience.Take(budget).ToList();
// Synthesis model only sees what survived selection + adaptation
return await _llm.SynthesizeAsync(anchors, model);
}
}
Questo è ancora deterministico: Gli stessi input + lo stesso profilo del modello → gli stessi ancri. Il ranking avviene una voltaM SK1 l'adattamento è solo un pezzo.
Questo significa che si può:
Il punto di vista chiave: I cavi sono strutturali, non prosa.. Gli inserimenti e il MMR sono deterministiciM SK1 Il LLM fa solo la sintesi finale, delimitato da ciò che è sopravvissuto
Contratto diancora: La generazione può variare la formulazione, ma non deve contraddizionare le ancorheM SK1 Se le ancore sono insufficienti, deve essere protetta e / o chiedere più proveMSC4
Una rappresentazione di un ancraggio di cemento:
{
"policyVersion": "cfcd-v1",
"segments": [
{"id":"seg-12","text":"Reset requires holding button 10s","salience":0.92},
{"id":"seg-45","text":"Factory reset clears all settings","salience":0.88}
],
"coverage": "3.2% semantic sample",
"hedging": "sampled 3% - avoid definitive conclusions"
}
La traduzione mostra ancora più chiaramente questo schema.
Traslate la frase-da-sentenza e otteneteM SK2
Anche con un'enorme finestra di contesto, i modelli ancora " sembrano liberiM SK2 per variare le frasi .
Quello che conta come forte prova locale?
Questo è deterministico: i segnali strutturali vengono rilevati tramite la classificazione dei modelli o del parsatoreM SK1 non lo studio dei modelli.
La politica di default: ΔM SK1 L'incertezza di fiducia, W =50 blocchi MST4 fortuna per dominioMSC5
public class TermLedger
{
private readonly Dictionary<string, TermMapping> _mappings = new();
public record TermMapping(
string SourceTerm,
string TargetTerm,
float Confidence,
string FirstSeenChunkId,
int LastSeenChunkIndex, // Track recency
int VotesForCurrentTarget,
int TotalVotes, // Preserve history
string? ChallengerTarget = null,
int ChallengerVotes = 0,
float ChallengerConfidence = 0);
public void ProposeMapping(string source, string target, float confidence, string chunkId, int chunkIndex)
{
source = source.ToLowerInvariant().Trim();
if (_mappings.TryGetValue(source, out var existing))
{
if (existing.TargetTerm == target)
{
// Same as current: accumulate votes
_mappings[source] = existing with
{
Confidence = Math.Max(existing.Confidence, confidence),
VotesForCurrentTarget = existing.VotesForCurrentTarget + 1,
TotalVotes = existing.TotalVotes + 1,
LastSeenChunkIndex = chunkIndex
};
}
else if (existing.ChallengerTarget == target)
{
// Same as challenger: accumulate challenger votes
var newChallengerVotes = existing.ChallengerVotes + 1;
var newChallengerConfidence = Math.Max(existing.ChallengerConfidence, confidence);
// Switch if challenger has >= 2 votes AND higher confidence
if (newChallengerVotes >= 2 && newChallengerConfidence > existing.Confidence)
{
// Swap: old current becomes challenger, challenger becomes current
_mappings[source] = existing with
{
TargetTerm = target,
Confidence = newChallengerConfidence,
VotesForCurrentTarget = newChallengerVotes,
TotalVotes = existing.TotalVotes + 1,
LastSeenChunkIndex = chunkIndex,
ChallengerTarget = existing.TargetTerm, // Preserve old mapping as challenger
ChallengerVotes = existing.VotesForCurrentTarget,
ChallengerConfidence = existing.Confidence
};
}
else
{
_mappings[source] = existing with
{
ChallengerVotes = newChallengerVotes,
ChallengerConfidence = newChallengerConfidence,
TotalVotes = existing.TotalVotes + 1,
LastSeenChunkIndex = chunkIndex
};
}
}
else if (confidence > existing.ChallengerConfidence)
{
// New challenger replaces old challenger
_mappings[source] = existing with
{
ChallengerTarget = target,
ChallengerVotes = 1,
ChallengerConfidence = confidence,
TotalVotes = existing.TotalVotes + 1,
LastSeenChunkIndex = chunkIndex
};
}
}
else
{
_mappings[source] = new TermMapping(
source, target, confidence, chunkId, chunkIndex,
VotesForCurrentTarget: 1, TotalVotes: 1);
}
}
public string? GetCanonicalTranslation(string source)
{
source = source.ToLowerInvariant().Trim();
return _mappings.TryGetValue(source, out var mapping)
? mapping.TargetTerm
: null;
}
}
In pratica volete anche la decasione del voto (o una finestra scorrere ) così che gli errori precoci non diventino permanentiM SK3 La chiave è che la regola della decazione sia determinista, non modelloMSC5deciziataMST6
Perché questo è importante per la debugging: Se la traduzione ruota "factory reset" midM SK2document , si può differenziare il ledger e vedere esattamente quando e perché.
chunk-12: "factory reset" → "Werkseinstellungen" (votes: 3, conf: 0.82)
chunk-47: challenger "Zurücksetzen" reaches 2 votes, conf: 0.91
chunk-47: SWITCH - "factory reset" → "Zurücksetzen" (old mapping preserved as challenger)
Niente indovinare. No "il modello è appena decisoM SK2 Inspicchabile , deterministicoM Sk4 verificabileM sk5
Questo ti dà:
Ecco perché. coerenza terminologica non può essere risolto con " solo più contesto".
La CFCD lo fa. Non. dare la memoria del modello.
E' una cosa che dà Il sistema memoria.
Il modello:
Il sistema:
Regole di scadenza (deterministaM SK1 non modello-decittoMSC3
T senza essere riferita.N i frammenti successivi decadono.Questa distinzione è tutto.
flowchart TB
subgraph Model["Probabilistic Model"]
M1[Detect Salience]
M2[Generate Output]
end
subgraph System["Deterministic System"]
S1[Promote Anchors]
S2[Store in Ledger]
S3[Enforce on Generation]
S4[Expire Stale Context]
end
M1 --> S1 --> S2
S2 --> S3 --> M2
S2 --> S4
style Model stroke:#f59e0b,stroke-width:2px
style System stroke:#22c55e,stroke-width:3px
Ecco il modello con il ledger come primo oggetto della classe -:
flowchart LR
S[Stream: chunks/sentences] --> M[Model proposes salience]
M --> P[Promotion rules]
P --> L[Ledger / Anchors]
L --> G[Generation constrained by anchors]
G --> O[Output]
L --> E[Expiry rules]
E -.-> L
style L stroke:#22c55e,stroke-width:3px
style P stroke:#22c55e,stroke-width:2px
style E stroke:#22c55e,stroke-width:2px
style M stroke:#f59e0b,stroke-width:2px
style G stroke:#f59e0b,stroke-width:2px
Le scatole verdi sono deterministe. Le squadre arancione sono probabilistice. Il ledger si siede tra di loro , tenendo ciò che è sopravvissutoM SK3
Tre quarti:
Il prompt diventa un Vedere del ledger, non il ledger stesso.
Quello ' è il momento "grok"M SK3 Il ledger non è il contesto . È un contratto.
Gli ancor non sono "testo importante". Sono i fatti strutturati, che limitano la generazione:
factory reset → restore factory settingsProductName, ModelNumber, UserIDpolicyVersion: "cfcd-v1", anchorSchemaVersion: 2Il punto è che le ancorhe non sono prosa, sono strutture, il modello scrive intorno a loro.
Questa è un'analogia, non una affermazione biologica: il punto è la consolidazione selettivaM SK2 non il meccanismo letterale .
I cervelli non riproducono l'intero flusso sensoriale.
They:
La lingua, le capacità motori, e la percezione si basano tutti su Carriere limitata-forward, non richiamo grezzo.
Il CFCD è lo stesso principio, implementato meccanicamente.
| Systemo biologico | Equivalente CFCD | |
|---|---|---|
| Attenzione (Cosa notare) | Detezione della salinità | |
| Consolidazione (ciò che ricordare) | Promozione dell'ancora SSK4deterministaM SK5 | |
| Inhibizione (Cosa ignorare) | Regole di deterrimento SSK4deterministicheM SK5 | |
| Ricominciare (che cosa cercare) | Chiedere il foglio SSK4deterministaM SK5 |
CFMoM e CFCD sono la stessa idea vista da diversi angoli:
| Dimensioni | Pattern |
|---|---|
| Progettore singolo | Fuzzinesse limitata |
| Molti proponenti | MoM Fuzzy Constretto |
| LongM SK1Contexto horizontale | Dragging Constraint Fuzzy Contexto |
Tutti tre rispettano la stessa regola:
Probabilità propone. Il determinismo persiste.
Una volta che si interiorizza quella regola, la maggior parte "il design del sistema AIM SK2 smette di essere misterioso.
flowchart LR
subgraph CFP["Part 1: Constrained Fuzziness"]
P1[Single Proposer] --> C1[Constrainer] --> O1[Output]
end
subgraph CFMoM["Part 2: Constrained Fuzzy MoM"]
P2A[Proposer A] --> CS[Consensus Space]
P2B[Proposer B] --> CS
P2C[Proposer C] --> CS
CS --> C2[Coordination Constrainer] --> O2[Output]
end
subgraph CFCD["Part 3: Context Dragging"]
T1[Time T] --> A1[Anchors]
T2[Time T+1] --> A1
A1 --> C3[Constrained Generation] --> O3[Output]
end
style CFP stroke:#22c55e,stroke-width:2px
style CFMoM stroke:#3b82f6,stroke-width:2px
style CFCD stroke:#8b5cf6,stroke-width:2px
Perché è così.
In altre parole: è ottimizzato per la produzione, non è insinuanteM SK2
| Anti--Pattern | Problemo | Soluzione CFCD M |
|---|---|---|
| Mettete tutto nel contesto. | Costo senza limitiM SK1 diluzione dell'attenzione | promuovere solo quello che sopravvive alla selezione |
| Ricursiva sommificazione | DriftM SK1 contraddizioni | Gli ancor sono strutturati, non prosa |
| Spero che il modello si ricordi. | Nessuna garanzia | Il sistema possiede la persistenza |
| Per-request full re-processing | Scale dei costi con storia | Il ledger persiste per tutte le richieste PSK2 |
| linguaggio naturale "memory" | Distorsione semantica | Ancore digitate, mappamenti espliciti MSC3 |
| Uno-grandezza-combacia con l'-intero contesto | Modello per la capacità di scarico o per l'infiammazione | Pieghe adattative dalla raccolta classificata |
Mostlylucid.Ephemeral è il substrato che rende pratica la CFCD. Se non avete letto gli articoli di fondo'
| Primitivi ephemeri | Role del CFCD |
|---|---|
| I segnali | Candidata salienza (modello propone) |
| finestre limitate | No unbounded "memory |
| Regole di Evizione | Il dimenticare è esplicito |
| L'expizione a cascata | Il contesto dello stop si spegne automaticamente |
| La propagazione del segnale | Gli ancrasi portano avanti senza mutazione |
Ephemerio non "ricordate". È Decide cosa può essere ricordato, e per quanto tempo..
Questo è esattamente quello che richiede la CFCD.
public class CFCDCoordinator
{
private readonly SignalSink _sink;
private readonly TermLedger _ledger;
private readonly TimeSpan _anchorLifetime = TimeSpan.FromHours(1);
public void PromoteAnchor(string term, string translation, string chunkId, int chunkIndex)
{
_ledger.ProposeMapping(term, translation, 0.8f, chunkId, chunkIndex);
// Emit signal for observability (key = chunkId for correlation)
_sink.Raise($"anchor.promoted:{term}", key: chunkId);
}
public void ExpireStaleAnchors()
{
var cutoff = DateTimeOffset.UtcNow - _anchorLifetime;
// Ledger entries older than cutoff without recent usage are removed
// This is deterministic, not model-decided
_ledger.ExpireOlderThan(cutoff);
_sink.Raise("anchors.expired");
}
}
Metterli insieme per un'intera catena di traduzione del documento:
public class CFCDTranslationPipeline
{
private readonly ILlmService _llm;
private readonly TermLedger _ledger;
private readonly SignalSink _sink;
private readonly int _seedChunks = 3; // K: configurable seed window
public async Task<TranslatedDocument> TranslateAsync(
Document source,
string targetLanguage)
{
var chunks = Chunker.Chunk(source, maxTokens: 500).ToList();
var translated = new List<TranslatedChunk>();
// Phase 1: Extract terminology candidates (first pass, fuzzy)
// Seed from first K chunks: front-loads terminology, avoids churn later
for (var i = 0; i < Math.Min(_seedChunks, chunks.Count); i++)
{
var chunk = chunks[i];
var candidates = await _llm.ExtractTerminologyAsync(chunk);
foreach (var term in candidates)
{
_ledger.ProposeMapping(
term.Source,
term.ProposedTranslation,
term.Confidence,
chunkId: chunk.Id,
chunkIndex: i);
}
}
_sink.Raise("terminology.seeded");
// Phase 2: Translate with ledger constraints
for (var i = 0; i < chunks.Count; i++)
{
var chunk = chunks[i];
// Get canonical translations for terms in this chunk
var constraints = ExtractConstraints(chunk, _ledger);
// Translate with constraints (model must respect ledger)
var result = await _llm.TranslateWithConstraintsAsync(
chunk,
targetLanguage,
constraints);
// Update ledger with any new terms (deterministic rules)
foreach (var newTerm in result.NewTerminology)
{
if (ShouldPromote(newTerm, _ledger))
{
_ledger.ProposeMapping(
newTerm.Source,
newTerm.Target,
newTerm.Confidence,
chunkId: chunk.Id,
chunkIndex: i);
_sink.Raise($"anchor.promoted:{newTerm.Source}");
}
}
translated.Add(result.Chunk);
}
return new TranslatedDocument(translated, _ledger.GetAllMappings());
}
private bool ShouldPromote(TermCandidate term, TermLedger ledger)
{
// Deterministic rules, not model judgment:
// - Proper nouns always promoted
// - Technical terms promoted if repeated
// - Common words never promoted
return term.Type == TermType.ProperNoun ||
(term.Type == TermType.Technical && term.OccurrenceCount >= 2);
}
}
L'errore che fanno la maggior parte dei sistemi AI è supporre che l'intelligenza migliora ricordando. più.
In pratica, l'intelligenza si basa sul fatto di decidere cosa fare. Non dovremo più pensarci..
CFCD è il modo in cui lo fai senza mentire a te stesso.
| Parte | Tipo | Asse S |
|---|---|---|
| 1 | Fuzzinesse limitata | Componente unica |
| 2 | MoM Fuzzy Constretto | Numerosi componenti |
| 3 ≥ | Dragging Constraint Fuzzy Contexto (Questo articolo) ♫ | Tempo ♫ / memoria ♫ |
| 4 | Summarizatore dell'immagine | Implementazione pratica |
Tutti i tre modelli hanno la stessa invariante: Componenti probabilistice propose; sistemi deterministici persistono.
L'informazione figura nella parte dispositiva. Dieci comandamenti dell'uso del LLM codificare queste regole. L'architettura di DiSE li implementa per l'evoluzione del codice. Detezione del bot li implementa per classificare le richieste. DocSummarizer li implementa per la ricerca del documento. ImageSummarizer li implementa per l'analisi delle immagini.
Domeni diversi. Stesso schema. Stessa regolaM SK2 DoomSummarizer implements context dragging for parallel long-form document generation - running summariesM SK2 negative prompts, entity continuityMSC4 and drift detection maintain coherence across concurrent LLM calls
Parte 4 Ora è disponibile: Summarizer Image : Un motore RAG di immagini constratte Fuzzy. Implementa tutti i tre modelli in una onda - basato su un tubo di analisi dell'immagineM SK2ColorWave calcola i fatti, VisionLlmWave proponeMSC4 ImageLedger accumula caratteristiche salientiMST5 e la selezione deterministica limita il risultatoMst6 Lo clona da github.comM SK1scottgal/lucidrag.
© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.