Tools and the Agent LoopTools, and binding them to a model
No narration yet
Module 2, Lesson 120 min
Tools, and binding them to a model
The twice-daily todoist-hygiene job runs a prompted skill today. This module gives it a real agent brain: tools wrapping your existing scripts/todoist/client.py, emitting a plan that validates against the apply contract you already trust. Same safety, sharper filing.
A tool is a function the model can decide to call. You describe it, name, description, argument schema, and hand it to the model. The model, mid-generation, can emit a request to call it with arguments; your runtime executes it and feeds the result back.
Defining a tool
import { tool } from "langchain";import * as z from "zod/v4";const snapshotInbox = tool( async (input) => { // shell out to scripts/todoist/client.py snapshot, return JSON string return await runTodoist("snapshot", input.date); }, { name: "snapshot_inbox", description: "Fetch a snapshot of the Todoist inbox for a given date.", schema: z.object({ date: z.string() }), },);
Binding tools to a model
const withTools = model.bindTools([snapshotInbox]);const res = await withTools.invoke(messages);// res.tool_calls may contain requests you must execute, then loop back
That is the raw level: attach tools, the model gains the ability to request them, and the resulting tool_calls are requests you must execute yourself and feed back as tool messages.
Practice
Try it yourself
Recall
What a tool needs
These are the three the model itself depends on. The function body is not one of them.
What three things does tool(fn, {...}) require in its options?