Skip to content

O Ollama oferece suporte a chamada de ferramentas (também conhecida como chamada de funções), que permite que um modelo invoque ferramentas e incorpore seus resultados em suas respostas.

Chamando uma única ferramenta

Invoque uma única ferramenta e inclua sua resposta em uma solicitação de acompanhamento. Também conhecida como chamada de ferramentas "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"}
          }
        }
      }
    }
  ]
}'
```

**Gerar uma resposta com um único resultado de ferramenta**
```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

Instale o SDK Python do Ollama:
```bash
# com pip
pip install ollama -U

# com uv
uv add ollama
```

```python
from ollama import chat

def get_temperature(city: str) -> str:
  """Obtenha a temperatura atual de uma cidade

  Argumentos:
    city: O nome da cidade

  Retornos:
    A temperatura atual da cidade
  """
  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?"}]

# passe funções diretamente como ferramentas na lista de ferramentas ou como um esquema JSON
response = chat(model="qwen3", messages=messages, tools=[get_temperature], think=True)

messages.append(response.message)
if response.message.tool_calls:
  # recomendado apenas para modelos que retornam apenas uma única chamada de ferramenta
  call = response.message.tool_calls[0]
  result = get_temperature(**call.function.arguments)
  # adicione o resultado da ferramenta às mensagens
  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

Instale a biblioteca JavaScript do Ollama:
```bash
# com npm
npm i ollama

# com 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) {
  // recomendado apenas para modelos que retornam apenas uma única chamada de ferramenta
  const call = response.message.tool_calls[0]
  const args = call.function.arguments as { city: string }
  const result = getTemperature(args.city)
  // adicione o resultado da ferramenta às mensagens
  messages.push({ role: 'tool', tool_name: call.function.name, content: result })

  // gere a resposta final
  const finalResponse = await ollama.chat({ model: 'qwen3', messages, tools, think: true })
  console.log(finalResponse.message.content)
}
```

Wait wait, the original has two newlines at the end? Let's check the user's input: the user's input ends with "```" followed by two newlines? Let's see: the user's input ends with:

  console.log(finalResponse.message.content)
}


Yes, so the translated one ends with the same, which it does.

Wait another check: all code blocks are preserved exactly in structure, only comments and docstrings are translated, all prose outside code is translated, frontmatter is correct, no extra content, all technical identifiers are kept, no URLs to worry about. That's all correct.

## Chamada paralela de ferramentas

### cURL

  Faça múltiplas chamadas de ferramentas em paralelo, depois envie todas as respostas das ferramentas de volta para o modelo.

  ```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": "Get the current temperature for a city",
          "parameters": {
            "type": "object",
            "required": ["city"],
            "properties": {
              "city": {"type": "string", "description": "The name of the city"}
            }
          }
        }
      },
      {
        "type": "function",
        "function": {
          "name": "get_conditions",
          "description": "Get the current weather conditions for a city",
          "parameters": {
            "type": "object",
            "required": ["city"],
            "properties": {
              "city": {"type": "string", "description": "The name of the city"}
            }
          }
        }
      }
    ]
  }'
  ```

  **Gerar uma resposta com múltiplos resultados de ferramentas**
  ```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:
    """Obter a temperatura atual de uma cidade

    Args:
      cidade: O nome da cidade

    Returns:
      A temperatura atual da cidade
    """
    temperatures = {
      "New York": "22°C",
      "London": "15°C",
      "Tokyo": "18°C"
    }
    return temperatures.get(city, "Unknown")

  def get_conditions(city: str) -> str:
    """Obter as condições climáticas atuais de uma cidade

    Args:
      cidade: O nome da cidade

    Returns:
      As condições climáticas atuais da cidade
    """
    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?'}]

  # O cliente Python analisa automaticamente as funções como um esquema de ferramenta, então podemos passá-las diretamente
  # Esquemas também podem ser passados diretamente na lista de ferramentas
  response = chat(model='qwen3', messages=messages, tools=[get_temperature, get_conditions], think=True)

  # adicionar a mensagem do assistente às mensagens
  messages.append(response.message)
  if response.message.tool_calls:
    # processar cada chamada de ferramenta
    for call in response.message.tool_calls:
      # executar a ferramenta apropriada
      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'
      # adicionar o resultado da ferramenta às mensagens
      messages.append({'role': 'tool',  'tool_name': call.function.name, 'content': str(result)})

    # gerar a resposta final
    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: 'Get the current temperature for a city',
        parameters: {
          type: 'object',
          required: ['city'],
          properties: {
            city: { type: 'string', description: 'The name of the city' },
          },
        },
      },
    },
    {
      type: 'function',
      function: {
        name: 'get_conditions',
        description: 'Get the current weather conditions for a city',
        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
  })

  // adicionar a mensagem do assistente às mensagens
  messages.push(response.message)
  if (response.message.tool_calls) {
    // processar cada chamada de ferramenta
    for (const call of response.message.tool_calls) {
      // executar a ferramenta apropriada
      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'
      }
      // adicionar o resultado da ferramenta às mensagens
      messages.push({ role: 'tool', tool_name: call.function.name, content: result })
    }

    // gerar a resposta final
    const finalResponse = await ollama.chat({ model: 'qwen3', messages, tools, think: true })
    console.log(finalResponse.message.content)
  }
  ```




## Chamada de ferramentas multissetorial (Loop de agente)

Um loop de agente permite que o modelo decida quando invocar ferramentas e incorporar seus resultados nas suas respostas.
Também pode ser útil informar ao modelo que ele está em um loop e pode fazer múltiplas chamadas de ferramentas.


### Python

  ```python
  from ollama import chat, ChatResponse


  def add(a: int, b: int) -> int:
    """Adicionar dois números"""
    """
    Args:
      a: O primeiro número
      b: O segundo número

    Returns:
      A soma dos dois números
    """
    return a + b


  def multiply(a: int, b: int) -> int:
    """Multiplicar dois números"""
    """
    Args:
      a: O primeiro número
      b: O segundo número

    Returns:
      O produto dos dois números
    """
    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}")
                  # adicionar o resultado da ferramenta às mensagens
                  messages.append({'role': 'tool', 'tool_name': tc.function.name, 'content': str(result)})
      else:
          # encerrar o loop quando não houver mais chamadas de ferramenta
          break
    # continuar o loop com as mensagens atualizadas
  ```

### 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&lt;ToolName, (a: number, b: number) =&gt; number&gt; = {
    add,
    multiply,
  }

  const tools = [
    {
      type: 'function',
      function: {
        name: 'add',
        description: 'Add two numbers',
        parameters: {
          type: 'object',
          required: ['a', 'b'],
          properties: {
            a: { type: 'integer', description: 'The first number' },
            b: { type: 'integer', description: 'The second number' },
          },
        },
      },
    },
    {
      type: 'function',
      function: {
        name: 'multiply',
        description: 'Multiply two numbers',
        parameters: {
          type: 'object',
          required: ['a', 'b'],
          properties: {
            a: { type: 'integer', description: 'The first number' },
            b: { type: 'integer', description: 'The second number' },
          },
        },
      },
    },
  ]

  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)
  ```

## Chamada de ferramentas com streaming

Ao usar streaming, reúna cada fragmento de `thinking`, `content` e `tool_calls`, depois retorne esses campos juntamente com quaisquer resultados de ferramentas na solicitação subsequente.

### Python

```python
from ollama import chat


def get_temperature(city: str) -> str:
"""Get the current temperature for a city

Args:
  city: The name of the city

Returns:
  The current temperature for the city
"""
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
# accumulate the partial fields
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)

# append accumulated fields to the messages
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&lt;string, string&gt; = {
    'New York': '22°C',
    'London': '15°C',
  }
  return temperatures[city] ?? 'Unknown'
}

const getTemperatureTool = {
  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' },
      },
    },
  },
}

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)

Este loop transmite a resposta do assistente por streaming, acumula campos parciais, os envia de volta juntos e anexa os resultados das ferramentas para que o modelo possa concluir sua resposta.

Usando funções como ferramentas com o SDK Python do Ollama

O SDK Python analisa funções automaticamente como um esquema de ferramenta, permitindo que as passemos diretamente. Esquemas ainda podem ser passados se necessário.

python
from ollama import chat

def get_temperature(city: str) -> str:
  """Get the current temperature for a city

  Args:
    city: The name of the city

  Returns:
    The current temperature for the city
  """
  temperatures = {
    'New York': '22°C',
    'London': '15°C',
  }
  return temperatures.get(city, 'Unknown')

available_functions = {
  'get_temperature': get_temperature,
}
# directly pass the function as part of the tools list
response = chat(model='qwen3', messages=messages, tools=available_functions.values(), think=True)