How to disable parallel tool calling
This guide assumes familiarity with the following concepts:
This API is currently only supported by OpenAI.
OpenAI models perform tool calling in parallel by default. That means
that if we ask a question like
"What is the weather in Tokyo, New York, and Chicago?"
and we have a
tool for getting the weather, it will call the tool 3 times in parallel.
We can force it to call only a single tool once by using the
parallel_tool_call
call option.
First letβs set up our tools and model:
import { ChatOpenAI } from "@langchain/openai";
import { z } from "zod";
import { tool } from "@langchain/core/tools";
const adderTool = tool(
async ({ a, b }) => {
return a + b;
},
{
name: "add",
description: "Adds a and b",
schema: z.object({
a: z.number(),
b: z.number(),
}),
}
);
const multiplyTool = tool(
async ({ a, b }) => {
return a + b;
},
{
name: "multiply",
description: "Multiplies a and b",
schema: z.object({
a: z.number(),
b: z.number(),
}),
}
);
const tools = [adderTool, multiplyTool];
const llm = new ChatOpenAI({
model: "gpt-4o-mini",
temperature: 0,
});
Now letβs show a quick example of how disabling parallel tool calls work:
const llmWithTools = llm.bindTools(tools, { parallel_tool_calls: false });
const result = await llmWithTools.invoke(
"Please call the first tool two times"
);
result.tool_calls;
[
{
name: 'add',
args: { a: 5, b: 3 },
type: 'tool_call',
id: 'call_5bKOYerdQU6J5ERJJYnzYsGn'
}
]
As we can see, even though we explicitly told the model to call a tool twice, by disabling parallel tool calls the model was constrained to only calling one.
Compare this to calling the model without passing parallel_tool_calls
as false:
const llmWithNoBoundParam = llm.bindTools(tools);
const result2 = await llmWithNoBoundParam.invoke(
"Please call the first tool two times"
);
result2.tool_calls;
[
{
name: 'add',
args: { a: 1, b: 2 },
type: 'tool_call',
id: 'call_Ni0tF0nNtY66BBwB5vEP6oI4'
},
{
name: 'add',
args: { a: 3, b: 4 },
type: 'tool_call',
id: 'call_XucnTCfFqP1JBs3LtbOq5w3d'
}
]
You can see that you get two tool calls.
You can also pass the parameter in at runtime like this:
const result3 = await llmWithNoBoundParam.invoke(
"Please call the first tool two times",
{
parallel_tool_calls: false,
}
);
result3.tool_calls;
[
{
name: 'add',
args: { a: 1, b: 2 },
type: 'tool_call',
id: 'call_TWo6auul71NUg1p0suzBKARt'
}
]