> ## Documentation Index
> Fetch the complete documentation index at: https://platform.atlan.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Add scores

> Attach numeric, categorical, and boolean evaluation results to a trace or a single span.

A score records how well a run went. Attaching it through the SDK puts quality
next to latency and cost on the same trace, so you can query all three
together instead of joining an external evaluation store.

## Score a trace or a span

`score_trace` / `scoreTrace` attaches the score to the trace's root span. Use
it for a judgement about the whole run.

`score` attaches to the span you call it on. Use it when the judgement is about
one step — a retrieval's precision, a single tool call's correctness.

<CodeGroup>
  ```python Python theme={null}
  with client.start_as_current_span("review-pr", as_type="task") as root:
      with client.start_as_current_span("retrieve", as_type="tool") as retrieval:
          retrieval.score("precision", value=0.8)  # about this step

      root.score_trace("review_score", value=0.87)  # about the whole run
  ```

  ```typescript TypeScript theme={null}
  await client.startAsCurrentSpan("review-pr", { asType: "task" }, async (root) => {
    await client.startAsCurrentSpan("retrieve", { asType: "tool" }, async (retrieval) => {
      retrieval.score("precision", 0.8); // about this step
    });

    root.scoreTrace("review_score", 0.87); // about the whole run
  });
  ```
</CodeGroup>

`score_trace` targets the root span only when the SDK opened that root in the
current context. Otherwise it falls back to the span it was called on, so the
score is never silently dropped.

## The three data types

| Data type           | Requires                       | Stored value                                      |
| ------------------- | ------------------------------ | ------------------------------------------------- |
| `NUMERIC` (default) | a numeric `value`              | the number as given                               |
| `CATEGORICAL`       | `string_value` / `stringValue` | the label, with numeric `0.0` unless you pass one |
| `BOOLEAN`           | a truthy or falsy `value`      | `1.0` or `0.0`                                    |

<CodeGroup>
  ```python Python theme={null}
  root.score_trace("review_score", value=0.87)
  root.score_trace("review_decision", data_type="CATEGORICAL", string_value="approve")
  root.score_trace("blocking_present", value=False, data_type="BOOLEAN")
  ```

  ```typescript TypeScript theme={null}
  root.scoreTrace("review_score", 0.87);
  root.scoreTrace("review_decision", undefined, {
    dataType: "CATEGORICAL",
    stringValue: "approve",
  });
  root.scoreTrace("blocking_present", false, { dataType: "BOOLEAN" });
  ```
</CodeGroup>

Pass `comment` on any score to record why the value was assigned.

## Invalid scores are dropped, not raised

Scoring never breaks the run. A score is dropped with a warning when the name
is empty or not a string, the data type is unrecognized, a `NUMERIC` value is
not numeric, a `CATEGORICAL` score has no `string_value`, or a `BOOLEAN` score
has no value at all.

That means a typo in a data type produces a missing score rather than an
exception. If a score you expect is absent, enable `ATLAN_DEBUG=true` and check
the warnings.

## How a score is stored

Each score writes two things to the span:

* an `atlan.score` span event carrying the name, numeric value, data type, and
  the optional string value and comment
* a rollup attribute `atlan.score.{name}` holding the numeric value

The rollup attribute is what makes scores queryable from the Gateway's trace
statistics without expanding every event. Use a stable, lowercase name with
underscores so the attribute stays consistent across runs.

## Next steps

<CardGroup cols={2}>
  <Card title="Trace your agent" icon="diagram-project" href="/sdk/tracing">
    Spans, observation types, usage and cost.
  </Card>

  <Card title="Reporting" icon="chart-line" href="/objects/reporting">
    Where scores surface alongside cost and latency.
  </Card>
</CardGroup>
