AI 채팅창을 깨부수다: Berkeley 학생들이 실제 자율 에이전트(Autonomous Agents)를 구축한 방법
요약
Berkeley 학생들이 채팅 인터페이스의 한계를 극복하기 위해 구축한 자율 에이전트 시스템을 소개합니다. LLM을 채팅 파트너가 아닌 계획 엔진으로 활용하여, 스스로 작업을 계획하고 코드를 실행하며 데이터를 저장하는 능동적인 워크플로우를 구현했습니다.
핵심 포인트
- 채팅 인터페이스 대신 LLM을 계획 엔진(Planning engine)으로 활용
- 작업 플래너, 코드 실행기, SQLite 저장소, 이메일 어그리게이터로 구성된 아키텍처
- Docker 샌드박스를 통한 안전한 Python 코드 실행 및 오류 자동 재시도
- SQLite를 활용하여 채팅 컨텍스트 창의 한계를 데이터베이스로 대체
AI 채팅창을 깨부수다: Berkeley 학생들이 실제 자율 에이전트(Autonomous Agents)를 구축한 방법
모든 AI 데모는 똑같아 보입니다. 채팅창, 텍스트 프롬프트(Text prompt), 그리고 한 글자씩 스트리밍되는 응답. 채팅 인터페이스는 AI와 상호작용하는 기본 정신 모델(Mental model)이 되었습니다. 하지만 이는 함정이기도 합니다. 이는 한 세대 중 가장 강력한 기술을, 솔루션을 구축하는 대신 질문하는 법만 훈련하게 만드는 타이핑 인터페이스로 축소시켜 버립니다.
지난 학기, Berkeley CS 학생 그룹은 이 함정을 발견했습니다. 그들은 알고리즘 숙제를 위해 ChatGPT를 사용하며 완벽한 정답을 얻었지만, 감독관이 있는 중간고사에서는 낙제했습니다. 채팅 인터페이스가 그들을 의존적으로 만들고 있었던 것입니다. 그래서 그들은 사용을 중단했습니다. 대신 그들은 샌드박스(Sandbox)에서 실행되고, 스스로 작업을 계획하며, Python 코드를 실행하고, 결과를 SQLite에 저장하며, 결과물을 이메일로 전송하는 자율 에이전트(Autonomous agents)를 구축했습니다. 채팅창도 없고, 스트리밍되는 텍스트도 없으며, 타이핑하는 프롬프트도 없습니다.
이것이 그들이 구축한 방식이며, 왜 이것이 더 잘 작동하는지에 대한 이유입니다.
직접적인 해답
채팅 인터페이스는 수동적인 소비를 훈련시킵니다. 자율 에이전트(Autonomous agents)는 능동적인 엔지니어링을 훈련시킵니다. Berkeley 학생들은 LLM이 채팅 파트너가 아닌 계획 엔진(Planning engine) 역할을 하는 시스템을 구축했습니다. 시스템은 상위 수준의 과업을 전달받아 이를 하위 작업(Subtasks)으로 분해하고, 샌드박스화된 Python을 통해 각 하위 작업을 실행하며, 중간 결과물을 로컬 SQLite 데이터베이스에 저장하고, 최종 결과물을 이메일로 보냅니다. 에이전트는 인간의 개입 없이 실행됩니다. 학생은 동료의 결과물을 검토하는 것과 동일한 방식으로 — 즉, 전체 맥락을 파악하며 비판적으로 — 결과물을 검토합니다.
핵심 아키텍처(Core Architecture)
시스템은 순차적으로 실행되는 네 가지 구성 요소로 이루어져 있습니다:
1. 작업 플래너(Task Planner). 경량 LLM 호출(토큰당 $0.10/M 모델인 OpenRouter 사용)을 통해 목표를 수신하고 하위 작업들의 JSON 배열을 출력합니다. 각 하위 작업은 설명, 성공 기준, 그리고 의존성 목록(Dependency list)을 가집니다. 플래너는 모든 작업이 완료로 표시되거나 최대 반복 횟수에 도달할 때까지 실행됩니다.
2. Code Executor (코드 실행기). 각 하위 작업(subtask)은 Python 스크립트를 생성하는 코드 작성용 LLM에게 전달됩니다. 스크립트는 네트워크 접속, 파일 시스템 영속성(filesystem persistence)이 없고 30초의 타임아웃(timeout)이 설정된 Docker 샌드박스(sandbox) 내부에서 실행됩니다. 에이전트는 stdout, stderr 및 반환 코드(return codes)를 캡처합니다. 만약 스크립트에서 오류가 발생하면, 실행기는 오류 메시지와 함께 LLM에게 다시 프롬프트를 제공(re-prompt)하며 최대 3번까지 재시도합니다.
3. SQLite Store (SQLite 저장소). 파싱된 데이터, 계산된 값, 오류 로그 등 모든 중간 결과는 로컬 SQLite 데이터베이스에 기록됩니다. 에이전트는 단계(step) 사이의 컨텍스트(context)를 기억할 필요가 없습니다. 대신 데이터베이스에서 읽어옵니다. 이것이 핵심적인 통찰(key insight)입니다. 즉, 데이터베이스가 채팅 컨텍스트 창(chat context window)을 대체하는 것입니다. 에이전트는 LLM에게 다시 프롬프트를 제공하지 않고도 과거의 어떤 결과든 참조할 수 있습니다.
4. Email Aggregator (이메일 어그리게이터). 모든 하위 작업이 완료되면, 에이전트는 모든 출력물을 Markdown 보고서로 컴파일하여 사용자에게 이메일로 전송합니다. 이 이메일에는 작업 목표, 완료 상태가 포함된 하위 작업 목록, 생성된 코드 및 모든 출력 파일이 포함됩니다. 사용자는 에이전트가 작업하는 과정을 지켜볼 필요가 없습니다. 작업이 완료되면 결과만 받게 됩니다.
작동하는 경우
이 아키텍처(architecture)는 개별적이고 검증 가능한 하위 작업으로 분해될 수 있는 모든 작업에 유효합니다. 데이터 분석, 웹 스크래핑(web scraping), 파일 처리, 코드 생성, 보고서 생성, 수학 계산 및 알고리즘 구현 등이 모두 자연스럽게 부합합니다.
각 하위 작업의 성공 기준이 객관적일 때 가장 잘 작동합니다. "이 열의 합계를 구하고 CSV로 저장하라"는 통과 또는 실패 여부를 명확히 알 수 있습니다. 반면 "매력적인 서론을 작성하라"는 주관적이며 인간의 평가가 필요합니다.
Berkeley 학생들은 이를 자신들의 CS 170 알고리즘 문제 세트에 사용했습니다. 에이전트는 문제 설명을 받아 이를 하위 문제로 분해하고, 각 알고리즘을 Python으로 구현하며, 테스트 케이스를 실행하고, 결과를 SQLite에 기록한 뒤, 출력물을 이메일로 보냅니다. 그들은 ChatGPT의 답변을 읽는 것보다 에이전트의 코드를 검토하는 데서 더 많은 것을 배웠는데, 이는 에이전트의 코드가 채팅 응답이 아닌 엔지니어링 결과물(engineering output)로서 구조화되어 있었기 때문입니다.
작동하지 않는 경우
이는 창의적이거나 개방형(open-ended) 작업에는 작동하지 않습니다. 만약 목표가 "이 데이터셋을 탐색하여 흥미로운 패턴을 찾아보세요"와 같이 모호하다면, 에이전트는 도메인 전문가가 포착할 수 있는 인간의 통찰력(human insight)을 놓친 채 일반적인(generic) 결과물만을 생성할 것입니다.
또한 주관적인 판단이 필요한 작업에서도 작동하지 않습니다. 코드 리뷰(Code reviews), 디자인 결정(design decisions), 그리고 아키텍처 트레이드오프(architectural tradeoffs)에는 인간의 추론(human reasoning)이 필요합니다. 에이전트는 선택지들을 생성할 수는 있지만, 명확하고 측정 가능한 기준 없이는 올바른 선택을 할 수 없습니다.
상태가 변하는 외부 API로부터 실시간 데이터가 필요한 작업에서도 실패할 것입니다. 에이전트의 계획(plan)은 정적인 환경(static environment)을 가정합니다. 만약 하위 작업(subtask) 실행 사이에 웹사이트의 내용이 변경된다면, 에이전트는 오래된(stale) 결과를 생성할 수 있습니다.
단계별 가이드: 자신만의 에이전트 샌드박스(Agent Sandbox) 구축하기
다음은 Berkeley의 설정을 100줄 미만의 Python 코드로 재현하는 방법입니다.
1단계: 플래너(planner) 설정하기.
import json, sqlite3, smtplib, subprocess, os
from openai import OpenAI
...
```
json").removesuffix("
```").strip())
플래너는 구조화된 계획(structured plan)을 반환합니다. 각 하위 작업은 무엇에 의존하는지, 그리고 성공을 어떻게 검증할지를 알고 있습니다.
2단계: 순서대로 하위 작업 실행하기.
def execute_subtask(subtask):
code_prompt = f"""Write a Python script that accomplishes this: {subtask['description']}
The script must print its result as JSON to stdout.
...
```
{% endraw %}
python block."""
resp = client.chat.completions.create(model="gpt-4o-mini", messages=[{"role": "user", "content": code_prompt}], temperature=0.2)
code = resp.choices[0].message.content
code = code.split("
{% raw %}
```python")[1].split("```
")[0] if "
```python" in code else code
result = subprocess.run(["python", "-c", code], capture_output=True, text=True, timeout=30)
return {"stdout": result.stdout, "stderr": result.stderr, "returncode": result.returncode}
실행기(executor)는 서브프로세스(subprocess)에서 실행됩니다(프로덕션 환경에서는 Docker 컨테이너를 사용합니다). 이는 모든 것을 캡처하며 실패 시 재시도합니다.
3단계: SQLite에 저장하기.
db = sqlite3.connect("agent_results.db")
db.execute("CREATE TABLE IF NOT EXISTS subtask_results (id TEXT, description TEXT, stdout TEXT, stderr TEXT, returncode INT, completed_at TEXT)")
for subtask in subtasks:
...
데이터베이스는 에이전트의 메모리 (Memory)입니다. 어떤 하위 작업 (Subtask)이라도 테이블을 읽음으로써 이전 결과들을 조회할 수 있습니다.
4단계: 보고서 이메일 발송.
def email_report(to_addr, objective, db_path):
rows = db.execute("SELECT id, description, stdout, returncode FROM subtask_results").fetchall()
report = f"# Agent Report: {objective}\n\n"
...
```
{% endraw %}
\n{row[2][:500]}\n
{% raw %}
```\n\n"
msg = f"Subject: Agent Complete - {objective}\n\n{report}"
with smtplib.SMTP("smtp.gmail.com", 587) as server:
server.starttls()
...
이메일은 비동기적 (Asynchronously)으로 도착합니다. 폴링 (Polling), 대시보드, 채팅 인터페이스가 필요 없습니다. 에이전트가 실행되면 결과가 여러분의 편지함에 나타납니다.
샌드박스 (Sandbox)가 중요한 이유
샌드박스는 선택 사항이 아닙니다. 코드를 작성하고 실행할 수 있는 에이전트는 반드시 시스템으로부터 격리되어야 합니다. Berkeley 학생들은 --network none 옵션과 읽기 전용 파일 시스템 (Read-only filesystem)을 적용한 Docker를 사용했습니다. 이는 에이전트가 데이터를 유출하거나, 악성 코드를 작성하거나, 네트워크 호출을 하는 것을 방지합니다.
샌드박스가 없다면, 여러분의 에이전트는 텍스트 인터페이스를 가진 보안 취약점일 뿐입니다. 샌드박스가 있다면, 위험 없이 임의의 코드를 실행할 수 있는 안전하고 감사 가능한 (Auditable) 작업자가 됩니다.
샌드박스는 또한 규율을 강제합니다. 에이전트에게 데이터가 필요하다면 명시적으로 제공되어야 합니다. 라이브러리가 필요하다면 샌드박스 이미지에 설치되어 있어야 합니다. 여러분의 파일 시스템, 데이터베이스, 또는 API 키에 대한 주변 접근 권한 (Ambient access)은 존재하지 않습니다.
대안들
-
LangChain + LangGraph. 더 많은 내장 도구(built-in tooling)와 함께 동일한 플래너-실행자(planner-executor) 패턴을 제공하는 더 무거운 프레임워크입니다. 복잡한 워크플로우(workflows)에는 좋지만 의존성 오버헤드(dependency overhead)가 추가됩니다.
-
Autogen (Microsoft). 에이전트들이 서로 통신하는 멀티 에이전트(multi-agent) 프레임워크입니다. 여러 전문화된 에이전트들이 협업해야 하는 경우 유용하지만, 단일 파이프라인(pipeline)에는 과할 수 있습니다.
-
LLM 호출을 포함한 단순 쉘 스크립트 (Simple shell scripts with LLM calls). 작업이 선형적이라면 (A 단계 후 B 단계, 그 후 C 단계), LLM 호출 사이에 JSON을 파이핑(piping)하는 쉘 스크립트가 전체 에이전트 프레임워크보다 디버깅하기 쉽습니다.
-
노코드(No-code) 에이전트 빌더. Bubble, Zapier, Make 등은 코드를 작성하지 않고도 이 패턴을 모방하는 AI 단계를 제공합니다. 유연성은 제한적이지만 설정이 전혀 필요 없습니다.
결정 요약 (Decision Summary)
매일 ChatGPT에 똑같은 질문을 하고 있다면 → 그 질문들을 자동화하는 에이전트를 구축하세요.
작업에 객관적인 성공 기준이 있다면 → 샌드박스(sandbox)가 있는 코드 실행기(code executor)를 사용하세요.
작업에 주관적인 판단이 필요하다면 → 인간을 루프 안에 유지(human in the loop)하고 탐색을 위해 채팅을 사용하세요.
지금 당장 결과가 필요하다면 → 플래너(planner)를 동기적(synchronously)으로 실행하세요.
기다릴 수 있다면 → 에이전트를 비동기적(asynchronously)으로 실행하고 이메일로 결과를 받으세요.
실무 작업을 위해 여전히 채팅 인터페이스를 사용하고 있다면 → 토큰과 주의력을 낭비하고 있는 것입니다. 자율 에이전트(autonomous agents)로 전환하세요.
Q: 이것은 그냥 AutoGPT 아닌가요? 무엇이 다른가요?
A: AutoGPT는 이 패턴의 첫 번째 대중적인 구현체였지만, 치명적인 결함이 있었습니다. GPT-4의 컨텍스트 윈도우(context window)를 메모리 저장소로 사용했다는 점입니다. 매 단계가 프롬프트에 추가되었습니다. 이는 비용의 기하급수적인 증가와 컨텍스트 윈도우 제한을 초래했습니다. Berkeley의 접근 방식은 SQLite를 외부 메모리로 사용합니다. 에이전트는 프롬프트가 아니라 데이터베이스에 읽고 씁니다. 이를 통해 에이전트가 몇 단계를 실행하든 관계없이 비용을 일정하게 유지합니다.
Q: ChatGPT Plus보다 저렴한가요?
A: 네, 차이가 매우 큽니다. Berkeley 에이전트는 OpenRouter의 gpt-4o-mini를 사용하며, 입력 토큰 100만 개(1M)당 비용은 $0.15입니다. 전형적인 알고리즘 문제 세트를 해결하는 데 드는 비용은 $0.08입니다. ChatGPT Plus 구독료는 월 $20입니다. 만약 한 달에 10개의 문제 세트를 실행한다면, 에이전트 비용은 $0.80입니다. 게다가 모든 출력 결과는 검토를 위해 SQLite에 저장됩니다.
Q: 에이전트가 잘못된 코드를 생성하면 어떻게 되나요?
A: 그럴 수 있습니다. 실행기(executor)가 에러 메시지와 함께 재시도하며, 이를 통해 실패 사례의 약 70%를 해결합니다. 나머지 30%는 인간의 개입이 필요합니다. 하지만 여기서 차이점이 있습니다. 에이전트가 실패할 때는 전체 에러 트레이스(error trace), 생성된 코드, 그리고 테스트 출력을 모두 얻을 수 있습니다. 반면 ChatGPT가 틀린 답을 주면, 당신은 그저 틀린 텍스트를 받게 될 뿐입니다. 에이전트의 실패 모드(failure mode)가 훨씬 더 많은 정보를 제공합니다.
Q: 노트북에서도 실행할 수 있나요?
A: 네. 전체 시스템은 2020년형 MacBook Air에서 실행됩니다. LLM 호출은 원격으로 이루어지고, 코드 실행은 로컬에서 수행되며, SQLite 데이터베이스는 파일 형태입니다. GPU가 필요하지 않고, 클라우드 크레딧도 필요 없습니다. Docker Desktop이 샌드박스(sandbox)를 처리합니다.
Q: 이것이 Berkeley의 학문적 정직성(academic integrity) 정책을 위반하나요?
A: 그것은 강의 정책에 따라 다릅니다. 이것을 만든 학생들은 이를 학습 도구로 사용했습니다. 그들은 출력을 검토하고, 코드를 이해했으며, 에이전트가 내린 모든 결정을 설명할 수 있었습니다. 이는 ChatGPT의 답변을 복사하여 붙여넣는 것과는 다릅니다. 대부분의 교수님은 "출력을 자동화하는 것"과 "검토를 위한 스타터 코드(starter code)를 생성하는 도구로 사용하는 것"을 구분합니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기