Ops·Calls·Traces 이해하기
Ops·Calls·Traces 이해하기 (Weave 트레이싱 기초)
LLM 애플리케이션을 운영하다 보면 "이 호출 하나가 왜 이렇게 느렸지?", "프롬프트를 바꾸니 결과가 달라진 이유가 뭘까?" 같은 질문이 꼭 생기게 돼요. W&B Weave의 트레이싱 시스템은 바로 그런 질문에 답하기 위한 네 가지 개념, Ops, Calls, Traces, Threads 위에 만들어져 있어요. 이 페이지에서는 각 개념이 무엇이고 서로 어떻게 연결되는지 짚어볼게요.
Ops (연산)
Op는 버전이 붙어 추적되는 함수예요. 함수에 @weave.op() 데코레이터를 붙이거나(Python), weave.op()로 감싸면(TypeScript) Weave가 자동으로 그 함수의 코드·입력·출력·실행 메타데이터를 잡아줘요. Ops는 트레이싱, 평가 스코어러, 그리고 추적되는 모든 연산의 기본 재료가 됩니다.
@weave.op
async def my_function(){
... }
// @noErrors
function myFunction() {
...
}
const myFunctionOp = weave.op(myFunction)
Calls (호출)
Call은 Op가 한 번 실행된 기록이에요. Op가 실행될 때마다 Weave는 다음 정보를 담는 Call을 만들어요.
- 입력 인자
- 출력 값
- 소요 시간과 지연(latency)
- 부모-자식 관계 (중첩 호출용)
- 발생한 에러
이 Call들은 Weave UI에서 Traces로 보이게 되고, 디버깅·분석·평가의 데이터가 됩니다. Call 객체의 전체 구조와 속성은 Call 스키마 참조 문서에서 확인할 수 있어요.
Call은 OpenTelemetry 데이터 모델의 span과 비슷하다고 볼 수 있어요. Call은:
- 같은 실행 컨텍스트를 공유하는 Call들의 묶음인 Trace에 속할 수 있고,
- 부모 Call과 자식 Call을 가질 수 있어 나무(tree) 구조를 이룹니다.
Traces (트레이스)
Trace는 같은 실행 컨텍스트를 공유하는 Call 전체의 나무 구조예요. 각 Trace는 trace_id라는 ID를 가지는데, 이 ID로 Call들의 전체 트리를 조회할 수 있어요. 만약 Call의 ID로 정보를 가져오면 그 특정 Call 하나의 데이터만 돌아오고, 자식 Call들은 포함되지 않아요.
Threads (스레드)
Thread는 하나의 세션(session)이나 대화에 관련된 Trace들의 모음이에요. 개별 Call이 아니라 대화 전체를 분석하거나 채점하고 싶을 때 Thread를 씁니다. Threads, Traces, Calls의 관계를 그림으로 보면 이렇게 돼요.
Thread: "session-abc"
├── Turn 1 (trace_id: aaa) -> user says "Hi"
│ ├── LLM call
│ └── format response
├── Turn 2 (trace_id: bbb) -> user says "What is the capital of France?"
│ ├── RAG retrieval
│ ├── LLM call
│ └── format response
└── Turn 3 (trace_id: ccc) -> user says "Thanks"
└── LLM call