生成式AI中的函数调用

2024/9/25 21:03:32

本文主要是介绍生成式AI中的函数调用,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

含义是什么 Function Calling 表示什么?

函数调用是指将大语言模型(LLM)可靠地连接到外部工具,以实现有效的工具使用和与外部API的交互。

大型语言模型(LLM)如 Llama、Mistral 或 GPT 模型经过微调,能够检测到何时需要调用函数,并输出包含调用函数所需参数的 JSON。通过函数调用所调用的函数将在您的 AI 应用程序中充当工具,并且您可以在单个请求中定义多个函数。

函数调用是构建基于大语言模型的聊天机器人或代理的重要能力,这些机器人或代理需要为大语言模型检索上下文或通过将自然语言转换为API调用来与外部工具交互。

功能调用使开发人员能够创建:

  • 能够高效使用外部工具回答问题的对话代理。例如,查询“1000美元等于多少土耳其里拉?”将被转换为类似 currency_converter(source_currency: string 'USD', target_currency: string 'TRY', amount: decimal '1000', when: datetime 'getdate()') 的函数调用。
  • 基于大语言模型的解决方案,用于从自然语言输入中提取和标记数据(例如,提取货币详情)
  • 可以帮助将自然语言转换为API调用或有效数据库查询的应用程序
  • 与知识库交互的对话式知识检索引擎

看来最近随着生成式人工智能出现的功能调用特性,可以逐渐应用于产品环境中。当我们查看伯克利功能调用排行榜时,你会发现大型语言模型能够以90%的成功率成功完成这一任务。

你可以轻松地在 watsonx.ai 环境中使用诸如 Mistral、Llama 和 Granite 在 Leaderboard 中的成功模型架构。以下我将一步步展示如何使用 watsonx.ai 提供端到端的解决方案。

使用RAG和Function Calling一起的优势

一种证明有效的大规模语言模型幻觉结果的技术是检索增强生成,或称为 RAG。RAG 可以使用一个接收器来搜索外部数据,在将提示发送给生成器(即 LLM)之前,用绑定来丰富提示。

关于RAG和Function Calling之间的关系,如果一个使用RAG方法的场景需要从外部环境中实时或当前的数据提供者获取数据,在将接收者通过向量相似性搜索找到的上下文发送到LLM模型之前,会创建一个服务来通过上下文功能调用来查询外部提供者的数据。这样,包含数据的上下文与实时和最新的外部数据结合,使其更加丰富和实用。

例如;你可以依赖大型语言模型(LLM)的能力,从向量数据库中构建绑定,在你的检索增强生成(RAG)应用程序中,从实时数据(如股票价格、订单跟踪、航班模式或库存管理)运行绑定性能的功能。这种集成的RAG及其功能范围的目的是通过现有数据源或实时API的绑定(使LLM能够访问正确的信息)来支持请求。

具有调用选项能力的LLM使AI工具能够自主执行某些任务。例如,这些能力使LLM能够通过熟悉其他API和系统的功能,自动化涉及数据检索、处理和分析的复杂工作流程。

功能调用用例

以下是一些可以从大型语言模型(LLM)的功能调用能力中受益的用例列表:

  • 对话代理:可以通过调用外部API或外部知识库来创建复杂的对话代理或聊天机器人,从而回答复杂的问题并提供更相关和有用的响应。
  • 自然语言理解:它可以将自然语言转换为结构化的JSON数据,从文本中提取结构化数据,并执行命名实体识别、情感分析和关键词提取等任务。
  • 数学问题解决:可以通过定义自定义函数来解决需要多个步骤和不同类型高级计算的复杂数学问题。
  • API集成:可以用来有效地将LLM与外部API集成,以根据输入获取数据或执行操作。这有助于构建问答系统或创意助手。通常,函数调用可以将自然语言转换为有效的API调用。
  • 信息提取:可以通过调用函数有效地从给定的输入中提取特定信息,例如从文章中检索相关新闻故事或引用。

在本指南中,我们将演示如何使用 watsonx.ai 平台提示 Mistral-Large-2 和其他第三方模型执行不同用例的功能调用。

集成第三方API与LLM模型创建支持生成式AI的财务助理/顾问示例

首先,我们必须详细定义我们想要调用的json对象。函数的描述参数在确定从所有定义的函数中选择哪个LLM模型时起着关键作用。在这里编写详细且可区分的描述非常重要。之后,当LLM在所有函数中调用此函数时,它会通过查看描述字段并使用类似零样本分类的方法来确定应该运行哪个函数。

此外,参数区域中每个参数的描述部分解释了如何找到正确的参数。为了做到这一点,LLM 可以通过使用实体提取方法,轻松地在传入的自然语言问题中找到诸如日期、数字、文本、地点、时间、金钱、人等对象,并将它们与正确的参数匹配。

通过这种方式,LLM 不仅能够利用零样本分类确定从功能列表中调用哪个函数,还能借助实体提取功能自动从输入的查询句子中提取所需的参数并将其设置为变量。

    {  
      "type": "function",  
      "function": {  
          "name": "finance_service",  
          "description": "财务顾问API提供所有金融需求和信息,包括金融指令、国际金融状态、资金交易、贷款、借方、银行操作等,您可以在该API中找到金融领域的所有内容",  
          "parameters": {  
              "type": "object",  
              "properties": {  
                  "startdate": {  
                      "type": "string",  
                      "description": "请求的交易开始日期或时间,格式为dd-MM-yyyy,这是一个必需参数,您必须找到并返回开始日期值。如果查询中不包含任何开始日期,您可以将开始日期设置为01-01-2024",  
                  },  
                  "enddate": {  
                      "type": "string",  
                      "description": "请求的交易结束日期或时间,格式为dd-MM-yyyy,这是一个必需参数,您必须找到并返回结束日期值。如果查询中不包含任何结束日期,您可以将结束日期设置为31-12-2024",  
                  },  
              },  
              "required": ["startdate"],  
              "required": ["enddate"]  
          },  
      },  
    }

在下一步中,我们将通过 ibm watsonx.ai-langchain SDK 访问平台,并为此需要从云环境中提供的参数,例如域名 URL、API 密钥、项目 ID 等。在从 IBM watsonx.ai 环境获取这些参数后,我们就可以在推理操作中使用 watsonx.ai 中的所有模型。

在这个场景中,我们将使用 mistral-large-2 模型来执行函数调用和实体提取操作。

        def 工具调用(self, categories, query) -> str:  
            response = ""  
            categories = categories  
            api_key=self.watsonx_ai_api_key  

            名称到函数 = {  
                    'financial-advisor': functools.partial(self.get_finance_advice),  
                }  

            messages = [  
                    ChatMessage(role="user", content=query)  
                ]  

            from langchain_ibm import WatsonxLLM  
            参数 = {  
                "decoding_method": "sample",  
                "max_new_tokens": 400,  
                "min_new_tokens": 1,  
                "temperature": 0.0,  
                "top_k": 20,  
                "top_p": 1,  
            }  

            客户端 = WatsonxLLM(  
                model_id="mistralai/mistral-large-latest",  
                url="<<cloud-watsonx.ai-base-url",  
                project_id="<<watsonx.ai-project-id>>",  
                apikey= api_key,  
                params=参数,  
            )  
            response = 客户端.chat(messages=messages, tools=self.tools, tool_choice="auto")  
            messages.append(response.choices[0].message)  
            工具调用 = response.choices[0].message.tool_calls[0]  
            函数名称 = 工具调用.function.name  
            函数参数 = json.loads(工具调用.function.arguments)  
            if self.validate_input(函数参数):  
                print("\n函数名称: ", 函数名称, "\n函数参数: ", 函数参数)  
                函数结果 = 名称到函数[函数名称](https://medium.com/**函数参数)  
                messages.append(ChatMessage(role="tool", name=函数名称, content=函数结果["content"], tool_call_id=工具调用.id))  
                response = 客户端.chat(model=model, messages=messages)  
            else:  
                raise ValueError("无效的输入参数")  
            return response.choices[0].message.content

准备的提示如下。这是我们的提示,旨在找出相关问题想要表达的内容及其所属的类别。在收到相关值后,此提示会查询第三方机构的API,并返回机构提供的类别值,这些值将被存储,用于最终发送给机构的查询。

        def prompt_generator(self, question, table) -> str:  
            prompt_category_detection = """你是一名财务专家,任务是分析以下财务句子,并从指定的表格中选择最相关的标题。请按照以下步骤操作:  
        **检索相关数据**:从识别的表格中找到与句子内容最匹配的财务主题和财务类别。  
        **财务句子:**  
        "{question}"  
        **字典:**  
        {table}  
        **说明:**  
        - 从字典中确定正确的表格。  
        - 使用该表格找到与财务句子最相关的财务主题和财务类别值。  
        - 确保检索到的值是与句子内容的最佳匹配。  
        **结论:**  
        请以以下格式提供结果,仅返回以下信息,不要添加任何其他单词或句子,仅以JSON对象格式给出答案,仅以以下格式返回答案,不要使用其他格式:  
        {{"category": "找到的类别", "id": 类别_id}}  
        """  
            return prompt_category_detection.format(question=question, table=table)

类别服务调用如下进行,并将响应存储在变量中,以便发送POST请求到主服务。

    def _解析用户查询(self, user_query: str) -> str:  
            category_prompt = self.prompt_generator(question=user_query, table=self.categories)  
            category_response = self.model.invoke(category_prompt)  
            category_json = json.loads(category_response.content)  
            print("从LLM零样本分类中找到的值:", category_json)  
            category_id = category_json["id"]  
            return category_json.content

使用从第一个服务返回的类别以及通过实体提取从问题中提取的开始日期和结束日期参数,LLM 自动调用以下函数。在进行此调用时,相关函数在代码的其他地方不会被调用。

     def 获取财务建议(self, startdate, enddate) -> Dict:  
            full_category_codes = ""  
            for cin self.category_codes:  
                full_category_codes += c["code"] + "-"  
            base_url = '<<third-party-api-base-uri' + full_category_codes +'&startDate='+ startdate +'&endDate='+ enddate  
            response = requests.get(base_url+'&type=json', headers=headers)  
            print(response.content)  
            return {  
                "状态码": response.status_code,  
                "内容": response.content  
            }
基于大语言模型的金融建议系统解决方案架构

该基于生成AI的金融推荐系统的解决方案架构非常成功地从端到端运行,其架构如下。系统通过界面或API接收用户的查询,并通过SDK将其发送到后台的watsonx.ai环境中。之后,watsonx.ai使用其基础模型库中的Mistral-Large-2模型查询传入的查询,并确定将在第4步中使用的功能然后,在第5步中确定的功能内执行实体提取,找到并发送时间相关的参数(如开始和结束日期)到变量。在这里,大型语言模型使用零样本分类功能来找到正确的功能,然后使用实体提取从自然语言查询句子中找到正确的参数。

在下一步中,LLM 会调用嵌入在 watsonx.ai 中的目录来调用正确的函数,并通过 Python 启动对该函数的调用。在调用过程中,还需要进行另一次分类过程来查找相关的目录信息。为此,我们通过 SDK 将 gpt-4o-mini 模型集成到 watsonx.ai 中,并利用其在表格数据上的分类能力。我们在这里使用 gpt-4o-mini 的原因是,与其他模型架构(如 mistral 和 llama)相比,该模型在表格数据的零样本分类等任务中更为成功,并且始终能给出相同的结果。另一个原因是展示 watsonx.ai 环境可以通过 SDK 访问不同云或其它环境中的模型,而不仅仅是其自身的模型服务器中的模型。

在完成所有这些工作的同时,我们充分利用了langchain在每一步中的能力。在LLM推理操作(如2、3和4所示)中对表格数据进行分类操作后,现在使用watsonx.ai及其所有获取的参数调用了服务。

服务返回的值。在最后一步,它被发送回watsonx.ai中的mistral-large-2模型,并要求该模型结合从机构接收的服务数据,生成对问题的适当回答。 如下所示,所有过程的分步输出和watsonx.ai生成的LLM回答都列出来了。

最后,通过执行文本生成来完成整个过程。通过发送5个独立的推理请求到大语言模型,满足了3个不同任务(零样本分类、实体提取、文本生成)在两个不同模型中的需求。

你可以这样理解系统和模型的输出。

测试结果:

问题1:2024年5月英镑对土耳其里拉的最高汇率是多少?

来自LLM分类和实体提取的分类结果:

    {'类别': '汇率', 'id': 35}  
    [{'名称': '(GBP) 英镑 (买入外币价格)', '代码': 'EN-POUND-BUY'}, {'名称': '(GBP) 英镑 (外币卖出)', '代码': 'EN-POUND-SALE'}]

函数参数,LLM 使用实体提取功能获取这些参数:

    {'startdate': '2024-01-05', 'enddate': '2024-05-31'}

文本生成结果来自LLM,在这一步中,LLM使用API响应体中的值

来自Watsonx.ai的回答 = “2024年5月,英镑兑土耳其里拉的最高汇率为41.2021 TRY”

问题2:根据最新数据,非居民投资组合中的股票和债务证券的年度变化率是多少?

来自LLM分类和实体提取的分类结果:

    {'类别': '国际投资头寸', 'id': 36}  
    {'名称': '境外居民投资组合中的股票和债务证券', '代码': 'stock_and_debt_external_citizens'}  
    [{'名称': '海外银行存款', '代码': 'bank_overseas_deposits'}, {'名称': '银行外汇存款账户', '代码': 'Bank_Foreign_Exchange_Deposits'}]

函数参数,LLM 使用实体提取功能获取这些参数:

    {'startdate': '2024-01-01', 'enddate': '2024-12-31'}

从LLM生成的文本结果,在这一步中,LLM使用API响应体中的值

来自Watsonx.ai的回答 = “非居民投资组合中的股票和债务证券的年度变化率为5.7%。”

问题3:2023年在航空和住宿业通过借记卡和信用卡支出的总额占借记卡和信用卡总支出的百分比是多少?

来自LLM分类和实体提取的分类结果:

    {'分类': '银行和信用卡部门支出统计', 'id': 77}  
    {'名称': '借记卡和信用卡消费金额', '代码': 'debit_credit_sp'}  
    [{'名称': '航空公司', '代码': 'trx-airlines-fnc'}, {'名称': '住宿', '代码': 'trx-accom-fnc'}]

函数参数,LLM 使用实体提取功能获取这些参数:

    {'startdate': '2023-01-01', 'enddate': '2023-12-31'}

文本生成结果来自LLM,在这一步中,LLM使用API响应体中的值

来自Watsonx.ai的回答 = “在2023年,借记卡和信用卡总支出中有10.5%用于航空和住宿行业。总支出金额为199,384,100土耳其里拉。”

此外,我们的 Mistral 官方网站上还提供了一个详细讲解如何使用我们在 watsonx.ai 中使用的 mistral-large-2 模型进行函数调用的培训视频。我们所做的就是通过 langchain 设置服务调用或 RAG 结构,使用 watsonx.ai 中的 Mistral 模型。

我也想感谢所有我的队友,Seray Boynuyoğun,Ceyda Hamurcu,Bengü Sanem Pazvant,Merve Özmen,Yunus Emre Emik 和 Ahmet Sait Çelik,他们作为IBM土耳其客户端工程团队的一员,为这项工作做出了贡献。没有团队是无法做到这一点的。一个团队!!



这篇关于生成式AI中的函数调用的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程