目录
- 一、前言
- 二、准备工作
- 三、Agent结构
- 四、python模块实现
- 4.1 实现手机号归属地查询工具
- 4.2实现天气查询工具
- 4.3定义创建Agent主体
- 4.4创建聊天界面
- 五、小结
- PS.扩展阅读
- ps1.六自由度机器人相关文章资源
- ps2.四轴机器相关文章资源
- ps3.移动小车相关文章资源
- ps3.wifi小车控制相关文章资源
一、前言
在本文中,我们将逐步实现一个手机号归属地天气查询agent。这个agent将能够接收用户的手机号输入,自动查询该手机号的归属地,并进一步根据获取的城市信息查询该地区的实时天气信息。我们将使用Python语言,并结合qwen_agent库,及fastapi服务来实现这个功能。
二、准备工作
首先,确保你已经安装了Python环境和以下库:
- qwen_agent:用于创建agent的框架。
- requests:用于发送HTTP请求。
- phone:用于查询手机号归属地
- json:用于处理JSON数据。
- re:用于正则表达式匹配。
- 本地大模型服务:ollama本地大模型管理软件及qwen大模型。
- fastapi:用户构建web前端聊天界面
如果还没有安装这些库,可以通过以下命令安装:
pip install qwen_agent requests #其它所需的模块
这里如果没有装所需的库,运行时会提示,根据提示安装缺的库即可。
没有ollama也先去安装ollama并运行qwen大模型,过程非常简单,网上很多,不再赘述。
三、Agent结构
qwen智能体基本结构是这样的:先定义工具类tools,然后定义智能体的任务描述,然后创建一个智能体,再然后就是web发布智能体服务,进行双向通讯。
四、python模块实现
4.1 实现手机号归属地查询工具
我们首先定义一个工具MobileAddress,用于查询手机号的归属地。这个工具将使用phone库的API调用来获取归属地信息。
@register_tool('get_mobile_address')
class MobileAddress(BaseTool):
description = '手机号归属地查询服务,输入手机号,返回该手机号的归属地。'
parameters = [{
'name': 'mobile',
'type': 'string',
'description': '输入的手机号',
'required': True
}]
def call(self, params: str, **kwargs) -> str:
print("调用了function:", len(params))
print("字符串内容:",params)
try:
params_json = json.loads(params[:-1])
prompt = params_json["mobile"]
print("转化后的号码:", prompt)
except json.JSONDecodeError as e:
print("JSON解析错误:", e)
return "参数格式错误"
res=p.find(prompt)
print("原始查询结果:",res)
return res
4.2实现天气查询工具
接下来,我们定义另一个工具WeatherByAddress,用于根据城市名称查询天气信息。这个工具将使用另一个外部API来获取天气数据。
@register_tool('get_weather')
class WeatherByAddress(BaseTool):
description = '根据提供的城市名称,查找代码,并通过互联网请求查询天气信息。'
parameters = [{'name': 'city', 'type': 'string', 'description': '城市名称', 'required': True}]
def call(self, params: str, **kwargs) -> str:
try:
params_json = json.loads(params)
city_name = params_json["city"]
# 假设我们有一个城市代码的映射字典
city_code = {'Beijing': '101010100'} # 示例代码
url = f'https://www.weather.com.cn/weather1d/{city_code[city_name]}.shtml'
response = requests.get(url)
if response.status_code == 200:
html_content = response.text
match = re.search(r'var hour3data=(\{.*?\});', html_content)
if match:
hour3data = match.group(1)
return hour3data
else:
return "未找到天气小时数据"
else:
return "请求失败,状态码: {}".format(response.status_code)
except json.JSONDecodeError as e:
return "参数格式错误"
4.3定义创建Agent主体
最后,我们创建一个Assistant实例,这个agent将使用我们定义的工具来处理用户的输入,并返回归属地和天气信息。
from qwen_agent.agents import Assistant
# 配置LLM
llm_cfg = {
'model': 'qwen',#这里可以根据自己的大模型类型修改配置参数
'model_server': 'http://localhost:11434/v1',#这里可以根据自己的大模型类型修改配置参数
'generate_cfg': {'top_p': 0.8}
}
# 创建agent
system_instruction = '你扮演一个助手,会调用工具,首先获取用户输入的手机号码,并调用手机号归属地查询服务工具获得城市地址,然后再调用天气查询工具获得所在城市的天气信息,最后进行整理,输出手机归属地和天气信息'
tools = ['get_mobile_address', 'get_weather']
bot = Assistant(llm=llm_cfg, system_message=system_instruction, description='function calling', function_list=tools)
4.4创建聊天界面
我们将使用FastAPI来创建一个简单的Web界面,用户可以通过这个界面输入手机号,并获取归属地和天气信息。
from fastapi import FastAPI, Request, Form
from fastapi.responses import HTMLResponse
from fastapi.templating import Jinja2Templates
app = FastAPI()
templates = Jinja2Templates(directory="templates")
@app.get("/", response_class=HTMLResponse)
async def read_root(request: Request):
return templates.TemplateResponse("chat.html", {"request": request})
@app.post("/chat")
async def chat(message: str = Form(...)):
messages = [{'role': 'user', 'content': message}]
responses = bot.run(messages=messages)
return {"responses": [content['content'] for content in responses]}
# 运行FastAPI应用
if __name__ == '__main__':
import uvicorn
uvicorn.run(app, host='0.0.0.0', port=9000, workers=1)
创建一个简单的html页面,如下:
<!DOCTYPE html>
<html>
<head>
<title>Chat Interface</title>
<script>
function send_message() {
var message = document.getElementById("message").value;
if (message.trim() === "") {
alert("Message cannot be empty!");
return;
}
fetch("/chat", {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body: "message=" + encodeURIComponent(message),
})
.then(response => {
if (!response.ok) {
throw new Error("Network response was not ok");
}
return response.json();
})
.then(data => {
var responses = data.responses;
var chat_window = document.getElementById("chat-window");
responses.forEach(response => {
var response_div = document.createElement("div");
response_div.innerText = response; // Fixed to access response directly
chat_window.appendChild(response_div);
});
document.getElementById("message").value = "";
chat_window.scrollTop = chat_window.scrollHeight;
})
.catch(error => console.error("Error:", error));
}
</script>
</head>
<body>
<div id="chat-window" style="width: 80%; height: 400px; border: 1px solid #000; overflow-y: scroll;"></div>
<input type="text" id="message" placeholder="Type a message..." style="height: 100px;width: 80%;">
<button onclick="send_message()" style="background-color: blue; color: white; font-size: larger; padding: 10px 20px;">Send</button>
</body>
</html>
五、小结
至此,我们实现了一个anget,他可以接收我们输入的电话号码,并且调用本地大模型进行处理,先是调用一个手机号码归属地查询tool,再去调用一个天气查询爬虫tool,最后大模型综合tool的反馈信息进行整合后输出给用户。以上是简单的实现,为了更加的准确好用需要进一步优化,包括qwen-anget本身好像有点问题,有时候只能调用一个手机号码归属地函数发挥不是很稳定因此需要优化prompt,第二,可以加入更多检查工具,比如,输入的号码检查,让大模型自己先检查一下对不对,比如对回答进行一些过滤,过滤掉不必要的信息等。
本篇所有源码及安装虚拟python环境已经打包上传解压运行,下载链接
[------------本篇完-------------]
PS.扩展阅读
————————————————————————————————————————
对于python机器人编程感兴趣的小伙伴,可以进入如下链接阅读相关咨询
ps1.六自由度机器人相关文章资源
(1) 对六自由度机械臂的运动控制及python实现(附源码)
(2) N轴机械臂的MDH正向建模,及python算法
ps2.四轴机器相关文章资源
(1) 文章:python机器人编程——用python实现一个写字机器人
(2)python机器人实战——0到1创建一个自动是色块机器人项目-CSDN直播
(3)博文《我从0开始搭建了一个色块自动抓取机器人,并实现了大模型的接入和语音控制-(上基础篇)》的vrep基础环境
(3)博文《我从0开始搭建了一个色块自动抓取机器人,并实现了大模型的接入和语音控制-(上基础篇)》的vrep基础环境
(4)实现了语音输入+大模型指令解析+机器视觉+机械臂流程打通
ps3.移动小车相关文章资源
(1)python做了一个极简的栅格地图行走机器人,到底能干啥?[第五弹]——解锁蒙特卡洛定位功能-CSDN博客
(2) 对应python资源:源码地址
(3)python机器人编程——差速AGV机器、基于视觉和预测控制的循迹、自动行驶(上篇)_agv编程-CSDN博客
(4)python机器人编程——差速AGV机器、基于视觉和预测控制的循迹、自动行驶(下篇)_agv路线规划原则python-CSDN博客
对应python及仿真环境资源:源码链接
ps3.wifi小车控制相关文章资源
web端配套资源源代码已经上传(竖屏版),下载地址
仿真配套资源已经上传:下载地址
web端配套资源源代码已经上传(横屏版),下载地址