🔄 Big News! bazed.ai is now sagentic.ai. Same vision, new name!

Skip to content

Creating Tools in Sagentic ​

Tools in Sagentic are reusable functions that agents can use to perform specific tasks. In this guide, we'll create a tool that allows an agent to perform a Google search using the SerpApi service.

Setting Up Your Tool ​

First, create a new file in the tools/ directory of your Sagentic project. You can name it something descriptive, like search.ts.

To ensure that your tool has access to the necessary functionality to perform a Google search, you'll need to install the serpapi package, which provides a convenient way to interact with the SerpApi service. You can install this dependency by running the following command in your project's root directory:

bash
npm install --save serpapi
bash
yarn add serpapi

Once installed, the serpapi package will be available for you to require and use within your tool, as demonstrated in the searchTool code example. This package will handle the complexities of making HTTP requests to the SerpApi service and parsing the response, allowing you to focus on the logic specific to your tool.

Writing the Tool Code ​

Here's the code for the Google search tool, step by step:

typescript
import { FunctionTool } from "sagentic";
import { getJson } from "serpapi";
import { z } from "zod";

// Define the arguments your tool will accept using Zod for schema validation
const SearchArgs = z.object({
  query: z.string().describe("The query to search for"),
});

// Define the structure of the search results your tool will return
const SearchResult = z
  .object({
    title: z.string().describe("The title of the result"),
    link: z.string().describe("The link of the result"),
    snippet: z.string().describe("The snippet of the result"),
  })
  .array()
  .describe("The search results");

// Create the search tool function
export const searchTool = (apiKey: string) =>
  new FunctionTool(
    "search",
    "Searches for a query on Google",
    SearchArgs,
    SearchResult,
    async (_agent, { query }) => {
      // Use the SerpApi `getJson` function to perform the search
      const results = await getJson({
        q: query,
        api_key: apiKey,
      });
      // Map the results to match the SearchResult schema
      return results.organic_results.map(
        (result: { title: any; link: any; snippet: any }) => ({
          title: result.title,
          link: result.link,
          snippet: result.snippet,
        })
      );
    }
  );

Understanding the Code ​

  • We import FunctionTool from Sagentic, which is a class that helps us define our tool.
  • We use getJson from the serpapi package to perform the actual search.
  • We use zod to define the input and output schemas for our tool. This ensures that the data passed to and from the tool is correctly typed and structured.
  • The searchTool function takes an apiKey parameter and returns a new FunctionTool instance.
  • The FunctionTool constructor takes the name of the tool, a description, the input schema, the output schema, and an asynchronous function that performs the search operation.

Tool Function ​

typescript
async (_agent, { query }) => {
  // Use the SerpApi `getJson` function to perform the search
  const results = await getJson({
    q: query,
    api_key: apiKey,
  });
  // Map the results to match the SearchResult schema
  return results.organic_results.map(
    (result: { title: any; link: any; snippet: any }) => ({
      title: result.title,
      link: result.link,
      snippet: result.snippet,
    })
  );
};

The tool function is where the actual search is performed. It takes two parameters: the agent that's calling the tool, and the arguments passed to the tool. In this case, the agent is not used, but it's available if needed.

Tools in Sagentic can execute any TypeScript code, leveraging the extensive Node.js library ecosystem. This flexibility allows tools to perform a diverse array of tasks, from simple computations to complex operations involving external APIs.

TypeScript automatically infers the types in tool functions based on Zod schemas, streamlining the development process by reducing manual type annotations and ensuring consistency across the tool's interface.

Zod Schemas ​

Zod is employed within Sagentic to define schemas for tools, ensuring data integrity and type safety. Descriptions within these schemas are crucial; they enable Sagentic to provide feedback to the LLM, facilitating self-correction. Custom validations in Zod enhance this process by enforcing data constraints, leading to more accurate LLM interactions.

Using Your Tool in an Agent ​

To utilize a tool within an agent, you first need to import it. For example, if you have a tool named search located in the tools directory, you would import it into your agent file like this:

typescript
import searchTool from "../tools/search";

Once imported, you have a couple of options for setting the tool within your agent's class.

Setting Tools in the Constructor ​

You can instantiate and set your tools within the constructor of your agent's class. Here's an example of how to do this:

typescript
import { Session } from "sagentic";
import searchTool from "../tools/search"; 

class SearcherAgent extends BaseAgent {
  constructor(session: Session, options: SearcherAgentOptions) {
    super(session, options);

    // Instantiate the search tool with the necessary API key
    const search = searchTool(session.context["serp-api-key"]); 
    // Set the instantiated tool in the agent's tools array
    this.tools = [search]; 
    // ...
  }
}

In this example, the searchTool is instantiated with an API key from the session context and then added to the agent's tools array.

Setting Tools as a Class Property ​

Alternatively, you can set the tools directly as a property of the agent's class:

typescript
import { Tool } from "sagentic";
import searchTool from "../tools/search"; 

class SearcherAgent extends BaseAgent {
  // Instantiate and set the tools array with the search tool
  tools: Tool[] = [searchTool("...")]; 
  // ...
}

Here, the tools property is an array that includes the instantiated searchTool. The API key or any other required parameters would be passed directly to the searchTool function.

Both methods are valid, and the choice between them can depend on whether you need to access the agent's context or options to configure your tools, or if you prefer a more straightforward setup.

Conclusion ​

Creating tools in Sagentic is a powerful way to extend the functionality of your agents. By encapsulating common tasks into tools, you can keep your agent code clean and focused while leveraging the full power of TypeScript and the Node.js ecosystem.