> ## 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.

# 하위 에이전트 트레이스

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

export const AgentLensBanner = ({href}) => <Tip>
    <strong>This workflow is also available in CoreWeave Agent Lens.</strong> Agent Lens is the Forge experience built for tracing, monitoring, and analyzing AI agents, with automated insights into agent failures and user intents. It uses the same trace data as Weights & Biases Weave, so the traces you already send appear there with nothing to migrate.{' '}
    <a href={href || '/products/agent-lens'}>{href ? 'See how to do this in Agent Lens' : 'Learn about Agent Lens'}</a>.
  </Tip>;

<AgentLensBanner href="/ko/products/agent-lens/tracing/sub-agents" />

이 가이드에서는 W\&B Weave를 사용하여 하위 에이전트를 트레이스하는 방법을 보여줍니다. 이를 통해 위임된 에이전트 호출이 상위 턴과 동일한 트레이스 내에서 중첩된 span으로 나타납니다. 하위 에이전트를 트레이스하면 상위 에이전트가 호출한 전문 에이전트, 그들이 수행한 작업, 최종 답변에 기여한 방식을 포함하여 에이전트의 전체 추론 계층 구조를 확인할 수 있습니다. 이 가이드는 Weave로 멀티 에이전트 시스템을 계측하는 개발자를 위한 것입니다.

하위 에이전트는 턴 내에서 실행되는 위임된 에이전트 호출입니다. 감독 에이전트가 전문 에이전트를 디스패치하는 경우와 같이, 한 에이전트가 다른 에이전트로 작업을 넘길 때 하위 에이전트를 사용하세요.

Weave로 계측하면 하위 에이전트는 상위 턴과 동일한 트레이스 내에서 중첩된 `invoke_agent` OpenTelemetry (OTel) span을 내보냅니다. **Agents** 뷰에서 이 중첩은 이를 트리거한 턴 아래에 하위 에이전트 호출로 렌더링되며, 자체 LLM Call과 도구 Call이 그 아래에 그룹화됩니다.

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

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

```plaintext theme={"system"}
턴 (invoke_agent — 루트 span)
├── LLM Call (chat)              ← 상위 에이전트의 추론
│   └── 서브에이전트 (invoke_agent)  ← 여기서 위임이 이루어집니다
│       ├── LLM Call (chat)      ← 하위 에이전트 자체의 LLM Call
│       └── 도구 Call (execute_tool)
└── LLM Call (chat)              ← 상위 에이전트가 최종 답변을 종합합니다
```

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

```python lines theme={"system"}
sub = weave.start_subagent(
    name="research-specialist",   # 필수: UI에서 이 하위 에이전트를 식별합니다.
    model="gpt-4o",               # 선택: 비어 있으면 상위 대화의 모델을 기본값으로 사용합니다.
)
```

`weave.start_subagent`는 OTel 컨텍스트에서 현재 활성 상태인 span의 하위 span이 자동으로 되는 `invoke_agent` span을 생성합니다. 일반적으로 상위 span은 상위 turn 또는 위임을 트리거한 LLM Call입니다. OTel 컨텍스트 전파가 상위-하위 관계를 처리하므로 명시적으로 위임할 필요가 없습니다.

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

다음 예시는 요청을 받아 Wikipedia 검색 도구로 답을 찾는 조사 전문 하위 에이전트에 위임하는 감독 에이전트를 실행합니다.

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

이 예시에서는 에이전트 간 트레이스에 집중하기 위해 라우팅 로직을 의도적으로 생략했습니다.

```python lines highlight="4,10,16,22,30" theme={"system"}
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 Call: 작업을 위임할 전문 에이전트를 결정합니다.
        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)

        # 감독 에이전트의 턴으로 돌아와 최종 답변을 종합합니다.
        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** 뷰에서 하위 에이전트는 턴 내부에 중첩된 `invoke_agent` 블록으로 표시되며, 자체 LLM Call과 도구 Call이 그 아래에 그룹화됩니다. 감독 에이전트의 직접 LLM Call은 하위 에이전트와 동일한 계층에 유지됩니다.

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

다음 예시는 단일 요청을 처리하기 위해 동일한 부모를 가진 세 하위 에이전트에 순서대로 작업을 위임하는 콘텐츠 파이프라인 에이전트를 실행합니다. `researcher`는 사실을 수집하고, `writer`는 게시물 초안을 작성하며, `reviewer`는 최종 출력을 다듬습니다.

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

```python lines highlight="1,5,11,15,22" theme={"system"}
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:

        # 조사 담당 하위 에이전트: 사실을 수집합니다.
        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."

        # 작성 담당 하위 에이전트: 게시글 초안을 작성합니다.
        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)

        # 검토 담당 하위 에이전트: 초안을 다듬습니다.
        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** 뷰에서 턴에는 동일한 부모를 공유하는 세 개의 하위 에이전트 호출이 포함되어 있으며, 각 호출 아래에는 해당 LLM Call이 중첩되어 있고, `researcher`에는 도구 Call이 포함되어 있습니다. 하위 에이전트 중 어느 것도 다른 하위 에이전트의 자식이 아닙니다.

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

하위 에이전트는 자체적으로 다른 하위 에이전트에게 위임할 수 있습니다. 각 `start_subagent` 호출은 OTel 컨텍스트에서 현재 활성인 span 아래에 중첩됩니다.

```python lines highlight="1,2,4,5,11,16" theme={"system"}
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)
```

이 예시는 턴 아래에 3단계의 중첩 구조를 생성합니다.

```plaintext theme={"system"}
턴 (invoke_agent)
└── research-coordinator (invoke_agent)
    ├── anthropic-researcher (invoke_agent)
    │   ├── 채팅
    │   └── anthropic-summarizer (invoke_agent)   ← anthropic-researcher 내부에 중첩됨
    │       └── 채팅
    └── openai-researcher (invoke_agent)          ← anthropic-researcher와 형제 관계
        └── 채팅
```

**Agents** 뷰에서 `research-coordinator`는 턴의 하위 에이전트로 표시되고, `anthropic-researcher`와 `openai-researcher`는 coordinator 아래의 sibling으로 표시되며, `anthropic-summarizer`는 `anthropic-researcher`의 하위 에이전트로 표시됩니다.


## Related topics

- [에이전트 트레이스하기](/ko/products/wandb/weave/guides/tracking/trace-agents.md)
