본문으로 건너뛰기

로컬 AI 에이전트 구축하기

고급

로컬 AI 에이전트는 완전히 자신의 하드웨어에서 실행되는 자율 루프입니다: 오픈 웨이트 모델(Ollama 또는 LM Studio가 서빙)이 무엇을 할지 결정하고, 여러분이 제공한 **도구(tool)**를 호출하고, 그 결과를 읽고, 작업이 끝날 때까지 계속 진행합니다 — 아무것도 머신을 떠나지 않은 채로 말입니다. 클라우드 API도, 호출당 청구도, 인터넷도 필요 없습니다. 함정은 이렇습니다: 노트북에서 실행될 만큼 작은 모델은 프런티어 모델보다 어려운 추론과 장기 지평(long-horizon) 계획에 약하며, 그 안정성과 안전성은 여러분의 책임입니다. 이 페이지는 로컬 에이전트에 대한 솔직한 근거, 최소 아키텍처, 실제로 로컬에서 실행되는 것, 그리고 첫 에이전트를 만드는 현실적인 경로를 다룹니다.

What you'll learn
  • 왜 로컬에서 실행되는 에이전트를 구축하는지 — 그리고 클라우드 API 에이전트 대비 솔직한 트레이드오프를 이해하기
  • 최소 아키텍처 이해하기: 로컬 모델 + 도구 호출 루프 + 도구 + 가드레일/정지 조건
  • 실제로 도구 사용 / 에이전트 작업을 할 수 있는 로컬 모델 고르기
  • 로컬 엔드포인트를 가리켜 로컬에서 실행되는 에이전트 프레임워크가 무엇인지 알기 (LangGraph, CrewAI, OpenAI Agents SDK)
  • 일회성 도구 호출에서 가드레일이 있는 루프까지 '단순하게 시작하기' 경로 따르기
  • 자율 루프가 실제 피해를 줄 수 없도록 에이전트를 샌드박스화하고 예산 상한을 설정하기

로컬 에이전트를 구축하는가 (그리고 언제 하지 말아야 하는가)

일반적인 도구 사용 에이전트는 클라우드 모델을 호출합니다. 로컬 에이전트는 그 클라우드 호출을 자신의 머신에서 실행되는 모델로 바꿉니다. 여러분은 어느 정도의 역량을 포기하고 어느 정도의 운영 부담을 떠안습니다. 그 대가로 다른 방법으로는 얻기 어려운 네 가지를 얻습니다:

  • 프라이버시 — 프롬프트, 도구 입력, 도구 출력이 결코 머신을 떠나지 않습니다. 이것이 규제·민감·에어갭(air-gapped) 환경의 팀들이 로컬 에이전트를 구축하는 근본 이유입니다: 데이터가 물리적으로 제3자에게 갈 수 없습니다.
  • 오프라인 — 인터넷도, API 의존성도, 공급자 장애도 없습니다. 에이전트는 여러분 디스크에 있는 파일이며, 비행기 안에서나 방화벽 뒤에서도 실행됩니다.
  • 호출당 비용 없음 — 에이전트 루프는 작업당 수십 번의 모델 호출을 발생시킬 수 있습니다. 로컬에서는 그 호출이 "무료"이므로(토큰이 아니라 전기와 하드웨어로 지불), 계량기를 지켜보지 않고 반복하게 둘 수 있습니다.
  • 완전한 통제 — 정확한 모델 버전을 고정하고, 동작을 커스터마이즈하며, 속도 제한이나 이용 약관의 예상치 못한 변경 없이 실행합니다.

솔직한 트레이드오프 — 결정하기 전에 이것들을 명확히 인식하세요:

  • 역량 격차. 에이전트에서 가장 어려운 부분은 추론입니다: 여러 단계의 작업을 계획하고, 실패한 도구 호출에서 회복하고, 언제 멈춰야 할지 아는 것. 노트북에서 실행할 수 있는 모델(대략 1B–14B 파라미터)은 여기서 프런티어 모델보다 눈에 띄게 약합니다. 단순하고 범위가 잘 정의된 루프는 로컬에서 잘 작동하지만, 장기 지평의 개방형 작업은 로컬 에이전트가 가장 자주 탈선하는 지점입니다.
  • 안정성과 안전성은 여러분의 책임. 어떤 공급자도 여러분을 위해 필터링하거나, 모니터링하거나, 가드레일을 쳐 주지 않습니다. 에이전트가 영원히 루프를 돌거나, 잘못된 도구를 호출하거나, 파괴적인 행동을 한다면, 그것은 여러분 설계의 문제입니다. (아래 경고를 참고하세요 — 사람들이 과소평가하는 부분이 바로 이것입니다.)
  • 하드웨어 한계. 더 크고 똑똑한 모델은 대부분의 머신이 가진 것보다 더 많은 RAM/VRAM을 필요로 합니다. 여러분은 보통 존재하는 최고의 모델이 아니라 하드웨어가 실행할 수 있는 가장 큰 유능한 모델을 고르게 됩니다.

지속적으로 유효한 경험 법칙: 로컬로 시작하고, 작업이 요구할 때 상향(escalate)하라. 프라이빗/오프라인/대규모에서 저렴한 작업과 범위가 잘 정의된 루프에는 로컬 에이전트를 사용하고, 작업이 진정으로 추가적인 추론을 필요로 할 때 프런티어 API 에이전트로 손을 뻗으세요. 아래 아키텍처는 어느 쪽이든 동일합니다 — 오직 엔드포인트만 바뀝니다 — 그래서 로컬에서 프로토타입을 만들고 나중에 모델을 바꿀 수 있습니다.

최소 아키텍처

에이전트를 핵심까지 벗겨내면 네 부분이 있습니다. 그 밖의 모든 것은 이 위에 얹은 편의 기능입니다.

┌─────────────────────────────────────────────┐
│ │
│ 1. LOCAL MODEL ──► decides next action │
│ (Ollama / LM Studio, tool-capable) │
│ │ │
│ ▼ │
│ 2. TOOL-CALLING LOOP │
│ parse the model's tool request, │
│ run it, feed the result back │
│ │ │
│ ▼ │
│ 3. TOOLS ──► search / read file / │
│ run code / call an API (your code) │
│ │ │
│ ▼ │
│ 4. GUARDRAIL / STOP CONDITION │
│ max steps, budget, approval gate, │
│ "done" check ──► exit the loop │
│ │
└─────────────────────────────────────────────┘
  1. 도구 호출을 지원하는 로컬 모델. 모델은 단순히 대화만 하는 게 아니라 도구를 호출하는 구조화된 요청(일명 함수 호출)을 방출할 수 있어야 합니다. Ollama는 이를 자체 API와 http://localhost:11434/v1OpenAI 호환 엔드포인트를 통해 노출하므로, OpenAI 형식을 사용하는 모든 프레임워크가 로컬 모델을 구동할 수 있습니다.
  2. 도구 호출 루프. 에이전트의 심장부입니다: 대화를 모델에 보내고, 도구 호출을 요청했는지 확인하고, 그 도구를 실행하고, 결과를 덧붙이고, 반복합니다. 모델이 도구를 요청하지 않고 답하면 루프가 끝납니다.
  3. 도구. 모델에게 노출하는 평범한 함수입니다 — 웹 검색, 파일 읽기, 셸 명령 실행, 데이터베이스 쿼리, API 호출. 각 도구에는 이름, 설명, 그리고 타입이 지정된 입력 스키마가 있어 모델이 언제 어떻게 사용할지 알 수 있습니다.
  4. 가드레일 / 정지 조건. 자율성에는 타협 불가입니다. 최소한 루프가 영원히 돌 수 없도록 하는 최대 단계 상한, 그리고 — 쓰기·삭제·지출·전송하는 모든 것에 대해서는 — 승인 게이트나 샌드박스가 필요합니다. 이것이 없으면 여러분에게 있는 것은 에이전트가 아니라, 파일 접근 권한을 가진 무한 루프입니다.

2단계의 루프는 정말로 작습니다. 로컬 Ollama 엔드포인트를 대상으로 한 Python 의사코드는 다음과 같습니다:

최소한의 로컬 에이전트 루프 (Python 의사코드, 로컬 Ollama를 가리킴)

from openai import OpenAI

# Point the OpenAI client at your LOCAL Ollama endpoint — nothing leaves the machine
client = OpenAI(base_url="http://localhost:11434/v1", api_key="ollama")

tools = [{
  "type": "function",
  "function": {
      "name": "read_file",
      "description": "Read a UTF-8 text file and return its contents",
      "parameters": {
          "type": "object",
          "properties": {"path": {"type": "string"}},
          "required": ["path"],
      },
  },
}]

def run_tool(name, args):
  if name == "read_file":
      # GUARDRAIL: only allow reads inside a sandboxed directory
      return safe_read(args["path"])
  raise ValueError(f"unknown tool: {name}")

messages = [{"role": "user", "content": "Summarize ./notes/today.md"}]

for step in range(8):                       # GUARDRAIL: hard step cap
  resp = client.chat.completions.create(
      model="llama3.1", messages=messages, tools=tools,
  )
  msg = resp.choices[0].message
  messages.append(msg)

  if not msg.tool_calls:                  # STOP: model answered, we're done
      print(msg.content)
      break

  for call in msg.tool_calls:
      result = run_tool(call.function.name, json.loads(call.function.arguments))
      messages.append({
          "role": "tool", "tool_call_id": call.id, "content": str(result),
      })
else:
  print("Stopped: hit the step cap without finishing.")

이것이 패턴의 전부입니다. 프레임워크는 이 위에 메모리, 재시도, 다중 에이전트 오케스트레이션, 트레이싱, 구조화된 상태를 추가합니다 — 하지만 그 모두는 이 루프의 더 견고한 버전일 뿐입니다.

어떤 로컬 모델이 에이전트 / 도구 사용 작업에 적합한가

모든 오픈 웨이트 모델이 에이전트를 구동할 수 있는 것은 아닙니다. 기준은 신뢰할 수 있는 도구 호출입니다: 모델은 잘 형식화된 도구 요청을 일관되게 방출하고, 올바른 도구를 고르고, 인자를 환각(hallucinate)하지 않아야 합니다. 선택 시 두 가지 필터:

  • 도구 사용이 가능한 모델이어야 합니다. Ollama가 이를 태그합니다 — 추측하지 말고 Tools 카테고리에서 현재 목록을 살펴보세요. 견고한 로컬 도구 사용으로 흔히 언급되는 모델에는 Qwen과 Llama의 인스트럭션 튜닝 계열이 포함됩니다. 다만 정확히 무엇이 최선인지는 분기마다 바뀝니다.
  • 컨텍스트를 위한 여유를 두고 하드웨어에 맞아야 합니다. 에이전트 루프는 긴 메시지 이력을 축적합니다(모든 도구 결과가 덧붙여짐). 따라서 가중치 넉넉한 컨텍스트 창을 모두 메모리에 확보해야 합니다. 편안하게 맞고 빠르게 실행되는 작은 모델이, 디스크로 스왑되어 루프 중간에 멈춰 버리는 큰 모델보다 나은 경우가 많습니다.

결정적인 수는 벤치마크를 읽는 것이 아닙니다 — 두세 개의 후보 모델을 대상으로 여러분의 작업에 대한 작은 평가(eval)를 실행하는 것입니다. 리더보드 상위에 오른 모델이라도 여러분의 에이전트가 필요로 하는 특정 도구에서는 여전히 신뢰할 수 없을 수 있습니다. 여러분 자신의 루프에서 측정하세요.

로컬에서 실행되는 프레임워크

위의 루프를 직접 손으로 만들 수 있으며, 첫 에이전트에서는 그것이 배우기에 훌륭한 방법입니다. 실제 용도에는 프레임워크가 재시도, 메모리, 다중 에이전트 조율, 트레이싱을 제공합니다. 핵심 사실: 인기 있는 에이전트 프레임워크는 **모델 불가지론적(model-agnostic)**입니다 — 여러분이 올바른 엔드포인트를 가리키기만 하면, 모델이 클라우드에 있든 localhost에 있든 신경 쓰지 않습니다.

  • LangGraph — 상태를 유지하는 에이전트를 위한 저수준 오케스트레이션 프레임워크(내구성 있는 실행, 영속성, 사람의 개입). 모델 불가지론적이며, LangChain Ollama 통합을 통해 우회 없이 로컬 모델에 연결됩니다. 에이전트의 상태 그래프에 대한 명시적 통제가 필요할 때 좋습니다.
  • CrewAI — 역할 기반 에이전트("크루") 하나 이상을 조율하는 고수준 프레임워크. LiteLLM을 통해 모델 불가지론적이며, LLM(model="ollama/llama3.1", base_url="http://localhost:11434")으로 에이전트를 로컬 모델에 가리킵니다. 협력하는 여러 에이전트를 빠르게 구성하고 싶을 때 좋습니다.
  • OpenAI Agents SDK — 경량 다중 에이전트 프레임워크. 이름에도 불구하고 **공급자 불가지론적(provider-agnostic)**입니다: LiteLLM 통합을 통해 OpenAI 모델 대신 로컬 Ollama 모델을 가리킬 수 있습니다. 로컬 백엔드 위에서 OpenAI의 에이전트 사용감을 원할 때 좋습니다.

세 가지를 모두 맛보기보다는 하나의 프레임워크를 골라 잘 익히세요. 개념(에이전트, 도구, 루프, 상태)은 전이되며, API는 세부 사항입니다.

첫 로컬 에이전트 만들기

현실적인 경로는 "루프가 전혀 없음"에서 "가드레일이 있는 자율 루프"까지 의도적인 단계를 밟습니다. 4단계로 건너뛰지 마세요 — 사람들이 로컬 에이전트에서 부딪히는 실패의 대부분은 약한 모델에게 너무 일찍 너무 많은 자유를 주는 데서 옵니다.

Guided walkthrough1 of 5
  1. Ollama를 설치하고(로컬에서 모델 실행하기 참고), 도구용으로 태그된 모델을 pull 하세요. 예: ollama pull llama3.1. http://localhost:11434에서 서빙되는지, 그리고 ollama list에 표시되는지 확인하세요. 아직 에이전트는 없습니다 — 그저 호출할 수 있는 모델일 뿐입니다.
Watch out
  • 도구를 가진 로컬 에이전트도 여전히 실제 행동을 할 수 있습니다 — 샌드박스화하고, 파괴적 단계에는 승인을 요구하고, 루프/예산에 상한을 두세요.

스스로 점검하기

스스로 점검하기

0/4
  1. 팀이 클라우드 API 대신 로컬에서 실행되는 에이전트를 구축하는 가장 중요한 단 하나의 이유는 무엇인가요?
  2. 최소 로컬 에이전트 아키텍처를 구성하는 네 부분은 무엇인가요?
  3. LangGraph, CrewAI, OpenAI Agents SDK가 로컬 사용에서 '모델 불가지론적'이라는 것은 무슨 뜻인가요?
  4. 첫 로컬 에이전트를 만들고 있습니다. 파일을 쓰거나 명령을 실행하는 도구를 추가하기 전에 무엇을 해야 하나요?
Enter 또는 스페이스 키를 눌러 카드를 뒤집습니다. 좌우 화살표 키로 카드를 이동할 수 있습니다.용어가 표시되었습니다.
1 / 6
Key takeaways
  • 로컬 에이전트는 클라우드 모델을 여러분 머신의 오픈 웨이트 모델로 바꾼 표준 도구 사용 루프입니다 — 프라이빗하고, 오프라인이며, 반복 비용이 무료입니다.
  • 최소 아키텍처 = 도구 사용이 가능한 로컬 모델 + 도구 호출 루프 + 도구 + 가드레일/정지 조건. 루프 자체는 아주 작습니다.
  • Ollama의 OpenAI 호환 엔드포인트(/v1)는 도구 호출을 지원하므로, 어떤 OpenAI 형식 프레임워크든 로컬 모델을 구동할 수 있습니다.
  • LangGraph, CrewAI, OpenAI Agents SDK는 모델 불가지론적입니다 — 클라우드 대신 로컬 엔드포인트를 가리키세요.
  • 하드웨어에 맞는 도구 사용 가능 모델을 고른 뒤, 리더보드가 아니라 여러분 자신의 작업에 대한 작은 평가로 결정하세요.
  • 역량 격차에 솔직하고 안전성을 책임지세요: 루프와 예산에 상한을 두고, 도구를 샌드박스화하고, 파괴적인 모든 것에 승인을 요구하세요.
  • 단순하게 시작하세요: 깔끔한 도구 호출 하나 → 경계가 있는 읽기 전용 루프 → 가드레일이 있는 파괴적 도구 → (선택적으로) 프레임워크.

출처 & 더 읽을거리