장기 실행 에이전트를 위한 Orkas 재구축
요약
장기 실행 에이전트의 안정성을 높이기 위해 Orkas의 아키텍처를 리팩토링한 과정을 다룹니다. 에이전트 런타임, 메모리, 컨텍스트 관리 등 하위 계층을 재구축하여 단순 채팅 UI의 한계를 극복하는 데 집중했습니다.
핵심 포인트
- 에이전트 런타임을 엔진 계층과 어댑터 계층으로 분리하여 재사용성 확보
- 장기 실행 작업 및 급증하는 컨텍스트 관리를 위한 아키텍처 개선
- 로컬 파일 및 셸 명령 실행을 위한 강력한 도구 루프 보장
- 프로바이더 로테이션 및 멀티 에이전트 워크플로우 최적화
AI 에이전트 (AI agents)가 실패하는 이유는 단지 모델이 약하기 때문만은 아닙니다. 제품이 에이전트의 작업을 단일 챗봇 응답처럼 취급할 때 종종 문제가 발생합니다.
Orkas 1.0 기반 리팩토링 (foundation refactor)에서 우리는 시스템의 하위 계층인 에이전트 런타임 (agent runtime), 프로바이더 로테이션 (provider rotation), 오케스트레이션 (orchestration), 외부 호스팅 (external hosting), 메모리 (memory), 그리고 컨텍스트 관리 (context management)를 재구축했습니다.
이 포스트는 아키텍처 (architecture)의 변화와 그 이면에 담긴 교훈을 요약합니다.
리팩토링이 발생한 이유
Orkas는 AI 에이전트를 위한 로컬 우선 (local-first) 데스크톱 워크스페이스 (desktop workspace)입니다. 에이전트는 로컬 파일, 셸 명령 (shell commands), 프로젝트 폴더, 커넥터 (connectors), 스킬 (skills), 그리고 지식 베이스 (knowledge bases)와 함께 작업할 수 있습니다.
이는 일반적인 채팅 UI (chat UI)와는 다른 문제들을 만들어냅니다:
- 장기 실행 작업 (long-running tasks)은 많은 단계를 거칠 수 있음
- 컨텍스트 (context)가 빠르게 증가함
- 도구 호출 (tool calls)에는 순서 지정과 안전 규칙이 필요함
- 프로바이더 (providers)가 실행 도중 실패할 수 있음
- 사용자가 에이전트를 중단하거나 수정할 수 있음
- 멀티 에이전트 워크플로우 (multi-agent workflows)는 단순한 정적 계획이 아닌 조정 (coordination)이 필요함
이번 리팩토링은 이러한 고려 사항들을 채팅 스타일의 가정에 의존하는 대신 Orkas 자체의 기반으로 옮기는 것에 관한 것이었습니다.
1. 인프로세스 에이전트 런타임 (An in-process agent runtime)
핵심적인 변화는 독립적이고 동적으로 로드 가능한 인프로세스 (in-process) 에이전트 런타임이었습니다.
이는 두 개의 계층으로 나뉩니다:
- 엔진 계층 (Engine layer): 범용 에이전트 루프 (agent loop), 도구 호출 (tool calling), 스트리밍 (streaming), 컨텍스트 압축 (context compaction), 재시도 동작 (retry behavior), 프로바이더 추상화 (provider abstraction), 메모리 (memory), 그리고 자기 진화 (self-evolution)를 담당합니다.
- 어댑터 계층 (Adapter layer): 해당 엔진을 Orkas 전용 스토리지 (storage), 권한 (permissions), 스킬 (skills), 커넥터 (connectors), 프로바이더 로테이션 (provider rotation), 그리고 이벤트 형식 (event formats)에 연결합니다.
이러한 경계는 약간의 복잡성을 더하지만, 재사용 가능한 에이전트 메커니즘을 제품 특화된 배선 (product-specific wiring)으로부터 분리해 줍니다.
2. 데스크톱 에이전트에는 데스크톱급 도구 동작이 필요합니다
로컬 데스크톱 에이전트는 실제 파일에 접근하고, 로컬 명령을 실행하며, 프로젝트 디렉토리에 걸쳐 작업할 수 있습니다. 이는 도구 루프 (tool loop)에 더 강력한 보장이 필요함을 의미합니다.
몇 가지 세부 사항이 중요해졌습니다:
- 쓰기 전 읽기 (read before write)
- 오래된 편집 보호 (stale edit protection)
- 병렬 읽기 전용 작업 (parallel read-only operations)
- 순차적 쓰기 (ordered writes)
- 반복되는 도구 호출에 대한 루프 탐지 (loop detection for repeated tool calls)
- 안전한 경계에서의 중단 처리 (interruption handling at safe boundaries)
- 긴 보고서나 대규모 편집을 위한 충분한 출력 공간 확보 (enough output room for long reports or large edits)
이것들은 화려한 기능은 아니지만, 에이전트의 작업이 취약한 대신 예측 가능하게 느껴지도록 만드는 요소들입니다.
3. 컨텍스트는 비용이자 신뢰성의 문제
긴 작업은 읽기, 검색, 요약, 재시도, 압축, 오류 복구와 같은 작고 반복적인 단계에서 토큰을 소모합니다.
이번 리팩터링(refactor)을 통해 컨텍스트 처리(context handling)를 모델 인지적(model-aware)으로 개선했습니다. 하나의 보수적인 컨텍스트 제한(context limit)을 사용하는 대신, 런타임(runtime)이 모델의 실제 컨텍스트 창(context window)을 읽고 사용량 임계값(usage threshold)을 기준으로 압축을 수행합니다.
또한 요약을 통해 유용한 공간을 확보할 수 없는 경우에는 압축을 피합니다.
교훈: 컨텍스트 관리(context management)는 단순한 UX 기능이 아닙니다. 이는 비용, 지연 시간(latency), 그리고 에이전트가 작업을 완료할 수 있는지 여부에 영향을 미칩니다.
4. 프로바이더 로테이션은 에이전트 러너 하위에 위치해야 합니다
모델 호출은 실패합니다. 키(key)는 제한에 도달합니다. 네트워크는 끊어집니다.
Orkas는 프로바이더 로테이션(provider rotation)을 에이전트 러너(agent runner) 하위로 이동시켜, 사용자의 턴(turn)이 세션 상태(session state)를 복제하지 않고도 안전한 실패 상황에서 살아남을 수 있도록 했습니다.
로테이션 규칙은 보수적입니다:
- 의미 있는 출력이 나오기 전에 실패가 발생하면 다른 프로바이더를 시도할 수 있습니다.
- 텍스트나 도구 호출(tool calls)이 시작되면 로테이션을 중단합니다.
- 일시적인 실패(transient failures)는 재시도할 수 있습니다.
- 요청(request) 또는 정책(policy) 오류는 무분별한 재시도로 숨겨져서는 안 됩니다.
핵심은 프로바이더를 보이지 않게 만드는 것이 아닙니다. 장애 조치(failover)를 안전하게 처리할 수 있는 위치에 두는 것입니다.
5. 정적 계획에서 그룹 채팅 오케스트레이션으로
이전의 오케스트레이션(orchestration)은 더 정적인 계획/DAG 모델을 사용했습니다. 그것은 깔끔해 보였지만, 실제 에이전트 작업은 새로운 정보가 나타남에 따라 변화합니다.
Orkas는 동적인 그룹 채팅 오케스트레이션(group-chat orchestration) 방식으로 전환했습니다:
- 커맨더(Commander)가 방을 조정합니다.
- 워커 에이전트(worker agents)는 집중된 컨텍스트 조각(slices of context)을 전달받습니다.
- 디스패치(dispatch)는 구조화된 도구 호출(structured tool calls)을 통해 이루어집니다.
- 커맨더는 작업을 확산(fan out)시키거나, 합성(synthesize)하거나, 혹은 인계(hand off)할 수 있습니다.
이는 사전에 하나의 고정된 계획을 컴파일하는 것보다 장기 실행 작업(long-running tasks)에 더 적합합니다.
6. 경계를 제거하지 않고 시스템 개방하기
이번 리팩터링(refactor)을 통해 Orkas는 외부 기능에 대해 더욱 개방적으로 변했습니다:
- 외부 패키지 (external packages)
- 커스텀 스킬 (custom skills)
- 로컬 CLI (local CLIs)
- 사용자 설정 MCP 서버 (user-configured MCP servers)
- Orkas에서 실행되는 외부 에이전트 (external agents launched from Orkas)
중요한 제약 사항은 위험한 작업들이 여전히 통제된 경계를 통한다는 점입니다: 명시적인 사용자 확인, 가능한 경우 로컬 프로세스 격리 (local process isolation), 암호화된 자격 증명 (encrypted credentials), 그리고 외부 부작용 (external side effects)에 대한 권한 확인이 이에 해당합니다.
개방형 호스팅(Open hosting)은 신뢰 경계(trust boundary)가 명확하게 유지될 때만 유용합니다.
7. 메모리와 자기 진화(self-evolution)에는 제한이 필요합니다
Orkas는 또한 다음과 같은 단순한 원칙을 중심으로 메모리와 자기 진화(self-evolution)를 재구축했습니다:
제한적이고, 관찰 가능하며, 적절한 경우 기본적으로 비활성화(off by default)되어야 한다.
메모리는 로컬에 존재하며 사용자 선호도(user preferences) 및 에이전트 노트(agent notes)와 같은 카테고리로 분리됩니다. 검색(Retrieval)은 의미론적 검색(semantic search)과 키워드 검색(keyword search)을 결합합니다.
자기 진화(Self-evolution)는 에이전트 전용(agent-private)입니다. 에이전트는 수정 사항, 오류 복구(error recovery), 반복되는 작업 패턴을 기반으로 개인 스킬이나 역량 노트(competence notes)를 업데이트할 수 있지만, 비용 제어(cost controls)와 명시적인 세션 동작에 의해 제한됩니다.
"사용할수록 개선되는 에이전트"는 사용자가 무엇이 변하고 있는지 이해하고 제어할 수 있을 때에만 유용합니다.
우리가 배운 점
에이전트 인프라(Agent infrastructure)는 채팅 인프라(chat infrastructure)와는 다른 형태를 가집니다.
프로덕션 에이전트 런타임(production agent runtime)은 다음을 처리해야 합니다:
- 도구 순서 지정 (tool ordering)
- 부작용 (side effects)
- 프로바이더 장애 (provider failures)
- 컨텍스트 압박 (context pressure)
- 토큰 비용 (token cost)
- 사용자 중단 (user interruption)
- 오케스트레이션 상태 (orchestration state)
- 로컬 보안 경계 (local security boundaries)
- 메모리 제한 (memory limits)
주요 과제는 복잡성이 어디에 위치해야 하는지를 결정하는 것입니다.
Orkas의 경우, 그 답은 다음과 같았습니다:
- 런타임 엔진(runtime engine)에는 일반적인 에이전트 동작 (generic agent behavior)
- 어댑터(adapter)에는 제품 특화된 배선 (product-specific wiring)
- 그룹 채팅 메시지 버스(group-chat message bus)에는 오케스트레이션 (orchestration)
- 명시적 동의 뒤에 위험한 외부 작업 (risky external actions)
- 로컬 제어 뒤에 메모리와 자기 진화 (memory and self-evolution)
마치며
Orkas 1.0의 기초 재구축 (foundation refactor)은 단순히 더 많은 표면적 기능 (surface features)을 추가하기 위한 것이 아니었습니다. 그것은 장기 실행 로컬 에이전트 (long-running local agents)의 하부 운영 계층 (operating layer)을 재구축하는 것에 관한 것이었습니다.
만약 당신이 에이전트 시스템, 특히 로컬 우선 (local-first) 또는 데스크톱 에이전트를 구축하고 있다면, 얻을 수 있는 교훈은 간단합니다:
결국 당신은 모델 API (model API)를 중심으로 구축하는 것을 멈추고, 에이전트 (agent)를 중심으로 런타임 (runtime)을 구축하기 시작할 것입니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기