需选用支持function calling的千问模型(如qwen-max-20240919),严格按openai-style定义tools,调用时传入tools和tool_choice参数,解析response中的tool_calls并执行对应函数,再将结果以tool角色注入上下文发起第二轮调用生成最终回复。
☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 多模态理解力帮你轻松跨越从0到1的创作门槛☜☜☜

如果您正在开发需要调用外部工具的通义千问智能体应用,但模型无法识别用户意图并生成结构化函数调用指令,则可能是由于工具定义格式错误、模型未启用Function Calling模式、或响应解析逻辑缺失所致。以下是实现千问函数调用的具体操作路径:
一、确认模型支持Function Calling并选择合适版本
并非所有千问模型均原生支持函数调用能力,需选用明确标注该能力的模型版本,以确保推理过程中可输出符合OpenAI-style规范的function_call字段。此为后续工具调度与执行的基础前提。
1、访问DashScope模型列表页,筛选支持Function Calling的模型,如qwen-max-20240919、qwen-plus-20240919或qwen3-14b(本地部署场景)。
2、在API调用中显式指定model参数值,例如:model="qwen-max-20240919",不可使用qwen-turbo等不支持该能力的轻量模型。
3、验证模型是否返回function_call字段:向模型发送含明确工具调用意图的prompt,如“查杭州天气”,检查response.output.choices[0].message.content中是否包含JSON格式的function_call对象。
二、定义工具函数并构造tools参数列表
工具定义必须严格遵循OpenAI-style JSON Schema格式,包含name、description、parameters三要素,且parameters须为合法JSON Schema object类型。此结构用于引导模型理解可用能力边界及参数约束。
1、编写Python函数,例如获取天气信息:def get_weather(city: str) -> dict:,内部实现HTTP请求调用第三方天气API。
2、将该函数封装为tools列表中的一个字典项,其结构如下:{"type": "function", "function": {"name": "get_weather", "description": "查询指定城市的实时天气", "parameters": {"type": "object", "properties": {"city": {"type": "string", "description": "城市名称,如杭州、北京"}, "unit": {"type": "string", "enum": ["celsius", "fahrenheit"], "default": "celsius"}}, "required": ["city"]}}。
3、确保tools列表中每个工具的name字段为纯ASCII字符串,不含空格或特殊符号,且与后续实际调用的函数名完全一致。
三、调用Generation接口并传入tools与tool_choice参数
启用函数调用需在SDK调用中显式注入tools参数,并设置tool_choice策略,否则模型默认忽略工具定义,仅返回自然语言响应。此步骤决定模型是否进入工具决策流程。
1、导入dashscope模块并初始化:from dashscope import Generation。
2、构造调用语句,必须同时包含tools和tool_choice参数:response = Generation.call(model="qwen-max-20240919", prompt="杭州现在温度多少度?", tools=tools, tool_choice="auto")。
3、tool_choice可选值为"auto"(由模型自主判断)、"none"(禁用工具)或指定工具名字符串(强制调用某工具),生产环境推荐使用"auto"。
四、解析模型响应并执行对应工具函数
模型返回内容可能为纯文本响应,也可能为包含function_call字段的结构化指令。需先判断响应类型,再决定是否触发本地工具调用,避免误执行或跳过关键动作。
1、检查response.output.choices[0].message.tool_calls是否存在且非空,若存在则进入工具调用分支。
2、遍历tool_calls列表,提取每个元素的function.name与function.arguments字段。
3、根据name字段映射到预定义的Python函数,使用json.loads解析arguments字符串后传入调用,例如:result = get_weather(**json.loads(tool_call.function.arguments))。
五、将工具执行结果注入上下文并发起第二轮调用
工具返回原始数据后不能直接呈现给用户,需将其作为新的消息角色“tool”插入历史对话,再发起一次模型调用,由模型融合工具结果生成自然语言回复。此为完成闭环的关键步骤。
1、构造新消息列表,包含原始user消息、模型返回的tool_calls消息、以及新增的tool消息:{"role": "tool", "content": json.dumps(result), "tool_call_id": tool_call.id}。
2、将该完整消息列表传入Generation.call的input.messages参数,再次调用同一模型。
3、第二轮响应的output.text即为最终面向用户的自然语言答案,例如:“杭州当前气温为26摄氏度,晴朗无云。”











