Understanding AI Tools

A tool is a function that can be called by the model to perform a specific task. You can think of a tool like a program you give to the model that it can run as and when it deems necessary.
Tools enable the AI to interact with external systems, databases, and APIs, making it much more powerful than a simple text generator.

Adding the Resource Tool

Let’s create a tool to give the model the ability to create, embed, and save a resource to your agent’s knowledge base. Update your route handler with the following code:
app/api/chat/route.ts
import { createResource } from "@/lib/actions/resources";
import { openai } from "@ai-sdk/openai"; // Replace with your AI provider
import { convertToModelMessages, streamText, tool, UIMessage } from "ai";
import { z } from "zod";

// Allow streaming responses up to 30 seconds
export const maxDuration = 30;

export async function POST(req: Request) {
  const { messages }: { messages: UIMessage[] } = await req.json();

  const result = streamText({
    model: openai("gpt-4o"), // Replace with your AI provider
    system: `You are a helpful assistant. Check your knowledge base before answering any questions.
    Only respond to questions using information from tool calls.
    if no relevant information is found in the tool calls, respond, "Sorry, I don't know."`,
    messages: convertToModelMessages(messages),
    tools: {
      addResource: tool({
        description: `add a resource to your knowledge base.
          If the user provides a random piece of knowledge unprompted, use this tool without asking for confirmation.`,
        inputSchema: z.object({
          content: z
            .string()
            .describe("the content or resource to add to the knowledge base"),
        }),
        execute: async ({ content }) => createResource({ content }),
      }),
    },
  });

  return result.toUIMessageStreamResponse();
}

How the Tool Works


Testing the Tool

1

Test the Tool

Head back to the browser and tell the model your favorite food. You should see an empty response in the UI.
2

Check the Database

Run the following command in a new terminal window:
terminal
pnpm db:studio
This will start Drizzle Studio where you can view the rows in your database.
3

Verify Results

You should see a new row in both the embeddings and resources table with your favorite food!
The tool call happens automatically when the AI determines it should add information to your knowledge base. The empty response indicates the tool was called successfully.

Updating the UI for Tool Calls

Let’s make a few changes in the UI to communicate to the user when a tool has been called. Update your root page (app/page.tsx) with the following code:
app/page.tsx
"use client";

import { useChat } from "@ai-sdk/react";
import { useState } from "react";

export default function Chat() {
  const [input, setInput] = useState("");
  const { messages, sendMessage } = useChat();
  return (
    <div className="flex flex-col w-full max-w-md py-24 mx-auto stretch">
      <div className="space-y-4">
        {messages.map((m) => (
          <div key={m.id} className="whitespace-pre-wrap">
            <div>
              <div className="font-bold">{m.role}</div>
              {m.parts.map((part) => {
                switch (part.type) {
                  case "text":
                    return <p>{part.text}</p>;
                  case "tool-addResource":
                  //we'll add the tool tool-getInformation in a later section
                  case "tool-getInformation":
                    return (
                      <p>
                        call{part.state === "output-available" ? "ed" : "ing"}{" "}
                        tool: {part.type}
                        <pre className="my-4 bg-zinc-100 p-2 rounded-sm">
                          {JSON.stringify(part.input, null, 2)}
                        </pre>
                      </p>
                    );
                }
              })}
            </div>
          </div>
        ))}
      </div>

      <form
        onSubmit={(e) => {
          e.preventDefault();
          sendMessage({ text: input });
          setInput("");
        }}>
        <input
          className="fixed bottom-0 w-full max-w-md p-2 mb-8 border border-gray-300 rounded shadow-xl"
          value={input}
          placeholder="Say something..."
          onChange={(e) => setInput(e.currentTarget.value)}
        />
      </form>
    </div>
  );
}

Understanding Tool Call Flow

AI Decision

Model Evaluation: The AI decides whether to call a tool based on the user’s input and tool descriptions.

Tool Execution

Function Call: The AI SDK automatically calls the execute function with the extracted parameters.

Database Update

Data Persistence: The tool creates embeddings and stores the resource in your database.

UI Feedback

User Communication: The UI shows which tool was called and its input parameters.

Tool Call States

The tool call has different states that you can track:
  • calling: The tool is currently being executed
  • output-available: The tool has completed and returned results

Testing the Updated Interface

1

Save and Refresh

Save the file and head back to the browser. Refresh the page to see the updated UI.
2

Test Tool Display

Tell the model your favorite movie. You should now see which tool is called in place of the model’s typical text response.
3

Verify Tool Information

The UI will display the tool name, state, and input parameters in a formatted JSON block.
With this change, you now conditionally render the tool that has been called directly in the UI, providing transparency about what the AI is doing behind the scenes.

Extension task