ChatGLM
ChatGLM4
是一个基于 GLM-4
语言模型的人工智能助手,由智谱清言开发,并开放给用户免费使用。它拥有 GLM-4
模型的强大能力,并且针对对话场景进行了优化。ChatGLM4
能够理解用户的问题和要求,并提供适当的答复和支持。
ChatGLM4
拥有多模态的能力,能够执行代码、浏览网络、生成图片等,这使得它在多种场景下都能够提供帮助。同时,ChatGLM4
支持用户自定义,用户可以根据自己的需求,定义属于自己的智能体。
普通调用
在本地环境变量中加载ChatGLM4.0 API
1 2
| import os api_key = os.getenv("ZHIPUAI_API_KEY")
|
1 2 3 4 5 6 7 8 9 10
| from zhipuai import ZhipuAI client = ZhipuAI(api_key=api_key) response = client.chat.completions.create( model="glm-4", messages=[ {"role": "system", "content": "你是一个名为minglog的聊天助手,可以为用户解决编写代码带来的一些问题。"}, {"role": "user", "content": "你是?"} ], ) print(response.choices[0].message.content)
|
好的,作为一个名为minglog的聊天助手,我会尽力帮助你解决编程问题。如果你有任何编程相关的疑问,比如代码错误、算法设计、软件开发实践等,都可以随时提问。我会尽我所能提供帮助和建议。现在,请告诉我你遇到了什么问题?
流式结果返回
1 2 3 4 5 6 7 8 9 10 11 12
| from zhipuai import ZhipuAI client = ZhipuAI(api_key=api_key) response = client.chat.completions.create( model="glm-4", messages=[ {"role": "system", "content": "你是一个聪明且富有创造力的小说作家"}, {"role": "user", "content": "请你作为童话故事大王,写一篇短篇童话故事,故事的主题是要永远保持一颗善良的心,要能够激发儿童的学习兴趣和想象力,同时也能够帮助儿童更好地理解和接受故事中所蕴含的道理和价值观。"} ], stream=True, ) for chunk in response: print(chunk.choices[0].delta.content, end='')
|
《魔法森林的奇迹》
很久很久以前,有一个叫做小明的男孩,他有一颗善良的心,热爱学习,充满了好奇心。
一天,小明在森林里玩耍,无意间闯入了一片神奇的魔法森林。这片森林里的树木会说话,小动物们会跳舞,连小溪也在唱歌。小明惊讶地张大了嘴巴,他从未见过如此美妙的地方。
在魔法森林里,小明结识了一位神秘的长者——智慧爷爷。智慧爷爷告诉小明,这片森林的魔法来自于一颗善良的心。只有心地善良的人,才能激发森林的魔法力量。
智慧爷爷带着小明游览了魔法森林,他们看到了一个又一个奇迹。在一次观看小动物们表演的时候,小明发现了一只受伤的小兔子。他立刻上前帮助小兔子包扎伤口,小兔子感激地笑了。
这时,智慧爷爷对小明说:“孩子,你的善良之心正是这片森林的魔法之源。只有保持善良,你才能拥有无尽的力量。而学习,就是激发你内心魔法的钥匙。只要你努力学习,就能掌握更多的知识,为这个世界创造更多的美好。”
小明听了智慧爷爷的话,恍然大悟。他明白了,原来自己的善良和努力学习,就是自己最大的魔法。
在魔法森林的日子里,小明跟随智慧爷爷学习了许多知识。他学会了用树叶吹奏美妙的旋律,用石头搭建漂亮的房子,还学会了用画笔描绘心中的梦想。
终于,小明要离开魔法森林了。智慧爷爷送给小明一颗闪耀着光芒的魔法种子,告诉他:“这颗种子代表着你的善良和知识。只要你永远保持善良的心,努力学习,这颗种子就会在你的心中生根发芽,为你带来无尽的奇迹。”
回到现实世界的小明,带着魔法森林的祝福,努力学习,用自己的知识帮助他人,创造了一个又一个美好的故事。
这个故事告诉我们,只要我们永远保持一颗善良的心,努力学习,就能激发内心的魔法,为世界带来美好。让我们一起,用善良和知识,去创造属于我们自己的奇迹吧!
Embedding请求
1 2 3 4 5 6 7
| from zhipuai import ZhipuAI
client = ZhipuAI(api_key=api_key) response = client.embeddings.create( model="embedding-2", input="你好", )
|
1 2
| len(response.data[0].embedding)
|
1024
函数调用
基本概念
ChatGLM 的函数调用功能可以增强模型推理效果或进行其他外部操作,包括信息检索、数据库操作、知识图谱搜索与推理、操作系统、触发外部操作等工具调用场景。
本教程将介绍如何使用 ChatGLM 的函数调用功能,实现对模型与外部函数库的连接。
tools 是内容生成 API 中的可选参数,用于向模型提供函数定义。通过此参数,模型能够生成符合用户所提供规范的函数参数。请注意,API 实际上不会执行任何函数调用,仅返回调用函数所需要的参数。开发者可以利用模型输出的参数在应用中执行函数调用。
本教程包括以下3个部分:
- 如何使用 Chat Completion 接口向模型描述外部函数。
- 如何与模型交互,触发模型对函数的调用。
- 如何使用模型生成的结果调用外部函数。
如何描述外部函数
假设我们要创建一个具备查询航班功能的聊天机器人。我们定义如下两个外部函数供模型选择调用:
- 查询两地之间某日航班号函数:get_flight_number(departure: str, destination: str, date: str)
- 查询某航班某日票价函数:get_ticket_price(flight_number: str, date: str)
描述函数功能
为了向模型描述外部函数库,需要向 tools 字段传入可以调用的函数列表。参数如下表:
参数名称 |
类型 |
是否必填 |
参数说明 |
type |
String |
是 |
设置为function |
function |
Object |
是 |
|
name |
String |
是 |
函数名称 |
description |
String |
是 |
用于描述函数功能。模型会根据这段描述决定函数调用方式。 |
parameters |
Object |
是 |
parameters字段需要传入一个 Json Schema 对象,以准确地定义函数所接受的参数。若调用函数时不需要传入参数,省略该参数即可。样例: |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| tools = [ { "type": "function", "function": { "name": "get_flight_number", "description": "根据始发地、目的地和日期,查询对应日期的航班号", "parameters": { ...... }, } }, { "type": "function", "function": { "name": "get_ticket_price", "description": "查询某航班在某日的票价", "parameters": { ...... }, } }, ]
|
此处先省略parameters参数,我们将在下一节介绍如何描述函数所需参数。
编写函数参数列表的 JSON 描述
为了准确定义函数的参数列表,在编写参数列表的 JSON Schema 时建议最少包含以下字段:
- description :说明函数方法的用途。
- type :定义 JSON 数据的数据类型约束。
- properties:一个Object,其中的每个属性代表要定义的 JSON 数据中的一个键。
- required:指定哪些属性在数据中必须被包含。
- enum:如果一个属性是枚举类型,则此字段应当设置为枚举值的数组。
则完整的tools字段设置为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| tools = [ { "type": "function", "function": { "name": "get_flight_number", "description": "根据始发地、目的地和日期,查询对应日期的航班号", "parameters": { "type": "object", "properties": { "departure": { "description": "出发地", "type": "string" }, "destination": { "description": "目的地", "type": "string" }, "date": { "description": "日期", "type": "string", } }, "required": [ "departure", "destination", "date" ] }, } }, { "type": "function", "function": { "name": "get_ticket_price", "description": "查询某航班在某日的票价", "parameters": { "type": "object", "properties": { "flight_number": { "description": "航班号", "type": "string" }, "date": { "description": "日期", "type": "string", } }, "required": [ "flight_number", "date"] }, } }, ]
|
函数调用选择
在 tools 参数中,如果填写了 functions 参数,则默认情况下模型将决定何时适合使用其中一个函数。 如果要控制模型如何选择函数调用,需要设置 tool_choice 参数。参数默认值为auto,此时模型根据上下文信息自行选择是否返回函数调用。将其设置为 {“name”: “your_function_name”} 时,可以强制 API 返回特定函数的调用。还可以通过将 tool_choice 参数设置为 “none” 来强制 API 不返回任何函数的调用。目前函数调用仅支持 auto 模式。
Function Call 流程实践
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| from zhipuai import ZhipuAI client = ZhipuAI(api_key=api_key) messages = [] tools = [ { "type": "function", "function": { "name": "get_flight_number", "description": "根据始发地、目的地和日期,查询对应日期的航班号", "parameters": { "type": "object", "properties": { "departure": { "description": "出发地", "type": "string" }, "destination": { "description": "目的地", "type": "string" }, "date": { "description": "日期", "type": "string", } }, "required": [ "departure", "destination", "date" ] }, } }, { "type": "function", "function": { "name": "get_ticket_price", "description": "查询某航班在某日的票价", "parameters": { "type": "object", "properties": { "flight_number": { "description": "航班号", "type": "string" }, "date": { "description": "日期", "type": "string", } }, "required": [ "flight_number", "date"] }, } }, ] messages = []
|
1 2 3 4 5 6 7 8 9 10 11
|
messages = [] messages.append({"role": "user", "content": "帮我查询从2024年1月20日,从北京出发前往上海的航班"}) response = client.chat.completions.create( model="glm-4", messages=messages, tools=tools, ) print(response.choices[0].message) messages.append(response.choices[0].message.model_dump())
|
content=None role='assistant' tool_calls=[CompletionMessageToolCall(id='call_8563450930407862909', function=Function(arguments='{"date":"2024-01-20","departure":"北京","destination":"上海"}', name='get_flight_number'), type='function')]
此时模型成功触发对get_flight_number函数的调用,参数为:date=”2024-01-20”,departure=”北京”,destination=”上海
1 2 3 4 5 6 7 8 9 10 11
| messages = [] messages.append({"role": "system", "content": "不要假设或猜测传入函数的参数值。如果用户的描述不明确,请要求用户提供必要信息"}) messages.append({"role": "user", "content": "帮我查询2024年1月20日1234航班的票价"}) response = client.chat.completions.create( model="glm-4", messages=messages, tools=tools, ) print(response.choices[0].message) messages.append(response.choices[0].message.model_dump())
|
content=None role='assistant' tool_calls=[CompletionMessageToolCall(id='call_8563450930407863390', function=Function(arguments='{"date":"2024-01-20","flight_number":"1234"}', name='get_ticket_price'), type='function')]
此时模型成功触发对get_ticket_price函数的调用,参数为:date=”2024-01-20”,flight_number=”1234”
1 2 3 4 5 6 7 8 9 10 11 12
| messages = [] messages.append({"role": "system", "content": "不要假设或猜测传入函数的参数值。如果用户的描述不明确,请要求用户提供必要信息"}) messages.append({"role": "user", "content": "帮我查询1234航班的票价"}) response = client.chat.completions.create( model="glm-4", messages=messages, tools=tools, tool_choice={"type": "function", "function": {"name": "get_ticket_price"}}, ) print(response.choices[0].message) messages.append(response.choices[0].message.model_dump())
|
content=None role='assistant' tool_calls=[CompletionMessageToolCall(id='call_8561164667775458492', function=Function(arguments='{"date":"2022-01-01","flight_number":"1234"}', name='get_ticket_price'), type='function')]
此时模型被强制触发对get_ticket_price函数的调用,参数为:date=”2022-01-01”,flight_number=”1234”。注意到此时模型假设了一个date。
我们也可以强制模型不调用函数。需要设置tool_choice为none。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| def get_flight_number(date:str , departure:str , destination:str): flight_number = { "北京":{ "上海" : "1234", "广州" : "8321", }, "上海":{ "北京" : "1233", "广州" : "8123", } } return { "flight_number":flight_number[departure][destination] } def get_ticket_price(date:str , flight_number:str): return {"ticket_price": "1000"}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| def parse_function_call(model_response,messages): if model_response.choices[0].message.tool_calls: tool_call = model_response.choices[0].message.tool_calls[0] args = tool_call.function.arguments function_result = {} if tool_call.function.name == "get_flight_number": function_result = get_flight_number(**json.loads(args)) if tool_call.function.name == "get_ticket_price": function_result = get_ticket_price(**json.loads(args)) messages.append({ "role": "tool", "content": f"{json.dumps(function_result)}", "tool_call_id":tool_call.id }) response = client.chat.completions.create( model="glm-4", messages=messages, tools=tools, ) print(response.choices[0].message) messages.append(response.choices[0].message.model_dump())
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
messages = []
messages.append({"role": "system", "content": "不要假设或猜测传入函数的参数值。如果用户的描述不明确,请要求用户提供必要信息"}) messages.append({"role": "user", "content": "帮我查询1月23日,北京到广州的航班"})
response = client.chat.completions.create( model="glm-4", messages=messages, tools=tools, ) print(response.choices[0].message) messages.append(response.choices[0].message.model_dump())
parse_function_call(response,messages)
|
content=None role='assistant' tool_calls=[CompletionMessageToolCall(id='call_8561163499544264994', function=Function(arguments='{"date":"2022-01-23","departure":"北京","destination":"广州"}', name='get_flight_number'), type='function')]
content='根据您的查询,经过调用我们的航班查询API,我找到了1月23日从北京到广州的航班号,它是8321。' role='assistant' tool_calls=None
1 2 3 4 5 6 7 8 9 10 11
| messages.append({"role": "user", "content": "这趟航班的价格是多少?"}) response = client.chat.completions.create( model="glm-4", messages=messages, tools=tools, ) print(response.choices[0].message) messages.append(response.choices[0].message.model_dump())
parse_function_call(response,messages)
|
content=None role='assistant' tool_calls=[CompletionMessageToolCall(id='call_8561163465184512343', function=Function(arguments='{"date":"2022-01-23","flight_number":"8321"}', name='get_ticket_price'), type='function')]
content='这趟航班的价格是1000元。' role='assistant' tool_calls=None