AgentScope 2.0 实战:构建一个会调用工具的天气助手

AgentScope 2.0 实战:构建一个会调用工具的天气助手

AgentScope 2.0 把 Agent 的核心循环、工具调用和模型适配做了更清晰的拆分。本文用一个最小但完整的天气助手案例,演示如何创建 ReActAgent、注册 Python 工具,并让 Agent 根据用户问题自动调用工具。

本文基于 AgentScope 2.0 文档中的 API 组织示例。模型使用通义千问 DashScope,工具使用本地 Python 函数。

1. 环境准备

AgentScope 2.0 要求 Python 3.11 或更高版本。推荐使用 uv 创建隔离环境:

uv venv --python 3.11
source .venv/bin/activate
uv pip install agentscope[full]
export DASHSCOPE_API_KEY="你的 DashScope API Key"

安装完成后,可以用下面的命令检查版本:

python -c "import agentscope; print(agentscope.__version__)"

安装与版本检查命令

uv venv --python 3.11
source .venv/bin/activate
uv pip install "agentscope[full]"
python -c "import agentscope; print(agentscope.__version__)"

2. 编写天气工具

先定义一个普通的 Python 函数。为了便于演示,这里返回固定数据;实际项目中可以替换成天气 API、数据库查询或内部服务调用。

def get_weather(city: str) -> str:
    """查询城市天气。"""
    return f"{city}:晴,28°C,东南风 2 级"

AgentScope 会根据函数名称、参数类型和文档字符串生成工具描述,模型据此判断什么时候需要调用它。

3. 创建 ReActAgent

新建 weather_agent.py:

import asyncio
import os

from agentscope.agent import ReActAgent
from agentscope.formatter import DashScopeChatFormatter
from agentscope.model import DashScopeChatModel
from agentscope.tool import Toolkit


def get_weather(city: str) -> str:
    """查询城市天气。"""
    return f"{city}:晴,28°C,东南风 2 级"


async def main() -> None:
    toolkit = Toolkit()
    toolkit.register_tool_function(get_weather)

    agent = ReActAgent(
        name="WeatherBot",
        sys_prompt="你是天气助手。遇到天气问题时,先调用 get_weather 工具,再用中文回答。",
        model=DashScopeChatModel(
            model_name="qwen-plus",
            api_key=os.environ["DASHSCOPE_API_KEY"],
            stream=True,
        ),
        formatter=DashScopeChatFormatter(),
        toolkit=toolkit,
    )

    result = await agent("查询杭州今天的天气")
    print(result.get_text_content())


if __name__ == "__main__":
    asyncio.run(main())

工具注册与 Agent 核心代码

toolkit = Toolkit()
toolkit.register_tool_function(get_weather)

# 将已注册工具交给 Agent 使用
agent = ReActAgent(
    name="WeatherBot",
    sys_prompt="遇到天气问题时先调用工具",
    model=model,
    formatter=DashScopeChatFormatter(),
    toolkit=toolkit,
)

代码的关键关系只有三步:创建 Toolkit、注册 get_weather、把 toolkit 传给 ReActAgent。

4. 运行过程

python weather_agent.py

一次典型的执行过程如下:

  1. 用户发送“查询杭州今天的天气”;
  2. `ReActAgent` 判断需要使用天气工具;
  3. AgentScope 执行 `get_weather(city="杭州")`;
  4. 工具结果回到 Agent;
  5. 模型生成最终回答。

输出示例:

杭州今天晴,气温 28°C,东南风 2 级。外出时建议做好防晒。

在生产环境中,建议把工具返回值设计成结构化数据,并在工具内部处理超时、重试和权限校验。例如:

from typing import Any


def get_weather(city: str) -> dict[str, Any]:
    return {
        "city": city,
        "condition": "晴",
        "temperature": 28,
        "wind": "东南风 2 级",
    }

5. 使用流式事件观察 Agent

AgentScope 2.0 同时提供 reply 和 reply_stream 两种入口。前者等待最终消息,后者可以逐步接收文本增量、工具调用开始和工具结果等事件。

from agentscope.event import EventType
from agentscope.message import UserMsg


async def stream_once(agent: ReActAgent) -> None:
    user_msg = UserMsg(name="user", content="查询杭州今天的天气")

    async for event in agent.reply_stream(user_msg):
        if event.type == EventType.TEXT_BLOCK_DELTA:
            print(event.delta, end="", flush=True)
        elif event.type == EventType.TOOL_CALL_START:
            print("\\n[开始调用工具]", flush=True)

流式事件适合接入 WebSocket、SSE 或命令行界面。前端可以在模型生成最终回答前先展示“正在查询天气”,从而改善长任务的交互体验。

6. 这个案例适合怎样扩展

6.1 接入真实天气服务

把 get_weather 替换成对外部天气 API 的调用即可。建议将网络请求封装在工具函数内部,并设置明确的超时时间。

6.2 增加多个工具

例如再注册 get_air_quality 和 get_traffic。模型会根据工具描述选择合适的函数,也可以在 Agent 层面对工具调用做权限控制。

6.3 增加计划能力

对于“查询天气、规划路线、整理出行建议”这类多步骤任务,可以传入 PlanNotebook,让 Agent 把任务拆成子任务并跟踪状态。

6.4 接入 FastAPI

如果要把 Agent 暴露成服务,可以在 FastAPI 接口中创建或复用 Agent,并用 SSE 输出流式事件。生产部署时还需要处理会话隔离、状态存储、并发限制和 API Key 管理。

7. 常见问题

问题一:为什么 Agent 不调用工具?

检查工具函数是否已经执行 toolkit.register_tool_function,同时确认系统提示词明确说明了什么时候使用工具。函数名称和文档字符串也应该足够具体。

问题二:为什么导入路径和旧版本不同?

AgentScope 2.0 的 Agent、模型、Formatter 和 Toolkit 分属不同模块。遇到旧教程时,应以 2.0 对应版本文档为准,不要直接混用旧版 Msg 和新版消息接口。

问题三:为什么流式输出没有内容?

确认模型初始化时启用了 stream=True,并且消费的是 reply_stream 返回的事件。只调用 reply 不会得到增量事件。

总结

这个案例展示了 AgentScope 2.0 的最小闭环:模型负责理解任务,ReActAgent 负责推理循环,Toolkit 负责管理工具,Python 函数负责执行具体动作。实际项目可以在此基础上继续加入真实 API、记忆、计划、并发工具调用和 FastAPI 服务化能力。

posted @ 2026-10-11 17:45  fitch_liu  阅读(31)  评论(0)    收藏  举报