Agents Are Going Async: 대화는 오케스트레이터가, 긴 작업은 백그라운드 하위 에이전트가 맡는 구조
LangChain은 긴 작업 여러 개를 맡는 에이전트가 사용자에게 계속 응답하려면 사용자 응대를 맡는 오케스트레이터와 뒤에서 일하고 결과를 보고하는 비동기 하위 에이전트로 나눠야 한다고 정리했습니다. Deep Agents는 작업 시작·확인·수정·취소·목록 5개 도구와, 후속 지시가 진행 중 작업을 끊을지 뒤에 쌓일지 정하는 설정을 둡니다. 알림 기능은 베타입니다.
긴 작업을 여러 개 맡는 에이전트는 사용자와 대화하는 오케스트레이터 하나와, 뒤에서 일하고 결과를 보고하는 비동기 하위 에이전트로 나누면 일하는 동안에도 연락이 끊기지 않습니다. 실제로 쓰려면 작업마다 상태를 기록하는 장부, 후속 지시를 끊을지 쌓을지 정하는 규칙, 승인을 받을 창구를 먼저 정해야 합니다.
요약
LangChain의 Sydney Runkle과 Thushanth Bengre는 2026년 11월 5일 회사 블로그에 에이전트 구조가 비동기로 옮겨 가고 있다는 글을 올렸습니다. 출발점은 ReAct 루프(모델이 생각하고 도구를 부르고 결과를 보는 일을 반복하는 기본 구조)의 약점입니다. 이 루프에서는 오래 걸리는 도구 호출이나 하위 에이전트 하나가 루프 전체를 붙잡습니다. 그동안 다른 일은 줄을 서고 사용자는 답을 받지 못합니다. 저자들은 해법으로 역할을 둘로 나눕니다. 사용자 곁에 남는 Orchestrator(작업을 배정하고 대화를 맡는 상위 에이전트)와, 각자 스레드에서 긴 작업을 처리하는 Async subagent(비동기 하위 에이전트)입니다. 원문은 이 구조를 좋은 비서실장에 빗댑니다. 큰 일을 뒤에서 굴리면서도 연락이 닿고 진행 상황을 알려 주는 사람입니다.
저자들은 이 구조가 업계 공통 흐름이라고 봅니다. Anthropic의 Claude Code는 하위 에이전트를 기본으로 백그라운드에서 돌리고 OpenAI의 dots와 DeepSeek Harness도 사람을 상대하는 쪽과 병렬 작업자를 나눴다고 소개합니다. LangChain은 자사 프레임워크 Deep Agents에 같은 구조를 넣었습니다. 오케스트레이터는 작업 도구 다섯 개로 하위 에이전트를 시작하고 상태를 보고 지시를 바꾸고 멈추고 목록을 확인합니다. 하위 에이전트 정의에 필드 하나만 더하면 비동기로 바뀝니다. 저자들의 요지는 한 문장으로 정리됩니다. “Async subagents let an agent stay responsive while background workers run long tasks.” 아래에서는 이 구조를 이루는 장치와, 사내 에이전트에 붙일 때 필요한 설정·역할·일정을 차례로 풉니다.
핵심 메커니즘
Orchestrator와 Async subagent: 응대와 실행을 나눈다
무엇인가. 에이전트 하나가 대화와 긴 작업을 함께 하던 구조를, 대화 담당 하나와 실행 담당 여럿으로 쪼갠 설계입니다.
어떻게 작동하나. 사용자가 일을 맡기면 오케스트레이터가 하위 에이전트를 띄웁니다. 호출은 곧바로 돌아오고 작업은 하위 에이전트 스레드에서 따로 진행됩니다. 원문은 이를 Python의 asyncio.create_task나 JavaScript에서 기다리지 않은 Promise에 비유합니다. 결과는 나중에 도착합니다. 원문이 꼽은 성립 조건은 두 가지입니다. 하위 에이전트가 루프를 붙잡지 않으니 사용자가 언제든 오케스트레이터에 말을 걸 수 있어야 하고 일이 들어오는 대로 작업을 바로 띄워 서로 막지 않고 병렬로 돌아야 합니다.
언제 쓰고 언제 안 쓰나. 몇 분 이상 걸리는 조사·코딩·문서 작성이 동시에 여러 건 들어올 때 맞습니다. 몇 초면 끝나는 조회나, 앞 결과가 있어야 다음 단계를 정할 수 있는 순차 작업은 기존 동기 호출이 더 단순합니다.
작은 예시(가상). 구매팀 담당자가 “협력사 세 곳의 최근 분기 리스크를 정리해 줘”라고 맡기고 곧바로 “지난주 발주 지연 건도 알려 줘”라고 묻습니다. 오케스트레이터는 협력사별 조사 세 건을 띄워 두고 발주 지연 질문에는 바로 답합니다.
다섯 가지 작업 도구: 시작·확인·수정·취소·목록
무엇인가. 오케스트레이터가 하위 에이전트를 다루는 손잡이입니다. Deep Agents는 start_async_task, check_async_task, update_async_task, cancel_async_task, list_async_tasks 다섯 개를 줍니다.
어떻게 작동하나. start_async_task는 하위 에이전트를 자기 스레드에서 띄우고 바로 돌아옵니다. check_async_task는 상태를, 끝났으면 결과까지 돌려줍니다. update_async_task는 돌고 있는 작업에 새 지시를 보내고 cancel_async_task는 작업을 멈춥니다. list_async_tasks는 모든 작업과 상태를 보여 줍니다. 모델 입장에서는 이 다섯 개가 보통의 도구 호출입니다. 그래서 언제 띄우고 언제 확인할지는 모델이 대화 흐름을 보고 정합니다.
언제 쓰나. 사용자가 “그거 어디까지 됐어?”라고 물으면 check, “그건 그만해”라면 cancel, “방향을 바꿔”라면 update가 불립니다.
update_strategy: 후속 지시를 끊을지, 쌓을지
무엇인가. 진행 중인 하위 에이전트에 새 지시가 왔을 때 처리 방식을 정하는 설정입니다. 사용자가 오케스트레이터에 말을 거는 것과는 별개이고 하위 에이전트 정의에 둡니다.
어떻게 작동하나. 기본값 "interrupt"는 지금 하던 실행을 멈추고 새 지시로 다시 시작합니다. 원문은 “데이터베이스를 Postgres로 바꿔”처럼 방향을 고치는 지시에 맞는다고 봅니다. "enqueue"는 지금 실행을 끝까지 마친 뒤 후속 지시를 처리합니다. “끝나면 테스트도 돌려”처럼 할 일을 덧붙일 때 씁니다.
언제 무엇을 쓰나. 지금까지 한 일이 새 지시로 쓸모없어지면 interrupt, 지금 한 일이 그대로 쓰이고 뒤에 일이 붙으면 enqueue입니다.
Task notifications: 결과가 오케스트레이터로 돌아오는 길
무엇인가. 하위 에이전트가 끝낸 결과를 오케스트레이터가 놓치지 않게 하는 장치입니다. 원문은 이 기능이 아직 베타라 API가 바뀔 수 있다고 밝힙니다.
어떻게 작동하나. 오케스트레이터의 시스템 프롬프트에는 끝나지 않은 작업 목록이 늘 들어 있습니다. 그래서 무엇이 진행 중인지 항상 압니다. 결과는 check_async_task로 직접 확인해 가져올 수도 있고 작업이 스스로 알려 올 수도 있습니다. 스스로 알려 올 때는 오케스트레이터 상태에 따라 경로가 셋으로 갈립니다. 다른 일을 하는 중이면 모델을 부르기 전마다 미완료 작업을 확인해 실행 도중에 결과를 받습니다. 쉬고 있으면 하위 에이전트가 새 실행을 일으켜 깨웁니다. 사용자 승인을 기다리며 멈춰 있으면 승인 요청은 그대로 두고 사용자가 답한 뒤 결과가 들어옵니다.
원문이 내다본 방향. 저자들은 이 방식이 하위 에이전트를 넘어 도구 호출로도 넓어진다고 봅니다. 예로 OpenAI의 비동기 도구 호출을 듭니다. 모델이 도구를 부른 뒤에도 계속 일하고 애플리케이션이 결과를 나중 요청에 실어 돌려주는 방식입니다.
waiting 상태: 승인은 하위 에이전트 스레드에서 따로 받는다
무엇인가. 하위 에이전트가 사람 승인이 필요한 단계에 이르면 상태가 waiting으로 바뀝니다.
어떻게 작동하나. 사용자는 오케스트레이터 대화를 끊지 않고 그 하위 에이전트의 스레드에서 직접 승인합니다. Managed Deep Agents(LangChain이 호스팅하는 Deep Agents)를 Slack에서 쓰면 승인 요청이 처음 일을 맡긴 스레드로 다시 올라옵니다.
작은 예시(가상). 코딩 하위 에이전트가 운영 DB 스키마를 바꾸기 직전 waiting이 되고 담당 개발자는 Slack 원래 스레드에서 승인합니다. 그사이 오케스트레이터는 다른 질문에 계속 답합니다.
통념과 다른 주장
흔히 이렇게 봅니다에이전트가 더 큰 일을 하려면 한 에이전트가 더 긴 컨텍스트로 더 오래 루프를 돌아야 한다.
저자는 이렇게 봅니다처리 능력은 한 루프의 길이가 아니라 뒤에서 일하는 작업자 수로 늘어납니다. 대화 창구는 하나로 열어 두고 실행은 여럿으로 나눠야 합니다.
근거Claude Code, OpenAI의 dots, DeepSeek Harness가 모두 사람을 상대하는 쪽과 백그라운드 작업자를 나눴다는 점을 듭니다. 기존 동기 구조에서는 긴 호출 하나가 다른 일을 모두 세웠다는 점도 함께 짚습니다.
저자가 든 사례
업계 흐름: Claude Code, dots, DeepSeek Harness
- 상황: 에이전트에 맡기는 일이 길어지면서 긴 작업 중에 사용자와 연락이 끊기는 문제가 생겼습니다.
- 한 일: 원문에 따르면 Claude Code는 하위 에이전트를 기본으로 백그라운드에서 돌립니다. OpenAI의 dots는 백그라운드 작업자에게 일을 넘겨 여러 일을 동시에 진행합니다. DeepSeek Harness는 사람과 대화하는 라우터와 병렬로 작업하는 백그라운드 작업자를 둡니다.
- 결과: 사용량이나 성능 수치는 원문에서 밝히지 않았습니다.
- 연결: Orchestrator와 Async subagent 분리, 통념과 다른 주장의 근거.
Deep Agents 구현: 필드 하나로 비동기 전환
- 상황: LangChain은 자사 에이전트 프레임워크 Deep Agents에 같은 구조를 넣었습니다.
- 한 일: 하위 에이전트 정의에
"async": True를 더하면 비동기가 됩니다. 원문 예시는openai:gpt-5.5모델을 쓰는 연구 비서에researcher하위 에이전트 하나를 붙인 형태입니다. Managed Deep Agents는 서비스하는 모든 에이전트에general-purpose하위 에이전트의 비동기 복사본을 기본으로 붙입니다. 그래서 에이전트가 실행 중에 앞에서 할지 뒤로 보낼지 고를 수 있습니다. - 결과: Python·JavaScript판 Deep Agents와 Managed Deep Agents에서 쓸 수 있고 알림 기능은 베타입니다. 공개 저장소
async-deep-agents에 연구·코딩 하위 에이전트를 거느린 감독 에이전트 예제가 Python·TypeScript로 있습니다. - 연결: 다섯 가지 작업 도구, update_strategy, Task notifications.
기술 디테일: 비동기 하위 에이전트를 직접 붙인다면
작업 장부부터 만듭니다(다섯 가지 작업 도구, Task notifications). 다섯 도구가 같은 기록을 읽고 써야 하므로 작업 하나를 레코드 하나로 둡니다. 원문은 상태 이름으로 waiting만 밝혔고 나머지 필드는 실제로 돌릴 때 필요한 예시입니다.
{
"task_id": "t-0412",
"subagent": "researcher",
"thread_id": "th-88f2",
"status": "running",
"instruction": "협력사 A의 최근 분기 리스크 요약",
"update_strategy": "interrupt",
"pending_updates": [],
"started_at": "2026-11-07T09:12:00+09:00",
"deadline_min": 30,
"result_summary": null,
"requested_by": "구매팀 김OO"
}
status 값은 pending, running, waiting, done, failed, cancelled 여섯 가지로 둡니다. 원문에 나온 것은 waiting뿐이고 나머지는 예시입니다.
시스템 프롬프트의 미완료 목록은 짧게 유지합니다(Task notifications). 원문 구조대로 끝나지 않은 작업을 프롬프트에 넣되, 한 작업에 한 줄(task_id, 하위 에이전트, 지시 앞 40자, 상태, 경과 시간)만 씁니다. 동시에 도는 작업은 5~10개로 상한을 두고 넘치면 새 시작 요청을 대기열로 돌립니다. 목록이 길어지면 오케스트레이터가 대화보다 작업 관리에 토큰을 쓰게 됩니다.
결과는 요약만 돌려받습니다(Orchestrator와 Async subagent). LangChain 문서에 따르면 Deep Agents의 하위 에이전트는 기본적으로 맡은 작업 설명만 보고 중간 도구 호출은 하위 에이전트 안에 남긴 채 최종 결과만 상위로 올립니다. 비동기에서도 같은 원칙을 지킵니다. result_summary는 500~1,000자로 제한하고 원본 산출물은 파일·링크로 따로 둡니다.
interrupt와 enqueue는 지시 유형으로 고릅니다(update_strategy). 사용자의 후속 지시를 분류하는 기준을 미리 적어 둡니다. 대상·범위·도구를 바꾸면 정정이니 interrupt입니다. 산출물에 단계를 덧붙이면 enqueue입니다. 판단이 애매하면 오케스트레이터가 사용자에게 한 번 물어봅니다. 하위 에이전트마다 기본값을 다르게 둘 수도 있습니다. 조사형은 interrupt, 코드 수정형은 중간 산출물이 꼬이지 않게 enqueue를 기본으로 두는 식입니다(가상 예시).
승인 경계는 하위 에이전트 정의에 적습니다(waiting 상태). 외부 메일 발송, 운영 DB 변경, 결제처럼 되돌리기 어려운 동작 앞에서 waiting으로 멈추게 하고 승인 요청에는 무엇을 왜 하려는지, 되돌리는 방법을 함께 담습니다. 승인 채널은 일을 맡긴 원래 스레드로 정합니다. 원문의 Managed Deep Agents가 Slack에서 쓰는 방식입니다.
모델은 역할별로 따로 고릅니다(Orchestrator와 Async subagent). 원문 예시는 openai:gpt-5.5 하나로 감독 에이전트를 만들었습니다. 실제로 돌릴 때는 오케스트레이터에 응답이 빠른 모델을 두고 하위 에이전트에는 작업 품질을 우선한 모델을 두는 조합도 검토합니다. 오케스트레이터는 짧은 판단을 자주 하고 하위 에이전트는 긴 작업을 드물게 하기 때문입니다. 작업 장부의 thread_id로 하위 에이전트 실행 기록을 따로 남겨 두면 결과가 이상할 때 어느 작업에서 틀렸는지 추적할 수 있습니다.
실패는 네 가지로 나눠 대응합니다. 아래 표는 실제로 돌릴 때 자주 부딪히는 경우를 정리한 가상 예시입니다.
현업 실행 디테일: 누가, 언제, 무엇을
역할. 아래 역할 분담은 파일럿 기준의 예시입니다.
| 역할 | 담당 | 하는 일 |
|---|---|---|
| 업무 오너 | 대상 부서 팀장 | 맡길 긴 작업 고르기, 결과물 기준 정하기 |
| 에이전트 엔지니어 | AX 추진 조직 개발자 1~2명 | 오케스트레이터·하위 에이전트 정의, 작업 장부, 알림 연결 |
| 승인권자 | 업무 오너가 지정한 담당자 | waiting 요청 처리, 승인 기준 관리 |
| 운영 담당 | IT 운영 | 동시 작업 상한, 시간 상한, 로그 점검 |
시작 전 준비물. 하루 이상 걸리거나 동시에 여러 건 몰리는 반복 업무 목록 3~5개, 업무마다 “다 됐다”의 기준, 사람 승인이 필요한 동작 목록, 사용자가 쓸 대화 채널(Slack, Teams 등)을 준비합니다.
4주 일정(가상 예시).
| 기간 | 할 일 | 산출물 |
|---|---|---|
| 1주차 | 긴 작업 후보 고르기, 지금 처리 시간 재기 | 대상 업무 2개, 기준 시간 |
| 2주차 | 하위 에이전트 2~3개 정의, 작업 장부와 다섯 도구 연결, 승인 경계 지정 | 동작하는 프로토타입 |
| 3주차 | 실무자 5~10명이 실제 업무로 사용 | 작업 로그, 사용자 의견 |
| 4주차 | 판정 기준으로 평가, 확대 여부 결정 | 판정 보고서 |
업무 오너에게 물을 질문.
- 이 일을 맡긴 뒤 결과가 나올 때까지 보통 얼마나 기다리나요? 그동안 같은 담당자에게 다른 요청이 몇 건 들어오나요?
- 중간에 방향을 바꾸는 일이 잦은가요, 아니면 할 일이 덧붙는 일이 잦은가요?
- 결과를 내보내기 전에 누가 무엇을 확인해야 하나요?
- 작업이 실패하거나 멈췄을 때 누가 알아야 하나요?
진행 판정 기준(예시). 3주차 로그로 판단합니다. 긴 작업이 도는 동안 사용자 질문에 답한 비율이 90% 이상인지, 완료된 결과가 오케스트레이터에서 빠짐없이 전달됐는지(유실 0건), waiting 요청이 평균 몇 시간 안에 처리됐는지, 동시 진행 작업 수가 기존 처리 방식보다 늘었는지를 봅니다. 두 개 이상 못 미치면 하위 에이전트 수를 줄이고 1주 더 돌립니다.
적용 제언. 사내 에이전트 도입이 “질문하면 답하는 챗봇”에서 “일을 맡기는 동료”로 넘어가는 단계라면 이 구조가 기본 설계가 됩니다. 처음부터 하위 에이전트를 많이 만들기보다, 구매 협력사 조사나 영업 제안서 초안처럼 오래 걸리고 동시에 몰리는 업무 하나에서 시작하는 편이 낫습니다. 이 구조에서 바뀌는 관행은 “에이전트가 일을 끝낼 때까지 기다린다”는 습관입니다. 업무 오너는 결과물 기준과 승인 경계를 먼저 정하고 IT는 동시 작업 상한과 작업 장부를 운영 대상으로 관리해야 합니다. 벤더를 고를 때는 모델 성능과 함께 백그라운드 작업 관리(시작·확인·수정·취소·목록)와 승인 흐름을 지원하는지 확인합니다.
원문 사례
| 항목 | 내용 |
|---|---|
| 저자·발표처 | Sydney Runkle, Thushanth Bengre · LangChain 블로그, 2026.11.5 |
| 핵심 주장 | 긴 작업 여러 개를 맡는 에이전트는 사용자 응대 오케스트레이터와 비동기 하위 에이전트로 나눠야 함 |
| 성립 조건 | 사용자가 언제든 오케스트레이터에 닿을 것, 작업이 서로 막지 않고 병렬로 돌 것 |
| 작업 도구 | start_async_task, check_async_task, update_async_task, cancel_async_task, list_async_tasks |
| 후속 지시 설정 | update_strategy: "interrupt"(기본, 정정용), "enqueue"(추가용) |
| 결과 수신 | 미완료 작업을 시스템 프롬프트에 기록, 작업 중·쉬는 중·승인 대기 중 세 상태별 처리 |
| 승인 | 하위 에이전트 waiting 상태, 하위 에이전트 스레드에서 응답, Managed판은 Slack 원래 스레드 |
| 업계 사례 | Anthropic Claude Code, OpenAI dots, DeepSeek Harness, OpenAI 비동기 도구 호출 |
| 사용 범위 | Deep Agents(Python·JavaScript), Managed Deep Agents, 알림 기능 베타 |
| 수치 | 사용량·성능 수치 없음 |
핵심 개념
- ReAct loop
- 모델이 추론하고 도구를 부르고 결과를 관찰하는 과정을 되풀이하는 에이전트의 기본 실행 구조입니다.
- Deep Agents
- LangChain이 만든 긴 작업용 에이전트 프레임워크로, Python과 JavaScript판이 있습니다.
- Managed Deep Agents
- Deep Agents를 LangChain이 호스팅해 운영해 주는 서비스로, Slack 승인 흐름과 기본 비동기 하위 에이전트를 제공합니다.
- general-purpose subagent
- 특정 역할 없이 위임받은 일을 처리하는 Deep Agents의 범용 하위 에이전트입니다.
- asyncio.create_task
- Python에서 작업을 띄워 두고 결과를 기다리지 않은 채 다음 코드로 넘어가게 하는 함수입니다. 원문이 비동기 하위 에이전트를 설명하며 든 비유입니다.
- Async tool calling
- 모델이 도구를 부른 뒤 결과를 기다리지 않고 계속 일하고 결과는 나중 요청에서 받는 방식입니다.
내 메모
TODO: 내 생각 추가
원문은 LangChain 블로그의 「Agents Are Going Async」(Sydney Runkle, Thushanth Bengre, 2026.11.5)입니다. 요약, 핵심 메커니즘의 원문 설명, 통념과 다른 주장, 저자가 든 사례, 원문 사례 표는 원문 내용을 AX Review가 다시 정리했습니다. 기술 디테일의 작업 장부 필드·상한값·실패 대응, 현업 실행 디테일의 역할·일정·판정 기준, 작은 예시, 인포그래픽은 실제로 돌릴 때 필요한 내용을 새로 작성한 것입니다. 하위 에이전트의 컨텍스트 분리 설명은 LangChain Deep Agents 문서(Subagents)를 참고했습니다. 전체 내용과 코드 예시는 원문에서 볼 수 있습니다.