에이전트 런타임을 아시나요? API를 여러 번 호출해도 AI가 똑똑해지지 않는 이유

API로 LLM을 계속 호출하면 답이 좋아질 것 같지만, 복잡한 작업에서는 오히려 꼬이기도 합니다. Claude Code와 Codex는 왜 다를까요? 에이전트 런타임의 구조부터 적용 방법, 멀티모델 라우팅까지 정리했습니다.

Share
에이전트 런타임을 아시나요? API를 여러 번 호출해도 AI가 똑똑해지지 않는 이유
goodtek 에이전트 런타임 소개 - LLM API 호출과 에이전트 런타임의 차이 및 실행 구조

에이전트 런타임을 아시나요?

API로 AI를 호출하면 답은 잘 옵니다.

문제는 조금 복잡한 일을 시킬 때부터 시작됩니다.

첫 번째 답을 받고 다시 묻습니다.
“여기 틀렸어. 다시 해줘.”

두 번째 답을 받고 또 묻습니다.
“이 부분까지 확인해서 다시 해줘.”

몇 번 왔다 갔다 하면 답이 더 좋아질 것 같지만, 실제로 해보면 꼭 그렇지는 않습니다.

앞에서 했던 말을 다시 반복하거나,
이미 해결한 부분을 건드리거나,
처음 요청과 조금씩 다른 방향으로 가기도 합니다.

저도 처음에는 모델 성능 문제라고 생각했습니다.

그런데 Claude Code나 Codex에 같은 일을 시키면 결과가 꽤 다릅니다.

코드를 읽고,
문제를 찾고,
파일을 수정하고,
테스트를 돌리고,
실패하면 다시 수정합니다.

중간에 사람이 계속 답을 복사해서 넣지 않아도 작업이 이어집니다.

차이는 모델만이 아닙니다.

에이전트 런타임이 있느냐 없느냐도 큰 차이를 만듭니다.


API 호출과 에이전트 런타임은 다릅니다

일반적인 LLM API 호출은 구조가 단순합니다.

사용자
→
애플리케이션
→
LLM API
→
답변

한 번 묻고 한 번 답을 받는 용도라면 이걸로 충분합니다.

문제는 여러 단계가 필요한 작업입니다.

예를 들어 이런 요청을 해봅니다.

로그인이 가끔 실패하는 원인을 찾아서 수정하고 테스트까지 해줘.

API를 한 번 호출하면 모델은 원인을 분석해서 답할 수 있습니다.

하지만 그 다음 단계는 직접 이어줘야 합니다.

  • 실제 파일을 수정했는지
  • 수정한 코드가 동작하는지
  • 테스트가 실패했는지
  • 다른 파일에도 영향이 있는지
  • 언제 작업을 끝내야 하는지

이걸 애플리케이션이 직접 관리해야 합니다.


대화를 여러 번 하는 게 문제는 아닙니다

API를 여러 번 호출한다고 해서 답변 품질이 무조건 떨어지는 것은 아닙니다.

직접 잘 설계하면 에이전트 루프를 만들 수도 있습니다.

문제는 단순히 대화 기록만 계속 쌓는 방식입니다.

messages.push(userMessage)
messages.push(modelAnswer)
messages.push(nextRequest)
messages.push(modelAnswer)
messages.push(errorLog)
messages.push(modelAnswer)

이 방식으로도 어느 정도는 동작합니다.

하지만 실제 작업에는 대화 내용 외에도 따로 관리해야 할 것이 많습니다.

항목 단순 API 반복 에이전트 런타임
현재 목표 프롬프트에 의존 작업 상태로 관리
도구 실행 직접 구현 런타임에서 처리
도구 결과 전달 직접 연결 다음 단계로 자동 연결
실패 후 재시도 직접 구현 루프 안에서 처리
다른 에이전트 호출 직접 라우팅 Handoff / Sub-agent
종료 조건 직접 판단 런타임에서 관리
상태 유지 메시지 배열에 섞이기 쉬움 세션/런 상태로 분리 가능

에이전트 런타임은 LLM을 여러 번 호출해주는 기능만 있는 것이 아닙니다.

작업이 끝날 때까지 필요한 실행 흐름을 관리하는 계층에 가깝습니다.


에이전트 런타임은 실제로 무엇을 하나

구조를 단순하게 표현하면 아래와 같습니다.

작업 요청
↓
Agent Runtime
↓
LLM 판단
Tool 실행
다른 Agent 호출
↓
결과 확인
↓ 실패하면 다시 실행
완료

핵심은 모델이 모든 일을 직접 하는 게 아니라는 점입니다.

모델은 다음에 무엇을 할지 판단하고, 실제 실행은 런타임이 맡습니다.

파일을 읽고, 명령어를 실행하고, 테스트를 돌리고, 결과를 다시 모델에게 전달합니다.

그 결과를 본 모델이 다음 행동을 정합니다.


버그 하나를 고치는 과정으로 비교해보면

일반 API 방식

사람 → 버그 찾아줘

AI → 원인은 A 같습니다.

사람 → 그럼 고쳐줘.

AI → 이렇게 수정하면 됩니다.

사람 → 테스트해줘.

AI → 테스트 코드는 이렇게 만들면 됩니다.

사람 → 실제로 돌렸더니 실패했어.

AI → 그러면 B 문제일 수 있습니다.

사람이 계속 가운데에서 작업을 이어줍니다.

에이전트 런타임 방식

로그인 버그 수정 요청
↓
관련 코드 검색
↓
원인 분석
↓
코드 수정
↓
테스트 실행
↓ 실패
실패 로그 분석
↓
다시 수정
↓
테스트 성공
↓
완료 보고

사람이 매 단계마다 중계하지 않아도 작업이 이어집니다.

Claude Code나 Codex를 썼을 때 일반 API 호출보다 훨씬 자연스럽게 느껴지는 이유도 이 부분에 있습니다.


적용은 생각보다 어렵지 않습니다

에이전트 런타임이라고 하면 거창해 보이지만, 요즘은 SDK를 이용하면 작게 시작할 수 있습니다.

OpenAI Agents SDK

설치는 간단합니다.

pip install openai-agents

가장 작은 형태는 이런 식입니다.

from agents import Agent, Runner

agent = Agent(
    name="Developer",
    instructions="""
    사용자의 개발 작업을 수행한다.
    필요한 도구를 사용하고
    검증이 끝날 때까지 작업을 계속한다.
    """
)

result = Runner.run_sync(
    agent,
    "로그인 오류의 원인을 분석해줘"
)

print(result.final_output)

여기서 중요한 부분은 Runner입니다.

Runner가 모델을 호출하고, Tool Call이 있으면 실행하고, 결과를 다시 넘기고, 작업을 이어갑니다.

OpenAI에서는 Responses API를 직접 쓰는 방식과 Agents SDK를 구분해서 설명합니다.

  • Responses API: 루프와 상태를 애플리케이션이 직접 관리
  • Agents SDK: Runner가 Agent Loop와 Tool 실행, Handoff 등을 관리

Claude도 같은 방향입니다

Claude 역시 일반 Messages API와 에이전트 실행 계층이 나뉘어 있습니다.

간단하게 시작하려면 Tool Runner를 사용할 수 있습니다.

from anthropic import Anthropic, beta_tool

client = Anthropic()

@beta_tool
def search_code(keyword: str) -> str:
    """Search source code."""
    return "검색 결과"

runner = client.beta.messages.tool_runner(
    model="claude-opus-5-5",
    max_tokens=4096,
    tools=[search_code],
    messages=[
        {
            "role": "user",
            "content": "로그인 관련 코드를 찾아서 문제를 분석해줘"
        }
    ],
)

for message in runner:
    print(message)

Tool Runner가 Tool 실행과 결과 반환, 요청과 응답의 반복을 관리합니다.

더 복잡한 구조에서는 Claude Agent SDK나 Managed Agents 같은 선택지도 있습니다.


에이전트가 여러 개가 되면 구조가 달라집니다

간단한 작업이라면 SDK 하나로도 충분합니다.

하지만 실제 서비스로 만들면 역할이 나뉘기 시작합니다.

User
↓
Orchestrator
↓
Developer Agent
DBA Agent
Security Agent
QA Agent
↓
Tools / MCP / DB / Git / Shell / Browser

이 단계부터는 단순한 LLM API 호출 서비스와는 성격이 달라집니다.

필요한 것도 많아집니다.

  • 여러 Agent 관리
  • Workflow
  • Memory
  • Tool / MCP
  • Human approval
  • Retry
  • State persistence
  • Model routing
  • Observability

Mastra 같은 프레임워크를 쓸 수도 있습니다

이런 구조를 직접 만들 수도 있지만, 프레임워크를 이용하는 방법도 있습니다.

Mastra는 TypeScript 기반으로 Agent, Tool, Workflow를 구성할 수 있는 프레임워크입니다.

AgentController 같은 런타임 계층에서는 다음 항목을 함께 다룰 수 있습니다.

Model
Storage
Workspace
Approval
Sub-agent
Session

이 정도가 되면 단순한 AI 채팅 서비스보다 작업 실행 서버에 가까워집니다.


제가 더 관심 있게 보는 부분은 모델 선택입니다

대부분의 에이전트 구조는 처음부터 사용할 모델을 정해놓습니다.

Developer Agent는 GPT, 분석 Agent는 Claude 같은 식입니다.

하지만 실제 작업은 난이도가 계속 바뀝니다.

간단한 UI 수정과 결제 구조 분석에 같은 모델을 쓸 필요는 없습니다.

작업 요청
↓
난이도 / 위험도 / 비용 판단
간단한 작업
빠르고 저렴한 모델
복잡한 분석
고성능 모델
전문 영역
전문 Agent

한 작업 안에서도 모델을 바꿀 수 있습니다.

작업 단계 적합한 모델
파일 검색 빠르고 저렴한 모델
아키텍처 분석 고성능 추론 모델
단순 코드 수정 저렴한 모델
보안 검토 전문 Agent 또는 고성능 모델
테스트 결과 판단 저렴한 모델

이렇게 하면 모든 단계에 비싼 모델을 쓰지 않아도 됩니다.


모델을 고르는 데 또 비싼 모델을 쓰는 문제

여기서 또 하나의 문제가 생깁니다.

어떤 모델을 사용할지 결정하려고 매번 큰 LLM을 호출하면 라우팅 자체에 비용이 생깁니다.

빠른 작업에서는 실제 작업보다 모델 선택에 시간이 더 걸릴 수도 있습니다.

그래서 저는 Jev 같은 Decision Model을 이런 위치에 넣는 방식에 관심이 있습니다.

긴 답변을 생성하는 모델 대신, 선택과 분류에 특화된 작은 모델을 앞단에 두는 겁니다.

Task
↓
Decision Model
ex. Jev
↓
Cheap / Fast
Reasoning
Specialist

런타임은 작업 정보를 Decision Model에 전달합니다.

{
  "task": "결제 중복 발생 가능성 분석",
  "files": 37,
  "risk": "high",
  "context_tokens": 82000,
  "needs_reasoning": true
}

결과는 길 필요가 없습니다.

{
  "model": "high_reasoning_model",
  "confidence": 0.94
}

또는 이런 형태도 가능합니다.

{
  "agent": "database_specialist",
  "model": "claude",
  "budget": "high"
}

판단은 작고 빠르게 하고, 실제 작업에 좋은 모델을 쓰는 구조입니다.


결국 런타임이 중심이 됩니다

User
↓
Agent Runtime
↓
Decision Model
↓
Fast Model
Reasoning Model
Specialist Agent
↓
Tools / MCP / DB / Git / Browser
↺ 결과와 상태를 Runtime으로 반환

런타임은 작업 상태를 계속 가지고 있습니다.

그 상태를 기준으로 다음에 어떤 Agent를 부를지, 어떤 모델을 쓸지, 사람에게 확인을 받을지 결정합니다.

GPT냐 Claude냐를 처음부터 하나로 고정하지 않아도 됩니다.

각 모델이 잘하는 일을 나눠서 쓰면 됩니다.


마치며

LLM API를 처음 사용하면 자연스럽게 이런 식으로 접근하게 됩니다.

질문하고, 답을 받고, 다시 답을 넣고, 수정 요청을 합니다.

간단한 작업에서는 충분합니다.

하지만 작업이 길어지면 결국 상태 관리, Tool 실행, 재시도, 완료 조건이 필요해집니다.

그걸 직접 만들기 시작하면 어느 순간 에이전트 런타임을 만들고 있는 셈입니다.

지금은 OpenAI Agents SDK도 있고, Claude Agent SDK와 Tool Runner도 있고, Mastra 같은 프레임워크도 있습니다.

처음부터 거대한 멀티 에이전트 시스템을 만들 필요는 없습니다.

Runner 하나부터 써봐도 일반 API 호출과 차이를 느낄 수 있습니다.

그 다음 단계에서는 런타임 안에서 모델 선택까지 동적으로 바꿔볼 수 있습니다.

간단한 작업은 저렴한 모델에게 보내고, 복잡한 판단만 좋은 모델에게 맡기는 방식입니다.

모델 선택에는 Jev 같은 Decision Model을 붙여볼 수도 있습니다.

앞으로는 어떤 모델을 쓰느냐보다, 여러 모델과 도구를 어떤 런타임에서 어떻게 움직이느냐가 더 중요해질 수 있습니다.


참고 자료

Read more