
Microsoft의 새로운 기능 CodeAct는 도구를 하나씩 호출하게 하지 않는다
요약
Microsoft의 새로운 기능 CodeAct는 에이전트가 도구를 하나씩 호출하는 기존 루프 대신, 수행할 작업을 하나의 Python 코드로 작성하여 실행하는 방식을 도입했습니다. 이를 통해 오케스트레이션 오버헤드를 줄여 지연 시간을 52.4% 단축하고 토큰 소비를 63.9% 절감했습니다.
핵심 포인트
- 도구 호출 루프를 코드 제어 구문(for, if 등)으로 대체하여 효율성 극대화
- 기존 방식 대비 실행 시간 약 52% 단축 및 토큰 사용량 약 64% 절감
- 모델의 추론 턴 수를 줄여 오케스트레이션 병목 현상 해결
- 모델은 execute_code 도구 하나를 통해 내부적으로 다른 도구들을 제어
에이전트에게 도구(Tool)를 사용하게 할 때, 현재의 표준은 "모델이 JSON으로 도구 호출을 하나 생성 → 실행 → 결과를 전달하여 다시 모델이 생각하게 함"이라는 루프다. 1단계마다 모델의 추론이 한 번씩 왕복한다. 날씨를 두 도시 분량만큼 가져와 비교하는 것만으로도, get_weather를 2회 호출하며 각각 별도의 턴(Turn)이 소요된다. 사용자의 주문을 전부 훑어서 합계를 내는 것과 같은 처리를 하게 되면, 이 턴 수가 그대로 지연(Latency)과 토큰 소비로 쌓여가게 된다.
Microsoft가 6월 Build 2026에서 정식으로 발표한 Microsoft Agent Framework의 새로운 기능인 CodeAct는 이 루프 자체를 접어버린다. 모델에게 도구를 하나씩 선택하게 하는 것을 그만두고, "하고 싶은 일을 전부 하나의 Python 프로그램으로 작성하라"고 시킨다. 작성된 코드를 격리 환경(Isolated Environment)에서 단 한 번 실행하고, 결과를 한꺼번에 반환한다.
벤치마크 수치가 명확하다. 주문 데이터를 조회하면서 합계를 계산하는 전형적인 "작은 호출의 연쇄"형 워크로드에서의 비교 결과는 다음과 같다.
| 기존의 도구 호출 | CodeAct | 차이 |
|---|---|---|
| 소요 시간 | 27.81초 | 13.23초 |
| 토큰 | 6,890 | 2,489 |
출처는 공식 블로그의 측정값이다.
포인트는 모델이 똑똑해진 것도, 도구가 빨라진 것도 아니라는 점이다. 동일한 모델, 동일한 도구, 동일한 프롬프트(Prompt)를 유지한 채, 오케스트레이션(Orchestration, 도구를 어떤 순서로 어떻게 연결할 것인가)의 주도권을 모델의 순차적 판단에서 코드의 제어 구문(Control Syntax)으로 옮긴 것뿐이다. 루프, 분기, 필터, 집계를 모델에게 여러 턴에 걸쳐 생각하게 하는 대신, for 문이나 조건 분기로 코드에 작성해 버린다. 중간 결과를 모델의 컨텍스트(Context)에 매번 되돌리지 않기 때문에 토큰이 늘어나지 않는다. 공식 문서에서도 "모델의 품질이 아니라 오케스트레이션의 오버헤드(Overhead)가 병목(Bottleneck)이 되고 있다"라고 명확히 기술하고 있다.
Modern AI agents often are not bottlenecked by model quality, but by orchestration overhead.
(CodeAct | Microsoft Learn)
"모델에게 코드를 작성하게 하여 실행한다"라는 발상 자체는 새로운 것이 아니다. 연구에서도, 다른 프레임워크에서도 반복적으로 시도되어 왔다. Microsoft의 구현이 현실적인 이유는, 후술할 샌드박스(Sandbox)를 만드는 방식과 기존의 도구 정의를 그대로 유용할 수 있는 설계에 있다.
CodeAct가 유효한 에이전트에게는 도구가 직접 보이지 않는다. 대신 execute_code라는 도구가 하나만 생긴다. 모델은 그 안에서 call_tool("도구 이름", ...)을 호출하는 코드를 작성한다. Python에서의 최소 구성은 다음과 같다(공식 문서 기준).
pip install agent-framework-hyperlight --pre
from agent_framework import Agent
from agent_framework.foundry import FoundryChatClient
from agent_framework.hyperlight import HyperlightCodeActProvider
...
HyperlightCodeActProvider에 전달한 도구는 모델의 직접적인 도구 목록에서 사라진다. 모델은 어디까지나 "코드 안에서 call_tool로 호출하는 부품"으로 취급한다. 순차적 승인이 필요한 부작용(Side Effect)이 있는 작업(메일 전송 등)은 반대로 프로바이더(Provider)에 넣지 않고 에이전트에 직접 붙은 도구로 남겨두며, approval_mode="always_require"를 붙여두는 방식의 구분 사용이 권장된다. CodeAct의 승인은 execute_code 호출 1회 전체에 적용되며, 그 안의 개별 call_tool 단위로는 멈출 수 없기 때문이다.
.NET 측도 준비되어 있다. 패키지는 Microsoft.Agents.AI.Hyperlight이며, HyperlightCodeActProvider와 수동 배선용인 HyperlightExecuteCodeFunction을 제공한다. 다만 현시점에서는 의존 대상인 Hyperlight.HyperlightSandbox.Api
문서에 따르면 Hyperlight.HyperlightSandbox.Api가 아직 nuget.org에 공개되지 않았기 때문에, 그대로 두면 리스토어(restore)에 실패할 것이라고 명시되어 있다. 테스트해 보려면 Python 버전을 먼저 사용하는 것이 좋다.
이 부분이 개인적으로 가장 흥미로운 설계 결정이었다. 모델이 작성한 코드는 신뢰할 수 없다. 단순히 호스트에서 exec를 실행했다가는 사고가 발생할 것이다. CodeAct는 이를 Microsoft가 제작한 마이크로 VM(MicroVM)인 Hyperlight 내에서 실행한다.
Hyperlight는 "애플리케이션에 내장할 수 있는 VMM(가상 머신 매니저)"로, Rust로 제작되었으며 Apache 2.0 라이선스를 따르고 CNCF의 Sandbox 프로젝트이기도 하다. 일반적인 VM이 부팅에 120밀리초(ms) 이상 걸리는 반면, Hyperlight의 마이크로 VM은 1~2밀리초 만에 실행된다 (Microsoft Open Source Blog). OS 전체를 탑재하지 않고 하드웨어 가상화(Linux에서는 KVM, Windows에서는 Windows Hypervisor Platform)를 통해 격리한다. 따라서 도구 호출(tool call)을 할 때마다 일회용 VM을 생성하더라도 지연 시간(latency)을 무시할 수 있다는 전제가 성립한다. 컨테이너의 프로세스 분리보다 한 단계 더 강력한, 하드웨어 경계에서의 격리라고 이해하면 된다.
주의할 점은, 격리되는 것은 모델이 작성한 오케스트레이션(orchestration) 코드뿐이며, call_tool의 대상이 되는 실제 도구 함수는 호스트 프로세스에서 풀 권한(full permission)을 가진 채로 동작한다는 점이다.
call_tool(...)은 호스트 콜백(host callback)으로 돌아가는 브리지(bridge)이며, 샌드박스 내부에서 도구를 재구현하는 것이 아니다.
즉, 샌드박스는 모델의 폭주하는 코드를 가두기 위한 것이지, 도구 자체의 I/O를 제한하기 위한 것이 아니다. 기밀 리소스에 접근하는 처리는 샌드박스의 권한을 확장하는 대신 "좁고 검토된 호스트 도구"로서 분리해낼 수 있도록 하는 설계 사상을 가지고 있다. 샌드박스 측에 전달할 수 있는 권한은 읽기 전용인 /input, 쓰기 가능한 /output, file_mounts를 통한 경로 마운트(path mount), 그리고 allowed_domains를 통한 외부 통신 허용 목록(allowlist)으로 제한된다. 출력은 마지막 식의 값이 아니라 명시적으로 print(...)한 내용이 반환되며, 생성물은 /output/<파일명>에 작성해야 한다는 세부적인 규칙도 있다.
알파 버전이라 그런지 빈틈은 있다. 현재의 제약 사항을 솔직하게 나열하자면, 샌드박스의 게스트(guest)는 Python만 지원하며(.NET에서는 JavaScript 백엔드도 선택 가능), 지원 플랫폼은 Linux(KVM)와 Windows(WHP)뿐이라 macOS는 미지원이다. 또한 execute_code 호출을 넘나들며 인메모리(in-memory) 변수를 유지할 수 없다. 호출 간에 데이터를 남기려면 마운트된 파일이나 /output을 사용해야 한다.
실무적으로 또 하나 유효한 점은 도구의 "계약(contract)"이 갖는 무게가 달라진다는 것이다. 기존에는 모델이 도구 목록에서 하나를 선택하기만 하면 되었지만, CodeAct에서는 모델이 해당 도구의 시그니처(signature)에 맞춰 코드를 작성한다. 따라서 인자 이름, 타입 어노테이션(type annotation), 반환 값의 형태가 이전보다 훨씬 중요해진다. 형식이 허술한 타입 어노테이션을 가진 도구를 전달하면 모델이 올바른 코드를 작성하지 못해 오히려 실패가 늘어날 수 있다.
그리고 당연하게도, 이 방식이 효과적인 것은 "오케스트레이션 오버헤드가 지배적일 때"뿐이다. 도구 호출이 1~2회로 끝나는 가벼운 태스크라면, 마이크로 VM을 띄워 승인 경계(approval boundary)를 하나로 묶는 추상화 자체가 오버헤드가 된다. 공식 문서에서도 "작은 태스크에는 적합하지 않다"라고 명확히 밝히고 있다. 만능 스위치가 아니라, 도구 사용량이 많은(tool-heavy) 워크플로우를 위한 최적화라고 받아들이는 것이 옳다.
확인한 1차 소스는 다음 네 가지다. Build 2026 요약(Agent Framework Blog), CodeAct의 설계와 측정(codeact-with-hyperlight), 그리고 패턴 해설 및 연동 가이드인 공식 문서 2편(CodeAct / Hyperlight CodeAct)이다. 블로그와 문서 사이에서 import 문 표기가 일부 혼용되고 있어(agent_framework_hyperlight 직하인지 agent_framework.hyperlight인지), 코드는 더 최신 공식 문서 기준인 from agent_framework.hyperlight import ...에 맞추었다. 직접 실행해 볼 때는 설치 직후의 실제 모듈 구성을 확인하는 것이 좋다.
LLM 에이전트 (LLM Agent)의 최적화라고 하면, 흔히 "더 똑똑한 모델"이나 "더 빠른 추론 (Inference)"에 눈길이 가기 마련이다. CodeAct가 보여주는 것은, 병목 현상 (Bottleneck)이 종종 모델의 외부, 즉 도구 (Tool)를 어떻게 연결할 것인가에 대한 제어 흐름 (Control Flow)에 있으며, 그 부분을 코드로 구현하는 것만으로도 시간은 절반으로, 토큰 (Token)은 40% 가까이 줄일 수 있다는, 눈에 띄지는 않지만 효과적인 사실이다. Linux/Windows에서 다수의 도구를 호출하는 기존 에이전트를 보유하고 있다면, 벤치마크 재현은 pip install 한 번으로 시작할 수 있다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기