06. OpenAI Agents SDK 입문: 첫 에이전트

🎯 이 장의 목표
  • 1부에서 손으로 만든 루프·메모리·도구를 SDK가 어떻게 추상화하는지 이해한다
  • AgentRunner라는 두 핵심 원시(primitive)를 익힌다
  • 동기/비동기 실행 방식의 차이를 안다
  • SDK의 다섯 가지 핵심 구성요소를 큰 그림으로 파악한다

비유로 시작하기: 직접 만든 공구 vs 잘 만든 공구함

1부에서 우리는 도구 호출 루프를 while문으로 직접 짰습니다. 작동은 했지만, 도구가 늘고 에이전트가 여러 개가 되면 그 코드는 금세 복잡해집니다. OpenAI Agents SDK는 그 반복 작업(모델 호출 → 도구 실행 → 결과 전달 → 재추론)을 잘 만든 공구함처럼 깔끔하게 정리해 줍니다.

이 SDK의 철학은 "최소한의 추상화"입니다. 배울 개념이 적어 금방 익히지만, 실무에 쓸 만큼은 충분합니다. 실험용 프로젝트였던 Swarm을 프로덕션용으로 다듬은 결과물입니다.

📌 핵심
최신 정보 (2026): OpenAI Agents SDK는 2026년 4월 대규모 업데이트로 샌드박스 실행, model-native harness, Skills, 서브에이전트 등을 추가했습니다. 기본 모델도 gpt-4.1에서 gpt-5.4-mini로 바뀌었습니다. 강의 영상은 이전 버전일 수 있으니, 모델명과 일부 API는 공식 문서로 확인하세요. 패키지는 openai-agents ≥ 0.14를 권장합니다.

설치

BASH
pip install openai-agents

OPENAI_API_KEY 환경변수가 설정되어 있어야 합니다(2장 참고).

두 핵심 원시: Agent와 Runner

SDK의 출발점은 단 두 가지입니다. Agent는 지시문(instructions)과 도구를 갖춘 LLM이고, Runner는 그 에이전트를 실제로 돌려 turn·도구·핸드오프·세션을 관리해 줍니다.

PYTHON
from agents import Agent, Runner

agent = Agent(
    name="Assistant",
    instructions="너는 간결하고 정확한 비서다.",
)

result = Runner.run_sync(agent, "재귀에 대한 하이쿠를 써줘.")
print(result.final_output)

Agent는 1부의 시스템 프롬프트(instructions)를 품은 객체이고, Runner.run_sync는 1부에서 우리가 손으로 짠 루프를 대신 돌려 줍니다. result.final_output이 최종 답입니다.

flowchart LR
    classDef user fill:#FFE082,stroke:#F9A825,color:#000
    classDef agent fill:#80DEEA,stroke:#00838F,color:#000
    classDef result fill:#A5D6A7,stroke:#2E7D32,color:#000

    U[입력]:::user --> R[Runner<br/>루프 관리]
    R:::agent --> A[Agent<br/>instructions + tools]:::agent
    A --> R
    R --> F[result.final_output]:::result

동기 vs 비동기 실행

Runner는 세 가지 실행 방식을 제공합니다. 작업 성격에 맞게 고릅니다.

메서드방식언제 쓰나
Runner.run_sync(...)동기스크립트·노트북에서 간단히 테스트
await Runner.run(...)비동기웹 서버 등 비동기 환경, 동시 처리
Runner.run_streamed(...)스트리밍토큰을 실시간으로 흘려보낼 때

비동기 버전은 다음과 같습니다.

PYTHON
import asyncio
from agents import Agent, Runner

async def main():
    agent = Agent(name="Assistant", instructions="간결하게 답한다.")
    result = await Runner.run(agent, "파이썬의 GIL을 한 문장으로 설명해줘.")
    print(result.final_output)

asyncio.run(main())

💡 팁: 강의 예제와 실무 코드 상당수가 async/await를 씁니다. async/await는 파이썬에서 "오래 걸리는 작업(예: API 응답 대기) 동안 멈춰 기다리지 않고 다른 일을 처리"하게 해주는 비동기 프로그래밍 문법이고, asyncio는 그 비동기 코드를 돌려주는 파이썬 표준 라이브러리입니다. 핸드오프·가드레일 등 SDK의 고급 기능이 비동기를 기본으로 하기 때문입니다. asyncio.run(main())으로 비동기 함수를 실행하는 패턴에 익숙해지세요.

⚠️ 흔한 실수: Jupyter 노트북에서 asyncio.run()을 호출하면 "이미 실행 중인 이벤트 루프" 에러가 날 수 있습니다. (Jupyter 노트북은 코드를 칸 단위로 나눠 바로 실행·확인하는 웹 기반 대화형 개발 환경으로, 데이터·AI 실습에 많이 쓰입니다.) 노트북에서는 await main()을 직접 쓰거나 nest_asyncio를 적용하세요.

SDK의 다섯 핵심 구성요소

이 SDK 전체를 다섯 가지로 요약할 수 있습니다. 2~3부에서 하나씩 다룹니다.

flowchart TB
    classDef agent fill:#80DEEA,stroke:#00838F,color:#000
    classDef tool fill:#90CAF9,stroke:#1565C0,color:#000
    classDef guard fill:#EF9A9A,stroke:#C62828,color:#000
    classDef mem fill:#A5D6A7,stroke:#2E7D32,color:#000

    A[Agents<br/>지시문+도구를 가진 LLM]:::agent
    T[Tools / Handoffs<br/>도구 호출·에이전트 위임]:::tool
    G[Guardrails<br/>입출력 검증]:::guard
    S[Sessions<br/>메모리 계층]:::mem
    TR[Tracing<br/>실행 추적·디버깅]:::agent

    A --- T
    A --- G
    A --- S
    A --- TR

다섯 요소를 한 줄씩 정리하면 이렇습니다. Agents는 핵심 빌딩 블록입니다. Tools/Handoffs는 도구 호출과 다른 에이전트로의 위임을 담당합니다. Guardrails는 입출력을 검증해 잘못된 사용을 막습니다(3부). Sessions는 메모리 계층으로 대화 맥락을 유지합니다. Tracing은 모든 실행을 기록해 디버깅·평가를 돕습니다.

트레이싱 미리보기

SDK의 강점 중 하나가 빌트인 트레이싱입니다. 멀티 에이전트·도구·핸드오프가 얽히면 "무슨 일이 일어났는지" 파악하기 어려운데, 트레이싱이 모든 LLM 호출·도구 실행·핸드오프를 구조적으로 기록합니다.

PYTHON
from agents import Agent, Runner, trace

agent = Agent(name="Assistant", instructions="간결하게 답한다.")

with trace("내 첫 워크플로"):
    result = Runner.run_sync(agent, "안녕!")
    print(result.final_output)
# OpenAI 플랫폼의 Traces 대시보드에서 실행 흐름 확인 가능

📌 핵심: Agent로 정의하고 Runner로 실행한다. 이 두 가지가 SDK의 심장입니다. 나머지(도구·핸드오프·가드레일·세션·트레이싱)는 모두 이 둘에 붙는 부가 기능입니다.

이 장에서 배운 것

  • OpenAI Agents SDK는 1부에서 손으로 짠 에이전트 루프를 최소 추상화로 정리한 프로덕션 SDK다.
  • 두 핵심 원시는 Agent(지시문+도구)와 Runner(실행·관리)다.
  • 실행은 run_sync(동기)·run(비동기)·run_streamed(스트리밍) 세 가지가 있다.
  • 전체는 Agents·Tools/Handoffs·Guardrails·Sessions·Tracing 다섯 요소로 요약된다.

✍️ 확인 문제

  1. 1부에서 직접 짠 while 도구 호출 루프는 SDK의 어떤 요소가 대신 처리해 주는가?
  2. Runner.run_syncRunner.run은 각각 어떤 상황에 적합한가?
  3. 멀티 에이전트 시스템에서 "무슨 일이 일어났는지" 파악하기 위해 SDK가 기본 제공하는 기능은 무엇인가?
이전 장: 05. 도구
다음 장: 07. SDK로 도구·메모리 다루기