Skip to content

Ollama รองรับการเรียกใช้เครื่องมือ (เรียกอีกอย่างว่าการเรียกใช้ฟังก์ชัน) ซึ่งช่วยให้โมเดลสามารถเรียกใช้เครื่องมือและรวมผลลัพธ์จากเครื่องมือเหล่านั้นเข้ากับคำตอบของตัวเองได้

การเรียกใช้เครื่องมือเดี่ยว

เรียกใช้เครื่องมือเพียงหนึ่งเครื่องและรวมคำตอบจากเครื่องมือนั้นเข้ากับคำขอติดตาม เรียกอีกอย่างว่าการเรียกใช้เครื่องมือแบบ "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"}
          }
        }
      }
    }
  ]
}'
```

**สร้างคำตอบด้วยผลลัพธ์จากเครื่องมือเพียงหนึ่งเครื่อง**
```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

ติดตั้ง Ollama Python SDK:
```bash
# with pip
pip install ollama -U

# with 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?"}]

# ส่งฟังก์ชันโดยตรงเป็นเครื่องมือในรายการเครื่องมือหรือเป็น JSON schema
response = chat(model="qwen3", messages=messages, tools=[get_temperature], think=True)

messages.append(response.message)
if response.message.tool_calls:
  # only recommended for models which only return a single tool call
  call = response.message.tool_calls[0]
  result = get_temperature(**call.function.arguments)
  # add the tool result to the messages
  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

ติดตั้งไลบรารี Ollama สำหรับ JavaScript:
```bash
# with npm
npm i ollama

# with 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) {
  // only recommended for models which only return a single tool call
  const call = response.message.tool_calls[0]
  const args = call.function.arguments as { city: string }
  const result = getTemperature(args.city)
  // add the tool result to the messages
  messages.push({ role: 'tool', tool_name: call.function.name, content: result })

  // generate the final response
  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": "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"}
          }
        }
      }
    }
  ]
}'
```

**สร้างการตอบกลับพร้อมผลลัพธ์จากเครื่องมือหลายรายการ**
```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:
  """รับอุณหภูมิปัจจุบันของเมือง

  พารามิเตอร์:
    city: ชื่อของเมือง

  ค่าที่ส่งกลับ:
    อุณหภูมิปัจจุบันของเมือง
  """
  temperatures = {
    "New York": "22°C",
    "London": "15°C",
    "Tokyo": "18°C"
  }
  return temperatures.get(city, "Unknown")

def get_conditions(city: str) -> str:
  """รับสภาพอากาศปัจจุบันของเมือง

  พารามิเตอร์:
    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 จะแปลงฟังก์ชันเป็น schema เครื่องมือโดยอัตโนมัติ ดังนั้นเราส่งฟังก์ชันได้ตรงๆ
# สามารถส่ง schema ไปยังรายการ tools ได้โดยตรงด้วย
response = chat(model='qwen3', messages=messages, tools=[get_temperature, get_conditions], think=True)

# เพิ่มข้อความจากผู้ช่วยเข้าไปในรายการ messages
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
    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: '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
})

// เพิ่มข้อความจากผู้ช่วยเข้าไปในรายการ messages
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
    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:
  """บวกตัวเลขสองจำนวน"""
  """
  พารามิเตอร์:
    a: ตัวเลขตัวแรก
    b: ตัวเลขตัวที่สอง

  ค่าที่ส่งกลับ:
    ผลรวมของตัวเลขทั้งสองจำนวน
  """
  return a + b


def multiply(a: int, b: int) -> int:
  """คูณตัวเลขสองจำนวน"""
  """
  พารามิเตอร์:
    a: ตัวเลขตัวแรก
    b: ตัวเลขตัวที่สอง

  ค่าที่ส่งกลับ:
    ผลคูณของตัวเลขทั้งสองจำนวน
  """
  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
                messages.append({'role': 'tool', 'tool_name': tc.function.name, 'content': str(result)})
    else:
        # จบลูปเมื่อไม่มีการเรียกใช้เครื่องมืออีกต่อไป
        break
  # ดำเนินลูปต่อด้วยรายการ messages ที่อัปเดตแล้ว
```

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

การเรียกใช้เครื่องมือด้วยการสตรีมมิ่ง

เมื่อทำการสตรีมมิ่ง ให้รวบรวมทุกชิ้นส่วนของ 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)

  # เพิ่มฟิลด์ที่รวบรวมแล้วไปยัง 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<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 จะแปลงฟังก์ชันเป็น schema ของเครื่องมือโดยอัตโนมัติ ทำให้เราส่งผ่านได้โดยตรง หากต้องการส่งผ่าน schema เองก็ยังสามารถทำได้

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,
}
# ส่งผ่านฟังก์ชันโดยตรงเป็นส่วนหนึ่งของรายการ tools
response = chat(model='qwen3', messages=messages, tools=available_functions.values(), think=True)