[논문 리뷰] Coding Agent Architecture — 코딩 에이전트 런타임을 분해하기
Ark 논문을 기준으로 코딩 에이전트를 agentic loop, prompt, tool, memory, context, error handling으로 분해해 본다.
Understanding the Architecture of Coding Agents: An Exploratory Study Using a Research Prototype
Marco Tulio Valente (2026)- arXiv
한 줄 요약
이 논문은 코딩 에이전트를 “LLM을 부르는 CLI”가 아니라 agentic loop, system prompt, tools, memory, context, error handling이 맞물린 런타임 아키텍처로 설명한다. 저자는 이를 보여주기 위해 Ark라는 최소 구현체와 ArkBench라는 작은 유지보수 벤치마크를 만들었다.
내 의견부터 말하면, 이 글감은 실용적이다. 요즘 코딩 에이전트 비교는 자꾸 모델 이름과 벤치마크 점수로 흐르는데, 실제로 팀에서 중요한 것은 “이 에이전트가 코드를 어떻게 읽고, 어떤 도구를 언제 호출하고, 실패를 어떻게 복구하고, 패치를 어떤 경계에서 적용하느냐”다. 모델은 중요하지만, 런타임 설계가 엉성하면 좋은 모델도 비싼 grep 봇이 된다.
왜 지금 중요한가
Claude Code, Codex, Cursor, OpenCode, Qwen Code 같은 도구가 빠르게 늘었다. 겉으로는 모두 “코딩 에이전트”지만 내부 동작은 꽤 다를 수 있다.
- 어떤 도구는 shell 권한을 넓게 열어준다.
- 어떤 도구는 patch application을 별도 검증 단계로 분리한다.
- 어떤 도구는 repo guidance 파일을 강하게 반영한다.
- 어떤 도구는 LSP, test runner, browser, MCP server를 tool graph로 붙인다.
- 어떤 도구는 trace와 replay를 남기고, 어떤 도구는 최종 diff만 남긴다.
사용자 입장에서는 “벤치마크에서 몇 점인가”보다 이 차이가 더 중요하다. 코딩 에이전트는 실제 repo를 바꾸는 실행 시스템이다. 따라서 아키텍처를 모르면 보안 경계, 실패 모드, 디버깅 비용을 예측하기 어렵다.
논문이 제안하는 Ark는 production-grade agent라기보다 교육·연구용 reference implementation에 가깝다. 그래서 오히려 읽을 가치가 있다. 너무 많은 feature가 들어간 에이전트보다, 최소 구성요소를 분해해 보여주는 작은 시스템이 설계 판단을 배우기 좋다.
핵심 구조: 코딩 에이전트는 여섯 덩어리다
논문이 설명하는 기본 구조는 단순하다.
- 사용자가 작업을 준다.
- 에이전트가 system prompt, task, memory, workspace instruction으로 context를 만든다.
- LLM이 다음 action을 고른다.
- 런타임이 tool을 실행한다.
- tool output을 memory에 기록한다.
- 다시 context를 만들고 반복한다.
- 완료 조건에 도달하면 patch 또는 final response를 반환한다.
이 구조를 코드 관점으로 줄이면 이런 루프다.
for iteration in range(max_iterations):
context = build_context(system_prompt, task, memory, workspace_rules)
action = llm.next_action(context)
if action.name == "finish":
return validate_and_apply_patch(action.input)
result = tools.run(action)
memory.append(iteration, action, result)너무 단순해 보이지만, 실제 설계 난이도는 각 함수 안에 있다. build_context가 무엇을 버리고 무엇을 유지하는지, tools.run이 어떤 권한으로 실행되는지, validate_and_apply_patch가 실패를 어떻게 다루는지가 에이전트 품질을 결정한다.
1. Agentic loop: 핵심은 반복이 아니라 제어권이다
논문은 agentic loop를 코딩 에이전트의 중심 컴포넌트로 본다. LLM에 한 번에 “수정해줘”라고 던지는 대신, LLM이 read/search/test/finish 같은 action을 하나씩 고르고 런타임이 실행 결과를 돌려주는 방식이다.
여기서 중요한 점은 LLM이 모든 것을 직접 실행하지 않는다는 것이다. LLM은 다음 action을 제안하고, 런타임은 그 action이 허용된 도구인지 검증한 뒤 실행한다. 이 경계를 흐리면 위험하다.
실무적으로는 아래 질문을 해야 한다.
- 한 iteration에서 action을 하나만 허용하는가, 여러 개 batch로 허용하는가?
- 최대 iteration 수는 어디서 끊는가?
- test 실패 후 자동 재시도는 몇 번까지 허용하는가?
- tool output이 너무 길면 어떤 방식으로 압축하는가?
- finish action은 자연어 보고인가, patch artifact인가?
나는 코딩 에이전트의 loop는 “모델을 더 생각하게 하는 장치”라기보다 비결정적 모델을 결정론적 실행 경계 안에 가두는 장치라고 보는 편이 맞다고 생각한다.
2. System prompt: 프롬프트가 아니라 프로토콜 문서다
Ark의 system prompt는 LLM에게 역할, 응답 형식, 사용 가능한 도구, 작업 제약, 종료 조건을 알려준다. 논문에서 흥미로운 지점은 system prompt가 agentic loop 코드보다 길다는 점이다. 이건 이상한 일이 아니다. 코딩 에이전트에서 prompt는 UX 문구가 아니라 runtime protocol이다.
좋은 system prompt에는 최소한 아래가 들어가야 한다.
- 응답 schema:
Thought,Action,Action Input처럼 파싱 가능한 형식 - tool 목록과 각 tool의 인자 형식
- workspace root 밖 접근 금지 같은 파일 경계
- 테스트를 언제 실행해야 하는지에 대한 정책
- 완료 조건과 finish format
- invalid response가 나왔을 때 repair할 수 있는 기준
반대로 “너는 훌륭한 시니어 개발자야” 같은 문장은 거의 중요하지 않다. 에이전트 prompt의 핵심은 격려가 아니라 계약이다. 모델이 따를 수 있고 런타임이 검증할 수 있는 형식이어야 한다.
3. Tools: 도구 목록은 능력 목록이자 공격면이다
Ark는 list_files, read_file, find_text, run_tests, finish 같은 제한된 도구를 제공한다. production agent라면 여기에 shell, git, package manager, browser, LSP, MCP server, database client 등이 붙을 수 있다.
도구가 많아질수록 성능은 좋아질 수 있지만, 공격면도 같이 커진다. 특히 코딩 에이전트에서 위험한 도구는 아래다.
- 임의 shell 실행
- 네트워크 접근
- secret이 있는 환경 변수 읽기
- package install / postinstall script 실행
- git push, release, deployment 같은 외부 side effect
- DB migration, infra mutation
그래서 tool 설계는 단순 wrapper가 아니라 policy 문제다. 예를 들어 run_tests는 안전한 편이지만 bash는 거의 모든 것을 할 수 있다. 둘을 같은 “tool” 추상화로만 보면 안 된다.
실무에서는 tool마다 아래 메타데이터를 붙이는 편이 낫다.
type ToolPolicy = {
name: string;
mutatesWorkspace: boolean;
touchesNetwork: boolean;
readsSecrets: boolean;
requiresApproval: boolean;
outputBudgetTokens: number;
};모델이 어떤 도구를 고르는지도 중요하지만, 런타임이 어떤 도구를 허용하고 어떤 결과를 context에 다시 넣는지가 더 중요하다.
4. Memory와 context: history 전체가 아니라 실행 상태를 보내라
논문에서 Ark의 memory는 실행 중 tool call, 인자, 결과를 기록하는 in-memory 자료구조다. 장기 메모리라기보다는 현재 run의 작업 기억에 가깝다. 이 memory를 바탕으로 다음 LLM 요청의 context를 구성한다.
여기서 코딩 에이전트의 흔한 실패가 나온다.
- 이미 읽은 파일을 계속 다시 읽는다.
- test를 돌렸는지 잊는다.
- 검색 결과 일부만 보고 성급하게 수정한다.
- 긴 tool output 때문에 중요한 작업 지시가 밀린다.
- patch 후 관련 import/call site를 끝까지 추적하지 않는다.
Ark는 “이미 읽은 파일, 수행한 검색, 테스트 실행 여부” 같은 현재 상태 summary를 context에 넣는다고 설명한다. 이 방향이 맞다. raw transcript를 계속 붙이는 것보다, 실행 상태를 구조화해서 제공하는 것이 낫다.
내가 production coding agent를 설계한다면 context를 최소 네 층으로 나눌 것이다.
- 정책 context: system prompt, AGENTS.md, 권한 규칙
- 작업 context: 사용자 요청, acceptance criteria, 현재 plan
- 근거 context: 읽은 파일, 검색 결과, diagnostics, test output
- 상태 context: 수정한 파일, 실패한 시도, 남은 risk, 다음 검증 단계
단순히 “최근 대화 N개”를 넣는 방식은 길게 보면 약하다. 코딩 에이전트에는 chat history보다 state reconstruction이 더 중요하다.
5. Error handling: LLM 실패를 정상 경로로 취급하라
Ark는 크게 두 종류의 오류를 다룬다.
- ReAct protocol 오류: LLM 응답이 정해진
Thought / Action / Action Input형식을 벗어나는 경우 - patch 오류: LLM이 만든 patch가 syntactically invalid하거나 적용에 실패하는 경우
이 지점이 중요하다. 많은 agent 데모는 모델이 항상 올바른 JSON이나 patch를 낼 것처럼 가정한다. 실제 운영에서는 그렇지 않다. 모델은 형식을 틀리고, observation을 스스로 지어내고, patch hunk를 깨뜨리고, 테스트가 통과했다는 식으로 말할 수 있다.
따라서 에이전트 런타임은 모델 출력을 신뢰하면 안 된다. 모델 출력은 항상 untrusted proposal이다.
function handleModelAction(action: unknown) {
const parsed = parseAction(action);
if (!parsed.ok) return askModelToRepairFormat();
const policy = checkToolPolicy(parsed.value);
if (!policy.allowed) return rejectAction(policy.reason);
return executeTool(parsed.value);
}코딩 에이전트의 신뢰도는 “모델이 똑똑한가”뿐 아니라 “모델이 틀렸을 때 런타임이 얼마나 좁고 명확하게 실패하는가”에서 나온다.
ArkBench 결과를 어떻게 읽을까
논문은 ArkBench라는 작은 benchmark도 제안한다. 대상은 mini e-commerce app이고, 10개 task로 구성된다.
- bug fix 3개
- refactoring 3개
- feature implementation 4개
논문에 따르면 Ark는 gpt-5.4-mini로 10개 중 8개를 해결했다. 평균 실행 시간은 약 23.5초, 평균 token 사용량은 3,342개, 평균 tool call은 7.1회다. 전체 API 비용은 0.50달러 미만이었다고 보고한다.
숫자는 흥미롭지만, 더 중요한 것은 실패 사례다.
첫 번째 실패는 visible test는 통과했지만 hidden case에서 잘못된 exception type을 냈다. 두 번째 실패는 refactoring에서 함수 정의와 일부 테스트는 고쳤지만 모든 import와 call site를 전파하지 못했다.
이건 실제 코딩 에이전트 실패와 꽤 닮았다.
- visible test에 overfit한다.
- 변경의 1차 위치는 맞추지만 2차 의존성을 놓친다.
- refactor는 bug fix보다 전역 추적이 어렵다.
- “테스트 통과”가 “작업 완료”를 의미하지 않는다.
그래서 코딩 에이전트 평가에는 unit test만으로 부족하다. structural verifier, hidden test, import graph check, public API compatibility check가 필요하다. 특히 refactoring task는 “동작이 같다”뿐 아니라 “요구한 구조 변화가 실제로 일어났는가”를 따로 봐야 한다.
실무 체크리스트: 코딩 에이전트를 고르거나 만들 때 볼 것
이 논문을 실무 관점으로 바꾸면 체크리스트는 꽤 명확하다.
1. Loop가 관측 가능한가
에이전트가 어떤 파일을 읽었고, 어떤 명령을 실행했고, 왜 그 action을 골랐는지 trace가 남아야 한다. 최종 diff만 남는 도구는 디버깅이 어렵다.
2. Tool 권한이 분리되어 있는가
read_file, run_tests, apply_patch, shell, network, git push는 같은 위험도가 아니다. tool policy와 approval boundary가 있어야 한다.
3. Context가 구조화되어 있는가
무작정 전체 repo를 넣거나 최근 transcript를 붙이는 방식은 오래 못 간다. 읽은 근거, 수정 상태, 테스트 결과, 남은 risk가 분리되어야 한다.
4. Patch 적용이 검증 가능한가
LLM이 만든 diff를 바로 믿지 말고, parser/formatter/typecheck/test를 통과해야 한다. 가능하면 patch application과 validation은 모델 바깥의 deterministic code가 맡아야 한다.
5. 실패를 학습 가능한 artifact로 남기는가
실패한 test output, invalid patch, 놓친 import, hidden verifier failure는 다음 run의 regression data가 되어야 한다. 에이전트 운영의 핵심은 성공률 숫자보다 failure corpus를 쌓는 것이다.
한계와 주의점
이 논문은 architecture를 설명하는 exploratory study에 가깝다. Ark는 의도적으로 작고, ArkBench도 10개 task짜리 lightweight benchmark다. 따라서 “Ark가 production coding agent보다 낫다”거나 “이 구조가 최적이다”라고 읽으면 안 된다.
또한 논문이 다루는 구성요소는 기본형이다. production 환경에서는 여기에 더 많은 문제가 붙는다.
- monorepo context selection
- LSP 기반 symbol navigation
- sandbox와 network egress policy
- dependency install 격리
- secret redaction
- multi-agent delegation
- PR review와 CI integration
- long-running task checkpoint/replay
그래도 기본 구조를 분해해 보여준다는 점에서 가치가 있다. 코딩 에이전트 논의는 지금 “더 큰 모델이 더 잘한다”에 과하게 쏠려 있다. 하지만 앞으로 차이는 model wrapper가 아니라 runtime architecture, verifier, context manager, tool policy에서 더 많이 날 가능성이 크다.
내 결론
코딩 에이전트를 제대로 쓰려면 “이 모델이 코딩을 잘하나?”보다 먼저 “이 런타임이 코딩 작업을 안전하게 반복·검증·복구할 수 있나?”를 물어야 한다.
이 논문의 좋은 점은 그 질문을 구체적인 컴포넌트로 쪼갠다는 데 있다. agentic loop, prompt protocol, tool boundary, memory/context, error handling, benchmark. 이 여섯 가지를 보면 코딩 에이전트를 훨씬 덜 신비롭게 평가할 수 있다.
내 기준으로는 앞으로 코딩 에이전트 비교표에 모델명과 SWE-bench 점수만 넣는 건 부족하다. 최소한 아래 열이 같이 있어야 한다.
- context manager 방식
- tool permission model
- patch validation 방식
- test/verifier integration
- trace/replay 지원
- hidden failure를 regression으로 저장하는지
코딩 에이전트는 chat product가 아니라 작은 운영체제에 가깝다. 운영체제를 고를 때 커널 구조와 권한 모델을 보듯, 코딩 에이전트도 런타임 아키텍처부터 봐야 한다.
참고 자료
- arXiv: Understanding the Architecture of Coding Agents: An Exploratory Study Using a Research Prototype
- PDF: arXiv PDF 2608.10934v1
- Ark GitHub: mtov/ark
- ArkBench GitHub: mtov/arkbench