Skip to main content

What is a Trace?

A trace is a single turn in a conversation — one user input paired with one AI output. It belongs to a session and can optionally include metadata like latency, token usage, cost, and retrieval context (for RAG evaluations). You can create traces from the Galtea dashboard (using Endpoint Connections) or programmatically using the Galtea SDK.
This entity was called Inference Result before SDK 5.0.0, and galtea.traces used to mean what is now a Span. See Dataset, Trace, and Span Renames for what to change in your code.
Two things are called “trace” here. A Galtea Trace is the turn described on this page, and its own id is id. An OpenTelemetry trace is a distributed-tracing correlation id, the API field traceId. The OpenTelemetry Trace ID property below holds that one, not the id of this Trace. The dashboard uses the same two names: “Galtea Trace ID” for this turn’s id and “OpenTelemetry Trace ID” for the correlation id.

SDK Integration

Trace Service SDK

Manage traces using the Python SDK

Trace Properties

Session
required
The session to which the trace belongs.
string | object
The input text or prompt for the trace. For most runs this is a plain string. For phone (voice) runs, when the simulated user’s audio was captured, this is a content-parts envelope {"user_message": "<transcript>", "content": [{"type": "audio", "uri": "...", "transcript": "..."}]} — the user_message field is the canonical scored scalar. Evaluations score the user_message together with any other key you add beside content. When user_message is empty, the audio transcript takes its place. A {"type": "text"} part in content, the shape OpenAI-style messages use, is scored as text after user_message, unless it repeats it. The judge cannot hear a turn whose audio has no transcript and no user_message, so a metric that reads the input is skipped when no turn of the session has text. Access the envelope via the SDK’s .input_data field and the spoken transcript via .input. A document turn adds file parts to content, which the Input Files field below lists.
AttachedFile[]
The files attached to the input. They come from the test case, or from input_file_paths on a trace you log yourself with Create Trace, Update Trace or Create and Evaluate Trace. Galtea stores each file without its upload signature. Read them with the SDK’s .input_files field, which returns one AttachedFile per attached file, ready for galtea.storage.download() or galtea.storage.read(), except a file part of your own. An agent callback receives the same objects as input_data.input_files.One input accepts at most 20 Galtea files, 20 MB in total, of the same types a test case input accepts. Galtea refuses a Galtea file that breaks a rule, and stores every other element of the content list as sent. See Content Parts.
A metric scores a file only when its judge model reads that kind of file. Only a Galtea file, one you uploaded to Galtea, is sent to a judge. A file on your own host is stored as sent and never reaches a judge, so it never skips an evaluation: the judge reads the text beside it. The kinds a judge reads depend on its model, and the model picker of the metric form shows them for each model. A judge is sent PNG, JPEG, WebP, GIF and PDF files only. The other accepted types are stored, and a Galtea input file of those types still reaches your endpoint, but no judge reads them. The rule is the same for the input and the output, and a metric that reads conversation_turns reads both sides of every turn.Before an evaluation runs, Galtea checks every Galtea file on each side the metric reads. One file the judge would not read skips the evaluation, whatever text sits beside it. A skipped evaluation costs no credits, and its reason names the file, its turn and what refused it:
  • The judge model cannot read that kind of file.
  • The model catalog does not say whether the judge model reads it.
  • The metric names no judge model.
  • The metric is DeepEval-based: those judges are sent text only.
  • The metric is deterministic: it compares text without a model.
  • The metric is a classifier metric: it is sent text only.
  • The file is a type no judge reads, such as DOCX, CSV or TIFF, or an audio file: a judge reads audio only through its transcript.
When the evaluator then reads a Galtea file to send it, it skips the evaluation if the file no longer exists in storage, is empty, or is larger than the 20 MB a judge can receive. The reason names the file.Audio input with no transcript is a separate case. A metric that reads the input is skipped when no turn of the session has input text or a Galtea input file, and a turn’s audio carries no transcript. Text or a Galtea file on another turn is enough, and the reason, Evaluators read an audio input through its transcript, and no turn carries one., names no file.Human evaluation and self-hosted metrics are never skipped for a file or for audio. On deployments that do not send files to the judge, the evaluator also skips a metric whose judge would read the file, and the reason names the file.To have the content scored, pick a metric whose judge model reads that kind of file, or log the text your pipeline extracted as the turn input or output, without the file. See Troubleshooting skipped evaluations.
AttachedFile used to be called InputFile, back when only an input could carry files. The same four fields now describe a file on either side. InputFile still works as a name for it, so code you already wrote keeps running, but it now warns with a GalteaDeprecationWarning. Switch to AttachedFile when you next touch that code.
string | object
The generated output or response for the trace. For most runs this is a plain string.It becomes a content-parts envelope, {"assistant_message": "<text>", "content": [...]}, when the turn answers with more than text. The content list holds one part per attachment: an audio part for a phone (voice) run whose agent audio was captured, or a file part for a product whose answer is a document. The assistant_message field is the canonical scored scalar. Evaluations score it together with any other key you add beside content, and with the text of any {"type": "text"} part.A document answer may carry no assistant_message at all, because the file is the whole answer. The SDK’s .actual_output is then None, unless a {"type": "text"} part carries text. Read the envelope through .actual_output_data in every case, and the output text through .actual_output.
AttachedFile[]
The files the turn answered with, for a product whose reply is a document: a generated report, a filled form, a redacted contract. Read them with the SDK’s .actual_output_files field, which returns one AttachedFile per attached file, ready for galtea.storage.download() or galtea.storage.read(), except a file part of your own.Attach them by naming local paths in output_file_paths on Create Trace, Update Trace or Create and Evaluate Trace. An agent callback answers with files through AgentResponse.output_file_paths. To reuse one upload across turns, call galtea.traces.upload_output_file() and build the envelope yourself.On a run Galtea makes through an endpoint connection, the files come from the response instead: the connection’s output_files key names them, and Galtea stores a copy of each, or links a file already in Galtea. See Files in the Response.One output accepts at most 20 Galtea files, 20 MB in total, of the same types an input accepts. Galtea refuses a Galtea file that breaks a rule, and stores every other element of the content list as sent. See Content Parts.Output files follow the same rule as Input Files: a metric scores a file only when its judge model reads that kind of file.
Retrieval context is not a stored field on the trace. It is derived from the trace’s RETRIEVER spans. You can still supply retrieval_context when logging (on create, update, or an agent response); Galtea records it as a RETRIEVER span.If your agent already emits spans, we recommend sending RETRIEVER spans directly instead. This keeps one source of truth and lets you capture several retrieval steps per turn, which a single retrieval_context value cannot.
float
The latency in milliseconds for the model’s response. null for a user without the evaluation.readInference permission.
dict
Token usage information for the trace. The token counts are null for a user without the evaluation.readInference permission.
dict
Cost information for the trace. The cost values and creditsUsed are null for a user without the evaluation.readInference permission. See Roles and permissions.
int
How many spans sent with this trace were not stored. Empty when none were. A span is dropped when its data is invalid, for example an empty name or a negative latency, and each drop adds to this count as more spans arrive. An unrecognized span type never causes a drop; Galtea normalizes it instead. The dashboard shows the count on the trace so you do not have to read a log to learn a span is missing.
string
The W3C trace ID that Galtea sends to your endpoint in the traceparent header on this Direct Inference turn. Galtea stores it when the turn starts. This is the OpenTelemetry trace id, not the id of this Trace, which is id. It lets you correlate the turn with your OTEL-instrumented service. Present on every conversation turn that Galtea generates through an HTTP endpoint connection (Direct Inference), including turns that failed. Phone and WebRTC turns do not have it.

Concepts overview

How Galtea’s concepts connect — diagram + per-entity quick reference.

Session

The conversation that groups traces together.

Evaluation

Score traces using metrics.

Span

Capture internal operations linked to traces.