smolagents 사용해보기
몇 줄의 코드로 스스로 코딩하는 AI agent를 만들고 문제를 해결하도록 할 수 있는 라이브러리, smolagents에 대해 알아보고, 예제 코드를 돌려보며 smolagents의 느낌을 가져봅니다.
2024년의 마지막 날, huggingface에서 smolagents 라는 작은 라이브러리를 출시했습니다. 몇 줄의 코드로 AI agent를 만들고, 손쉽게 다양한 도구를 쥐어줄 수 있는 라이브러리입니다. 특히 직접 문제를 풀기 위한 코드를 작성하는 'CodeAgent'를 라이브러리 자체에서 지원하여, 정해진 도구를 사용하는 'ToolCallingAgent'와 함께 사용되었을 때 엄청난 시너지를 낼 수 있을 것 같은 느낌입니다. 이 포스팅에서는 smolagents를 사용하는 방법을 간단히 알아보고, 이 라이브러리를 어떻게 응용할 수 있을지 생각해보겠습니다!
설치
smolagents는 pip로 간단히 설치 가능합니다.
pip install smolagents
간단히 시작해보기
간단한 working example로 smolagents가 어떻게 작동하는지 느낌을 가져봅시다.
사전 준비: Huggingface token 받기
smolagents를 이용하면 기본적으로 Huggingface inference API를 이용하는 HfApiModel을 통해 huggingface에 올려진 오픈소스 LLM 들을 손쉽게 사용할 수 있습니다. 물론 OpenAI와 Anthropic 의 모델들도 LiteLLMModel을 통해 사용할 수 있구요. 처음 예시는 HfApiModel을 사용해 볼텐데요, huggingface 로그인 없이 사용하게 되면 몇 번 API call을 안 해도 빠르게 rate limiting이 걸려 제대로 튜토리얼을 진행할 수 없더라구요. Huggingface token을 받아서 진행해 줍시다.
Huggingface에 로그인하신 뒤, token은 아래에서 받을 수 있습니다.

Token을 발급받은 뒤, 적절한 이름의 환경 변수로 저장해 줍시다. 저는 다른 API KEY들과의 일관성을 위해서, HUGGINGFACE_API_KEY 로 저장했습니다.
튜토리얼: 검색 툴이 달린 AI agent를 활용해보자 : 임진왜란은 몇 년 동안이나 지속되었나?
smolagents 공식 튜토리얼에서는, 치타가 최대 속도로 달리면 얼마나 빠르게 파리의 퐁 데자르 다리를 건널 수 있는지를 AI agent에게 알아내도록 하는 코드 예시를 제공합니다. 여기서는 좀 더 재밌게, 한국인 입맛에 좀 맞게 문제를 변형해 보겠습니다. AI agent가 필요한 정보를 찾아서, 그 정보를 이용하여 필요한 연산을 수행할 수 있는지 알아보기 위해, 임진왜란이 몇 년 동안에 걸친 전쟁이었는지를 물어보겠습니다. 아래 코드입니다.
import os
from smolagents import CodeAgent, DuckDuckGoSearchTool, HfApiModel
agent = CodeAgent(
tools=[DuckDuckGoSearchTool()],
model=HfApiModel(token=os.getenv("HUGGINGFACE_API_KEY"))
)
agent.run("In days, how long did the the Limjin war (Japanese Invasion of Korea) last?")
Agent의 종류는 CodeAgent
를 사용하고, agent에게 DuckDuckGoSearchTool()
형태로 검색 도구를 사용할 수 있게 허락했습니다.
우선 결과부터 확인해봅시다.

실제로 임진왜란은 양력으로 1592년 5월 23일에 시작되어, 1598년 12월 24일에 끝난 전쟁입니다. 일수로 따져 보면.. 2406일이 맞네요!
그럼 어떻게 agent가 이렇게 정확한 결과를 줄 수 있었는지, 한 번 agent의 추론 과정을 살펴봅시다. smolagents에서 agent.run 을 실행하면, 터미널 창에 매 스텝 별로, 실제로 문제를 풀면서 CodeAgent가 작성하는 코드와 그 결과가 꽤나 화려하게 출력됩니다. 첫 스텝으로 어떤 작업을 했을까요?

web_search
함수를 적절한 query문을 넣어 실행하고 있음을 알 수 있다.모델은 DuckDuckGoSearchTool을 사용할 수 있으므로, 임진왜란 날짜에 대한 정보를 가장 먼저 찾는 것은 자연스러워 보이네요. 또 하나 눈여겨볼 것은, Executing this code 로 나타난 코드 블럭은, 모델이 직접 구현한 코드라는 겁니다. 즉, DuckDuckGoSearchTool의 형태로 제공된 web_search 함수를 "Limjin War start and end dates" 라는 query를 넣어 실행하고, 그 결과를 파이썬 print를 써서 출력하는 코드가 되는 셈입니다.
다음 스텝에서, CodeAgent가 이 검색 결과를 바탕으로 어떤 코드를 짰을지 궁금하지 않으신가요?

놀랍게도, 파이썬의 datetime 내장 라이브러리를 활용하여 검색 결과에 나타나있던 임진왜란의 시작과 끝 날짜의 차이를 계산하는 코드를 짰군요! 그 결과를 일수로 출력하고 있습니다. 이 결과값을 바탕으로 다음 스텝에서는 최종 출력을 하는 일만 남았습니다.

smolagents에서 OpenAI, Anthropic, DeepSeek 모델 사용하기
기본값이 Qwen/Qwen2.5-Coder-32B-Instruct로 설정된 huggingface의 inference API도 물론 좋지만, 개인적으로는 아무래도 GPT, claude, DeepSeek 모델을 쓸 수 있다면 쓰고 싶은 느낌입니다. 가능할까요? smolagents의 LiteLLMModel을 이용하여 쉽게 가능합니다!
from smolagents import CodeAgent, DuckDuckGoSearchTool, LiteLLMModel
agent = CodeAgent(
tools=[DuckDuckGoSearchTool()],
model=LiteLLMModel("openai/gpt-4o"),
)
agent.run("How long did the the Limjin war last? Answer in exact days.")
LiteLLMModel("gpt-4o")와 같이 작성해도 작동하는 것을 확인했습니다. Claude sonnet은 LiteLLMModel("anthropic/claude-3-5-sonnet-latest")를 사용하시면 됩니다.
참고로, OPENAI_API_KEY, ANTHROPIC_API_KEY 등으로 API key들이 적절하게 환경 변수에 설정이 되어 있어야 합니다. LiteLLM 문서를 참고하시면 좋습니다. 주요 provider/model을 리스팅해보면 아래와 같습니다.
- openai/gpt-4o
- anthropic/claude-3-5-sonnet-latest
- deepseek/deepseek-chat
데이터 읽어서, 그래프 그려줄 수 있니?
CodeAgent는 스스로 추론하여 필요한 코드를 짜고, 실행하여 결과를 뽑아냅니다. 이 결과를 바탕으로 다시 추론을 하거나 (이렇게 추론-실행을 반복하면 multi-step agent 라고 부릅니다), 최종 결과를 출력합니다. 코드를 어느 정도까지 짤 수 있는지 궁금해지는데요, 한번 그 능력을 테스트해 봅시다.
만약 이미지를 생성하는 작업을 수행하면 결과 처리는 어떻게 할지도 궁금해지더라구요. 한번 "데이터를 읽어서 그래프를 그려 주는" 작업을 시켜봅시다.
import 가능한 패키지 늘려주기
맨 처음에는, 아래 코드처럼 iris 데이터셋을 어떻게든 가져와서, petal length vs sepal length 관계를 나타내는 산점도를 그려달라고 해 봤습니다.
agent = CodeAgent(
tools=[DuckDuckGoSearchTool()],
model=LiteLLMModel("openai/gpt-4o-mini"),
)
agent.run("Draw and save a scatter plot of the petal and sepal length of the iris dataset. Do not display the plot.")

그 결과, 코드는 원하는대로 짰지만, matplotlib 라이브러리의 import가 허용되지 않았다는 에러가 뜨네요. 보안 상의 이유로, smolagents는 승인된 import의 수를 굉장히 제한적으로 유지하고 있습니다. os 라이브러리를 허용해줬다가, os.system('rm -rf /') 을 실행했다고 상상해 보세요 😱
그럼에도 불구하고 지금 작업에 꼭 필요한 패키지가 있을 때는, CodeAgent의 additional_authorized_imports 파라미터를 사용하여 추가적으로 import 가능한 패키지를 넘겨주면 됩니다.
from smolagents import CodeAgent, DuckDuckGoSearchTool, LiteLLMModel
agent = CodeAgent(
tools=[DuckDuckGoSearchTool()],
model=LiteLLMModel("openai/gpt-4o-mini"),
additional_authorized_imports=[
"seaborn", "matplotlib", "pandas", "sklearn"
],
)
agent.run("Draw and save a scatter plot of the petal and sepal length of the iris dataset. Do not display the plot.")
그 결과, 성공적으로 matplotlib과 seaborn을 이용하여 코드를 짜고 알아서 실행하는 데 성공합니다. scatter_plot_iris.png 라는 이름으로 파일을 저장해줬군요.

iris_scatter_plot.png 파일은 아래와 같이 생겼습니다. 기대했던 그래프입니다 😀
