Ollama supporta la chiamata di strumenti (nota anche come chiamata di funzioni), che permette a un modello di invocare strumenti e incorporare i loro risultati nelle sue risposte.
Chiamare un singolo strumento
Invocare un singolo strumento e includere la sua risposta in una richiesta di follow-up. Nota anche come chiamata di strumenti "single-shot".
cURL
shell
curl -s http://localhost:11434/api/chat -H "Content-Type: application/json" -d '{
"model": "qwen3",
"messages": [{"role": "user", "content": "What is the temperature in New York?"}],
"stream": false,
"tools": [
{
"type": "function",
"function": {
"name": "get_temperature",
"description": "Get the current temperature for a city",
"parameters": {
"type": "object",
"required": ["city"],
"properties": {
"city": {"type": "string", "description": "The name of the city"}
}
}
}
}
]
}'Generare una risposta con un singolo risultato di strumento
shell
curl -s http://localhost:11434/api/chat -H "Content-Type: application/json" -d '{
"model": "qwen3",
"messages": [
{"role": "user", "content": "What is the temperature in New York?"},
{
"role": "assistant",
"tool_calls": [
{
"type": "function",
"function": {
"index": 0,
"name": "get_temperature",
"arguments": {"city": "New York"}
}
}
]
},
{"role": "tool", "tool_name": "get_temperature", "content": "22°C"}
],
"stream": false
}'Python
Installa l'SDK Python di Ollama:
bash
# with pip
pip install ollama -U
# with uv
uv add ollamapython
from ollama import chat
def get_temperature(city: str) -> str:
"""Ottieni la temperatura corrente per una città
Args:
city: Il nome della città
Returns:
La temperatura corrente per la città
"""
temperatures = {
"New York": "22°C",
"London": "15°C",
"Tokyo": "18°C",
}
return temperatures.get(city, "Unknown")
messages = [{"role": "user", "content": "What is the temperature in New York?"}]
# passa le funzioni direttamente come strumenti nella lista degli strumenti o come schema JSON
response = chat(model="qwen3", messages=messages, tools=[get_temperature], think=True)
messages.append(response.message)
if response.message.tool_calls:
# consigliato solo per modelli che restituiscono una sola chiamata di strumento
call = response.message.tool_calls[0]
result = get_temperature(**call.function.arguments)
# aggiungi il risultato dello strumento ai messaggi
messages.append({"role": "tool", "tool_name": call.function.name, "content": str(result)})
final_response = chat(model="qwen3", messages=messages, tools=[get_temperature], think=True)
print(final_response.message.content)JavaScript
Installa la libreria JavaScript di Ollama:
bash
# with npm
npm i ollama
# with bun
bun i ollamatypescript
import ollama from 'ollama'
function getTemperature(city: string): string {
const temperatures: Record<string, string> = {
'New York': '22°C',
'London': '15°C',
'Tokyo': '18°C',
}
return temperatures[city] ?? 'Unknown'
}
const tools = [
{
type: 'function',
function: {
name: 'get_temperature',
description: 'Get the current temperature for a city',
parameters: {
type: 'object',
required: ['city'],
properties: {
city: { type: 'string', description: 'The name of the city' },
},
},
},
},
]
const messages = [{ role: 'user', content: "What is the temperature in New York?" }]
const response = await ollama.chat({
model: 'qwen3',
messages,
tools,
think: true,
})
messages.push(response.message)
if (response.message.tool_calls?.length) {
// consigliato solo per modelli che restituiscono una sola chiamata di strumento
const call = response.message.tool_calls[0]
const args = call.function.arguments as { city: string }
const result = getTemperature(args.city)
// aggiungi il risultato dello strumento ai messaggi
messages.push({ role: 'tool', tool_name: call.function.name, content: result })
// genera la risposta finale
const finalResponse = await ollama.chat({ model: 'qwen3', messages, tools, think: true })
console.log(finalResponse.message.content)
}Chiamata parallela di strumenti
cURL
Esegui più chiamate a strumenti in parallelo, quindi invia tutte le risposte degli strumenti al modello.
```shell
curl -s http://localhost:11434/api/chat -H "Content-Type: application/json" -d '{
"model": "qwen3",
"messages": [{"role": "user", "content": "Quali sono le condizioni meteorologiche e la temperatura correnti a New York e Londra?"}],
"stream": false,
"tools": [
{
"type": "function",
"function": {
"name": "get_temperature",
"description": "Ottieni la temperatura corrente per una città",
"parameters": {
"type": "object",
"required": ["city"],
"properties": {
"city": {"type": "string", "description": "Il nome della città"}
}
}
}
},
{
"type": "function",
"function": {
"name": "get_conditions",
"description": "Ottieni le condizioni meteorologiche correnti per una città",
"parameters": {
"type": "object",
"required": ["city"],
"properties": {
"city": {"type": "string", "description": "Il nome della città"}
}
}
}
}
]
}'
```
**Genera una risposta con più risultati di strumenti**
```shell
curl -s http://localhost:11434/api/chat -H "Content-Type: application/json" -d '{
"model": "qwen3",
"messages": [
{"role": "user", "content": "Quali sono le condizioni meteorologiche e la temperatura correnti a New York e Londra?"},
{
"role": "assistant",
"tool_calls": [
{
"type": "function",
"function": {
"index": 0,
"name": "get_temperature",
"arguments": {"city": "New York"}
}
},
{
"type": "function",
"function": {
"index": 1,
"name": "get_conditions",
"arguments": {"city": "New York"}
}
},
{
"type": "function",
"function": {
"index": 2,
"name": "get_temperature",
"arguments": {"city": "London"}
}
},
{
"type": "function",
"function": {
"index": 3,
"name": "get_conditions",
"arguments": {"city": "London"}
}
}
]
},
{"role": "tool", "tool_name": "get_temperature", "content": "22°C"},
{"role": "tool", "tool_name": "get_conditions", "content": "Parzialmente nuvoloso"},
{"role": "tool", "tool_name": "get_temperature", "content": "15°C"},
{"role": "tool", "tool_name": "get_conditions", "content": "Piovoso"}
],
"stream": false
}'
```
Python
```python
from ollama import chat
def get_temperature(city: str) -> str:
"""Ottieni la temperatura corrente per una città
Args:
city: Il nome della città
Returns:
La temperatura corrente per la città
"""
temperatures = {
"New York": "22°C",
"London": "15°C",
"Tokyo": "18°C"
}
return temperatures.get(city, "Unknown")
def get_conditions(city: str) -> str:
"""Ottieni le condizioni meteorologiche correnti per una città
Args:
city: Il nome della città
Returns:
Le condizioni meteorologiche correnti per la città
"""
conditions = {
"New York": "Parzialmente nuvoloso",
"London": "Piovoso",
"Tokyo": "Soleggiato"
}
return conditions.get(city, "Unknown")
messages = [{'role': 'user', 'content': 'Quali sono le condizioni meteorologiche e la temperatura correnti a New York e Londra?'}]
# Il client Python analizza automaticamente le funzioni come schema di strumento, quindi possiamo passarli direttamente
# Gli schemi possono anche essere passati direttamente nella lista degli strumenti
response = chat(model='qwen3', messages=messages, tools=[get_temperature, get_conditions], think=True)
# aggiungi il messaggio dell'assistente ai messaggi
messages.append(response.message)
if response.message.tool_calls:
# elabora ogni chiamata a strumento
for call in response.message.tool_calls:
# esegui lo strumento appropriato
if call.function.name == 'get_temperature':
result = get_temperature(**call.function.arguments)
elif call.function.name == 'get_conditions':
result = get_conditions(**call.function.arguments)
else:
result = 'Unknown tool'
# aggiungi il risultato dello strumento ai messaggi
messages.append({'role': 'tool', 'tool_name': call.function.name, 'content': str(result)})
# genera la risposta finale
final_response = chat(model='qwen3', messages=messages, tools=[get_temperature, get_conditions], think=True)
print(final_response.message.content)
```
JavaScript
```typescript
import ollama from 'ollama'
function getTemperature(city: string): string {
const temperatures: { [key: string]: string } = {
"New York": "22°C",
"London": "15°C",
"Tokyo": "18°C"
}
return temperatures[city] || "Unknown"
}
function getConditions(city: string): string {
const conditions: { [key: string]: string } = {
"New York": "Parzialmente nuvoloso",
"London": "Piovoso",
"Tokyo": "Soleggiato"
}
return conditions[city] || "Unknown"
}
const tools = [
{
type: 'function',
function: {
name: 'get_temperature',
description: 'Ottieni la temperatura corrente per una città',
parameters: {
type: 'object',
required: ['city'],
properties: {
city: { type: 'string', description: 'Il nome della città' },
},
},
},
},
{
type: 'function',
function: {
name: 'get_conditions',
description: 'Ottieni le condizioni meteorologiche correnti per una città',
parameters: {
type: 'object',
required: ['city'],
properties: {
city: { type: 'string', description: 'Il nome della città' },
},
},
},
}
]
const messages = [{ role: 'user', content: 'Quali sono le condizioni meteorologiche e la temperatura correnti a New York e Londra?' }]
const response = await ollama.chat({
model: 'qwen3',
messages,
tools,
think: true
})
// aggiungi il messaggio dell'assistente ai messaggi
messages.push(response.message)
if (response.message.tool_calls) {
// elabora ogni chiamata a strumento
for (const call of response.message.tool_calls) {
// esegui lo strumento appropriato
let result: string
if (call.function.name === 'get_temperature') {
const args = call.function.arguments as { city: string }
result = getTemperature(args.city)
} else if (call.function.name === 'get_conditions') {
const args = call.function.arguments as { city: string }
result = getConditions(args.city)
} else {
result = 'Unknown tool'
}
// aggiungi il risultato dello strumento ai messaggi
messages.push({ role: 'tool', tool_name: call.function.name, content: result })
}
// genera la risposta finale
const finalResponse = await ollama.chat({ model: 'qwen3', messages, tools, think: true })
console.log(finalResponse.message.content)
}
```
Chiamata di strumenti multi-turno (Ciclo agente)
Un ciclo agente consente al modello di decidere quando invocare gli strumenti e incorporare i loro risultati nelle risposte.
Può anche essere utile indicare al modello che si trova in un ciclo e può effettuare più chiamate a strumenti.
Python
```python
from ollama import chat, ChatResponse
def add(a: int, b: int) -> int:
"""Somma due numeri"""
"""
Args:
a: Il primo numero
b: Il secondo numero
Returns:
La somma dei due numeri
"""
return a + b
def multiply(a: int, b: int) -> int:
"""Moltiplica due numeri"""
"""
Args:
a: Il primo numero
b: Il secondo numero
Returns:
Il prodotto dei due numeri
"""
return a * b
available_functions = {
'add': add,
'multiply': multiply,
}
messages = [{'role': 'user', 'content': 'Quanto fa (11434+12341)*412?'}]
while True:
response: ChatResponse = chat(
model='qwen3',
messages=messages,
tools=[add, multiply],
think=True,
)
messages.append(response.message)
print("Thinking: ", response.message.thinking)
print("Content: ", response.message.content)
if response.message.tool_calls:
for tc in response.message.tool_calls:
if tc.function.name in available_functions:
print(f"Calling {tc.function.name} with arguments {tc.function.arguments}")
result = available_functions[tc.function.name](./**tc.function.arguments)
print(f"Result: {result}")
# aggiungi il risultato dello strumento ai messaggi
messages.append({'role': 'tool', 'tool_name': tc.function.name, 'content': str(result)})
else:
# termina il ciclo quando non ci sono più chiamate a strumenti
break
# continua il ciclo con i messaggi aggiornati
```
JavaScript
```typescript
import ollama from 'ollama'
type ToolName = 'add' | 'multiply'
function add(a: number, b: number): number {
return a + b
}
function multiply(a: number, b: number): number {
return a * b
}
const availableFunctions: Record<ToolName, (a: number, b: number) => number> = {
add,
multiply,
}
const tools = [
{
type: 'function',
function: {
name: 'add',
description: 'Somma due numeri',
parameters: {
type: 'object',
required: ['a', 'b'],
properties: {
a: { type: 'integer', description: 'Il primo numero' },
b: { type: 'integer', description: 'Il secondo numero' },
},
},
},
},
{
type: 'function',
function: {
name: 'multiply',
description: 'Moltiplica due numeri',
parameters: {
type: 'object',
required: ['a', 'b'],
properties: {
a: { type: 'integer', description: 'Il primo numero' },
b: { type: 'integer', description: 'Il secondo numero' },
},
},
},
},
]
async function agentLoop() {
const messages = [{ role: 'user', content: 'Quanto fa (11434+12341)*412?' }]
while (true) {
const response = await ollama.chat({
model: 'qwen3',
messages,
tools,
think: true,
})
messages.push(response.message)
console.log('Thinking:', response.message.thinking)
console.log('Content:', response.message.content)
const toolCalls = response.message.tool_calls ?? []
if (toolCalls.length) {
for (const call of toolCalls) {
const fn = availableFunctions[call.function.name as ToolName]
if (!fn) {
continue
}
const args = call.function.arguments as { a: number; b: number }
console.log(`Calling ${call.function.name} with arguments`, args)
const result = fn(args.a, args.b)
console.log(`Result: ${result}`)
messages.push({ role: 'tool', tool_name: call.function.name, content: String(result) })
}
} else {
break
}
}
}
agentLoop().catch(console.error)
```
Chiamata di strumenti con streaming
Quando si utilizza lo streaming, raccogli ogni frammento di thinking, content e tool_calls, quindi restituisci questi campi insieme a eventuali risultati degli strumenti nella richiesta di follow-up.
Python
python
from ollama import chat
def get_temperature(city: str) -> str:
"""Ottieni la temperatura corrente per una città
Args:
city: Il nome della città
Returns:
La temperatura corrente per la città
"""
temperatures = {
'New York': '22°C',
'London': '15°C',
}
return temperatures.get(city, 'Unknown')
messages = [{'role': 'user', 'content': "What is the temperature in New York?"}]
while True:
stream = chat(
model='qwen3',
messages=messages,
tools=[get_temperature],
stream=True,
think=True,
)
thinking = ''
content = ''
tool_calls = []
done_thinking = False
# accumula i campi parziali
for chunk in stream:
if chunk.message.thinking:
thinking += chunk.message.thinking
print(chunk.message.thinking, end='', flush=True)
if chunk.message.content:
if not done_thinking:
done_thinking = True
print('\n')
content += chunk.message.content
print(chunk.message.content, end='', flush=True)
if chunk.message.tool_calls:
tool_calls.extend(chunk.message.tool_calls)
print(chunk.message.tool_calls)
# aggiungi i campi accumulati ai messaggi
if thinking or content or tool_calls:
messages.append({'role': 'assistant', 'thinking': thinking, 'content': content, 'tool_calls': tool_calls})
if not tool_calls:
break
for call in tool_calls:
if call.function.name == 'get_temperature':
result = get_temperature(**call.function.arguments)
else:
result = 'Unknown tool'
messages.append({'role': 'tool', 'tool_name': call.function.name, 'content': result})JavaScript
typescript
function getTemperature(city: string): string {
const temperatures: Record<string, string> = {
'New York': '22°C',
'London': '15°C',
}
return temperatures[city] ?? 'Unknown'
}
const getTemperatureTool = {
type: 'function',
function: {
name: 'get_temperature',
description: 'Ottieni la temperatura corrente per una città',
parameters: {
type: 'object',
required: ['city'],
properties: {
city: { type: 'string', description: 'Il nome della città' },
},
},
},
}
async function agentLoop() {
const messages = [{ role: 'user', content: "What is the temperature in New York?" }]
while (true) {
const stream = await ollama.chat({
model: 'qwen3',
messages,
tools: [getTemperatureTool],
stream: true,
think: true,
})
let thinking = ''
let content = ''
const toolCalls: any[] = []
let doneThinking = false
for await (const chunk of stream) {
if (chunk.message.thinking) {
thinking += chunk.message.thinking
process.stdout.write(chunk.message.thinking)
}
if (chunk.message.content) {
if (!doneThinking) {
doneThinking = true
process.stdout.write('\n')
}
content += chunk.message.content
process.stdout.write(chunk.message.content)
}
if (chunk.message.tool_calls?.length) {
toolCalls.push(...chunk.message.tool_calls)
console.log(chunk.message.tool_calls)
}
}
if (thinking || content || toolCalls.length) {
messages.push({ role: 'assistant', thinking, content, tool_calls: toolCalls } as any)
}
if (!toolCalls.length) {
break
}
for (const call of toolCalls) {
if (call.function.name === 'get_temperature') {
const args = call.function.arguments as { city: string }
const result = getTemperature(args.city)
messages.push({ role: 'tool', tool_name: call.function.name, content: result } )
} else {
messages.push({ role: 'tool', tool_name: call.function.name, content: 'Unknown tool' } )
}
}
}
}
agentLoop().catch(console.error)
```
Questo ciclo effettua lo streaming della risposta dell'assistente, accumula i campi parziali, li restituisce insieme e aggiunge i risultati degli strumenti per consentire al modello di completare la risposta.
## Utilizzo di funzioni come strumenti con l'SDK Python di Ollama
L'SDK Python analizza automaticamente le funzioni come schema di strumento, quindi è possibile passarli direttamente. È comunque possibile passare schemi manualmente se necessario.
```python
from ollama import chat
def get_temperature(city: str) -> str:
"""Ottieni la temperatura corrente per una città
Args:
city: Il nome della città
Returns:
La temperatura corrente per la città
"""
temperatures = {
'New York': '22°C',
'London': '15°C',
}
return temperatures.get(city, 'Unknown')
available_functions = {
'get_temperature': get_temperature,
}
# passa direttamente la funzione come parte della lista di strumenti
response = chat(model='qwen3', messages=messages, tools=available_functions.values(), think=True)