ChatGLM3大模型Function Calling原理解析
上一篇文章我们部署了清华开源的 ChatGLM3 模型,顺便也体验了一把它的 function call 特性。这个功能最大的价值就是让大模型能调用咱们自己写的代码,实现定制化的任务。不过大模型本身是静态的,拿不到互联网的实时数据,所以今天就用 function call 来做一个查询实时天气的功能,顺便拆解一下它的实现原理。其实 OpenAI 的工具调用(Tool Calling)机制也一样,看完你就明白了。
1. 实测效果
输入:帮我查询北京的天气怎么样
输出:strong>北京当前的天气情况如下:温度为14℃,体感温度为13℃,湿度为38%,天气状况为晴朗。
2. 运行步骤
ChatGLM3 官方仓库里已经提供了 tools 的使用 demo,直接用它就好。先启动 OpenAI 格式的 API server:
cd openai_api_demo nohup python api_server.py &
然后进入 tools_using_demo 文件夹,运行 openai_api_demo.py:
cd tools_using_demo python openai_api_demo.py
运行时可能会碰到一个报错:
openai.UnprocessableEntityError: Error code: 422 - ... 'msg': 'Input should be a valid dictionary'
这个多半是 openai 包的版本问题。用下面命令指定安装 1.8.0 版本,再重新运行就好:
pip install openai==1.8.0 python openai_api_demo.py
3. 原理分析
不妨先设想一个业务场景:前端一个输入框,用户用自然语言描述自己想查什么;服务端有两个现成的方法——根据城市查询天气、根据 IP 查询地理位置。服务端需要根据用户描述来判定该调用哪个方法、传什么参数。比如用户说“我想查一下北京的天气”,服务端就要调用 getWeather("北京")。
如果没有大模型,这个需求实现起来还挺棘手。但有了大模型,事情就简单了:我们把系统中已有的方法名、方法描述、方法参数、参数类型,连同用户的问题一起发给大模型,让大模型理解用户意图,然后告诉我们应该调用哪个方法、参数传什么。我们拿到结果再执行就好。
交互流程中,最关键的就是下面这 2、3、4 步:
(图片位置保持不变)
其实这就是 function calling 的核心原理。理论上如果没有这个特性,通过写 prompt 也能实现类似效果,但远不如这个优雅和可靠。
4. 代码解析
简单看一下 demo 代码。在 tools_using_demo 文件夹里,tool_register.py 定义了两个方法,并用 @register_tool 注解自动获取方法的描述信息。而 openai_api_demo.py 中的 run_conversation 方法会把用户问题和两个方法的描述信息一起发给大模型。如果大模型认为需要进行方法调用,响应里就会包含 function_call 字段,里面就有需要调用的方法名和参数,比如:
Function Call Response: {'arguments': '{"city_name": "北京"}', 'name': 'get_weather'}
然后根据方法名和参数调用我们自己写的方法,拿到返回值:
Tool Call Response: {'current_condition': {'temp_C': '14', 'FeelsLikeC': '13', 'humidity': '38', 'weatherDesc': [{'value': 'Clear'}], 'observation_time': '02:00 PM'}}
方法的返回值通常不是自然语言,所以还需要再把返回值发给大模型,让它总结成一句能看懂的话,最后输出给用户。
