Welcome! In this lesson, you’ll learn how to build a custom tool for your AI agent. Built-in tools are useful, but sometimes you need your agent to do something specific — like reading a file, querying a database, or calling a custom API. That’s where custom tools come in. By the end, you’ll know how to design, implement, and integrate a custom tool using the Agents SDK. You’ll see how to define the tool’s behavior, set its parameters, and make it available to your agent in real-world scenarios.
Why do you need a custom tool? Imagine you want your agent to read files, interact with internal systems, or process data in a unique way. Built-in tools might not cover these needs. Custom tools let you extend your agent’s abilities. For example, if you want your agent to read a file and return its contents, you can create a tool for that. This flexibility is essential for solving real business problems.
Start by writing a Python function for your task. Keep it simple and focused. Here’s an example for reading a file’s contents:
This function takes a file path and returns the file’s contents. In real life, you might use this to let your agent read logs or documents. What if the file doesn’t exist? Handle errors for robustness:
Now your tool is more user-friendly.
Your agent needs to know what arguments to provide. Use Pydantic’s BaseModel to define and validate parameters. For example:
This model ensures the tool always gets a string as the file path. If the agent sends the wrong type, Pydantic raises an error. Parsing arguments is straightforward:
This is especially helpful for tools with multiple parameters or strict input validation.
With your function and parameter model ready, integrate your tool using the Agents SDK’s FunctionTool class. Here’s how you define the tool:
Key parameters:
name: Unique tool name.description: Explains what the tool does.params_json_schema: Describes expected parameters, matching your Pydantic model.on_invoke_tool: The function called when the tool is used.
Now, let’s look at the function that will be called when the tool is used. Notice the use of the context argument (ctx), which is an instance of RunContextWrapper. Even if you don’t use it immediately, including it in your function signature is best practice:
ctx: The context object for the current agent run.args: The arguments for your tool, as a JSON string.
Including ctx allows your tool to access information about the current run, such as user input, conversation history, or other metadata, if needed.
When your custom tool is called by the agent, it receives a context argument (often named ctx). This context provides information about the current run, such as the user’s input, conversation history, and other metadata. In the Agents SDK, this context is typically an instance of RunContextWrapper.
You don’t need to use it for every tool, but it’s good practice to include it in your tool’s function signature so your tool is compatible with the agent’s runtime. This also makes your tool future-proof and allows you to access useful runtime information if needed.
Add your tool to the agent’s tools list. Here’s how:
You can also add instructions to guide the agent:
This helps the agent know when to use the tool.
Run your agent and test the custom tool using the Runner class:
The agent processes the request, uses the custom tool, and returns the file’s contents. This pattern lets you build agents that interact with the real world and automate tasks.
You learned how to build a custom tool for your AI agent: why custom tools matter, how to design the tool function, define parameters with Pydantic, integrate with the Agents SDK (including the context argument), and attach it to your agent. You also saw how to run and test your agent with the new tool. Custom tools make your agents more useful and adaptable.
Now it’s your turn! In the next section, you’ll practice building and integrating your own custom tool. You’ll get hands-on experience with each step, reinforcing what you’ve learned and preparing you to create even more powerful agents. Let’s get started!
