Agno : コンセプト : ツール – 概要 / 独自ツールの作成

ツールは Agno エージェントが外部の世界とやり取りするのを支援する関数です。ツールは、web 検索、SQL の実行、電子メールの送信や API 呼び出しのような外部システムとのやり取りを可能にすることで、エージェントを「エージェント型 (agentic)」にします。

Agno : ユーザガイド : コンセプト : ツール – 概要 / 独自ツールの作成

作成 : クラスキャット・セールスインフォメーション
作成日時 : 07/29/2025
バージョン : Agno 1.7.5

* 本記事は docs.agno.com の以下のページを独自に翻訳した上で、補足説明を加えてまとめ直しています :

* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。

 

 

Agno ユーザガイド : コンセプト : ツール – 概要

ツールは Agno エージェントが外部の世界とやり取りするのを支援する関数です。

ツールは、web 検索、SQL の実行、電子メールの送信や API 呼び出しのような外部システムとのやり取りを可能にすることで、エージェントを「エージェント型 (agentic)」にします。

Agno は 80+ の事前構築済みツールキットを備えますが、殆どの場合、独自ツールを作成することになります。一般的な構文は :

import random

from agno.agent import Agent
from agno.models.openai import OpenAIChat
from agno.tools import tool


@tool(show_result=True, stop_after_tool_call=True)
def get_weather(city: str) -> str:
    """Get the weather for a city."""
    # In a real implementation, this would call a weather API
    weather_conditions = ["sunny", "cloudy", "rainy", "snowy", "windy"]
    random_weather = random.choice(weather_conditions)

    return f"The weather in {city} is {random_weather}."


agent = Agent(
    model=OpenAIChat(model="gpt-4o-mini"),
    tools=[get_weather],
    markdown=True,
)
agent.print_response("What is the weather in San Francisco?", stream=True)

Note : 上記の例では、get_weather 関数がツールです。それが呼び出されたとき、show_result=True を設定しているため、ツールの結果は出力で表示されます。
それから、stop_after_tool_call=True を設定しているので、エージェントはツール呼び出しの後に停止します。

 

ツールキット・クラスの使用

ツールキット・クラスは、複数のツールを (それらの実行に対して追加の制御により) 管理する方法を提供します。実行後にエージェントを停止するツール、結果を表示するツールを指定できます。

from agno.agent import Agent
from agno.models.openai import OpenAIChat
from agno.tools.googlesearch import GoogleSearchTools

agent = Agent(
    model=OpenAIChat(id="gpt-4.5-preview"),
    tools=[
        GoogleSearchTools(
            stop_after_tool_call_tools=["google_search"],
            show_result_tools=["google_search"],
        )
    ],
    show_tool_calls=True,
)

agent.print_response("What's the latest about gpt 4.5?", markdown=True)

この例では、GoogleSearchTools ツールキットは google_search 関数を実行後にエージェントを停止し、この関数の結果を表示するように設定されています。

 

Agno ユーザガイド : コンセプト : ツール – 独自ツールの作成

独自ツールの作成方法と、@tool デコレータを使用してツールの動作を変更する方法を学習します。

殆どの本番環境の場合、独自のツールを作成する必要があります。それが、Agno で最高のツール使用エクスペリエンスを提供することにフォーカスしている理由です。

ルールは単純です :

  • 任意の python 関数は、エージェントによりツールとして使用できます。

  • @tool デコレータを使用してこのツールが呼び出される前後に起きることを変更できます。

 

任意の python 関数がツールとして使用可能

例えば、get_top_hackernews_stories 関数をツールとして使用する方法を以下に示します :

hn_agent.py

import json
import httpx

from agno.agent import Agent

def get_top_hackernews_stories(num_stories: int = 10) -> str:
    """
    Use this function to get top stories from Hacker News.

    Args:
        num_stories (int): Number of stories to return. Defaults to 10.

    Returns:
        str: JSON string of top stories.
    """

    # Fetch top story IDs
    response = httpx.get('https://hacker-news.firebaseio.com/v0/topstories.json')
    story_ids = response.json()

    # Fetch story details
    stories = []
    for story_id in story_ids[:num_stories]:
        story_response = httpx.get(f'https://hacker-news.firebaseio.com/v0/item/{story_id}.json')
        story = story_response.json()
        if "text" in story:
            story.pop("text", None)
        stories.append(story)
    return json.dumps(stories)

agent = Agent(tools=[get_top_hackernews_stories], show_tool_calls=True, markdown=True)
agent.print_response("Summarize the top 5 stories on hackernews?", stream=True)

出力

 

@tool デコレータのマジック

ツールの動作を変更するには、@tool デコレータを使用します。幾つかの注目すべき機能は :

  • requires_confirmation=True : 実行前にユーザの確認を必要とします。

  • requires_user_input=True : 実行前にユーザの入力を必要とします。user_input_fields を使用して、どのフィールドがユーザ入力を必要としているか指定します。

  • external_execution=True : ツールはエージェントの制御の外で実行されます。

  • show_result=True : ツール呼び出しの出力をエージェントの応答で表示します。このフラグなしでは、ツール呼び出しの結果は更なる処理のためにモデルに送信されます。

  • stop_after_tool_call=True : ツール呼び出しの後、エージェントの実行を停止します。

  • tool_hooks : このツール呼び出しの前後にカスタムロジックを実行します。

  • cache_results=True : 同じ呼び出しの繰り返しを避けるために、ツールの結果をキャッシュします。cache_dir と cache_ttl を使用してキャッシュを設定します。

@tool デコレータで可能な多くのパラメータを使用する例が以下です。

advanced_tool.py

import httpx
from agno.agent import Agent
from agno.tools import tool
from typing import Any, Callable, Dict

def logger_hook(function_name: str, function_call: Callable, arguments: Dict[str, Any]):
    """Hook function that wraps the tool execution"""
    print(f"About to call {function_name} with arguments: {arguments}")
    result = function_call(**arguments)
    print(f"Function call completed with result: {result}")
    return result

@tool(
    name="fetch_hackernews_stories",                # Custom name for the tool (otherwise the function name is used)
    description="Get top stories from Hacker News",  # Custom description (otherwise the function docstring is used)
    show_result=True,                               # Show result after function call
    stop_after_tool_call=True,                      # Return the result immediately after the tool call and stop the agent
    tool_hooks=[logger_hook],                       # Hook to run before and after execution
    requires_confirmation=True,                     # Requires user confirmation before execution
    cache_results=True,                             # Enable caching of results
    cache_dir="/tmp/agno_cache",                    # Custom cache directory
    cache_ttl=3600                                  # Cache TTL in seconds (1 hour)
)
def get_top_hackernews_stories(num_stories: int = 5) -> str:
    """
    Fetch the top stories from Hacker News.

    Args:
        num_stories: Number of stories to fetch (default: 5)

    Returns:
        str: The top stories in text format
    """
    # Fetch top story IDs
    response = httpx.get("https://hacker-news.firebaseio.com/v0/topstories.json")
    story_ids = response.json()

    # Get story details
    stories = []
    for story_id in story_ids[:num_stories]:
        story_response = httpx.get(f"https://hacker-news.firebaseio.com/v0/item/{story_id}.json")
        story = story_response.json()
        stories.append(f"{story.get('title')} - {story.get('url', 'No URL')}")

    return "\n".join(stories)

agent = Agent(tools=[get_top_hackernews_stories])
agent.print_response("Show me the top news from Hacker News")

 

以上