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

0 环境准备

1 开发环境准备

1.1 创建项目python环境

1.2 在pycharm创建项目

1.3 安装项目依赖

2 资源准备

3 adk agent构建

3.1 新建adk_agent_tool 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

6 测试

6.1 启动adk

6.2 访问web地址

6.3 输入问题

6.4 查看调试信息

7 完整代码

附录:

项目目录结构

可能存在的问题

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 python包

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

3.2 编辑__init__.py文件

from . import agent

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

4  配置env

4.1 新建.env文件

4.2 编辑.env文件

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

OLLAMA_API_BASE=http://localhost:11434
MODEL=qwen3:8b
OPENAI_API_KEY=ollama
OPENWEATHER_API_KEY=5082d49xxxxx163cb
OPENWEATHER_BASE_URL=https://api.openweathermap.org/data/2.5/weather
USER_AGENT=weather-app/1.0

5 agent逻辑实现

5.1 新建agent.py文件

5.2 导入相关依赖包

import json
import os

import httpx
from dotenv import load_dotenv
from google.adk import Agent
from google.adk.models.lite_llm import LiteLlm

5.3 加载配置文件

load_dotenv()

model_name = os.getenv('MODEL')

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

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

6 测试

        进入mcp_demo目录,执行adk web可以运行adk程序,这种方式是adk提供的web调用agent的方式,在此web页面可以看到完整的agent调用流程及过程参数和结果。

6.1 启动adk

adk web

        在mcp_demo执行以上命令可以看到命令行输出信息,可以看到web访问地址如下图:

6.2 访问web地址

打开浏览器,地址栏输入http://localhost:8000/ ,如下图:

默认选中的是刚刚实现的adk_agent_tool工具。

6.3 输入问题

        在聊天框输入武汉今天的天气怎么样,可以看到adk调用的工具及调用结果如下图:

6.4 查看调试信息

        点击聊天框内的get_weather_tool可以查看adk调用agent工具的过程、参数及调用结果。如下图:

7 完整代码

import json
import os

import httpx
from dotenv import load_dotenv
from google.adk import Agent
from google.adk.models.lite_llm import LiteLlm

load_dotenv()

model_name = os.getenv('MODEL')

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):
    """
    格式化天气数据
    :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):
    """
    查询即时天气函数
    :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)

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

附录:

项目目录结构

可能存在的问题

        调用天气查询方法是连接超时,请检查是否开启科学上网。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值