Overview

Tags are string identifiers that you can attach to spans. They are used to categorize and filter spans.

You can either add tags to a span when it is created, or post-hoc after a span has been created.

1. Adding tags to a span when it is created

Sometimes you have some context prior to running a function and you want to tag it at creation time. For example, you may want to tag a span with the model provider endpoint that you use, or the test dataset that you used to run the request.

Note that tags are not the same as metadata. Metadata is additional information about a trace in a form of key-value pairs. Tags are used to categorize and filter spans, and they must be created in the Laminar UI in advance. See metadata for a more detailed comparison.

Example. Tagging a manual span

This is a dynamic way to tag a span, i.e. you can create tags at runtime.

import { Laminar } from '@lmnr-ai/lmnr';

const span = Laminar.startSpan('foo', { tags: ["my_tag", "another_tag"] });
// elsewhere
Laminar.withSpan(span, () => {
    // your code here
})

Note that only the span created by this Laminar.startSpan call will have the tags.

Example. Tagging an observed function

This is a static way to tag a span, i.e. the observed function will always have the same set of tags.

import { Laminar, observe } from '@lmnr-ai/lmnr';

await observe(
  {
    name: "foo",
    tags: ["my_tag", "another_tag"]
  },
  async (message) => {
    // your code here
  },
  "Hello, world!"
)

Example. Tagging any span from within its context

Note that for adding span tags to work, you must call it inside a span context. This is why we use observe here.

import { Laminar, observe } from '@lmnr-ai/lmnr';

async function foo(message: string) {
  if (message.length > 100) {
    // ✅ Correct usage. We are inside an `observe`d function,
    Laminar.addSpanTags(["long_input"]);
  }
}

// ❌ Incorrect usage. We are not inside any span context. This will not work.
// Laminar.addSpanTags(["my_tag", "another_tag"])

await observe(
  {
    name: "foo",
  },
  foo,
  "a".repeat(200)
)

2. Adding tags to a span once it is created

This is useful to incorporate user feedback into the trace for further analysis.

2.1. Tagging in the Laminar UI

Once you’ve created and sent a trace to Laminar, you can add tags to the spans in the Laminar UI.

2.2. Tagging in the Laminar SDK

You can also add tags to a span in the Laminar SDK. You will need to save the trace ID and then add tags to the root span of that trace using LaminarClient.tags.tag.

import { Laminar, LaminarClient, observe } from '@lmnr-ai/lmnr';

const laminarClient = new LaminarClient();

// Take note of the traceId.
const { traceId, responseText } = await observe(
  {
    name: "chat_completion",
  },
  async (message: string) => {
    const response = await openaiClient.chat.completions.create({
      model: "gpt-4.1-nano",
      messages: [{ role: "user", content: message }],
    });
    const responseText = response.choices[0].message.content;
    return {
      // ✅ Correct usage. We are inside an `observe`d function,
      // so `getTraceId` returns a string UUID.
      traceId: Laminar.getTraceId(),
      responseText,
    }
  },
  "Hello, world!"
)

// Call this function later, when you get user feedback.
const userFeedbackHandler = (
  traceId: string,
  userFeedback: "good" | "bad"
) => laminarClient.tags.tag(traceId, userFeedback);

Make sure to call Laminar.getTraceId inside a span context, e.g. inside an observed function. Otherwise, it will return null.

Viewing tags

The tags will be visible in the Laminar UI, shown on each span as shields.

Filtering by span tags

In the traces view and the spans view, you can filter by span tags.

Simply add a “Tags” filter and type the name of the tag you want to include.