Building AI Agents from Scratch

Giving Your Agent Tools

Define the first tools and let the model decide when to call them.

A tool is a function plus a description the model can see. You do not call it from an if on the user text. You advertise it; the model may emit a tool_call instead of a final answer.

Advertise one tool

Chat Completions wants a list of tool objects. The name and description are the UI:

TOOLS = [
    {
        "type": "function",
        "function": {
            "name": "list_dir",
            "description": "List files in a project-relative directory. Use when the user asks what is on disk.",
            "parameters": {
                "type": "object",
                "properties": {
                    "path": {
                        "type": "string",
                        "description": "Relative directory. Use . for the project root.",
                    }
                },
                "required": ["path"],
            },
        },
    }
]

Pass tools=TOOLS into chat.completions.create. If the model wants the tool, message.tool_calls is a list. If it is done, tool_calls is empty and content is the answer.

The model decides

Ask “What files are in this folder?” and you should see a tool call. Ask “What is 2+2?” and you should not — there is no calculator. That contrast is the lesson.

response = client.chat.completions.create(
    model=MODEL,
    messages=messages,
    tools=TOOLS,
)
message = response.choices[0].message
print(message.content)
print(message.tool_calls)

Check it

  1. Print tool_calls for a disk question — you should see list_dir and a path argument.
  2. Print it for a trivia question — tool_calls should be missing or empty.
  3. Change the description to forbid . and see if the model picks another path.

You have not executed anything yet. Next: parse the call, run Python, send the result back.