En av de enklaste sätten att få ett AI-system att misslyckas är att låta det minnas för mycket
De flesta " handlingar av sammanhanget" tillvägagångssätt leder till en av två fel
Båda dessa tillvägagångssätt är dyra
Det finns ett bättre mönster, -, som speglar hur biologiska system faktiskt skalar kognition.
Jag kallar det Begränsat Fuzzy Kontexttdragning (CFCD).
Begränsat Fuzzy Kontexttdragning är ett mönster där sannolikhetsmodeller föreslår vad som är relevantt, men bara deterministiska regler är tillåtna att föra fram det relevanta för att påverka framtidens resonemang eller generation.
Eller mer tydligt:
Modeller kan lägga märke till
Detta är samma filosofiska splittring som Begränsad otydighet och Begränsad Fuzzy MoM - bara tillämpades längs tidsaxeln istället för besluts Axel.
LLMs är inte " minnen ". De har en mönster- som matchar grenar över
När vi behandlar sammanhanget som " bara mer text
Längare kontextfenster löser inte detta.
Den verkliga frågan är inte hur mycket kontext att behålla, men:
Vad förtjänar att överleva
CFCD tvingar till en hård separation:
| Rolar | tillåten att vara fuzzyt? | tiläten att bli framtida begränsningarM SK4 | |||||
|---|---|---|---|---|---|---|---|
| Detektor av löshet | Ja | Nej | |||||
| Kontextförbättring | Nej | Ja | |||||
| Generering | Ja | Nej МСK3 | |||||
| Ankerlagning | ( | lagaren | ) | МSK3 | Nej ♫ | Ja ♫ |
sannolikhet kan föreslå. Determinism bestämmer vad som drars fram
Deterministiskt betyder: samma ingångar + samma policy ⇒ samma ankar. Du kan fortfarande använda sannolikhetsnotar ; du bara kör dem genom en bestämd promotion M SK2 utgångsfunktioner
CFCD är hur man får fördelarna med ett sammanhang utan att betala priset för ett sammanhang
Detta misslyckas eftersom:
Den viktigaste insikten salience-detektorn kräver inte ett LLM. Du kan använda deterministisk ML (embeddings, TFM SK3IDFMska4 BMM Ska5 för att hitta vad som är viktigt Mska6 och sedan begränsa LLM för att bara se vad som överlevt urvalen
DocSummarizer implementerar detta:
LLM ser aldrig hela dokumentet.
// 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);
}
}
}
Eftersom utgången är en klassificerad samling, kan du anpassa ankartalet till syntetiska modellen vid starttid
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);
}
}
Detta är fortfarande deterministiskt: samma ingångar + samma modellprofil → samma ankar. Rangeringen sker en gång
Det betyder att du kan
Den viktigaste insikten ankar är strukturer, inte prose. Embeddingerna och MMR är deterministiska. LLM gör bara den slutgiltiga synenM SK2 omringad av vad som överlevt
Ankarkontrakt: generation may vary phrasing, but must not contradict anchors
En konkret ankarrepresentation:
{
"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"
}
Talande visar detta mönster ännu mer tydligt
översätta meningen
Även med ett stort kontextfenster
Vad räknas som starka lokala bevis?
Detta är deterministiskt : strukturella ledtrådar upptäcks genom mönster eller parserklassificering
Standardpolitiken : Δ=0.08 trovärdighetsmängd , WM SK3 bitar ( tur per domain M SK5
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;
}
}
I praktiken vill man också ha röstförruttning ( eller en ruttningsfenster ) så att tidiga misstag inte blir permanentaM SK3 Nyckeln är att förruttningensregeln är deterministisk
Varför är detta viktigt för att lösa problem?: Om översättningen vänder " fabriksreset " mitten | - | dokument |, | kan du differa ledgern och se exakt när och varför
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)
Ingen gissning . Nej "modellet bestämde sig för att göra det". Obsekabelt M SK3 deterministiskt , revidbart MSC5
Det ger dig
Det är därför terminologisk konsistens kan inte lösas med " bara mer kontext
CFCD gör det inte ge modellen minne.
Det ger system minne.
Modelet:
Systemet:
Förbättrande regler (deterministisk
T utan att vara referenseradN följande chunks bryts utDen skillnaden är allt
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
Här är mönstret med ledgern som ett första objekt
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
De gröna lådorna är deterministiska.
Tre vänder:
Prompten blir en syn i ledgern.
Det är "'" -hetken. Ledgern är inte sammanhanget, det är ett kontrakt.
Ankar är inte "inriktad text ". De är typed, strukturerade fakta som begränsar generationen:
factory reset → restore factory settingsProductName, ModelNumber, UserIDpolicyVersion: "cfcd-v1", anchorSchemaVersion: 2Poängen är ":". Ankaren är inte ordspråk, de är strukturer. Modelet skriver runt dem.
Detta är en analogi , inte ett biologiskt påstående: poängen är selektiv konsolidation
Hjärnor spelar inte upp hela den sensoriska strömmen igen.
De:
Språk, ,, motorik och perception är alla beroende av begränsade dragning- framåt, inte råtillminning .
CFCD är samma princip
| Biologisk system | |||
|---|---|---|---|
| uppmärksamhet ( vad att lägga märke till | |||
| Konsolidering ( vad man ska komma ihåg) | Ankerförstärkning M(deterministiskt | ||
| Inhibition | |||
| Påminn ( vad man får tag på) | Ledgerquery |
CFMoM och CFCD är samma idé som ses från olika vinklar
| Dimensioner | Pattern | ||
|---|---|---|---|
| Den enda kandidaten | Begränsad otydighet | ||
| Flera förslag | Begränsad Fuzzy MoM | ||
| lång - horisontell kontext | Begränsat Fuzzy Kontext dragning |
Alla tre följer samma regel
sannolikhet föreslår . Determinism förblir kvar
När du internaliserar regeln, slutar den mest mystiska,
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
För att det
Med andra ord, det optimerar för produktionen.
| Anti-Pattern | Probleem | CFCD lösning | |
|---|---|---|---|
| Stuffa allt i ett sammanhang | Ogränsad kostnadM SK1 uppmärksamhetsredduktion | Förstärk bara det som överlever urvalen | |
| Rekursiv sammanfattning | Drift | ||
| Förhoppningsvis kommer modellen ihåg | Inga garantera | Systemet äger uthållighet | |
| Per request full re-processing | Storskalar med historia | Ledger förblir vid requester | |
| Naturspråk "memory" | Semantisk drift | ||
| Ett-storlek | Modell för avfallskapacitet eller svält | Adaptiv skikt från klassificerad samling |
Mostlylucid.Ephemeral är substratet som gör CFCD praktiskt.
| Ephemeral Primitive | |
|---|---|
| Signaler | Kandidell dragkraft (modell föreslår |
| Avgränsade fönster | Inget gränslöst "memory" |
| Eviktionsregler | Att glömma är explicitt |
| Sliding utgång | Stale-kontexten försvinner automatiskt |
| Signalförökning | Anker förflyttar sig framåt utan mutationer |
Öfmeric inte " minns ". Det bestämmer vad som är tillåtet att komma ihåg, och hur länge.
Det är precis vad CFCD behöver.
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");
}
}
Att sammanföra det till en komplett dokumentöversättning
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);
}
}
Det misstag som de flesta AI-system gör är att anta att intelligens förbättras genom att komma ihåg mer.
I praktiken skalar intelligensen genom att bestämma vad att aldrig tänka på det igen.
CFCD är hur du gör det utan att ljuga åt dig själv.
| del | mönster ♫ ♫ | ♫ Axel ♫ |
|---|---|---|
| 1 | Begränsad otydighet | Enkel komponent |
| 2 | Begränsad Fuzzy MoM | Flera komponenter |
| ♫ 3 ♫ ♫ МSK2 ♫ Begränsat Fuzzy Kontext Dragging ♫ | ||
| 4 | Image Summarizer | Praktisk implementation |
Alla tre mönster har samma invariant sannolikhetskomponenter föreslår ; deterministiska system förblir kvar.
Den De tio budorden som LLM använder kodifiera dessa regler. DiSE-arkitekturen implementerar dem för kodentwicklungen. Bot-detektor implementerar dem för kravklassificering. DocSummarizer implementerar dem för att hitta dokument ImageSummarizer implementerar dem för bildanalys
Skillnade domener . Samma mönster. Samme regel. DoomSummarizer implementerar dragging av kontext för parallella långa-formdokument generering - körda sammanfattningar , negativa instruktioner M SK3 enhetens kontinuitet , och driftdetektorn upprätthåller en jämlikhet över samtida LLM sändningar
Del 4 finns nu: Image Summarizer : En begränsad Fuzzy Image RAG Engine. Den implementerar alla tre mönster i en våg -based image analysis pipeline github.com/scottgalM SK2lucidrag.
© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.