커스텀 계측
커스텀 계측 (Custom instrumentation)
코드에 계측을 직접 추가하면 애플리케이션이 어떤 함수를 트레이싱하는지, 어떤 입력/출력이 기록되는지, 트레이스 계층이 어떻게 구성되는지 정밀하게 제어할 수 있어요. 세 가지 핵심 계측 접근 방식이 있습니다.
출처: 문서
본문
코드에 계측을 직접 추가하면 애플리케이션이 어떤 함수를 트레이싱하는지, 어떤 입력과 출력이 기록되는지, 트레이스 계층이 어떻게 구성되는지 정밀하게 제어할 수 있습니다. 세 가지 핵심 계측 접근 방식:
@traceable데코레이터: 대부분의 경우 권장trace컨텍스트 매니저: Python 전용RunTreeAPI: 명시적이고 저수준의 제어
이 페이지는 또한 다음을 다룹니다:
- 커스텀 런 ID 지정 — 런 직후 피드백을 연결하거나 외부 시스템과의 상관관계에 유용.
- 프로세스가 종료되기 전에 모든 트레이스가 제출되도록 보장.
LangChain(Python 또는 JS/TS)은 LangChain 특화 지침을 참고하세요.
플러그: 내장 LangSmith 통합이 있는 LLM 제공자 또는 에이전트 프레임워크를 사용한다면 통합 개요를 참고하세요.
사전 준비 사항
트레이싱 전에 다음 환경 변수를 설정하세요:
-
LANGSMITH_TRACING=true: 트레이싱 활성화. 코드를 변경하지 않고 트레이싱을 켜고 끄려면 이를 설정하세요.참고:
LANGSMITH_TRACING은@traceable데코레이터와trace컨텍스트 매니저를 제어합니다. 환경 변수를 변경하지 않고@traceable에 대해 런타임에 이를 재정의하려면tracing_context(enabled=True/False)(Python) 사용하거나traceable에tracingEnabled를 직접 전달(JS/TS)하세요.RunTree객체는 이러한 제어의 영향을 받지 않습니다. 게시되면 항상 LangSmith로 데이터를 보냅니다. -
LANGSMITH_API_KEY: LangSmith API 키. -
기본적으로 LangSmith는
default라는 프로젝트에 트레이스를 기록합니다. 다른 프로젝트에 기록하려면LANGSMITH_PROJECT를 설정하세요. 자세한 내용은 특정 프로젝트에 트레이스 기록을 참고하세요.
@traceable / traceable 사용
@traceable(Python), traceable(TypeScript), traceable(Kotlin) 또는 Tracing.traceFunction(Java)을 어떤 함수에 적용해 추적된 런으로 만듭니다. LangSmith는 중첩 호출 간 컨텍스트 전파를 자동으로 처리합니다.
다음 예시는 간단한 파이프라인을 트레이싱합니다: run_pipeline이 format_prompt를 호출해 메시지를 만들고, invoke_llm으로 모델을 호출하고, parse_output으로 결과를 추출합니다.
각 함수는 개별적으로 추적되며, (역시 추적되는) run_pipeline 안에서 호출되므로 LangSmith는 이를 자식 런으로 자동 중첩합니다. invoke_llm은 run_type="llm"을 사용해 LLM 호출로 표시, LangSmith가 토큰 수와 지연 시간을 올바르게 렌더링할 수 있게 합니다:
from langsmith import traceable
from openai import Client
openai = Client()
@traceable
def format_prompt(subject):
return [
{
"role": "system",
"content": "You are a helpful assistant.",
},
{
"role": "user",
"content": f"What's a good name for a store that sells {subject}?"
}
]
@traceable(run_type="llm")
def invoke_llm(messages):
return openai.chat.completions.create(
messages=messages, model="gpt-5.4-mini", temperature=0
)
@traceable
def parse_output(response):
return response.choices[0].message.content
@traceable
def run_pipeline():
messages = format_prompt("colorful socks")
response = invoke_llm(messages)
return parse_output(response)
run_pipeline()
import { traceable } from "langsmith/traceable";
import OpenAI from "openai";
const openai = new OpenAI();
const formatPrompt = traceable((subject: string) => {
return [
{
role: "system" as const,
content: "You are a helpful assistant.",
},
{
role: "user" as const,
content: `What's a good name for a store that sells ${subject}?`,
},
];
},{ name: "formatPrompt" });
const invokeLLM = traceable(
async ({ messages }: { messages: { role: string; content: string }[] }) => {
return openai.chat.completions.create({
model: "gpt-5.4-mini",
messages: messages,
temperature: 0,
});
},
{ run_type: "llm", name: "invokeLLM" }
);
const parseOutput = traceable(
(response: any) => {
return response.choices[0].message.content;
},
{ name: "parseOutput" }
);
const runPipeline = traceable(
async () => {
const messages = await formatPrompt("colorful socks");
const response = await invokeLLM({ messages });
return parseOutput(response);
},
{ name: "runPipeline" }
);
await runPipeline();
import com.langchain.smith.tracing.RunType;
import com.langchain.smith.tracing.TraceConfig;
import com.langchain.smith.tracing.Tracing;
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.models.ChatModel;
import com.openai.models.chat.completions.ChatCompletion;
import com.openai.models.chat.completions.ChatCompletionCreateParams;
import com.openai.models.chat.completions.ChatCompletionMessageParam;
import com.openai.models.chat.completions.ChatCompletionSystemMessageParam;
import com.openai.models.chat.completions.ChatCompletionUserMessageParam;
import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
public class TraceablePipeline {
public static void main(String[] args) {
new TraceablePipelineRunner().run();
}
private static final class TraceablePipelineRunner {
private final OpenAIClient openai = OpenAIOkHttpClient.fromEnv();
private final Function<String, List<ChatCompletionMessageParam>> formatPrompt =
Tracing.traceFunction(
subject ->
Arrays.asList(
ChatCompletionMessageParam.ofSystem(
ChatCompletionSystemMessageParam.builder()
.content("You are a helpful assistant.")
.build()),
ChatCompletionMessageParam.ofUser(
ChatCompletionUserMessageParam.builder()
.content("What's a good name for a store that sells " + subject + "?")
.build())),
TraceConfig.builder().name("format_prompt").build());
private final Function<List<ChatCompletionMessageParam>, ChatCompletion> invokeLlm =
Tracing.traceFunction(
messages ->
openai.chat()
.completions()
.create(
ChatCompletionCreateParams.builder()
.model(ChatModel.GPT_5_5)
.messages(messages)
.build()),
TraceConfig.builder().name("invoke_llm").runType(RunType.LLM).build());
private final Function<ChatCompletion, String> parseOutput =
Tracing.traceFunction(
response -> response.choices().get(0).message().content().orElse(""),
TraceConfig.builder().name("parse_output").build());
private final Function<String, String> runPipeline =
Tracing.traceFunction(
subject -> parseOutput.apply(invokeLlm.apply(formatPrompt.apply(subject))),
TraceConfig.builder().name("run_pipeline").build());
void run() {
runPipeline.apply("colorful socks");
}
}
}
View example trace — 이 예시에 대한 공개 LangSmith 런을 엽니다.
import com.langchain.smith.tracing.RunType
import com.langchain.smith.tracing.TraceConfig
import com.langchain.smith.tracing.traceable
import com.openai.client.okhttp.OpenAIOkHttpClient
import com.openai.models.ChatModel
import com.openai.models.chat.completions.ChatCompletion
import com.openai.models.chat.completions.ChatCompletionCreateParams
import com.openai.models.chat.completions.ChatCompletionMessageParam
import com.openai.models.chat.completions.ChatCompletionSystemMessageParam
import com.openai.models.chat.completions.ChatCompletionUserMessageParam
import kotlin.jvm.optionals.getOrNull
val openai = OpenAIOkHttpClient.fromEnv()
val formatPrompt =
traceable(
{ subject: String ->
listOf(
ChatCompletionMessageParam.ofSystem(
ChatCompletionSystemMessageParam.builder()
.content("You are a helpful assistant.")
.build(),
),
ChatCompletionMessageParam.ofUser(
ChatCompletionUserMessageParam.builder()
.content("What's a good name for a store that sells $subject?")
.build(),
),
)
},
TraceConfig.builder().name("format_prompt").build(),
)
val invokeLlm =
traceable(
{ messages: List<ChatCompletionMessageParam> ->
openai.chat().completions().create(
ChatCompletionCreateParams.builder()
.model(ChatModel.GPT_5_5)
.messages(messages)
.build(),
)
},
TraceConfig.builder().name("invoke_llm").runType(RunType.LLM).build(),
)
val parseOutput =
traceable(
{ response: ChatCompletion ->
response.choices()[0].message().content().getOrNull().orEmpty()
},
TraceConfig.builder().name("parse_output").build(),
)
val runPipeline =
traceable(
{ subject: String -> parseOutput(invokeLlm(formatPrompt(subject))) },
TraceConfig.builder().name("run_pipeline").build(),
)
println(runPipeline("colorful socks"))
View example trace — 이 예시에 대한 공개 LangSmith 런을 엽니다.
UI에서 format_prompt, invoke_llm, parse_output가 중첩 자식 런으로 있는 run_pipeline 트레이스를 확인할 수 있습니다.
참고:
traceable로 동기 함수를 감쌀 때(예: 위 예시의formatPrompt) 호출할 때await키워드를 사용해 트레이스가 올바르게 기록되도록 하세요.
trace 컨텍스트 매니저 사용 (Python 전용)
Python에서는 trace 컨텍스트 매니저를 사용해 트레이스를 LangSmith로 기록할 수 있습니다. 다음과 같은 상황에서 유용합니다:
- 특정 코드 블록에 대한 트레이스를 기록하고 싶을 때.
- 트레이스의 입력, 출력 및 기타 속성을 제어하고 싶을 때.
- 데코레이터나 래퍼를 사용하는 것이 불가능할 때.
- 위 중 어느 하나 또는 전부.
컨텍스트 매니저는 traceable 데코레이터와 wrap_openai 래퍼와 원활하게 통합되므로, 같은 애플리케이션에서 함께 사용할 수 있습니다.
다음 예시는 세 가지를 모두 함께 사용하는 것을 보여줍니다. wrap_openai는 OpenAI 클라이언트를 감싸 그 호출이 자동으로 추적되게 합니다. my_tool은 run_type="tool"과 커스텀 name으로 @traceable을 사용해 트레이스에 올바르게 나타나게 합니다. chat_pipeline 자체는 데코레이트되지 않습니다. 대신 ls.trace가 호출을 감싸, 프로젝트 이름과 입력을 명시적으로 전달하고 rt.end()로 출력을 수동으로 설정할 수 있게 합니다:
import openai
import langsmith as ls
from langsmith.wrappers import wrap_openai
client = wrap_openai(openai.Client())
@ls.traceable(run_type="tool", name="Retrieve Context")
def my_tool(question: str) -> str:
return "During this morning's meeting, we solved all world conflict."
def chat_pipeline(question: str):
context = my_tool(question)
messages = [
{ "role": "system", "content": "You are a helpful assistant. Please respond to the user's request only based on the given context." },
{ "role": "user", "content": f"Question: {question}\nContext: {context}"}
]
chat_completion = client.chat.completions.create(
model="gpt-5.4-mini", messages=messages
)
return chat_completion.choices[0].message.content
app_inputs = {"input": "Can you summarize this morning's meetings?"}
with ls.trace("Chat Pipeline", "chain", project_name="my_test", inputs=app_inputs) as rt:
output = chat_pipeline("Can you summarize this morning's meetings?")
rt.end(outputs={"output": output})
RunTree API 사용
트레이스를 LangSmith로 기록하는 더 명시적인 또 다른 방법은 RunTree API입니다. 이 API를 사용하면 트레이싱을 더 깊이 제어할 수 있습니다. 런과 자식 런을 수동으로 만들어 트레이스를 조립할 수 있습니다. 여전히 LANGSMITH_API_KEY를 설정해야 하지만, 이 방법에는 LANGSMITH_TRACING이 필요하지 않습니다.
이 방법은 대부분의 사용 사례에 권장되지 않습니다. 트레이스 컨텍스트를 수동으로 관리하는 것은 컨텍스트 전파를 자동으로 처리하는 @traceable에 비해 오류가 발생하기 쉽습니다.
import openai
from langsmith.run_trees import RunTree
# This can be a user input to your app
question = "Can you summarize this morning's meetings?"
# Create a top-level run
pipeline = RunTree(
name="Chat Pipeline",
run_type="chain",
inputs={"question": question}
)
pipeline.post()
# This can be retrieved in a retrieval step
context = "During this morning's meeting, we solved all world conflict."
messages = [
{ "role": "system", "content": "You are a helpful assistant. Please respond to the user's request only based on the given context." },
{ "role": "user", "content": f"Question: {question}\nContext: {context}"}
]
# Create a child run
child_llm_run = pipeline.create_child(
name="OpenAI Call",
run_type="llm",
inputs={"messages": messages},
)
child_llm_run.post()
# Generate a completion
client = openai.Client()
chat_completion = client.chat.completions.create(
model="gpt-5.4-mini", messages=messages
)
# End the runs and log them
child_llm_run.end(outputs=chat_completion)
child_llm_run.patch()
pipeline.end(outputs={"answer": chat_completion.choices[0].message.content})
pipeline.patch()
import OpenAI from "openai";
import { RunTree } from "langsmith";
// This can be a user input to your app
const question = "Can you summarize this morning's meetings?";
const pipeline = new RunTree({
name: "Chat Pipeline",
run_type: "chain",
inputs: { question }
});
await pipeline.postRun();
// This can be retrieved in a retrieval step
const context = "During this morning's meeting, we solved all world conflict.";
const messages = [
{ role: "system", content: "You are a helpful assistant. Please respond to the user's request only based on the given context." },
{ role: "user", content: `Question: ${question}Context: ${context}` }
];
// Create a child run
const childRun = await pipeline.createChild({
name: "OpenAI Call",
run_type: "llm",
inputs: { messages },
});
await childRun.postRun();
// Generate a completion
const client = new OpenAI();
const chatCompletion = await client.chat.completions.create({
model: "gpt-5.4-mini",
messages: messages,
});
// End the runs and log them
childRun.end(chatCompletion);
await childRun.patchRun();
pipeline.end({ outputs: { answer: chatCompletion.choices[0].message.content } });
await pipeline.patchRun();
import com.langchain.smith.client.LangsmithClient;
import com.langchain.smith.client.okhttp.LangsmithOkHttpClient;
import com.langchain.smith.tracing.RunTree;
import com.langchain.smith.tracing.RunType;
import com.langchain.smith.tracing.TraceConfig;
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.models.ChatModel;
import com.openai.models.chat.completions.ChatCompletion;
import com.openai.models.chat.completions.ChatCompletionCreateParams;
import com.openai.models.chat.completions.ChatCompletionMessageParam;
import com.openai.models.chat.completions.ChatCompletionSystemMessageParam;
import com.openai.models.chat.completions.ChatCompletionUserMessageParam;
import java.time.Instant;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class RunTreeExample {
public static void main(String[] args) throws InterruptedException {
LangsmithClient langsmith = LangsmithOkHttpClient.fromEnv();
OpenAIClient openai = OpenAIOkHttpClient.fromEnv();
ExecutorService executor = Executors.newSingleThreadExecutor();
try {
String question = "Can you summarize this morning's meetings?";
String runId = "01990f3e-7f97-74c5-a9b6-8d3f7e8e2f11";
RunTree pipeline = RunTree.builder()
.id(runId)
.name("Chat Pipeline")
.runType(RunType.CHAIN)
.inputs(Collections.singletonMap("question", question))
.client(langsmith)
.executor(executor)
.build();
pipeline.postRun();
String context = "During this morning's meeting, we solved all world conflict.";
List<ChatCompletionMessageParam> messages = Arrays.asList(
ChatCompletionMessageParam.ofSystem(
ChatCompletionSystemMessageParam.builder()
.content(
"You are a helpful assistant. Please respond to the user's " +
"request only based on the given context.")
.build()),
ChatCompletionMessageParam.ofUser(
ChatCompletionUserMessageParam.builder()
.content("Question: " + question + "\nContext: " + context)
.build()));
RunTree childRun = pipeline.createChild(
TraceConfig.builder().name("OpenAI Call").runType(RunType.LLM).build());
childRun.setInputs(Collections.singletonMap("messages", messages));
childRun.postRun();
ChatCompletion chatCompletion = openai.chat().completions().create(
ChatCompletionCreateParams.builder()
.model(ChatModel.GPT_5_5)
.messages(messages)
.build());
String answer = chatCompletion.choices().get(0).message().content().orElse("");
System.out.println(answer);
childRun.setOutputs(Collections.singletonMap("response", chatCompletion.toString()));
childRun.setEndTime(Instant.now().toString());
childRun.patchRun();
pipeline.setOutputs(Collections.singletonMap(
"answer", answer));
pipeline.setEndTime(Instant.now().toString());
pipeline.patchRun();
} finally {
executor.shutdown();
if (!executor.awaitTermination(10, TimeUnit.SECONDS)) {
throw new IllegalStateException(
"Timed out waiting for LangSmith traces to submit");
}
}
}
}
import com.langchain.smith.client.okhttp.LangsmithOkHttpClient
import com.langchain.smith.tracing.RunTree
import com.langchain.smith.tracing.RunType
import com.langchain.smith.tracing.TraceConfig
import com.openai.client.okhttp.OpenAIOkHttpClient
import com.openai.models.ChatModel
import com.openai.models.chat.completions.ChatCompletionCreateParams
import com.openai.models.chat.completions.ChatCompletionMessageParam
import com.openai.models.chat.completions.ChatCompletionSystemMessageParam
import com.openai.models.chat.completions.ChatCompletionUserMessageParam
import java.time.Instant
import java.util.concurrent.Executors
import java.util.concurrent.TimeUnit
val langsmith = LangsmithOkHttpClient.fromEnv()
val openai = OpenAIOkHttpClient.fromEnv()
val executor = Executors.newSingleThreadExecutor()
try {
val question = "Can you summarize this morning's meetings?"
val runId = "01990f3e-7f97-74c5-a9b6-8d3f7e8e2f11"
val pipeline =
RunTree.builder()
.id(runId)
.name("Chat Pipeline")
.runType(RunType.CHAIN)
.inputs(mapOf("question" to question))
.client(langsmith)
.executor(executor)
.build()
println("[run-tree-example] Posting parent run to LangSmith…")
pipeline.postRun()
val context = "During this morning's meeting, we solved all world conflict."
val messages =
listOf(
ChatCompletionMessageParam.ofSystem(
ChatCompletionSystemMessageParam.builder()
.content(
"You are a helpful assistant. Please respond to the user's " +
"request only based on the given context.",
)
.build(),
),
ChatCompletionMessageParam.ofUser(
ChatCompletionUserMessageParam.builder()
.content("Question: $question\nContext: $context")
.build(),
),
)
val childRun =
pipeline.createChild(
TraceConfig.builder().name("OpenAI Call").runType(RunType.LLM).build(),
)
childRun.inputs = mapOf("messages" to messages)
println("[run-tree-example] Posting child run to LangSmith…")
childRun.postRun()
val chatCompletion =
openai.chat().completions().create(
ChatCompletionCreateParams.builder()
.model(ChatModel.GPT_5_5)
.messages(messages)
.build(),
)
val answer = chatCompletion.choices()[0].message().content().orElse("")
println("[run-tree-example] Answer:")
println(answer)
childRun.outputs = mapOf("response" to chatCompletion.toString())
childRun.endTime = Instant.now().toString()
childRun.patchRun()
pipeline.outputs =
mapOf(
"answer" to answer,
)
pipeline.endTime = Instant.now().toString()
pipeline.patchRun()
} finally {
executor.shutdown()
check(executor.awaitTermination(10, TimeUnit.SECONDS)) {
"Timed out waiting for LangSmith traces to submit"
}
}
Java와 Kotlin 예시는 커스텀 루트 런 ID와 전용 실행기를 사용합니다. 실행기를 종료하고 종료를 기다리면 프로세스가 끝나기 전에 백그라운드 런 제출이 완료됩니다.
예시 사용법
이전 섹션에서 설명한 유틸리티를 확장해 어떤 코드든 트레이싱할 수 있습니다. 다음 코드는 몇 가지 예시 확장을 보여줍니다.
클래스의 공개 메서드 트레이싱:
from typing import Any, Callable, Type, TypeVar
T = TypeVar("T")
def traceable_cls(cls: Type[T]) -> Type[T]:
"""Instrument all public methods in a class."""
def wrap_method(name: str, method: Any) -> Any:
if callable(method) and not name.startswith("__"):
return traceable(name=f"{cls.__name__}.{name}")(method)
return method
# Handle __dict__ case
for name in dir(cls):
if not name.startswith("_"):
try:
method = getattr(cls, name)
setattr(cls, name, wrap_method(name, method))
except AttributeError:
# Skip attributes that can't be set (e.g., some descriptors)
pass
# Handle __slots__ case
if hasattr(cls, "__slots__"):
for slot in cls.__slots__: # type: ignore[attr-defined]
if not slot.startswith("__"):
try:
method = getattr(cls, slot)
setattr(cls, slot, wrap_method(slot, method))
except AttributeError:
# Skip slots that don't have a value yet
pass
return cls
@traceable_cls
class MyClass:
def __init__(self, some_val: int):
self.some_val = some_val
def combine(self, other_val: int):
return self.some_val + other_val
# See trace: https://smith.langchain.com/public/882f9ecf-5057-426a-ae98-0edf84fdcaf9/r
MyClass(13).combine(29)
커스텀 런 ID 지정
기본적으로 LangSmith는 각 런에 무작위 ID를 할당합니다. 런 ID를 미리 알아야 할 때(예: 런 직후 피드백을 연결하기 위해), LangSmith 런을 외부 시스템의 ID와 상관시키거나, 결정적 ID로 런을 멱등성(idempotent) 있게 만들 때 이를 재정의할 수 있습니다.
참고: 커스텀 런 ID에는 UUID v7을 사용하세요. UUIDv7은 타임스탬프를 내장해 트레이스 내 런의 올바른 시간 정렬을 보존합니다. LangSmith SDK는
uuid7헬퍼(Python v0.4.43+, JS v0.3.80+)를 내보냅니다:
- Python:
from langsmith import uuid7- JS/TS:
import { uuid7 } from 'langsmith'어떤 UUID v7 문자열이든 허용됩니다 — SDK 헬퍼를 사용하거나 시스템이 이미 UUID v7 식별자를 사용한다면 자체 것을 사용할 수 있습니다.
다음 중 하나를 사용하세요:
-
@traceable:@traceable함수를 호출할 때langsmith_extra안의run_id를 전달(Python), 또는traceable에 전달되는 구성 객체의id를 전달(TypeScript):from langsmith import traceable, uuid7 @traceable def my_pipeline(question: str) -> str: return "answer" run_id = uuid7() my_pipeline("What is the capital of France?", langsmith_extra={"run_id": run_id}) # run_id can now be used to attach feedback, query the run, etc.import { traceable } from "langsmith/traceable"; import { uuid7 } from "langsmith"; const runId = uuid7(); const myPipeline = traceable( async (question: string) => { return "answer"; }, { name: "my-pipeline", id: runId } ); await myPipeline("What is the capital of France?"); // runId can now be used to attach feedback, query the run, etc. -
trace컨텍스트 매니저 (Python 전용): trace 컨텍스트 매니저 생성자에run_id를 직접 전달:from langsmith import trace, uuid7 run_id = uuid7() with trace("my-pipeline", run_id=run_id) as run: result = "answer" run.end(outputs={"result": result}) # run_id can now be used to attach feedback, query the run, etc.
종료 전에 모든 트레이스가 제출되도록 보장
LangSmith는 프로덕션 애플리케이션을 방해하지 않도록 백그라운드 스레드에서 트레이싱을 수행합니다. 즉 프로세스가 모든 트레이스가 LangSmith에 성공적으로 게시되기 전에 끝날 수 있습니다. 다음 옵션을 참고하세요:
-
LangChain을 사용한다면 LangChain 트레이싱 가이드를 참고하세요.
-
LangSmith SDK를 독립형으로 사용한다면 종료 전에
flush메서드를 사용할 수 있습니다:from langsmith import Client client = Client() @traceable(client=client) async def my_traced_func(): # Your code here... pass try: await my_traced_func() finally: await client.flush()import { Client } from "langsmith"; const langsmithClient = new Client({}); const myTracedFunc = traceable(async () => { // Your code here... },{ client: langsmithClient }); try { await myTracedFunc(); } finally { await langsmithClient.flush(); }
관련 문서
- 관측성 개념: 런, 트레이스, LangSmith 데이터 모델에 대한 배경.
- 런 (span) 데이터 형식:
dotted_order,trace_id,parent_run_id를 포함한 런 필드의 스키마 레퍼런스. - SDK로 사용자 피드백 기록: 런 ID를 미리 지정하는 일반적인 사용 사례.
- 추적된 함수 내에서 현재 런 (span)에 접근: 트레이스 안에서 활성 런을 읽거나 수정.
- 특정 프로젝트에 트레이스 기록:
default대신 명명된 프로젝트로 트레이스 라우팅. - API로 트레이싱: SDK의 저수준 REST API 대안.
- Tracing Basics video — Introduction to LangSmith 코스에서.
더 알아보기
- 관측성 개념은 Observability concepts 문서를 참고하세요.
- 런 ID를 미리 지정하고 피드백 연결하는 방법은 Attach user feedback 문서를 확인해 보세요.