
백그라운드에서 서브에이전트 (Subagents) 실행하기
요약
기존의 인라인 서브에이전트 방식은 도구 호출이 동기적으로 이루어져 서브에이전트 작업 중 감독 에이전트가 차단되는 데드락 문제가 발생합니다. 이를 해결하기 위해 Deep Agents는 비동기 서브에이전트 패턴을 도입하여, 감독 에이전트가 제어권을 유지한 채 여러 작업을 병렬로 실행하고 관리할 수 있도록 지원합니다.
핵심 포인트
- 인라인 서브에이전트는 동기적 도구 호출로 인해 작업 완료 전까지 감독 에이전트의 추론과 응답을 차단함
- 비동기 서브에이전트는 즉시 Task ID를 반환하여 감독 에이전트가 병렬 실행, 중간 업데이트, 작업 취소 등을 가능하게 함
- 비동기 방식은 '발사 후 망각'이 아닌 '발사 후 조종(Fire-and-steer)' 모델을 지향함
- 에이전트 프로토콜을 기반으로 설계되어 특정 배포 환경에 종속되지 않고 독립적인 상태를 유지함
핵심 요약 (Key Takeaways)
인라인 서브에이전트 (Inline subagents)는 작업이 진행되는 동안 감독 에이전트 (Supervisor agent)를 차단합니다. 에이전트 루프 (Agent loop) 내의 도구 호출 (Tool calls)은 동기적 (Synchronous)이기 때문에, 서브에이전트가 완료될 때까지 감독 에이전트는 사용자에게 응답하거나, 다른 작업을 조정하거나, 경로를 수정할 수 없습니다. 이는 작업이 한 시간 이상 걸릴 때 실제로 발생하는 문제입니다.
비동기 서브에이전트 (Async subagents)는 즉시 작업 ID (Task ID)를 반환하므로 감독 에이전트가 제어권을 유지할 수 있습니다. 감독 에이전트는 여러 서브에이전트를 병렬로 실행하고, 사용자와 계속 대화하며, 작업 중간 업데이트를 보내거나, 더 이상 필요하지 않은 작업을 취소할 수 있습니다. 이는 단순히 "발사 후 망각 (Fire-and-forget)" 방식이라기보다 "발사 후 조종 (Fire-and-steer)" 방식에 더 가깝습니다.
비동기 서브에이전트는 에이전트 프로토콜 (Agent Protocol)을 기반으로 구축되어 특정 배포 환경에 종속되지 않습니다. 이들은 자체적인 프로세스와 상태 (State)를 가진 완전히 분리된 에이전트로 실행되며, LangSmith 배포 환경에 호스팅하거나 자체 인프라에 셀프 호스팅할 수 있습니다. 어떤 방식이든 감독 에이전트는 동일한 표준 인터페이스를 통해 이들을 관리합니다.
우리는 에이전트에게 더 많은 것을 요구하기 시작했습니다. 즉, 에이전트가 더 길고 복잡한 작업을 수행하기를 원합니다. 그렇게 함에 따라, 우리가 에이전트를 오케스트레이션 (Orchestrate)하던 전형적인 방식에서 몇 가지 결함이 나타나기 시작했습니다.
우리는 이를 해결하기 위해 최근 Deep Agents에 비동기 서브에이전트를 출시했습니다! 이는 에이전트가 위임된 작업을 백그라운드에서 실행할 수 있게 해주는 패턴이며, 기존 에이전트 아키텍처 (Agent architectures)의 몇 가지 단점을 보완해주기 때문에 저희도 매우 기대하고 있는 기능입니다.
전통적인 서브에이전트가 한계에 부딪히는 지점
서브에이전트 (Subagent)란 감독 에이전트 (Supervisor agent)가 범위가 정해진 작업을 위임하는 에이전트를 의미합니다. 서브에이전트는 감독 에이전트로부터 지침을 받고, 관련 도구 (Tools)에 대한 접근 권한을 가지며, 작업이 완료되면 요약본을 반환합니다. 이는 저희가 구축하는 거의 모든 에이전트에 채택하고 있는 컨텍스트 엔지니어링 (Context engineering) 패턴으로, 여기에는 몇 가지 중요한 이유가 있습니다:
작업이 더 작은 태스크 (Tasks)로 나뉘어질 때 에이전트 (Agents)는 더 나은 성능을 발휘합니다 — 감독 에이전트 (Supervisor agent)가 문제를 이해하고, 태스크를 조직한 다음, 이를 실행할 작업자 (Workers)들을 조율합니다. 작은 태스크에 관한 모든 정보가 전체 목표에 중요한 것은 아닙 — 작업을 집중적이고 독립적인 에이전트 실행 (Agent runs)으로 분리함으로써, 감독 에이전트로부터 불필요한 컨텍스트 (Context)를 숨길 수 있습니다.
이 패턴은 효과적입니다. 하지만 에이전트에게 더 길고 복잡한 태스크를 부여함에 따라, 인라인 서브에이전트 (Inline subagents) 방식이 무너지기 시작했습니다.
서브에이전트가 작동하는 동안 에이전트가 데드락 (Deadlock) 상태에 빠집니다
서브에이전트는 감독 에이전트에게 주어진 도구 (Tool)를 통해 호출됩니다. 에이전트 내부에서 도구 호출 (Tool calling)이 작동하는 방식 때문에, 서브에이전트의 응답으로 도구 호출이 완료될 때까지 감독 에이전트는 다른 어떤 것에 대해서도 추론 (Reasoning)할 수 없습니다.
서브에이전트에게 작고 위험 부담이 적은 태스크가 주어졌을 때는 이것이 큰 문제가 아니었습니다. 하지만 이제 에이전트에게 더 복잡한 태스크와 도구를 부여하고 (또한 실행 시간이 더 오래 걸리는 모델을 사용함에 따라), 이 문제는 더욱 강력하게 체감됩니다. 만약 서브에이전트가 한 시간 동안 작업한다면, 에이전트와 다시 상호작용하기 위해 한 시간을 기다려야 합니다.
새로운 정보를 조율하기 어렵습니다
에이전트가 작업하는 동안 에이전트에게 중요한 정보 채널에는 몇 가지가 있습니다:
사용자 입력 (User input) — 사용자는 태스크가 진행 중인 동안 에이전트의 방향을 조정하거나, 컨텍스트를 추가하거나, 우선순위를 변경하고 싶을 수 있습니다. 다른 작업의 결과 (Results from other work) — 한 서브에이전트의 출력이 다른 서브에이전트가 다음에 무엇을 해야 할지에 대한 정보를 제공할 수 있습니다. 부분적인 진행 상황 (Partial progress) — 때로는 태스크가 완료되기 전에 잘못된 방향으로 향하고 있는 태스크를 수정(Course-correct)하고 싶을 때가 있습니다.
인라인 서브에이전트 (inline subagents)를 사용할 때는 이러한 채널들을 전혀 사용할 수 없습니다. 감독자 (Supervisor)가 차단(blocked)되어 사용자가 대화할 수 없습니다. 서브에이전트 (Subagents)를 동시에 실행할 수 없으므로 결과 간의 교차 수분 (cross-pollination)도 일어나지 않습니다. 또한 서브에이전트의 턴 (turns)은 '전부 아니면 전무 (all-or-nothing)' 방식이어서, 작업 중간에 업데이트를 보내거나 부분적인 실패를 우아하게 처리할 방법이 없습니다. 감독자는 서브에이전트를 발사하고 그저 결과가 좋기를 바랄 뿐입니다.
등장: 비동기 서브에이전트 (Async Subagents)
비동기 서브에이전트를 생각하는 간단한 방법은 순차적 (sequentially)인 대신 백그라운드 (background)에서 실행되는 서브에이전트로 보는 것입니다. 서브에이전트가 끝날 때까지 기다렸다가 다음으로 넘어가는 대신, 감독자는 태스크 (task)를 시작하고 즉시 태스크 ID (task ID)를 받은 뒤 계속해서 작업을 진행합니다. 백그라운드에서 작업이 진행되는 동안 감독자는 사용자와 대화하거나, 더 많은 서브에이전트를 시작하거나, 문제의 다른 부분에 대해 진전을 보일 수 있습니다.
서브에이전트는 상태를 유지 (stateful)하며 자체적인 대화 스레드 (conversation thread)를 유지하기 때문에, 감독자는 후속 지침을 보내거나, 작업 중간에 방향을 수정 (course-correct)하거나, 더 이상 필요하지 않은 작업을 취소할 수 있습니다. 이를 '발사 후 망각 (fire-and-forget)'이라기보다는 '발사 후 조종 (fire-and-steer)'에 가깝다고 생각하십시오.
작동 방식
감독자에게 서브에이전트당 하나의 차단형 도구 호출 (blocking tool call)을 제공하는 대신, 비동기 서브에이전트는 감독자에게 태스크 큐 (task queue)와 더 유사하게 작동하는 일련의 관리 도구 (management tools)를 제공합니다:
감독자는 자신의 추론 루프 (reasoning loop)의 일부로서 이러한 도구들을 자연스럽게 사용합니다. 즉, 몇 가지 태스크를 시작하고, 다시 사용자와 대화하고, 진행 상황을 확인하며, 필요에 따라 방향을 수정할 수 있습니다.
전통적인 서브에이전트는 사실상 부모 에이전트 (parent agent)의 함수일 뿐입니다. 이들은 프로세스를 공유하고, 상태를 공유하며, 오직 감독자의 실행 루프 (execution loop) 내부에서만 존재합니다. 비동기 서브에이전트는 이들을 완전히 별개이며 개별적으로 접근 가능한 에이전트로 취급합니다. 이들은 자체 프로세스에서 실행될 수 있고, 자체 상태를 유지할 수 있으며, 수백 또는 수천 개의 서브에이전트를 호출할 수 있는 규모로 확장될 수 있습니다.
에이전트 프로토콜 (Agent Protocol) 기반 구축
그러한 분리는 프로세스 내 함수 호출 (in-process function calls) 이상의 것을 필요로 합니다. 비동기 서브에이전트 (Async subagents)는 원격 에이전트를 관리하기 위한 프레임워크 불가지론적 (framework-agnostic) API 규격인 에이전트 프로토콜 (Agent Protocol)을 기반으로 구축됩니다. 이는 스레드 생성, 실행 (runs) 시작, 상태 폴링 (polling), 업데이트 전송, 그리고 장기 메모리 (long-term memory) 관리를 위한 표준 엔드포인트 (endpoints)를 정의합니다. 감독자 (supervisor)가 일관된 인터페이스를 통해 비동기 작업을 관리하는 데 필요한 모든 것을 제공합니다.
핵심적인 이점은 배포 유연성입니다. 특정 호스팅 플랫폼에 종속되지 않습니다. 관리형 경험을 위해 LangSmith 배포 환경에서 비동기 서브에이전트를 실행하거나, 자체 인프라에 직접 호스팅할 수 있습니다. 감독자는 서브에이전트가 어디에 위치하든 상관하지 않습니다. 작업을 보내고, 작업 ID (task ID)를 받은 뒤, 어떤 방식이든 동일한 표준 인터페이스를 통해 생명주기 (lifecycle)를 관리합니다.
Agent Protocol에 대해 더 자세히 알아보려면 규격서 및 API 참조를 확인하세요.
Deep Agents에서 비동기 서브에이전트를 사용하는 방법
Deep Agents는 저희가 자주 언급하는 범용 에이전트 하네스 (agent harness)입니다. Deep Agents에 비동기 서브에이전트를 추가하는 방법은 subagents 리스트에 비동기 서브에이전트 스펙 (spec)을 교체하는 것만큼 간단하며, 인라인 서브에이전트 (inline subagents)와 자유롭게 혼합하여 사용할 수 있습니다.
LangSmith 배포를 사용하는 경우
에이전트를 정의하고 langgraph.json에 등록하세요. 연구자 (researcher)가 별도의 에이전트이기 때문에, 감독자는 자동으로 비동기 관리 도구를 갖게 됩니다.
// agents.ts
import { createAgent } from "langchain";
import { createDeepAgent } from "deepagents";
...
// langgraph.json
{
"dependencies": ["."],
...
서브에이전트는 자체 상태 (state)를 가진 별도의 프로세스에서 실행되며, 감독자는 작업을 위임하고 다시 확인하기만 하면 됩니다.
셀프 호스팅 (Self-hosted)
서브에이전트가 실행되는 위치를 완전히 제어하고 싶다면 직접 호스팅할 수 있습니다. 서브에이전트는 Agent Protocol 엔드포인트를 구현하기만 하면 되며, 감독자는 그래프 ID (graph ID) 대신 URL을 통해 서브에이전트에 연결합니다.
export const agent = createDeepAgent({
model: "anthropic:claude-opus-4-6",
subagents: [{
...
셀프 호스팅 (Self-hosted) 서버는 Agent Protocol 엔드포인트(스레드 생성, 실행 시작, 상태 폴링, 작업 취소)를 구현하며, Docker 컨테이너, VM, 자체 Kubernetes 클러스터 등 어디에서나 실행할 수 있습니다. 저희는 시작점으로 사용할 수 있는 Hono 서버, Postgres 기반 상태 관리, Docker Compose 설정이 포함된 완전한 셀프 호스팅 예제를 제공합니다.
더 알아보기
배포 설정, 트레이싱 (Tracing), 문제 해결 (Troubleshooting)을 포함한 전체 가이드는 비동기 서브에이전트 (async subagents) 문서를 참조하세요.
AI 자동 생성 콘텐츠
본 콘텐츠는 LangChain Blog의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기