Build a local tool-calling assistant
Give Qwen3 a single safe function, inspect its tool request, return a result, and confirm the final answer stays in a local Ollama session.
Before you begin
- Difficulty
- Intermediate
- Software
- Ollama, Python
- Hardware
- The Qwen3 8B Ollama package is 5.2 GB. Allow additional memory for the runtime, tool schema, and conversation history.
Sources and files
Official Qwen3 8B package Official single-tool request and response exampleChoose a model for this task
The steps below use the recommended model. Alternatives have their own package and command; open their model pages before switching.
The workflow
Install Ollama and Qwen3
Start Ollama on your machine and download the publisher-listed 8B package. The tool calls below use the qwen3 model family.
ollama run qwen3:8bInstall the local Python client
Create a Python environment for your small tool runner and install the official Ollama client.
pip install ollama -UDefine one bounded function
Create a function that reads a small, explicit local lookup table, such as the sample city-to-temperature dictionary in the official guide. Avoid shell execution or arbitrary file access in the first version.
Send a request with that tool
Save this source-derived example as tool_agent.py, then run python tool_agent.py. It keeps the allowed function in your own process and checks the requested name before calling it.
from ollama import chat
def get_temperature(city: str) -> str:
return {"New York": "22°C", "London": "15°C"}.get(city, "Unknown")
messages = [{"role": "user", "content": "What is the temperature in New York?"}]
response = chat(model="qwen3:8b", messages=messages, tools=[get_temperature], think=True)
messages.append(response.message)
if not response.message.tool_calls:
raise RuntimeError("No tool call returned")
call = response.message.tool_calls[0]
if call.function.name != "get_temperature":
raise ValueError("Unapproved tool name")
result = get_temperature(**call.function.arguments)
messages.append({"role": "tool", "tool_name": "get_temperature", "content": result})
print(chat(model="qwen3:8b", messages=messages, tools=[get_temperature], think=True).message.content)Inspect and execute the requested call
Read response.message.tool_calls, check the function name and arguments against your allowlist, run your one function, then append its result as a role="tool" message. Do not execute an unrecognized tool name.
Ask for a final response and verify
Call chat again with the original messages, assistant tool call, and tool result. Confirm the final answer includes the value from your lookup table and that no network or shell tool was granted.
When it doesn’t go to plan
Check the tools argument and function signature, then ask a question that explicitly needs your lookup value. The official guide includes a complete single-tool example.
Append both the assistant tool-call message and the role="tool" result before the second chat call, matching the official message sequence.
The model behind this workflow
Qwen3 8BWill it run on your machine?
Save your machine to see a personalized rating and its reasoning.
Add my hardwareKeep exploring
Set up a private AI chat assistant
Install a local runtime, run Qwen3.5 9B, confirm responses, and know when to choose the smaller 4B package.
Build a private local coding assistant
Connect an open coding-capable model in Ollama to Cline, run a small repository task, and review the result locally.
Generate images on your own GPU
Use the official FLUX.2 Klein 4B ComfyUI template with exact model files, a first prompt, and an output check.