Skip to content

feat(traces): compare two AgentCore traces from the CLI#1831

Open
OrenAshkenazy wants to merge 10 commits into
aws:mainfrom
OrenAshkenazy:feat/traces-compare
Open

feat(traces): compare two AgentCore traces from the CLI#1831
OrenAshkenazy wants to merge 10 commits into
aws:mainfrom
OrenAshkenazy:feat/traces-compare

Conversation

@OrenAshkenazy

Copy link
Copy Markdown

Summary

Problem

AgentCore traces can contain runtime, model, and tool spans across the shared
aws/spans log group and endpoint-specific application log groups. CloudWatch
does not currently provide a practical way to compare two invocations side by side, and its
trace view may show the invocation as one span containing many events.

Diagnosing a latency regression therefore requires manually exporting both
traces, correlating endpoint log groups, de-duplicating spans, and calculating
latency and token differences.

Solution

Adds agentcore traces compare to compare two AgentCore runtime traces using CloudWatch telemetry.

The command reports:

  • End-to-end duration
  • LLM time and call count
  • Tool time and call count
  • Input, output, and total tokens
  • Absolute and percentage deltas
  • Comparability warnings
  • Human-readable and JSON output

It supports traces from named runtime endpoints and validates the selected runtime.

Example

agentcore traces compare 6a650d4d5967b68b44a9ac2f71c20cf0 6a650d27066bdda15a10a0991e47b730
Trace comparison: baseline 6a650d4d5967b68b44a9ac2f71c20cf0 → candidate 6a650d27066bdda15a10a0991e47b730

Metric                      Baseline     Candidate                   Delta
End-to-end latency             6.33s         5.70s         -0.63s (-10.0%)
LLM latency                    3.67s         2.85s         -0.82s (-22.4%)
Tool latency                   2.58s         2.77s          +0.19s (+7.3%)
LLM calls                          2             2                0 (0.0%)
Tool calls                         1             1                0 (0.0%)
Input tokens                   2,848         2,829             -19 (-0.7%)
Output tokens                    300           248            -52 (-17.3%)
Total tokens                   3,148         3,077             -71 (-2.3%)

Baseline model(s): us.anthropic.claude-haiku-4-5-20251001-v1:0
Candidate model(s): us.anthropic.claude-haiku-4-5-20251001-v1:0


agentcore traces compare \
  --agent githubagent \
  --baseline-trace-id <baseline-trace-id> \
  --candidate-trace-id <candidate-trace-id> \
  --json | jq .

{
"success": true,
"agentName": "githubagent",
"targetName": "default",
"consoleUrl": "https://us-east-1.console.aws.amazon.com/cloudwatch/home?region=us-east-1#/gen-ai-observability/agent-core/agent-alias/alias/endpoint/DEFAULT/agent/githubagent?start=-43200000&resourceId=arn%3Aaws%3Abedrock-agentcore%3Aus-east-1%3A801945369277%3Aruntime%2FRuntime-f0DXUN7T-is%2Fruntime-endpoint%2FDEFAULT%3ADEFAULT&serviceName=service.DEFAULT&tabId=traces",
"baseline": {
  "traceId": "6a650d4d5967b68b44a9ac2f71c20cf0",
  "spanCount": 12,
  "endToEndMs": 6334.9,
  "timingSource": "invocation-span",
  "llmMs": 3671.3,
  "llmCalls": 2,
  "toolMs": 2578.3,
  "toolCalls": 1,
  "inputTokens": 2848,
  "outputTokens": 300,
  "totalTokens": 3148,
  "models": [
    "us.anthropic.claude-haiku-4-5-20251001-v1:0"
  ]
},
"candidate": {
  "traceId": "6a650d27066bdda15a10a0991e47b730",
  "spanCount": 12,
  "endToEndMs": 5701.9,
  "timingSource": "invocation-span",
  "llmMs": 2847.1,
  "llmCalls": 2,
  "toolMs": 2766.3,
  "toolCalls": 1,
  "inputTokens": 2829,
  "outputTokens": 248,
  "totalTokens": 3077,
  "models": [
    "us.anthropic.claude-haiku-4-5-20251001-v1:0"
  ]
},
"deltas": {
  "endToEndMs": {
    "baseline": 6334.9,
    "candidate": 5701.9,
    "delta": -633,
    "deltaPercent": -10
  },
  "llmMs": {
    "baseline": 3671.3,
    "candidate": 2847.1,
    "delta": -824.2,
    "deltaPercent": -22.4
  },
  "toolMs": {
    "baseline": 2578.3,
    "candidate": 2766.3,
    "delta": 188,
    "deltaPercent": 7.3
  },
  "llmCalls": {
    "baseline": 2,
    "candidate": 2,
    "delta": 0,
    "deltaPercent": 0
  },
  "toolCalls": {
    "baseline": 1,
    "candidate": 1,
    "delta": 0,
    "deltaPercent": 0
  },
  "inputTokens": {
    "baseline": 2848,
    "candidate": 2829,
    "delta": -19,
    "deltaPercent": -0.7
  },
  "outputTokens": {
    "baseline": 300,
    "candidate": 248,
    "delta": -52,
    "deltaPercent": -17.3
  },
  "totalTokens": {
    "baseline": 3148,
    "candidate": 3077,
    "delta": -71,
    "deltaPercent": -2.3
  }
},
"warnings": []
}
  

## Validation

- [v] Lint passes
- [v] Tested against DEFAULT and named runtime endpoints
Closes #1830

…pare

Fetch application spans from the endpoint-specific runtime log group,
detected per trace via aws.endpoint.name; validate trace ownership against
the runtime resource ID; report missing application spans as unavailable
rather than zero; de-duplicate token fields independently; extend
comparability warnings to all token fields and zero-baseline changes.
Classify tool/LLM spans via traceloop.span.kind (LangGraph) and
openinference.span.kind in addition to GenAI attributes, with a .tool
name-suffix fallback; scope ownership validation, endpoint detection, and
metrics to spans matching the runtime via aws.agent.id/cloud.resource_id
so distributed traces with multiple runtimes are handled correctly; merge
duplicate span records field by field, preferring defined runtime-log
values.
Nanosecond-to-ms conversion leaked sub-microsecond floats and
float-arithmetic noise into the --json contract, so two otherwise-equal
runs could diff in CI. Round latency (ms) and percentage fields to one
decimal at the output boundary; token and call-count fields stay integers.
Query gen_ai.request.model / gen_ai.response.model and report the distinct
set of models used in each trace (preferring the response model). Surface
them in the table and JSON, and warn when baseline and candidate used
different models — a strong signal the traces are not directly comparable.
@OrenAshkenazy
OrenAshkenazy requested a review from a team July 26, 2026 07:04
@github-actions github-actions Bot added the size/xl PR size: XL label Jul 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/xl PR size: XL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant