玩转Ollama函数调用:让AI从“光说不练”到“动手解决问题”

简介: 你是否厌倦AI瞎编答案?Ollama函数调用功能为AI装上“小手”,让它能调用天气查询、计算器等自定义工具,先做事、再回答,告别胡说八道!本文手把手教你从零实现单次调用、并行调用、多轮智能体循环及流式响应,全程Python实战,小白也能轻松上手。

你有没有过这种体验:问AI“纽约现在多少度?”,它张口就编了个数字;让它算个复杂数学题,结果错得离谱还理直气壮?

其实不是AI笨,是它缺了“动手能力”——只会靠自己的知识库瞎猜,不会调用外部工具。而Ollama的“函数调用(Function Call)”功能,就是给AI装上一双“小手”,让它能调用咱们写好的工具(比如查天气的函数、计算器函数),先做事,再回答,再也不瞎蒙了!

今天咱们就从零开始,用最接地气的话、最详细的例子,手把手教你玩透Ollama函数调用。

一、先搭好“玩耍环境”

要玩函数调用,得先把基础环境搭好,就像玩游戏前先装客户端一样。

1. 安装Ollama

2. 安装Python SDK(新手首选Python,简单易上手)

终端里输入下面的命令,安装Ollama的Python工具包:

# 用pip安装(最常用)
pip install ollama -U

# 如果你用uv包管理工具,也可以这样装
# uv add ollama

二、先搞懂核心逻辑:用“拍戏”理解函数调用

动手写代码前,先花2分钟搞懂核心概念,用“拍戏”打比方,一看就懂:

  • 你(用户):提问的人,比如“纽约现在多少度?”
  • AI助手(演员):Ollama跑的模型,负责理解你的问题,判断要不要调用工具、调用哪个工具。
  • 工具(道具组):咱们写的函数(比如查气温的get_temperature),能解决具体问题。
  • 对话剧本(messages列表):记录所有“剧情”——你的问题、AI的思考、调用的工具、工具返回的结果,AI全靠这个剧本判断下一步该做啥。

函数调用的核心流程就4步,像拍小短片一样:

  1. 你把“问题 + 工具清单”交给AI(递剧本);
  2. AI看完剧本,说“我需要调用查气温工具,查纽约的温度”(出指令);
  3. 你执行这个工具,得到“22°C”(道具组干活);
  4. 把工具结果加到剧本里,再交给AI,AI整理出最终回答(演员收尾)。

三、入门篇:让AI查纽约的气温(单次工具调用)

先从最简单的“单次调用”开始,目标:问AI“纽约现在多少度?”,AI调用我们写的气温函数,返回准确答案。

步骤1:写好“气温查询工具”

先写一个模拟的气温查询函数(先不用真实API,重点看逻辑):

from ollama import chat

def get_temperature(city: str) -> str:
    """
    模拟查询城市当前气温的工具函数
    :param city: 城市名称(比如New York、London)
    :return: 该城市的气温,查不到就返回Unknown
    """
    # 模拟的气温数据,实际可以换成真实的天气API
    temperature_dict = {
   
        "New York": "22°C",
        "London": "15°C",
        "Tokyo": "18°C",
    }
    # 查得到就返回气温,查不到返回Unknown
    return temperature_dict.get(city, "Unknown")

步骤2:写对话逻辑,让AI调用工具

# 1. 初始化“对话剧本”,先把用户的问题写进去
messages = [{
   "role": "user", "content": "What is the temperature in New York?"}]

# 2. 把问题+工具交给AI,让它判断要不要调用工具
# think=True:让AI输出思考过程,方便我们看它咋想的
response = chat(
    model="qwen3",  # 用咱们刚才启动的qwen3模型
    messages=messages,  # 对话剧本
    tools=[get_temperature],  # 给AI的工具清单
    think=True
)

# 3. 把AI的回复加到剧本里(剧情更新)
messages.append(response.message)

# 4. 判断AI是否要调用工具
if response.message.tool_calls:
    # 这里只处理单个工具调用(新手先看这个)
    call = response.message.tool_calls[0]
    print(f"AI想调用工具:{call.function.name}")
    print(f"调用参数:{call.function.arguments}")

    # 5. 执行工具函数,获取结果
    result = get_temperature(**call.function.arguments)
    print(f"工具返回结果:{result}")

    # 6. 把工具结果加到剧本里
    messages.append({
   
        "role": "tool",  # 角色是“工具”
        "tool_name": call.function.name,  # 工具名
        "content": str(result)  # 工具返回的内容
    })

    # 7. 把更新后的剧本交给AI,让它生成最终回答
    final_response = chat(
        model="qwen3",
        messages=messages,
        tools=[get_temperature],
        think=True
    )

    # 8. 打印最终结果
    print("\n===== AI最终回答 =====")
    print(final_response.message.content)
else:
    # 如果AI没调用工具,直接打印它的回答
    print(response.message.content)

步骤3:运行代码,看效果

运行后会看到这样的输出(超直观):

AI想调用工具:get_temperature
调用参数:{'city': 'New York'}
工具返回结果:22°C

===== AI最终回答 =====
The current temperature in New York is 22°C.

是不是超简单?AI没有瞎编,而是乖乖调用我们写的函数,返回了准确结果!

四、进阶篇1:一次查多个信息(并行工具调用)

如果问“纽约和伦敦的气温+天气状况分别是啥?”,总不能让AI一个个查吧?这时候就需要“并行调用”——AI一次调用多个工具,效率拉满。

步骤1:新增“天气状况工具”

先加一个查天气状况的函数:

def get_conditions(city: str) -> str:
    """
    模拟查询城市当前天气状况的工具函数
    :param city: 城市名称
    :return: 天气状况(晴/多云/下雨等)
    """
    conditions_dict = {
   
        "New York": "Partly cloudy",
        "London": "Rainy",
        "Tokyo": "Sunny",
    }
    return conditions_dict.get(city, "Unknown")

步骤2:修改对话逻辑,处理多个工具调用

from ollama import chat

# 1. 初始化剧本,问更复杂的问题
messages = [{
   "role": "user", "content": "What are the current weather conditions and temperature in New York and London?"}]

# 2. 把两个工具都交给AI
response = chat(
    model="qwen3",
    messages=messages,
    tools=[get_temperature, get_conditions],  # 工具清单加了新成员
    think=True
)
messages.append(response.message)

# 3. 处理多个工具调用(重点!)
if response.message.tool_calls:
    print("===== AI调用的所有工具 =====")
    for call in response.message.tool_calls:
        print(f"工具名:{call.function.name},参数:{call.function.arguments}")

        # 执行对应的工具函数
        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"

        print(f"工具返回:{result}\n")
        # 把每个工具的结果都加到剧本里
        messages.append({
   
            "role": "tool",
            "tool_name": call.function.name,
            "content": result
        })

    # 4. 生成最终回答
    final_response = chat(
        model="qwen3",
        messages=messages,
        tools=[get_temperature, get_conditions],
        think=True
    )

    print("===== AI最终回答 =====")
    print(final_response.message.content)

步骤3:运行效果

===== AI调用的所有工具 =====
工具名:get_temperature,参数:{'city': 'New York'}
工具返回:22°C

工具名:get_conditions,参数:{'city': 'New York'}
工具返回:Partly cloudy

工具名:get_temperature,参数:{'city': 'London'}
工具返回:15°C

工具名:get_conditions,参数:{'city': 'London'}
工具返回:Rainy

===== AI最终回答 =====
New York currently has a temperature of 22°C with partly cloudy conditions, while London has a temperature of 15°C and is rainy.

看!AI一次性调用了4次工具(两个城市×两个工具),把所有信息都收集齐了,再整理成通顺的回答,比一个个问高效多了!

五、进阶篇2:让AI自己“循环解题”(多轮工具调用/智能体循环)

遇到复杂问题,比如“(11434+12341)*412等于多少?”,AI没法一步算出来,这时候需要“多轮调用”——AI先调用加法,得到结果后,再调用乘法,直到算出最终答案,就像个会自己思考的小助手。

步骤1:写加法、乘法工具

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_tools = {
   
    "add": add,
    "multiply": multiply
}

步骤2:写“智能体循环”逻辑

# 1. 初始化剧本,问复杂数学题
messages = [{
   "role": "user", "content": "What is (11434+12341)*412?"}]

# 2. 核心:循环让AI解题,直到它说“不用调用工具了”
while True:
    # 每次循环都把最新的剧本交给AI
    response: ChatResponse = chat(
        model="qwen3",
        messages=messages,
        tools=available_tools.values(),  # 把加法、乘法工具传进去
        think=True
    )
    messages.append(response.message)

    # 打印AI的思考过程,看它咋解题的
    print(f"===== AI思考过程 =====\n{response.message.thinking}\n")
    print(f"===== AI当前回复 =====\n{response.message.content}\n")

    # 3. 判断是否需要调用工具
    if response.message.tool_calls:
        # 执行每个工具调用
        for call in response.message.tool_calls:
            tool_name = call.function.name
            tool_args = call.function.arguments
            print(f"调用工具:{tool_name},参数:{tool_args}")

            # 执行工具函数
            result = available_tools[tool_name](**tool_args)
            print(f"工具返回:{result}\n")

            # 把结果加到剧本里
            messages.append({
   
                "role": "tool",
                "tool_name": tool_name,
                "content": str(result)
            })
    else:
        # 没有工具调用了,说明解题完成,退出循环
        print("===== 解题完成!=====")
        break

步骤3:运行效果(超有意思!)

===== AI思考过程 =====
用户现在问的是(11434+12341)*412,我需要先算加法,再算乘法。首先调用add工具计算11434+12341,得到结果后再调用multiply工具乘以412。

===== AI当前回复 =====
I need to calculate 11434 + 12341 first, then multiply the result by 412.

调用工具:add,参数:{'a': 11434, 'b': 12341}
工具返回:23775

===== AI思考过程 =====
现在已经算出11434+12341=23775,接下来需要调用multiply工具计算23775*412。

===== AI当前回复 =====
Now I will calculate 23775 * 412.

调用工具:multiply,参数:{'a': 23775, 'b': 412}
工具返回:9795300

===== AI思考过程 =====
已经算出最终结果是9795300,不需要再调用任何工具了,可以直接回答用户。

===== AI当前回复 =====
(11434+12341)*412 = 9795300

===== 解题完成!=====

是不是超酷?AI像个小学生一样,先算加法再算乘法,一步步把复杂问题拆解开,自己循环解题,完全不用我们干预!

六、高阶篇:实时看到AI的思考过程(流式工具调用)

前面的例子都是“一次性等结果”,流式调用能让你实时看到AI的思考、回复、工具调用,就像看AI“边想边说”,体验更丝滑。

完整代码(带详细注释)

from ollama import chat

def get_temperature(city: str) -> str:
    """还是用这个气温查询函数"""
    temperature_dict = {
   
        "New York": "22°C",
        "London": "15°C",
    }
    return temperature_dict.get(city, "Unknown")

# 初始化剧本
messages = [{
   "role": "user", "content": "What is the temperature in New York?"}]

# 流式调用的核心循环
while True:
    # 开启stream=True,返回流式数据
    stream = chat(
        model="qwen3",
        messages=messages,
        tools=[get_temperature],
        stream=True,  # 关键:开启流式
        think=True
    )

    # 用来聚合流式返回的内容(因为流式是分块返回的)
    thinking = ""
    content = ""
    tool_calls = []
    done_thinking = False

    # 逐块接收AI的回复
    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)

    # 把聚合后的内容加到剧本里
    if thinking or content or tool_calls:
        messages.append({
   
            "role": "assistant",
            "thinking": thinking,
            "content": content,
            "tool_calls": tool_calls
        })

    # 处理工具调用
    if tool_calls:
        print("\n")  # 换行
        for call in tool_calls:
            print(f"调用工具:{call.function.name},参数:{call.function.arguments}")
            result = get_temperature(**call.function.arguments)
            print(f"工具返回:{result}")
            messages.append({
   
                "role": "tool",
                "tool_name": call.function.name,
                "content": result
            })
    else:
        # 没有工具调用,退出循环
        break

运行效果(实时输出,超有代入感)

用户问纽约的气温,我需要调用get_temperature工具,参数是city=New York

我需要调用工具查询纽约的气温。
调用工具:get_temperature,参数:{'city': 'New York'}
工具返回:22°C
纽约当前的气温是22°C。

流式调用的关键是“聚合分片内容”——因为AI的思考、回复、工具调用是分小块返回的,必须把这些小块拼起来,AI才能记住完整的上下文。

七、Python专属小技巧:函数自动变工具

Ollama的Python SDK超贴心——不用手动写复杂的JSON工具定义,直接把函数传进去就行!对比一下就知道多方便:

# ❶ 懒人版:直接传函数(推荐!)
response = chat(
    model="qwen3",
    messages=messages,
    tools=[get_temperature],  # 直接传函数,SDK自动解析
    think=True
)

# ❷ 手动版:写JSON定义(麻烦,不推荐)
# 只有特殊需求时才用这个
custom_tool = [
    {
   
        "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"}
                }
            }
        }
    }
]
response = chat(
    model="qwen3",
    messages=messages,
    tools=custom_tool,
    think=True
)

Python SDK会自动读取函数的注释、参数类型,转换成AI能识别的工具定义,省了超多事!现在你已经掌握了Ollama函数调用的核心玩法,快去试试让AI帮你做更多实际的事吧!

相关文章
|
2月前
|
人工智能 Linux API
[大模型实战 01] 本地大模型初体验:Ollama 部署与 Python 调用指南
大模型实战系列第一篇。拒绝晦涩理论,直接上手!我会带着各位友人们零基础安装 Ollama,利用国内 ModelScope 极速下载模型,详解服务端口配置与 Python 脚本调用,涵盖显存计算与常见避坑指南。
[大模型实战 01] 本地大模型初体验:Ollama 部署与 Python 调用指南
|
2月前
|
网络协议 安全 Linux
Rocky Linux 9:Samba服务安装配置全攻略
本文手把手教你用Rocky Linux 9从零搭建Samba文件共享服务:详解防火墙/SELinux配置、smb.conf核心参数(global与共享段)、目录权限与SELinux上下文设置、Samba用户创建及Win/Linux双端访问,新手也能轻松实现跨系统无缝传文件!
|
2月前
|
人工智能 JavaScript 数据可视化
保姆级教程:OpenClaw(Clawdbot)阿里云及Windows本地部署方案,与本地Ollama配置指南
在AI智能体快速普及的2026年,OpenClaw(前身为Clawdbot)凭借开源免费、可自托管、系统级权限控制的核心优势,成为个人与轻量团队打造专属AI助手的首选工具,其GitHub星标已飙升至18万+,登顶多个开源榜单。Ollama作为目前最受开发者欢迎的本地大模型运行工具,GitHub星标突破16万,支持480+开源模型一键部署,二者组合可实现“本地推理+本地执行”的全闭环,彻底摆脱对云端大模型的依赖,确保数据隐私安全且无网络依赖。
3662 2
|
2月前
|
机器学习/深度学习 测试技术 API
Qwen3.5 中等规模模型系列正式开源:更强智能,更低算力
通义千问Qwen3.5发布四款中等规模多模态模型,支持256K原生上下文(可扩至1M)、201种语言及统一视觉语言训练。凭借Gated Delta+MoE混合架构与百万Agent强化学习,35B-A3B仅激活3B参数即超越旧旗舰,性能、效率与部署成本兼具。(239字)
6541 23
|
3月前
|
人工智能 运维 监控
Moltbot(原 Clawdbot)成本失控的 5 个技术陷阱与实时监控方案
Hacker News上警示频发:Clawdbot(原Moltbot)因五大技术陷阱致成本失控——上下文O(N²)膨胀、Agent无限循环、大页浏览器加载、并发爆炸、模型误用。本文详解每类陷阱原理、真实案例及可落地的缓解方案,并提供实时监控、预算熔断与CLI管理工具,助AI Agent实现低成本、高可控运行。
446 5