태그

태그 (Tags)

Tags를 사용하면 Langfuse에서 observation과 trace를 분류하고 필터링할 수 있어요. 태그는 문자열(각각 최대 200자)이며, 하나의 observation에 여러 태그를 달 수 있어요. 태그가 200자를 넘으면 버려져요.

출처: 문서

본문

Tags를 사용하면 Langfuse에서 observation과 trace를 분류하고 필터링할 수 있어요.

태그는 문자열(각각 최대 200자)이며, 하나의 observation에 여러 태그를 달 수 있어요. 태그가 200자를 넘으면 버려져요.

trace의 모든 observation에 적용된 전체 태그 집합은 자동으로 집계되어 Langfuse의 trace 객체에 추가돼요.

Langfuse UI에서 (In the Langfuse UI)

observation에 태그가 지정되면 다음을 할 수 있어요:

  • 하나 이상의 태그로 traces·observations 테이블을 필터링해요. filter search bar에서 tags:(billing AND urgent)처럼 타입된 쿼리로도 가능해요.
  • custom dashboards와 metrics를 태그별로 세분화해요. 예를 들어 checkout과 support-bot의 비용이나 지연시간을 비교할 수 있어요.
  • 그 카테고리를 environment, user, session에 섞지 않고 feature, 엔드포인트, 워크플로별로 trace를 조직화해요.

Traces table with a Trace Tags column

태그는 나중에 변경할 수 없어요 (Tags cannot be changed later)

Langfuse는 observation에 대해 불변(immutable) 데이터 모델을 사용하므로, 태그는 생성된 후 UI에서 추가하거나 편집할 수 없어요.

구현 (Implementation)

propagate_attributes()를 사용해 컨텍스트 내 observation 그룹에 태그를 적용해요.

Python SDK

@observe() 데코레이터 사용 시:

from langfuse import observe, propagate_attributes

@observe()
def my_function():
    # Apply tags to all child observations
    with propagate_attributes(
        tags=["tag-1", "tag-2"]
    ):
        # All nested observations automatically have these tags
        result = process_data()
        return result

observation을 직접 생성할 때:

from langfuse import get_client, propagate_attributes

langfuse = get_client()

with langfuse.start_as_current_observation(as_type="span", name="my-operation") as root_span:
    # Apply tags to all child observations
    with propagate_attributes(tags=["tag-1", "tag-2"]):
        # All observations created here automatically have these tags
        with root_span.start_as_current_observation(
            as_type="generation",
            name="llm-call",
            model="gpt-4o"
        ) as gen:
            # This generation automatically has the tags
            pass

JS/TS SDK

컨텍스트 매니저 사용 시:

import { startActiveObservation, propagateAttributes } from "@langfuse/tracing";

await startActiveObservation("context-manager", async (span) => {
  span.update({
    input: { query: "What is the capital of France?" },
  });

  // Apply tags to all child observations
  await propagateAttributes(
    {
      tags: ["tag-1", "tag-2"],
    },
    async () => {
      // All observations created here automatically have these tags
      // ... your logic ...
    }
  );
});

observe 래퍼 사용 시:

import { observe, propagateAttributes } from "@langfuse/tracing";

const processData = observe(
  async (data: string) => {
    // Apply tags to all child observations
    return await propagateAttributes(
      { tags: ["tag-1", "tag-2"] },
      async () => {
        // All nested observations automatically have these tags
        const result = await performProcessing(data);
        return result;
      }
    );
  },
  { name: "process-data" }
);

const result = await processData("input");

자세한 내용은 JS/TS SDK docs를 참고하세요.

OpenAI (Python)

from langfuse import get_client, propagate_attributes
from langfuse.openai import openai

langfuse = get_client()

with langfuse.start_as_current_observation(as_type="span", name="openai-call"):
    # Apply tags to all observations including OpenAI generation
    with propagate_attributes(
        tags=["tag-1", "tag-2"]
    ):
        completion = openai.chat.completions.create(
            name="test-chat",
            model="gpt-3.5-turbo",
            messages=[
                {"role": "system", "content": "You are a calculator."},
                {"role": "user", "content": "1 + 1 = "}
            ],
            temperature=0,
        )

또는 감싸는 observation 없이 OpenAI를 사용할 때:

from langfuse.openai import openai

completion = openai.chat.completions.create(
  name="test-chat",
  model="gpt-3.5-turbo",
  messages=[
    {"role": "system", "content": "You are a calculator."},
    {"role": "user", "content": "1 + 1 = "}],
  temperature=0,
  metadata={"langfuse_tags": ["tag-1", "tag-2"]}
)

OpenAI (JS/TS)

import OpenAI from "openai";
import { observeOpenAI } from "@langfuse/openai";
import { startActiveObservation, propagateAttributes } from "@langfuse/tracing";

await startActiveObservation("openai-call", async () => {
  // Apply tags to all observations
  await propagateAttributes(
    {
      tags: ["tag-1", "tag-2"],
    },
    async () => {
      const res = await observeOpenAI(new OpenAI()).chat.completions.create({
        messages: [{ role: "system", content: "Tell me a story about a dog." }],
        model: "gpt-3.5-turbo",
        max_tokens: 300,
      });
    }
  );
});

Langchain (Python)

from langfuse import get_client, propagate_attributes
from langfuse.langchain import CallbackHandler

langfuse = get_client()
langfuse_handler = CallbackHandler()

with langfuse.start_as_current_observation(as_type="span", name="langchain-call"):
    # Apply tags to all child observations
    with propagate_attributes(
        tags=["tag-1", "tag-2"]
    ):
        response = chain.invoke(
            {"topic": "cats"},
            config={"callbacks": [langfuse_handler]}
        )

또는 observation 없이 chain invocation에서 메타데이터를 사용:

from langfuse.langchain import CallbackHandler

handler = CallbackHandler()

chain.invoke(
    {"animal": "dog"},
    config={
        "callbacks": [handler],
        "metadata": {"langfuse_tags": ["tag-1", "tag-2"]},
    },
)

Langchain (JS/TS)

import { startActiveObservation, propagateAttributes } from "@langfuse/tracing";
import { CallbackHandler } from "@langfuse/langchain";

const langfuseHandler = new CallbackHandler();

// Apply tags to all child observations
await propagateAttributes(
  {
    tags: ["tag-1", "tag-2"],
  },
  async () => {
    await chain.invoke(
      { input: "<user_input>" },
      { callbacks: [langfuseHandler] }
    );
  }
);

또는 chain invocation에서 메타데이터를 사용:

CallbackHandler를 사용할 때 생성자에 태그를 전달할 수도 있어요:

const handler = new CallbackHandler({
  tags: ["tag-1", "tag-2"],
});

또는 chain invocation의 runnable 구성으로 태그를 동적으로 설정:

const langfuseHandler = new CallbackHandler()
const tags = ["tag-1", "tag-2"];

// Pass config to the chain invocation to be parsed as Langfuse trace attributes
await chain.invoke({ input: "<user_input>" }, { callbacks: [langfuseHandler], tags: tags });

속성 전파(Attribute Propagation)에 대한 참고 — 우리는 Attribute Propagation을 사용해 trace의 모든 observation에 tags를 전파해요. tags가 있는 모든 observation을 사용해 tags-레벨 메트릭을 만듭니다. Attribute Propagation 사용 시 다음을 고려하세요:

  • 값은 200자 이하의 문자열이어야 해요.
  • 모든 observation이 적용되도록 trace 초기에 호출하세요. 그래야 Langfuse의 모든 메트릭이 정확해요.
  • 잘못된 값은 경고와 함께 버려져요. 자세히: Python SDK | TypeScript SDK
  • Filter search bartags:(billing AND urgent) 같은 타입된 쿼리로 observation과 trace를 태그별로 필터링해요.
  • Metadata — 문자열 라벨이 부족할 때 키-값 쌍을 첨부해요.
  • Environments — 프로덕션, 스테이징, 개발 데이터를 분리해요.
  • Custom dashboards — 메트릭을 태그별로 세분화해요.
  • Metrics API — 태그로 필터링된 집계 사용량과 비용을 조회해요.
  • Scores vs tags — 트레이싱 후 분류·평가가 필요할 때는 score를 선택하세요.
  • What does a good trace look like? — 비즈니스 레벨 차원에 태그를 언제 쓸지.

GitHub Discussions

더 알아보기 (Learn more)