> ## Documentation Index
> Fetch the complete documentation index at: https://docs.coreweave.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 중첩 함수 트레이스하기

> W&B 트레이싱으로 깊게 중첩된 Call 구조를 추적하는 방법을 알아보세요

이 튜토리얼에서는 Weave에서 중첩 함수를 트레이스하여 LLM 기반 애플리케이션의 전체 실행 흐름을 하위 함수와 부모-자식 관계까지 포함해 모니터링하는 방법을 설명합니다. 튜토리얼을 마치면 Weave **Traces** 페이지에서 중첩된 트레이스를 캡처하고 시각화하며, 메타데이터를 추가할 수 있습니다.

LLM 기반 애플리케이션에는 모니터링이 필요한 여러 LLM Call과 추가 데이터 처리, 검증 로직이 포함될 수 있습니다. Weave에서는 `@weave.op()` 데코레이터(Python)를 사용하거나 `weave.op()`으로 래핑(TypeScript)하여 이러한 중첩 함수와 부모-자식 관계를 추적할 수 있습니다.

애플리케이션의 전체 실행 흐름을 캡처하려면 함수와 하위 함수에 최대한 세분화하여 데코레이터를 적용하세요. 그러면 애플리케이션의 동작을 더 잘 파악하고 원하는 방향으로 개선할 수 있습니다.

<h2 id="trace-nested-functions">
  중첩 함수 트레이스
</h2>

이 섹션에서는 함수와 그 안에 중첩된 하위 함수를 트레이스하는 예시를 단계별로 살펴봅니다. 다음 코드는 [퀵스타트 예시](/ko/products/wandb/weave/quickstart)를 확장한 것으로, LLM이 반환한 항목의 개수를 세고 이를 상위 수준 함수로 래핑하는 로직을 추가합니다. 또한 `weave.op()`를 사용하여 모든 함수와 각 함수의 호출 순서, 부모-자식 관계를 트레이스합니다.

<Tabs>
  <Tab title="Python">
    ```python {1,7,26,32,42} theme={"system"}
    import weave
    import json
    from openai import OpenAI

    client = OpenAI()

    @weave.op()
    def extract_dinos(sentence: str) -> dict:
        response = client.chat.completions.create(
            model="gpt-4o",
            messages=[
                {
                    "role": "system",
                    "content": """Extract any dinosaur `name`, their `common_name`, \
    names and whether its `diet` is a herbivore or carnivore, in JSON format."""
                },
                {
                    "role": "user",
                    "content": sentence
                }
                ],
                response_format={ "type": "json_object" }
            )
        return response.choices[0].message.content

    @weave.op()
    def count_dinos(dino_data: dict) -> int:
        # 반환된 목록의 항목 수를 셉니다
        k = list(dino_data.keys())[0]
        return len(dino_data[k])

    @weave.op()
    def dino_tracker(sentence: str) -> dict:
        # LLM을 사용해 공룡을 추출합니다
        dino_data = extract_dinos(sentence)

        # 반환된 공룡 수를 셉니다
        dino_data = json.loads(dino_data)
        n_dinos = count_dinos(dino_data)
        return {"n_dinosaurs": n_dinos, "dinosaurs": dino_data}

    weave.init('jurassic-park')

    sentence = """I watched as a Tyrannosaurus rex (T. rex) chased after a Triceratops (Trike), \
    both carnivore and herbivore locked in an ancient dance. Meanwhile, a gentle giant \
    Brachiosaurus (Brachi) calmly munched on treetops, blissfully unaware of the chaos below."""

    result = dino_tracker(sentence)
    print(result)
    ```

    **중첩 함수**

    위 코드를 실행하면 **Traces** 페이지에 두 중첩 함수(`extract_dinos`, `count_dinos`)의 입력과 출력은 물론, 자동으로 로깅된 OpenAI 트레이스도 표시됩니다.

    <img src="https://mintcdn.com/coreweave-dbfa0e8d/3Dv_sw2eg8feUJlx/products/wandb/weave/_media/tutorial_tracing_2_nested_dinos.png?fit=max&auto=format&n=3Dv_sw2eg8feUJlx&q=85&s=7a5cd8f7a6a7e372a8cc1e279fcbad2d" alt="가운데의 트레이스 트리 패널과 선택한 Call의 세부 정보 패널이 표시된 중첩 Weave Traces 페이지" width="1354" height="1334" data-path="products/wandb/weave/_media/tutorial_tracing_2_nested_dinos.png" />
  </Tab>

  <Tab title="TypeScript">
    ```typescript twoslash theme={"system"}
    // @noErrors
    import OpenAI from 'openai';
    import * as weave from 'weave';

    const openai = new OpenAI();

    const extractDinos = weave.op(async (sentence: string) => {
      const response = await openai.chat.completions.create({
        model: 'gpt-4o',
        messages: [
          {
            role: 'system',
            content:
              'Extract any dinosaur `name`, their `common_name`, names and whether its `diet` is a herbivore or carnivore, in JSON format.',
          },
          {role: 'user', content: sentence},
        ],
        response_format: {type: 'json_object'},
      });
      return response.choices[0].message.content;
    });

    const countDinos = weave.op(async (dinoData: string) => {
      const parsed = JSON.parse(dinoData);
      return Object.keys(parsed).length;
    });

    const dinoTracker = weave.op(async (sentence: string) => {
      const dinoData = await extractDinos(sentence);
      const nDinos = await countDinos(dinoData);
      return {nDinos, dinoData};
    });

    async function main() {
      await weave.init('jurassic-park');

      const sentence = `I watched as a Tyrannosaurus rex (T. rex) chased after a Triceratops (Trike),
            both carnivore and herbivore locked in an ancient dance. Meanwhile, a gentle giant
            Brachiosaurus (Brachi) calmly munched on treetops, blissfully unaware of the chaos below.`;

      const result = await dinoTracker(sentence);
      console.log(result);
    }

    main();

    ```

    **중첩 함수**

    위 코드를 실행하면 **Traces** 페이지에 두 중첩 함수(`extract_dinos`, `count_dinos`)의 입력과 출력은 물론, 자동으로 로깅된 OpenAI 트레이스도 표시됩니다.

    <img src="https://mintcdn.com/coreweave-dbfa0e8d/3Dv_sw2eg8feUJlx/products/wandb/weave/_media/tutorial_tracing_2_nested_dinos.png?fit=max&auto=format&n=3Dv_sw2eg8feUJlx&q=85&s=7a5cd8f7a6a7e372a8cc1e279fcbad2d" alt="가운데의 트레이스 트리 패널과 선택한 Call의 세부 정보 패널이 표시된 중첩 Weave Traces 페이지" width="1354" height="1334" data-path="products/wandb/weave/_media/tutorial_tracing_2_nested_dinos.png" />
  </Tab>
</Tabs>

코드를 실행하면 Weave에 각 함수 호출과 호출 간의 관계를 모두 캡처한 중첩 트레이스가 생성됩니다.

<h2 id="track-metadata">
  메타데이터 추적
</h2>

이제 Weave가 중첩 함수를 트레이스하므로, 사용자나 환경 같은 run 관련 컨텍스트를 추가해 트레이스를 더 풍부하게 만들 수 있습니다. 메타데이터를 추적하려면 `weave.attributes` 컨텍스트 관리자를 사용하고, 호출 시점에 추적할 메타데이터를 딕셔너리로 전달하세요.

이전 예시를 이어서 살펴보겠습니다.

<Tabs>
  <Tab title="Python">
    ```python lines {1,10-11} theme={"system"}
    import weave

    weave.init('jurassic-park')

    sentence = """I watched as a Tyrannosaurus rex (T. rex) chased after a Triceratops (Trike), \
    both carnivore and herbivore locked in an ancient dance. Meanwhile, a gentle giant \
    Brachiosaurus (Brachi) calmly munched on treetops, blissfully unaware of the chaos below."""

    # 앞에서 정의한 함수와 함께 메타데이터 추적
    with weave.attributes({'user_id': 'lukas', 'env': 'production'}):
        result = dino_tracker(sentence)
    ```
  </Tab>

  <Tab title="TypeScript">
    ```plaintext theme={"system"}
    This feature is not available in TypeScript yet.
    ```
  </Tab>
</Tabs>

<Note>
  사용자 ID나 코드의 실행 환경(개발, 스테이징, 프로덕션) 같은 메타데이터는 런타임에 추적하세요.

  system 프롬프트 같은 시스템 설정을 추적하려면 [Weave Models](/ko/products/wandb/weave/guides/core-types/models)를 사용하세요.
</Note>

속성 사용에 대한 자세한 내용은 [속성 정의 및 로깅](/ko/products/wandb/weave/guides/tools/attributes)을 참조하세요.

<h2 id="whats-next">
  다음 단계
</h2>

* [App Versioning 튜토리얼](/ko/products/wandb/weave/tutorial-weave_models)을 따라 즉석에서 수행한 프롬프트, 모델, 애플리케이션 변경 사항을 캡처하고 버전별로 관리하며 체계적으로 정리해 보세요.
