Skip to main content

Overview

AgentGateway (v1.1.0 or later, Apache 2.0) is an open-source Rust proxy that sits between your application and its LLM provider. Fiddler integrates with AgentGateway at the proxy layer, giving you full LLM observability — prompts, responses, token usage, latency — without adding any SDK to your application code.

Architecture

AgentGateway exposes an OpenAI-compatible API (/v1/chat/completions). Your application requires no SDK — it just calls the proxy instead of the provider directly.

Prerequisites

  • Fiddler account with a GenAI application already created
  • AgentGateway v1.1.0+ for tracing. If you also plan to add Fiddler guardrails, which require v1.4.0+, start on v1.4.0+ from the outset — a 1.1.0-era gateway silently misroutes the guardrail webhook.
  • A valid LLM provider API key (e.g. OPENAI_API_KEY)
  • Your Fiddler API key (found under organizational settings) and application UUID (found under application settings)

Quick Start

Step 1 — Install AgentGateway

Step 2 — Configure AgentGateway

Create agentgateway_config.yaml:
The frontendPolicies.tracing block captures prompt and response content via CEL expressions and exports spans directly to Fiddler over HTTPS. $FIDDLER_API_KEY and $FIDDLER_APP_ID are expanded from environment variables at runtime — no credentials are hardcoded in the config file.
The binds block above is AgentGateway’s low-level backend API. AgentGateway v1.4.0+ deprecates it in favor of the gateways/routes and llm.models shapes (see AgentGateway’s Migrate from binds guide); it still works, but if you also run Fiddler guardrails — which attach via llm.models[].guardrails — define your model once in the llm.models shape and combine the two, per Combined Tracing and Guardrails.

Step 3 — Start AgentGateway

Step 4 — Point Your Application at AgentGateway

Traces appear in Fiddler automatically — no SDK import, no callback registration, no changes to your application logic. To override the default proxy URL, set AGENTGATEWAY_URL (defaults to http://localhost:4000/v1):

Step 5 — Verify Traces Are Arriving

Open the Fiddler UI and navigate to your application’s Explorer. You should see the trace within a few seconds of making your first completion call.

Span Type Mapping

Fiddler’s AgentGateway mapper enriches spans based on gen_ai.operation.name, which AgentGateway sets automatically: The mapper sets fiddler.span.type = "llm" on LLM spans internally — no CEL config is required for that classification. (The fiddler.span.type: '"llm"' line in the CEL config above is a safety net for deployments that process spans without the dedicated mapper.) Spans the mapper does not enrich are still forwarded, not dropped: an execute_tool span is classified as a tool span by Fiddler’s downstream span-type mapping (the same mapping the Strands and Google ADK integrations use).

Attribute Mapping

AgentGateway emits the OpenTelemetry GenAI inference attributes, and Fiddler’s semantic layer maps them automatically: Only prompt/completion content, conversation.id, and span.type need CEL — everything else is emitted by AgentGateway by default.

Session Grouping

Fiddler groups all LLM calls that share the same gen_ai.conversation.id into a single Session. The recommended pattern is to generate one UUID per logical conversation in your application and pass it on every LLM call as the X-Fiddler-Conversation-Id HTTP header. The CEL expression in the AgentGateway config (see Step 2) extracts the header and stamps it as the span attribute. The header transport is preferred over OpenAI’s metadata request body field because:
  • OpenAI’s metadata parameter requires store=true, which persists conversation data on OpenAI’s side — a privacy concern for many customers.
  • AgentGateway is a passthrough proxy: anything in the request body must be a valid OpenAI parameter or the request fails.
  • Headers are visible to AgentGateway and silently stripped by OpenAI.

MCP Tool Call Tracing

AgentGateway can also proxy MCP (Model Context Protocol) tool servers. With the tracing config below, each MCP tool call is captured in Fiddler as a tool span — with the tool name, input arguments, and result.

Configure an MCP Route

What Gets Captured

The attributes above follow the OpenTelemetry GenAI execute-tool span convention. Each MCP tools/call is recorded as a tool span: AgentGateway additionally emits the MCP-convention fields on the span automatically — mcp.method.name, mcp.session.id, mcp.resource.type, and mcp.target — so no extra CEL is needed for those. Tool calls that share an MCP session are grouped into one Fiddler Session via gen_ai.conversation.id, set here from the MCP session ID (mcp.sessionId).
Fiddler classifies these as tool spans from gen_ai.operation.name = execute_tool — the same downstream classification used for the Strands and Google ADK integrations. Fiddler’s AgentGateway mapper enriches only LLM (chat/completion) spans, so a tool span carries exactly the attributes your CEL config captures above; nothing is added or normalized by the mapper. There is no AgentGateway-specific mapper test for the tool-span path, so re-verify MCP tracing after an AgentGateway or Fiddler upgrade.

Combined Tracing and Guardrails

Tracing and Fiddler guardrails are independent, and both can run from the same AgentGateway config file. AgentGateway’s schema declares frontendPolicies, backends, and llm as siblings and validates a file that combines them, so you add the guardrail webhook alongside the tracing block:
  • Keep the frontendPolicies.tracing block from the Quick Start.
  • Add the fiddler-guardrail backend and the llm.models[].guardrails webhook from the AgentGateway Guardrails quick start.
  • Define your LLM backend once, in the llm.models shape (guardrails attach there), rather than in both binds and llm.models.
This combination is valid against AgentGateway’s v1.4.0 configuration schema. Validate the combined file against your AgentGateway version before production use, and make sure the tracing export and the LLM listener do not both claim port 4000.

Troubleshooting

Traces not appearing in Fiddler Verify all three environment variables are set before starting AgentGateway:
Both application.id (OTel resource attribute) and fiddler-application-id (HTTP header on the export request) are required. If application.id is missing, Fiddler skips those spans, logs a warning, and increments a missing_application_id_failure counter — so check your Fiddler ingestion logs and metrics if traces are absent. Fiddler checks that the attribute is present; it does not validate the UUID’s format at this stage. Prompt and response content not showing The frontendPolicies.tracing.attributes CEL block is required. Verify it is present in agentgateway_config.yaml and that AgentGateway is v1.1.0+:
Span type showing as Unknown service.name: '"agentgateway"' in the resources block is how Fiddler routes AgentGateway spans to its mapper, and setting it is the documented default on every release — rename it and Fiddler no longer recognizes the spans. From 26.17, Fiddler also recognizes the agentgateway instrumentation scope; scope-based routing is evaluated first, so spans route correctly even if a deployment overrides service.name. Within the mapper, the span is then classified from gen_ai.operation.name (set automatically by AgentGateway). Verify service.name: '"agentgateway"' is present, that AgentGateway is v1.1.0+, and that the frontendPolicies.tracing.attributes block is configured. As a fallback, fiddler.span.type: '"llm"' in the attributes block covers deployments that process spans without the dedicated mapper. Not all LLM calls are producing traces randomSampling: true is active. Set it to false to capture every span:

Known Limitations


Next Steps

Upstream-link maintenance. AgentGateway’s latest standalone docs are live-edited and carry no version-pinned URLs (/docs/standalone/1.4.x/ returns 404), so links to agentgateway.dev/docs/standalone/latest/... can silently retarget when a new AgentGateway version ships. Re-verify AgentGateway behavior cited here against your installed version. Official docs: agentgateway.dev.