×
Community Blog GenAI on Alibaba Cloud [Part 3]: Teach Qwen to Use Tools (Function Calling)

GenAI on Alibaba Cloud [Part 3]: Teach Qwen to Use Tools (Function Calling)

This article introduces how to enable an AI assistant to perform real-time tasks by using Function Calling to interact with external tools and functions.

In the previous episodes, we built a chatbot and a RAG system. But our AI had a major limitation: It was trapped in a box.

If you asked Qwen: "What is the weather in Cairo right now?", it would apologize and say it doesn't have real-time access to the internet. If you asked it to "Send an email to my boss," it would say it can't interact with external apps.

Function Calling (also known as Tool Use) changes everything. It allows the LLM to say: "I don't know the answer, but I know a piece of code that does. Please run this function for me and give me the result."

In this episode, we will build a "Smart Assistant" that can fetch real-time data (simulated) by calling Python functions.

The Concept: The "Tool Use" Loop

Function calling is a 4-step dance between your code and Qwen:

  1. User: Asks "What's the weather in Singapore?"
  2. Qwen: Analyzes the prompt. It sees you have given it a "Weather Tool." Instead of answering text, it replies with a structured command: Call function 'get_weather' with argument 'Singapore'.
  3. Your Code: Pauses, executes the Python function get_weather("Singapore"), and gets the result (30°C, Rainy).
  4. Qwen: Receives the result and generates the final natural language answer: "Currently in Singapore, it is 30°C and rainy."

Step 1: The Setup

We continue using the OpenAI-Compatible client for Alibaba Cloud, as it provides the cleanest syntax for tool use.

pip install openai python-dotenv

Step 2: Define Your "Tools"

Create a file named agent_qwen.py.

First, we define a normal Python function. In a real app, this would hit a weather API or a database. For this demo, we will mock it.

import json

# This is the actual code the AI will "trigger"
def get_current_weather(location, unit="celsius"):
    """Get the current weather in a given location"""
    print(f" > [System] AI is calling the weather function for {location}...")
    
    # MOCK DATA: In reality, you would call an API like OpenWeatherMap here.
    if "singapore" in location.lower():
        return json.dumps({"location": "Singapore", "temperature": "30", "unit": unit, "forecast": "thunderstorms"})
    elif "cairo" in location.lower():
        return json.dumps({"location": "Cairo", "temperature": "25", "unit": unit, "forecast": "sunny"})
    elif "london" in location.lower():
        return json.dumps({"location": "London", "temperature": "10", "unit": unit, "forecast": "foggy"})
    else:
        return json.dumps({"location": location, "temperature": "unknown"})

Step 3: The Tool Definition (The Schema)

We need to tell Qwen that this tool exists. We do this using a JSON schema. This is how Qwen knows when to call the function and what parameters to extract.

# The "Menu" of tools we offer to Qwen
tools_schema = [
    {
        "type": "function",
        "function": {
            "name": "get_current_weather",
            "description": "Get the current weather in a given location",
            "parameters": {
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "The city and state, e.g. San Francisco, CA",
                    },
                    "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]},
                },
                "required": ["location"],
            },
        },
    }
]

Step 4: The Code (The Agent Loop)

Here is the complete script. It handles the conversation and the automatic execution of the function.

Copy and paste this into

import os
import json
from openai import OpenAI
from dotenv import load_dotenv

load_dotenv()

# 1. Setup Client (International Endpoint)
client = OpenAI(
    api_key=os.getenv("DASHSCOPE_API_KEY"), 
    base_url="https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
)

# 2. Define the Function (The implementation)
def get_current_weather(location, unit="celsius"):
    # ... (Paste the function from Step 2 here) ...
    # For brevity, re-pasting the simple logic:
    if "singapore" in location.lower():
        return json.dumps({"location": "Singapore", "temperature": "30", "unit": unit})
    elif "cairo" in location.lower():
        return json.dumps({"location": "Cairo", "temperature": "25", "unit": unit})
    else:
        return json.dumps({"location": location, "temperature": "20", "unit": unit})

# 3. Define the Tool Schema (The definition)
tools = [
    {
        "type": "function",
        "function": {
            "name": "get_current_weather",
            "description": "Get the current weather in a given location",
            "parameters": {
                "type": "object",
                "properties": {
                    "location": {"type": "string", "description": "The city name"},
                    "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]},
                },
                "required": ["location"],
            },
        },
    }
]

def run_conversation():
    # 4. Start the conversation
    messages = [
        {"role": "system", "content": "You are a helpful assistant. Use tools if needed."},
        {"role": "user", "content": "What's the weather like in Cairo right now?"}
    ]

    print(f"User Question: {messages[1]['content']}")

    # 5. First Call: Ask Qwen
    response = client.chat.completions.create(
        model="qwen-plus", # Qwen-Plus and Qwen-Max are best for tools
        messages=messages,
        tools=tools,
        tool_choice="auto", 
    )
    
    response_message = response.choices[0].message
    tool_calls = response_message.tool_calls

    # 6. Check if Qwen wants to use a tool
    if tool_calls:
        print("\n[Qwen decided to call a function!]")
        
        # Step 6a: Execute the function
        # We need to map the function name string to the actual Python function
        available_functions = {
            "get_current_weather": get_current_weather,
        }
        
        # Append Qwen's "intent" to the history so it remembers it asked
        messages.append(response_message) 

        for tool_call in tool_calls:
            function_name = tool_call.function.name
            function_to_call = available_functions[function_name]
            function_args = json.loads(tool_call.function.arguments)
            
            print(f" > Calling: {function_name} with args: {function_args}")
            
            # Run the python code
            function_response = function_to_call(
                location=function_args.get("location"),
                unit=function_args.get("unit"),
            )
            
            # Step 6b: Send the result BACK to Qwen
            messages.append(
                {
                    "tool_call_id": tool_call.id,
                    "role": "tool",
                    "name": function_name,
                    "content": function_response,
                }
            )

        # 7. Second Call: Get the final answer
        print("\n[Sending function results back to Qwen...]")
        second_response = client.chat.completions.create(
            model="qwen-plus",
            messages=messages,
        ) 
        
        print("\n--- Final Answer ---")
        print(second_response.choices[0].message.content)
        print("--------------------")

if __name__ == "__main__":
    run_conversation()

Step 5: Run the Agent

Run the script:

python agent_qwen.py

Expected Output:

User Question: What's the weather like in Cairo right now?

[Qwen decided to call a function!]
 > Calling: get_current_weather with args: {'location': 'Cairo'}
 > [System] AI is calling the weather function for Cairo...

[Sending function results back to Qwen...]

--- Final Answer ---
The weather in Cairo is currently 25°C.
--------------------

Why is this "Amazing"?

Notice carefully: We never wrote code to print "The weather in Cairo is currently 25°C."

  1. Qwen recognized "Cairo" from the user text.
  2. Qwen prepared the arguments for our function.
  3. Our function returned raw JSON: {"temperature": "25"}.
  4. Qwen read that JSON and converted it into a polite English sentence.

This is the power of Structure-to-Text.

Use Cases for Alibaba Cloud Developers

Now that you know how to trigger functions, imagine what you can build:

  1. CloudOps Bot: "Qwen, restart the ECS instance named 'web-server'." (Tool: calls Alibaba Cloud ECS SDK).
  2. Database Analyst: "Qwen, how many users signed up last week?" (Tool: Executes a SQL query on RDS).
  3. Customer Support: "Qwen, check the status of Order #123." (Tool: HTTP request to your backend API).

Tips for Success

Model Selection: For simple tools, qwen-turbo works. For complex logic (chained tools), use qwen-plus or qwen-max.

Descriptions Matter: The description field in the tool schema is what the AI reads. Be descriptive! "Get weather" is okay; "Get current weather for a specific city to help the user plan their day" is better.

What's Next?

We have covered the basics (Chat), the knowledge (RAG), and the action (Tools).

In Episode 4, we will look at Deployment. Running python scripts on your laptop is fun, but how do we put this on the internet for the world to see? We will deploy our Qwen app using Function Compute (Alibaba Cloud's Serverless platform) to make it a real API.

Happy Coding!


Disclaimer: The views expressed herein are for reference only and don't necessarily represent the official views of Alibaba Cloud.

1 1 0
Share on

Farah Abdou

19 posts | 0 followers

You may also like

Comments

nickhameasldf December 27, 2025 at 10:32 am

good