Documentation
¶
Overview ¶
@index Match analysis helpers for benchmark run results.
@index Comparison helpers for benchmark runs with and without CCG.
@index Benchmark corpus loading, saving, and validation utilities.
@index JSONL session parsing and extraction helpers for benchmark analysis.
@index Markdown report generation for benchmark comparisons.
@index Benchmark runner orchestration for Claude CLI subprocess execution.
Package benchmark provides types and utilities for benchmarking ccg MCP tool effectiveness.
@index Token baseline and graph-assisted retrieval benchmarking helpers.
Index ¶
- Constants
- func BuildClaudeArgs(cfg RunnerConfig) []string
- func BuildPrompt(q Query) string
- func CountCcgToolCalls(result RunResult) int
- func EstimateTokens(text string) int
- func ExtractAnswer(seg QuerySegment) string
- func ExtractFilesRead(seg QuerySegment) []string
- func ExtractTokens(seg QuerySegment) (inputTokens, outputTokens int)
- func GraphTokens(ctx context.Context, db *gorm.DB, backend SearchBackend, expander NodeExpander, ...) (tokens int, elapsedMs int64, count int, err error)
- func MatchFiles(result RunResult, query Query) float64
- func MatchSymbols(result RunResult, query Query) float64
- func NaiveTokens(repoRoot string, exts []string) (int, error)
- func NaiveTokensWithOptions(repoRoot string, exts []string, opts NaiveTokensOptions) (int, error)
- func SaveCorpus(path string, c *Corpus) error
- func ValidateCorpus(c *Corpus) error
- func WriteReport(report *ComparisonReport, outPath string) error
- type BenchmarkRun
- type ComparisonReport
- type ContentBlock
- type Corpus
- type Executor
- type MatchResult
- type MessagePayload
- type NaiveTokensOptions
- type NodeExpander
- type Query
- type QuerySegment
- type RunResult
- type RunTokenBenchOptions
- type Runner
- type RunnerConfig
- type SearchBackend
- type SessionMessage
- type TokenBenchResult
- type ToolCall
- type UsageInfo
Constants ¶
const DefaultNaiveTokensMaxFileBytes int64 = 1 << 20
DefaultNaiveTokensMaxFileBytes caps per-file size considered by the naive baseline. @intent prevent oversized files from skewing or dominating the naive token baseline.
Variables ¶
This section is empty.
Functions ¶
func BuildClaudeArgs ¶
func BuildClaudeArgs(cfg RunnerConfig) []string
BuildClaudeArgs constructs the CLI argument slice for `claude -p`. Working directory is set on the subprocess directly (not via --cwd flag). In "without-ccg" mode, --strict-mcp-config disables all MCP servers. NOTE: For actual runs, use Runner.Run which creates a real temp file for --mcp-config. @intent expose deterministic argument construction for tests and tooling that inspect benchmark invocation behavior.
func BuildPrompt ¶
BuildPrompt creates the prompt string that wraps a query with benchmark markers. The markers allow the JSONL analyzer to locate query boundaries. @intent surround benchmark queries with markers so later session analysis can recover exact query segments.
func CountCcgToolCalls ¶
CountCcgToolCalls returns the number of tool calls using mcp__ccg__ prefix. @intent quantify how much a benchmark run relied on CCG-specific MCP tools.
func EstimateTokens ¶
EstimateTokens는 텍스트의 대략적인 토큰 수를 반환한다 (4자 = 1토큰). @intent provide a cheap, consistent token estimate for baseline-versus-graph comparisons.
func ExtractAnswer ¶
func ExtractAnswer(seg QuerySegment) string
ExtractAnswer returns the text of the last assistant text block in the segment. @intent capture the final assistant answer that should be evaluated for symbol hits.
func ExtractFilesRead ¶
func ExtractFilesRead(seg QuerySegment) []string
ExtractFilesRead returns deduplicated file paths from Read tool calls in the segment. @intent estimate file-inspection behavior from tool-use records without double-counting reads.
func ExtractTokens ¶
func ExtractTokens(seg QuerySegment) (inputTokens, outputTokens int)
ExtractTokens sums input and output token counts across all messages in a segment. @intent aggregate token usage for the full lifecycle of one benchmark query.
func GraphTokens ¶
func GraphTokens(ctx context.Context, db *gorm.DB, backend SearchBackend, expander NodeExpander, query, repoRoot string, limit int) (tokens int, elapsedMs int64, count int, err error)
GraphTokens는 단일 쿼리로 검색해 토큰 수, 경과 시간(ms), 결과 수를 반환한다. @intent measure the token footprint of graph-assisted retrieval for one query.
func MatchFiles ¶
MatchFiles computes the ratio of expected files found in FilesRead or mentioned in the Answer text (as a fallback when tool-call data is unavailable). Returns 1.0 if no expected files are specified. @intent score whether a benchmark run inspected the files the query was expected to touch.
func MatchSymbols ¶
MatchSymbols computes the ratio of expected symbols found in the answer text. Returns 1.0 if no expected symbols are specified. @intent score whether the final answer mentioned the symbols the query was expected to surface.
func NaiveTokens ¶
NaiveTokens는 repoRoot 아래 exts 확장자를 가진 모든 파일의 토큰 수 합계를 반환한다. @intent measure the naive full-file reading baseline for a repository slice.
func NaiveTokensWithOptions ¶
func NaiveTokensWithOptions(repoRoot string, exts []string, opts NaiveTokensOptions) (int, error)
NaiveTokensWithOptions는 repoRoot 아래 exts 확장자를 가진 파일 중 옵션에 맞는 파일만 집계한다. @intent compute a configurable naive token baseline while skipping excluded or oversized files.
func SaveCorpus ¶
SaveCorpus writes a Corpus to a YAML file. @intent persist benchmark corpus definitions in the YAML format used by the CLI.
func ValidateCorpus ¶
ValidateCorpus checks that all queries have required fields and no duplicate IDs. @intent reject malformed benchmark corpora before any benchmark execution depends on them.
func WriteReport ¶
func WriteReport(report *ComparisonReport, outPath string) error
WriteReport renders a ComparisonReport as markdown and writes it to outPath. @intent turn benchmark comparison data into a readable artifact for sharing and regression tracking.
Types ¶
type BenchmarkRun ¶
type BenchmarkRun struct {
Mode string `json:"mode"`
RunAt time.Time `json:"run_at"`
Results []RunResult `json:"results"`
}
BenchmarkRun holds all results from a single benchmark execution. @intent represent one complete benchmark session for a given execution mode.
func (*BenchmarkRun) ResultByID ¶
func (r *BenchmarkRun) ResultByID(id string) *RunResult
ResultByID returns the RunResult for the given query ID, or nil if not found. @intent support direct lookup of a query result inside a benchmark run.
type ComparisonReport ¶
type ComparisonReport struct {
WithCCG *BenchmarkRun `json:"with_ccg"`
WithoutCCG *BenchmarkRun `json:"without_ccg,omitempty"`
Matches []MatchResult `json:"matches"`
MatchesWithout []MatchResult `json:"matches_without,omitempty"`
}
ComparisonReport holds a comparison between two benchmark runs. @intent package benchmark runs and their scored matches into one comparison artifact.
func Compare ¶
func Compare(withCCG *BenchmarkRun, withoutCCG *BenchmarkRun, corpus *Corpus) *ComparisonReport
Compare builds a ComparisonReport from a with-ccg run and an optional without-ccg run. Matches contains with-ccg metrics; MatchesWithout contains without-ccg metrics when provided. @intent produce one report that captures both benchmark modes and their scored query matches.
type ContentBlock ¶
type ContentBlock struct {
Type string `json:"type"`
Text string `json:"text,omitempty"`
Name string `json:"name,omitempty"` // tool_use
ID string `json:"id,omitempty"`
Input json.RawMessage `json:"input,omitempty"`
}
ContentBlock is a single content item (text, tool_use, etc.). @intent represent individual Claude message blocks so benchmark analyzers can inspect tool calls and text.
type Corpus ¶
type Corpus struct {
Version string `yaml:"version" json:"version,omitempty"`
Queries []Query `yaml:"queries" json:"queries"`
}
Corpus holds the collection of benchmark queries. @intent group benchmark queries into a reusable corpus that can be run and validated together.
func LoadCorpus ¶
LoadCorpus reads a queries.yaml file and validates its contents. @intent load a benchmark corpus from disk while enforcing schema and ID constraints up front.
type Executor ¶
type Executor interface {
Execute(ctx context.Context, args []string, prompt, dir string) ([]byte, error)
}
Executor abstracts the subprocess execution so tests can inject a mock. dir sets the working directory for the subprocess; empty means inherit from parent. @intent decouple benchmark orchestration from the concrete Claude CLI process implementation.
type MatchResult ¶
type MatchResult struct {
QueryID string `json:"query_id"`
FileHitRatio float64 `json:"file_hit_ratio"`
SymbolHitRatio float64 `json:"symbol_hit_ratio"`
StrictSymbolHitRatio float64 `json:"strict_symbol_hit_ratio"`
TentativeSymbolHitRatio float64 `json:"tentative_symbol_hit_ratio"`
LLMStrictBias float64 `json:"llm_strict_bias"`
StrictContaminationRate float64 `json:"strict_contamination_rate"`
ToolAwareStrictRatio float64 `json:"tool_aware_strict_ratio"`
ToolAwareTentativeRatio float64 `json:"tool_aware_tentative_ratio"`
TotalToolCalls int `json:"total_tool_calls"`
CcgToolCalls int `json:"ccg_tool_calls"`
TotalInputTokens int `json:"total_input_tokens"`
}
MatchResult holds the computed match metrics for a single query. @intent summarize scored file, symbol, tool, and token metrics for one benchmark query.
func AnalyzeRun ¶
func AnalyzeRun(run *BenchmarkRun, corpus *Corpus) []MatchResult
AnalyzeRun computes MatchResult for every result in the run against the corpus. Results with no matching query are skipped. @intent turn a full benchmark run into per-query scored matches against the corpus definition.
func ComputeMatch ¶
func ComputeMatch(result RunResult, query Query) MatchResult
ComputeMatch derives a MatchResult from a single RunResult and its Query. @intent consolidate per-query benchmark scoring into one reusable result structure.
type MessagePayload ¶
type MessagePayload struct {
Role string `json:"role"`
Content []ContentBlock `json:"content"`
Usage *UsageInfo `json:"usage,omitempty"`
}
MessagePayload is the nested message object inside a SessionMessage. @intent expose assistant role, content blocks, and usage data from session lines.
type NaiveTokensOptions ¶
NaiveTokensOptions tunes which files contribute to the naive token baseline. @intent control file selection (excludes, size cap) for the naive reading baseline.
type NodeExpander ¶
type NodeExpander interface {
GetEdgesFrom(ctx context.Context, nodeID uint) ([]model.Edge, error)
GetNodesByIDs(ctx context.Context, ids []uint) ([]model.Node, error)
GetAnnotation(ctx context.Context, nodeID uint) (*model.Annotation, error)
}
NodeExpander는 노드의 1-hop 이웃과 어노테이션을 가져오는 추상화다. nil을 전달하면 확장 없이 기본 검색 결과만 사용한다. @intent optionally enrich graph token context with neighbors and annotations beyond raw search hits.
type Query ¶
type Query struct {
ID string `yaml:"id" json:"id"`
Description string `yaml:"description" json:"description"`
ExpectedFiles []string `yaml:"expected_files" json:"expected_files,omitempty"`
ExpectedSymbols []string `yaml:"expected_symbols" json:"expected_symbols,omitempty"`
ExpectedStrictSymbols []string `yaml:"expected_strict_symbols" json:"expected_strict_symbols,omitempty"`
ExpectedTentativeSymbols []string `yaml:"expected_tentative_symbols" json:"expected_tentative_symbols,omitempty"`
Difficulty string `yaml:"difficulty" json:"difficulty,omitempty"`
}
Query represents a single benchmark query with expected results. @intent define one benchmark prompt and the files or symbols it is expected to surface.
type QuerySegment ¶
type QuerySegment struct {
QueryID string
Messages []SessionMessage
}
QuerySegment groups the messages belonging to a single benchmark query. @intent isolate the portion of a session that belongs to one marked benchmark query.
func ExtractQuerySegments ¶
func ExtractQuerySegments(msgs []SessionMessage) ([]QuerySegment, error)
ExtractQuerySegments splits a session's messages into per-query segments using markers. An unclosed segment (START without END) is included, spanning to the last message. @intent reconstruct per-query transcript slices from a whole benchmark session log.
type RunResult ¶
type RunResult struct {
QueryID string `json:"query_id"`
ToolCalls []ToolCall `json:"tool_calls,omitempty"`
FilesRead []string `json:"files_read,omitempty"`
Answer string `json:"answer,omitempty"`
InputTokens int `json:"input_tokens"`
OutputTokens int `json:"output_tokens"`
ElapsedMs int64 `json:"elapsed_ms"`
Error string `json:"error,omitempty"`
}
RunResult captures the outcome of executing a single query. @intent store answer text, tool usage, timing, and token counts for one benchmark query.
func ExtractRunResult ¶
func ExtractRunResult(queryID string, seg QuerySegment) RunResult
ExtractRunResult builds a RunResult from a query segment. @intent convert an extracted query segment into the canonical benchmark run result shape.
type RunTokenBenchOptions ¶
type RunTokenBenchOptions struct {
Naive NaiveTokensOptions
}
RunTokenBenchOptions bundles optional knobs for the token benchmark execution. @intent extend the token benchmark with baseline tuning while keeping the core API stable.
type Runner ¶
type Runner struct {
// contains filtered or unexported fields
}
Runner executes benchmark queries sequentially using the provided Executor. @intent own the end-to-end lifecycle of benchmark query execution for one mode.
func NewRunner ¶
func NewRunner(cfg RunnerConfig, exec Executor) *Runner
NewRunner creates a Runner with the given config and executor. @intent assemble benchmark orchestration from execution config and a subprocess adapter.
type RunnerConfig ¶
type RunnerConfig struct {
Mode string // "with-ccg" | "without-ccg"
CWD string // benchmark workspace directory
MaxToolCalls int
TimeoutSec int
}
RunnerConfig holds configuration for a benchmark run. @intent collect execution mode, workspace, and timeout settings for one benchmark run.
func DefaultRunnerConfig ¶
func DefaultRunnerConfig() RunnerConfig
DefaultRunnerConfig returns a RunnerConfig with sensible defaults. @intent provide conservative benchmark defaults that work for most local runs.
type SearchBackend ¶
type SearchBackend interface {
Query(ctx context.Context, db *gorm.DB, query string, limit int) ([]model.Node, error)
}
SearchBackend는 FTS 검색 백엔드 추상화다. @intent abstract graph search so token benchmarks can run against any configured backend.
type SessionMessage ¶
type SessionMessage struct {
Type string `json:"type"`
Message *MessagePayload `json:"message,omitempty"`
Content json.RawMessage `json:"content,omitempty"`
ToolUseID string `json:"tool_use_id,omitempty"`
IsError bool `json:"is_error,omitempty"`
}
SessionMessage represents one line from a Claude Code session JSONL file. @intent model the subset of Claude session JSONL needed to reconstruct benchmark runs.
func ParseJSONL ¶
func ParseJSONL(path string) ([]SessionMessage, error)
ParseJSONL reads a Claude Code session JSONL file and returns all parsed lines. Lines that are not valid JSON are silently skipped. @intent ingest recorded Claude sessions even when they contain partial or non-JSON noise lines.
type TokenBenchResult ¶
type TokenBenchResult struct {
QueryID string `json:"query_id"`
NaiveTokens int `json:"naive_tokens"`
GraphTokens int `json:"graph_tokens"`
Ratio float64 `json:"ratio"`
SearchElapsedMs int64 `json:"search_elapsed_ms"`
ResultCount int `json:"result_count"`
// Recall: 정답 파일/심볼이 결과에 포함되었는지 측정
FilesHit int `json:"files_hit"`
FilesTotal int `json:"files_total"`
SymbolsHit int `json:"symbols_hit"`
SymbolsTotal int `json:"symbols_total"`
Recall float64 `json:"recall"`
}
TokenBenchResult는 단일 쿼리에 대한 토큰 벤치마크 결과다. @intent report naive-versus-graph token cost and recall for one benchmark query.
func RunTokenBench ¶
func RunTokenBench(ctx context.Context, db *gorm.DB, backend SearchBackend, expander NodeExpander, corpus *Corpus, repoRoot string, exts []string, limit int) ([]TokenBenchResult, error)
RunTokenBench는 corpus의 각 쿼리에 대해 naive/graph 토큰과 recall을 비교한다. 검색은 항상 Description을 사용하며, expected_symbols/files는 정답 매칭에만 사용한다. limit은 쿼리당 총 결과 예산이며 단어 수에 반비례해 단어당 limit이 자동 조정된다. @intent execute the full token benchmark corpus and compare naive reading cost against graph retrieval cost.
func RunTokenBenchWithOptions ¶
func RunTokenBenchWithOptions(ctx context.Context, db *gorm.DB, backend SearchBackend, expander NodeExpander, corpus *Corpus, repoRoot string, exts []string, limit int, opts RunTokenBenchOptions) ([]TokenBenchResult, error)
@intent extend token benchmarking with baseline tuning options while preserving the core execution flow.
type ToolCall ¶
type ToolCall struct {
Tool string `json:"tool"`
ToolUseID string `json:"tool_use_id,omitempty"`
Input string `json:"input,omitempty"`
Output string `json:"output,omitempty"`
}
ToolCall records a single tool invocation during query execution. @intent capture the tool usage footprint of one benchmarked query execution.
func ExtractToolCalls ¶
func ExtractToolCalls(seg QuerySegment) []ToolCall
ExtractToolCalls collects all tool_use blocks from a segment's messages. @intent recover structured tool invocation history for one benchmark query.