Ollama поддерживает вызов инструментов (также известный как вызов функций), который позволяет модели вызывать инструменты и включать их результаты в свои ответы.
Вызов одного инструмента
Вызовите один инструмент и включите его ответ в последующий запрос.
Также известен как «одноразовый» вызов инструментов.
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"}
}
}
}
}
]
}'
```
**Сгенерировать ответ с результатом одного инструмента**
```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
Установите Python SDK для Ollama:
```bash
# с помощью pip
pip install ollama -U
# с помощью uv
uv add ollama
```
```python
from ollama import chat
def get_temperature(city: str) -> str:
"""Получить текущую температуру для города
Аргументы:
city: Название города
Возвращает:
Текущую температуру для города
"""
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?"}]
# передавать функции напрямую в список инструментов tools или в виде JSON-схемы
response = chat(model="qwen3", messages=messages, tools=[get_temperature], think=True)
messages.append(response.message)
if response.message.tool_calls:
# рекомендуется только для моделей, которые возвращают единственный вызов инструмента
call = response.message.tool_calls[0]
result = get_temperature(**call.function.arguments)
# добавить результат вызова инструмента в сообщения
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
Установите JavaScript-библиотеку для Ollama:
```bash
# с помощью npm
npm i ollama
# с помощью bun
bun i ollama
```
```typescript
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) {
// рекомендуется только для моделей, которые возвращают единственный вызов инструмента
const call = response.message.tool_calls[0]
const args = call.function.arguments as { city: string }
const result = getTemperature(args.city)
// добавить результат вызова инструмента в сообщения
messages.push({ role: 'tool', tool_name: call.function.name, content: result })
// сгенерировать итоговый ответ
const finalResponse = await ollama.chat({ model: 'qwen3', messages, tools, think: true })
console.log(finalResponse.message.content)
}
```
Параллельный вызов инструментов
cURL
Выполните несколько вызовов инструментов параллельно, затем отправьте все ответы от инструментов обратно модели.
shell
curl -s http://localhost:11434/api/chat -H "Content-Type: application/json" -d '{
"model": "qwen3",
"messages": [{"role": "user", "content": "What are the current weather conditions and temperature in New York and London?"}],
"stream": false,
"tools": [
{
"type": "function",
"function": {
"name": "get_temperature",
"description": "Получить текущую температуру для города",
"parameters": {
"type": "object",
"required": ["city"],
"properties": {
"city": {"type": "string", "description": "The name of the city"}
}
}
}
},
{
"type": "function",
"function": {
"name": "get_conditions",
"description": "Получить текущие погодные условия для города",
"parameters": {
"type": "object",
"required": ["city"],
"properties": {
"city": {"type": "string", "description": "The name of the city"}
}
}
}
}
]
}'Сгенерировать ответ с результатами нескольких инструментов
shell
curl -s http://localhost:11434/api/chat -H "Content-Type: application/json" -d '{
"model": "qwen3",
"messages": [
{"role": "user", "content": "What are the current weather conditions and temperature in New York and London?"},
{
"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": "Partly cloudy"},
{"role": "tool", "tool_name": "get_temperature", "content": "15°C"},
{"role": "tool", "tool_name": "get_conditions", "content": "Rainy"}
],
"stream": false
}'Python
python
from ollama import chat
def get_temperature(city: str) -> str:
"""Получить текущую температуру для города
Args:
city: Название города
Returns:
Текущая температура для города
"""
temperatures = {
"New York": "22°C",
"London": "15°C",
"Tokyo": "18°C"
}
return temperatures.get(city, "Unknown")
def get_conditions(city: str) -> str:
"""Получить текущие погодные условия для города
Args:
city: Название города
Returns:
Текущие погодные условия для города
"""
conditions = {
"New York": "Partly cloudy",
"London": "Rainy",
"Tokyo": "Sunny"
}
return conditions.get(city, "Unknown")
messages = [{'role': 'user', 'content': 'What are the current weather conditions and temperature in New York and London?'}]
# Клиент Python автоматически преобразует функции в схему инструмента, поэтому мы можем передавать их напрямую
# Схемы также можно передавать напрямую в списке tools
response = chat(model='qwen3', messages=messages, tools=[get_temperature, get_conditions], think=True)
# добавить сообщение ассистента в сообщения
messages.append(response.message)
if response.message.tool_calls:
# обработать каждый вызов инструмента
for call in response.message.tool_calls:
# выполнить соответствующий инструмент
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'
# добавить результат инструмента в сообщения
messages.append({'role': 'tool', 'tool_name': call.function.name, 'content': str(result)})
# сгенерировать итоговый ответ
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": "Partly cloudy",
"London": "Rainy",
"Tokyo": "Sunny"
}
return conditions[city] || "Unknown"
}
const tools = [
{
type: 'function',
function: {
name: 'get_temperature',
description: 'Получить текущую температуру для города',
parameters: {
type: 'object',
required: ['city'],
properties: {
city: { type: 'string', description: 'The name of the city' },
},
},
},
},
{
type: 'function',
function: {
name: 'get_conditions',
description: 'Получить текущие погодные условия для города',
parameters: {
type: 'object',
required: ['city'],
properties: {
city: { type: 'string', description: 'The name of the city' },
},
},
},
}
]
const messages = [{ role: 'user', content: 'What are the current weather conditions and temperature in New York and London?' }]
const response = await ollama.chat({
model: 'qwen3',
messages,
tools,
think: true
})
// добавить сообщение ассистента в список сообщений
messages.push(response.message)
if (response.message.tool_calls) {
// обработать каждый вызов инструмента
for (const call of response.message.tool_calls) {
// выполнить соответствующий инструмент
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'
}
// добавить результат инструмента в сообщения
messages.push({ role: 'tool', tool_name: call.function.name, content: result })
}
// сгенерировать итоговый ответ
const finalResponse = await ollama.chat({ model: 'qwen3', messages, tools, think: true })
console.log(finalResponse.message.content)
}Многоходовый вызов инструментов (Цикл агента)
Цикл агента позволяет модели самостоятельно решать, когда вызывать инструменты и включать их результаты в свои ответы.
Также может быть полезно сообщить модели, что она находится в цикле и может выполнять несколько вызовов инструментов.
Python
python
from ollama import chat, ChatResponse
def add(a: int, b: int) -> int:
"""Сложить два числа"""
"""
Args:
a: Первое число
b: Второе число
Returns:
Сумма двух чисел
"""
return a + b
def multiply(a: int, b: int) -> int:
"""Умножить два числа"""
"""
Args:
a: Первое число
b: Второе число
Returns:
Произведение двух чисел
"""
return a * b
available_functions = {
'add': add,
'multiply': multiply,
}
messages = [{'role': 'user', 'content': 'What is (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}")
# добавить результат инструмента в сообщения
messages.append({'role': 'tool', 'tool_name': tc.function.name, 'content': str(result)})
else:
# завершить цикл, когда больше нет вызовов инструментов
break
# продолжить цикл с обновленными сообщениями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: 'Сложить два числа',
parameters: {
type: 'object',
required: ['a', 'b'],
properties: {
a: { type: 'integer', description: 'Первое число' },
b: { type: 'integer', description: 'Второе число' },
},
},
},
},
{
type: 'function',
function: {
name: 'multiply',
description: 'Умножить два числа',
parameters: {
type: 'object',
required: ['a', 'b'],
properties: {
a: { type: 'integer', description: 'Первое число' },
b: { type: 'integer', description: 'Второе число' },
},
},
},
},
]
async function agentLoop() {
const messages = [{ role: 'user', content: 'What is (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)Вызов инструментов с потоковой передачей
При потоковой передаче собирайте каждый фрагмент полей thinking, content и tool_calls, а затем возвращайте эти поля вместе с результатами работы любых инструментов в последующем запросе.
Python
python
from ollama import chat
def get_temperature(city: str) -> str:
"""Получить текущую температуру для указанного города
Args:
city: Название города
Returns:
Текущая температура для указанного города
"""
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
# накапливайте частичные поля
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)
# добавьте накопленные поля в список сообщений
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: 'Получить текущую температуру для указанного города',
parameters: {
type: 'object',
required: ['city'],
properties: {
city: { type: 'string', description: 'Название города' },
},
},
},
}
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)
```
Этот цикл потоково передаёт ответ ассистента, накапливает частичные поля, передаёт их обратно вместе и добавляет результаты работы инструментов, чтобы модель могла завершить свой ответ.
## Использование функций в качестве инструментов с помощью Ollama Python SDK
Python SDK автоматически преобразует функции в схему инструмента, поэтому их можно передавать напрямую. При необходимости схемы можно передавать и вручную.
```python
from ollama import chat
def get_temperature(city: str) -> str:
"""Получить текущую температуру для указанного города
Args:
city: Название города
Returns:
Текущая температура для указанного города
"""
temperatures = {
'New York': '22°C',
'London': '15°C',
}
return temperatures.get(city, 'Unknown')
available_functions = {
'get_temperature': get_temperature,
}
# передавайте функцию напрямую как часть списка инструментов
response = chat(model='qwen3', messages=messages, tools=available_functions.values(), think=True)