Python Functions as Tools

Turn any Python function into an agent tool.

Any python function can be used as a tool by an Agent.

For example, here's how to use a get_top_hackernews_stories function as a tool:

1import json
2import httpx
3
4from kern.agent import Agent
5
6def get_top_hackernews_stories(num_stories: int = 10) -> str:
7 """
8 Use this function to get top stories from Hacker News.
9
10 Args:
11 num_stories (int): Number of stories to return. Defaults to 10.
12
13 Returns:
14 str: JSON string of top stories.
15 """
16
17 # Fetch top story IDs
18 response = httpx.get('https://hacker-news.firebaseio.com/v0/topstories.json')
19 story_ids = response.json()
20
21 # Fetch story details
22 stories = []
23 for story_id in story_ids[:num_stories]:
24 story_response = httpx.get(f'https://hacker-news.firebaseio.com/v0/item/{story_id}.json')
25 story = story_response.json()
26 if "text" in story:
27 story.pop("text", None)
28 stories.append(story)
29 return json.dumps(stories)
30
31agent = Agent(tools=[get_top_hackernews_stories], markdown=True)
32agent.print_response("Summarize the top 5 stories on hackernews?", stream=True)

Accessing built-in parameters in Tools

Kern automatically injects some built-in parameters into your tool functions, so you can easily gain access to important information and objects in your tools.

These built-in parameters are:

  • run_context: The run context object from where you can access the session state, dependencies, metadata, etc.
  • agent: The agent object.
  • team: The team object.
  • images: The images object.
  • videos: The videos object.
  • audio: The audio object.
  • files: The files object.

For example to access agent in a tool, you can do:

1from kern.agent import Agent
2from kern.models.openai import OpenAIResponses
3
4def get_agent_model(agent: Agent) -> str:
5 """Get the model of the agent."""
6 return agent.model.id
7
8agent = Agent(
9 model=OpenAIResponses(id="gpt-5.2"),
10 tools=[get_agent_model],
11)
12
13agent.print_response("What is the model of the agent?", stream=True)

See Tool Built-in Parameters for more details on run_context, agent, team, and media parameters.

Magic of the @tool decorator

To modify the behavior of a tool, use the @tool decorator. Some notable features:

  • requires_confirmation=True: Requires user confirmation before execution.
  • requires_user_input=True: Requires user input before execution. Use user_input_fields to specify which fields require user input.
  • external_execution=True: The tool will be executed outside of the agent's control.
  • show_result=True: Show the output of the tool call in the Agent's response, True by default. Without this flag, the result of the tool call is sent to the model for further processing.
  • stop_after_tool_call=True: Stop the agent run after the tool call.
  • tool_hooks: Run custom logic before and after this tool call.
  • cache_results=True: Cache the tool result to avoid repeating the same call. Use cache_dir and cache_ttl to configure the cache.

Here's an example that uses many possible parameters on the @tool decorator.

1import httpx
2from kern.agent import Agent
3from kern.tools import tool
4from typing import Any, Callable, Dict
5
6def logger_hook(function_name: str, function_call: Callable, arguments: Dict[str, Any]):
7 """Hook function that wraps the tool execution"""
8 print(f"About to call {function_name} with arguments: {arguments}")
9 result = function_call(**arguments)
10 print(f"Function call completed with result: {result}")
11 return result
12
13@tool(
14 name="fetch_hackernews_stories", # Custom name for the tool (otherwise the function name is used)
15 description="Get top stories from Hacker News", # Custom description (otherwise the function docstring is used)
16 stop_after_tool_call=True, # Return the result immediately after the tool call and stop the agent
17 tool_hooks=[logger_hook], # Hook to run before and after execution
18 requires_confirmation=True, # Requires user confirmation before execution
19 cache_results=True, # Enable caching of results
20 cache_dir="/tmp/agno_cache", # Custom cache directory
21 cache_ttl=3600 # Cache TTL in seconds (1 hour)
22)
23def get_top_hackernews_stories(num_stories: int = 5) -> str:
24 """
25 Fetch the top stories from Hacker News.
26
27 Args:
28 num_stories: Number of stories to fetch (default: 5)
29
30 Returns:
31 str: The top stories in text format
32 """
33 # Fetch top story IDs
34 response = httpx.get("https://hacker-news.firebaseio.com/v0/topstories.json")
35 story_ids = response.json()
36
37 # Get story details
38 stories = []
39 for story_id in story_ids[:num_stories]:
40 story_response = httpx.get(f"https://hacker-news.firebaseio.com/v0/item/{story_id}.json")
41 story = story_response.json()
42 stories.append(f"{story.get('title')} - {story.get('url', 'No URL')}")
43
44 return "\n".join(stories)
45
46agent = Agent(tools=[get_top_hackernews_stories])
47agent.print_response("Show me the top news from Hacker News")

See the @tool Decorator Reference for more details.