如何使用通义千问API 您所在的位置:网站首页 百度ai接口收费多少 如何使用通义千问API

如何使用通义千问API

2024-07-10 22:51| 来源: 网络整理| 查看: 265

SDK使用

您可以通过SDK实现单轮对话、多轮对话、流式输出、function call等多种功能。您可以查看模型介绍,根据需要选择使用的模型。

前提条件

DashScope SDK提供了Python和Java两个版本,请确保您已安装最新版SDK:安装DashScope SDK。

已开通服务并获得API-KEY:API-KEY的获取与配置。

我们推荐您将API-KEY配置到环境变量中以降低API-KEY的泄漏风险,详情可参考方式一:通过环境变量设置API-KEY(推荐)。

重要

您也可以在代码中配置API-KEY,但是会存在泄露风险。

同时DashScope 提供了与OpenAI兼容的接口访问服务,详情参考OpenAI接口兼容。

说明

当您使用DashScope Java SDK时,为了效率您应该尽可能复用Generation以及其他请求对象,但对象(如Generation)不是线程安全的,您应该采取一定的措施,如及时关闭进程、管理同步机制等,来确保对象的安全。

单轮对话

您可以将通义千问应用在内容创作、翻译服务、文本摘要等多种场景。您可以运行以下示例代码,体验通义千问模型的单轮对话能力。

import random from http import HTTPStatus from dashscope import Generation # 建议dashscope SDK 的版本 >= 1.14.0 def call_with_messages(): messages = [{'role': 'system', 'content': 'You are a helpful assistant.'}, {'role': 'user', 'content': '如何做西红柿炒鸡蛋?'}] response = Generation.call(model="qwen-turbo", messages=messages, # 设置随机数种子seed,如果没有设置,则随机数种子默认为1234 seed=random.randint(1, 10000), # 将输出设置为"message"格式 result_format='message') 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() // Copyright (c) Alibaba, Inc. and its affiliates. // 建议dashscope SDK的版本 >= 2.12.0 import java.util.Arrays; import com.alibaba.dashscope.aigc.generation.Generation; import com.alibaba.dashscope.aigc.generation.GenerationParam; import com.alibaba.dashscope.aigc.generation.GenerationResult; import com.alibaba.dashscope.common.Message; import com.alibaba.dashscope.common.Role; import com.alibaba.dashscope.exception.ApiException; import com.alibaba.dashscope.exception.InputRequiredException; import com.alibaba.dashscope.exception.NoApiKeyException; public class Main { public static GenerationResult callWithMessage() throws ApiException, NoApiKeyException, InputRequiredException { Generation gen = new Generation(); Message systemMsg = Message.builder() .role(Role.SYSTEM.getValue()) .content("You are a helpful assistant.") .build(); Message userMsg = Message.builder() .role(Role.USER.getValue()) .content("如何做西红柿炒鸡蛋?") .build(); GenerationParam param = GenerationParam.builder() .model("qwen-turbo") .messages(Arrays.asList(systemMsg, userMsg)) .resultFormat(GenerationParam.ResultFormat.MESSAGE) .topP(0.8) .build(); return gen.call(param); } public static void main(String[] args) { try { GenerationResult result = callWithMessage(); System.out.println(result); } catch (ApiException | NoApiKeyException | InputRequiredException e) { // 使用日志框架记录异常信息 // Logger.error("An error occurred while calling the generation service", e); System.err.println("An error occurred while calling the generation service: " + e.getMessage()); } System.exit(0); } }

运行结果的示例如下所示:

{ "status_code": 200, "request_id": "5d768057-2820-91ba-8c99-31cd520e7628", "code": "", "message": "", "output": { "text": null, "finish_reason": null, "choices": [ { "finish_reason": "stop", "message": { "role": "assistant", "content": "材料:\n西红柿2个,鸡蛋3个,油适量,盐适量,糖适量,葱花适量。\n\n步骤:\n\n1. 鸡蛋打入碗中,加入少许盐,用筷子搅拌均匀,放置一会儿让蛋白和蛋黄充分融合。\n\n2. 西红柿洗净,切成小块。如果喜欢口感更沙一些,可以切得稍微大一些;如果喜欢口感细腻,可以切得小一些。\n\n3. 热锅凉油,油热后倒入打好的鸡蛋液,用铲子快速搅拌,炒至鸡蛋凝固并变成金黄色,盛出备用。\n\n4. 锅中再加一点油,放入切好的西红柿,用中小火慢慢翻煮,让西红柿出汁,这样炒出来的西红柿才会更甜。\n\n5. 西红柿出汁后,加入适量的糖,继续翻煮,直到西红柿变得软烂。\n\n6. 将炒好的鸡蛋倒回锅中,与西红柿一起翻煮均匀,让鸡蛋充分吸收西红柿的汁水。\n\n7. 最后,根据个人口味加入适量的盐调味,撒上葱花进行提香,翻炒均匀即可出锅。\n\n8. 如果喜欢汤汁多一些,可以适当加点水,调整一下浓稠度。\n\n西红柿炒鸡蛋就做好了,简单易做,营养美味,是一道家常菜的经典之作。" } } ] }, "usage": { "input_tokens": 25, "output_tokens": 289, "total_tokens": 314 } }多轮对话

相比于单轮对话,多轮对话可以参考历史聊天信息,更符合日常交流的场景。但由于调用时会引入历史聊天信息,使用的token量会增多。您可以运行以下示例代码,体验通义千问模型的多轮对话能力。

from http import HTTPStatus from dashscope import Generation def multi_round(): messages = [{'role': 'system', 'content': 'You are a helpful assistant.'}, {'role': 'user', 'content': '如何做西红柿炖牛腩?'}] response = Generation.call(model="qwen-turbo", messages=messages, # 将输出设置为"message"格式 result_format='message') if response.status_code == HTTPStatus.OK: print(response) # 将assistant的回复添加到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从messages列表里删除,确保user/assistant消息交替出现 messages = messages[:-1] # 将新一轮的user问题添加到messages列表中 messages.append({'role': 'user', 'content': '不放糖可以吗?'}) # 进行第二轮模型的响应 response = Generation.call(model="qwen-turbo", messages=messages, result_format='message', # 将输出设置为"message"格式 ) 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() // Copyright (c) Alibaba, Inc. and its affiliates. import java.util.ArrayList; import java.util.List; import com.alibaba.dashscope.aigc.generation.Generation; import com.alibaba.dashscope.aigc.generation.GenerationParam; import com.alibaba.dashscope.aigc.generation.GenerationResult; import com.alibaba.dashscope.common.Message; import com.alibaba.dashscope.common.Role; import com.alibaba.dashscope.exception.ApiException; import com.alibaba.dashscope.exception.InputRequiredException; import com.alibaba.dashscope.exception.NoApiKeyException; import com.alibaba.dashscope.utils.JsonUtils; public class Main { public static GenerationParam createGenerationParam(List messages) { return GenerationParam.builder() .model("qwen-turbo") .messages(messages) .resultFormat(GenerationParam.ResultFormat.MESSAGE) .topP(0.8) .build(); } public static GenerationResult callGenerationWithMessages(GenerationParam param) throws ApiException, NoApiKeyException, InputRequiredException { Generation gen = new Generation(); return gen.call(param); } public static void main(String[] args) { try { List messages = new ArrayList(); messages.add(createMessage(Role.SYSTEM, "You are a helpful assistant.")); messages.add(createMessage(Role.USER, "如何做西红柿炖牛腩?")); GenerationParam param = createGenerationParam(messages); GenerationResult result = callGenerationWithMessages(param); printResult(result); // 添加assistant返回的消息到列表 messages.add(result.getOutput().getChoices().get(0).getMessage()); // 添加新的用户消息 messages.add(createMessage(Role.USER, "不放糖可以吗?")); result = callGenerationWithMessages(param); printResult(result); printResultAsJson(result); } catch (ApiException | NoApiKeyException | InputRequiredException e) { e.printStackTrace(); } System.exit(0); } private static Message createMessage(Role role, String content) { return Message.builder().role(role.getValue()).content(content).build(); } private static void printResult(GenerationResult result) { System.out.println(result); } private static void printResultAsJson(GenerationResult result) { System.out.println(JsonUtils.toJson(result)); } }

运行结果的示例如下所示:

{ "status_code": 200, "request_id": "10b7f68b-f4a3-9798-8f1b-c2177eadf4b2", "code": "", "message": "", "output": { "text": null, "finish_reason": null, "choices": [ { "finish_reason": "stop", "message": { "role": "assistant", "content": "材料:\n牛腩500克,西红柿3个,洋葱1个,大蒜4瓣,生姜2片,八角2颗,香叶2片,干辣椒2个,生抽、老抽、料酒、糖、盐适量,清水适量\n\n步骤:\n\n1. 牛腩切块,用清水浸泡半小时,去除血水和杂质。然后冲洗干净备用。\n\n2. 西红柿洗净,切成滚刀块。洋葱切块,大蒜和生姜切片。\n\n3. 热锅凉油,下入八角、香叶、干辣椒炒出香味。\n\n4. 加入洋葱块,翻炒至微黄。\n\n5. 倒入牛腩块,大火翻炒几分钟,使其表面微焦,这样可以锁住肉的鲜味。\n\n6. 加入大蒜和生姜片,继续翻炒均匀。\n\n7. 倒入料酒,煮一会儿去腥。\n\n8. 加入生抽、老抽上色,再加适量糖,翻炒均匀。\n\n9. 倒入足够的清水,水量要没过牛腩,大火烧开后撇去浮沫。\n\n10. 转小火,加入西红柿块,盖上锅盖慢慢炖煮,期间可适当调整火力,保持汤汁微微沸腾。\n\n11. 炖煮约1-1.5小时,直到牛腩变得软烂,汤汁浓稠。\n\n12. 最后根据个人口味加盐调味,收汁即可。\n\n13. 出锅前可撒些葱花或者香菜提香。\n\n这道西红柿炖牛腩就做好了,香气四溢,肉质酥烂,非常美味。" } } ] }, "usage": { "input_tokens": 26, "output_tokens": 361, "total_tokens": 387 } } { "status_code": 200, "request_id": "a00b67bd-f477-93ea-a648-862179d7d1fe", "code": "", "message": "", "output": { "text": null, "finish_reason": null, "choices": [ { "finish_reason": "stop", "message": { "role": "assistant", "content": "当然可以,糖主要是为了中和牛肉的腥味并增加一些甜味。如果你不喜欢或不添加糖,也可以,只是口感可能会稍微偏重于牛肉本身的原味,而且可能没有那么甜润。你可以根据自己的口味来调整,如果牛腩本身比较嫩,或者你喜欢酸甜口,可以少放或者不放糖,如果牛腩较老,可能会需要一些糖来提升风味。" } } ] }, "usage": { "input_tokens": 403, "output_tokens": 88, "total_tokens": 491 } }

您也可以运行以下代码,体验实时交互的功能。

from dashscope import Generation def get_response(messages): response = Generation.call(model="qwen-turbo", messages=messages, # 将输出设置为"message"格式 result_format='message') return response messages = [{'role': 'system', 'content': 'You are a helpful assistant.'}] # 您可以自定义设置对话轮数,当前为3 for i in range(3): user_input = input("请输入:") messages.append({'role': 'user', 'content': user_input}) assistant_output = get_response(messages).output.choices[0]['message']['content'] messages.append({'role': 'assistant', 'content': assistant_output}) print(f'用户输入:{user_input}') print(f'模型输出:{assistant_output}') print('\n') import java.util.ArrayList; import java.util.List; import com.alibaba.dashscope.aigc.generation.Generation; import com.alibaba.dashscope.aigc.generation.GenerationParam; import com.alibaba.dashscope.aigc.generation.GenerationResult; import com.alibaba.dashscope.common.Message; import com.alibaba.dashscope.common.Role; import com.alibaba.dashscope.exception.ApiException; import com.alibaba.dashscope.exception.InputRequiredException; import com.alibaba.dashscope.exception.NoApiKeyException; import java.util.Scanner; public class Main { public static GenerationParam createGenerationParam(List messages) { return GenerationParam.builder() .model("qwen-turbo") .messages(messages) .resultFormat(GenerationParam.ResultFormat.MESSAGE) .topP(0.8) .build(); } public static GenerationResult callGenerationWithMessages(GenerationParam param) throws ApiException, NoApiKeyException, InputRequiredException { Generation gen = new Generation(); return gen.call(param); } public static void main(String[] args) { try { List messages = new ArrayList(); messages.add(createMessage(Role.SYSTEM, "You are a helpful assistant.")); for (int i = 0; i < 3;i++) { Scanner scanner = new Scanner(System.in); System.out.print("请输入:"); String userInput = scanner.nextLine(); if ("exit".equalsIgnoreCase(userInput)) { break; } messages.add(createMessage(Role.USER, userInput)); GenerationParam param = createGenerationParam(messages); GenerationResult result = callGenerationWithMessages(param); System.out.println("模型输出:"+result.getOutput().getChoices().get(0).getMessage().getContent()); messages.add(result.getOutput().getChoices().get(0).getMessage()); } } catch (ApiException | NoApiKeyException | InputRequiredException e) { e.printStackTrace(); } System.exit(0); } private static Message createMessage(Role role, String content) { return Message.builder().role(role.getValue()).content(content).build(); } }

在您输入问题后,点击Enter键令模型生成回复。使用过程示例如下图所示:

2024-04-08_18-58-36 (1).gif

流式输出

大模型并不是一次性生成最终结果,而是逐步地生成中间结果,最终结果由中间结果拼接而成。非流式输出方式等待模型生成结束后再将生成的中间结果拼接后返回,而流式输出可以实时地将中间结果返回,您可以在模型进行输出的同时进行阅读,减少等待模型回复的时间。使用流式输出需要您进行一些配置,DashScope Python SDK中需要设置stream为True,DashScope Java SDK中需要使用streamCall接口调用。

from http import HTTPStatus from dashscope import Generation def call_with_stream(): messages = [ {'role': 'user', 'content': '如何做西红柿炖牛腩?'}] responses = Generation.call(model="qwen-turbo", messages=messages, result_format='message', # 设置输出为'message'格式 stream=True, # 设置输出方式为流式输出 incremental_output=True # 增量式流式输出 ) for response in responses: if response.status_code == HTTPStatus.OK: print(response.output.choices[0]['message']['content'], end='') 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_stream() // Copyright (c) Alibaba, Inc. and its affiliates. import java.util.Arrays; import java.util.concurrent.Semaphore; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.concurrent.Semaphore; import com.alibaba.dashscope.aigc.generation.Generation; import com.alibaba.dashscope.aigc.generation.GenerationParam; import com.alibaba.dashscope.aigc.generation.GenerationResult; import com.alibaba.dashscope.common.Message; import com.alibaba.dashscope.common.ResultCallback; import com.alibaba.dashscope.common.Role; import com.alibaba.dashscope.exception.ApiException; import com.alibaba.dashscope.exception.InputRequiredException; import com.alibaba.dashscope.exception.NoApiKeyException; import com.alibaba.dashscope.utils.JsonUtils; import io.reactivex.Flowable; public class Main { private static final Logger logger = LoggerFactory.getLogger(Main.class); private static void handleGenerationResult(GenerationResult message, StringBuilder fullContent) { fullContent.append(message.getOutput().getChoices().get(0).getMessage().getContent()); logger.info("Received message: {}", JsonUtils.toJson(message)); } public static void streamCallWithMessage(Generation gen, Message userMsg) throws NoApiKeyException, ApiException, InputRequiredException { GenerationParam param = buildGenerationParam(userMsg); Flowable result = gen.streamCall(param); StringBuilder fullContent = new StringBuilder(); result.blockingForEach(message -> handleGenerationResult(message, fullContent)); logger.info("Full content: \n{}", fullContent.toString()); } public static void streamCallWithCallback(Generation gen, Message userMsg) throws NoApiKeyException, ApiException, InputRequiredException, InterruptedException { GenerationParam param = buildGenerationParam(userMsg); Semaphore semaphore = new Semaphore(0); StringBuilder fullContent = new StringBuilder(); gen.streamCall(param, new ResultCallback() { @Override public void onEvent(GenerationResult message) { handleGenerationResult(message, fullContent); } @Override public void onError(Exception err) { logger.error("Exception occurred: {}", err.getMessage()); semaphore.release(); } @Override public void onComplete() { logger.info("Completed"); semaphore.release(); } }); semaphore.acquire(); logger.info("Full content: \n{}", fullContent.toString()); } private static GenerationParam buildGenerationParam(Message userMsg) { return GenerationParam.builder() .model("qwen-turbo") .messages(Arrays.asList(userMsg)) .resultFormat(GenerationParam.ResultFormat.MESSAGE) .topP(0.8) .incrementalOutput(true) .build(); } public static void main(String[] args) { try { Generation gen = new Generation(); Message userMsg = Message.builder().role(Role.USER.getValue()).content("如何做西红柿炖牛腩?").build(); streamCallWithMessage(gen, userMsg); streamCallWithCallback(gen, userMsg); } catch (ApiException | NoApiKeyException | InputRequiredException | InterruptedException e) { logger.error("An exception occurred: {}", e.getMessage()); } } }

流式输出效果如下图所示:2024-04-08_19-12-00 (1).gif

Asyncio接口

如果您使用Dashscope Python SDK,可以使用asyncio调用实现并发,提高程序的效率。示例代码如下:

说明

您的Dashscope Python SDK版本需要不低于 1.19.0。

import asyncio from http import HTTPStatus import platform from dashscope import Generation from dashscope.aigc.generation import AioGeneration async def async_dashscope_sample(): response = await AioGeneration.call("qwen-turbo", prompt='今天天气好吗?') if response.status_code == HTTPStatus.OK: print('Result is: %s' % response.output) else: print('Failed request_id: %s, status_code: %s, code: %s, message:%s' % (response.request_id, response.status_code, response.code, response.message)) async def async_dashscope_stream_sample(): responses = await AioGeneration.call(model="qwen-turbo", prompt='今天天气好吗?', stream=True) # responses是async迭代器,需要用async for循环来遍历 async for response in responses: print(response) async def main(): response = await async_dashscope_sample() print(response) await async_dashscope_stream_sample() if __name__ == '__main__': # 如果当前操作系统为Windows,则使用WindowsSelectorEventLoopPolicy作为事件循环策略 if platform.system() == 'Windows': asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy()) loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) asyncio.run(main(), debug=False) Function call

大模型在面对实时性问题、私域知识型问题或数学计算等问题时可能效果不佳。您可以使用function call功能,通过调用外部工具来提升模型的输出效果。您可以在调用大模型时,通过tools参数传入工具的名称、描述、入参等信息。大模型在收到提示词以及工具信息后,会判断是否需要使用工具:

如果不需要使用工具,大模型不会返回tool_calls参数,您的程序可以直接返回大模型的回答。

如果需要使用工具,大模型会返回一个包含tool_calls字段的信息,您的程序可以根据此信息判断需要调用工具。您的程序需要解析tool_calls信息中包含的工具函数名和入参,并将入参输入到工具函数来得到工具调用的结果。您的程序需要将工具信息按照以下格式配置:

{ "name": "$工具名", "role": "tool", "content": "$工具输出" }

将工具信息添加到历史对话信息中,再次向大模型提问,获得最终回答。

Function call的工作流程示意图如下所示:

image说明

Function call信息暂时不支持增量输出,增量输出请参考输入参数配置incremental_output参数。

Function call的使用涉及到参数解析功能,因此对大模型的响应质量要求较高,推荐您优先使用qwen-max模型。示例代码如下所示:

from dashscope import Generation from datetime import datetime import random import json # 定义工具列表,模型在选择使用哪个工具时会参考工具的name和description tools = [ # 工具1 获取当前时刻的时间 { "type": "function", "function": { "name": "get_current_time", "description": "当你想知道现在的时间时非常有用。", "parameters": {} # 因为获取当前时间无需输入参数,因此parameters为空字典 } }, # 工具2 获取指定城市的天气 { "type": "function", "function": { "name": "get_current_weather", "description": "当你想查询指定城市的天气时非常有用。", "parameters": { # 查询天气时需要提供位置,因此参数设置为location "type": "object", "properties": { "location": { "type": "string", "description": "城市或县区,比如北京市、杭州市、余杭区等。" } } }, "required": [ "location" ] } } ] # 模拟天气查询工具。返回结果示例:“北京今天是晴天。” def get_current_weather(location): return f"{location}今天是晴天。 " # 查询当前时间的工具。返回结果示例:“当前时间:2024-04-15 17:15:18。“ def get_current_time(): # 获取当前日期和时间 current_datetime = datetime.now() # 格式化当前日期和时间 formatted_time = current_datetime.strftime('%Y-%m-%d %H:%M:%S') # 返回格式化后的当前时间 return f"当前时间:{formatted_time}。" # 封装模型响应函数 def get_response(messages): response = Generation.call( model='qwen-max', messages=messages, tools=tools, seed=random.randint(1, 10000), # 设置随机数种子seed,如果没有设置,则随机数种子默认为1234 result_format='message' # 将输出设置为message形式 ) return response def call_with_messages(): print('\n') messages = [ { "content": input('请输入:'), # 提问示例:"现在几点了?" "一个小时后几点" "北京天气如何?" "role": "user" } ] # 模型的第一轮调用 first_response = get_response(messages) assistant_output = first_response.output.choices[0].message print(f"\n大模型第一轮输出信息:{first_response}\n") messages.append(assistant_output) if 'tool_calls' not in assistant_output: # 如果模型判断无需调用工具,则将assistant的回复直接打印出来,无需进行模型的第二轮调用 print(f"最终答案:{assistant_output.content}") return # 如果模型选择的工具是get_current_weather elif assistant_output.tool_calls[0]['function']['name'] == 'get_current_weather': tool_info = {"name": "get_current_weather", "role":"tool"} location = json.loads(assistant_output.tool_calls[0]['function']['arguments'])['properties']['location'] tool_info['content'] = get_current_weather(location) # 如果模型选择的工具是get_current_time elif assistant_output.tool_calls[0]['function']['name'] == 'get_current_time': tool_info = {"name": "get_current_time", "role":"tool"} tool_info['content'] = get_current_time() print(f"工具输出信息:{tool_info['content']}\n") messages.append(tool_info) # 模型的第二轮调用,对工具的输出进行总结 second_response = get_response(messages) print(f"大模型第二轮输出信息:{second_response}\n") print(f"最终答案:{second_response.output.choices[0].message['content']}") if __name__ == '__main__': call_with_messages() // Copyright (c) Alibaba, Inc. and its affiliates. // version >= 2.12.0 import java.util.ArrayList; import java.util.Arrays; import java.util.List; import com.alibaba.dashscope.aigc.conversation.ConversationParam.ResultFormat; import com.alibaba.dashscope.aigc.generation.Generation; import com.alibaba.dashscope.aigc.generation.GenerationOutput.Choice; import com.alibaba.dashscope.aigc.generation.GenerationParam; import com.alibaba.dashscope.aigc.generation.GenerationResult; import com.alibaba.dashscope.common.Message; import com.alibaba.dashscope.common.Role; import com.alibaba.dashscope.exception.ApiException; import com.alibaba.dashscope.exception.InputRequiredException; import com.alibaba.dashscope.exception.NoApiKeyException; import com.alibaba.dashscope.tools.FunctionDefinition; import com.alibaba.dashscope.tools.ToolCallBase; import com.alibaba.dashscope.tools.ToolCallFunction; import com.alibaba.dashscope.tools.ToolFunction; import com.alibaba.dashscope.utils.JsonUtils; import com.fasterxml.jackson.databind.node.ObjectNode; import com.github.victools.jsonschema.generator.Option; import com.github.victools.jsonschema.generator.OptionPreset; import com.github.victools.jsonschema.generator.SchemaGenerator; import com.github.victools.jsonschema.generator.SchemaGeneratorConfig; import com.github.victools.jsonschema.generator.SchemaGeneratorConfigBuilder; import com.github.victools.jsonschema.generator.SchemaVersion; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.Scanner; public class Main { public class GetWhetherTool { private String location; public GetWhetherTool(String location) { this.location = location; } public String call() { return location+"今天是晴天"; } } public class GetTimeTool { public GetTimeTool() { } public String call() { LocalDateTime now = LocalDateTime.now(); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); String currentTime = "当前时间:" + now.format(formatter) + "。"; return currentTime; } } public static void SelectTool() throws NoApiKeyException, ApiException, InputRequiredException { SchemaGeneratorConfigBuilder configBuilder = new SchemaGeneratorConfigBuilder(SchemaVersion.DRAFT_2020_12, OptionPreset.PLAIN_JSON); SchemaGeneratorConfig config = configBuilder.with(Option.EXTRA_OPEN_API_FORMAT_VALUES) .without(Option.FLATTENED_ENUMS_FROM_TOSTRING).build(); SchemaGenerator generator = new SchemaGenerator(config); ObjectNode jsonSchema_whether = generator.generateSchema(GetWhetherTool.class); ObjectNode jsonSchema_time = generator.generateSchema(GetTimeTool.class); FunctionDefinition fd_whether = FunctionDefinition.builder().name("get_current_whether").description("获取指定地区的天气") .parameters(JsonUtils.parseString(jsonSchema_whether.toString()).getAsJsonObject()).build(); FunctionDefinition fd_time = FunctionDefinition.builder().name("get_current_time").description("获取当前时刻的时间") .parameters(JsonUtils.parseString(jsonSchema_time.toString()).getAsJsonObject()).build(); Message systemMsg = Message.builder().role(Role.SYSTEM.getValue()) .content("You are a helpful assistant. When asked a question, use tools wherever possible.") .build(); Scanner scanner = new Scanner(System.in); System.out.print("\n请输入:"); String userInput = scanner.nextLine(); Message userMsg = Message.builder().role(Role.USER.getValue()).content(userInput).build(); List messages = new ArrayList(); messages.addAll(Arrays.asList(systemMsg, userMsg)); GenerationParam param = GenerationParam.builder().model(Generation.Models.QWEN_MAX) .messages(messages).resultFormat(ResultFormat.MESSAGE) .tools(Arrays.asList(ToolFunction.builder().function(fd_whether).build(),ToolFunction.builder().function(fd_time).build())).build(); // 大模型的第一轮调用 Generation gen = new Generation(); GenerationResult result = gen.call(param); System.out.println("\n大模型第一轮输出信息:"+JsonUtils.toJson(result)); for (Choice choice : result.getOutput().getChoices()) { messages.add(choice.getMessage()); // 如果需要调用工具 if (result.getOutput().getChoices().get(0).getMessage().getToolCalls() != null) { for (ToolCallBase toolCall : result.getOutput().getChoices().get(0).getMessage() .getToolCalls()) { if (toolCall.getType().equals("function")) { // 获取工具函数名称和入参 String functionName = ((ToolCallFunction) toolCall).getFunction().getName(); String functionArgument = ((ToolCallFunction) toolCall).getFunction().getArguments(); // 大模型判断调用天气查询工具的情况 if (functionName.equals("get_current_whether")) { GetWhetherTool GetWhetherFunction = JsonUtils.fromJson(functionArgument, GetWhetherTool.class); String whether = GetWhetherFunction.call(); Message toolResultMessage = Message.builder().role("tool") .content(String.valueOf(whether)).toolCallId(toolCall.getId()).build(); messages.add(toolResultMessage); System.out.println("\n工具输出信息:"+whether); } // 大模型判断调用时间查询工具的情况 else if (functionName.equals("get_current_time")) { GetTimeTool GetTimeFunction = JsonUtils.fromJson(functionArgument, GetTimeTool.class); String time = GetTimeFunction.call(); Message toolResultMessage = Message.builder().role("tool") .content(String.valueOf(time)).toolCallId(toolCall.getId()).build(); messages.add(toolResultMessage); System.out.println("\n工具输出信息:"+time); } } } } // 如果无需调用工具,直接输出大模型的回复 else { System.out.println("\n最终答案:"+result.getOutput().getChoices().get(0).getMessage().getContent()); return; } } // 大模型的第二轮调用 包含工具输出信息 param.setMessages(messages); result = gen.call(param); System.out.println("\n大模型第二轮输出信息:"+JsonUtils.toJson(result)); System.out.println(("\n最终答案:"+result.getOutput().getChoices().get(0).getMessage().getContent())); } public static void main(String[] args) { try { SelectTool(); } catch (ApiException | NoApiKeyException | InputRequiredException e) { System.out.println(String.format("Exception %s", e.getMessage())); } System.exit(0); } }

通过运行以上代码,您可以输入问题,得到在工具辅助条件下模型的输出结果。使用过程示例如下图所示:2024-04-29_11-22-10 (1).gif

以下是发起function call流程(模型的第一轮调用)时模型的返回信息。当输入“杭州天气”时,模型会返回tool_calls参数;当输入“你好”时,模型判断无需调用工具,模型不会返回tool_calls参数。

输入:杭州天气{ "status_code": 200, "request_id": "bd803417-56a7-9597-9d3f-a998a35b0477", "code": "", "message": "", "output": { "text": null, "finish_reason": null, "choices": [ { "finish_reason": "tool_calls", "message": { "role": "assistant", "content": "", "tool_calls": [ { "function": { "name": "get_current_weather", "arguments": "{\"properties\": {\"location\": \"杭州市\"}, \"type\": \"object\"}" }, "id": "", "type": "function" } ] } } ] }, "usage": { "input_tokens": 222, "output_tokens": 27, "total_tokens": 249 } }输入:你好{ "status_code": 200, "request_id": "28e9d70c-c4d7-9bfb-bd07-8cf4228dda91", "code": "", "message": "", "output": { "text": null, "finish_reason": null, "choices": [ { "finish_reason": "stop", "message": { "role": "assistant", "content": "你好!有什么能帮到你的吗?如果有关于天气、时间或者其他问题,随时告诉我。" } } ] }, "usage": { "input_tokens": 221, "output_tokens": 21, "total_tokens": 242 } }

您可以根据您的需求,参照代码中tools的定义来扩充您的工具库。

输入参数配置

模型的生成结果由输入参数的配置决定,如用户指令、模型名称、是否流式输出、温度参数等。您可以查看下表来了解响应函数输入参数的配置方式。

数据类型列中各字段的含义如下所示:

string表示字符串类型;

array在Python中表示列表,在Java中表示ArrayList;

integer表示整数型;

float表示浮点型;

boolean表示布尔型;

object表示哈希表。

参数

数据类型

默认值

说明

model(必选)

string

指定用于对话的通义千问模型名,目前可选择qwen-turbo、qwen-plus、qwen-max、qwen-max-0403、qwen-max-0107、qwen-max-1201和qwen-max-longcontext。

说明

qwen-max-0403、qwen-max-0107、qwen-max-1201、qwen-max-longcontext在当前SDK版本中未定义,您可以指定model为模型名称字符串进行调用。

例如:

Python:model='qwen-max-longcontext'

Java:.model("qwen-max-0403")

messages

array

messages:用户与模型的对话历史。array中的每个元素形式为{"role":角色, "content": 内容},角色当前可选值:system、user、assistant和tool。

system:表示系统级消息,用于指导模型按照预设的规范、角色或情境进行回应。是否使用system角色是可选的,如果使用则必须位于messages的最开始部分。

user和assistant:表示用户和模型的消息。它们应交替出现在对话中,模拟实际对话流程。

tool:表示工具的消息。在使用function call功能时,如果要传入工具的结果,需将元素的形式设为{"content":"工具返回的结果", "name":"工具的函数名", "role":"tool"}。其中name是工具函数的名称,需要和上轮response中的tool_calls[i]['function']['name']参数保持一致;content是工具函数的输出。参考代码给出了示例。

prompt:用户输入的指令,用于指导模型生成回复。

说明

messages和prompt任选一个参数使用即可。由于和prompt组合使用的对话历史参数history即将废弃,仅依赖prompt指令会限制模型进行有记忆的对话能力。

messages参数允许模型参考历史对话,从而更准确地解析用户的意图,确保对话的流程性和连续性,因此在多轮对话场景下推荐您优先使用messages参数。

prompt

string

无(与messages不可同时为空)

seed(可选)

integer

生成时使用的随机数种子,用于控制模型生成内容的随机性。seed支持无符号64位整数。

max_tokens(可选)

integer

1500或2000

指定模型可生成的最大token个数。

qwen-turbo最大值和默认值为1500 tokens。

qwen-max、qwen-max-1201、qwen-max-longcontext和qwen-plus模型,最大值和默认值均为2000 tokens。

top_p(可选)

float

生成过程中的核采样方法概率阈值,例如,取值为0.8时,仅保留概率加起来大于等于0.8的最可能token的最小集合作为候选集。取值范围为(0,1.0),取值越大,生成的随机性越高;取值越低,生成的确定性越高。

top_k(可选)

integer

生成时,采样候选集的大小。例如,取值为50时,仅将单次生成中得分最高的50个token组成随机采样的候选集。取值越大,生成的随机性越高;取值越小,生成的确定性越高。取值为None或当top_k大于100时,表示不启用top_k策略,此时,仅有top_p策略生效。

repetition_penalty(可选)

float

用于控制模型生成时连续序列中的重复度。提高repetition_penalty时可以降低模型生成的重复度,1.0表示不做惩罚。没有严格的取值范围。

presence_penalty(可选)

float

用户控制模型生成时整个序列中的重复度。提高presence_penalty时可以降低模型生成的重复度,取值范围[-2.0, 2.0]。

temperature(可选)

float

用于控制模型回复的随机性和多样性。具体来说,temperature值控制了生成文本时对每个候选词的概率分布进行平滑的程度。较高的temperature值会降低概率分布的峰值,使得更多的低概率词被选择,生成结果更加多样化;而较低的temperature值则会增强概率分布的峰值,使得高概率词更容易被选择,生成结果更加确定。

取值范围:[0, 2),不建议取值为0,无意义。

stop (可选)

string or array

None

stop参数用于实现内容生成过程的精确控制,在模型生成的内容即将包含指定的字符串或token_id时自动停止。stop可以为string类型或array类型。

string类型

当模型将要生成指定的stop词语时停止。

例如将stop指定为"你好",则模型将要生成“你好”时停止。

array类型

array中的元素可以为token_id或者字符串,或者元素为token_id的array。当模型将要生成的token或其对应的token_id在stop中时,模型生成将会停止。以下为stop为array时的示例(tokenizer对应模型为qwen-turbo):

1.元素为token_id:

token_id为108386和104307分别对应token为“你好”和“天气”,设定stop为[108386,104307],则模型将要生成“你好”或者“天气”时停止。

2.元素为字符串:

设定stop为["你好","天气"],则模型将要生成“你好”或者“天气”时停止。

3.元素为array:

token_id为108386和103924分别对应token为“你好”和“啊”,token_id为35946和101243分别对应token为“我”和“很好”。设定stop为[[108386, 103924],[35946, 101243]],则模型将要生成“你好啊”或者“我很好”时停止。

说明

stop为array类型时,不可以将token_id和字符串同时作为元素输入,比如不可以指定stop为["你好",104307]。

stream (可选)

boolean

False

用于控制是否使用流式输出。当以stream模式输出结果时,接口返回结果为generator,需要通过迭代获取结果,默认每次输出为当前生成的整个序列,最后一次输出为最终全部生成结果,可以通过设置参数incremental_output为False改变输出模式为非增量输出。

enable_search(可选)

boolean

False

用于控制模型在生成文本时是否使用互联网搜索结果进行参考。取值如下:

True:启用互联网搜索,模型会将搜索结果作为文本生成过程中的参考信息,但模型会基于其内部逻辑判断是否使用互联网搜索结果。

False(默认):关闭互联网搜索。

result_format(可选)

string

text

用于指定返回结果的格式,默认为text,也可选择message。当设置为message时,输出格式请参考返回结果。推荐您优先使用message格式。

incremental_output (可选)

boolean

False

控制在流式输出模式下是否开启增量输出,即后续输出内容是否包含已输出的内容。设置为True时,将开启增量输出模式,后面输出不会包含已经输出的内容,您需要自行拼接整体输出;设置为False则会包含已输出的内容。您可以参考流式输出代码。

默认False:

I

I like

I like apple

True:

I

like

apple

该参数只能在stream为True时使用。

说明

incremental_output暂时无法和tools参数同时使用。

tools

array

None

用于指定可供模型调用的工具库,一次function call流程模型会从中选择其中一个工具。tools中每一个tool的结构如下:

type,类型为string,表示tools的类型,当前仅支持function。

function,类型为object,键值包括name,description和parameters:

name:类型为string,表示工具函数的名称,必须是字母、数字,可以包含下划线和短划线,最大长度为64。

description:类型为string,表示工具函数的描述,供模型选择何时以及如何调用工具函数。

parameters:类型为object,表示工具的参数描述,需要是一个合法的JSON Schema。JSON Schema的描述可以见链接。参考代码中给出了参数描述的示例。如果parameters参数为空,表示function没有入参。

使用tools时需要同时指定result_format为message。在function call流程中,无论是发起function call的轮次,还是向模型提交工具函数的执行结果,均需设置tools参数。当前支持的模型包括qwen-turbo、qwen-plus、qwen-max和qwen-max-longcontext。

说明

tools暂时无法和incremental_output参数同时使用。

tool_choice

string or object

见说明

在使用tools参数时,用于控制模型调用指定工具。有四种取值:

none表示不调用工具。tools参数为空时,默认值为none。

auto表示模型判断是否调用工具,可能调用也可能不调用。tools参数不为空时,默认值为auto。

object结构可以指定模型调用指定工具。例如{"type": "function", "function": {"name": "user_function"}}

type现在只支持function

function

name表示期望被调用的工具名称

说明

当前支持qwen-max/qwen-max-0428/qwen-max-0403/qwen-plus/qwen-turbo

返回结果

result_format设置为"message"时的结果示例:

{ "status_code": 200, "request_id": "05dc83af-7185-9e14-9b0b-4466de159d6a", "code": "", "message": "", "output": { "text": null, "finish_reason": null, "choices": [ { "finish_reason": "stop", "message": { "role": "assistant", "content": "首先,准备两个鸡蛋,一个西红柿,适量的盐、糖、料酒和生抽。将鸡蛋打入碗中,搅拌均匀,西红柿切块。锅中加油,油热后加入鸡蛋液,炒至金黄色,盛出备用。锅中加油,油热后加入西红柿块,翻炒均匀,加入适量的盐、糖、料酒和生抽,炒至西红柿软烂,加入炒好的鸡蛋,翻炒均匀即可。" } } ] }, "usage": { "input_tokens": 12, "output_tokens": 98, "total_tokens": 110 } }

发起function call时的结果示例:

{ "status_code": 200, "request_id": "a2b49cd7-ce21-98ff-87ac-b00cc590dc5e", "code": "", "message": "", "output": { "text": null, "finish_reason": null, "choices": [ { "finish_reason": "tool_calls", "message": { "role": "assistant", "content": "", "tool_calls":[ { 'function': { 'name': 'get_current_weather', 'arguments': '{"properties": {"location": "北京市"}}' }, 'id': '', 'type': 'function'}] } } ] }, "usage": { "input_tokens": 12, "output_tokens": 98, "total_tokens": 110 } }

返回参数说明

返回参数

数据类型

说明

备注

status_code

integer

200(HTTPStatus.OK)表示请求成功,否则表示请求失败,可以通过code获取错误码,通过message字段获取错误详细信息。

说明

只有Python会输出该参数,使用Java调用失败会抛出异常,异常信息为code和message的内容。

request_id

string

系统生成的标志本次调用的id。

code

string

表示错误码,调用成功时为空值。仅适用于Python。

message

string

表示调用失败的详细信息,调用成功时为空值。仅适用于Python。

output

object

表示调用结果信息。

output.text

string

模型生成的回复。

在使用prompt传入指令时不为空

output.finish_reason

string

有四种情况:

正在生成时为null;

因触发输入参数中的stop条件而结束为stop;

因生成长度过长而结束为length;

因发生工具调用为tool_calls。

output.choices

array

当result_format为message时输出choices。

当result_format为message时输出choices。

output.choices[i].finish_reason

string

有三种情况:

正在生成时为null;

因触发输入参数中的stop条件而结束为stop;

因生成长度过长而结束为length。

output.choices[i].message

object

模型输出的消息。

output.choices[i].message.role

string

模型的角色,固定为assistant。

output.choices[i].message.content

string

模型生成的文本。

output.choices[i].message.tool_calls

object

如果模型需要调用工具,则会生成tool_calls参数,应用于function call场景。

包含三个参数:type、function和id。返回结果中给出了function_call的示例。type、function参数详情如下:

type,类型为string,当前只能设置为function。

function,类型为object,包含name和arguments两个参数:

name,类型为string,表示需要调用的工具的名称,如果是function call场景则表示要调用的工具函数名称。

arguments,类型为string,表示模型生成的要传入工具的参数。可以通过Python中的json.loads方法解析为字典。

usage

object

计量信息,表示本次请求所消耗的token数据。

usage.input_tokens

integer

用户输入文本转换成token后的长度。

您可以参考本地tokenizer统计token数据进行token的估计。

usage.output_tokens

integer

模型生成回复转换为token后的长度。

usage.total_tokens

integer

usage.input_tokens与usage.output_tokens的总和

HTTP调用接口

您可以通过HTTP调用接口来使用通义千问模型,免去安装DashScope SDK的步骤。您可以通过HTTP调用接口实现单轮对话、多轮对话、流式输出、function call等多种功能。您可以查看模型介绍,根据需要选择使用的模型。

前提条件

已开通服务并获得API-KEY:API-KEY的获取与配置。

我们推荐您将API-KEY配置到环境变量中以降低API-KEY的泄漏风险,详情可参考方式一:通过环境变量设置API-KEY(推荐)。您也可以在代码中配置API-KEY,但是泄漏风险会提高

如果您使用Windows系统,示例中的Shell脚本可以通过Windows Subsystem for Linux (WSL)或Git Bash等方式运行。

提交接口调用POST https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation单轮对话

您可以将通义千问应用在内容创作、翻译服务、文本摘要等多种场景。您可以运行以下示例代码,体验通义千问模型的单轮对话能力。

read -p "请输入: " user_content curl --location 'https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation' \ --header "Authorization: Bearer $DASHSCOPE_API_KEY" \ --header 'Content-Type: application/json' \ --data '{ "model": "qwen-turbo", "input":{ "messages":[ { "role": "system", "content": "You are a helpful assistant." }, { "role": "user", "content": "'"$user_content"'" } ] }, "parameters": { "result_format": "message" } }'import requests import os api_key = os.getenv("DASHSCOPE_API_KEY") url = 'https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation' headers = {'Content-Type': 'application/json', 'Authorization':f'Bearer {api_key}'} body = { 'model': 'qwen-turbo', "input": { "messages": [ { "role": "system", "content": "You are a helpful assistant." }, { "role": "user", "content": input("请输入:") } ] }, "parameters": { "result_format": "message" } } response = requests.post(url, headers=headers, json=body) print(response.json())import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import java.nio.charset.StandardCharsets; import java.util.Scanner; public class Main { private static final String USER_AGENT = "Java-HttpURLConnection/1.0"; public static void main(String[] args) throws Exception { String urlStr = "https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation"; String apiKey = System.getenv("DASHSCOPE_API_KEY"); URL url = new URL(urlStr); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("POST"); connection.setRequestProperty("Content-Type", "application/json"); connection.setRequestProperty("Authorization", "Bearer " + apiKey); connection.setDoOutput(true); Scanner scanner = new Scanner(System.in); System.out.println("请输入:"); String UserInput = scanner.nextLine(); String jsonInputString = String.format("{\"model\": \"qwen-turbo\", \"input\": {\"messages\": [{\"role\": \"system\", \"content\": \"You are a helpful assistant.\"}, {\"role\": \"user\", \"content\": \"%s\"}]}, \"parameters\": {\"result_format\": \"message\"}}",UserInput); try (DataOutputStream wr = new DataOutputStream(connection.getOutputStream())) { wr.write(jsonInputString.getBytes(StandardCharsets.UTF_8)); wr.flush(); } StringBuilder response = new StringBuilder(); try (BufferedReader in = new BufferedReader( new InputStreamReader(connection.getInputStream()))) { String inputLine; while ((inputLine = in.readLine()) != null) { response.append(inputLine); } } System.out.println(response); connection.disconnect(); } }

输入“介绍一下通义千问”,得到的示例结果如下:

{ "output": { "choices": [ { "finish_reason": "stop", "message": { "role": "assistant", "content": "通义千问,是阿里云自主研发的超大规模语言模型,能够回答问题、创作文字,还能表达观点、撰写代码。我是阿里云推出的一种超大规模语言模型,我是一个能够回答问题、创作文字,还能表达观点、撰写代码的AI助手。如果您有任何问题或需要帮助,请随时告诉我,我会尽力提供支持。" } } ] }, "usage": { "total_tokens": 97, "output_tokens": 73, "input_tokens": 24 }, "request_id": "0105f672-d7b4-9172-9d03-51c669ec830a" }多轮对话

相比于单轮对话,多轮对话可以参考历史聊天信息,更符合日常交流的场景。但由于调用时会引入历史聊天信息,使用的token量会增多。您可以运行以下示例代码,体验通义千问模型的多轮对话能力。如果您使用Java语言,请在pom.xml文件中添加org.json依赖。

import requests import os api_key = os.getenv("DASHSCOPE_API_KEY") url = 'https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation' headers = {'Content-Type': 'application/json', 'Authorization': f'Bearer {api_key}'} messages = [ { "role": "system", "content": "You are a helpful assistant." } ] # 封装模型的响应函数 def get_response(last_messages): body = { 'model': 'qwen-turbo', "input": { "messages": last_messages }, "parameters": { "result_format": "message" } } response = requests.post(url, headers=headers, json=body) return response.json() # 您可以在此修改对话轮数,当前为3轮对话 for i in range(3): UserInput = input('请输入:') messages.append({ "role": "user", "content": UserInput }) response = get_response(messages) assistant_output = response['output']['choices'][0]['message'] print("用户输入:", UserInput) print(f"模型输出:{assistant_output['content']}\n") messages.append(assistant_output)// 需要添加org.json依赖,在pom.xml文件中添加以下依赖: // // org.json // json // 20240303 // import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import java.nio.charset.StandardCharsets; import java.util.Scanner; import org.json.JSONArray; import org.json.JSONObject; public class Main { private static final String USER_AGENT = "Java-HttpURLConnection/1.0"; public static void main(String[] args) throws Exception { // 定义messages JSONArray messages = new JSONArray(); // 定义系统消息system_message并添加到messages中 JSONObject system_message = new JSONObject(); system_message.put("role","system"); system_message.put("content","You are a helpful assistant."); messages.put(system_message); // 您可以在此修改对话轮数,当前为3轮对话 for (int i = 0; i < 3; i++) { Scanner scanner = new Scanner(System.in); System.out.print("请输入:"); String UserInput = scanner.next(); // 定义用户消息user_message并添加到messages中 JSONObject user_message = new JSONObject(); user_message.put("role","user"); user_message.put("content",UserInput); messages.put(user_message); // 定义传入的body对象 JSONObject body = new JSONObject(); // 定义body中的input对象 JSONObject input_message = new JSONObject(); input_message.put("messages",messages); // 定义body中的parameters对象 JSONObject parameters_message = new JSONObject(); parameters_message.put("result_format","message"); // 将model、input与parameters传入body中 body.put("model","qwen-turbo"); body.put("input",input_message); body.put("parameters",parameters_message); // 进行模型的调用 JSONObject assistant_output = get_response(body); // 取出content并打印出来 JSONObject output = assistant_output.getJSONObject("output"); JSONArray choices = output.getJSONArray("choices"); JSONObject firstChoice = choices.getJSONObject(0); JSONObject assistant_message = firstChoice.getJSONObject("message"); String content = assistant_message.getString("content"); System.out.println("用户输入:"+UserInput); System.out.println("模型输出:"+content+'\n'); // 将assistant_message添加到messages中 messages.put(assistant_message); } } // 封装模型响应函数 public static JSONObject get_response(JSONObject body) throws Exception { String urlStr = "https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation"; String apiKey = System.getenv("DASHSCOPE_API_KEY"); // 请使用您自己的API密钥替换这里 URL url = new URL(urlStr); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("POST"); connection.setRequestProperty("Content-Type", "application/json"); connection.setRequestProperty("Authorization", "Bearer " + apiKey); connection.setDoOutput(true); String jsonInputString = body.toString(); try (DataOutputStream wr = new DataOutputStream(connection.getOutputStream())) { wr.write(jsonInputString.getBytes(StandardCharsets.UTF_8)); wr.flush(); } StringBuilder response = new StringBuilder(); try (BufferedReader in = new BufferedReader( new InputStreamReader(connection.getInputStream()))) { String inputLine; while ((inputLine = in.readLine()) != null) { response.append(inputLine); } } JSONObject response_json = new JSONObject(response.toString()); connection.disconnect(); return response_json; } }curl --location 'https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation' \ --header "Authorization: Bearer $DASHSCOPE_API_KEY" \ --header 'Content-Type: application/json' \ --data '{ "model": "qwen-turbo", "input":{ "messages":[ { "role": "system", "content": "You are a helpful assistant." }, { "role": "user", "content": "你好" }, { "role": "assistant", "content": "你好啊,我是通义千问。" }, { "role": "user", "content": "你有哪些技能?" } ] }, "parameters": { "result_format": "message" } }'

当您运行Python或Java程序时,输入问题后点击Enter键获取模型生成的回复,使用过程示例如下图所示:

2024-04-08_18-58-36 (1).gif

流式输出

大模型并不是一次性生成最终结果,而是逐步地生成中间结果,最终结果由中间结果拼接而成。非流式输出方式等待模型生成结束后再将生成的中间结果拼接后返回,而流式输出可以实时地将中间结果返回,您可以在模型进行输出的同时进行阅读,减少等待模型回复的时间。使用流式输出需要您进行一些配置,在请求头headers中配置"X-DashScope-SSE"为"enable",或配置"Accept"为"text/event-stream",即可得到流式输出的效果。

import requests import os import re url = 'https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation' headers = {'Content-Type': 'application/json', 'Authorization': 'Bearer ' + os.getenv("DASHSCOPE_API_KEY"), 'X-DashScope-SSE': 'enable' } body = { "model": "qwen-turbo", "input": { "messages": [ { "role": "system", "content": "You are a helpful assistant." }, { "role": "user", "content": input("请输入:\n") } ] }, "parameters": { "incremental_output": True, "result_format": "message" } } response = requests.post(url, headers=headers, json=body, stream=True) # 使用正则表达式提取模型输出的content pattern = re.compile(r'"content":"(.*?)","role"') http_response = [] print("模型生成回复:") for chunk in response.iter_content(chunk_size=None): chunk = chunk.decode('utf-8') http_response.append(chunk) match = pattern.search(chunk) if match: print(match.group(1), end='', flush=True) print("\nhttp返回结果:") for i in range(len(http_response)): print(http_response[i]) import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Scanner; import java.util.regex.Matcher; import java.util.regex.Pattern; public class Main { private static final String USER_AGENT = "Java-HttpURLConnection/1.0"; public static void main(String[] args) throws Exception { String urlStr = "https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation"; String apiKey = System.getenv("DASHSCOPE_API_KEY"); URL url = new URL(urlStr); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("POST"); connection.setRequestProperty("Content-Type", "application/json"); connection.setRequestProperty("Authorization", "Bearer " + apiKey); connection.setRequestProperty("X-DashScope-SSE", "enable"); connection.setDoOutput(true); Scanner scanner = new Scanner(System.in); System.out.println("请输入:"); String UserInput = scanner.nextLine(); String jsonInputString = String.format("{\"model\": \"qwen-turbo\", \"input\": {\"messages\": [{\"role\": \"system\", \"content\": \"You are a helpful assistant.\"}, {\"role\": \"user\", \"content\": \"%s\"}]}, \"parameters\": {\"result_format\": \"message\",\"incremental_output\":true}}",UserInput); try (DataOutputStream wr = new DataOutputStream(connection.getOutputStream())) { wr.write(jsonInputString.getBytes(StandardCharsets.UTF_8)); wr.flush(); } StringBuilder response = new StringBuilder(); String regex = "\"content\":\"(.*?)\",\"role\""; Pattern pattern = Pattern.compile(regex); ArrayList show_result = new ArrayList(); System.out.println("模型生成回复:"); try (BufferedReader in = new BufferedReader( new InputStreamReader(connection.getInputStream()))) { String inputLine; while ((inputLine = in.readLine()) != null) { response.append(inputLine); Matcher matcher = pattern.matcher(inputLine); show_result.add(inputLine); if (matcher.find()) { String content = matcher.group(1); System.out.print(content); } } System.out.println("\nhttp返回结果:"); } for (int i = 0; i < show_result.size(); i++) { System.out.println(show_result.get(i)); } connection.disconnect(); } }read -p "请输入: " user_content curl --location 'https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation' \ --header "Authorization: Bearer $DASHSCOPE_API_KEY" \ --header "Content-Type: application/json" \ --header "X-DashScope-SSE: enable" \ --data '{ "model": "qwen-turbo", "input":{ "messages":[ { "role": "system", "content": "You are a helpful assistant." }, { "role": "user", "content": "'"$user_content"'" } ] }, "parameters": { "result_format": "message", "incremental_output":true } }'

当您运行Python或Java程序时,输入问题后点击Enter键以获取模型生成的流式输出,并打印出HTTP返回的结果,HTTP返回结果示例如下所示。

id:1 event:result :HTTP_STATUS/200 data:{"output":{"choices":[{"message":{"content":"你好","role":"assistant"},"finish_reason":"null"}]},"usage":{"total_tokens":28,"input_tokens":27,"output_tokens":1},"request_id":"c13ac6fc-9281-9ac4-9f1d-003a38c48e02"} id:2 event:result :HTTP_STATUS/200 data:{"output":{"choices":[{"message":{"content":",","role":"assistant"},"finish_reason":"null"}]},"usage":{"total_tokens":29,"input_tokens":27,"output_tokens":2},"request_id":"c13ac6fc-9281-9ac4-9f1d-003a38c48e02"} ... ... ... ... ... ... ... ... id:12 event:result :HTTP_STATUS/200 data:{"output":{"choices":[{"message":{"content":"","role":"assistant"},"finish_reason":"stop"}]},"usage":{"total_tokens":91,"input_tokens":27,"output_tokens":64},"request_id":"c13ac6fc-9281-9ac4-9f1d-003a38c48e02"}Function call

大模型在面对实时性问题、私域知识型问题或数学计算等问题时可能效果不佳。您可以使用function call功能,通过调用外部工具来提升模型的输出效果。您可以在调用大模型时,通过tools参数传入工具的名称、描述、入参等信息。大模型在收到提示词以及工具信息后,会判断是否需要使用工具:

如果不需要使用工具,大模型不会返回tool_calls参数,您的程序可以直接返回大模型的回答。

如果需要使用工具,大模型会返回一个包含tool_calls字段的信息,您的程序可以根据此信息判断需要调用工具。您的程序需要解析tool_calls信息中包含的工具函数名和入参,并将入参输入到工具函数来得到工具调用的结果。您的程序需要将工具信息按照以下格式配置:

{ "name": "$工具名", "role": "tool", "content": "$工具输出" }

将工具信息添加到历史对话信息中,再次向大模型提问,获得最终回答。

Function call的工作流程示意图如下所示:

image说明

Function call信息暂时不支持增量输出,增量输出请参考输入参数配置中incremental_output参数。

Function call的使用涉及到参数解析功能,因此对大模型的响应质量要求较高,推荐您优先使用qwen-max模型。示例代码如下所示:

import requests import os from datetime import datetime import json # 定义工具列表,模型在选择使用哪个工具时会参考工具的name和description tools = [ # 工具1 获取当前时刻的时间 { "type": "function", "function": { "name": "get_current_time", "description": "当你想知道现在的时间时非常有用。", "parameters": {} # 因为获取当前时间无需输入参数,因此parameters为空字典 } }, # 工具2 获取指定城市的天气 { "type": "function", "function": { "name": "get_current_weather", "description": "当你想查询指定城市的天气时非常有用。", "parameters": { # 查询天气时需要提供位置,因此参数设置为location "type": "object", "properties": { "location": { "type": "string", "description": "城市或县区,比如北京市、杭州市、余杭区等。" } } }, "required": [ "location" ] } } ] # 模拟天气查询工具。返回结果示例:“北京今天是晴天。” def get_current_weather(location): return f"{location}今天是晴天。 " # 查询当前时间的工具。返回结果示例:“当前时间:2024-04-15 17:15:18。“ def get_current_time(): # 获取当前日期和时间 current_datetime = datetime.now() # 格式化当前日期和时间 formatted_time = current_datetime.strftime('%Y-%m-%d %H:%M:%S') # 返回格式化后的当前时间 return f"当前时间:{formatted_time}。" def get_response(messages): api_key = os.getenv("DASHSCOPE_API_KEY") url = 'https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation' headers = {'Content-Type': 'application/json', 'Authorization':f'Bearer {api_key}'} body = { 'model': 'qwen-max', "input": { "messages": messages }, "parameters": { "result_format": "message", "tools": tools } } response = requests.post(url, headers=headers, json=body) return response.json() messages = [ { "role": "user", "content": "今天天气怎么样?" } ] def call_with_messages(): messages = [ { "content": input('请输入:'), # 提问示例:"现在几点了?" "一个小时后几点" "北京天气如何?" "role": "user" } ] # 模型的第一轮调用 first_response = get_response(messages) print(f"\n第一轮调用结果:{first_response}") assistant_output = first_response['output']['choices'][0]['message'] messages.append(assistant_output) if 'tool_calls' not in assistant_output: # 如果模型判断无需调用工具,则将assistant的回复直接打印出来,无需进行模型的第二轮调用 print(f"最终答案:{assistant_output.content}") return # 如果模型选择的工具是get_current_weather elif assistant_output['tool_calls'][0]['function']['name'] == 'get_current_weather': tool_info = {"name": "get_current_weather", "role":"tool"} location = json.loads(assistant_output['tool_calls'][0]['function']['arguments'])['properties']['location'] tool_info['content'] = get_current_weather(location) # 如果模型选择的工具是get_current_time elif assistant_output['tool_calls'][0]['function']['name'] == 'get_current_time': tool_info = {"name": "get_current_time", "role":"tool"} tool_info['content'] = get_current_time() print(f"工具输出信息:{tool_info['content']}") messages.append(tool_info) # 模型的第二轮调用,对工具的输出进行总结 second_response = get_response(messages) print(f"第二轮调用结果:{second_response}") print(f"最终答案:{second_response['output']['choices'][0]['message']['content']}") if __name__ == '__main__': call_with_messages() import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import java.nio.charset.StandardCharsets; import java.util.Scanner; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import org.json.JSONArray; import org.json.JSONObject; public class Main { private static final String USER_AGENT = "Java-HttpURLConnection/1.0"; public static void main(String[] args) throws Exception { // 用户输入问题 Scanner scanner = new Scanner(System.in); System.out.println("请输入:"); String UserInput = scanner.nextLine(); // 初始化messages JSONArray messages = new JSONArray(); // 定义系统信息system_message JSONObject system_message = new JSONObject(); system_message.put("role","system"); system_message.put("content","You are a helpful assistant."); // 根据用户的输入构造user_message JSONObject user_message = new JSONObject(); user_message.put("role","user"); user_message.put("content",UserInput); // 将system_message和user_message依次添加到messages中 messages.put(system_message); messages.put(user_message); // 进行模型的第一轮调用,并打印出结果 JSONObject response_json = get_response(messages); System.out.println("第一轮调用结果:"+response_json); // 获取助手信息assistant_message JSONObject assistant_message = response_json.getJSONObject("output").getJSONArray("choices").getJSONObject(0).getJSONObject("message"); // 初始化工具信息tool_message JSONObject tool_message = new JSONObject(); // 如果assistant_message没有tool_calls参数,则直接打印出assistant_message中的响应信息并返回 if (! assistant_message.has("tool_calls")){ System.out.println("最终答案:"+assistant_message.get("content")); return; } // 如果assistant_message有tool_calls参数,说明模型判断需要调用工具 else { // 将assistant_message添加到messages中 messages.put(assistant_message); // 如果模型判断需要调用get_current_weather函数 if (assistant_message.getJSONArray("tool_calls").getJSONObject(0).getJSONObject("function").getString("name").equals("get_current_weather")) { // 获取参数arguments信息,并提取出location参数 JSONObject arguments_json = new JSONObject(assistant_message.getJSONArray("tool_calls").getJSONObject(0).getJSONObject("function").getString("arguments")); String location = arguments_json.getJSONObject("properties").getString("location"); // 运行工具函数,得到工具的输出,并打印 String tool_output = get_current_weather(location); System.out.println("工具输出信息:"+tool_output); // 构造tool_message信息 tool_message.put("name","get_current_weather"); tool_message.put("role","tool"); tool_message.put("content",tool_output); } // 如果模型判断需要调用get_current_time函数 if (assistant_message.getJSONArray("tool_calls").getJSONObject(0).getJSONObject("function").getString("name").equals("get_current_time")) { // 运行工具函数,得到工具的输出,并打印 String tool_output = get_current_time(); System.out.println("工具输出信息:"+tool_output); // 构造tool_message信息 tool_message.put("name","get_current_time"); tool_message.put("role","tool"); tool_message.put("content",tool_output); } } // 将tool_message添加到messages中 messages.put(tool_message); // 进行模型的第二轮调用,并打印出结果 JSONObject second_response = get_response(messages); System.out.println("第二轮调用结果:"+second_response); System.out.println("最终答案:"+second_response.getJSONObject("output").getJSONArray("choices").getJSONObject(0).getJSONObject("message").getString("content")); } // 定义获取天气的函数 public static String get_current_weather(String location) { return location+"今天是晴天"; } // 定义获取当前时间的函数 public static String get_current_time() { LocalDateTime now = LocalDateTime.now(); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); String currentTime = "当前时间:" + now.format(formatter) + "。"; return currentTime; } // 封装模型响应函数,输入:messages,输出:json格式化后的http响应 public static JSONObject get_response(JSONArray messages) throws Exception{ // 初始化工具库 JSONArray tools = new JSONArray(); // 定义工具1:获取当前时间 String jsonString_time = "{\"type\": \"function\", \"function\": {\"name\": \"get_current_time\", \"description\": \"当你想知道现在的时间时非常有用。\", \"parameters\": {}}}"; JSONObject get_current_time_json = new JSONObject(jsonString_time); // 定义工具2:获取指定地区天气 String jsonString_weather = "{\"type\": \"function\", \"function\": {\"name\": \"get_current_weather\", \"description\": \"当你想查询指定城市的天气时非常有用。\", \"parameters\": {\"type\": \"object\", \"properties\": {\"location\": {\"type\": \"string\", \"description\": \"城市或县区,比如北京市、杭州市、余杭区等。\"}}}, \"required\": [\"location\"]}}"; JSONObject get_current_whether_json = new JSONObject(jsonString_weather); // 将两个工具添加到工具库中 tools.put(get_current_time_json); tools.put(get_current_whether_json); String toolsString = tools.toString(); // 接口调用URL String urlStr = "https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation"; // 通过环境变量获取DASHSCOPE_API_KEY String apiKey = System.getenv("DASHSCOPE_API_KEY"); URL url = new URL(urlStr); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("POST"); // 定义请求头信息 connection.setRequestProperty("Content-Type", "application/json"); connection.setRequestProperty("Authorization", "Bearer " + apiKey); connection.setDoOutput(true); // 定义请求体信息 String jsonInputString = String.format("{\"model\": \"qwen-max\", \"input\": {\"messages\":%s}, \"parameters\": {\"result_format\": \"message\",\"tools\":%s}}",messages.toString(),toolsString); // 获取http响应response try (DataOutputStream wr = new DataOutputStream(connection.getOutputStream())) { wr.write(jsonInputString.getBytes(StandardCharsets.UTF_8)); wr.flush(); } StringBuilder response = new StringBuilder(); try (BufferedReader in = new BufferedReader( new InputStreamReader(connection.getInputStream()))) { String inputLine; while ((inputLine = in.readLine()) != null) { response.append(inputLine); } } connection.disconnect(); // 返回json格式化后的response return new JSONObject(response.toString()); } }入参描述

您可以参考下表参考输入参数的配置。其中数据类型列的字段含义如下所示:

string表示字符串类型;

array表示数组;

integer表示整数型;

float表示浮点型;

boolean表示布尔型;

object表示哈希表。

传参方式

字段

数据类型

必选

描述

示例值

Header

Content-Type

string

请求类型:application/json

"Content-Type":"application/json"

Accept

string

选择text/event-stream则会开启SSE响应,默认无设置。

"Accept":"text/event-stream"

Authorization

string

API-KEY,例如:Bearer d1**2a

"Authorization":"Bearer d1**2a"

X-DashScope-SSE

string

设置为enable或者设置Accept: text/event-stream即可启用SSE响应。

"X-DashScope-SSE":"enable"

Body

model

string

指定用于对话的通义千问模型名,目前可选择qwen-turbo、qwen-plus、qwen-max、qwen-max-0403、qwen-max-0107、qwen-max-1201和qwen-max-longcontext。

"model":"qwen-turbo"

input

object

输入模型的信息。

input.prompt

说明

字段中的点号(.)表示后者为前者的属性。在API测试工具中,并不能直接将Key设置为input.prompt。传入方式为"input":{"prompt":"xxx"}。

string

用户当前输入的期望模型执行指令,支持中英文。与inpussages指定其中一个即可。

"input":{"prompt":"你好"}

input.history

array

即将废弃,请使用messages字段用户与模型的对话历史,array中的每个元素形式为{"user":"用户输入","bot":"模型输出"}的一轮对话,多轮对话按时间正序排列。

"input":{"history":[{"user":"今天天气好吗?",

"bot":"今天天气不错,要出去玩玩嘛?"},

{"user":"那你有什么地方推荐?",

"bot":"我建议你去公园,春天来了,花朵开了,很美丽。"}]}

inpussages

array

表示用户与模型的对话历史。array中的每个元素形式为{"role":角色, "content": 内容},如果role为tool,元素形式为:

{"role":"tool","content":内容,"name":工具函数名}

角色可选值:system、user、assistant和tool。

"input":{

"messages":[

{

"role": "system",

"content": "You are a helpful assistant."

},

{

"role": "user",

"content": "你好,附近哪里有博物馆?"

}]

}

inpussages.role

string

messages存在的时候不能省略。

inpussages.content

string

inpussages.name

string

inpussages.role为tool时不能省略

role为tool表示当前message为function_call的调用结果,name是工具函数名,需要和上轮response中的tool_calls[i].function.name参数保持一致,content为工具函数的输出。参考代码的多轮调用给出了示例。

parameters

object

用于控制模型生成的参数

parameters.result_format

string

用于指定返回结果的格式,默认为text,也可设置为message。当设置为message时,输出格式请参考返回结果。推荐优先使用message格式。

"parameters":{"result_format":"message"}

parameters.seed

integer

生成时使用的随机数种子,用户控制模型生成内容的随机性。seed支持无符号64位整数。在使用seed时,模型将尽可能生成相同或相似的结果,但目前不保证每次生成的结果完全相同。

"parameters":{"seed":666}

parameters.max_tokens

integer

用于限制模型生成token的数量,表示生成token个数的上限。其中qwen-turbo最大值和默认值为1500,qwen-max、qwen-max-1201 、qwen-max-longcontext 和 qwen-plus最大值和默认值均为2000。

"parameters":{"max_tokens":1500}

parameters.top_p

float

生成时,核采样方法的概率阈值。例如,取值为0.8时,仅保留累计概率之和大于等于0.8的概率分布中的token,作为随机采样的候选集。取值范围为(0,1.0),取值越大,生成的随机性越高;取值越低,生成的随机性越低。注意,取值不要大于等于1。

"parameters":{"top_p":0.7}

parameters.top_k

integer

生成时,采样候选集的大小。例如,取值为50时,仅将单次生成中得分最高的50个token组成随机采样的候选集。取值越大,生成的随机性越高;取值越小,生成的确定性越高。注意:如果top_k参数为空或者top_k的值大于100,表示不启用top_k策略,此时仅有top_p策略生效。

"parameters":{"top_k":50}

parameters.repetition_penalty

float

用于控制模型生成时连续序列中的重复度。提高repetition_penalty时可以降低模型生成的重复度。1.0表示不做惩罚。没有严格的取值范围。

"parameters":{"repetition_penalty":1.0}

parameters.presence_penalty

float

用户控制模型生成时整个序列中的重复度。提高presence_penalty时可以降低模型生成的重复度,取值范围 [-2.0, 2.0]。

"parameters":{"presence_penalty":1.0}

parameters.temperature

float

用于控制随机性和多样性的程度。具体来说,temperature值控制了生成文本时对每个候选词的概率分布进行平滑的程度。较高的temperature值会降低概率分布的峰值,使得更多的低概率词被选择,生成结果更加多样化;而较低的temperature值则会增强概率分布的峰值,使得高概率词更容易被选择,生成结果更加确定。

取值范围:[0, 2),不建议取值为0,无意义。

"parameters":{"temperature":0.85}

parameters.stop

string/array

stop参数用于实现内容生成过程的精确控制,在模型生成的内容即将包含指定的字符串或token_id时自动停止,生成的内容不包含指定的内容。stop可以为string类型或array类型。

string类型

当模型将要生成指定的stop词语时停止。

例如将stop指定为"你好",则模型将要生成“你好”时停止。

array类型

array中的元素可以为token_id或者字符串,或者元素为token_id的array。当模型将要生成的token或其对应的token_id在stop中时,模型生成将会停止。

例如将stop指定为["你好","天气"]或者[108386,104307],则模型将要生成“你好”或者“天气”时停止。如果将stop指定为[[108386, 103924],[35946, 101243]],则模型将要生成“你好啊”或者“我很好”时停止。

说明

stop为array类型时,不可以将token_id和字符串同时作为元素输入,比如不可以指定stop为["你好",104307]。

"parameters":{"stop":["你好","天气"]}

parameters.enable_search

boolean

模型内置了互联网搜索服务,该参数控制模型在生成文本时是否参考使用互联网搜索结果。取值如下:

true:启用互联网搜索,模型会将搜索结果作为文本生成过程中的参考信息,但模型会基于其内部逻辑“自行判断”是否使用互联网搜索结果。

false(默认):关闭互联网搜索。

"parameters":{"enable_search":false}

parameters.incremental_output

boolean

控制在流式输出模式下是否开启增量输出,即后续输出内容是否包含已输出的内容。设置为True时,将开启增量输出模式,后面输出不会包含已经输出的内容,您需要自行拼接整体输出;设置为False则会包含已输出的内容。

默认False:

I

I like

I like apple

True:

I

like

apple

该参数只能在开启SSE响应时使用。

说明

incremental_output暂时无法和tools参数同时使用。

"parameters":{"incremental_output":false}

parameters.tools

array

用于指定可供模型调用的工具列表。当输入多个工具时,模型会选择其中一个生成结果。tools中每一个tool的结构如下:

type,类型为string,表示tools的类型,当前仅支持function。

function,类型为object,键值包括name,description和parameters:

name:类型为string,表示工具函数的名称,必须是字母、数字,可以包含下划线和短划线,最大长度为64。

description:类型为string,表示工具函数的描述,供模型选择何时以及如何调用工具函数。

parameters:类型为object,表示工具的参数描述,需要是一个合法的JSON Schema。JSON Schema的描述可以见链接。参考代码中给出了一个参数描述的示例。如果parameters参数为空,表示function没有入参。

使用tools时需要同时指定result_format为message。在function call流程中,无论是发起function call的轮次,还是向模型提交工具函数的执行结果,均需设置tools参数。当前支持的模型包括qwen-turbo、qwen-plus、qwen-max和qwen-max-longcontext。

说明

tools暂时无法和incremental_output参数同时使用。

"parameters":{"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" ] } } } ]}

parameters.tool_choice

string/object

在使用tools参数时,用于控制模型调用指定工具。有四种取值:

none表示不调用工具。tools参数为空时,默认值为none。

auto表示模型判断是否调用工具,可能调用也可能不调用。tools参数不为空时,默认值为auto。

object结构可以指定模型调用指定工具。例如{"type": "function", "function": {"name": "user_function"}}

type现在只支持function

function

name表示期望被调用的工具名称

说明

当前支持qwen-max/qwen-max-0428/qwen-max-0403/qwen-plus/qwen-turbo

{"type": "function", "function": {"name": "user_function"}}

出参描述

字段

数据类型

描述

示例值

output.text

string

模型输出的内容。当result_format设置为text时返回该字段。

我建议你去颐和园

output.finish_reason

string

有三种情况:正在生成时为null,生成结束时如果由于停止token导致则为stop,生成结束时如果因为生成长度过长导致则为length。当result_format设置为text时返回该字段。

stop

output.choices

array

当result_format设置为message时返回该字段。

普通示例

{ "choices": [ { "finish_reason": "null", "message": { "role": "assistant", "content": "周围的咖啡馆在..." } } ] }

function call示例

{ "choices": [ { "finish_reason": "tool_calls", "message": { "role": "assistant", "content": "", "tool_calls": [ { "function": { "name": "get_current_weather", "arguments": "{\"location\": \"Boston\", \"unit\": \"fahrenheit\"}" }, "type": "function" } ] } } ] }

output.choices[x].finish_reason

string

停止原因,null:生成过程中

stop:stop token导致结束

length:生成长度导致结束

output.choices[x].message

object

message每个元素形式为{"role":角色, "content": 内容}。角色可选值:system、user、assistant。content为模型输出的内容。

output.choices[x].message.role

string

output.choices[x].message.content

string

output.choices[x].message.tool_calls

object

如果模型需要调用工具,则会生成tool_calls参数,应用于function_call场景。其中包含type和function两个参数,返回结果中给出了function_call的示例。参数详情如下::

type,类型为string,当前只可能为function

function,类型为dict,包含name和arguments两个参数:

name,类型为string,表示需要调用的工具的名称,如果是function_call场景则表示要调用的function名称

arguments,类型为string,表示模型生成的工具入参,在Python中可以使用json.loads方法转化为字典类型。

usage

object

本次调用使用的token信息。

usage.output_tokens

integer

模型输出内容的 token个数。

380

usage.input_tokens

integer

本次请求输入内容的token个数。在enable_search设置为true时,输入的 token 数目由于需要添加搜索相关内容,因此会比您在请求中的输入token个数多。

633

usage.total_tokens

integer

usage.output_tokens与usage.input_tokens的总和。

1013

request_id

string

本次请求的系统唯一码。

7574ee8f-38a3-4b1e-9280-11c33ab46e51

异常响应示例

在访问请求出错的情况下,输出的结果中会通过code和message指明错误原因。

{ "code":"InvalidApiKey", "message":"Invalid API-key provided.", "request_id":"fb53c4ec-1c12-4fc4-a580-cdb7c3261fc1" }状态码说明

DashScope灵积模型服务通用状态码详情,请参见返回状态码说明。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有