Ollama 工具调用完全指南:Python/JS 实现单次、并行及流式函数调用

AI
本文详解 Ollama 工具调用功能,涵盖单次、并行、多轮智能体循环及流式传输场景。提供 cURL、Python 和 JavaScript 代码示例,演示如何使用 Ollama SDK 实现函数调用,帮助模型获取外部数据并生成准确结果,适合开发者快速上手。

工具调用指的是 AI 模型在处理用户问题或执行任务的过程中,主动调用外部工具、接口、插件或第三方功能来获取信息、完成计算、执行操作并辅助生成更准确、更实用结果的一种能力。

简单来说,当 AI 自身无法直接给出答案,或需要借助外部数据、功能才能更好地完成任务时,就会通过工具调用的方式与外部系统交互。

注意,Ollama 也支持工具调用(也称为函数调用),这使得模型能够调用工具并将其结果整合到自己的回复中。

调用单个工具

指调用单个工具来执行相应操作,并且在后续发起的请求中携带工具返回的响应内容。这种执行方式被称作 “单次” 工具调用,其核心特点是仅触发一次工具交互,不进行连续或多次的工具调用操作。

cURL

下面命令适合 Linux 运行,直接在 Windows 上运行会失败。

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"}
          }
        }
      }
    }
  ]
}'

Python

安装 ollama 依赖,如果用的 pip,则运行 pip install ollama -U;如果使用 uv,则运行 uv add ollama。示例代码如下:

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",
        "Tokyo": "18°C",
    }
    return temperatures.get(city, "Unknown")

messages = [{"role": "user", "content": "What is the temperature in New York?"}]

# 将函数直接作为工具传入工具列表中,或是以JSON模式的形式传入
response = chat(model="qwen3:8b", messages=messages, tools=[get_temperature], think=True)
print(f"模型回复: {response}")

messages.append(response.message)
if response.message.tool_calls:
    # 根据模型响应调用工具
    call = response.message.tool_calls[0]
    result = get_temperature(**call.function.arguments)
    print(f"工具调用结果: {result}")
    
    # 将工具执行结果添加至消息列表中
    messages.append({"role": "tool", "tool_name": call.function.name, "content": str(result)})

    final_response = chat(model="qwen3:8b", messages=messages, tools=[get_temperature], think=True)
    print(f"最终回复: {final_response}")

运行结果:

$ python .\ollama_example11.py

模型回复: model='qwen3:8b' created_at='2026-04-09T05:30:41.7314715Z' done=True done_reason='stop' 
  total_duration=21277626500 load_duration=102722400 prompt_eval_count=147 prompt_eval_duration=221103600 
  eval_count=92 eval_duration=20913381900 message=Message(role='assistant', content='', 
  thinking='Okay, the user is asking for the temperature in New York...the XML tags.\n', 
  images=None, tool_name=None, 
  tool_calls=[ToolCall(function=Function(name='get_temperature', arguments={'city': 'New York'}))]) logprobs=None 

工具调用结果: 22°C

最终回复: model='qwen3:8b' created_at='2026-04-09T05:31:32.399058Z' done=True done_reason='stop' 
  total_duration=50663135600 load_duration=198630000 prompt_eval_count=253 prompt_eval_duration=17237567400 eval_count=110 
  eval_duration=33135037900 message=Message(role='assistant', 
  content='The current temperature in New York is 22°C.', 
  thinking='Okay, the user asked for the temperature in New York... informative way.\n',
  images=None, tool_name=None, tool_calls=None) logprobs=None

JavaScript

安装 Ollama JavaScript 库:

# 使用 npm
npm i ollama

# 使用 bun
bun i ollama

示例代码:

import ollama from 'ollama'

function getTemperature(city) {
    const temperatures = {
        '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?" }]

// 调用chat函数,传入模型、消息列表和工具列表
const response = await ollama.chat({
    model: 'qwen3:8b',
    messages,
    tools,
    think: true,
})
console.log("初始响应:", response)

messages.push(response.message)
if (response.message.tool_calls?.length) {
    // 根据工具调用信息执行相应的工具,并将结果添加到消息列表中
    const call = response.message.tool_calls[0]
    const args = call.function.arguments
    const result = getTemperature(args.city)
    console.log("工具执行结果:", result)

    // 将工具执行结果添加到消息列表中
    messages.push({ role: 'tool', tool_name: call.function.name, content: result })

    // 生成最终响应
    const finalResponse = await ollama.chat({ model: 'qwen3:8b', messages, tools, think: true })
    console.log("最终消息:", finalResponse)
}

运行结果:

$ node .\ollama_example11.js

初始响应: {
  model: 'qwen3:8b',
  created_at: '2026-04-09T05:45:11.1702265Z',
  message: {
    role: 'assistant',
    content: '',
    thinking: `Okay, the user is asking for the temperature in New York...JSON within the tool_call tags.\n`,
    tool_calls: [ [Object] ]
  },
  done: true,
  done_reason: 'stop',
  total_duration: 35531389500,
  load_duration: 2715340100,
  prompt_eval_count: 147,
  prompt_eval_duration: 14441761400,
  eval_count: 91,
  eval_duration: 18293857100
}
工具执行结果: 22°C
最终消息: {
  model: 'qwen3:8b',
  created_at: '2026-04-09T05:45:45.0500353Z',
  message: {
    role: 'assistant',
    content: 'The current temperature in New York is **22°C**.',
    thinking: `Okay, the user asked for the temperature in New York.... again to confirm it's accurate.\n`
  },
  done: true,
  done_reason: 'stop',
  total_duration: 33857016600,
  load_duration: 195576500,
  prompt_eval_count: 252,
  prompt_eval_duration: 11162045700,
  eval_count: 107,
  eval_duration: 22481463400
}

并行工具调用

cURL

并行请求多个工具调用,然后将所有工具响应发送回模型。例如:

curl -s http://localhost:11434/api/chat -H "Content-Type: application/json" -d '{
  "model": "qwen3:8b",
  "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"}
          }
        }
      }
    }
  ]
}'

生成包含多个工具结果的响应

curl -s http://localhost:11434/api/chat -H "Content-Type: application/json" -d '{
  "model": "qwen3:8b",
  "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
from pprint import pprint

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",
            "Tokyo": "18°C"
    }
    return temperatures.get(city, "Unknown")

def get_conditions(city: str) -> str:
    """Get the current weather conditions for a city
    
    Args:
        city: The name of the city

    Returns:
        The current weather conditions for the city
    """
    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 客户端会自动将函数解析为工具模式,因此我们可以直接传入这些函数
# 模式也可以直接在工具列表中传入
response = chat(model='qwen3:8b', messages=messages, tools=[get_temperature, get_conditions], think=True)
pprint(response, indent=4, sort_dicts=False)

# 将助手消息添加至消息列表中
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'
        pprint(result, indent=4, sort_dicts=False)
        # 将工具执行结果添加至消息列表中
        messages.append({'role': 'tool',  'tool_name': call.function.name, 'content': str(result)})

    # 生成最终回复
    final_response = chat(model='qwen3:8b', messages=messages, tools=[get_temperature, get_conditions], think=True)
    pprint(final_response, indent=4, sort_dicts=False)

运行结果:

$ python .\ollama_example12.py

ChatResponse(model='qwen3:8b', created_at='2026-04-09T06:03:06.7116427Z', done=True, done_reason='stop', total_duration=108967819800, 
    load_duration=2809840800, prompt_eval_count=201, prompt_eval_duration=26233640600, 
    eval_count=340, eval_duration=79729986800, 
    message=Message(role='assistant', content='', thinking='Okay, the user ... calls accordingly.\n', 
    images=None, tool_name=None, 
    tool_calls=[ToolCall(function=Function(name='get_temperature', arguments={'city': 'New York'})), 
                ToolCall(function=Function(name='get_conditions', arguments={'city': 'New York'})), 
                ToolCall(function=Function(name='get_temperature', arguments={'city': 'London'})), 
                ToolCall(function=Function(name='get_conditions', arguments={'city': 'London'}))]), logprobs=None)

'22°C'
'Partly cloudy'
'15°C'
'Rainy'

ChatResponse(model='qwen3:8b', created_at='2026-04-09T06:04:50.027088Z', done=True, done_reason='stop', total_duration=103306809200, 
    load_duration=218098500, prompt_eval_count=575, prompt_eval_duration=50309812900, eval_count=216, 
    eval_duration=52678229600, message=Message(role='assistant', 
        content="Here's the current weather information:\n\n**New York**  \n- Temperature: 22°C  \n- Conditions: Partly cloudy  \n\n**London**  \n- Temperature: 15°C  \n- Conditions: Rainy  \n\nLet me know if you need further details! 🌤️", 
        thinking="Okay, let me process the information... a friendly and concise way.\n", 
        images=None, tool_name=None, tool_calls=None), logprobs=None)

JavaScript

下面通过 JavaScript 示例代码演示并行请求多个工具调用,然后将所有工具响应发送回模型。例如:

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:8b',
  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:8b', messages, tools, think: true })
  console.log(finalResponse.message.content)
}

运行结果:

$ node .\ollama_example12.js

模型响应:
 {
    "model": "qwen3:8b",
    "created_at": "2026-04-09T06:25:35.7366921Z",
    "message": {
        "role": "assistant",
        "content": "",
        "thinking": "Okay, the user is asking for the current weather conditions ... for both cities.\n",
        "tool_calls": [
            {
                "id": "call_r7yya7hr",
                "function": {
                    "index": 0,
                    "name": "get_conditions",
                    "arguments": {
                        "city": "New York"
                    }
                }
            },
            {
                "id": "call_gos64phx",
                "function": {
                    "index": 1,
                    "name": "get_temperature",
                    "arguments": {
                        "city": "New York"
                    }
                }
            },
            {
                "id": "call_x2lo8m0i",
                "function": {
                    "index": 2,
                    "name": "get_conditions",
                    "arguments": {
                        "city": "London"
                    }
                }
            },
            {
                "id": "call_9urpv5be",
                "function": {
                    "index": 3,
                    "name": "get_temperature",
                    "arguments": {
                        "city": "London"
                    }
                }
            }
        ]
    },
    "done": true,
    "done_reason": "stop",
    "total_duration": 56713915300,
    "load_duration": 99189300,
    "prompt_eval_count": 201,
    "prompt_eval_duration": 206832400,
    "eval_count": 249,
    "eval_duration": 56304831300
}
工具调用结果: Partly cloudy
工具调用结果: 22°C
工具调用结果: Rainy
工具调用结果: 15°C
最终响应:
 {
    "model": "qwen3:8b",
    "created_at": "2026-04-09T06:27:12.8520794Z",
    "message": {
        "role": "assistant",
        "content": "Here's the current weather information:\n\n**New York**  \n- **Conditions:** Partly cloudy  \n- **Temperature:** 22°C  \n\n**London**  \n- **Conditions:** Rainy  \n- **Temperature:** 15°C  \n\nLet me know if you need further details! 🌤️",
        "thinking": "Okay, let me process the information. The user asked ... way without markdown.\n"
    },
    "done": true,
    "done_reason": "stop",
    "total_duration": 97091345400,
    "load_duration": 244567700,
    "prompt_eval_count": 484,
    "prompt_eval_duration": 37440786500,
    "eval_count": 246,
    "eval_duration": 59306896400
}

多轮工具调用(智能体循环)

智能体循环允许模型决定何时调用工具,并将工具的结果整合到其回复中。

告诉模型它处于一个循环中,并且可以进行多次工具调用,这可能也会有所帮助。

Python

下面示例使用 Python 代码实现多轮工具调用,例如:

from ollama import chat, ChatResponse


def add(a: int, b: int) -> int:
    """Add two numbers"""
    """
    Args:
        a: The first number
        b: The second number

    Returns:
        The sum of the two numbers
    """
    return a + b


def multiply(a: int, b: int) -> int:
    """Multiply two numbers"""
    """
    Args:
        a: The first number
        b: The second number

    Returns:
        The product of the two numbers
    """
    return a * b


available_functions = {
    'add': add,
    'multiply': multiply,
}

messages = [{'role': 'user', 'content': 'What is (11434+12341)*412?'}]
while True:
    response = chat(
        model='qwen3:8b',
        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
# 使用更新后的消息继续执行循环

运行结果:

$ python .\ollama_example13.py

Thinking:  Okay, let's break down the user's question: (11434 + 12341) * 412. They want to know the result of this calculation. 
....
Content:
Calling add with arguments {'a': 11434, 'b': 12341}
Result: 23775
Calling multiply with arguments {'a': 23775, 'b': 412}
Result: 9795300

Thinking:  Okay, let's see. The user asked for (11434 + 12341) * 412. First, I need to add 11434 and 12341. Let me check that again. 11,434 plus 12,341. Adding the units: 4+1=5. Tens: 3+4=7. Hundreds: 4+3=7. Thousands: 1+2=3. Ten-thousands: 1+1=2. So that's 23,775. Yep, that's correct.
...
Content:  The result of $(11434 + 12341) \times 412$ is $\boxed{9795300}$.

JavaScript

下面示例使用 JavaScript 代码实现多轮工具调用,例如:

import ollama from 'ollama'

// 定义一个工具函数,实现加法操作
function add(a, b) {
    return a + b
}

// 定义一个工具函数,实现乘法操作
function multiply(a, b) {
    return a * b
}

// 定义一个工具调用对象,用于在聊天中调用该函数
const availableFunctions = {
    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' },
                },
            },
        },
    },
]

// Agent 主函数
async function agentLoop() {
    // 定义初始消息,用户询问如何计算 (11434+12341)*412
    const messages = [{ role: 'user', content: 'What is (11434+12341)*412?' }]
    // 定义 Agent 主循环
    while (true) {
        // 向 Ollama 发送消息,并等待回复
        const response = await ollama.chat({
            model: 'qwen3:8b',
            messages,
            tools,
            think: true,
        })
        // 将回复添加到消息列表中,以便下一次发送给 Ollama
        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]
                if (!fn) {
                    continue
                }

                const args = call.function.arguments
                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
        }
    }
}

// 运行 Agent 主函数,并捕获可能的错误
agentLoop().catch(console.error)

运行结果:

$ node .\ollama_example13.js

Thinking: Okay, let's see. The user is asking for the result of (11434 + 12341) multiplied by 412. Hmm, I need to break this down step by step. First, I should handle the addition inside the parentheses. So 11434 plus 12341. Let me add those two numbers. 
...
Content: 
Calling add with arguments { a: 11434, b: 12341 }
Result: 23775
Calling multiply with arguments { a: 23775, b: 412 }
Result: 9795300
Thinking: Okay, let me see. The user asked for (11434 + 12341) * 412. First, I called the add function with 11434 and 12341, which gave 23775. Then I used the multiply function with 23775 and 412. The tool response was 9795300. So the final answer should be 9,795,300. Let me just double-check the multiplication to be sure. 23775 * 412: breaking it down, 23775 * 400 = 9,510,000 and 23775 * 12 = 285,300. Adding those together gives 9,510,000 + 285,300 = 9,795,300. Yep, that matches. So the answer is correct.

Content: The result of (11434 + 12341) * 412 is **9,795,300**.

Step-by-step:
1. **Addition**: 11434 + 12341 = 23775
2. **Multiplication**: 23775 × 412 = 9,795,300

Final answer: 9,795,300

带流式传输的工具调用

在流式传输时,收集每一块 thinking、content 和 tool_calls,然后在后续请求中返回这些字段以及所有工具结果。

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:8b',
        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})

运行结果:

$ python .\ollama_example14.py

Okay, the user is asking for the temperature in New York. Let me check the tools available...tool_call tags.

[ToolCall(function=Function(name='get_temperature', arguments={'city': 'New York'}))]
Okay, the user asked for the temperature in New York...confirm it's accurate.

The current temperature in New York is **22°C**.

JavaScript

下面使用 JavaScript 实现带流式传输的工具调用,例如:

import ollama from 'ollama'

// 定义一个工具函数,用于获取城市温度
function getTemperature(city) {
    const temperatures = {
        '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' },
            },
        },
    },
}

// Agent 主循环函数
async function agentLoop() {
    // 初始化消息列表,包含用户提问的消息
    const messages = [{ role: 'user', content: "What is the temperature in New York?" }]
    // 循环执行聊天并处理工具调用结果
    while (true) {
        // 调用 chat 方法,并传入模型、消息列表和工具调用对象等参数
        const stream = await ollama.chat({
            model: 'qwen3:8b',
            messages,
            tools: [getTemperatureTool],
            stream: true,
            think: true,
        })

        let thinking = ''
        let content = ''
        const toolCalls = []
        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 })
        }

        // 如果没有工具调用,结束循环
        if (!toolCalls.length) {
            break
        }

        // 处理工具调用结果,将结果添加到消息列表中
        for (const call of toolCalls) {
            if (call.function.name === 'get_temperature') {
                const args = call.function.arguments
                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 方法,并捕获可能的错误
agentLoop().catch(console.error)

运行结果:

$ node .\ollama_example14.js

Okay, the user is asking for the temperature in New York... specified XML tags.
[
  {
    id: 'call_igefovta',
    function: { index: 0, name: 'get_temperature', arguments: [Object] }
  }
]
Okay, the user asked for the temperature in New York...confirm it's accurate.

The current temperature in New York is **22°C**.

这个循环会流式传输助手的响应,累积部分字段,将它们一起传回,并附加工具结果,以便模型能够完成其回答。

使用 Ollama Python SDK 将函数用作工具

Python SDK 会自动将函数解析为工具模式,因此我们可以直接传递它们。如果需要,仍然可以传递模式。

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,
}

messages = [{"role": "user", "content": "What is the temperature in New York?"}]

# 直接将函数作为工具列表的一部分传入
response = chat(model='qwen3:8b', messages=messages, tools=available_functions.values(), think=True)
print("Thinking: ", response.message.thinking)
print("Content: ", response.message.content)
print("Tool calls: ", response.message.tool_calls)

运行结果:

$ python .\ollama_example15.py

Thinking:  Okay, the user is asking for the temperature in New York...inside the XML tags.

Content:  

Tool calls:  [ToolCall(function=Function(name='get_temperature', arguments={'city': 'New York'}))]

原文:https://docs.ollama.com/capabilities/tool-calling#tool-calling-with-streaming

  

天下之事常成于困约,而败于奢靡。——陆游
0 不喜欢
说说我的看法 -
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
其他应用
公众号