Documentation Index
Fetch the complete documentation index at: https://translations.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
Op는 버전이 관리되고 추적되는 함수입니다. 함수를 @weave.op()(Python) 데코레이터로 감싸거나 weave.op()(TypeScript)로 래핑하면 Weave가 해당 함수의 코드, 입력, 출력, 실행 메타데이터를 자동으로 캡처합니다. Op는 트레이싱, 평가 스코어러, 그리고 추적되는 모든 계산의 기본 구성 요소입니다.
@weave.op
async def my_function(){
... }
Call은 Op의 기록된 실행입니다. Op가 실행될 때마다 Weave는 다음 정보를 캡처하는 Call을 생성합니다:
- 입력 인수
- 출력 값
- 실행 시간과 지연 시간
- (중첩된 호출에 대한) 부모-자식 관계
- 발생한 모든 오류
Call은 Weave 트레이싱 시스템의 근간을 이루며, 디버깅, 분석, 평가를 위한 데이터를 제공합니다.
Call은 OpenTelemetry 데이터 모델의 span과 유사합니다. Call은 다음을 수행할 수 있습니다:
- Trace(동일한 실행 컨텍스트 내 Call들의 모음)에 속할 수 있습니다
- 부모 및 자식 Call을 가질 수 있으며, 트리 구조를 형성합니다
Weave에서 Call을 생성하는 주요 방법은 세 가지가 있습니다.
Weave는 openai, anthropic, cohere, mistral과 같은 주요 LLM 라이브러리에 대한 호출을 자동으로 추적합니다. 프로그램 시작 시점에 weave.init('project_name')만 호출하면 됩니다:import weave
from openai import OpenAI
client = OpenAI()
# Initialize Weave Tracing
weave.init('intro-example')
response = client.chat.completions.create(
model="gpt-4",
messages=[
{
"role": "user",
"content": "How are you?"
}
],
temperature=0.8,
max_tokens=64,
top_p=1,
)
Weave는 openai와 같은 주요 LLM 라이브러리에 대한 호출을 자동으로 추적합니다.import OpenAI from 'openai'
import * as weave from 'weave'
const client = new OpenAI()
// Initialize Weave Tracing
await weave.init('intro-example')
const response = await client.chat.completions.create({
model: 'gpt-4',
messages: [
{
role: 'user',
content: 'How are you?',
},
],
temperature: 0.8,
max_tokens: 64,
top_p: 1,
});
JS / TS 프로젝트에 대한 전체 설정 가이드는 TypeScript SDK: 타사 통합 가이드를 참고하세요.
호출 이후 생성된 메트릭이나 기타 값을 Call 객체의 summary 딕셔너리에 저장할 수 있습니다. 실행 중에 call.summary를 수정하면, 호출이 완료될 때 사용자가 추가한 값이 Weave가 계산한 요약 데이터와 병합됩니다.
하지만 LLM 애플리케이션에는 추적하고 싶은 추가 로직(전처리/후처리, 프롬프트 등)이 포함되는 경우가 자주 있습니다.
Weave에서는 @weave.op 데코레이터를 사용해 이러한 호출을 수동으로 추적할 수 있습니다. 예를 들어:import weave
# Weave 트레이싱 초기화
weave.init('intro-example')
# 함수 데코레이션
@weave.op
def my_function(name: str):
return f"Hello, {name}!"
# 함수 호출 -- Weave가 입력과 출력을 자동으로 추적합니다
print(my_function("World"))
클래스의 메서드도 추적할 수 있습니다.동기 & 비동기 제너레이터 함수 트레이싱
Weave는 깊게 중첩된 패턴을 포함하여 동기/비동기 제너레이터 함수를 모두 트레이싱할 수 있습니다.제너레이터는 값을 지연 평가 방식으로 yield하므로, 제너레이터가 완전히 소비될 때만 출력이 기록됩니다(예: 리스트로 변환하는 경우).
출력이 트레이스에 캡처되도록 하려면 제너레이터를 완전히 소비하십시오(예: list()를 사용).
from typing import Generator
import weave
weave.init("my-project")
# 이 함수는 간단한 동기 제너레이터를 사용합니다.
# Weave는 호출과 그 입력값(`x`)을 트레이스하지만,
# 출력값은 제너레이터가 소비되었을 때만 캡처됩니다(예: `list()`를 통해).
@weave.op
def basic_gen(x: int) -> Generator[int, None, None]:
yield from range(x)
# 제너레이터 파이프라인 안에서 사용하는 일반 동기 함수입니다.
# 이 함수의 호출도 Weave에 의해 별도로 트레이스됩니다.
@weave.op
def inner(x: int) -> int:
return x + 1
# 다른 트레이싱된 함수(`inner`)를 호출하는 동기 제너레이터입니다.
# 각 `yield`된 값은 `inner`에 대한 개별 트레이스 호출에서 나옵니다.
@weave.op
def nested_generator(x: int) -> Generator[int, None, None]:
for i in range(x):
yield inner(i)
# 위 제너레이터를 합성하는 더 복잡한 제너레이터입니다.
# 여기서의 트레이싱은 계층적인 호출 트리를 생성합니다:
# - `deeply_nested_generator` (부모)
# - `nested_generator` (자식)
# - `inner` (손자)
@weave.op
def deeply_nested_generator(x: int) -> Generator[int, None, None]:
for i in range(x):
for j in nested_generator(i):
yield j
# Weave가 출력을 캡처하려면 제너레이터를 *소비*해야 합니다.
# 이는 동기와 비동기 제너레이터 모두에 해당합니다.
res = deeply_nested_generator(4)
list(res) # 모든 중첩 호출과 yield를 트리거하여 트레이싱합니다

Weave에서는 weave.op으로 함수를 래핑하여 이러한 호출을 수동으로 추적할 수 있습니다. 예를 들어:import * as weave from 'weave'
await weave.init('intro-example')
function myFunction(name: string) {
return `Hello, ${name}!`
}
const myFunctionOp = weave.op(myFunction)
래핑을 인라인으로 정의할 수도 있습니다:const myFunctionOp = weave.op((name: string) => `Hello, ${name}!`)
이는 함수뿐 아니라 클래스 메서드에도 동일하게 적용됩니다:class MyClass {
constructor() {
this.myMethod = weave.op(this.myMethod)
}
myMethod(name: string) {
return `Hello, ${name}!`
}
}
경우에 따라 Call 객체 자체에 대한 핸들을 얻는 것이 유용할 수 있습니다. op.call 메서드를 호출하면 결과와 Call 객체를 모두 반환합니다. 예시는 다음과 같습니다:result, call = my_function.call("World")
그런 다음 call을 사용해서 추가 속성을 설정하거나, 업데이트하거나, 가져올 수 있습니다(가장 일반적인 사용 사례는 피드백에 사용할 호출 ID를 가져오는 것입니다).op가 클래스의 메서드인 경우, 인스턴스를 첫 번째 인수로 op에 전달해야 합니다(아래 예시 참고).
# 첫 번째 인수로 `instance`를 전달하는 것에 주의하세요.
print(instance.my_method.call(instance, "World"))
import weave
# Weave Tracing 초기화
weave.init("intro-example")
class MyClass:
# 메서드를 데코레이팅합니다
@weave.op
def my_method(self, name: str):
return f"Hello, {name}!"
instance = MyClass()
# 메서드를 호출하면 Weave가 입력과 출력을 자동으로 추적합니다.
instance.my_method.call(instance, "World")
이 기능은 아직 TypeScript SDK에서 지원되지 않습니다.
호출의 표시 이름을 재정의해야 할 때가 있습니다. 다음 네 가지 방법 중 하나로 설정할 수 있습니다:
- op을 호출하는 시점에 표시 이름을 변경합니다:
result = my_function("World", __weave={"display_name": "My Custom Display Name"})
__weave 딕셔너리를 사용하면 호출 표시 이름이 설정되며, 이는 Op 표시 이름보다 우선합니다.
- 호출마다 표시 이름을 개별적으로 변경합니다.
Op.call 메서드를 사용해 Call 객체를 반환한 다음, Call.set_display_name을 사용해 표시 이름을 설정합니다.
result, call = my_function.call("World")
call.set_display_name("My Custom Display Name")
- 특정 Op에서 생성되는 모든 Call의 표시 이름을 변경합니다:
@weave.op(call_display_name="My Custom Display Name")
def my_function(name: str):
return f"Hello, {name}!"
-
call_display_name는 Call 객체를 입력으로 받아 문자열을 반환하는 함수가 될 수도 있습니다. 함수가 호출될 때 Call 객체는 자동으로 전달되므로, 함수 이름, 호출 입력값, 필드 등을 기반으로 이름을 동적으로 생성하는 데 사용할 수 있습니다.
-
일반적인 사용 사례 중 하나는 함수 이름에 타임스탬프를 덧붙이는 것입니다.
from datetime import datetime
@weave.op(call_display_name=lambda call: f"{call.func_name}__{datetime.now()}")
def func():
return ...
-
.attributes를 사용해 사용자 지정 메타데이터를 기록할 수도 있습니다.
def custom_attribute_name(call):
model = call.attributes["model"]
revision = call.attributes["revision"]
now = call.attributes["date"]
return f"{model}__{revision}__{now}"
@weave.op(call_display_name=custom_attribute_name)
def func():
return ...
with weave.attributes(
{
"model": "finetuned-llama-3.1-8b",
"revision": "v0.1.2",
"date": "2024-08-01",
}
):
func() # 표시 이름은 "finetuned-llama-3.1-8b__v0.1.2__2024-08-01"가 됩니다.
with weave.attributes(
{
"model": "finetuned-gpt-4o",
"revision": "v0.1.3",
"date": "2024-08-02",
}
):
func() # 표시 이름은 "finetuned-gpt-4o__v0.1.3__2024-08-02"가 됩니다.
기술 메모: “Call”은 “Op”에서 생성됩니다. Op는 @weave.op으로 데코레이션된 함수 또는 메서드입니다.
기본적으로 Op의 이름은 함수 이름과 같으며, 해당 Op에서 생성된 Call들은 동일한 표시 이름을 갖습니다. 위 예시는 특정 Op에서 생성되는 모든 Call의 표시 이름을 재정의하는 방법을 보여줍니다. 때때로 사용자는 Op 자체의 이름을 재정의하고 싶어 합니다. 이는 다음 두 가지 방법 중 하나로 수행할 수 있습니다:
- 어떤 Call이 기록되기 전에 Op의
name 속성을 설정합니다.
my_function.name = "My Custom Op Name"
- op 데코레이터에서
name 옵션을 설정합니다.
@weave.op(name="My Custom Op Name)
호출의 기본 이름을 재정의하려면 weave.op()을 호출할 때 callDisplayName 옵션을 사용하세요.const extractDinosOp = weave.op(extractDinos, {
callDisplayName: (input: string) => `Your New Display Name`
});
실행이 완료된 후에도 호출의 표시 이름을 업데이트할 수 있습니다.
기본적으로 병렬 호출은 모두 Weave에서 개별 루트 호출로 표시됩니다. 동일한 상위 op 아래에 올바르게 중첩되도록 하려면 ThreadPoolExecutor를 사용해야 합니다.다음 코드 예시는 ThreadPoolExecutor 사용 방법을 보여줍니다.
첫 번째 함수 func는 x를 받아 x+1을 반환하는 간단한 op입니다. 두 번째 함수 outer는 입력 목록을 받는 또 다른 op입니다.
outer 내부에서 ThreadPoolExecutor와 exc.map(func, inputs)를 사용하면, 각 func 호출이 동일한 상위 트레이스 컨텍스트를 유지합니다.import weave
@weave.op
def func(x):
return x+1
@weave.op
def outer(inputs):
with weave.ThreadPoolExecutor() as exc:
exc.map(func, inputs)
# 사용 중인 Weave 프로젝트 이름으로 업데이트하십시오
client = weave.init('my-weave-project')
outer([1,2,3,4,5])
Weave UI에서는 하나의 상위 호출 아래에 다섯 개의 중첩된 하위 호출이 생성되므로, 값 증가 연산이 병렬로 실행되더라도 완전한 계층형 트레이스를 확인할 수 있습니다.
이 기능은 아직 TypeScript SDK에서 지원되지 않습니다.
API를 직접 사용하여 Call을 수동으로 생성할 수도 있습니다.
Python
TypeScript
HTTP API
import weave
# Weave Tracing 초기화
client = weave.init('intro-example')
def my_function(name: str):
# Call 시작
call = client.create_call(op="my_function", inputs={"name": name})
# ... 함수 코드 ...
# Call 종료
client.finish_call(call, output="Hello, World!")
# 함수 호출
print(my_function("World"))
이 기능은 아직 TypeScript SDK에서 사용할 수 없습니다.
curl -L 'https://trace.wandb.ai/call/start' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d '{
"start": {
"project_id": "string",
"id": "string",
"op_name": "string",
"display_name": "string",
"trace_id": "string",
"parent_id": "string",
"started_at": "2024-09-08T20:07:34.849Z",
"attributes": {},
"inputs": {},
"wb_run_id": "string"
}
}
클래스와 객체 메서드도 추적할 수 있습니다.
weave.op을 사용해 클래스의 임의의 메서드를 추적할 수 있습니다.import weave
# Weave 트레이싱 초기화
weave.init("intro-example")
class MyClass:
# 메서드에 데코레이터 적용
@weave.op
def my_method(self, name: str):
return f"Hello, {name}!"
instance = MyClass()
# 메서드를 호출하면 Weave가 입력과 출력을 자동으로 추적합니다
print(instance.my_method("World"))
클래스 메서드에 데코레이터 적용
인스턴스 메서드를 추적하려면 @weave.op을 사용하세요.class Foo {
@weave.op
async predict(prompt: string) {
return "bar"
}
}
정적 클래스 메서드에 데코레이터 적용
클래스 내 유틸리티 함수를 모니터링하려면 정적 메서드에 @weave.op을 적용하세요.class MathOps {
@weave.op
static square(n: number): number {
return n * n;
}
}
웹 앱
Python
TypeScript
HTTP API
웹 앱에서 호출을 보려면 다음을 수행합니다.
- 프로젝트의 Traces 탭으로 이동합니다.
- 목록에서 확인하려는 호출을 찾습니다.
- 호출을 클릭하여 상세 페이지를 엽니다.
상세 페이지에는 호출의 입력, 출력, 실행 시간(runtime), 그리고 추가 메타데이터가 표시됩니다.
Weave Python SDK를 사용해 호출을 보려면 get_call 메서드를 사용할 수 있습니다.import weave
# 클라이언트 초기화
client = weave.init("your-project-name")
# ID로 특정 호출 가져오기
call = client.get_call("call-uuid-here")
print(call)
import * as weave from 'weave'
// 클라이언트 초기화
const client = await weave.init('intro-example')
// ID로 특정 호출 가져오기
const call = await client.getCall('call-uuid-here')
console.log(call)
서비스 API를 사용해 호출을 보려면 /call/read 엔드포인트로 요청을 보내면 됩니다.curl -L 'https://trace.wandb.ai/call/read' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d '{
"project_id": "string",
"id": "string",
}'
weave.Markdown으로 렌더링된 trace 사용자 정의하기
weave.Markdown을 사용하면 원본 데이터를 유지하면서 trace 정보의 표시 방식을 사용자 정의할 수 있습니다. 이를 통해 입력과 출력을 읽기 쉬운 서식 있는 콘텐츠 블록으로 렌더링하면서, 그 이면의 데이터 구조는 그대로 보존할 수 있습니다.
@weave.op 데코레이터에서 postprocess_inputs와 postprocess_output 함수를 사용하여 trace 데이터를 서식화할 수 있습니다. 다음 코드 예제는 postprocessor를 사용해 Weave에서 호출을 이모지와 더 읽기 쉬운 형식으로 렌더링하는 방법을 보여 줍니다:import weave
def postprocess_inputs(query) -> weave.Markdown:
search_box = f"""
**Search Query:**
``+`
{query}
``+`
"""
return {"search_box": weave.Markdown(search_box),
"query": query}
def postprocess_output(docs) -> weave.Markdown:
formatted_docs = f"""
# {docs[0]["title"]}
{docs[0]["content"]}
[Read more]({docs[0]["url"]})
---
# {docs[1]["title"]}
{docs[1]["content"]}
[Read more]({docs[1]["url"]})
"""
return weave.Markdown(formatted_docs)
@weave.op(
postprocess_inputs=postprocess_inputs,
postprocess_output=postprocess_output,
)
def rag_step(query):
# S&P 500 기업들에 대한 예시 신문 기사
docs = [
{
"title": "OpenAI",
"content": "OpenAI is a company that makes AI models.",
"url": "https://www.openai.com",
},
{
"title": "Google",
"content": "Google is a company that makes search engines.",
"url": "https://www.google.com",
},
]
return docs
if __name__ == "__main__":
weave.init('markdown_renderers')
rag_step("Tell me about OpenAI")
이 기능은 아직 TypeScript SDK에서 사용할 수 없습니다.
다음 스크린샷에서 포매팅되지 않은 출력과 포매팅된 출력의 차이를 비교해서 확인할 수 있습니다.
호출은 생성 후 대부분 변경할 수 없지만, 다음과 같은 몇 가지 수정 작업은 가능합니다:
이러한 수정 작업은 모두 UI에서 호출 상세 페이지로 이동해 수행할 수 있습니다:
Python
TypeScript
HTTP API
콜의 표시 이름을 설정하려면 Call.set_display_name() 메서드를 사용할 수 있습니다.import weave
# 클라이언트 초기화
client = weave.init("your-project-name")
# ID로 특정 콜 가져오기
call = client.get_call("call-uuid-here")
# 콜의 표시 이름 설정
call.set_display_name("My Custom Display Name")
콜의 표시 이름을 설정하려면 client.updateCall을 사용해 콜 ID로 직접 업데이트하세요:import * as weave from 'weave'
// 클라이언트 초기화
const client = await weave.init('your-project-name')
// ID로 콜의 표시 이름 업데이트
await client.updateCall('call-uuid-here', 'My Custom Display Name')
Service API를 사용해 콜의 표시 이름을 설정하려면 /call/update 엔드포인트에 요청을 보내면 됩니다.curl -L 'https://trace.wandb.ai/call/update' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d '{
"project_id": "string",
"call_id": "string",
"display_name": "string",
}'
또한 실행 시 콜의 표시 이름을 설정할 수도 있습니다.
자세한 내용은 피드백 관련 문서를 참고하세요.
Python
TypeScript
HTTP API
Python API를 사용하여 Call을 삭제하려면 Call.delete 메서드를 사용하세요.import weave
# 클라이언트 초기화
client = weave.init("your-project-name")
# ID로 특정 Call 가져오기
call = client.get_call("call-uuid-here")
# Call 삭제
call.delete()
이 기능은 아직 TypeScript SDK에서 지원되지 않습니다.
Service API를 사용하여 Call을 삭제하려면 /calls/delete 엔드포인트로 요청을 보내세요.curl -L 'https://trace.wandb.ai/calls/delete' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d '{
"project_id": "string",
"call_ids": [
"string"
],
}'
Python API를 사용해 여러 개의 Call을 삭제하려면 delete_calls()에 Call ID 목록을 전달합니다.import weave
# 클라이언트 초기화
client = weave.init("my-project")
# 클라이언트에서 모든 Call 가져오기
all_calls = client.get_calls()
# 처음 1000개의 Call 객체 목록 가져오기
first_1000_calls = all_calls[:1000]
# 처음 1000개의 Call ID 목록 가져오기
first_1000_calls_ids = [c.id for c in first_1000_calls]
# ID를 사용해 처음 1000개의 Call 객체 삭제
client.delete_calls(call_ids=first_1000_calls_ids)
이 기능은 아직 TypeScript SDK에서 사용할 수 없습니다.
프로젝트의 /calls 페이지(“Traces” 탭)에는 프로젝트의 모든 Call이 테이블 형태로 표시됩니다. 이 페이지에서 다음 작업을 수행할 수 있습니다:
위에 표시된 내보내기 모달(Export Modal)을 사용하면 데이터를 여러 형식으로 내보낼 수 있으며, 선택한 Call에 대해 동일한 결과를 얻을 수 있는 Python 및 cURL 예제 코드도 함께 확인할 수 있습니다.
가장 쉽게 시작하는 방법은 UI에서 원하는 뷰를 구성한 다음, 생성된 코드 스니펫을 통해 내보내기 API를 더 자세히 살펴보는 것입니다.
Python
TypeScript
HTTP API
Python API를 사용해 Call을 가져오려면 client.get_calls 메서드를 사용할 수 있습니다:import weave
# Initialize the client
client = weave.init("your-project-name")
# Fetch calls
calls = client.get_calls(filter=...)
TypeScript API를 사용해 Call을 가져오려면 client.getCalls 메서드를 사용할 수 있습니다.import * as weave from 'weave'
// Initialize the client
const client = await weave.init('intro-example')
// Fetch calls
const calls = await client.getCalls(filter=...)
가장 강력한 쿼리 계층은 Service API입니다. Service API를 사용해 Call을 가져오려면 /calls/stream_query 엔드포인트로 요청을 보내면 됩니다.curl -L 'https://trace.wandb.ai/calls/stream_query' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d '{
"project_id": "string",
"filter": {
"op_names": [
"string"
],
"input_refs": [
"string"
],
"output_refs": [
"string"
],
"parent_ids": [
"string"
],
"trace_ids": [
"string"
],
"call_ids": [
"string"
],
"trace_roots_only": true,
"wb_user_ids": [
"string"
],
"wb_run_ids": [
"string"
]
},
"limit": 100,
"offset": 0,
"sort_by": [
{
"field": "string",
"direction": "asc"
}
],
"query": {
"$expr": {}
},
"include_costs": true,
"include_feedback": true,
"columns": [
"string"
],
"expand_columns": [
"string"
]
}'
전체 필드 목록은 schema를 참조하세요.
| Property | Type | Description |
|---|
id | string (uuid) | Call의 고유 식별자 |
project_id | string (optional) | 연결된 프로젝트 식별자 |
op_name | string | 연산 이름(참조일 수도 있음) |
display_name | string (optional) | Call에 대한 사용자 친화적인 이름 |
trace_id | string (uuid) | 이 Call이 속한 trace의 식별자 |
parent_id | string (uuid) | 상위 Call의 식별자 |
started_at | datetime | Call이 시작된 시점의 타임스탬프 |
attributes | Dict[str, Any] | Call에 대한 사용자 정의 메타데이터 (실행 중에는 읽기 전용) |
inputs | Dict[str, Any] | Call에 대한 입력 파라미터 |
ended_at | datetime (optional) | Call이 종료된 시점의 타임스탬프 |
exception | string (optional) | Call이 실패한 경우의 에러 메시지 |
output | Any (optional) | Call의 결과 |
summary | Optional[SummaryMap] | 실행 이후 요약 정보. 실행 중에 이를 수정하여 사용자 지정 메트릭을 기록할 수 있습니다. |
wb_user_id | Optional[str] | 연결된 Weights & Biases 사용자 ID |
wb_run_id | Optional[str] | 연결된 Weights & Biases 실행 ID |
deleted_at | datetime (optional) | Call이 삭제된 경우 해당 시점의 타임스탬프 |
위 표는 Weave에서 Call이 가지는 핵심 속성을 정리한 것입니다. 각 속성은 함수 호출을 추적하고 관리하는 데 중요한 역할을 합니다.
id, trace_id, parent_id 필드는 시스템 내에서 Call을 구성하고 서로 연관시키는 데 사용됩니다.
- 시간 정보(
started_at, ended_at)는 성능 분석을 가능하게 합니다.
attributes와 inputs 필드는 Call에 대한 컨텍스트를 제공합니다. attributes는 Call이 시작되면 고정되므로, 호출 전에 weave.attributes로 설정해야 합니다. output과 summary는 결과를 캡처하며, 실행 중에 summary를 업데이트하여 추가 메트릭을 기록할 수 있습니다.
- Weights & Biases와의 통합은
wb_user_id와 wb_run_id를 통해 이뤄집니다.
이와 같은 포괄적인 속성 집합을 통해 프로젝트 전반에 걸쳐 함수 호출을 세밀하게 추적하고 분석할 수 있습니다.
Calculated Fields:
Trace 테이블의 설정, 필터, 정렬 구성을 저장된 뷰 로 저장해 두고, 선호하는 구성을 빠르게 불러올 수 있습니다. UI와 Python SDK에서 저장된 뷰를 설정하고 사용할 수 있습니다. 자세한 내용은 Saved Views를 참고하세요.
Weave를 사용하면 코드의 함수 호출을 트레이싱하고, 해당 호출이 실행된 W&B 실행에 직접 연결할 수 있습니다.
@weave.op()으로 함수를 트레이싱하고 이를 wandb.init() 컨텍스트 내부에서 호출하면, Weave는 자동으로 해당 트레이스를 W&B 실행과 연결합니다.
연결된 실행에 대한 링크는 Traces 테이블에 표시됩니다.
다음 Python 코드는 트레이싱된 op가 wandb.init() 컨텍스트 내에서 실행될 때 W&B
실행에 어떻게 연결되는지를 보여줍니다. 이러한 트레이스는
Weave UI에 표시되며 해당 실행과 연관됩니다.import wandb
import weave
def example_wandb(projname):
# projname을 엔터티와 프로젝트로 분리
entity, project = projname.split("/", 1)
# 트레이싱을 위한 Weave 컨텍스트 초기화
weave.init(projname)
# 트레이싱 가능한 op 정의
@weave.op()
def say(message: str) -> str:
return f"I said: {message}"
# 첫 번째 W&B 실행
with wandb.init(
entity=entity,
project=project,
notes="Experiment 1",
tags=["baseline", "paper1"],
) as run:
say("Hello, world!")
say("How are you!")
run.log({"messages": 2})
# 두 번째 W&B 실행
with wandb.init(
entity=entity,
project=project,
notes="Experiment 2",
tags=["baseline", "paper1"],
) as run:
say("Hello, world from experiment 2!")
say("How are you!")
run.log({"messages": 2})
if __name__ == "__main__":
# 여기를 실제 W&B 사용자 이름/프로젝트로 바꾸세요
example_wandb("your-username/your-project")
이 코드 예제를 사용하려면:
- 터미널에서 다음과 같이 의존성을 설치합니다:
- W&B에 로그인합니다:
- 스크립트에서
your-username/your-project를 실제 W&B 엔터티/프로젝트로 바꿉니다.
- 스크립트를 실행합니다:
python weave_trace_with_wandb.py
- https://weave.wandb.ai에 접속한 후, 프로젝트를 선택합니다.
- Traces 탭에서 트레이스 결과를 확인합니다. 연결된 실행에 대한 링크는 Traces 테이블에 표시됩니다.
이 기능은 아직 TypeScript SDK에서는 사용할 수 없습니다.
기본적으로 Weave는 openai, anthropic, cohere, mistral 같은 일반적인 LLM 라이브러리에 대한 호출을 자동으로 패치하고 추적합니다.
autopatch_settings 인수는 더 이상 사용되지 않습니다. 암시적 패치를 비활성화하려면 implicitly_patch_integrations=False를 사용하고, 통합별로 설정을 구성하려면 patch_openai(settings={...})와 같은 개별 패치 함수를 호출하세요.
모든 자동 패치 비활성화
weave.init(..., implicitly_patch_integrations=False)
특정 통합만 활성화
import weave
weave.init(..., implicitly_patch_integrations=False)
# 그런 다음 원하는 통합만 수동으로 패치합니다
weave.integrations.patch_anthropic()
weave.integrations.patch_cohere()
입력 및 출력 후처리
패치 함수에 설정을 전달하여 입력과 출력(예: PII 데이터)에 대한 처리 방식(후처리)을 사용자 정의할 수 있습니다:import weave.integrations
def redact_inputs(inputs: dict) -> dict:
if "email" in inputs:
inputs["email"] = "[REDACTED]"
return inputs
weave.init(...)
weave.integrations.patch_openai(
settings={
"op_settings": {"postprocess_inputs": redact_inputs}
}
)
TypeScript SDK는 OpenAI와 Anthropic에 대해서만 자동 패치를 지원합니다. OpenAI는 Weave를 import하면 자동으로 패치되며, 추가 설정이 필요하지 않습니다.또한 TypeScript SDK는 다음을 지원하지 않습니다:
- 자동 패치 구성 또는 비활성화
- 입력/출력 후처리
자동 패치가 동작하지 않는 예외적인 경우(ESM, Next.js 같은 번들러)에는 명시적 래핑을 사용하세요:import OpenAI from 'openai'
import * as weave from 'weave'
import { wrapOpenAI } from 'weave'
const client = wrapOpenAI(new OpenAI())
await weave.init('your-team/my-project')
ESM 설정 및 문제 해결에 대한 자세한 내용은 TypeScript SDK 통합 가이드를 참조하세요.
자세한 내용은 PII 데이터와 함께 Weave 사용하기를 참조하세요.
큰 트레이스가 잘리지 않게 하려면 어떻게 하나요?
자세한 내용은 문제 해결 가이드의 트레이스 데이터가 잘립니다 섹션을 참고하세요.
트레이싱을 비활성화하려면 어떻게 해야 하나요?
전체 프로그램에 대해 추적을 무조건 비활성화하려면 환경 변수 WEAVE_DISABLED=true를 설정하면 됩니다.
WEAVE_DISABLED는 함수 정의 시점에 한 번만 읽힙니다. 이 변수는 런타임에 추적을 켜거나 끄는 용도로는 사용할 수 없습니다.
조건에 따라 특정 초기화에 대해서만 트레이싱을 활성화하거나 비활성화하고 싶을 수 있습니다. 이 경우 init 설정에서 disabled 플래그를 사용해 클라이언트를 초기화할 수 있습니다.
import weave
# 클라이언트 초기화
client = weave.init(..., settings={"disabled": True})
이 기능은 아직 TypeScript SDK에서 사용할 수 없습니다.
특정 코드 블록에 대해 조건부로 트레이싱을 비활성화하려면 트레이싱 컨텍스트 관리자를 사용할 수 있습니다. with tracing_disabled()를 사용하면 with 블록 내부에서 실행되는 함수 호출에 대해서만 트레이싱이 수행되지 않습니다. 이 방법은 애플리케이션 코드에서 로깅하지 않을 호출의 범위를 명확히 지정할 때 사용하도록 설계되었습니다.
import weave
from weave.trace.context.call_context import tracing_disabled
client = weave.init('your-team/your-project-name')
@weave.op
def my_op():
...
with tracing_disabled():
my_op()
함수를 정의할 때 추적 동작은 이미 정해지지만, 애플리케이션 로직과 결합하면 실행 시점에 제어하는 데 사용할 수 있습니다. 예를 들어, 컨텍스트 매니저를 조건문으로 감싸서 실행 시점의 값에 따라 추적을 동적으로 활성화하거나 비활성화할 수 있습니다.
if should_trace:
my_op()
else:
with tracing_disabled():
my_op()
일반적으로는 op를 직접 호출합니다:
@weave.op
def my_op():
...
my_op()
하지만 op의 call 메서드를 직접 호출하여 call 객체에 바로 접근할 수도 있습니다.
@weave.op
def my_op():
...
output, call = my_op.call()
여기서부터 call 객체에는 입력, 출력 및 기타 메타데이터를 포함해 호출에 대한 모든 정보가 들어 있습니다.