要实现千问AI在对话中自动调用外部工具执行真实操作(例如查询天气、发送邮件或读取数据库),需要完成两个核心环节:结构化工具声明与运行时联动。简单来说,首先要用模型能够理解的格式告知它可用工具,然后将这些实际函数注册到系统中,最后发起请求并处理模型的响应。

定义符合OpenAI格式的工具描述(JSON Schema规范)
第一步,使用JSON Schema清晰地定义工具的功能、名称和所需参数。模型仅识别这种格式,自然语言描述无法被理解。
工具描述必须包含 【name、description、parameters三个字段,缺一不可】,其中description字段应以具体动词开头,例如“获取北京当前温度”,避免使用“提供气象服务”等模糊表述。参数定义清晰,模型才能准确调用。
parameters字段必须声明type为"object",并且在properties中为每个参数指定类型(string/number/boolean)以及是否必填(required)。遗漏required字段会导致模型传递空值,进而调用失败。
将写好的工具对象放入tools数组,例如:[{"type":"function","function":{"name":"get_weather","description":"获取指定城市的当前天气","parameters":{"type":"object","properties":{"city":{"type":"string","description":"城市名称,如上海"}},"required":["city"]}}} ]
通过DashScope SDK注册Python函数(自动提取工具定义)
如果你本地已有现成的Python函数,使用DashScope SDK注册比手动编写JSON Schema更高效可靠——SDK会自动从函数签名和文档字符串中提取name、description和parameters。
方法一:用 @tool 装饰器注册
在函数上方添加@tool装饰器,函数名自动成为工具名称,文档字符串的第一行作为description,类型注解生成parameters结构。操作非常简单,直接拖入文件即可。
方法二:用 dashscope.Tool.register() 显式注册
调用dashscope.Tool.register(get_weather),SDK将扫描函数体并生成完整的工具定义。注意函数必须包含明确的类型提示(type hint),否则parameters将缺失类型信息,导致模型调用时报错。
发起带工具的API请求并解析响应(完整流程)
第一步:构造请求体
调用dashscope.Generation.call()时,需传入messages(包含用户输入)、tools(上一步定义的工具列表)以及tool_choice="auto"参数。
第二步:判断是否触发调用
检查response.choices[0].message.tool_calls是否存在。如果为空,表示模型认为无需调用工具,直接返回content即可。
第三步:提取并执行工具
遍历tool_calls,使用function.name匹配已注册的工具,通过json.loads(function.arguments)解析参数,然后以关键字参数方式调用对应函数。
第四步:注入工具结果并二次请求
将函数返回值构造成tool_message,格式如下:{"role": "tool", "content": '{"temperature": 32.1, "unit": "celsius"}', "tool_call_id": "call_abc123"},连同原始messages一起发起第二轮call,这样模型才能基于真实数据生成最终回答。
