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

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

5e5a6b93-1b1f-425a-b01d-d15e85720563

随着大语言模型(LLM)的快速发展,其在实际应用中的能力越来越受到关注。Function Calling 是一种新兴的技术,允许大模型与外部工具或API进行交互,从而扩展了模型的功能边界。本文将深入探讨 Function Calling 的原理、应用场景以及如何通过优化实现更智能、高效的函数调用。

1. 什么是 Function Calling?

unction Calling 是一种机制,允许大语言模型动态调用外部函数或API,以完成特定任务。例如,当用户提问“今天的天气如何?”时,模型可以通过调用天气API获取实时数据并返回结果。这种方式不仅提升了模型的实用性,还使其能够处理复杂的多步骤任务。

  • 关键特点:
    • 动态调用:根据用户需求调用合适的函数。
    • 上下文感知:结合对话上下文选择最佳函数。
    • 扩展性强:支持多种API和服务集成。

2. Function Calling 的核心原理

workflow

  1. 用户输入问题或指令。
  2. 模型分析输入,生成 JSON 格式的函数调用请求。
  3. 后端解析请求,调用对应函数或API。
  4. 将函数返回的结果传递回模型。
  5. 模型基于结果生成最终回答。

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, 发送内容:写着一封来自未来胖虎的问候邮件,主题:来自未来的问候

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/27095.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

通过 PromptTemplate 生成干净的 SQL 查询语句并执行SQL查询语句

问题描述 在使用 LangChain 和 Llama 模型生成 SQL 查询时,遇到了 sqlite3.OperationalError 错误。错误信息如下: OperationalError: (sqlite3.OperationalError) near "sql SELECT Name FROM MediaType LIMIT 5; ": syntax error [SQL: …

计算机毕业设计SpringBoot+Vue.js企业资产管理系统(源码+文档+PPT+讲解)

温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…

从零开始:H20服务器上DeepSeek R1 671B大模型部署与压力测试全攻略

前言 最近,我有幸在工作中接触到了DeepSeek R1 671B模型,这是目前中文开源领域参数量最大的高质量模型之一。DeepSeek团队在2024年推出的这款模型,以其惊人的6710亿参数量和出色的推理性能,引起了业界广泛关注。 作为一名AI基础…

Qt 文件操作+多线程+网络

文章目录 1. 文件操作1.1 API1.2 例子1,简单记事本1.3 例子2,输出文件的属性 2. Qt 多线程2.1 常用API2.2 例子1,自定义定时器 3. 线程安全3.1 互斥锁3.2 条件变量 4. 网络编程4.1 UDP Socket4.2 UDP Server4.3 UDP Client4.4 TCP Socket4.5 …

计算机毕业设计SpringBoot+Vue.js公司日常考勤系统(源码+文档+PPT+讲解)

温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…

基于单片机的智能宿舍管理系统(论文+源码)

2.1总体方案设计 本课题为智能宿舍的设计,整个系统架构如图2.1所示,整个系统在器件上包括了主控制器STM32单片机,LD3320语音识别模块,按键模块,串口通信模块,照明模块,窗帘控制模块家电控制模块…

弱监督语义分割学习计划(2)-使用CoT进行Open Vocabulary Label简单实现类激活图

零: 项目说明 是这样的一个事情,经过与deepseek的一番讨论和交流,DeepSeek为我设计了一个30天高强度学习计划,重点聚焦弱监督/无监督语义分割在野外场景的应用,结合理论与实践,并最终导向可落地的开源项目。目前开始了…

RabbitMQ操作实战

1.RabbitMQ安装 RabbitMQ Windows 安装、配置、使用 - 小白教程-腾讯云开发者社区-腾讯云下载erlang:http://www.erlang.org/downloads/https://cloud.tencent.com/developer/article/2192340 Windows 10安装RabbitMQ及延时消息插件rabbitmq_delayed_message_exch…

力扣27.移除元素(双指针)

题目看起来很乱&#xff0c;实际上意思是&#xff1a;把数组中值不等于val的元素放在下标为0,1,2,3......&#xff0c;并且返回数组中值不等于val的元素的个数 方法一&#xff1a;直接判断覆盖 class Solution { public:int removeElement(vector<int>& nums, int…

【弹性计算】弹性裸金属服务器和神龙虚拟化(二):适用场景

弹性裸金属服务器和神龙虚拟化&#xff08;二&#xff09;&#xff1a;适用场景 1.混合云和第三方虚拟化软件部署2.高隔离容器部署3.高质量计算服务4.高速低时延 RDMA 网络支持场景5.RISC CPU 支持6.GPU 性能无损输出 公共云服务提供商推出 弹性裸金属服务器&#xff0c;很显然…

深入解析 Spring WebFlux:原理与应用

优质博文&#xff1a;IT-BLOG-CN WebFlux 是 Spring Framework 5 引入的一种响应式编程框架&#xff0c;和Spring MVC同级&#xff0c;旨在处理高并发和低延迟的非阻塞应用。这是一个支持反应式编程模型的新Web框架体系。 顺便一提&#xff0c;Spring Cloud Gateway在实现上是…

命名管道的实现与共享内存介绍

1.命名管道实现 comm.hpp文件 1.定义宏 通过宏来简便代码中&#xff0c;判断错误用宏就可以少写代码。 #define ERR_EXIT(m) \do \{ \perror(m); \exit(EXIT_FAILURE); \} while (0)在宏定义中使用 do { ... …

Window下Redis的安装和部署详细图文教程(Redis的安装和可视化工具的使用)

文章目录 Redis下载地址&#xff1a;一、zip压缩包方式下载安装 1、下载Redis压缩包2、解压到文件夹3、启动Redis服务4、打开Redis客户端进行连接5、使用一些基础操作来测试 二、msi安装包方式下载安装 1、下载Redis安装包2、进行安装3、进行配置4、启动服务5、测试能否正常工…

哔哩哔哩IT私塾python爬虫视频教程中的项目文件

视频链接&#xff1a; Python课程天花板,Python入门Python爬虫Python数据分析5天项目实操/Python基础.Python教程_哔哩哔哩_bilibili 视频教程中要访问的链接&#xff1a; 豆瓣电影 Top 250 httpbin.org seo推广公司网站模板_站长素材 Examples - Apache ECharts WordCloud…

go前后端开源项目go-admin,本地启动

https://github.com/go-admin-team/go-admin 教程 1.拉取项目 git clone https://github.com/go-admin-team/go-admin.git 2.更新整理依赖 go mod tidy会整理依赖&#xff0c;下载缺少的包&#xff0c;移除不用的&#xff0c;并更新go.sum。 # 更新整理依赖 go mod tidy 3.编…

深入理解Spring @Async:异步编程的利器与实战指南

一、为什么需要异步编程&#xff1f; 在现代高并发系统中&#xff0c;同步阻塞式编程会带来两大核心问题&#xff1a; // 同步处理示例 public void processOrder(Order order) {// 1. 保存订单&#xff08;耗时50ms&#xff09;orderRepository.save(order); // 2. 发送短信…

PHP:IDEA开发工具配置XDebug,断点调试

文章目录 一、php.ini配置二、IDEA配置 一、php.ini配置 [xdebug] zend_extension"F:\wamp64\bin\php\php7.4.0\ext\php_xdebug-2.8.0-7.4-vc15-x86_64.dll" xdebug.remote_enable on xdebug.remote_host 127.0.0.1 xdebug.remote_port 9001 xdebug.idekey"…

FPGA开发,使用Deepseek V3还是R1(9):FPGA的全流程(详细版)

以下都是Deepseek生成的答案 FPGA开发&#xff0c;使用Deepseek V3还是R1&#xff08;1&#xff09;&#xff1a;应用场景 FPGA开发&#xff0c;使用Deepseek V3还是R1&#xff08;2&#xff09;&#xff1a;V3和R1的区别 FPGA开发&#xff0c;使用Deepseek V3还是R1&#x…

AtCoder Beginner Contest 001(A - 積雪深差、B - 視程の通報、C - 風力観測、D - 感雨時刻の整理)题目翻译

由于我发现网上很少有人会发很久之前AtCoder Beginner Contes的题&#xff0c;所以我打算从AtCoder Beginner Contest 001开始写。大约两周一更&#xff0c;需要的可以订阅专栏&#xff0c;感谢支持Thanks♪(&#xff65;ω&#xff65;)&#xff89; →题目讲解 A - 積雪深差 …

upload

&#xff08;上传一句话木马&#xff0c;用蚁剑链接验证是否成功/传有回显的&#xff1a;<?php phpinfo();?>&#xff09; 学看代码 #function checkfile(){}&#xff1a;定义了一个名叫checkfile的函数 #var file方法.(获取名为‘upload_file’的元素)[获取哪些&…