같은 작업이 같은 해결책으로 이어지지 않는 이유
Coding Agent에게 같은 질문을 다섯 번 던지면 서로 다르지만 각각 나름대로 타당한 여러 해결책을 받을 수 있습니다.
그렇다고 다섯 번 시도할 때마다 반드시 다섯 개의 완전히 다른 구현이 나온다는 뜻은 아닙니다. 과제가 좁게 정의되어 있고 기존 코드가 강한 관례를 이미 제공하고 있다면, 여러 Run 사이의 큰 부분은 비슷해질 가능성이 높습니다. 또한 Large Language Model이 매번 아무 이유 없이 다른 방향으로 튀는 순수한 랜덤 머신이라는 뜻도 아닙니다.
기술적으로 더 중요한 사실은 따로 있습니다.
같은 작업이 항상 같은 해결 경로와 같은 구현으로 이어진다는 기술적 보장은 없습니다.
단순한 텍스트 생성에서는 이런 특성이 이미 오래전부터 알려져 있었습니다. 하지만 Coding Agent에서는 한 단계가 더 추가됩니다. Agent는 단순히 텍스트나 코드를 생성하지 않습니다. Repository를 탐색하고, 파일을 읽고, Tools를 선택하고, 테스트를 실행하고, 그 결과를 해석한 뒤 다음 행동을 조정합니다.
따라서 Agent는 단순히 답을 생성하는 것이 아니라 해결책에 도달하는 경로를 구성합니다.
바로 이 지점에서 Agentic Software Development를 더 빠른 새로운 조립 라인으로 보는 관점이 흔들리기 시작합니다.
조립 라인 작업이라는 신화
섹션 제목: “조립 라인 작업이라는 신화”AI Productivity에 대한 많은 논의는 머릿속에서 다음과 같은 단순한 모델로 축약할 수 있습니다.
Ticket ↓Agent ↓예측 가능한 처리 ↓Patch이 그림이 맞다면 Coding Agent는 결국 새로운 형태의 자동화일 뿐입니다. 더 많은 Ticket을 넣고, 얼마나 빠르고 저렴하게 코드를 생산하는지만 측정하면 될 것입니다.
일부 작업에서는 실제로 이 모델과 꽤 비슷한 결과가 나올 수 있습니다. 과제가 좁게 정의될수록, 기존 구조가 해결 공간을 강하게 제한할수록, 그리고 Agent가 스스로 결정해야 할 것이 적을수록 여러 Run은 서로 비슷해질 수 있습니다.
하지만 Agentic Work가 진짜 흥미로워지는 지점은 해결 경로가 완전히 사전에 정해져 있지 않을 때입니다.
Anthropic은 그래서 Workflows와 Agents를 구분합니다. Workflows에서는 Model과 Tools가 미리 정의된 코드 경로를 따라 오케스트레이션됩니다. 반면 Agents에서는 Model이 작업을 어떻게 처리할지, 어떤 Tools를 사용할지 스스로 결정합니다. OpenAI도 Agents를 비슷하게 설명합니다. Model이 Workflow를 제어하고, 의사결정을 내리며, 현재 상태에 따라 Tools를 동적으로 선택하는 시스템이라는 것입니다.
이 차이는 단순한 용어 문제가 아닙니다.
고정된 Workflow는 실행 중에 갑자기 “이번에는 다른 길이 더 나아 보인다”고 판단하지 않습니다. Agent는 바로 그런 판단을 합니다.
Agent는 동일한 생산 패턴을 보장하는 Ticket-to-Patch 머신이 아닙니다.
따라서 Agentic Work는 조립 라인보다는 변화하는 Context 안에서 이어지는 일련의 의사결정에 더 가깝습니다.

전통적인 소프트웨어에서 결정론이 의미하는 것
섹션 제목: “전통적인 소프트웨어에서 결정론이 의미하는 것”소프트웨어 개발에서는 입력과 출력 사이의 경로가 코드로 완전히 정의된 시스템에 익숙합니다.
단순화하면 다음과 같습니다.
Input ↓Step A ↓Step B ↓Step C ↓Output같은 입력이 주어지고 관련 상태가 바뀌지 않았다면, 우리는 같은 실행 흐름과 같은 결과를 기대합니다.
물론 전통적인 소프트웨어에도 차이를 만드는 요소는 많습니다. 시간, 동시성, 외부 서비스, 네트워크 상태, 랜덤 값, 변경된 데이터베이스 등이 그렇습니다. 중요한 차이는 이런 변동성을 보통 명시적인 시스템 상태의 일부로 모델링할 수 있다는 점입니다. 알고리즘 자체가 오늘은 B1 대신 B2가 더 그럴듯해 보인다고 즉흥적으로 판단하지는 않습니다.
많은 자동화는 바로 이 성질에 의존합니다.
Formatter는 같은 파일을 같은 방식으로 포맷해야 합니다. Compiler는 같은 조건에서 같은 소스 코드로부터 같은 결과를 만들어야 합니다. CI Pipeline은 매번 실행될 때마다 어떤 Quality Check가 이번에는 더 의미 있어 보이는지 새로 판단해서는 안 됩니다.
이런 문제에서는 결정론이 매우 가치 있습니다.
그리고 이것이 Agents를 조립 라인으로 상상하는 모델이 왜 매력적인지도 설명해 줍니다. 소프트웨어 개발은 수십 년 동안 반복 작업을 점점 더 결정론적인 프로세스로 바꿔 왔습니다.
하지만 Coding Agent는 이 흐름에 추가된 또 하나의 고정된 단계가 아닙니다. 일정한 경계 안에서 다음으로 무엇을 하는 것이 합리적인지 스스로 선택할 수 있는 Model을 Control Flow 안에 넣는 것입니다.
LLM은 왜 전통적인 함수처럼 동작하지 않는가
섹션 제목: “LLM은 왜 전통적인 함수처럼 동작하지 않는가”애플리케이션 관점에서는 Large Language Model을 함수처럼 호출할 수 있습니다.
const result = model(input);하지만 이 문법이 같은 Input에 항상 정확히 같은 Output을 반환하는 전통적인 함수와 개념적으로 동일하다는 뜻은 아닙니다.
Language Model은 현재 Context 뒤에 이어질 수 있는 가능한 Continuation에 대해 확률을 계산합니다. 아주 단순화하면, “유일한 다음 Token”이 있는 것이 아니라 여러 가능한 Continuation에 대한 분포가 존재합니다. 일부는 가능성이 높고, 일부는 낮으며, 많은 것은 사실상 중요하지 않습니다.
따라서 Model이 제멋대로 움직이는 것은 아닙니다. TypeScript Function을 요청했는데 같은 확률로 요리법이나 중세 시를 내놓지는 않습니다. 현재 Context가 합리적인 Continuation의 공간을 강하게 제한합니다.
하지만 그 공간 안에는 여러 개의 타당한 다음 단계가 동시에 존재할 수 있습니다.
temperature나 top_p 같은 Sampling Parameter는 이런 확률 분포에서 어떤 선택이 이루어지는지에 영향을 줍니다. Varianz를 줄이거나 늘릴 수 있지만 이 글의 핵심은 아닙니다. 반복 가능성을 높이는 설정이 있다고 해도 이를 모든 경우에 동일한 출력을 보장하는 일반적인 계약으로 이해해서는 안 됩니다. Agentic Work에서 더 중요한 것은 작은 차이가 단순한 표현 차이를 넘어 Model이 선택하는 다음 작업 단계까지 바꾸기 시작할 때 무슨 일이 일어나는가입니다.
우리의 Mental Model에는 우선 이 문장이면 충분합니다.
비결정론적이라는 것은 Model이 임의로 움직인다는 뜻이 아닙니다. 하나의 해결 공간 안에서 여러 개의 타당한 다음 단계가 존재할 수 있다는 뜻입니다.
단일 답변에서는 이것이 다른 표현으로 나타날 수 있습니다. 코드에서는 같은 요구사항을 서로 다른 구조로 구현할 수 있습니다.
Agent에서는 더 흥미로운 일이 벌어집니다.
Token Varianz에서 Decision Varianz로
섹션 제목: “Token Varianz에서 Decision Varianz로”Coding Agent는 보통 한 번의 단계로 최종 Patch를 만들지 않습니다.
먼저 디렉터리 구조를 볼 수도 있습니다. 비슷한 기존 Feature를 검색할 수도 있습니다. 그다음 Facade, Store, Test를 열어볼 수도 있습니다. 또는 API Contract부터 볼 수도 있습니다. 기존 Test를 먼저 실행할 수도 있고, Symbol을 검색하거나 Git History를 확인할 수도 있습니다.
이 모든 행동은 합리적일 수 있습니다.
전형적인 Agent Loop를 아주 단순화하면 다음과 같습니다.
Task ↓Decision ↓Action / Tool ↓Observation ↓new Context ↓next decision이런 Loop는 오늘날 Agents의 핵심 Architecture Pattern 중 하나입니다. Model은 현재 상태를 바탕으로 다음 Action을 고르고, 결과를 관찰한 뒤, 새로 얻은 정보를 포함해 작업을 이어갑니다.
이때 Language Model의 출력 Varianz는 새로운 종류의 Varianz로 변합니다.
이제 차이는 단지 한 줄의 코드를 두 가지 방식으로 쓰는 수준에 머물지 않습니다. 다음과 같은 요소부터 달라질 수 있습니다.
- 어떤 파일을 먼저 조사하는지,
- 어떤 검색을 시작하는지,
- 어떤 Test를 먼저 실행하는지,
- 기존 Architecture에 대해 어떤 가설을 세우는지,
- 어떤 오류를 더 중요하다고 판단하는지,
- 다음에 어떤 Tool을 사용하는지.
어떤 하나의 결정은 한 Run에서만 특정 정보를 발견하게 만들고, 다른 Run에서는 그 정보가 처음부터 보이지 않게 만들 수도 있습니다.
Agent에서 Varianz는 Output Varianz에만 머물지 않습니다. Process Varianz가 될 수 있습니다.
Agentic Systems를 이해하는 데 이 점은 Language Model이 확률적으로 생성된다는 사실 자체보다 훨씬 중요합니다.
Context는 정적인 Input Block이 아니다
섹션 제목: “Context는 정적인 Input Block이 아니다”이 시리즈의 이전 글에서는 Context가 Model이 이론적으로 알 수 있는 모든 정보가 아니라, 특정 작업 단계에서 실제로 사용할 수 있는 정보라는 점을 살펴봤습니다.
Agent에서는 이 Context도 정적이지 않습니다.
한 번의 Action 뒤에는 다음과 같은 검색 결과가 추가될 수 있습니다.
Search Result그다음에는 소스 코드가 들어올 수 있습니다.
loaded file그리고 이후에는 다음과 같은 결과가 올 수 있습니다.
Compiler Error또는:
Test Output또는:
Git Diff각 Observation은 다음에 어떤 Action이 합리적인지에 대한 판단을 바꿀 수 있습니다.
그래서 Anthropic은 Agent의 Context Engineering을 단순히 “좋은 초기 Prompt를 설계하는 일”로만 설명하지 않습니다. 멀티스텝 프로세스 전체에서 현재 어떤 정보가 Context 안에 있어야 하는지를 계속 관리하는 문제로 설명합니다. Agentic Systems는 모든 정보를 처음부터 넣는 대신 필요한 시점에 “just in time”으로 추가 정보를 불러올 수도 있습니다.
이 점은 중요한 결과로 이어집니다.
두 개의 Agent Run이 같은 작업으로 시작한다고 해봅시다. 둘 다 거의 동일한 조건에서 출발합니다. Run A에서는 Agent가 기존 Repository에서 같은 Pattern의 구현을 먼저 찾습니다. Run B에서는 새 Feature의 파일부터 직접 엽니다.
첫 번째 결정이 끝난 순간 두 상황은 이미 완전히 같지 않습니다.
Run A의 Context에는 기존 Architecture Example이 들어왔을 수 있습니다. Run B의 Context에는 로컬 구현의 세부 정보가 들어왔을 수 있습니다.
다음 결정은 각각 서로 다른 Context를 기준으로 내려집니다.
해결 경로 초반의 차이는 이후의 Context를 바꿉니다.
그리고 달라진 Context가 다시 다음 의사결정에 영향을 줍니다.
이렇게 Path Dependence가 생깁니다.
Path Dependence: 작은 갈림길이 다른 진행을 만든다
섹션 제목: “Path Dependence: 작은 갈림길이 다른 진행을 만든다”Path Dependence라는 용어는 여기서 실제 의미보다 더 이론적으로 들릴 수 있습니다.
뜻은 단순합니다. 이후의 진행은 그 이전에 어떤 단계들을 이미 거쳤는지에 영향을 받는다는 것입니다.

비슷한 Feature가 두 개 있는 Repository를 생각해 봅시다. 오래된 Feature는 지금은 낡은 구조를 사용하고 있고, 새로운 Feature는 현재 Architecture를 따릅니다.
한 Agent는 새로운 Feature를 먼저 발견하고 그 Pattern을 따릅니다.
다른 Agent는 검색 중 오래된 Feature를 먼저 발견하고 그것을 로컬 Convention으로 해석합니다.
두 판단 모두 당시에는 이해할 수 있습니다. Agent는 두 구현 뒤에 있는 역사적 맥락을 자동으로 알지 못합니다.
그 순간부터 사용할 수 있는 단서가 달라집니다. 이후 검색에서는 다른 용어를 사용할 수 있고, 다른 파일이 중요해 보이며, 다른 Dependency를 조사하게 됩니다. 결과적으로 Patch의 구조도 달라집니다.
처음의 작은 차이가 여러 단계를 거치면서 증폭될 수 있습니다.
그렇다고 두 Agent가 반드시 계속 멀어지기만 하는 것은 아닙니다. Test, Compiler Error, 명시적인 Architecture Rule이 나중에 두 경로를 같은 허용 범위로 다시 모을 수도 있습니다.
하지만 보장은 없습니다.
그래서 최종 Output만 보고 “같은 Input인데 왜 두 가지 다른 해결책이 나왔지?”라고 묻는 것은 Agent의 실제 작업 과정을 놓치기 쉽습니다. Agent의 과정은 하나의 입력과 하나의 출력이 아니라 여러 번의 Decision과 Observation으로 이루어져 있습니다.
같은 작업이 자동으로 같은 상태를 의미하지는 않는다
섹션 제목: “같은 작업이 자동으로 같은 상태를 의미하지는 않는다”여러 Run을 비교할 때 쉽게 놓치는 두 번째 포인트가 있습니다.
완전히 같은 Prompt 두 개가 있다고 해서 두 Agent Run이 수학적으로 완전히 동일한 조건에서 시작하고 진행한다고 볼 수는 없습니다.
다음과 같은 요소가 다를 수 있습니다.
- 이미 로드된 파일,
- Search Results,
- 외부 Tools의 결과,
- Repository 상태,
- 기존 Session History,
- 사용할 수 있는 Memories,
- 활성화된 Skills,
- Cached Information,
- Test 또는 Compiler Output.
Web-based Tools를 사용한다면 두 Run 사이에 외부 세계 자체가 변했을 수도 있습니다.
그렇다고 이 논리를 지나치게 확대해서는 안 됩니다. Agent Run은 원래 비교할 수 없다고 결론 내리는 것도 잘못입니다. 좋은 Evaluation은 초기 상태를 가능한 한 깨끗하게 통제하려고 합니다. Anthropic도 Agent Evals에서 각 Trial마다 격리된 Clean Environment를 사용하는 것을 권장합니다. 남아 있는 파일, Cache, 공유 상태가 추가적인 Varianz를 만들지 않도록 하기 위해서입니다.
이런 외부 영향을 상당 부분 통제해도 핵심은 남습니다.
초기 조건이 매우 비슷하더라도 해결 경로가 반드시 동일할 필요는 없습니다.
Agent에게는 여전히 허용된 해결 공간 안에서 선택할 여지가 있기 때문입니다.
내 Architecture Lab에서 관찰한 사례
섹션 제목: “내 Architecture Lab에서 관찰한 사례”나는 이 동작을 이론으로만 보는 것이 아닙니다. Architecture Lab에서는 일부러 많은 작은 애플리케이션과 반복되는 Feature를 Coding Agents에게 만들어 보게 합니다. 한편으로는 기술과 Architecture Approach를 실험하기 위한 것이고, 다른 한편으로는 Coding Agents를 위한 Guardrails가 실제로 어느 정도까지 구체적이어야 하는지 이해하기 위한 실험입니다.
특히 Agent Files와 Skills에 관심이 많습니다.
Agent Files는 예를 들어 Architecture Rule을 설명합니다. 어떤 Layer가 존재하는가? State는 어디에 있어야 하는가? 어떤 Dependency가 허용되는가? 어떤 Pattern을 사용해야 하고 어떤 Pattern은 명시적으로 피해야 하는가?
Skills는 반복되는 작업 방식을 설명합니다. 특정 Slice는 어떻게 만들어야 하는가? CRUD Feature에는 어떤 단계가 포함되는가? 변경 이후 어떤 검증을 수행해야 하는가?
최근 교육 Seminar용 Demo App에서 Architecture 관점으로 매우 만족스러운 상태를 만든 적이 있었습니다. 구조가 명확했고 여러 Features가 같은 원칙을 따랐으며, 필요한 Agent Files와 Skills도 이미 존재했습니다.
그다음 또 하나의 Feature를 만들게 했습니다. 기능적으로 특별히 복잡한 것도 아니었고, 구조적으로는 다시 CRUD였습니다. 즉 이미 프로젝트 안에 Examples와 Work Instructions가 존재하는 종류의 작업이었습니다.
그런데 갑자기 내가 직접이라면 절대 그렇게 설계하지 않았을 Architecture가 만들어졌습니다. 흥미로운 점은 Agent가 명백한 혼란을 만들어냈다는 것이 아니었습니다. 오히려 반대였습니다. 해결책 자체는 내부적으로 꽤 그럴듯했고, 각각의 결정도 이해할 수 있었습니다. 무작위 코드 덩어리가 아니라 일관된 해결 경로였지만, 단지 내가 기대한 Architecture로 이어지지 않았습니다.
Agent는 프로세스 초반 어딘가에서 다른 길로 들어선 것입니다. 다른 기존 구조를 첫 Reference로 삼았을 수도 있고, 초기 해석 하나가 이후 다른 파일들을 더 중요해 보이게 만들었을 수도 있습니다. 정확히 어느 갈림길이었는지는 이 관찰에서 핵심이 아닙니다. 중요한 것은 그 결과입니다. 그 결정이 다른 Context를 만들었고, 이후의 결정은 그 Context를 기반으로 이루어졌습니다.
이 관찰은 일반적인 행동에 대한 과학적 증명이 아닙니다. 하나의 실무 사례일 뿐입니다. 하지만 내게는 매우 인상적이었습니다. 가장 손쉬운 설명이 Agent에게 Guardrails가 없었다는 것이 아니었기 때문입니다.
Agent Files, Skills, 기존 Architecture Examples가 모두 존재했습니다. 그럼에도 그 경계 안에는 여전히 Decision Space가 남아 있었습니다.
Guardrails는 해결 공간을 제한할 수 있지만, Decision Path를 자동으로 결정론적으로 만들지는 않습니다.
Coding Agents를 실제로 사용할 때 이 구분은 매우 중요합니다.
비결정론적이라고 해서 통제할 수 없는 것은 아니다
섹션 제목: “비결정론적이라고 해서 통제할 수 없는 것은 아니다”이 지점에서 잘못된 인상을 받기 쉽습니다.
Agent의 경로를 정확히 예측할 수 없다면 Agentic Systems는 근본적으로 통제할 수 없다고 생각할 수 있습니다.
하지만 그런 결론은 나오지 않습니다.
Non-determinism과 arbitrariness는 서로 다른 개념입니다.
Software Architecture에서도 이미 비슷한 원리를 알고 있습니다. 보통 팀은 모든 개발자가 파일을 어떤 순서로 열어야 하는지까지 규정하지 않습니다. 하지만 어떤 해결책이 Acceptable한지는 꽤 정확하게 규정할 수 있습니다.
Agent를 통제하는 방식도 비슷합니다.
명확한 Requirements로 해결 공간을 제한할 수 있습니다. Architecture Rules로 원하지 않는 Dependency를 금지할 수 있습니다. Agent Files로 프로젝트별 Convention을 제공할 수 있습니다. Skills로 검증된 Workflows를 설명할 수 있습니다.
그리고 그 뒤에는 전통적인 Software Engineering이 제공하는 더 강한 Constraint가 있습니다.
Type System은 특정 상태를 애초에 허용하지 않습니다. Compiler는 잘못된 코드를 거부합니다. Linter는 Architecture 또는 Quality Rule을 검사할 수 있습니다. Tests는 비즈니스 동작을 검증합니다. Architecture Tests는 금지된 Dependency를 발견합니다. Evals는 반복적인 행동 요구사항을 확인합니다. Reviews는 완전히 자동화하기 어려운 부분을 평가할 수 있습니다.

이것이 Solution Path를 통제하는 것과 Solution Space를 통제하는 것의 근본적인 차이입니다.
Agent가 어떤 길을 택할지는 보장할 수 없습니다. 하지만 어떤 길이 허용 가능한지는 매우 정밀하게 정의할 수 있습니다.
내가 보기에는 이것이 더 유용한 Engineering 관점입니다. 목표는 점점 길어지는 Prompt로 Agent를 모든 해결 경로가 동일해지는 어설픈 결정론적 Workflow로 바꾸는 것이 아닙니다. 목표는 허용 가능한 해결책의 공간을 정의하는 것입니다.
이 공간이 명확하게 설명되고 기술적으로 강하게 보호될수록, 여러 Run이 그 안에서 서로 다른 길을 선택하는 것은 덜 문제가 됩니다.
여러 해결책은 자동으로 오류가 아니다
섹션 제목: “여러 해결책은 자동으로 오류가 아니다”Varianz는 보통 두 결과가 다를 때만 논의되기 때문에 빠르게 부정적인 뉘앙스를 갖습니다.
하지만 소프트웨어 개발에서 서로 다른 해결책은 특별한 일이 아닙니다.
경험 많은 개발자 다섯 명에게 같은 Ticket을 줘도 다섯 개의 동일한 Pull Request가 나오지는 않을 것입니다. 한 사람은 기존 Abstraction을 확장하고, 다른 사람은 로컬 구현이 더 단순하다고 판단할 수 있습니다. 어떤 사람은 Data Model부터 시작하고, 다른 사람은 Use Case부터 시작합니다. 일부 차이는 Review에서 논의할 대상이고, 다른 차이는 그냥 서로 다른 합리적 Trade-off일 수 있습니다.
여기서 사람과 비교하는 이유는 Model Behavior를 인간처럼 설명하려는 것이 아닙니다. 여러 개의 유효한 해결책이 존재하는 문제에서는 Varianz 자체가 곧 낮은 품질을 의미하지 않는다는 점을 보여주기 위해서입니다.
두 Agent Run이 서로 다른 구현을 만들더라도 둘 다 정확할 수 있습니다. 서로 다른 Trade-off를 드러낼 수 있고, Bug에 대해 다른 가설을 세우면서도 모두 원인에 도달할 수 있으며, 논의를 가능하게 하는 Alternative Architecture를 제시할 수도 있습니다.
그런 경우 Varianz는 결함이 아니라 열린 해결 공간의 일부입니다.
문제가 되는 시점은 차이가 시스템에 중요한 경계를 넘을 때입니다. Functional Requirements가 어떤 Run에서는 충족되고 다른 Run에서는 충족되지 않거나, Architecture Rule이 안정적으로 지켜지지 않거나, Security Constraint가 Run마다 달라지거나, 프로세스가 Agentic System이 안정적으로 제공할 수 있는 수준보다 더 높은 Reproducibility를 요구할 때입니다.
따라서 중요한 질문은 이것이 아닙니다.
“왜 Agent가 이번에는 다르게 했지?”
대신 이렇게 물어야 합니다.
“이번에 달라진 부분이 여전히 우리가 허용하는 경계 안에 있는가?”
이것이 훨씬 생산적인 Quality Question입니다.
Evaluation에 어떤 의미가 있는가
섹션 제목: “Evaluation에 어떤 의미가 있는가”이 관점에서 보면 한 번의 인상적인 Agent Run이 왜 제한된 의미만 갖는지도 이해하기 쉽습니다.
시스템이 확률적으로 동작하고, 여러 결정을 내리며, 앞선 Action이 뒤의 Context를 바꾼다면 한 번의 성공적인 Run은 우선 한 가지를 보여줍니다. 그 Run이 성공했다는 것입니다.
비슷한 작업도 항상 비슷하게 잘 해결된다는 것을 자동으로 증명하지는 않습니다.
그래서 Anthropic의 최신 Agent Eval 가이드에서는 한 작업에 대한 개별 시도를 Trial이라고 명시합니다. Model Output이 Run 사이에서 달라질 수 있기 때문에 여러 Trials를 사용해 Behavior를 더 안정적으로 평가합니다. 특히 유용한 구분은 “한 번이라도 성공할 확률”과 “여러 시도에서 얼마나 일관되게 성공하는가”라는 더 엄격한 질문입니다.
일반적인 소프트웨어 개발에서 이것이 모든 작은 Ticket을 Agent에게 50번 구현시키라는 뜻은 아닙니다.
핵심은 Mental Model입니다.
새 Agent File이 Architecture Rule을 안정적으로 전달하는지 알고 싶다면 한 번의 성공은 약한 Signal일 뿐입니다.
반복되는 CRUD 작업을 위한 Skill을 만든다면 그 Skill을 작성할 때 사용했던 단 하나의 Task로만 검증해서는 안 됩니다.
Repository용 Agent Model이나 새로운 Harness를 평가한다면 대표적인 Task와 하나 이상의 Run이 필요합니다.
Evaluation은 해결 경로를 불필요하게 고정해서도 안 됩니다. 여기에서도 Path와 Outcome의 구분이 중요합니다. Anthropic은 Agent Evals에서 특정 Tool Call 순서를 엄격하게 검사하면 합리적인 해결 경로를 오히려 벌점 처리할 수 있다고 지적합니다. 가능한 경우 모든 중간 단계를 강제하기보다 원하는 결과와 관련 Constraints가 충족되었는지를 평가하는 편이 더 낫습니다.
이것은 실제 Software Development와 잘 맞습니다.
Coding Agent의 기준은 예를 들어 다음과 같을 수 있습니다.
- Behavior가 Tests로 보호됨,
- Public API가 변경되지 않음,
- 금지된 Layer Dependency가 없음,
- Type Check 성공,
- Linter 성공,
- Security Rules 준수,
- Functional Use Case가 완전히 구현됨.
Agent가 그 상태에 어떻게 도달했는지는, 그 경로 자체가 중요한 Risk를 만들지 않는 한 두 번째 문제일 수 있습니다.
시스템이 확률적이고 Path-dependent하다면 한 번의 성공적인 Run만으로 Quality를 판단하기에는 보통 부족합니다.
이것은 무제한 Evaluation을 요구하는 말이 아닙니다. 좋은 Demo 하나와 Agent Quality 전체를 혼동하지 말자는 의미입니다.
Workflow가 더 나은 선택일 때
섹션 제목: “Workflow가 더 나은 선택일 때”결국 Agents에 대한 열광 속에서 의외로 쉽게 잊히는 질문으로 돌아옵니다.
이 작업은 정말 Agentic 방식이어야 할까요?
Anthropic은 LLM-based Systems를 설계할 때 문제를 해결할 수 있는 가장 단순한 접근부터 선택할 것을 명시적으로 권장합니다. 명확하게 정의된 작업에서는 Workflows가 더 높은 Predictability와 Consistency를 제공할 수 있습니다. Agents는 Flexibility와 Model-driven Decisions가 실제로 필요한 곳에서 의미가 있습니다.
이것은 Agents의 한계가 아니라 일반적인 Architecture Work입니다.
Commit 이후 항상 다음을 실행해야 한다는 것을 정확히 알고 있다면:
Format→ Lint→ Test→ Build→ Deploy매번 어떤 Step이 더 합리적인지 새로 판단하는 Agent는 필요하지 않습니다.
파일을 명확한 규칙에 따라 변환할 수 있다면 Script가 더 나을 가능성이 높습니다.
알려진 Schema에서 재현 가능한 Boilerplate Code를 만들 수 있다면 Generator가 정확한 도구입니다.
Agent의 강점은 의사결정이 필요한 곳에서 나타납니다.
이 Bug와 관련된 시스템 영역은 어디인가?
어떤 기존 구현이 가장 좋은 Reference인가?
어떤 Test가 가설을 검증하는 데 도움이 되는가?
로컬 Fix로 충분한가, 아니면 Bug가 구조적 문제를 가리키는가?
여러 가능한 해결책 중 어떤 것이 현재 Constraints에 가장 잘 맞는가?
이런 질문에 대해 완전히 결정론적인 프로세스를 만들 수 있다면, 이미 그 답을 Software로 작성해 두었다는 뜻일 것입니다.
여기서 간단한 Engineering Rule을 얻을 수 있습니다.
올바른 해결 경로가 이미 구체적으로 알려져 있을수록, 그 경로를 Agent의 판단에 맡길 이유는 줄어듭니다.
Automation과 Agentic Work는 경쟁 관계가 아닙니다.
좋은 시스템은 둘을 결합합니다.
결정론적인 Mechanism은 이미 알려져 있고 검증 가능한 부분을 보호합니다. Agent는 의사결정의 자유가 실제로 가치를 만드는 곳에서만 재량을 갖습니다.
Agentic Work는 조립 라인 작업이 아니다
섹션 제목: “Agentic Work는 조립 라인 작업이 아니다”조립 라인의 비유는 편안한 세상을 약속합니다. 위에서 Ticket을 넣고, Agent가 처리하고, 아래에서 Patch가 나옵니다. 한 번 잘 작동하면 더 많은 Tickets와 더 많은 Agents만 추가하면 될 것처럼 보입니다.
하지만 이 그림은 Agent를 흥미롭게 만드는 바로 그 성질을 과소평가합니다. Agent는 현재 Context를 해석하고, 다음 단계를 결정하고, 행동하고, 결과를 관찰한 뒤 다시 결정합니다. 초반의 다른 분기는 서로 다른 정보를 보이게 만들 수 있고, 달라진 Context는 다시 다른 다음 결정을 더 합리적으로 보이게 만듭니다. 이렇게 Path Dependence가 만들어집니다.
이것은 같은 작업이 반드시 같은 구현을 만들지 않는 이유를 설명해 줍니다. 하지만 이런 Varianz가 자동으로 나쁘다는 뜻은 아닙니다. 여러 경로가 모두 올바른 결과로 이어질 수 있습니다. Architecture Rules, Agent Files, Skills, Tests, Compiler, Type Systems, Evals는 해결 공간을 충분히 강하게 제한해서 서로 다른 경로가 결국 같은 Quality Boundary 안에 들어오도록 만들 수 있습니다.
따라서 Agentic Software Development에는 다른 Control Concept가 필요합니다. 모든 Step이 미리 정해질 필요는 없습니다. 중요한 것은 어떤 결과를 받아들일 것인지, 그리고 그 결과에 도달하는 동안 어떤 경계는 절대 넘지 말아야 하는지를 아는 것입니다.
Agentic Work는 조립 라인 작업이 아닙니다.
그리고 Non-determinism은 우선 두 개의 그럴듯한 Run이 왜 서로 다른 길을 택할 수 있는지만 설명합니다.
그것만으로는 Agent가 한 경로에서 틀렸음에도 매우 설득력 있게 행동하는 이유를 설명하지 못합니다. 또한 처음에는 의도되지 않았던 특정 가정이나 Architecture Decision이 여러 변경을 거치며 어떻게 굳어질 수 있는지도 설명하지 못합니다.
결국 서로 다른 해결책이 모두 옳다면, “서로 다르다”는 사실 자체는 비교적 큰 문제가 아닐 것입니다.
왜 Agents가 Hallucinate할 수 있는지, 그리고 하나의 작은 편차가 어떻게 장기적인 Drift로 발전할 수 있는지는 이 시리즈의 다음 질문입니다.
출처 및 추가 읽을거리
섹션 제목: “출처 및 추가 읽을거리”- Anthropic: Building effective agents — 미리 정의된 Workflows와 Model-driven Agents를 구분하고 각각을 언제 선택할지 설명합니다. Building effective agents
- Anthropic: Effective context engineering for AI agents — 멀티스텝 Agent Loop에서 Context를 동적인 State로 설명하고 “just in time” 정보 로딩을 다룹니다. Effective context engineering for AI agents
- Anthropic: Demystifying evals for AI agents — Trials, Run 간 Varianz, 격리된 Eval Environment, 그리고 지나치게 고정된 Trajectory보다 Outcome을 평가하는 접근을 설명합니다. Demystifying evals for AI agents
- OpenAI: A practical guide to building AI agents — LLM이 Workflow 실행과 동적인 Tool 선택을 제어하는 시스템으로 Agents를 설명합니다. A practical guide to building AI agents