Qwen-Agent的使用示例-天气查询
Qwen-Agent的使用示例-天气查询
- 代码解释
- 1. 代码结构和初始化
- 2. Assistant 初始化
- 3. 参数传递流程
- 4. 数据流转过程
- Qwen-Agent中Assistant是如何分析和构造参数的
- 1. Assistant的基本架构
- 2. 参数分析过程
- 3. 参数构造过程
- 4. 工具注册机制
- 5. 参数验证和错误处理
- 工作原理总结
- 示例代码的调用过程 :
- 示例代码的数据流转 :
先上代码,
#!/usr/bin/env python
# -*- coding: utf-8 -*-"""
Qwen-Agent的使用示例
"""import os
import json
from typing import Dict, Any
from functools import lru_cache
from qwen_agent.agents import Assistant# 使用LRU缓存优化天气数据查询
@lru_cache(maxsize=100)
def get_weather(city: str) -> Dict[str, Any]:"""模拟天气查询功能,使用LRU缓存提高性能"""weather_data = {"北京": {"temperature": "26°C", "condition": "晴朗"},"上海": {"temperature": "28°C", "condition": "多云"},"广州": {"temperature": "30°C", "condition": "小雨"}}if city in weather_data:return weather_data[city]return {"error": f"没有找到{city}的天气信息"}# 创建自定义工具类
from qwen_agent.tools.base import BaseTool, register_tool@register_tool('get_weather')
class WeatherTool(BaseTool):description = "获取指定城市的天气信息"parameters = {'type': 'object','properties': {'city': {'type': 'string','description': '城市名称'}},'required': ['city']}def call(self, params: str, **kwargs) -> Dict[str, Any]:try:args = json.loads(params)return get_weather(args['city'])except json.JSONDecodeError:return {"error": "参数解析失败"}except Exception as e:return {"error": f"查询天气失败: {str(e)}"}# 创建Assistant实例
assistant = Assistant(llm={'model': 'qwen-max','model_type': 'qwen_dashscope','api_key': os.getenv("DASHSCOPE_API_KEY") # 若没有配置环境变量,请用百炼API Key将下行替换为:api_key="sk-xxx"},function_list=['get_weather'])# 示例使用
if __name__ == "__main__":# 初始化对话历史# messages = [{'role': 'system', 'content': 'You are a helpful assistant.'}]messages = []# # 测试Agent对话user_query = "我应该带伞出门吗?我在广州。"print(f"\n用户: {user_query}")messages.append({"role": "user", "content": user_query})final_response = Nonefor response in assistant.run(messages):if isinstance(response, list):# 获取列表中最后一个回复final_response = response[-1]if isinstance(final_response, dict) and "content" in final_response:messages.append(final_response)print(f"Agent: {final_response['content']}")
代码解释
1. 代码结构和初始化
1.工具函数定义 :
def get_weather(city: str) -> Dict[str, Any]:"""模拟天气查询功能,使用LRU缓存提高性能"""weather_data = {"北京": {"temperature": "26°C", "condition": "晴朗"},"上海": {"temperature": "28°C", "condition": "多云"},"广州": {"temperature": "30°C", "condition": "小雨"}}if city in weather_data:return weather_data[city]return {"error": f"没有找到{city}的天气信息"}
这是一个基础工具函数,模拟天气查询功能,接收城市名称作为参数,返回对应的天气信息。
2.工具类封装 :
@register_tool('get_weather')
class WeatherTool(BaseTool):description = "获取指定城市的天气信息"parameters = {'type': 'object','properties': {'city': {'type': 'string','description': '城市名称'}},'required': ['city']}
- 使用装饰器 @register_tool 注册工具
- 继承 BaseTool 基类
- 定义工具描述和参数规范
2. Assistant 初始化
llm={'model': 'qwen-max','model_type': 'qwen_dashscope','api_key': os.getenv("DASHSCOPE_API_KEY") # 若没有配置环境变量,请用百炼API Key将下行替换为:api_key="sk-xxx"},function_list=['get_weather'])
- 配置模型参数(模型类型、API密钥)
- 注册可用工具列表
3. 参数传递流程
- 用户输入处理 :
user_query = "我应该带伞出门吗?我在广州。"messages.append({"role": "user", "content": user_query})
- 用户查询被封装成标准消息格式
- 添加到对话历史列表
- 工具调用流程 :
- Assistant 接收到查询后,分析需要调用的工具
- 通过 WeatherTool 的 call 方法调用工具:
def call(self, params: str, **kwargs) -> Dict[str, Any]:try:args = json.loads(params)return get_weather(args['city'])except json.JSONDecodeError:return {"error": "参数解析失败"}except Exception as e:return {"error": f"查询天气失败: {str(e)}"}
- 参数以 JSON 字符串形式传递,解析后调用底层函数
- 响应处理 :
final_response = Nonefor response in assistant.run(messages):if isinstance(response, list):# 获取列表中最后一个回复final_response = response[-1]if isinstance(final_response, dict) and "content" in final_response:messages.append(final_response)# print(f"Agent: {final_response['content']}")print(f"Agent: {final_response['content']}")
- assistant.run() 返回生成器对象,支持流式输出
- 检查响应类型,将有效回复添加到对话历史
4. 数据流转过程
- 用户输入 → 消息历史
- 消息历史 → Assistant 分析
- Assistant 调用工具 → 获取天气数据
- 天气数据 → Assistant 生成回复
- 回复 → 消息历史(保存)+ 控制台(显示)
Qwen-Agent中Assistant是如何分析和构造参数的
1. Assistant的基本架构
Assistant是Qwen-Agent框架中的一个高级组件,继承自基础的Agent类 ,它主要负责:
- 接收用户输入
- 分析用户意图
- 决定是否需要调用工具
- 构造工具调用参数
- 处理工具返回结果
2. 参数分析过程
-
消息处理 :
- Assistant接收messages列表作为输入
- 每条消息都包含role(角色)和content(内容)
- 例如: {“role”: “user”, “content”: “我应该带伞出门吗?我在广州。”}
-
意图理解 :
- 通过配置的LLM(本例中是qwen-max)分析用户输入
- 理解用户真实需求(如需要查询天气来决定是否带伞)
- 识别需要调用的工具(如get_weather工具)
3. 参数构造过程
-
工具选择 :
- 从注册的 function_list 中选择合适的工具
- 本例中通过 @register_tool(‘get_weather’) 注册了WeatherTool
-
参数映射 :
- 根据工具的 parameters 定义构造参数
- WeatherTool定义了必需的 city 参数
- 从用户输入中提取城市信息(“广州”)
- 构造符合JSON格式的参数字符串
-
调用转换 :
- WeatherTool的 call 方法接收参数字符串
- 使用 json.loads 解析参数
- 调用底层 get_weather 函数获取结果
4. 工具注册机制
@register_tool('get_weather')
class WeatherTool(BaseTool):description = "获取指定城市的天气信息"parameters = {'type': 'object','properties': {'city': {'type': 'string','description': '城市名称'}},'required': ['city']}
这个注册过程定义了:
- 工具名称:get_weather
- 工具描述:用于LLM理解工具用途
- 参数结构:指定了必需的参数及其类型
5. 参数验证和错误处理
- 参数格式验证:确保符合工具定义的schema
- JSON解析处理:使用try-except处理可能的解析错误
- 参数完整性检查:确保必需参数都已提供
工作原理总结
整个过程是一个"理解-决策-执行"的闭环:
- LLM理解用户意图
- 根据意图选择合适的工具
- 从用户输入中提取必要信息
- 构造规范的参数格式
- 执行工具调用
- 处理返回结果
示例代码的调用过程 :
- 当用户询问"我应该带伞出门吗?我在广州。"时
- Assistant 分析出需要查询广州的天气
- 构造参数: {“city”: “广州”}
- 这个参数被转换为字符串传递给 call 方法
- call 方法解析参数并调用 get_weather
- get_weather 返回广州的天气数据
- Assistant 根据天气数据生成回答
示例代码的数据流转 :
用户输入 → Assistant分析 → 构造参数 → call方法 → get_weather → 返回天气数据 → Assistant生成回答