How to create LLM tools from any Python SDK using langchain-autotools

On this page
langchain-autotools is
a community-maintained library that creates LLM tools from an existing
Python SDK. You pass it an SDK client object, choose which of the SDK's
functions to expose with CrudControls, and hand the resulting
operations to a LangChain agent. That saves you from writing and
describing a wrapper function for every API call. It has one notable
limitation: it can only call the SDK's top-level functions, which we show
with an Azure Blob Storage example.
Giving LLMs access to our internal and external APIs and databases is one of the most promising ways to use LLMs in business. Chatbot applications like ChatGPT are great, but that's where the productivity gains start. They get much higher once we integrate these models into our existing workflows, or build new workflows around them.
The established concept for letting LLMs interact with other technologies is called Tools. Tools are a good concept, but it's not that straightforward to design them so that LLMs can work with them. And at the end of the day, creating them is a lot of work.
langchain-autotools integrates with the well-known Langchain SDK, and its goal is to make creating tools for LLMs as easy as possible.
Update (November 2026): The code below targets LangChain 0.2 and
langchain-autotools 0.0.x. In LangChain 1.0, hub and the legacy agent
APIs (AgentExecutor, create_structured_chat_agent) moved to the
langchain-classic package, and create_agent is the recommended way to
build agents (see the v1 migration
guide).
langchain-autotools 0.2.0
is built for LangChain 1.x and takes the SDK client directly
(AutoToolWrapper(client=s3, ...)) instead of a dict.
What are LLM tools?
In their purest form, LLM tools are just functions that run after an LLM decides to use them.
The process is fairly simple:
-
Create a runtime environment where you can run code, for example a Python environment.
-
Create a function that, for example, interacts with an API or a database. The function can have parameters, which the LLM provides later.
-
Describe in natural language what the function does. Also describe its parameters and return value.
-
When you want the LLM to execute a task, send it your task prompt plus the descriptions of all tools (think: functions). The LLM then decides whether it can fulfill the prompt without a tool, or whether it needs one.
-
If the LLM decides to use a tool, it tells you which one. You then call your function with the parameters the LLM provided. In pseudo Python code, this is just an if statement:
To summarize: a tool is nothing more than a function with a good description, so that the LLM knows what it does and how to use it.
If you deal with many external systems, you can probably see the problem already: wrapping all of them into functions and writing a good description for each one is cumbersome. (For a framework-free look at how agents call tools, see our guide on building AI agents without frameworks.)
Many external systems nowadays provide SDKs, and those SDKs already come with extensive documentation. Why not use that documentation to create tools for our LLMs?
How to create LLM tools with langchain-autotools
We can, and that's what langchain-autotools is for. It combines the Langchain Agent concept with the SDK's documentation, so that agents can use any SDK as their tool.
Note: An agent in this context is just an LLM that can use tools.
With langchain-autotools, creating a tool takes four steps:
-
Instantiate a client object of the SDK you want to use.
-
Create an
autotoolwith that client. -
Create an
agentthat uses a predefined prompt and theautotool. -
Execute the prompt with your agent.
In pseudocode, this looks like this:
The tedious part, wrapping your SDK functions into well-described functions, is gone.
The parameters of the AgentExecutor:
agentis the agent object you created, using an LLM as well as a prompt.prompt: You can supply your own prompt or use a predefined one. The Langchain prompt hub is an excellent place to find predefined prompts, and Langchain makes them easy to use: just callhub.pull("author/prompt-name").tools: A list of tools to supply.autotool.operationscontains a list of all available functions of your SDK client.handle_parsing_errorsdefines how the agent reacts when a tool can't be invoked correctly because the LLM's answer is not in the expected format, or more generally whenever a runtime error happens after an LLM response. By default, execution is aborted and an exception is raised. Setting this totruesends the error message along with the original task to the LLM again, and the execution is repeated. This is a surprisingly robust way of dealing with such errors. You can also provide your own error handling functions; read more in the Langchain documentation.max_iterationsis the maximum number of iterations the agent may use for the task. One iteration is one LLM call. If you want the LLM to fetch your database user count, the first call will most likely result in a tool call. In the second iteration, you present the result to the agent, which decides whether the task is finished. This task therefore needs 2 iterations.
Specifying the functions to expose to the LLM
SDKs typically provide a lot of functions. Sending all of them to the LLM would probably overload its context window, or at least cause unnecessary costs. Most of the time, we only need two or three functions anyway.
langchain-autotools lets you filter the functions you expose to the LLM
with CrudControls. CrudControls define CRUD verbs, and only functions
that match these verbs are exposed.
Note: At the time of writing, langchain-autotools does not
automatically add ALL methods to the autotool.operations list, only
those with one of these words in their name: get, list, read.
We're not sure whether this is a bug or intentional. Either way, we
suggest always defining the CrudControls manually, as they override
the default behavior.
You can define the following CRUD verbs:
createreadupdatedelete
For example, to expose only the query and queryMany functions and the
drop_database function, you could define:
Note that you need to explicitly enable each CRUD verb you want to use. Providing a list of functions per verb is not enough.
The available parameters of CrudControls are:
read: Enable the read verbread_list: Comma-separated list of function-names to expose to the LLMcreate: Enable the create verbcreate_list: Comma-separated list of function-names to expose to the LLMupdate: Enable the update verbupdate_list: Comma-separated list of function-names to expose to the LLMdelete: Enable the delete verbdelete_list: Comma-separated list of function-names to expose to the LLM
To use the CrudControls, pass them to the AutoToolWrapper:
Example: a langchain-autotools agent for Azure Blob Storage
Now for a real-world example with langchain-autotools. Say I have an Azure Blob Storage account where I keep data needed for some of my customer service requests.
We could build a small customer service LLM agent that fetches documents from the Blob Storage when needed and answers questions using them. The agent therefore needs two capabilities:
- Listing files in our blob storage
- Downloading files and extracting the content
This example also demonstrates one of the limitations of the autotools library. But first things first.
Start by installing the required libraries:
Get the connection string from the Access keys page of your Azure storage account:
Connection string on the Access keys page of an Azure storage account
Load the required dependencies and initialize the Azure Blob Storage client:
Next, define the autotools client and the CRUD controls. You can find the correct function names of the Azure Blob Storage SDK in the documentation.
Then initialize autotools and Langchain as described in the previous section:
Most likely, your agent didn't respond with the correct answer, even though the answer was in one of the blobs. The agent's output shows why:
The download_blob function returns a StorageStreamDownloader, which is
not the content of the blob.
You would need to call download_blob('blobname').readall() to get the
actual text content. That isn't possible with langchain-autotools at the
moment: you can only call top-level functions of the SDK. To work around
this, we create and describe our own function:
The @tool decorator turns the function into a Langchain tool.
We can combine the automatically created autotool functions with our own function like this:
If we run the agent_executor again, we get the correct answer, provided it is in one of the blobs.
langchain-autotools is a quick way to give an agent access to an SDK's
simple, top-level functions. Expect to write a few custom @tool
functions for anything that needs chained calls, like reading a
downloaded blob.
If you want the same API available to any MCP client instead of a single LangChain agent, FastMCP can generate an MCP server from an OpenAPI spec or a FastAPI app.
Further reading
- Extract structured data for LLMs from any website
- Chat with your confluence using LLMs
- How to fine-tune your very own LLM
- Creating an MCP server with FastMCP
- Building AI agents with smolagents
- Building a multi-step AI agent without frameworks
Interested in building high-quality AI agent systems?
We prepared a comprehensive guide based on cutting-edge research for how to build robust, reliable AI agent systems that actually work in production. This guide covers:
- Understanding the 14 systematic failure modes in multi-agent systems
- Evidence-based best practices for agent design
- Structured communication protocols and verification mechanisms



