이 페이지에서는 @weave.op 데코레이터로 트레이싱된 함수의 속성을 설명합니다. Weave agent SDK로 에이전트를 계측하는 경우에는 대신 에이전트 span(Turn, LLM, Tool, SubAgent)에 속성과 이벤트를 설정하세요. 자세한 내용은 에이전트 span에 속성과 이벤트 설정을 참조하세요.
Weave의 속성을 사용하면 트레이스와 평가에 맞춤형 메타데이터를 추가할 수 있습니다. 이 메타데이터에는 환경 이름, 모델 버전, 실험 ID, 사용자 ID, 기타 컨텍스트 정보 등이 포함될 수 있으며, 이를 통해 Weave 데이터를 정리하고 필터링하고 분석할 수 있습니다.
다음 기준으로 트레이스를 그룹화하거나 필터링하는 데 속성이 특히 유용합니다:
Weave는 속성을 추가하는 두 가지 방법을 제공합니다:
- 호출별 속성:
weave.attributes() 컨텍스트 관리자를 사용해 특정 오퍼레이션이나 코드 블록에 메타데이터를 추가합니다.
- 전역 속성: 초기화 시
global_attributes 필드를 사용해 프로젝트의 모든 트레이스와 평가에 적용되는 속성을 설정합니다.
트레이스와 평가 중 로깅된 모든 속성은 UI에서 볼 수 있습니다. 그런 다음 이를 사용해 데이터를 필터링하고 그룹화할 수 있습니다.
이 가이드는 트레이스와 평가를 맞춤형 메타데이터로 더 풍부하게 만들고자 하는 Weave 사용자을 위한 것입니다. 이 가이드에서는 개별 호출별 속성에 속성을 추가하는 방법, 초기화 시 프로젝트 전체의 기본값을 설정하는 방법, 두 접근 방식을 함께 사용하는 방법, 그리고 실행 중 현재 속성 집합을 조회하는 방법을 다룹니다.
weave.attributes() 컨텍스트 관리자를 사용하면 특정 트레이스 오퍼레이션에 메타데이터를 추가할 수 있습니다. 이를 사용해 특정 함수 Call이나 evaluation run에 컨텍스트 정보를 태그하세요.
Call이 시작되면 call.attributes를 수정할 수 없습니다. op를 호출하기 전에 이
컨텍스트 관리자를 사용해 필요한 메타데이터를 설정하세요.
import weave
weave.init("[TEAM-NAME]/[PROJECT-NAME]")
@weave.op
def my_function(name: str):
return f"Hello, {name}!"
# 특정 Call에 속성 추가
with weave.attributes({'env': 'production', 'user_id': '12345'}):
result = my_function("World")
import {init, op, withAttributes} from 'weave';
async function main() {
await init('your-team/attribute-example');
const myFunction = op(async function myFunction(name: string) {
return `Hello, ${name}!`;
});
// 특정 Call에 속성 추가
const result = await withAttributes(
{env: 'production', user_id: '12345'},
async () => myFunction('World')
);
console.log('Result:', result);
}
main().catch(console.error);
이 함수는 컨텍스트 관리자 블록(Python) 또는 callback 함수(TypeScript) 안의 모든 트레이스 오퍼레이션에 속성을 연결합니다.
weave.attributes() 컨텍스트를 중첩해서 사용할 수도 있습니다. 동일한 키가 있으면 내부 컨텍스트가 외부 컨텍스트를 재정의합니다.
@weave.op
def process_data(data: str):
return data.upper()
# 외부 컨텍스트
with weave.attributes({
"env": "production",
"version": "1.0.0",
"region": "us-west-2"
}):
process_data("hello") # 세 가지 속성이 모두 적용됨
# 내부 컨텍스트가 'version'을 재정의
with weave.attributes({
"version": "1.1.0",
"experiment": "exp-456"
}):
process_data("world") # env='production', version='1.1.0', region='us-west-2', experiment='exp-456'가 적용됨
import {init, op, withAttributes} from 'weave';
async function main() {
await init('your-team/attribute-example');
const processData = op(async function processData(data: string) {
return data.toUpperCase();
});
// 외부 컨텍스트
await withAttributes(
{
env: 'production',
version: '1.0.0',
region: 'us-west-2'
},
async () => {
await processData('hello'); // 세 가지 속성이 모두 적용됨
// 내부 컨텍스트가 'version'을 재정의
await withAttributes(
{
version: '1.1.0',
experiment: 'exp-456'
},
async () => {
await processData('world'); // env='production', version='1.1.0', region='us-west-2', experiment='exp-456'가 적용됨
}
);
}
);
}
main().catch(console.error);
Weave를 초기화할 때 전역 속성을 설정하면 프로젝트의 모든 트레이스와 평가에 자동으로 적용됩니다. 이는 환경, 배포 버전, 팀 정보처럼 프로젝트 전반에서 사용하는 메타데이터를 전달할 때 유용합니다.
import weave
weave.init(
"my-project",
global_attributes={
"env": "production",
"app_version": "2.1.0",
"region": "us-west-2",
"team": "ml-platform"
}
)
# 이제 global_attributes 딕셔너리에 지정한 속성이 이후의 모든 오퍼레이션에 적용됩니다
@weave.op
def my_function():
return "Hello"
my_function() # 모든 전역 속성이 자동으로 적용됩니다
# 평가에도 전역 속성이 적용됩니다
evaluation = weave.Evaluation(dataset=examples, scorers=[scorer])
asyncio.run(evaluation.evaluate(model)) # 모든 전역 속성이 적용됩니다
import {init, op, withAttributes} from 'weave';
async function main() {
await init('your-team/attribute-example', {
globalAttributes: {
env: 'production',
app_version: '2.1.0',
region: 'us-west-2',
team: 'ml-platform'
}
});
// 이제 globalAttributes 객체에 지정한 속성이 이후의 모든 오퍼레이션에 적용됩니다
const myFunction = op(async function myFunction() {
return 'Hello';
});
const result = await myFunction(); // 모든 전역 속성이 자동으로 적용됩니다
console.log('Result:', result);
}
main().catch(console.error);
전역 속성과 호출별 속성을 함께 사용할 수 있습니다. 동일한 키를 가진 호출별 속성은 전역 속성을 재정의합니다.
import weave
# 전역 속성 설정
weave.init(
"my-project",
global_attributes={
"env": "production",
"app_version": "2.1.0"
}
)
@weave.op
def process(data: str):
return data
# 이 호출에는 env='production', app_version='2.1.0'가 적용됩니다
process("test1")
# 이 호출에는 env='staging', app_version='2.1.0', experiment='A'가 적용됩니다
with weave.attributes({'env': 'staging', 'experiment': 'A'}):
process("test2")
import {init, op, withAttributes} from 'weave';
async function main() {
// 전역 속성 설정
await init('your-team/attribute-example', {
globalAttributes: {
env: 'production',
app_version: '2.1.0'
}
});
const process = op(async function process(data: string) {
return data;
});
// 이 호출에는 env='production', app_version='2.1.0'가 적용됩니다
await process('test1');
// 이 호출에는 env='staging', app_version='2.1.0', experiment='A'가 적용됩니다
await withAttributes(
{env: 'staging', experiment: 'A'},
async () => process('test2')
);
}
main().catch(console.error);
런타임에는 현재 Call에 적용된 속성을 확인할 수 있습니다. 이는 Weave가 어떤 메타데이터를 연결하는지 디버깅하거나, 코드가 바깥쪽 호출자가 설정한 컨텍스트 정보를 기준으로 분기해야 할 때 유용합니다.
다음 예시에서는 Weave 데코레이터로 process_data 함수를 로깅하도록 설정하고, 로깅할 속성을 구성한 뒤 실행 중에 이를 반환합니다.import weave
weave.init("your-team/your-project")
@weave.op
def process_data(data: str):
# op 내부에서 현재 call 조회
call = weave.get_current_call()
if call:
print(f"Attributes: {call.attributes}")
return data.upper()
# 속성을 설정하고 함수를 실행
with weave.attributes({
"env": "production",
"version": "1.0.0",
"region": "us-west-2"
}):
process_data("hello")
with weave.attributes({
"version": "1.1.0",
"experiment": "exp-456"
}):
process_data("world")
출력은 다음과 같습니다.Attributes: {'env': 'production', 'version': '1.0.0', 'region': 'us-west-2'}
Attributes: {'env': 'production', 'version': '1.1.0', 'region': 'us-west-2', 'experiment': 'exp-456'}
weave.get_current_call()은 @weave.op로 데코레이팅된 함수 내부에서만 작동합니다. op 외부에서는 None을 반환합니다.
Weave TypeScript SDK에서는 client.getCurrentAttributes()를 사용해 현재 속성을 조회할 수 있습니다. Weave Python SDK와 달리 TypeScript에서는 op 내부뿐 아니라 withAttributes() 컨텍스트 내에서도 속성에 액세스할 수 있습니다.import * as weave from 'weave';
import { withAttributes } from 'weave';
async function main() {
const client = await weave.init('your-team/your-project');
const processData = weave.op(async function processData(data: string) {
// op 내부에서도 속성에 액세스할 수 있습니다
const attrs = client.getCurrentAttributes();
console.log('Attributes inside op:', attrs);
return data.toUpperCase();
});
// 속성을 설정하고 함수를 실행
await withAttributes(
{
env: 'production',
version: '1.0.0',
region: 'us-west-2'
},
async () => {
// 컨텍스트 내 어디서든 속성을 조회
console.log('Current attributes:', client.getCurrentAttributes());
await processData('hello');
await withAttributes(
{
version: '1.1.0',
experiment: 'exp-456'
},
async () => {
console.log('Nested attributes:', client.getCurrentAttributes());
await processData('world');
}
);
}
);
}
main().catch(console.error);
출력은 다음과 같습니다.Current attributes: { env: 'production', version: '1.0.0', region: 'us-west-2' }
Attributes inside op: { env: 'production', version: '1.0.0', region: 'us-west-2' }
Nested attributes: { env: 'production', version: '1.1.0', region: 'us-west-2', experiment: 'exp-456' }
Attributes inside op: { env: 'production', version: '1.1.0', region: 'us-west-2', experiment: 'exp-456' }