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
# باستخدام 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?"}]

# تمرير الدوال مباشرة كأدوات في قائمة الأدوات أو كمخطط 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

ثبّت مكتبة Ollama JavaScript:
```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": "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 بتحليل الوظائف تلقائياً كمخطط أداة، لذا يمكننا تمريرها مباشرة
# يمكن أيضاً تمرير المخططات مباشرة في قائمة الأدوات
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: '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.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:
  """اجمع رقمين"""
  """
  المعاملات:
    أ: الرقم الأول
    ب: الرقم الثاني

  الإرجاع:
    مجموع الرقمين
  """
  return a + b


def multiply(a: int, b: int) -> int:
  """اضرب رقمين"""
  """
  المعاملات:
    أ: الرقم الأول
    ب: الرقم الثاني

  الإرجاع:
    حاصل ضرب الرقمين
  """
  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: '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:
  """الحصول على درجة الحرارة الحالية لمدينة

  المعاملات:
    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
  # تجميع الحقول الجزئية
  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: '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)

تقوم هذه الحلقة ببث رد المساعد بشكل متدفق، وتجميع الحقول الجزئية، وإعادتها معًا، وإلحاق نتائج الأدوات حتى يتمكن النموذج من إكمال إجابته.

استخدام الدوال كأدوات مع Python SDK لـ Ollama

يقوم Python SDK تلقائيًا بتحليل الدوال كمخطط أداة، لذا يمكننا تمريرها مباشرة. لا يزال يمكن تمرير المخططات إذا لزم الأمر.

python
from ollama import chat

def get_temperature(city: str) -> str:
  """الحصول على درجة الحرارة الحالية لمدينة

  المعاملات:
    city: اسم المدينة

  الإرجاع:
    درجة الحرارة الحالية للمدينة
  """
  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)