에이전트와 비동기(Async) 애플리케이션

에이전트와 비동기(Async) 애플리케이션

출처: Async Applications with Agents — Hugging Face smolagents 공식 문서

이 가이드는 smolagents 라이브러리의 동기(synchronous) 에이전트를 Starlette으로 만든 비동기 파이썬 웹 애플리케이션에 어떻게 통합하는지 보여줘요. async 파이썬과 에이전트 통합에 익숙하지 않은 분들이, 동기 에이전트 로직과 비동기 웹 서버를 조합할 때의 모범 사례를 이해하도록 도와주는 예제예요.

개요

  • Starlette — 파이썬으로 비동기 웹 애플리케이션을 만들기 위한 가벼운 ASGI 프레임워크예요.
  • anyio.to_thread.run_sync — 블로킹(동기) 코드를 백그라운드 스레드에서 실행해서, 비동기 이벤트 루프를 막지 않게 해주는 유틸리티예요.
  • CodeAgentsmolagents 라이브러리의 에이전트로, 작업을 프로그램적으로 해결할 수 있어요.

왜 백그라운드 스레드를 쓸까요?

CodeAgent.run()은 파이썬 코드를 동기적으로 실행해요. 이걸 async 엔드포인트에서 직접 부르면 Starlette의 이벤트 루프를 막아서 성능과 확장성이 떨어져요. 이 작업을 anyio.to_thread.run_sync로 백그라운드 스레드에 넘기면, 높은 동시성에서도 앱이 반응적이고 효율적으로 유지돼요.

예제 워크플로

  • Starlette 앱은 task 문자열을 담은 JSON 페이로드를 받는 /run-agent 엔드포인트를 노출해요.
  • 요청이 들어오면 에이전트가 anyio.to_thread.run_sync로 백그라운드 스레드에서 실행돼요.
  • 결과는 JSON 응답으로 반환돼요.

Starlette 앱과 CodeAgent 만들기

1. 의존성 설치

pip install smolagents starlette anyio uvicorn

2. 애플리케이션 코드 (main.py)

import anyio.to_thread
from starlette.applications import Starlette
from starlette.requests import Request
from starlette.responses import JSONResponse
from starlette.routing import Route

from smolagents import CodeAgent, InferenceClientModel

agent = CodeAgent(
    model=InferenceClientModel(model_id="Qwen/Qwen3-Next-80B-A3B-Thinking"),
    tools=[],
)

async def run_agent(request: Request):
    data = await request.json()
    task = data.get("task", "")
    # 에이전트를 백그라운드 스레드에서 동기적으로 실행
    result = await anyio.to_thread.run_sync(agent.run, task)
    return JSONResponse({"result": result})

app = Starlette(routes=[
    Route("/run-agent", run_agent, methods=["POST"]),
])

3. 앱 실행

uvicorn async_agent.main:app --reload

4. 엔드포인트 테스트

curl -X POST http://localhost:8000/run-agent -H 'Content-Type: application/json' -d '{"task": "What is 2+2?"}'

예상 응답:

{"result": "4"}

더 알아보기


전체 코드는 examples/async_agent에서 확인할 수 있어요.