Local Function Calling
Let a local model request function calls with a tools schema, then run them and return the results.
TL;DR
- Send a
toolsschema array in the chat request. - The model returns
tool_calls, not plain text output. - Your app runs the function and feeds the result to
/api/chat.
Define Tools
tools arrayDescribe callable functions as a tools array.
"tools": [ { "type": "function", ... } ]Function SchemaGive each tool a name and description.
{ "name": "get_weather",
"description": "Get weather" }Parameter TypesDefine argument names and JSON types.
"properties": {"city": {"type":"string"}}Make The Call
Pass toolsSend the tools array to /api/chat.
# body: { model, messages, tools }tool_callsThe reply contains tool calls, not text.
# message.tool_calls[0].function.nameArgumentsEach call carries parsed argument values.
# function.arguments -> {"city":"Oslo"}Run And Return
Execute LocallyYour app runs the named function itself.
# result = get_weather(city="Oslo")role toolSend the result back as a tool message.
{ "role": "tool", "content": "12C" }Final AnswerThe model turns the result into a reply.
# Second call yields natural-language textPython With ollama
Define A FunctionPass Python functions directly as tools.
def get_weather(city: str) -> str: ...Pass toolsThe client builds the schema from functions.
ollama.chat(model="llama3.1",
messages=msgs, tools=[get_weather])Read tool_callsInspect which tool the model chose.
resp.message.tool_callsTips
- Use a tool-capable model like
llama3.1for function calling, since smaller or older models may ignore thetoolsarray. - Describe each tool and its parameters clearly in the schema, because the model picks tools from your descriptions and types.
Warnings
- The model only names a function and arguments; your code must run it, then send the output back as a
toolmessage. - Always validate
tool_callsarguments before executing, since a model can hallucinate values or call a tool you did not expect.
In Practice
Send a tools array, read the model's tool_calls, then run the function to produce the answer.
get_weatheris a plain function the client turns into a tool schema.tools=[...]tells the model it may call that function.- The model replies with
tool_callsnaming the function and args. - Your app runs it, then sends the result back for a final reply.
import ollama
def get_weather(city: str) -> str:
return "12C and clear"
msgs = [{"role": "user",
"content": "Weather in Oslo?"}]
resp = ollama.chat(
model="llama3.1",
messages=msgs,
tools=[get_weather],
)
print(resp.message.tool_calls)FAQ
You send a tools schema with the chat request. Instead of text, the model replies with tool_calls naming a function and its arguments. Your app runs the function, then sends the result back for a final answer.
Tool-capable models like llama3.1 and qwen2.5 support it. Older or very small models may ignore the tools array entirely, so check the model's capabilities before relying on it.
No. Ollama only returns the model's chosen function name and arguments in tool_calls. Running the function is your application's job, which keeps execution and secrets under your control.
Append a message with "role": "tool" and the function's output as content, then call /api/chat again with the full history. The model uses the result to write its final reply.