ADK实战-基于ollama+qwen3实现外部工具串行调用

article/2025/6/10 10:13:37

0 环境准备

1 开发环境准备

1.1 创建项目python环境

1.2 在pycharm创建项目

1.3 安装项目依赖

2 资源准备

3 adk agent构建

3.1 新建adk_agent_tool_serial python包

3.2 编辑__init__.py文件

4  配置env

4.1 新建.env文件

4.2 编辑.env文件

5 agent逻辑实现

5.1 新建agent.py文件

5.2 导入相关依赖包

5.3 加载配置文件

5.4 定义请求天气接口方法

5.5 定义格式化天气结果方法

5.6 定义获取天气工具方法

5.7 定义天气agent

5.8 定义写入本地文件方法

5.9 定义写入本地文件agent

5.10 定义串行agent

6 完整代码


0 环境准备

  • ollama已部署推理模型qwen3:8b
  • 已安装miniconda环境
  • 具备科学上网条件

1 开发环境准备

1.1 创建项目python环境

通过conda命令创建项目的python开发环境

 conda create -n mcp_demo python=3.10

1.2 在pycharm创建项目

  • 解释器类型:选择自定义环境
  • 环境:选择现有
  • 类型:选择conda
  • 环境:选择上一步创建的环境

1.3 安装项目依赖

安装adk、litellm相关依赖

安装python-dotenv python读取环境配置文件依赖

pip install google-adk litellm python-dotenv httpx

2 资源准备

        本项目中需要调用天气接口获取城市的天气信息,因此需要注册天气API网站,并且获取调用key。

具体流程请参考以下链接的第二章节:MCP实战-基于Ollama+qwen2.5以sse方式实现MCP协议工具调用_mcp sse-CSDN博客

3 adk agent构建

3.1 新建adk_agent_tool_serial python包

        adk在识别agent时是一个python包一个agent,包名就是agent名字,因此我们需要新建一个目录,此例中是adk_agent_tool_serial,如下图所示:

3.2 编辑__init__.py文件

from . import agent

这样可以是adk_agent_tool_serial的内容可以被导入,adk可以识别并调用adk_agent_tool_serial。

4  配置env

4.1 新建.env文件

4.2 编辑.env文件

        填充模型,open weather等配置参数

OLLAMA_API_BASE=http://localhost:11434
MODEL=qwen3:8b
EMBEDDINGS_MODEL=quentinz/bge-large-zh-v1.5:latest
OPENAI_API_KEY=ollama
OPENWEATHER_API_KEY=5082xxxxd4cddffd1051163cb
OPENWEATHER_BASE_URL=https://api.openweathermap.org/data/2.5/weather
USER_AGENT=weather-app/1.0

注意将key换成自己的key,按照参考博客一步步申请。

5 agent逻辑实现

5.1 新建agent.py文件

5.2 导入相关依赖包

import json
import osimport httpx
from dotenv import load_dotenv
from google.adk.agents import LlmAgent, SequentialAgent
from google.adk.models.lite_llm import LiteLlm

5.3 加载配置文件

load_dotenv()model_name = os.getenv('MODEL')
api_base = os.getenv('OLLAMA_API_BASE')openweather_api_key = os.getenv('OPENWEATHER_API_KEY')
openweather_base_url = os.getenv('OPENWEATHER_BASE_URL')
user_agent = os.getenv('USER_AGENT')

5.4 定义请求天气接口方法


async def get_weather(city):"""从OpenWeather API 获取天气信息:param city: 城市名称(需要试用英文,如 beijing):return: 天气数据字典;若发生错误,返回包含error信息的字典"""params = {"q": city,"appid": openweather_api_key,"units": "metric","lang": "zh_cn",}headers = {"User-Agent": user_agent}async with httpx.AsyncClient() as client:try:response = await client.get(openweather_base_url, params=params, headers=headers, timeout=30)response.raise_for_status()return response.json()except httpx.HTTPStatusError as e:return {"error": f"HTTP请求错误:{e}"}except Exception as e:return {"error": f"发生错误:{e}"}

5.5 定义格式化天气结果方法

def format_weather_data(data):"""格式化天气数据:param data: 天气数据字典:return: 格式化后的字符串;若发生错误,返回包含error信息的字符串"""#  如果传入的是字符串,则先转换成字典if isinstance(data, str):data = json.loads(data)if "error" in data:return data["error"]weather = data["weather"][0]["description"]temperature = data["main"]["temp"]city = data["name"]country = data["sys"]["country"]humidity = data["main"]["humidity"]wind = data["wind"]["speed"]return f"城市:{city}, {country}\n天气:{weather}\n温度:{temperature}°C\n湿度:{humidity}%\n风速:{wind}m/s"

5.6 定义获取天气工具方法

async def get_weather_tool(city: str):"""查询即时天气函数:param city: 必要参数,字符串类型,用于表示查询天气的具体城市名称,\注意,中国的城市需要用对应城市的英文名称代替,例如如果需要查询北京市天气,则city参数需要输入'Beijing';:return:OpenWeather API查询即时天气的结果,具体URL请求地址为:https://api.openweathermap.org/data/2.5/weather\返回结果对象类型为解析之后的JSON格式对象,并用字符串形式进行表示,其中包含了全部重要的天气信息"""weather_data = await get_weather(city)return format_weather_data(weather_data)

5.7 定义天气agent

weather_agent = LlmAgent(name = "天气查询agent",model=LiteLlm(model=f"{model_name}",api_base=api_base,custom_llm_provider="ollama"),description = ("回答城市天气情况的问题"),instruction = ("你是一个天气助手,根据输入的城市输出该城市的天气情况"),tools = [get_weather_tool],output_key = "content"
)

5.8 定义写入本地文件方法

def write_weather_to_file(content: str) -> bool:"""将天气结果写入本地文件。:param content: 必要参数,字符串类型,用于表示需要写入文档的具体内容。:return:是否成功写入"""flag = Truetry:with open("weather.txt", "w", encoding="utf-8") as file:file.write(content)except Exception as e:print(f"写入文件时发生错误: {e}")flag = Falsereturn flag

5.9 定义写入本地文件agent

write_weather_to_file_agent = LlmAgent(name = "将天气结果写入文件agent",model=LiteLlm(model=f"ollama_chat/{model_name}",api_base=api_base,custom_llm_provider="ollama"),description = ("将天气结果内容写入文件"),instruction = ("你是一个写本地文件的助手,根据天气结果写入到本地文件中"),tools = [write_weather_to_file]
)

5.10 定义串行agent

root_agent = SequentialAgent(name = "串行agent",sub_agents = [weather_agent, write_weather_to_file],description = ("你是一个天气助手,你可以根据输入的城市,将该城市的天气情况写入到本地文件中")
)

6 完整代码

import json
import osimport httpx
from dotenv import load_dotenv
from google.adk.agents import LlmAgent, SequentialAgent
from google.adk.models.lite_llm import LiteLlmload_dotenv()model_name = os.getenv('MODEL')
api_base = os.getenv('OLLAMA_API_BASE')openweather_api_key = os.getenv('OPENWEATHER_API_KEY')
openweather_base_url = os.getenv('OPENWEATHER_BASE_URL')
user_agent = os.getenv('USER_AGENT')async def get_weather(city):"""从OpenWeather API 获取天气信息:param city: 城市名称(需要试用英文,如 beijing):return: 天气数据字典;若发生错误,返回包含error信息的字典"""params = {"q": city,"appid": openweather_api_key,"units": "metric","lang": "zh_cn",}headers = {"User-Agent": user_agent}async with httpx.AsyncClient() as client:try:response = await client.get(openweather_base_url, params=params, headers=headers, timeout=30)response.raise_for_status()return response.json()except httpx.HTTPStatusError as e:return {"error": f"HTTP请求错误:{e}"}except Exception as e:return {"error": f"发生错误:{e}"}def format_weather_data(data) -> str:"""格式化天气数据:param data: 天气数据字典:return: 格式化后的字符串;若发生错误,返回包含error信息的字符串"""#  如果传入的是字符串,则先转换成字典if isinstance(data, str):data = json.loads(data)if "error" in data:return data["error"]weather = data["weather"][0]["description"]temperature = data["main"]["temp"]city = data["name"]country = data["sys"]["country"]humidity = data["main"]["humidity"]wind = data["wind"]["speed"]return f"城市:{city}, {country}\n天气:{weather}\n温度:{temperature}°C\n湿度:{humidity}%\n风速:{wind}m/s"async def get_weather_tool(city: str) -> str:"""查询即时天气函数:param city: 必要参数,字符串类型,用于表示查询天气的具体城市名称,\注意,中国的城市需要用对应城市的英文名称代替,例如如果需要查询北京市天气,则city参数需要输入'Beijing';:return:OpenWeather API查询即时天气的结果,具体URL请求地址为:https://api.openweathermap.org/data/2.5/weather\返回结果对象类型为解析之后的JSON格式对象,并用字符串形式进行表示,其中包含了全部重要的天气信息"""weather_data = await get_weather(city)return format_weather_data(weather_data)def write_weather_to_file(content: str) -> bool:"""将天气结果写入本地文件。:param content: 必要参数,字符串类型,用于表示需要写入文档的具体内容。:return:是否成功写入"""flag = Truetry:with open("weather.txt", "w", encoding="utf-8") as file:file.write(content)except Exception as e:print(f"写入文件时发生错误: {e}")flag = Falsereturn flagweather_agent = LlmAgent(name = "天气查询agent",model=LiteLlm(model=f"{model_name}",api_base=api_base,custom_llm_provider="ollama"),description = ("回答城市天气情况的问题"),instruction = ("你是一个天气助手,根据输入的城市输出该城市的天气情况"),tools = [get_weather_tool],output_key = "content"
)write_weather_to_file_agent = LlmAgent(name = "将天气结果写入文件agent",model=LiteLlm(model=f"ollama_chat/{model_name}",api_base=api_base,custom_llm_provider="ollama"),description = ("将天气结果内容写入文件"),instruction = ("你是一个写本地文件的助手,根据天气结果写入到本地文件中"),tools = [write_weather_to_file]
)root_agent = SequentialAgent(name = "串行agent",sub_agents = [weather_agent, write_weather_to_file],description = ("你是一个天气助手,你可以根据输入的城市,将该城市的天气情况写入到本地文件中")
)


http://www.hkcw.cn/article/VXLQTtARMn.shtml

相关文章

降本增效的新引擎:GEO如何提升企业营销ROI

在当前经济环境下,企业面临着前所未有的成本压力和效率挑战。深耕数字营销二十余年,我们见证了从传统广告到数字营销,再到如今生成式AI时代的每一次效率变革。在这个新阶段,生成式引擎优化(GEO)正在成为企业…

Blinko智能笔记系统实现跨平台同步与隐私保护的完整技术方案解析

文章目录 前言1. Docker Compose一键安装2. 简单使用演示3. 安装cpolar内网穿透4. 配置公网地址5. 配置固定公网地址 推荐 ​ 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。 点击跳转到网站 前言 是否…

OpenCV CUDA模块特征检测------创建Harris角点检测器的GPU实现接口cv::cuda::createHarrisCorner

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 该函数创建一个 基于 Harris 算法的角点响应计算对象,专门用于在 GPU 上进行高效计算。 它返回的是一个 cv::Ptrcv::cuda::Cornernes…

013旅游网站设计技术详解:打造一站式旅游服务平台

旅游网站设计技术详解:打造一站式旅游服务平台 在互联网与旅游业深度融合的时代,旅游网站成为人们规划行程、预订服务的重要工具。一个功能完备的旅游网站,通过用户管理、订单管理等核心模块,实现用户与管理员的高效交互。本文将…

Linux运维笔记:1010实验室电脑资源规范使用指南

文章目录 0. 检查资源使用情况,避免冲突检查在线用户检查 CPU 使用情况检查 GPU 使用情况协作建议 1. 备份重要文件和数据2. 定期清理硬盘空间3. 退出 ThinLinc 时注销,释放内存4. 校外使用时配置 VPN注意事项总结 实验室的电脑配备了 CPU 和 GPU 资源&a…

Nginx + Tomcat负载均衡群集

目录 一、案例环境 二、部署 Tomcat(102/103) 1、准备环境 (1)关闭firewalld 防火墙 (2)安装JDK 2、安装配置 Tomcat (1)Tomcat 的安装和配置 (2)移动…

每日算法-250603

每日算法学习 今天学习了两道关于子数组和的 LeetCode 题目。 1524. 和为奇数的子数组数目 题目 思路 💡 前缀和 核心思想:子数组 arr[i..j] 的和可以表示为两个前缀和之差,即 prefixSum[j1] - prefixSum[i] (假设 prefixSum[k] 表示 arr[0…

【T2I】InteractDiffusion: Interaction Control in Text-to-Image Diffusion Models

CODE: CVPR 2024 https://jiuntian.github.io/interactdiffusion Abstract 大规模文本到图像(t2i)扩散模型在基于文本描述生成连贯图像方面展示了令人难以置信的能力,从而在内容生成方面实现了广泛的应用。虽然最近的进步已经引入了对物体定位、姿态和图像轮廓等因…

今日行情明日机会——20250603

上证指数放量收阳线,阳包阴,量能超过5天均量,个股涨多跌少,行情有所回暖。 深证指数缩量收阳线,再次回打支撑位。 2025年6月3日涨停股主要行业方向分析(基于图片数据) 1. 医药(政策…

Foundation Models for Generalist Geospatial Artificial Intelligence论文阅读

文章目录 摘要1. 引言2. 研究背景3. 预训练数据3.1 HLS-2数据3.2 高效数据采样3.3 预处理程序 4. 模型结构和预训练4.1 时空数据考虑4.2 预训练4.3 预训练结果 5. 下游任务5.1 任务微调数据集5.2 微调模型设置5.3 微调任务结果5.3.1 云插补任务5.3.2 洪水映射任务5.3.3 火灾痕迹…

C++实现汉诺塔游戏用户交互

目录 一、模型调整(一)模型定义(二)模型实现1.电脑自动完成部分2.SDL图形显示2.1拿起放下盘子的函数2.2左右移动手指的函数 二、处理用户输入,进行人机分流三、总结四、源码下载 上篇文章使用C语言实现汉诺塔游戏电脑自动完成的步骤,还没有实现用户交互&…

嵌入式学习 D32:系统编程--进程间通信IPC

引言--进程间通信管道的概念管道相关操作有名管道及其相关操作信号通信 一、引言--进程间通信 1)因为空间是独立和隔绝的,数据发不过去,需要进程间的通信来交互,所以需要通信。 2)linux进程间通信的常用几种方式&…

黑马Java面试笔记之 消息中间件篇(Kafka)

一. Kafka保证消息不丢失 Kafka如何保证消息不丢失 使用Kafka在消息的收发过程中都会出现消息丢失,Kafka分别给出了解决方案 生产者发送消息到Brocker丢失消息在Brocker中存储丢失消费者从Brocker接收消息丢失 1.1 生产者发送消息到Brocker丢失 设置异步发送 消息…

java的SPI机制

SPI(Service Provider Interface)是java提供的一种服务发现机制。允许你定义一个接口或抽象类,然后由第三方实现这个接口,并在运行时动态加载这些实现类 核心思想是:面向接口编程,解耦接口与实现 核心组件…

SpringCloud 分布式锁Redisson锁的重入性 高并发 获取锁

介绍 Redisson 的锁支持 可重入性,这意味着同一个线程在获取锁后,如果再次尝试获取该锁,它可以成功地获得锁,而不会被阻塞。 每次一个线程成功获取锁后,它的持有次数会增加。当线程再次获取该锁时,Rediss…

PyTorch--池化层(4)

池化层(Pooling Layer) 用于降低特征图的空间维度,减少计算量和参数数量,同时保留最重要的特征信息。 池化作用:比如1080p视频——720p 池化层的步长默认是卷积核的大小 ceil 允许有出界部分;floor 不允许…

【自动思考记忆系统】demo (Java版)

背景:看了《人工智能》中的一段文章,于是有了想法。想从另一种观点(⭕️)出发,尝试编码,告别传统程序员一段代码解决一个问题的方式。下图是文章原文和我的思考涂鸦✍️,于是想写一个自动思考记…

小白的进阶之路系列之十二----人工智能从初步到精通pytorch综合运用的讲解第五部分

在本笔记本中,我们将针对Fashion-MNIST数据集训练LeNet-5的变体。Fashion-MNIST是一组描绘各种服装的图像瓦片,有十个类别标签表明所描绘的服装类型。 # PyTorch model and training necessities import torch import torch.nn as nn import torch.nn.functional as F impor…

pytorch3d+pytorch1.10+MinkowskiEngine安装

1、配置pytorch1.10cuda11.0 pip install torch1.10.1cu111 torchvision0.11.2cu111 torchaudio0.10.1 -f https://download.pytorch.org/whl/cu111/torch_stable.html 2、配置 MinkowskiEngine库 不按下面步骤,出现错误 1、下载MinkowskiEngine0.5.4到本地 2、查看…

ORACLE 缺失 OracleDBConsoleorcl服务导致https://xxx:port/em 不能访问

这个原因是,操作过一下 ORCL的服务配置变更导致的。 再PATH中添加个环境变量,路径如下 管理员权限运行cmd 等待创建完成 大概3分钟 查看服务 点击第一个访问,下图登录后的截图