Stufe 4c (#764): Bezeichner auf Englisch - Typen, Methoden, Felder, Parameter, Locals, Testnamen
Mit Roslyn umbenannt (Verweise folgen, Zeichenketten bleiben unberuehrt). Nicht umbenannt, weil gespeichert oder ueber die API gebunden (Stufe 4e): Properties, Record-Parameter, Enum-Member sowie die Parameter der Endpunkt-Handler (Routen-/Query-Bindung ueber den Namen). Die JSON-Felder anonymer Objekte bleiben ausdruecklich benannt (JsonFilter: pfad). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
837a634a22
commit
77062facc9
@@ -21,7 +21,7 @@ public sealed class ProactiveCompactionTests
|
||||
private const string SummaryModel = "test/summary";
|
||||
|
||||
[Fact]
|
||||
public async Task Keine_Anfrage_geht_ueber_die_Kontextgrenze_hinaus()
|
||||
public async Task No_request_goes_beyond_the_context_limit()
|
||||
{
|
||||
var fixture = new EngineFixture();
|
||||
var agent = fixture.AddAgent("agent-a");
|
||||
@@ -43,24 +43,24 @@ public sealed class ProactiveCompactionTests
|
||||
agent, $"Frage {i}: " + new string('y', 600), "test-instance", default);
|
||||
}
|
||||
|
||||
var anfragenAnDenAgenten = fixture.Client.ReceivedRequests
|
||||
var requestsToAgent = fixture.Client.ReceivedRequests
|
||||
.Where(r => r.Model == AgentModel)
|
||||
.ToList();
|
||||
|
||||
anfragenAnDenAgenten.Count.ShouldBe(20);
|
||||
requestsToAgent.Count.ShouldBe(20);
|
||||
|
||||
// The actual point: not "at some point it was truncated", but "nothing overfull ever
|
||||
// went out". Previously the check hung on the promptTokens of the
|
||||
// answer — always 100 with the fake —, so it never got over the threshold and never truncated.
|
||||
foreach (var anfrage in anfragenAnDenAgenten)
|
||||
foreach (var request in requestsToAgent)
|
||||
{
|
||||
ContextCompactor.EstimateTokens(anfrage.Messages)
|
||||
ContextCompactor.EstimateTokens(request.Messages)
|
||||
.ShouldBeLessThan(agent.LoopGuard.MaxContextTokens);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Gekuerzt_wird_mit_dem_guenstigen_Modell_bevor_gesendet_wird()
|
||||
public async Task Shortening_uses_the_cheap_model_before_sending()
|
||||
{
|
||||
var fixture = new EngineFixture();
|
||||
var agent = fixture.AddAgent("agent-a");
|
||||
@@ -85,86 +85,86 @@ public sealed class ProactiveCompactionTests
|
||||
// Calibration
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
|
||||
private static ContextCompactor NeuerKompaktierer()
|
||||
private static ContextCompactor NewCompactor()
|
||||
=> new(new FakeChatClient(), TestLogging.Factory);
|
||||
|
||||
[Fact]
|
||||
public void Ohne_Messwerte_gilt_die_rohe_Schaetzung()
|
||||
public void Without_measurements_the_raw_estimate_applies()
|
||||
{
|
||||
var messages = Conversation.Start().Repeat(4).Build();
|
||||
|
||||
NeuerKompaktierer().EstimateFor("m", messages)
|
||||
NewCompactor().EstimateFor("m", messages)
|
||||
.ShouldBe(ContextCompactor.EstimateTokens(messages));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Eine_unterschaetzte_Anfrage_hebt_die_Schaetzung_an()
|
||||
public void An_underestimated_request_raises_the_estimate()
|
||||
{
|
||||
var messages = Conversation.Start().Repeat(4).Build();
|
||||
var roh = ContextCompactor.EstimateTokens(messages);
|
||||
var raw = ContextCompactor.EstimateTokens(messages);
|
||||
|
||||
var compactor = NeuerKompaktierer();
|
||||
var compactor = NewCompactor();
|
||||
|
||||
// The API consistently charges twice as much as estimated.
|
||||
for (var i = 0; i < 20; i++)
|
||||
compactor.Calibrate("m", 1_000, 2_000);
|
||||
|
||||
compactor.EstimateFor("m", messages).ShouldBeGreaterThan(roh);
|
||||
compactor.EstimateFor("m", messages).ShouldBeGreaterThan(raw);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Ein_einzelner_Ausreisser_kippt_die_Schwelle_nicht()
|
||||
public void A_single_outlier_does_not_tip_the_threshold()
|
||||
{
|
||||
var messages = Conversation.Start().Repeat(4).Build();
|
||||
var roh = ContextCompactor.EstimateTokens(messages);
|
||||
var raw = ContextCompactor.EstimateTokens(messages);
|
||||
|
||||
var compactor = NeuerKompaktierer();
|
||||
var compactor = NewCompactor();
|
||||
compactor.Calibrate("m", 1_000, 4_000); // far off once
|
||||
|
||||
// A measurement only shifts the factor by its weight, not to its value.
|
||||
compactor.EstimateFor("m", messages).ShouldBeLessThan(roh * 2);
|
||||
compactor.EstimateFor("m", messages).ShouldBeLessThan(raw * 2);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Ein_absurder_Messwert_wird_gedeckelt()
|
||||
public void An_absurd_measurement_is_capped()
|
||||
{
|
||||
var messages = Conversation.Start().Repeat(4).Build();
|
||||
var roh = ContextCompactor.EstimateTokens(messages);
|
||||
var raw = ContextCompactor.EstimateTokens(messages);
|
||||
|
||||
var compactor = NeuerKompaktierer();
|
||||
var compactor = NewCompactor();
|
||||
for (var i = 0; i < 50; i++)
|
||||
compactor.Calibrate("m", 1, 1_000_000);
|
||||
|
||||
// At most four times — anything above that is no longer a calibration case.
|
||||
compactor.EstimateFor("m", messages).ShouldBeLessThanOrEqualTo(roh * 4);
|
||||
compactor.EstimateFor("m", messages).ShouldBeLessThanOrEqualTo(raw * 4);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Jedes_Modell_wird_fuer_sich_kalibriert()
|
||||
public void Every_model_is_calibrated_on_its_own()
|
||||
{
|
||||
// Different tokenizers split the same text differently — a common
|
||||
// factor would be the average of things that have nothing to do with each other.
|
||||
var messages = Conversation.Start().Repeat(4).Build();
|
||||
var roh = ContextCompactor.EstimateTokens(messages);
|
||||
var raw = ContextCompactor.EstimateTokens(messages);
|
||||
|
||||
var compactor = NeuerKompaktierer();
|
||||
var compactor = NewCompactor();
|
||||
for (var i = 0; i < 20; i++)
|
||||
compactor.Calibrate("gross", 1_000, 3_000);
|
||||
|
||||
compactor.EstimateFor("gross", messages).ShouldBeGreaterThan(roh);
|
||||
compactor.EstimateFor("unberuehrt", messages).ShouldBe(roh);
|
||||
compactor.EstimateFor("gross", messages).ShouldBeGreaterThan(raw);
|
||||
compactor.EstimateFor("unberuehrt", messages).ShouldBe(raw);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Unbrauchbare_Messwerte_werden_verworfen()
|
||||
public void Unusable_measurements_are_discarded()
|
||||
{
|
||||
var messages = Conversation.Start().Repeat(4).Build();
|
||||
var roh = ContextCompactor.EstimateTokens(messages);
|
||||
var raw = ContextCompactor.EstimateTokens(messages);
|
||||
|
||||
var compactor = NeuerKompaktierer();
|
||||
var compactor = NewCompactor();
|
||||
compactor.Calibrate("m", 0, 5_000); // without an estimate no ratio
|
||||
compactor.Calibrate("m", 1_000, 0); // without a measurement neither
|
||||
|
||||
compactor.EstimateFor("m", messages).ShouldBe(roh);
|
||||
compactor.EstimateFor("m", messages).ShouldBe(raw);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user