Today I learned about ToolLoopAgent while working with the Vercel AI SDK. It's an abstraction where you define your tools and model, and it handles the agent loop automatically by calling the model, executing whichever tools it selects, feeding results back, and repeating until the task is complete.
I used it to build a chatbot for my company's developer documentation. The docs are written in Markdown, then converted into a JSON file that the server loads on startup. The structure is just filename as key, trimmed and minified content as value:
{
"docs/api/payments.md": "# Payments API\n...",
"docs/guide/quickstart.md": "# Quickstart\n..."
}
This JSON acts as a virtual filesystem. The agent gets five tools to navigate it: listFiles, searchFiles, searchLines, grepFiles, and readFile.
The prompt is pretty much like this:
Your task is to help users find information in the documentation by:
1. Understanding their query
2. Using the documentation navigation files to choose the right source page
3. Reading the relevant endpoint or overview page before answering
4. Providing clear, accurate answers based on the documentation
Available Tools:
- Use 'listFiles' to explore the directory structure. Pass {"path": "."} for root, or {"path": "docs/api"} for subdirectories.
- Use 'searchFiles' to find files containing a keyword (case-insensitive). Returns excerpts so you can choose the right file. Pass {"keyword": "your search term"}.
- Use 'searchLines' to search for plain text patterns across all files. Returns matching lines with file paths. Pass {"pattern": "your pattern"}.
- Use 'grepFiles' for advanced regex searches when plain text is not enough. Pass {"pattern": "your regex"}.
- Use 'readFile' to read the full contents of a file. Pass {"path": "exact/file/path.md"}.
The rest of the prompt is mostly guardrails to keep responses scoped to the docs. For small to medium datasets this works well (~200 Markdown files) because the memory footprint stays under 10MB while giving the agent fast in-memory access. We don't need RAG here unless semantic understanding is critical to the use case.
To integrate with OpenRouter, I swapped the Vercel AI SDK for the OpenRouter Agent SDK. Fortunately they have the same function called callModel (docs), which handles LLM calls with automatic tool execution.
For the model I decided to use gpt-oss-120b, and it's surprisingly good at tool calling for the price, it returns accurate results and points to the right endpoints. With this approach I can keep the docs chatbot really cheap without a third party subscription.
This reminds me that the definition of an agent is actually pretty simple: an LLM running in a loop with access to tools, repeating until the job is done. Simon Willison covers it well here.