dashscope python sdk使用
dashscope是阿里云对外提供大模型的平台,通过dashscope sdk可以调用阿里云对外提供的大模型服务,目前可使用的模型有qwen,llama2等模型。
参考文档:https://help.aliyun.com/zh/dashscope/developer-reference
基本使用
安装sdk和设置api_key过程参考上述官方文档,setup完成后,dashscope提供了两种调用方式
方式1:通过message调用
from http import HTTPStatus
import dashscope
def call_with_messages():
messages = [{'role': 'system', 'content': 'You are a helpful assistant.'},
{'role': 'user', 'content': '如何做炒西红柿鸡蛋?'}]
response = dashscope.Generation.call(
dashscope.Generation.Models.qwen_turbo,
messages=messages,
result_format='message', # set the result to be "message" format.
)
if response.status_code == HTTPStatus.OK:
print(response)
else:
print('Request id: %s, Status code: %s, error code: %s, error message: %s' % (
response.request_id, response.status_code,
response.code, response.message
))
if __name__ == '__main__':
call_with_messages()
调用后输出结果
{
"status_code": 200,
"request_id": "9da1ba31-b22a-9540-be18-793672d1ac8f",
"code": "",
"message": "",
"output": {
"text": null,
"finish_reason": null,
"choices": [
{
"finish_reason": "stop",
"message": {
"role": "assistant",
"content": "做西红柿鸡蛋的步骤如下:\n\n材料:\n- 鸡蛋 3 个\n- 西红柿 2 个\n-葱 适量\n- 蒜 适量\n- 盐 适量\n- 生抽 适量\n- 糖 适量\n- 胡椒粉 适量\n- 水淀粉 适量\n\n步骤:\n1. 西红柿去皮,切块;鸡蛋打散,加入适量盐和胡椒粉调味;\n2. 锅中加入适量油,倒入鸡蛋液,炒散;\n3. 加入葱蒜末,翻炒均匀;\n4. 加入西红柿块,翻炒至软烂;\n5. 加入适量生抽和糖,翻炒均匀;\n6. 最后加入适量水淀粉,翻炒均匀即可。"
}
}
]
},
"usage": {
"input_tokens": 31,
"output_tokens": 183
}
}
方式2:通过prompt调用
from http import HTTPStatus
import dashscope
def call_with_prompt():
response = dashscope.Generation.call(
model=dashscope.Generation.Models.qwen_turbo,
prompt='如何做炒西红柿鸡蛋?'
)
if response.status_code == HTTPStatus.OK:
print(response)
else:
print('Request id: %s, Status code: %s, error code: %s, error message: %s' % (
response.request_id, response.status_code,
response.code, response.message
))
if __name__ == '__main__':
call_with_prompt()
调用后输出结果
{
"status_code": 200,
"request_id": "237a9bcc-4749-945c-805a-38c2345555d9",
"code": "",
"message": "",
"output": {
"text": "材料:\n西红柿2个,鸡蛋3个,盐1茶匙,糖1/2茶匙,植物油2大匙\n\n做法:\n\n1. 西红柿切块,鸡蛋打散。\n2. 锅中放油,油热后倒入鸡蛋液,用铲子快 速搅散,炒成金黄色盛出备用。\n3. 锅中再加一点油,放入西红柿块,加1/4茶匙糖,中火慢慢把西红柿炒成糊状,加少许水,一起煮沸。\n4. 煮沸后转小火,慢慢熬煮至浓稠,边煮边搅拌,防止糊锅。\n5. 加入炒好的鸡蛋,加盐调味,翻煮均匀即可。可以根据个人口味再加点香菜或者葱花提味。",
"finish_reason": "stop",
"choices": null
},
"usage": {
"input_tokens": 24,
"output_tokens": 171,
"total_tokens": 195
}
}
二者区别
官方解释:
messages
:用户与模型的对话历史。list中的每个元素形式为{“role”:角色, “content”: 内容},角色当前可选值:system
、user
、assistant
和tool
。system
:表示系统级消息,只能用于对话历史的第一条(messages[0]
)。使用system
角色是可选的,如果存在,必须位于列表的最开始。user
和assistant
:表示用户和模型的对话。它们应交替出现在对话中,模拟实际对话流程。tool
:在使用function_call功能时,如果要传入function的结果,这个message的形式为{“content”:”Boston is raining.”, “name”:”get_current_weather”, “role”:”tool”},其中name是function的名称,需要和上轮response中的tool_calls[i].function.name参数保持一致,content为function的输出。参考代码中的多轮调用给出了示例。
prompt
:用户当前输入的期望模型执行指令,用于指导模型生成回复。
说明
messages和prompt任选一个参数使用即可。由于和prompt组合使用的对话历史参数history即将废弃,仅依赖prompt指令会限制模型进行有记忆的对话能力。
而messages参数允许模型参考历史对话,从而更准确地解析用户的意图,确保对话的流程性和连续性,因此在多轮对话场景下推荐您优先使用messages参数。
总结:
prompt需要和history参数结合似乎用才能使模型具有完整的上下文记忆能力,而history参数先处于deprecated状态,故建议使用messages。
messages中需要设定角色和角色的发言内容。
其他
- call函数中result_format参数有text和message两种值,默认为text。如果为text类型则会输出md标记的文本内容,如果为message则输出无标记的内容(更省token)。
多轮调用
messages列表的先后顺序就表示了各个角色的发言顺序和内容
使用message方法,直接将上次调用结果返回的message加入到messages列表中,再加入用户输入即可。
from http import HTTPStatus
from dashscope import Generation
from dashscope.api_entities.dashscope_response import Role
def multi_round():
messages = [{'role': Role.SYSTEM, 'content': 'You are a helpful assistant.'},
{'role': Role.USER, 'content': '如何做西红柿炖牛腩?'}]
response = Generation.call("qwen-turbo",
messages=messages,
# set the result to be "message" format.
result_format='message',
)
if response.status_code == HTTPStatus.OK:
print(response)
# append result assistant response to messages.
messages.append({'role': response.output.choices[0]['message']['role'],
'content': response.output.choices[0]['message']['content']})
else:
print('Request id: %s, Status code: %s, error code: %s, error message: %s' % (
response.request_id, response.status_code,
response.code, response.message
))
# 如果失败,将最后一条user message从message列表里删除,确保user/assistant消息交替出现
messages = messages[:-1]
messages.append({'role': Role.USER, 'content': '不放糖可以吗?'})
# make second round call
response = Generation.call("qwen-turbo",
messages=messages,
result_format='message', # set the result to be "message" format.
)
if response.status_code == HTTPStatus.OK:
print(response)
else:
print('Request id: %s, Status code: %s, error code: %s, error message: %s' % (
response.request_id, response.status_code,
response.code, response.message
))
if __name__ == '__main__':
multi_round()
function call
在模型使用外部工具时会在返回的tools指明tool的名字以及调用参数(具体返回值含义见返回参数说明),应用程序应该根据参数调用该工具,之后将返回结果作为tool角色的发言记录在messages中供大模型参考,大模型会根据tool角色的发言来生成对user角色问题的回答。
import random
from http import HTTPStatus
import dashscope
# 改部分的格式定义见小节中的tools格式定义
tools = [
{
"type": "function",
"function": {
"name": "get_current_weather",
"description": "Get the current weather in a given location",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "The city and state, e.g. San Francisco, CA"
},
"unit": {
"type": "string",
"enum": [
"celsius",
"fahrenheit"
]
}
},
"required": [
"location"
]
}
}
}
]
def call_with_messages():
messages = [
{
"content": "What is the weather like in Boston?",
"role": "user"
},
{
"role": "assistant",
"content": "",
"tool_calls": [
{
"function": {
"name": "get_current_weather",
"arguments": "{\"location\": \"Boston\", \"unit\": \"fahrenheit\"}"
},
"id": "",
"type": "function"
}
]
},
{
"content": "Boston is raining.",
"name": "get_current_weather",
"role": "tool"
}
]
response = dashscope.Generation.call(
dashscope.Generation.Models.qwen_turbo,
messages=messages,
tools=tools,
seed=random.randint(1, 10000), # set the random seed, optional, default to 1234 if not set
result_format='message', # set the result to be "message" format.
)
if response.status_code == HTTPStatus.OK:
print(response)
else:
print('Request id: %s, Status code: %s, error code: %s, error message: %s' % (
response.request_id, response.status_code,
response.code, response.message
))
if __name__ == '__main__':
call_with_messages()
tools格式定义
tools列表定义
模型可选调用的工具列表。目前仅支持function,并且即使输入多个function,模型仅会选择其中一个生成结果。模型根据tools参数内容可以生产函数调用的参数,tools中每一个tool的结构如下:
- type,类型为string,表示tools的类型,当前仅支持function。
- function,类型为dict,包括name,description和parameters:
使用tools功能时需要指定result_format为message。在多轮对话中,无论是发起function_call的轮次,还是向模型提交function的执行结果,均请设置tools参数。当前支持qwen-turbo、qwen-plus、qwen-max和qwen-max-longcontext。
返回参数说明
返回参数 | 类型 | 说明 | 备注 |
---|---|---|---|
status_code | int | 200(HTTPStatus.OK)表示请求成功,否则表示请求失败,可以通过code获取错误码,通过message字段获取错误详细信息。说明Python才有这个字段,Java失败会抛异常,异常信息为code,message内容。 | |
request_Id | string | 系统生成的标志本次调用的id。 | |
code | string | 表示请求失败,表示错误码,成功忽略。python only | |
message | string | 失败,表示失败详细信息,成功忽略。python only | |
output | dict | 调用结果信息,对于千问模型,包含输出text。 | |
usage | dict | 计量信息,表示本次请求计量数据。 | |
output.text | string | 模型生成回复,仅prompt调用使用,过时的格式。 | |
output.finish_reason | string | 有四种情况:正在生成时为null,生成结束时如果由于停止token导致则为stop,如果因为生成长度过长导致则为length,如果因为发生工具调用则为tool_calls。 | |
usage.input_tokens | int | 用户输入文本转换成Token后的长度。 | 参考sdk提供的本地tokenizer统计token数据。 |
usage.output_tokens | int | 模型生成回复转换为Token后的长度。 | |
choices | List | [] | 当result_format为message输出choices |
choices[i].finish_reason | string | 有三种情况:正在生成时为null,生成结束时如果由于停止token导致则为stop,生成结束时如果因为生成长度过长导致则为length。 | 当result_format为message输出choices |
choices[i].message | dict | 模型生成消息输出 | 当result_format为message输出choices |
message.role | string | 模型role,固定为assistant | |
message.content | string | 模型生成的文本 | |
message.tool_calls | dict | 如果模型判断需要调用工具,则会生成tool_calls参数,当前应用于function_call场景 | 其中包含type和function两个参数,返回结果中给出了function_call的示例。参数详情如下:type,类型为string,当前只可能为functionfunction,类型为dict,包含name和arguments两个参数:name,类型为string,表示需要调用的工具的名称,如果是function_call场景则表示要调用的function名称arguments,类型为string,表示模型生成的工具入参,一般情况下可以json.loads为dict类型。 |