Claude Code, Codex, Hermes, Pi 등 11개 Coding Agent에서 본 'Agent Harness'의 설계 원칙
요약
본 논문은 Claude Code, Codex 등 11개 코딩 에이전트를 분석하여 'Agent Harness'의 설계 원칙을 제시합니다. Agent를 Model과 외부 소프트웨어인 Harness로 정의하고, 이 Harness가 LLM 호출, Context 관리, Tool 사용 등을 담당하는 핵심 구조임을 밝힙니다. 이를 통해 실제 프로덕션 환경에서 작동하는 코딩 에이전트들의 공통적인 아키텍처와 설계 패턴을 심층적으로 분석했습니다.
핵심 포인트
- Agent = Model + Harness로 정의되며, Harness가 Agent의 안정성과 성능을 결정한다.
- 11개 주요 Coding Agent를 소스 코드 레벨에서 비교하여 7가지 핵심 Subsystem으로 분해했다.
- Tool System이나 Memory 관리 등 각 시스템별 구현 규모와 방식의 차이를 파악할 수 있다.
- 제시된 7가지 요소는 실제 코딩 에이전트 설계 시 유용한 체크리스트 역할을 한다.
같은 LLM을 사용하더라도 Coding Agent에 따라 사용 편의성은 상당히 다릅니다.
어떤 Agent는 장시간 작업에도 안정적으로 작동합니다. 반면, 몇십 분 만에 문맥을 잃거나 매번 approval을 요구하여 작업이 멈추는 Agent도 있습니다.
이러한 차이는 모델 성능만으로는 설명할 수 없습니다.
2026년 7월에 공개된 Barbaste et al. (2026)의 논문 「Harness Engineering: Anatomy, Architecture, and Evolution of Coding Agents」에서는 모델 외부에 있는 소프트웨어를 Agent Harness라고 정의하고, Claude Code, Codex, Hermes, Pi, OpenCode를 포함한 11개의 Coding Agent를 소스 코드 레벨에서 비교했습니다.
논문에서는 Agent를 다음과 같이 단순하게 정의합니다.
Agent = Model + Harness
Harness에는 LLM을 호출하는 Loop, Tool, Context 관리, Permission, Sub-agent, 그리고 MCP나 Skills와 같은 확장 메커니즘까지 포함됩니다.
조사 대상은 Claude Code, Codex CLI, Gemini CLI, Mistral Vibe, OpenHands, Aider, Mini-SWE-Agent, Hermes, Pi, OpenCode, OpenClaw의 11개 시스템입니다. 또한 Databricks의 Omnigent을 Meta-Harness로 분석했습니다.
약 400만 라인에 달하는 Python, TypeScript, Rust 코드를 조사하여 13개의 교차 관찰(Observation), 29개의 설계 패턴(Design Pattern), 18개의 설계 권장 사항(Design Recommendation)을 정리했습니다.
이 논문의 흥미로운 점은 주요 Coding Agent를 동일한 7가지 관점에서 분해하고, Production 환경에서 실제로 어떤 설계가 선택되었는지 소스 코드로부터 비교할 수 있다는 점입니다.
Claude Code나 Codex와 같은 완성된 제품을 개별적으로 살펴보는 것만으로는 파악하기 어려운 공통적인 설계 원칙이나 각 시스템의 차이점이 상당히 구체적으로 드러납니다.
Agent Harness를 구성하는 7가지 요소
논문에서는 Coding Agent의 Harness를 7개의 Subsystem으로 분해했습니다.

| Subsystem | 역할 | 최소 구성 예시 | 대규모 구현 예시 |
|---|---|---|---|
| Agent Loop | LLM 호출과 Action 실행을 반복하며, 종료 조건이나 Recovery를 관리함 | Mini-SWE-Agent의 단순한 while loop | OpenHands의 Event-sourced loop |
| ... | |||
| 이 테이블을 보면, 같은 Subsystem이라도 구현 규모가 몇 자릿수나 차이가 납니다. |
예를 들어 Tool System은 Mini-SWE-Agent라면 bash만 사용합니다. 반면 Claude Code는 43종류의 typed tool을 가지고 있습니다.
Memory도 마찬가지입니다. 히스토리를 그대로 보존하는 구성도 있지만, Codex처럼 Agent 자신이 session을 넘나들며 Memory를 정리하는 메커니즘도 있습니다.
하지만 구현 방식이 다르더라도 모든 Agent는 이 7가지 문제에 어떤 식으로든 답을 가지고 있습니다.
'Tool을 몇 개 가져야 하는가'는 시스템마다 다를지라도, 'Agent에게 무엇을 실행하게 할 것인가'라는 설계 문제 자체는 사라지지 않습니다.
이 7가지 분류는 직접 Agent를 설계할 때의 체크리스트로도 유용하다고 생각합니다.
Agent Loop는 생각보다 단순해도 좋다
11개 시스템의 Agent Loop는 크게 3가지 종류로 분류됩니다.
가장 일반적인 것이 다음과 같은 Iterative Action-Observation 형태입니다.
Prompt
↓
LLM
...
Claude Code, Codex, Gemini CLI, OpenHands 등 많은 Agent가 이 계통에 속합니다.
Aider는 약간 달라서 코드를 수정한 후 lint나 test를 실행하고, 문제가 있으면 그 결과를 다시 LLM에게 되돌립니다. 논문에서는 Reflection-Augmented Loop로 분류되었습니다.
Claude Code나 Codex에서는 더 나아가 Coordinator가 여러 Worker를 구동하는 Coordinator-Worker 형태가 추가되어 있습니다.
다만, 여기서 중요한 것은 루프(Loop)를 복잡하게 만든다고 성능이 올라가는 것은 아니다라는 점입니다.
Mini-SWE-Agent의 루프는 놀라울 정도로 작으며, 기본적으로 while loop로 LLM과 bash를 왕복하는 것뿐입니다.
while True:
response = model(messages)
if response.is_final:
...
실제 구현은 조금 더 있지만, 본질은 이와 같습니다.
그럼에도 불구하고 논문에서 인용된 자체 보고 SWE-Bench 결과는 대규모 Harness와 비슷한 범위에 들어 있습니다.
논문에서는 이 결과를 통해 루프의 복잡도가 벤치마크 성능을 예측하지 못한다고 지적합니다.
그렇다면, 대규모 Coding Agent는 왜 수십만~100만 줄 규모가 되는 것일까요?
증가하는 부분은 주로 Safety, Recovery, UI, Plugin, Transport, Session 관리와 같이 실제 운영에 필요한 부분입니다.
즉, Agent로서 작동하게 하는
것 자체는 비교적 쉽지만, Agent를 안심하고 매일 사용할 수 있는
상태로 만들기 위해서는 방대한 엔지니어링이 필요하다는 것입니다.
논문의 Recommendation 1도 먼저 선형적인 while loop부터 시작할 것을 권장합니다.
턴 제한(turn limit), 비용 제한(cost limit), 자동 압축(auto compaction), 읽기 전용 모드(read-only mode) 등 독립적인 정책(Policy)이 늘어나 단계적으로 미들웨어화(Middleware化)하면 된다는 생각입니다.
Recommendation 1. 먼저 선형적인 while 루프부터 시작하고, 독립된 턴 단위의 정책이 증가한 단계에서 미들웨어 파이프라인으로 전환한다. 근거는 Observation 1이다. Agent Loop의 복잡도는 Benchmark 성능을 예측하는 것이 아니며, Mini-SWE-Agent는 약 50줄의 선형 루프로 SWE-Bench Verified에서 74% 이상의 성능을 보고했다(자체 보고치. Table 4 주석 참조).
확장의 기준으로, 턴 수 상한, 비용 상한, 자동 압축, 컨텍스트 예산 경고(Context Budgetの警告), 읽기 전용 모드 등 서로 독립적인 턴 단위의 정책이 3개 이상 필요해지면 Mistral Vibe의 Middleware Pipeline Pattern을 채택한다.
이 구성에서는 새로운 정책을 루프 본체의 조건 분기로 추가하는 것이 아니라, 각각을 조합 가능한 미들웨어로 구현합니다.
11개를 조사해도 LangChain을 사용하는 Agent는 0개였다
개인적으로 이 논문에서 특히 흥미로웠던 것은 존재하는 기능보다 **'존재하지 않았던 기술'**이었습니다.
11개 시스템의 Agent Runtime에서는 LangChain, LangGraph, AutoGen, CrewAI와 같은 범용 Agent Framework가 하나도 사용되지 않았습니다.
Gemini CLI 역시 Google 자체의 Agent Framework를 사용하고 있지 않습니다.
각 Harness는 Python의 asyncio, TypeScript의 Promise, Rust의 Tokio와 같이 언어 표준에 가까운 비동기 처리 방식을 사용하여 Agent Loop를 직접 구현했습니다.
물론, LangGraph를 사용하면 Agent 성능이 나빠진다라는 의미는 아닙니다.
이 논문은 성능 비교를 수행하지 않았으며, 동적으로 로드되는 내부 Dependency까지 완전히 추적한 것도 아닙니다.
그럼에도 불구하고, Claude Code나 Codex 같은 제품이 루프를 자체적으로 가지고 있는 이유는 짐작할 수 있습니다.
Agent Runtime에서는 다음 동작들을 세밀하게 제어해야 합니다.
- Prompt
- Tool Call
- Streaming
- Retry
- Permission
- Context
- Caching
추상화 계층(abstraction layer)이 늘어날수록, 문제가 발생했을 때 실제로 LLM에게 무엇이 전달되었는지를 추적하기 어려워집니다.
논문의 Recommendation 15에서는 Agent Runtime에 대해 raw SDK call을 사용하거나, 2026년 시점에서는 Claude Agent SDK, Codex, OpenHands SDK와 같은 Harness SDK를 시작점으로 삼는 방법이 제시되었습니다.
여기서는 '프레임워크가 필요 없어졌다'기보다는, Harness 자체가 프레임워크의 역할을 하기 시작했다고 생각하는 것이 더 자연스럽습니다.
Code RAG에도 Embedding을 사용하지 않는다
또 다른 '0/11'은 Code Retrieval입니다.
11개 시스템 모두 소스 코드 검색의 주요 수단으로 Vector Embedding을 사용하고 있지 않습니다.
대신 사용되는 것은 다음과 같습니다.
- ripgrep
- glob
- tree-sitter
- 파일 경로(file path)
- Language Server
- Markdown Context File
이는 일반적인 RAG Application과는 상당히 다릅니다.
코드에는 src/auth/login.ts 와 같이 경로 자체에 의미가 있을 뿐만 아니라, 클래스(class), 함수(function), import, 참조(reference), 심볼(symbol), 타입(type) 등 검색에 활용할 수 있는 명시적인 구조 정보가 풍부합니다.
코드에는 본래부터 명시적인 구조가 있어, src/auth/login.ts 와 같이 경로 자체가 의미를 가지는 것 외에도, 클래스, 함수, import, 참조, 심볼, 타입 등 검색에 활용할 수 있는 구조 정보가 풍부합니다.
게다가 Coding Agent는 스스로 Repository를 수정합니다.
Embedding Index는 코드 변경이 일어날 때마다 구식이 될 가능성이 있습니다. 따라서 논문의 Recommendation 8과 16에서는 우선 ripgrep + glob + tree-sitter 와 같은 결정론적 검색(deterministic retrieval)을 사용하는 것을 권장하고 있습니다.
의미론적 검색(Semantic Retrieval)이 정말 필요하다면, 홀드아웃 태스크(held-out task)로 개선 확인을 거친 후에 Embedding을 추가해야 한다는 입장입니다.
RAG를 평소 다루다 보면 Repository가 커질수록 Vector DB를 넣고 싶어집니다.
하지만 Coding Agent에서는 Repository 자체가 이미 상당히 강력한 Index를 가지고 있다는 관점이 흥미롭습니다.
Tool이 많다고 좋은 것은 아니다
Tool의 개수도 시스템마다 상당히 다릅니다.
Mini-SWE-Agent는 bash만 사용합니다.
Pi는 7개를 구현했고, 기본값(default)에서는 더 적은 수로 제한하고 있습니다.
반면, Claude Code는 43개, Hermes는 69개, OpenClaw는 100개를 넘습니다.
그럼에도 불구하고 논문의 Recommendation 3은 처음에는 bash만으로도 충분하다는 입장입니다.
예를 들어, bash의 출력이 너무 길어서 다루기 어려워지면 read_file 을 추가합니다.
파일 전체를 다시 작성하면서 토큰을 대량 소비하게 되면 search_replace 를 추가합니다.
즉, Tool을 처음부터 만들어 넣는 것이 아니라, 실제로 관측된 실패 모드(Failure Mode)에 따라 필요한 Tool을 추가해 나가는 사고방식입니다.
더 나아가 Tool의 개수가 15개 전후를 넘어서면 다른 문제가 발생합니다.
모든 Tool Schema를 매번 Prompt에 넣으면, 그것만으로도 Context를 대량 소비하게 됩니다.
Claude Code는 이 문제에 대해 Deferred Tool Loading을 구현했습니다.
모든 Tool을 처음부터 Model에게 보여주는 것이 아니라, 필요한 Tool을 ToolSearch 를 통해 나중에 불러옵니다.
논문에 따르면, 이 메커니즘 덕분에 초기 Prompt를 약 40% 줄일 수 있었습니다.
Codex 역시 유사하게 BM25 기반의 tool_search 를 가지고 있습니다.
Hermes에서는 MCP나 Plugin의 Tool Schema가 Context Window의 10%를 초과하면, Tool 그룹을 검색형 브릿지 Tool(Bridge Tool)로 압축합니다.
MCP Server를 대량으로 연결한 Agent에서 Context가 부풀어 오르는 문제에도 그대로 적용할 수 있는 설계입니다.
Memory는 '어떻게 요약하는가'에서 '누가 작성하는가'로
Context가 길어졌을 때의 처리는 상당히 정점에 달했습니다.
Claude Code, Codex, Gemini CLI, Mistral Vibe, Hermes, Pi, OpenCode 등은 일정 임계값(Threshold)을 넘으면 LLM으로 이력을 압축합니다.
다만, 최근 구현에서는 모든 이력을 매번 처음부터 요약하지는 않습니다.
Gemini CLI는 최근 기록을 일정량 그대로 유지합니다.
Pi나 OpenCode는 이전의 요약(Summary)을 다음 요약에 입력하여 점진적으로 업데이트합니다.
Mistral Vibe는 압축(Compaction) 후에 과거 사용자 요청(User Request)을 재주입합니다.
여기까지가 Context Management에 대한 이야기인데, 논문에서는 2026년이 되어서부터 다른 변화도 일어나고 있다고 지적하고 있습니다.
차이가 나기 시작하는 것은 Persistent Memory의 쓰기 경로입니다.
Codex는 최근 세션에서 메모리 후보를 추출하여 내부 Sub-agent가 정리한 후 다음 세션에서 사용할 수 있도록 합니다.
Gemini CLI는 다른 설계를 채택하고 있습니다.
세션에서 추출한 메모리 후보를 받은 편지함(Inbox)에 두고, 사용자가 확인한 후에 반영합니다.
Hermes는 더 간단해서 크기 제한이 있는 Markdown을 Memory로 사용합니다.
즉, Memory 설계에서는 어떤 Vector DB를 사용할 것인지보다, 누가 Memory를 쓰고, 누가 승인하고, 언제 Context로 되돌릴 수 있는지에 대한 쓰기 및 반영 메커니즘이 중요해지고 있습니다.
Safety는 Prompt가 아닌 Runtime 쪽으로 이동하고 있다
Production Agent의 코드량이 늘어나는 큰 이유 중 하나가 Safety입니다.
Codex의 Safety는 여러 레이어로 구성되어 있습니다.
Execution Policy
↓
Lifecycle Hooks
...
OS Sandbox에 대해서는 Linux에서는 Bubblewrap, macOS에서는 Seatbelt, Windows에서는 restricted token을 사용하고 있습니다.
Gemini CLI 역시 PLAN, DEFAULT, AUTO_EDIT, YOLO 같은 승인 모드(Approval Mode) 외에도 OS Sandbox와 Policy를 갖추고 있습니다. Claude Code도 Permission Rule, Hook, Sandbox Runtime을 조합하여 사용합니다.
여기서 흥미로운 점은 Safety Policy가 System Prompt상의 지시에서 Runtime 측에서 강제할 수 있는 메커니즘으로 이동하기 시작했다는 것입니다.
예를 들어, '이 명령어는 실행하지 않는다'라고 Prompt에만 적는 것만으로는 최종적인 판단이 Model의 해석에 의존합니다. 이에 반해, Codex는 Starlark의 Execution Policy, Gemini CLI는 TOML 기반의 Policy, Claude Code는 PreToolUse Hook을 사용하여 실행 시점에 판별할 수 있는 형태로 구현하고 있습니다.
Agent에게 큰 권한을 부여할수록 Prompt Engineering뿐만 아니라 Runtime 측에서 동작을 제어하는 Engineering이 중요해집니다.
Multi-Agent는 나중에 추가한다
최근에는 Agent를 만들면 바로 Multi-Agent 구성을 생각하게 됩니다.
하지만 이 논문의 Recommendation 12는 상당히 신중합니다.
먼저 Single Agent로 시작해야 합니다.
그 위에, '병렬 탐색을 통해 Context를 분리하는 것이 확실히 유리하다'라는 Task가 발견된 후에 Sub-agent를 도입할 것을 권장하고 있습니다.
Claude Code는 Agent를 재귀적으로 생성(spawn)할 수 있습니다.
Codex는 Thread Tree를 가지고 있습니다.
Gemini CLI는 Agent Registry와 A2A(Agent to Agent)를 구현했습니다.
반면, Pi는 Sub-agent를 Core에 넣지 않고 Extension으로 제공합니다.
Multi-Agent는 공짜가 아닙니다.
논문이 참조한 Anthropic의 Multi-Agent 연구에서는 Orchestrator-Worker 형태가 병렬 리서치(Research)에서는 유효했지만, 단순 채팅 기준선(Chat baseline)과 비교하여 약 15배 많은 Token을 소비했습니다.
코드 수정처럼 하나의 상태를 연속적으로 변경해 나가는 Task에서는 Sub-agent를 늘릴수록 Coordination Cost도 증가합니다.
따라서 Multi-Agent화 자체를 목적으로 삼기보다는, 병렬화를 통한 이점이 명확한 Task에 도입하는 순서가 자연스럽습니다.
Skills, MCP, ACP는 역할이 분리되기 시작했다
확장성(Extensibility)에 대해서도 몇 가지 공통 패턴이 보입니다.
논문 조사에 따르면, Skills가 11개 시스템 중 9개에서, MCP가 8개에서 채택되었습니다.
ACP도 6개 시스템까지 증가했습니다.
논문의 Recommendation 14에서는 Skills와 MCP의 역할을 상당히 명확하게 구분하고 있습니다.
Skills
Workflow, Domain Knowledge, 절차 등을 Agent에게 전달하는 Capability Template입니다.
예를 들어 다음과 같습니다.
코드 리뷰 절차
릴리스 작업 절차
사내 API를 이용할 때의 규칙
...
MCP
데이터베이스(Database), Slack, 사내 API(Internal API) 등 외부 시스템과의 통합(Integration)에 적합합니다.
ACP
IDE나 다른 Harness 등 외부 호스트에서 Agent 자체를 조작하는 프로토콜로 사용되기 시작했습니다.
OpenHands에서는 Claude Code, Codex, Gemini CLI를 교체 가능한 백엔드(Backend)로 다루는 용도까지 나오고 있습니다.
이러한 분류는 구현할 때에도 사용하기 쉽습니다.
새로운 절차를 Agent에게 가르치고 싶을 뿐이라면, 당장 MCP 서버를 만들 필요가 없습니다. Skill만으로 충분할 가능성이 높습니다.
외부 프로세스나 API와의 연결이 필요해진 단계에서 MCP를 고려하면 됩니다.
설계 원칙에 18가지 Recommendation을 정리하다
논문의 Section 16에는 18개의 Recommendation이 있습니다.
모두 나열하면 길기 때문에, 설계 판단 기준으로 요약하면 다음과 같습니다.
| 영역 | 설계 원칙 |
|---|---|
| Loop | 선형(linear) while loop부터 시작한다. 정책(Policy)이 늘어나면 미들웨어화(Middleware化)한다 |
| ... | |
| 이 18개 항목을 살펴보면, 논문 전체에 공통적으로 나타나는 설계 사상이 보입니다. |
기능을 미리 만들어 두지 않고, 관측된 실패 모드(Failure Mode)에 대응하는 최소한의 메커니즘을 추가하는 것입니다.
약 90줄 분량의 Minimum Viable Harness
논문의 Section 16.10에서는 지금까지의 Recommendation들을 요약한 약 90줄 분량의 Python 구현이 Minimum Viable Harness로 제시되었습니다.
이 구현에는 주로 다음 요소들이 포함되어 있습니다.
- Mini-SWE-Agent와 같은 선형(linear) 루프
- Mistral Vibe를 참고한 턴 단위의 정책(Policy)
bash,read_file,write_file,search_replace네 가지 도구(Tool)- 계층적(
AGENTS.md) 파일의 자동 탐색 - 턴/비용 제한 - 임계값(Threshold)을 초과했을 때의 Context Compaction
Agent Loop 자체는 간단한 while 루프이며, 각 턴 전에 제한(limit)과 Compaction 상태를 확인하고, LLM이 Tool Call을 반환하면 해당 도구를 실행하고 그 결과를 Context로 되돌립니다.
Context Compaction 역시 비교적 단순합니다. Context가 설정된 임계값을 초과하면, 지금까지의 대화를 LLM으로 요약하여 System Prompt, Summary, 그리고 직전 30%의 기록만 남깁니다.
반면, Sandbox, Multi-Agent, MCP, Skills는 의도적으로 포함되어 있지 않습니다. 게다가 Framework, RAG, Vector Store에도 의존하지 않습니다.
저자들은 이 구현을 프로덕션 코드(Production Code)가 아니라, 복사하여 용도에 맞게 확장하기 위한 스캐폴드(Scaffold)로 위치시키고 있습니다. 또한 18개의 Recommendation 중 10개를 직접 구현하고, 나머지 8개는 호환성이 있다고 말합니다.
이 구현이 참고가 되는 점은 Coding Agent의 최소 구성과, 거기서부터 기능을 추가해 나가는 순서가 구체적으로 보인다는 것입니다.
처음부터 Multi-Agent나 영구 메모리(Persistent Memory), 복잡한 워크플로우를 준비하는 것이 아니라, 먼저 작은 루프와 도구부터 시작하고 실제로 관측된 실패 모드에 따라 필요한 기능을 추가해 나가는 방식입니다. 논문 전체에서 반복적으로 언급되는
이 논문을 읽을 때 주의할 점
본 연구는 11개의 Coding Agent를 동일한 Task나 Model로 비교한 벤치마크가 아니라, 소스 코드(Source Code)를 기반으로 아키텍처를 분석한 스터디입니다.
또한, 논문 중에 등장하는 SWE-Bench 수치는 각 시스템이 자체 보고한(self-reported) 결과이며, 사용된 Model이나 Configuration, 측정 시기까지 통일되어 있지 않습니다. 따라서 성능을 직접 비교하기 위한 숫자가 아니라, 각 Harness의 설계를 이해하기 위한 참고치로 보아야 합니다.
본 논문은 어떤 아키텍처가 가장 고성능인지 판단하기보다는, 주요 Coding Agent들이 실제로 어떤 설계 방식을 채택하고 있는지 알아보기 위한 레퍼런스로 읽는 것이 적절합니다.
요약
이 논문을 읽고 가장 인상 깊었던 점은, Production Agent를 지탱하는 것은 Context, Tool, Memory, Safety, Orchestration과 같은 주변의 엔지니어링(Engineering)이라는 것입니다.
Agent Loop 자체는 단순해도 성립합니다. 먼저 작은 루프와 최소한의 Tool부터 시작하여, 실제로 발생한 Failure Mode에 따라 Compaction, Permission, Persistent Memory, Sub-agent 등을 추가해 나가는 방식이 전체적으로 일관되어 있습니다.
**'모델 외부를 어떻게 설계할 것인가'**를 생각하기 위한 레퍼런스로 매우 참고가 되는 논문이었습니다.
토론(Discussion)

AI 자동 생성 콘텐츠
본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기