Hugging Faceの新しいAgent Framework「smolagents」とCodeAgentの活用法

こんにちは
AIチームの戸田です

今回はHugging Faceが提供しているAgent Frameworkのsmolagentsが非常に興味深かったので、実際に触ってみた内容を共有します。

smolagentsは、Agentをシンプルに構築できることを目的としたライブラリで、従来のAgent Frameworkと比較して以下の2点で差別化されています。

  • シンプルな設計: 必要最小限の抽象化でAgentの構築が可能。公式のコードも約1,000行と軽量。
  • CodeAgent: Pythonコードを直接生成・実行することで、処理ステップを削減し、パフォーマンスを向上。

特に注目すべきは、後者のCodeAgentという仕組みです。CodeAgentは、タスクに応じたPythonコードを生成し、それを実行することで複雑なロジックや操作を簡潔に処理できる点が優れています。

なぜCodeAgentが必要とされるのか

従来のAgent Frameworkでは、LLMの出力を解析し、事前に定義されたJSONやXMLなどのフォーマットに従ってツールや関数を呼び出す方法が一般的ですが、このアプローチには以下のような課題があります。

  • 解析の複雑さ:LLMの出力を正確に解析し、適切なツールや引数を特定するためのパーサーが複雑化します。
  • 表現力の限界:JSONなどの定型的なフォーマットでは、複雑なロジックや条件分岐、ループなどを表現するのが困難です。
  • LLMの訓練データとの不整合:LLMは大量のコードデータで訓練されており、コードによる指示やアクションの生成には慣れていますが、カスタムフォーマットには最適化されていません。

これらの問題を解決するために、CodeAgentのアプローチが必要とされています。

CodeAgentのメリット

複数の研究(参考論文1, 参考論文2, 参考論文3)で従来のツールを呼び出すAgentに比べてCodeAgentの方が優れていると述べられています。

Executable Code Actions Elicit Better LLM Agents Figure 1より

簡単にどのような点で優れているのかをまとめました。

1. コードによる高度な表現力

CodeAgentは、LLMが直接Pythonコードを生成し、そのコードを実行することでタスクを達成します。これにより、複雑なアルゴリズム、条件分岐、ループ、例外処理など、Pythonコードで表現できるあらゆるロジックを活用できます。

2. LLMの能力を最大限に活用

LLMは既に大量のコードデータで訓練されており、コード生成や理解に優れています。CodeAgentはこの能力を直接活用し、より自然で効率的なエージェントの動作を実現します。

3. ツールやライブラリの柔軟な統合

Pythonコードを生成・実行するため、既存の豊富なPythonのライブラリやツールを簡単に統合できます。これにより、データ分析、機械学習、ウェブスクレイピングなど、多彩なタスクに対応可能です。

4. 開発とデバッグの容易さ

生成されたコードは通常のPythonコードであるため、開発者は既知のデバッグ手法やテストフレームワークを活用できます。これにより、問題の特定や解決が容易になります。

smolagentsの使い方

ここからはsmolagentsの基本的な使い方やCodeAgentの具体例を見ていきます。

インストール

smolagentはpipで簡単にインストール可能です。

pip install smolagents

シンプルなCodeAgentの構築と実行

以下は、smolagentsを用いた簡単なCodeAgentの構築例です。このコードではAgentにフィボナッチ数列の118番目の数字を答えさせます。

from smolagents import CodeAgent, LiteLLMModel

model = LiteLLMModel(model_id="openai/gpt-4o")
agent = CodeAgent(
    tools=[],
    model=model
)
agent.run(
    "Could you give me the 118th number in the Fibonacci sequence?",
)

このコードを実行すると以下のような出力が得られます。

1264937032042997393488322という出力が得られました。こちらのサイトで確認してみるとあってそうです。

今回の例ではモデルにOpenAIのGPT-4oを使用していますが、LiteLLMを通じて使用できるClaudeやGeminiなどの他のLLMや、transformersから使えるLocal LLMも設定することができます。

CodeAgentを定義する際の引数であるtoolsにはAgentが使用する関数(所謂Function Calling)を設定するのですが、smolagentsはデフォルトでPythonコード実行機能が備わっているので何も設定しなくても、以下のような関数をAgent自身で生成して実行することで回答を得ています。

  def fibonacci(n):                                                      
      a, b = 0, 1                                                        
      for _ in range(n-1):                                               
          a, b = b, a + b                                                
      return a                                                           
                                                                         
  fibonacci_118 = fibonacci(118)                                         
  print(fibonacci_118) 

ちなみに生成したコードにバグが含まれていた場合、エラー出力を考慮してコードを再生成してくれます。何回まで再チャレンジするかはmax_stepsパラメータで設定します(デフォルト6)。

使用できるライブラリを追加する

CodeAgentが生成するコードが利用できるモジュールはprintなどのPythonにデフォルトで設定されているもののみですが、CodeAgentを定義する際にadditional_authorized_importsを設定することで、使用できるモジュールを追加できます。以下はrequestsとbeautifulsoupを設定することでスクレイピングを行えるCodeAgentの例です。

from smolagents import CodeAgent, LiteLLMModel

model = LiteLLMModel(model_id="openai/gpt-4o")

agent = CodeAgent(
    tools=[],
    model=model,
    additional_authorized_imports=['requests', 'bs4'],
)

agent.run("Could you get me the title of the page at url 'https://www.ai-shift.co.jp/techblog/5333'?")

スクレイピング対象は前回のTech Blogで、タイトルを取得します。

コードを実行すると以下のような出力が得られます。

どうやら適切なタイトルを取得することができたようです。

本来であれば自分でbeautifulsoupを使ってクローリング用の関数を作ったり、Firecrawlのようなツールとの連携が必要ですが、CodeAgentではこういった手間がありません。

一方、意図を超えたコードを生成して実行できてしまう可能性がある点には気をつけて下さい。smolagentsは無限ループやリソースの肥大化を防ぐために操作数を制限しているのですが、セキュリティを最大限に高めるにE2B などのサンドボックス環境でコードを実行することが好ましいです。E2Bは、分離されたコンテナでコードを実行するリモート実行サービスで、smolagentsではCodeAgentを定義する際にuse_e2b_executorをTrueに設定することで使用できます。複雑な処理をさせるときは、基本的にこちらを使うのが良いでしょう。

Tools

これまでの例でtoolsは空でしたが、生成したPythonコードだけでは処理しきれない指示に対応するために、OpenAIのFunction Callingのように独自ツールを関数として設定することができます。

smolgagentsにはデフォルトでWeb検索(DuckDuckGoSearchTool)や音声処理(SpeechToTextTool)などの様々なツールが用意されていますが、smolagents.Toolクラスを継承する、もしくはデコレーターsmolagents.toolを使用することで独自のツールを定義することができます

以下はツールを設定した Agentの例です。

from smolagents import CodeAgent, LiteLLMModel, DuckDuckGoSearchTool, 

model = LiteLLMModel(model_id="openai/gpt-4o")

# デフォルトで用意されているWeb検索のツール
search_tool = DuckDuckGoSearchTool()

# Hugging Face Hub上で、指定されたタスクの最もダウンロードされたモデルを返すツールを作成
@tool
def model_download_tool(task: str) -> str:
    """
    This is a tool that returns the most downloaded model of a given task on the Hugging Face Hub.
    It returns the name of the checkpoint.

    Args:
        task: The task for which to get the download count.
    """
    most_downloaded_model = next(iter(list_models(filter=task, sort="downloads", direction=-1)))
    return most_downloaded_model.id

agent = CodeAgent(
    tools=[search_tool, model_download_tool],  # Web検索と上記で作成したオリジナルツールを追加
    model=model,
)

なお、こちらはtoolsを設定する例を示すためのサンプルコードなので、これにより何かの問題を解決する、といったことは想定していないのでご了承ください。

おわりに

smolagentsのCodeAgentは、LLMの持つコード生成能力を直接利用することで、従来の Agent Frameworkでは難しかった柔軟なタスクの実行を可能にします。Pythonコードを生成・実行するというアプローチは、LLMの訓練データとの親和性が高く、優れたパフォーマンスを実現します。

一方で、セキュリティやリソース管理といった実運用上の課題も存在します。安全な実行環境の構築や適切なモジュールの制限など、ガイドラインに従った運用が求められます。

smolagentsは、シンプルでありながら強力なエージェントを構築するための有用なツールだと思います。興味を持たれた方は、ぜひ一度試してみてください。

最後までお読みいただき、ありがとうございました!

PICK UP

TAG