大模型function calling:让AI函数调用更智能、更高效
大模型function calling:让AI函数调用更智能、更高效

随着大语言模型(LLM)的快速发展,其在实际应用中的能力越来越受到关注。Function Calling 是一种新兴的技术,允许大模型与外部工具或API进行交互,从而扩展了模型的功能边界。本文将深入探讨 Function Calling 的原理、应用场景以及如何通过优化实现更智能、高效的函数调用。
1. 什么是 Function Calling?
unction Calling 是一种机制,允许大语言模型动态调用外部函数或API,以完成特定任务。例如,当用户提问“今天的天气如何?”时,模型可以通过调用天气API获取实时数据并返回结果。这种方式不仅提升了模型的实用性,还使其能够处理复杂的多步骤任务。
- 关键特点:
- 动态调用:根据用户需求调用合适的函数。
- 上下文感知:结合对话上下文选择最佳函数。
- 扩展性强:支持多种API和服务集成。
2. Function Calling 的核心原理

- 用户输入问题或指令。
- 模型分析输入,生成 JSON 格式的函数调用请求。
- 后端解析请求,调用对应函数或API。
- 将函数返回的结果传递回模型。
- 模型基于结果生成最终回答。
3.基本操作
llm使用的是llama3.2:3b的模型,有一些模型是不支持tools的。
# 安装依赖包
pip isntall ollama
pip install yfinance
"""
1.将问题输出到llm模型中
2.模型解析问题中参数,将需要回调的函数和参数输出。
3.将回调结果作为上下文输入llm模型中验证
"""
import ollama
from ollama import Clientclient = Client(host='http://192.168.3.203:11434/',headers={'x-some-header': 'some-value'}
)def add_two_numbers(a: int, b: int) -> int:"""Add two numbersArgs:a (int): The first numberb (int): The second numberReturns:int: The sum of the two numbers"""return int(a) + int(b)def subtract_two_numbers(a: int, b: int) -> int:"""Subtract two numbers"""return int(a) - int(b)# Tools can still be manually defined and passed into chat
subtract_two_numbers_tool = {'type': 'function','function': {'name': 'subtract_two_numbers','description': 'Subtract two numbers','parameters': {'type': 'object','required': ['a', 'b'],'properties': {'a': {'type': 'integer', 'description': 'The first number'},'b': {'type': 'integer', 'description': 'The second number'},},},},
}messages = [{'role': 'user', 'content': 'What is three plus one?'}]
print('Prompt:', messages[0]['content'])available_functions = {'add_two_numbers': add_two_numbers,'subtract_two_numbers': subtract_two_numbers,
}def main():response = client.chat('llama3.2:3b',messages=messages,tools=[add_two_numbers, subtract_two_numbers_tool],)if response.message.tool_calls:# There may be multiple tool calls in the responsefor tool in response.message.tool_calls:# Ensure the function is available, and then call itif function_to_call := available_functions.get(tool.function.name):print('Calling function:', tool.function.name)print('Arguments:', tool.function.arguments)output = function_to_call(**tool.function.arguments)print('Function output:', output)else:print('Function', tool.function.name, 'not found')# Only needed to chat with the model using the tool call resultsif response.message.tool_calls:# Add the function response to messages for the model to usemessages.append(response.message)messages.append({'role': 'tool', 'content': str(output), 'name': tool.function.name})# Get final response from model with function outputsfinal_response = client.chat('llama3.2:3b', messages=messages)print('Final response:', final_response.message.content)else:print('No tool calls returned from model')if __name__ == '__main__':main()"""
结果
Prompt: What is three plus one?
Calling function: add_two_numbers
Arguments: {'a': 3, 'b': 1}
Function output: 4
"""
"""
1.通过llm模型获取解析回调函数和函数的参数
2.通过yfinance库获取公司最新股票信息
"""
from ollama import Client
import yfinance as yfclient = Client(host='http://192.168.3.203:11434',headers={'x-some-header': 'some-value'}
)def get_current_stock_price(ticker_symbol):# 定义函数stock = yf.Ticker(ticker_symbol)current_price = stock.history(period='1d')['Close'].iloc[0]return current_price# 本地测试
# data = get_current_stock_price("MSFT")
# print(data)# 工具函数请求参数
tools = [{'type': 'function','function': {'name': 'get_current_stock_price','description': 'Get the current price for a stock','parameters': {'type': 'object','properties': {'ticker_symbol': {'type': 'string','description': 'The ticker symbol of the stock'}}},'required': ['ticker_symbol']}}]
response = client.chat(model='llama3.2:3b',messages=[{'role': 'user','content': 'What is the current price of MSFT'}],# provide a tool to get the current price of a stocktools=tools)
print(response['message']['tool_calls'])
# [ToolCall(function=Function(name='get_current_stock_price', arguments={'ticker_symbol': 'MSFT'}))]# 模拟函数库
function_map = {'get_current_stock_price': get_current_stock_price}def call_function_safely(response, function_map):# 模型结果回调函数tool_call = response['message']['tool_calls'][0]function_name = tool_call['function']['name']arguments = tool_call['function']['arguments']function_to_call = function_map.get(function_name)if function_to_call:try:result = function_to_call(**arguments)print(f"The current price of {arguments['ticker_symbol']} is : {result}")except TypeError as e:print(f"Argument error: {e}")else:print(f"{function_name} is not a recognized function")call_function_safely(response, function_map)
4.实现自动发送邮件
import os
from dotenv import load_dotenvimport smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipartimport json
from openai import OpenAIGPT_MODEL = "llama3.2:3b"load_dotenv(dotenv_path="/Users/wuzhibin/workspace/pythonDemo/ollama_demo/.env")
# 大模型密钥
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
# 邮箱授权码
AUTHORIZATION_CODE = os.getenv("AUTHORIZATION_CODE")
print("1111", OPENAI_API_KEY, AUTHORIZATION_CODE)
client = OpenAI(base_url="http://192.168.3.203:11434/v1", api_key=OPENAI_API_KEY)tools = [{"type": "function","function": {"name": "send_email","description": "Send an email to the specified email with the subject and content","parameters":{"type": "object","properties": {"FromEmail": {"type": "string","description": "The email address, eg., rememeber0101@126.com",},"Subject": {"type": "string","description": "Subject of the email",},"Body": {"type": "string","description": "The content of the email",},"Recipients": {"type": "string","description": "The recipients' email addresses",}},"required": ["FromEmail", "Subject", "Body", "Recipients"],},}}
]def chat_completion_request(messages, tools=None, tool_choice=None, model=GPT_MODEL):try:response = client.chat.completions.create(model=model,messages=messages,tools=tools,tool_choice=tool_choice,)return responseexcept Exception as e:print("Unable to generate ChatCompletion response")print(f"Exception: {e}")return edef send_email(sender_email, sender_authorization_code, recipient_email, subject, body):# 创建 MIMEMultipart 对象message = MIMEMultipart()message["From"] = sender_emailmessage["To"] = recipient_emailmessage["Subject"] = subjectmessage.attach(MIMEText(body, "plain"))# 创建 SMTP_SSL 会话with smtplib.SMTP_SSL("smtp.126.com", 465) as server:server.login(sender_email, sender_authorization_code)text = message.as_string()server.sendmail(sender_email, recipient_email, text)def main():messages = []while True:msg = input("【You】: ")messages.append({"role": "user", "content": msg})response = chat_completion_request(messages=messages,tools=tools)print(response)if content := response.choices[0].message.content:print(f"【AI】: {content}")messages.append({"role": "assistant", "content": content})else:fn_name = response.choices[0].message.tool_calls[0].function.namefn_args = response.choices[0].message.tool_calls[0].function.arguments# print(f"【Debug info】: fn_name - {fn_name}")# print(f"【Debug info】: fn_args - {fn_args}")if fn_name == "send_email":try:args = json.loads(fn_args)# 返回将要发送的邮件内容给用户确认print("【AI】: 邮件内容如下:")print(f"发件人: {args['FromEmail']}")print(f"收件人: {args['Recipients']}")print(f"主题: {args['Subject']}")print(f"内容: {args['Body']}")confirm = input("AI: 确认发送邮件吗? (yes/no): ").strip().lower()if confirm == "yes":send_email(sender_email=args["FromEmail"],sender_authorization_code=AUTHORIZATION_CODE, recipient_email=args["Recipients"], subject=args["Subject"], body=args["Body"],)print("邮件已发送,还需要什么帮助吗?")messages.append({"role": "assistant", "content": "邮件已发送,还需要什么帮助吗?"})else:print("邮件发送已取消,还需要什么帮助吗?")messages.append({"role": "assistant", "content": "邮件发送已取消,还需要什么帮助吗?"})except Exception as e:print(f"发送邮件时出错:{e}")messages.append({"role": "assistant", "content": "抱歉,功能异常!"}) if __name__ == "__main__":main()# 帮我发送一封邮件 发件人: xxxxxxx@126.com, 收信人:xxxxxxx@qq.com, 发送内容:写着一封来自未来胖虎的问候邮件,主题:来自未来的问候
相关文章:
大模型function calling:让AI函数调用更智能、更高效
大模型function calling:让AI函数调用更智能、更高效 随着大语言模型(LLM)的快速发展,其在实际应用中的能力越来越受到关注。Function Calling 是一种新兴的技术,允许大模型与外部工具或API进行交互,从而扩…...
LeetCode:131. 分割回文串(DP Java)
目录 131. 分割回文串 题目描述: 实现代码与解析: 动态规划 原理思路: 131. 分割回文串 题目描述: 给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是 回文串 。返回 s 所有可能的分割方案。…...
计算机毕业设计SpringBoot+Vue.js贸易行业CRM系统(源码+文档+PPT+讲解)
温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…...
虚拟机中的指示命令
1. 复制文件:cp 源文件 目标文件(cp file1.txt file2.txt) 2. 复制文件夹:cp -r 源文件夹 目标文件夹(cp -r dir1 dir2) 3. 创建一个空的文件:touch file1.txt 4. 创建一个空目录&a…...
图像分类项目2:鸟类图像分类
1 数据集处理 1.1数据集下载 数据集来源:kaggle,网址:https://www.kaggle.com/,点击进入网站,左侧选择Datasets。 进入后搜索栏搜索关键词bird。此时出现很多数据集可以选择,推荐选择第一个或者第三个。…...
Redis数据结构-List列表
1.List列表 列表类型适用于存储多个有序的字符串(这里的有序指的是强调数据排列顺序的重要,不是升序降序的意思),列表中的每个字符串称为元素(element),一个列表最多可以存储2^32-1个元素。在R…...
启动你的RocketMQ之旅(三)-Producer启动和发送流程(上)
前言: 👏作者简介:我是笑霸final。 📝个人主页: 笑霸final的主页2 📕系列专栏:java专栏 📧如果文章知识点有错误的地方,请指正!和大家一起学习,一…...
Unity UGUI SuperScrollView介绍
先铺垫一下ScrollView Unity中常用的ScrollView 是 Unity 中的一个常见 UI 组件,主要用于创建可滚动的视图。当内容超过其显示区域时,ScrollView 可以让用户通过滚动查看全部内容。它通常包含一个显示区域和一个内容区域,内容区域可以超过显…...
pandas 数据透视表
数据的透视表 数据的透视表: 使用函数 pivot_table( ) # 引用pandas import pandas as pd # pivot_table 使用 pd.pivot_table(data,values,index,aggfunc,fill_value,columns)参数1:data DataFrame的源数据参数2:values 要进行聚合操作的列参数3:index 进行分组…...
【STM32安全性研究】STM32F103RCT6固件读取
最近从飞哥那买了个stm32固件提取器,效果很好。下面记录对某产品主控STM32F103RCT6固件的提取过程,说明提取时的注意事项。 注意本文的目的仅用于stm32安全性研究,不提供涉及产品本身的内容,包括固件、软件等。 stm32固件提取可参考论坛https://www.aisec.fraunhofer.de/en…...
塔子哥Python算法基础课
【入门题】【输入篇1】AB Problem 题目描述: 给定两个整数 A 和 B,请计算它们的和并输出结果。 输入: 输入包含一行,包含两个整数 A 和 B,以空格分隔。 输出: 输出一行,包含一个整数&#…...
C++ 内存管理:深入理解 new、malloc、delete 和 free
引言 在 C 中,内存管理是一个非常重要的主题。正确使用动态内存分配和释放工具(如 new、malloc、delete 和 free)可以避免内存泄漏和程序崩溃。本文将深入探讨这些工具的区别,并介绍池化计数技术。 1. new 与 malloc 在动态申请内…...
基于互联网协议的诊断通信(DoIP)
1、ISO 13400标准和其他汽车网络协议标准有何不同? ISO 13400 标准即 DoIP 协议标准,与其他常见汽车网络协议标准(如 CAN、LIN、FlexRay 等)有以下不同: 通信基础与适用场景 ISO 13400:基于互联网协议&a…...
Android15 am命令 APP安装流程
一. PM 安装命令 使用命令 pm install -r xxx.apk pm命令安装app 会触发PackageManagerShellCommand 中runInstall()方法 frameworks/base/services/core/java/com/android/server/pm/PackageManagerShellCommand.java1. onCommand 函数: public int onCommand(String cmd…...
SpringMVC学习(初识与复习Web程序的工作流程)(1)
目录 一、SpringMVC(框架)的简要概述。 (1)SpringMVC与Servlet。 (2)技术方向。 (3)最终学习目标。 二、Web程序的基本工作流程。 (1)工作流程。 <1>浏览器。前后端任务。 <…...
解锁网络防御新思维:D3FEND 五大策略如何对抗 ATTCK
D3FEND 简介 背景介绍 2021年6月22日(美国时间),美国MITRE公司正式发布了D3FEND——一个网络安全对策知识图谱。该项目由美国国家安全局(NSA)资助,并由MITRE的国家安全工程中心(NSECÿ…...
评估自动驾驶(AD)策略性能的关键指标
以下是针对自动驾驶(AD)策略性能评测指标的详细解读,结合其物理意义与工程价值: 核心评测指标分类与含义 1. 安全性指标(Safety) 动态碰撞率(Dynamic Collision Ratio, DCR) 定义&a…...
【领域】百度OCR识别
一、定义 OCR(Optical Character Recognition,光学字符识别)是计算机视觉重要方向之一。传统定义的OCR一般面向扫描文档类对象,现在我们常说的OCR一般指场景文字识别(Scene Text Recognition,STRÿ…...
Docker 学习(一)
一、Docker 核心概念 Docker 是一个开源的容器化平台,允许开发者将应用及其所有依赖(代码、运行时、系统工具、库等)打包成一个轻量级、可移植的“容器”,实现 “一次构建,随处运行”。 1、容器(Container…...
15. C++多线程编程-网络编程-GUI编程(如Qt)学习建议
1. 多线程编程 多线程编程允许程序同时执行多个任务,从而提高性能和响应速度。多线程常用于处理并发任务、提高CPU利用率、优化I/O操作等。 学习内容: 线程与进程的区别:理解线程和进程的基本概念及其区别。 线程的创建与管理:…...
【vscode-解决方案】vscode 无法登录远程服务器的两种解决办法
解决方案一: 查找原因 命令 ps ajx | grep vscode 可能会看到一下这堆信息(如果没有大概率不是这个原因导致) 这堆信息的含义:当你使用 vscode 远程登录服务器时,我们远程机器服务端要给你启动一个叫做 vscode serv…...
5个GitHub热点开源项目!!
1.自托管 Moonlight 游戏串流服务:Sunshine 主语言:C,Star:14.4k,周增长:500 这是一个自托管的 Moonlight 游戏串流服务器端项目,支持所有 Moonlight 客户端。用户可以在自己电脑上搭建一个游戏…...
化学工业领域 - 基础化工、精细化工、煤化工极简理解
引入 基础化工、精细化工和煤化工是化学工业中的三个重要分支 它们在原料、产品、工艺、应用方面各有特点 一、基础化工(Basic Chemical Industry) 1、基本介绍 基础化工是指以石油、天然气、煤炭等为原料,生产大宗化学品和基础化学原料的…...
慢sql治理
一、慢SQL的定义与影响 慢SQL通常指的是执行时间超过合理阈值的SQL语句。这个阈值可以根据系统的实际情况进行设定,例如1秒或更长。慢SQL会导致系统响应时间延迟、资源占用增加、数据库连接池被占满、锁竞争增加等一系列问题,严重影响系统的稳定性和用户…...
基于SpringBoot的美妆购物网站系统设计与实现现(源码+SQL脚本+LW+部署讲解等)
专注于大学生项目实战开发,讲解,毕业答疑辅导,欢迎高校老师/同行前辈交流合作✌。 技术范围:SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容:…...
计算机毕业设计Hadoop+Spark+DeepSeek-R1大模型音乐推荐系统 音乐数据分析 音乐可视化 音乐爬虫 知识图谱 大数据毕业设计
温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…...
mysql5.7离线安装及问题解决
这次主要是讲解mysql5.7离线安装教程和一主一从数据库配置 1、去官网下载自己对应的mysql https://downloads.mysql.com/archives/community/2、查看需要安装mysql服务器的linux的类型 uname -a第二步看一下系统有没有安装mysql rpm -qa|grep -i mysql3、上传安装包 用远程…...
Matlab 大量接单
分享一个matlab接私活、兼职的平台 1、技术方向满足任一即可 2、技术要求 3、最后 技术方向满足即可 MATLAB:熟练掌握MATLAB编程语言,能够使用MATLAB进行数据处理、机器学习和深度学习等相关工作。 机器学习、深度学习、强化学习、仿真、复现、算法、…...
C++数据结构之数组(详解)
1.介绍 在C中,数组是一种基本的数据结构,用于存储相同类型的元素的集合。数组的元素在内存中是连续存储的,可以通过索引访问。下面将详细介绍C数组的相关内容。 2.数组的定义 数组的定义需要指定元素的类型和数组的大小。 type arrayName[a…...
AWS API Gateway灰度验证实现
在微服务架构中,灰度发布(金丝雀发布)是验证新版本稳定性的核心手段。通过将小部分流量(如 10%)导向新版本服务,可以在不影响整体系统的情况下快速发现问题。AWS API Gateway 原生支持流量按比例分配功能,无需复杂编码即可实现灰度验证。本文将详细解析其实现方法、最佳…...
