返回 DeepSeek-Reasonix
phasetrace.go
根目录 / cmd / e2ebench / phasetrace.go
1 package main
2
3 // phaseTrace is the per-task privacy-safe latency trace: only counts and
4 // milliseconds, no prompts, arguments, or outputs. It stitches the harness
5 // clock (total, solved, tokens) to the trajectory digest's phase buckets.
6 type phaseTrace struct {
7 TotalMs int64 `json:"total_ms"`
8 TTFTMs int64 `json:"ttft_ms,omitempty"`
9 TimeToFirstTool int64 `json:"time_to_first_tool_ms,omitempty"`
10
11 Planner phaseModel `json:"planner"`
12 Executor phaseModel `json:"executor"`
13 Tool phaseTool `json:"tool"`
14 // Recovery counts extra requests forced by provider flakiness (stream and
15 // header retries, missing-reasoning replays, empty-final retries); Ms is
16 // the model-gap time of the rounds those events tainted.
17 Recovery phaseModel `json:"recovery"`
18
19 CompactionMs int64 `json:"compaction_ms,omitempty"`
20 // NoProgressSignals counts progress-guard escalations (each threshold
21 // fires once), not raw zero-evidence-gain rounds.
22 NoProgressSignals int `json:"no_progress_signals,omitempty"`
23 // Rounds is the outcome ledger: total classified rounds, how many bought
24 // progress, the wasted gap total, and the per-outcome composition.
25 Rounds phaseRounds `json:"rounds"`
26
27 PromptTokens int `json:"prompt_tokens"`
28 CompletionTokens int `json:"completion_tokens"`
29 Solved bool `json:"solved"`
30 }
31
32 type phaseModel struct {
33 Requests int `json:"requests"`
34 Ms int64 `json:"ms"`
35 }
36
37 type phaseTool struct {
38 Calls int `json:"calls"`
39 QueueMs int64 `json:"queue_ms"`
40 CriticalPathMs int64 `json:"critical_path_ms"`
41 }
42
43 type phaseRounds struct {
44 Total int `json:"total"`
45 Useful int `json:"useful"`
46 WastedMs int64 `json:"wasted_ms"`
47 Outcomes map[string]int `json:"outcomes,omitempty"`
48 MsByKind map[string]int64 `json:"ms_by_outcome,omitempty"`
49 }
50
51 func classifiedRounds(outcomes map[string]int) int {
52 total := 0
53 for _, n := range outcomes {
54 total += n
55 }
56 return total
57 }
58
59 // buildPhaseTrace derives the trace from a graded result; nil without a
60 // recorded trajectory (the digest carries every phase input).
61 func buildPhaseTrace(r result) *phaseTrace {
62 t := r.Trajectory
63 if t == nil {
64 return nil
65 }
66 return &phaseTrace{
67 TotalMs: r.WallMs,
68 TTFTMs: t.TTFTMs,
69 TimeToFirstTool: t.FirstToolMs,
70 Planner: phaseModel{Requests: t.PlannerRequests, Ms: t.PlannerStreamMs},
71 Executor: phaseModel{Requests: t.ExecutorRequests, Ms: t.ModelStreamMs},
72 Tool: phaseTool{
73 Calls: t.TopLevelCalls,
74 QueueMs: t.ToolQueueMs,
75 CriticalPathMs: t.toolWall(),
76 },
77 Recovery: phaseModel{
78 Requests: t.StreamRetries + t.HeaderRetries + t.ReasoningReplays + t.EmptyFinalRetries,
79 Ms: t.RecoveryGapMs,
80 },
81 CompactionMs: t.CompactionMs,
82 NoProgressSignals: t.NoProgressSignals,
83 Rounds: phaseRounds{
84 Total: classifiedRounds(t.RoundOutcomes),
85 Useful: t.UsefulRounds,
86 WastedMs: t.WastedGapMs,
87 Outcomes: t.RoundOutcomes,
88 MsByKind: t.RoundOutcomeMs,
89 },
90 PromptTokens: r.PromptTokens,
91 CompletionTokens: r.CompletionTokens,
92 Solved: r.Passed,
93 }
94 }
95
95 lines GO