您当前的位置:首页 > 电脑百科 > 人工智能

大语言模型插件功能在携程的Python实践

时间:2024-01-26 12:47:25  来源:携程技术  作者:

作者简介

成学,携程高级安全研发工程师,关注Python/ target=_blank class=infotextkey>Python/Golang后端开发、大语言模型等领域。

一、背景

2023年初,科技圈最火爆的话题莫过于大语言模型了,它是一种全新的聊天机器人模型,除了能应对基本的日常聊天外,还能胜任如文案编写、旅游规划等各项工作。

携程信息安全部也紧跟时代步伐,在携程内部推出基于大语言模型的智能聊天机器人,并发布网页版1.0,让所有“程里人”可以便捷无门槛地享受大语言模型带来的便利。在运营半年多后,我们广泛收集了用户的使用感受以及建议,结合当下大语言模型的发展进程,新推出了网页版2.0,相较于1.0版本,简化了页面展示,增加了历史会话保存、自定义对话设置、支持插件、AI绘图等功能。

其中插件功能可以扩展大语言模型的个性化能力,让其如虎添翼,开发者可以根据特定需求定义特定插件供用户使用。目前网页版2.0版本支持10多种插件,如google搜索插件可以对输入的问题进行联网查询;Base64插件可以对Base64内容进行解密等。那么这些插件是如何实现的呢?让我们一探究竟吧。

二、需求调研

2.1 Function Calling

目前多个大语言模型都推出了Function Calling(函数调用)能力,用于帮助开发者通过 API 方式实现类似于插件的能力。通过Function Calling,我们可以将多个自定义的函数描述连同提出的问题一起传给大语言模型,它会分析这些函数描述与提问内容的相关性,并将最相关的函数及对应的函数传参一起返回,我们再执行函数对应的业务逻辑,即可得到问题的答案。

Function Calling的大体使用流程如下:

图片

举个例子,我们的问题是“今天上海天气如何”,大语言模型本身不能联网,不知道当前上海的天气信息,但是按照Function Calling的使用步骤,我们可以回答这个问题:

  • 我们可以事先在应用服务端定义一个查询天气的函数,函数描述为“查询某时某地的天气情况”,函数传参为“日期”和“地点”,在函数内部编写具体查询天气的代码,如从气象局网站获取对应的天气信息。
  • 除此之外,我们还可以定义一些其他自定义的函数,如base65加解密函数、ip信息查询函数等。
  • 在调用大语言模型的API时,将这些定义的函数按照api规范连同问题“今天上海天气如何”一起传给模型。
  • 通常情况下模型会返回和问题相匹配的函数,即查询天气的函数,同时返回函数传参“今天”和“上海”。
  • 根据这个返回内容,我们再实际调用查询天气的函数,获取到天气信息。
  • 最后将天气信息返回给用户。

由此可以看出Function Calling(函数调用)的本质就是利用大语言模型的文字分析能力,在提供的一系列函数中,找出能够回答问题的最合适的函数,函数内部的具体逻辑则交给开发者自己实现,而不是大语言模型实现。

再进一步分析可以发现,如果没有Function Calling,其实通过prompt提示我们也可以实现Function Calling的功能,例如prompt类似于“我有一些函数,定义为xxxx,我想知道“今天上海天气如何”,请告诉我用哪个函数可以解答这个问题,并告诉我函数的传参“。当然这个prompt效果并不一定很好,每个人的prompt也不尽相同,那么Function Calling这个功能就应运而生了,针对这种场景进行调优并规范了函数的定义和返回格式,方便了开发者的使用。

2.2 如何实现异步

在定义插件时,有一些插件如Ping插件、IP扫描插件等,由于网络耗时或执行本身比较慢,提问后无法立马返回结果,所以需要使用异步的方式,等后台服务执行完成后,再把结果返回给前端。对于这种场景,我们需要主动向前端推送消息,常用的方法就是使用WebSocket。

WebSocket是从html5开始提供的一种浏览器与服务器进行全双工通讯的网络技术,它的目的是在浏览器和服务器之间建立一个不受限的双向通信的通道。比如说,服务器可以在任意时刻发送消息给浏览器。它不是一种全新的协议,而是利用了HTTP协议来建立连接,属于应用层协议。

它具有如下优点:

  • 支持双向通信,实时性更强
  • 更好的二进制支持
  • 较少的控制开销。连接创建后,ws客户端、服务端进行数据交换时,协议控制的数据包头部较小。在不包含头部的情况下,服务端到客户端的包头只有2~10字节(取决于数据包长度),客户端到服务端的的话,需要加上额外的4字节的掩码。而HTTP协议每次通信都需要携带完整的头部
  • 支持扩展。ws协议定义了扩展,用户可以扩展协议,或者实现自定义的子协议(比如支持自定义压缩算法等)

除了WebSocket,我们还可以选择使用socketIO。Socket.IO也可以实现客户端和服务段之间双向通信。但与WebSocket不同的是,socketIO是一个第三方库,他具有WebSocket的基本功能,同时也增强了一些的功能。比如:

  • 兼容性:WebSocket是HTML5标准中的一部分,需要浏览器支持HTML5才能使用,而Socket.IO是基于WebSocket协议的封装,可以在不支持WebSocket的浏览器上使用
  • API:WebSocket只提供了底层的API,需要开发者自己实现消息的编解码、心跳等功能,而Socket.IO提供了更高层次的API,封装了消息的编解码、心跳等功能,使用更加方便
  • 处理异常:WebSocket在连接异常时会直接断开连接,而Socket.IO的心跳机制会尝试重新连接,提高了连接的稳定性
  • 支持的协议:WebSocket只支持单一的协议,而Socket.IO支持多种协议,包括WebSocket、Flash Socket、AJAX长轮询等
  • HTTP 长轮询回退:如果无法建立 WebSocket 连接,连接将回退到 HTTP 长轮询

但需要强调的是:Socket.IO与WebSocket并不能兼容,尽管 Socket.IO 确实在可能的情况下使用 WebSocket 进行传输,但它为每个数据包添加了额外的元数据。因此WebSocket客户端将无法成功连接到Socket.IO服务器,而Socket.IO客户端也将无法连接到普通WebSocket服务器。

socketIO服务连接时,可以在f12中看到连接的过程:

图片

总共分为5步:

  • 客户端发起握手请求(GET),服务端返回本次连接的前置基础信息
{
      "sid": "FSDjX-WRwSA4zTZMALqx",  // 会话的ID,它必须包含在后续所有HTTP请求的查询参数中
      "upgrades": ["websocket"],  // 数组包含服务器支持的所有“更好”传输的列表
      "pingInterval": 25000,  // 心跳检测时间,25秒
      "pingTimeout": 20000  // # 心跳超时时间,20秒
  }
  • 客户端带上sid(POST),长轮询,发送连接请求
  • 客户端带上sid(GET),长轮询,获取连接确认
  • 升级建立WebSocket连接,响应码为101,且一直处于连接状态
  • 客户端接收数据 (GET),长轮询,WebSocket连接建立成功后关闭

三、 基本实现

以下实现案例基于国内开源大语言模型ChatGLM3,ChatGLM3 是智谱AI和清华大学 KEG 实验室联合发布的对话预训练模型。

3.1 定义各种插件

根据ChatGLM3模型的插件规范,定义插件的相关信息,这里举2个例子,Google搜索(同步插件)、Ping(异步插件)。

all_plugins = {
    "google": {
        "name_cn": "谷歌搜索",  # 中文名称
        "sync": True,  # 是否同步执行
        "message": "{result}",  # 返回给用户的消息
        # info内容为符合ChatGLM3 function call规范的函数定义
        "info": {
            "name": "google",  # 函数名
            "description": "当问题需要进行实时搜索(如今天的日期或者今天的天气等)时, 或者无法回答时, 使用 google 搜索",  # 函数描述
            "parameters": {
                "type": "object",
                "properties": {
                    "keyword": {  # 传参参数名
                        "type": "string",  # 参数数据类型
                        "description": "搜索的关键词"  # 参数描述
                    }
                },
                "required": ["keyword"]  # 必填参数
            }
        }
    },
    "ping": {
        "name_cn": "ping",
        "sync": False,
        "message": "使用ping插件,由于该任务执行时间比较长,完成后我会主动将结果发送给您。请耐心等待。如果您有其他问题,可以继续提问。",
        "info": {
            "name": "ping",
            "description": "使用ping工具对IP地址进行ping测试",
            "parameters": {
                "type": "object",
                "properties": {
                    "addr": {
                        "type": "string",
                        "description": "被ping的ip或者域名"
                    }
                },
                "required": ["addr"]
            }
        }
    }
}

定义插件对应的函数实现:

class Functions:
    @classmethod
    def ping(cls, **kwargs):
        """ping实现"""
        # 省略ping的代码实现
        pass


    @classmethod
    def google(cls, **kwargs):
        """google搜索实现"""
        # 查询关键字
        keyword = kwargs['keyword']
        # 搜索结果
        search_context = []
        # 使用google api搜索
        res = server['service'].cse().list(q=keyword, cx=server['cx'], ).execute()
        # 遍历搜索结果
        for row in res.get('items', []):
            # 提取每条搜索结果的简要信息
            search_context.Append(row['snippet'])
        # 汇总搜索结果和问题组成prompt
        prompt = [{"role": "user", "content": f"请结合以下内容,回答问题:{keyword}n" + "n".join(search_context)}]
        # 调用大语言模型生成答案
        return reply_text(prompt)

3.2 使用Function Calling实现插件功能

大体逻辑为:将插件信息和用户提问一起发送给大语言模型的API,得到与之匹配的插件,再调用插件对应的函数,得到结果返回给用户。以下代码为简化的ChatGLM3示例代码:

import torch
from transformers import AutoTokenizer, AutoModel


def main():
    """使用插件时回复文字"""
    DEVICE = 'cuda' if torch.cuda.is_available() else 'cpu'
    tokenizer = AutoTokenizer.from_pretrained('/home/chatglm3-6b', tRust_remote_code=True)
    model = AutoModel.from_pretrained('/home/chatglm3-6b', trust_remote_code=True).to(DEVICE).eval()
    # 汇总所有的插件信息
    tools = [plugin['info'] for plugin in all_plugins.values()]
    # 将插件信息设置在对话历史中
    history = [{"role": "system", "content": "Answer the following questions as best as you can. You have access to the following tools:", "tools": tools}]
    # 调用function calling
    response, _ = model.chat(tokenizer, query, history=history)
    # 获取匹配的插件名称
    plugin_name = response.get("name", "")
    # 获取匹配的插件参数
    arguments = response.get("parameters", {})
    # 没有匹配到插件则退出
    if not plugin_name:
        return None
    # 获取插件完整信息
    plugin = all_plugins[plugin_name]
    # 使用反射机制获取插件对应的函数对象
    func = getattr(Functions, plugin_name)
    # 执行函数并返回结果
    res = func(**arguments)
    return res

3.3 异步插件的实现

本项目Web后端使用的框架为flask,使用socketIO实现异步交互,需要安装对应的库:flask_socketio,启动时,在flask的app上使用SocketIO包装一下即可,这样在同一个端口上同时开启了http服务和socketIO服务,下面只展示基本关键代码:

from flask import Flask
from flask_socketio import SocketIO


# flask原始 app
web_app = Flask(__name__, static_folder=Config.STATIC_PATH)


# socketIO包装app
socketio = SocketIO(web_app, cors_allowed_origins="*", logger=True)


# 可监听连接和断开
@socketio.on('connect')
def handle_connect():
    print("connect")


@socketio.on('disconnect')
def handle_disconnect():
    print("disconnect")


# 本地启动app
if __name__ == '__main__':
    socketio.run(web_app, address, port, allow_unsafe_werkzeug=True)

在socketIO中调用emit(event, *args, **kwargs)方法即可给指定目标(event,本项目对应为user)发送消息。

我们通过function calling获取到对应插件时,如果是同步插件,则立即执行对应函数,如果是异步插件,应该异步开启执行对应函数,并立马结束当前会话,等异步函数执行完成后主动发送消息给前端用户,因此我们需要修改一下上面的插件代码:

def main(user, question):
    """使用插件时回复文字"""
    ...代码同上
    # 使用反射机制获取插件对应的函数对象
    func = getattr(Functions, plugin_name)
    # 判断插件是否同步
    if plugin['sync']:
        # 同步的插件,直接调用函数
        res = func(**arguments)
    else:
        # 异步的插件,这里使用线程池示例执行异步任务
        thread_pool = ThreadPool(3)
        
        # 定义回调函数, 接收到结果后推送给前端
        def callback(result):
            # 推送给前端
            socketio.emit(user, f"任务结果为: {result}")


        # 异步调用
        res = thread_pool.apply_async(func, kwds=arguments, callback=callback)
    return res

四、 未来规划

4.1 更多的插件

上述插件案例只是插件功能的冰山一角,通过该功能我们可以定义各种实用的插件,目前携程信息安全部的大语言模型智能聊天机器人只是支持一些基本的插件,也欢迎大家给我们提出宝贵的建议,集思广益,一起开发出更多实用好用的插件。

4.2 每个用户的自定义插件

目前的插件功能可以支持我们这些项目的开发者实现自定义插件,这些插件也必须提前写入项目中,并不能支持终端用户直接自定义自己的插件。后续我们会调研可行性方案,让终端的用户自己编写对应的插件代码,实现每个用户都能定义自己的插件。



Tags:大语言模型   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除。
▌相关推荐
大语言模型插件功能在携程的Python实践
作者简介成学,携程高级安全研发工程师,关注Python/Golang后端开发、大语言模型等领域。一、背景2023年初,科技圈最火爆的话题莫过于大语言模型了,它是一种全新的聊天机器人模型,...【详细内容】
2024-01-26  Tags: 大语言模型  点击:(2)  评论:(0)  加入收藏
面向超长上下文,大语言模型如何优化架构,这篇综述一网打尽了
ChatGPT 的诞生,让基于 Transformer 的大型语言模型 (LLM) 为通用人工智能(AGI)铺开了一条革命性的道路,并在知识库、人机交互、机器人等多个领域得到应用。然而,目前存在一个普...【详细内容】
2024-01-03  Tags: 大语言模型  点击:(20)  评论:(0)  加入收藏
大语言模型真的需要这么多层吗?
研究表明,移除70% 的注意力头和 20% 的前馈网络对上下文学习影响甚微,这暗示大语言模型或许训练得不够充分。本文经授权转载宝玉老师的个人博客(微博@宝玉xp ),链 接https://ba...【详细内容】
2023-12-19  Tags: 大语言模型  点击:(24)  评论:(0)  加入收藏
大语言模型量化方法对比:GPTQ、GGUF、AWQ
在过去的一年里,大型语言模型(llm)有了飞速的发展,在本文中,我们将探讨几种(量化)的方式,除此以外,还会介绍分片及不同的保存和压缩策略。说明:每次加载LLM示例后,建议清除缓存,以防...【详细内容】
2023-11-17  Tags: 大语言模型  点击:(169)  评论:(0)  加入收藏
SEO中的大语言模型量化方法
随着互联网的快速发展,搜索引擎优化(SEO)已经成为了企业提升网站流量和排名的重要手段。在SEO的过程中,大语言模型量化方法被广泛应用,以帮助企业更好地理解搜索引擎的工作原理,并...【详细内容】
2023-11-16  Tags: 大语言模型  点击:(104)  评论:(0)  加入收藏
大语言模型数据泄露堪忧,超自动化Agent成解决之道
文/王吉伟阻碍广大企业应用大语言模型(LLM,Large Langeuage Models)的诸多因素中,无疑数据安全是最重要的。3月份ChatGPT发生了用户隐私数据泄露事件,OpenAI声明由于开源代码库中...【详细内容】
2023-11-15  Tags: 大语言模型  点击:(105)  评论:(0)  加入收藏
无限上下文,多级内存管理!突破ChatGPT等大语言模型上下文限制
目前,ChatGPT、Llama 2、文心一言等主流大语言模型,因技术架构的问题上下文输入一直受到限制,即便是Claude 最多只支持10万token输入,这对于解读上百页报告、书籍、论文来说非常...【详细内容】
2023-11-02  Tags: 大语言模型  点击:(141)  评论:(0)  加入收藏
十个2023年最具影响力的开源大语言模型
由于大型语言模型(LLM)的崛起,2023年被认为是开源领域的关键一年。下面精心挑选了一些在2023年上半年掀起波澜的最有影响力的模型。这些模型几乎可以与band、GPT-3.5、GPT4、Cl...【详细内容】
2023-10-13  Tags: 大语言模型  点击:(254)  评论:(0)  加入收藏
引入大语言模型、首个支持国产算力生态,全新开源RL框架RLLTE来了
近年来,强化学习的研究热度不断攀升,在智能制造、自动驾驶、大语言模型等多个领域取得了耀眼成绩,展示出巨大的研究潜力。然而,强化学习算法高效、可靠的工程实现仍是长期存在的...【详细内容】
2023-10-12  Tags: 大语言模型  点击:(256)  评论:(0)  加入收藏
在本地运行大语言模型的五种简便方法
译者 | 陈峻审校 | 重楼现如今,像ChatGPT、以及phind之类基于AI的聊天机器人,已经能够为我们生活的方方面面提供各种帮助了。但是,您可能并不总是希望由外部应用程序来处理您提...【详细内容】
2023-10-11  Tags: 大语言模型  点击:(222)  评论:(0)  加入收藏
▌简易百科推荐
简易百科之什么是大型语言模型?
简易百科之什么是大型语言模型?随着人工智能技术的不断发展,语言模型在自然语言处理领域的应用越来越广泛。大型语言模型作为其中的一种重要类型,受到了广泛的关注和研究。那么...【详细内容】
2024-01-26    简易百科  Tags:大型语言模型   点击:(7)  评论:(0)  加入收藏
大语言模型插件功能在携程的Python实践
作者简介成学,携程高级安全研发工程师,关注Python/Golang后端开发、大语言模型等领域。一、背景2023年初,科技圈最火爆的话题莫过于大语言模型了,它是一种全新的聊天机器人模型,...【详细内容】
2024-01-26    携程技术  Tags:大语言模型   点击:(2)  评论:(0)  加入收藏
ChatGPT元年之后,AI重塑世界,人类如何与其“智慧共生”?
过去一年,人工智能(AI)凭借大语言模型的爆火迅速进入大众视野。它比以往任何时候都更强大,也更具亲和力。这不仅给未来生活带来了新希望,也在人们心中蒙上了一层担忧—&mdas...【详细内容】
2024-01-26    文汇网  Tags:AI   点击:(2)  评论:(0)  加入收藏
性AI机器人时代来临!人类与机器人的爱情,你敢尝试吗?
你是否曾经想过,如果有一天,你可以和一个AI机器人结婚,你敢尝试吗?在科技飞速发展的今天,人类与机器人的关系也越来越密切。从智能手机到智能音箱,从智能家居到智能汽车,我们似乎已...【详细内容】
2024-01-22  互联网的一些事    Tags:AI机器人   点击:(4)  评论:(0)  加入收藏
大型语言模型中最大的瓶颈:速率限制
作者 | Matt Asay策划 | 言征 出品 | 51CTO技术栈(微信号:blog51cto)速率限制意味着每个人都在等待更好的计算资源或不同的生成人工智能模型。大型语言模型(LLM),如OpenAI的GPT-4...【详细内容】
2024-01-19    51CTO技术栈  Tags:大型语言模型   点击:(1)  评论:(0)  加入收藏
鹅厂最新AI工具刷屏!杨幂寡姐多风格写真秒秒钟生成,LeCun点赞 | 可免费体验
大厂们在整活方面开始卷起来了!前脚字节阿里的工具火了,现在腾讯这个新照片生成应用PhotoMaker直接刷屏,瞧这阵仗……只需上传一张或以上照片,无需额外LoRA训练,就能...【详细内容】
2024-01-16    量子位  Tags:AI工具   点击:(12)  评论:(0)  加入收藏
不是人才用不起,而是AI巡检更有性价比!
作者 | 涂承烨审校 | 重楼在许多行业中,如煤炭、电力、化工等,安全生产是至关重要的。这就需要通过巡检,对设备运行状态进行实时监测,及时发现并处理潜在的安全隐患,从而降低事故...【详细内容】
2024-01-16    51CTO  Tags:AI巡检   点击:(11)  评论:(0)  加入收藏
AI伴侣“占领”GPT商店,但这可能并不是件坏事
不久前,被不少人认为是“AI时代App Store”的GPT商店正式上线,然而同样是盛况空前的情况下,GPT商店与App Store上线之初的景象却完全不同。在此前经历了短暂的教育、知识类GPTs...【详细内容】
2024-01-15    三易生活  Tags:AI伴侣   点击:(9)  评论:(0)  加入收藏
机器人女友挤满GPT商店!严禁定制情人的OpenAI傻眼了
GPT商店是OpenAI探索大语言模型应用场景的一个重要媒介,自本月10号上线以来,商店里已经上架了超一万个应用。然而,让OpenAI颇为矛盾的是,越来越多的“机器人女友”和“机器人男...【详细内容】
2024-01-15    财联社  Tags:机器人女友   点击:(18)  评论:(0)  加入收藏
2024年人工智能趋势、预测和可能性
图片来源:由无界 AI生成欢迎来到2024年人工智能的可能性之旅。在这里,每一个预测都是一个潜在的窗口,让我们看到一个充满创新、变革,更重要的是充满机遇的未来。就像20世纪50年...【详细内容】
2024-01-15  AI新智界    Tags:人工智能   点击:(21)  评论:(0)  加入收藏
站内最新
站内热门
站内头条