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

# 하위 에이전트 트레이스

> Weave의 하위 에이전트 span을 사용하여 하위 에이전트 위임을 추적하고 중첩된 에이전트 호출을 확인하세요.

이 가이드에서는 W\&B Weave를 사용해 하위 에이전트를 트레이스하여, 위임된 에이전트 호출이 상위 turn과 동일한 트레이스 내에 중첩된 span으로 표시되도록 하는 방법을 설명합니다. 하위 에이전트를 트레이싱하면 부모가 어떤 전문 에이전트를 호출했는지, 각 에이전트가 무엇을 했는지, 그리고 최종 응답에 어떻게 기여했는지를 포함해 에이전트 추론의 전체 계층 구조를 확인할 수 있습니다. 이 가이드는 Weave로 멀티 에이전트 시스템을 계측하는 개발자를 위한 것입니다.

하위 에이전트는 turn 내부에서 실행되는 위임된 에이전트 호출입니다. 한 에이전트가 다른 에이전트에 작업을 넘길 때, 예를 들어 감독 에이전트가 전문 에이전트에 작업을 할당하는 경우 하위 에이전트를 사용하세요.

Weave로 이를 계측하면 하위 에이전트는 상위 turn과 동일한 트레이스 내에 중첩된 `invoke_agent` OpenTelemetry (OTel) span을 생성합니다. **Agents** 뷰에서는 이 중첩 구조가 이를 트리거한 turn 아래의 하위 에이전트 호출로 렌더링되며, 그 아래에 해당 하위 에이전트의 LLM Call과 도구 Call이 그룹화되어 표시됩니다.

<div id="sub-agent-data-model">
  ## 하위 에이전트 데이터 모델
</div>

코드에 트레이싱을 계측하기 전에 Weave가 트레이스에서 하위 에이전트를 어떻게 표현하는지 이해해 두면 도움이 됩니다. `weave.start_subagent` span은 OTel `invoke_agent` span에 매핑되며, 상위 turn과 동일한 오퍼레이션 이름을 생성합니다. Weave는 트레이스의 부모-자식 관계를 통해 이 둘을 구분합니다:

```plaintext theme={null}
Turn (invoke_agent — root span)
├── LLM call (chat)              ← 상위 에이전트의 추론
│   └── SubAgent (invoke_agent)  ← 여기서 위임 발생
│       ├── LLM call (chat)      ← 하위 에이전트의 LLM Call
│       └── 도구 Call (execute_tool)
└── LLM call (chat)              ← 상위 에이전트가 최종 답변 합성
```

하위 에이전트는 현재 활성 대화의 `conversation_id`를 상속하므로 **Agents** 뷰에서 나머지 대화와 함께 그룹화됩니다.

```python lines theme={null}
sub = weave.start_subagent(
    name="research-specialist",   # Required: identifies this sub-agent in the UI.
    model="gpt-4o",               # Optional: 비어 있으면 상위 대화의 모델을 사용합니다.
)
```

`weave.start_subagent`는 `invoke_agent` span을 생성하며, 이 span은 OTel 컨텍스트에서 현재 활성화된 span의 자식으로 자동 연결됩니다. 일반적으로 상위 turn 또는 위임을 트리거한 LLM Call의 자식이 됩니다. OTel 컨텍스트 전파가 이러한 부모-자식 관계를 처리하므로 명시적으로 위임을 지정할 필요는 없습니다.

<div id="trace-a-single-sub-agent">
  ## 단일 하위 에이전트 트레이스하기
</div>

다음 예시에서는 요청을 받아, 답을 찾기 위해 Wikipedia 검색 도구를 사용하는 리서치 전문 하위 에이전트에 작업을 위임하는 supervisor 에이전트를 실행합니다.

Weave는 대화를 `weave.start_conversation`으로 감싸고 이어서 `conversation.start_turn`을 사용해 전체 계층 구조를 캡처합니다. 그런 다음 Weave는 specialist의 `weave.start_subagent` 블록을 사용해 하위 에이전트 트레이스를 캡처하고, 각 LLM Call과 도구 실행을 하위 span으로 기록합니다.

이 예시에서는 에이전트 간 Tracing에 집중할 수 있도록 라우팅 로직을 의도적으로 생략했습니다.

```python lines highlight="4,10,16,22,30" theme={null}
import weave
from weave.conversation import Message, Usage

weave.init("[YOUR-TEAM]/[YOUR-PROJECT]")

with weave.start_conversation(agent_name="supervisor") as conversation:
    with conversation.start_turn(user_message="Research the founders of Anthropic.") as turn:

        # 슈퍼바이저 LLM 호출: 어떤 전문가에게 위임할지 결정합니다.
        with weave.start_llm(model="gpt-4o", provider_name="openai") as llm:
            llm.input_messages = [Message(role="user", content="Research the founders of Anthropic.")]
            llm.output("Delegating to the research specialist.")
            llm.usage = Usage(input_tokens=80, output_tokens=10)

        # 리서치 전문가에게 하위 에이전트로 위임합니다.
        with weave.start_subagent(name="research-specialist", model="gpt-4o") as sub:
            with sub.llm(model="gpt-4o", provider_name="openai") as sub_llm:
                sub_llm.input_messages = [Message(role="user", content="Find founders of Anthropic.")]
                sub_llm.output("I should search for this.")
                sub_llm.usage = Usage(input_tokens=120, output_tokens=15)

                with weave.start_tool(name="wikipedia_search", arguments='{"query":"Anthropic"}') as tool:
                    tool.result = "Anthropic was founded by Dario and Daniela Amodei in 2021."

            with sub.llm(model="gpt-4o", provider_name="openai") as sub_llm:
                sub_llm.output("Anthropic was founded by Dario and Daniela Amodei in 2021.")
                sub_llm.usage = Usage(input_tokens=200, output_tokens=25)

        # 슈퍼바이저 turn으로 돌아와 최종 답변을 종합합니다.
        with weave.start_llm(model="gpt-4o", provider_name="openai") as llm:
            llm.output("Anthropic was founded by Dario and Daniela Amodei in 2021.")
            llm.usage = Usage(input_tokens=300, output_tokens=20)
```

**Agents** 뷰에서 하위 에이전트는 turn 내부에 중첩된 `invoke_agent` 블록으로 표시되며, 그 아래에 자체 LLM Calls와 도구 Calls가 함께 그룹화되어 나타납니다. supervisor의 직접 LLM Calls는 하위 에이전트와 같은 계층에 그대로 표시됩니다.

<div id="trace-multiple-sub-agents">
  ## 여러 하위 에이전트 트레이스
</div>

다음 예시에서는 콘텐츠 파이프라인 에이전트가 단일 요청을 처리할 때, 사실을 수집하는 `researcher`, 게시물 초안을 작성하는 `writer`, 최종 출력을 다듬는 `reviewer`의 세 하위 에이전트에 순차적으로 작업을 위임합니다.

Weave는 각 하위 에이전트마다 별도의 `weave.start_subagent` 블록을 열어, 세 하위 에이전트를 모두 동일한 turn 아래의 형제 관계로 캡처합니다. 각 하위 에이전트는 활성 turn의 OTel 컨텍스트를 상속하므로, 서로 아래에 중첩되는 대신 turn 아래에 중첩된 동일 레벨의 `invoke_agent` span으로 표시됩니다.

```python lines highlight="1,5,11,15,22" theme={null}
with weave.start_conversation(agent_name="content-pipeline") as conversation:
    with conversation.start_turn(user_message="Write a short blog post about Anthropic.") as turn:

        # Researcher 하위 에이전트: 사실 수집.
        with weave.start_subagent(name="researcher", model="gpt-4o") as researcher:
            with researcher.llm(model="gpt-4o", provider_name="openai") as sub_llm:
                sub_llm.input_messages = [Message(role="user", content="Find key facts about Anthropic.")]
                sub_llm.output("I should search Wikipedia.")
                sub_llm.usage = Usage(input_tokens=80, output_tokens=15)

                with weave.start_tool(name="wikipedia_search", arguments='{"query":"Anthropic"}') as tool:
                    tool.result = "Anthropic was founded by Dario and Daniela Amodei in 2021."

        # Writer 하위 에이전트: 게시물 초안 작성.
        with weave.start_subagent(name="writer", model="gpt-4o") as writer:
            with writer.llm(model="gpt-4o", provider_name="openai") as sub_llm:
                sub_llm.input_messages = [Message(role="user", content="Draft a post using the research.")]
                sub_llm.output("Anthropic, founded in 2021 by Dario and Daniela Amodei, builds AI safety research...")
                sub_llm.usage = Usage(input_tokens=180, output_tokens=120)

        # Reviewer 하위 에이전트: 초안 다듬기.
        with weave.start_subagent(name="reviewer", model="gpt-4o") as reviewer:
            with reviewer.llm(model="gpt-4o", provider_name="openai") as sub_llm:
                sub_llm.input_messages = [Message(role="user", content="Review and tighten the draft.")]
                sub_llm.output("Final post: Anthropic, founded in 2021 by Dario and Daniela Amodei, builds AI safety research...")
                sub_llm.usage = Usage(input_tokens=200, output_tokens=140)
```

**Agents** 뷰에서는 turn에 서로 형제 관계인 세 개의 하위 에이전트 호출이 있으며, 각각 그 아래에 자체 LLM Call이 중첩되어 있고 `researcher`에는 도구 Call도 포함됩니다. 어느 하위 에이전트도 다른 하위 에이전트의 자식이 아닙니다.

<div id="trace-nested-sub-agents">
  ## 중첩된 하위 에이전트 트레이스
</div>

하위 에이전트는 다시 다른 하위 에이전트에 작업을 위임할 수 있습니다. 각 `start_subagent` 호출은 OTel 컨텍스트에서 현재 활성 상태인 span 아래에 중첩됩니다.

```python lines highlight="1,2,4,5,11,16" theme={null}
with weave.start_conversation(agent_name="orchestrator") as conversation:
    with conversation.start_turn(user_message="Compare Anthropic and OpenAI.") as turn:

        with weave.start_subagent(name="research-coordinator") as coordinator:
            with weave.start_subagent(name="anthropic-researcher") as r1:
                with r1.llm(model="gpt-4o", provider_name="openai") as sub_llm:
                    sub_llm.output("Anthropic facts...")
                    sub_llm.usage = Usage(input_tokens=120, output_tokens=30)

                # 중첩: 연구자가 자체 요약 하위 에이전트에 작업을 위임합니다.
                with weave.start_subagent(name="anthropic-summarizer") as summarizer:
                    with summarizer.llm(model="gpt-4o", provider_name="openai") as sub_llm:
                        sub_llm.output("Anthropic summary: ...")
                        sub_llm.usage = Usage(input_tokens=80, output_tokens=20)

            with weave.start_subagent(name="openai-researcher") as r2:
                with r2.llm(model="gpt-4o", provider_name="openai") as sub_llm:
                    sub_llm.output("OpenAI facts...")
                    sub_llm.usage = Usage(input_tokens=120, output_tokens=30)
```

이 예시를 실행하면 turn 아래에 3단계의 중첩 구조가 생성됩니다:

```plaintext theme={null}
turn (invoke_agent)
└── research-coordinator (invoke_agent)
    ├── anthropic-researcher (invoke_agent)
    │   ├── chat
    │   └── anthropic-summarizer (invoke_agent)   ← anthropic-researcher 내부에 중첩됨
    │       └── chat
    └── openai-researcher (invoke_agent)          ← anthropic-researcher의 형제 노드
        └── chat
```

Agents 뷰에서는 `research-coordinator`가 turn의 하위 에이전트로 표시되고, `anthropic-researcher`와 `openai-researcher`는 coordinator 아래에서 같은 수준으로 표시되며, `anthropic-summarizer`는 `anthropic-researcher`의 하위 에이전트로 표시됩니다.
