Replies: 9 comments 1 reply
-
Hey @YZx0pa Thanks for the question- you can use something like Check out all the tools references here: https://docs.agno.com/tools/functions#tool-parameters-reference We also have a cookbook on this: https://github.com/agno-agi/agno/blob/main/cookbook/agent_concepts/tool_concepts/stop_after_tool_call.py Please let me know if you need any help here. |
Beta Was this translation helpful? Give feedback.
-
Thank you for your advice, currently I defined a class of tools like below, and try to do await agent.arun(messages=user_input,stop_after_tool_call=True), but seems it doesn't stop interact with model after tool call. class CreationTool(Toolkit):
|
Beta Was this translation helpful? Give feedback.
-
Hey @YZx0pa I tried something like this and it seems to be working well for me- do you mind sharing your full config so I can verify what's not working and where exactly it's breaking?
|
Beta Was this translation helpful? Give feedback.
-
Hi @pritipsingh Thanks for the example! I see you're registering each class method as an individual tool — I believe that works fine. In my current approach, I instantiate the class once and register the whole instance as a single toolkit: creation_tool = CreationTool() class CreationTool(Toolkit): I actually prefer adding the class instance as a tool (instead of individual methods), because:
My concern is: if I eventually have CreationTool1, CreationTool2, etc., each with similar methods like add_data and modify_data, |
Beta Was this translation helpful? Give feedback.
-
You're right that decorating a method with You still need to explicitly call That said, you don’t need to manually list every method in tools = [...] like:
Instead, you can register the decorated methods once using
Agno’s own example demonstrates this pattern really well: So yes, your current approach using a single class instance + |
Beta Was this translation helpful? Give feedback.
-
Hi @YZx0pa, so just getting this right- by saying you want to supress the second step you dont want the agent to reply to the query? Because thats whats happening when you call You can maybe capture the run like this- """Show how to use multiple tool execution hooks, to run logic before and after a tool is called."""
import json
from typing import Any, Callable, Dict
from agno.agent import Agent
from agno.tools.toolkit import Toolkit
from agno.utils.log import logger
class CustomerDBTools(Toolkit):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.register(self.retrieve_customer_profile)
self.register(self.delete_customer_profile)
def retrieve_customer_profile(self, customer_id: str):
"""
Retrieves a customer profile from the database.
Args:
customer_id: The ID of the customer to retrieve.
Returns:
A string containing the customer profile.
"""
logger.info(f"Looking up customer profile for {customer_id}")
return json.dumps(
{
"customer_id": customer_id,
"name": "John Doe",
"email": "john.doe@example.com",
}
)
def delete_customer_profile(self, customer_id: str):
"""
Deletes a customer profile from the database.
Args:
customer_id: The ID of the customer to delete.
"""
logger.info(f"Deleting customer profile for {customer_id}")
return f"Customer profile for {customer_id}"
def validation_hook(function_name: str, call_func: Callable, arguments: Dict[str, Any]):
if function_name == "retrieve_customer_profile":
cust_id = arguments.get("customer_id")
if cust_id == "123":
raise ValueError("Cannot retrieve customer profile for ID 123")
if function_name == "delete_customer_profile":
cust_id = arguments.get("customer_id")
if cust_id == "123":
raise ValueError("Cannot delete customer profile for ID 123")
logger.info("Before Validation Hook")
result = call_func(**arguments)
logger.info("After Validation Hook")
# Remove name from result to sanitize the output
result = json.loads(result)
result.pop("name")
return json.dumps(result)
def logger_hook(function_name: str, call_func: Callable, arguments: Dict[str, Any]):
logger.info("Before Logger Hook")
result = call_func(**arguments)
logger.info("After Logger Hook")
return result
agent = Agent(
tools=[CustomerDBTools()],
# Hooks are executed in order of the list
tool_hooks=[validation_hook, logger_hook],
)
if __name__ == "__main__":
var = agent.run("retrieve_customer_profile for customer_id 456")
print(var)
print(var.content)
# agent.print_response("I am customer 456, please retrieve my profile.", markdown=True) in |
Beta Was this translation helpful? Give feedback.
-
Hi @kausmeows Thanks for you reply, In Agno, what I’m looking for is a way to stop further agent interaction after a function call is executed. I want the system to directly return the function’s result, rather than passing it back to the LLM agent for an additional reply. This behavior is similar to using @tool(show_result=True, stop_after_tool_call=True) on standalone functions. I’m trying to achieve the same effect for methods defined inside a class-based tool. Thanks! |
Beta Was this translation helpful? Give feedback.
-
I see @YZx0pa , We still have to build it. We added |
Beta Was this translation helpful? Give feedback.
-
Great thanks! |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
I’ve defined custom functions inside a class as a toolkit, where each function returns specific results (e.g., generated content). I’ve noticed that after the agent calls a tool and receives the tool’s response, it still sends the tool's return content along with the agent's prompt back to the model to generate the final assistant message.
Since the function output is already meaningful and can be long, I’d like to avoid sending it back to the model. Is there a way to stop the agent from re-engaging the model after a successful tool call, and instead directly use the tool’s response as the final output? Thank you!
Beta Was this translation helpful? Give feedback.
All reactions